2 * Packet matching code.
4 * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
5 * Copyright (C) 2000-2005 Netfilter Core Team <coreteam@netfilter.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/cache.h>
13 #include <linux/capability.h>
14 #include <linux/skbuff.h>
15 #include <linux/kmod.h>
16 #include <linux/vmalloc.h>
17 #include <linux/netdevice.h>
18 #include <linux/module.h>
19 #include <linux/icmp.h>
21 #include <net/compat.h>
22 #include <asm/uaccess.h>
23 #include <linux/mutex.h>
24 #include <linux/proc_fs.h>
25 #include <linux/err.h>
26 #include <linux/cpumask.h>
28 #include <linux/netfilter/x_tables.h>
29 #include <linux/netfilter_ipv4/ip_tables.h>
30 #include <net/netfilter/nf_log.h>
31 #include "../../netfilter/xt_repldata.h"
33 MODULE_LICENSE("GPL");
34 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
35 MODULE_DESCRIPTION("IPv4 packet filter");
37 /*#define DEBUG_IP_FIREWALL*/
38 /*#define DEBUG_ALLOW_ALL*/ /* Useful for remote debugging */
39 /*#define DEBUG_IP_FIREWALL_USER*/
41 #ifdef DEBUG_IP_FIREWALL
42 #define dprintf(format, args...) printk(format , ## args)
44 #define dprintf(format, args...)
47 #ifdef DEBUG_IP_FIREWALL_USER
48 #define duprintf(format, args...) printk(format , ## args)
50 #define duprintf(format, args...)
53 #ifdef CONFIG_NETFILTER_DEBUG
54 #define IP_NF_ASSERT(x) \
57 printk("IP_NF_ASSERT: %s:%s:%u\n", \
58 __func__, __FILE__, __LINE__); \
61 #define IP_NF_ASSERT(x)
65 /* All the better to debug you with... */
70 void *ipt_alloc_initial_table(const struct xt_table *info)
72 return xt_alloc_initial_table(ipt, IPT);
74 EXPORT_SYMBOL_GPL(ipt_alloc_initial_table);
77 We keep a set of rules for each CPU, so we can avoid write-locking
78 them in the softirq when updating the counters and therefore
79 only need to read-lock in the softirq; doing a write_lock_bh() in user
80 context stops packets coming through and allows user context to read
81 the counters or update the rules.
83 Hence the start of any table is given by get_table() below. */
85 /* Returns whether matches rule or not. */
86 /* Performance critical - called for every packet */
88 ip_packet_match(const struct iphdr *ip,
91 const struct ipt_ip *ipinfo,
96 #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
98 if (FWINV((ip->saddr&ipinfo->smsk.s_addr) != ipinfo->src.s_addr,
100 FWINV((ip->daddr&ipinfo->dmsk.s_addr) != ipinfo->dst.s_addr,
102 dprintf("Source or dest mismatch.\n");
104 dprintf("SRC: %pI4. Mask: %pI4. Target: %pI4.%s\n",
105 &ip->saddr, &ipinfo->smsk.s_addr, &ipinfo->src.s_addr,
106 ipinfo->invflags & IPT_INV_SRCIP ? " (INV)" : "");
107 dprintf("DST: %pI4 Mask: %pI4 Target: %pI4.%s\n",
108 &ip->daddr, &ipinfo->dmsk.s_addr, &ipinfo->dst.s_addr,
109 ipinfo->invflags & IPT_INV_DSTIP ? " (INV)" : "");
113 ret = ifname_compare_aligned(indev, ipinfo->iniface, ipinfo->iniface_mask);
115 if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
116 dprintf("VIA in mismatch (%s vs %s).%s\n",
117 indev, ipinfo->iniface,
118 ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":"");
122 ret = ifname_compare_aligned(outdev, ipinfo->outiface, ipinfo->outiface_mask);
124 if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
125 dprintf("VIA out mismatch (%s vs %s).%s\n",
126 outdev, ipinfo->outiface,
127 ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":"");
131 /* Check specific protocol */
133 FWINV(ip->protocol != ipinfo->proto, IPT_INV_PROTO)) {
134 dprintf("Packet protocol %hi does not match %hi.%s\n",
135 ip->protocol, ipinfo->proto,
136 ipinfo->invflags&IPT_INV_PROTO ? " (INV)":"");
140 /* If we have a fragment rule but the packet is not a fragment
141 * then we return zero */
142 if (FWINV((ipinfo->flags&IPT_F_FRAG) && !isfrag, IPT_INV_FRAG)) {
143 dprintf("Fragment rule but not fragment.%s\n",
144 ipinfo->invflags & IPT_INV_FRAG ? " (INV)" : "");
152 ip_checkentry(const struct ipt_ip *ip)
154 if (ip->flags & ~IPT_F_MASK) {
155 duprintf("Unknown flag bits set: %08X\n",
156 ip->flags & ~IPT_F_MASK);
159 if (ip->invflags & ~IPT_INV_MASK) {
160 duprintf("Unknown invflag bits set: %08X\n",
161 ip->invflags & ~IPT_INV_MASK);
168 ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
171 printk("ip_tables: error: `%s'\n",
172 (const char *)par->targinfo);
177 /* Performance critical - called for every packet */
179 do_match(const struct ipt_entry_match *m, const struct sk_buff *skb,
180 struct xt_match_param *par)
182 par->match = m->u.kernel.match;
183 par->matchinfo = m->data;
185 /* Stop iteration if it doesn't match */
186 if (!m->u.kernel.match->match(skb, par))
192 /* Performance critical */
193 static inline struct ipt_entry *
194 get_entry(const void *base, unsigned int offset)
196 return (struct ipt_entry *)(base + offset);
199 /* All zeroes == unconditional rule. */
200 /* Mildly perf critical (only if packet tracing is on) */
201 static inline bool unconditional(const struct ipt_ip *ip)
203 static const struct ipt_ip uncond;
205 return memcmp(ip, &uncond, sizeof(uncond)) == 0;
209 /* for const-correctness */
210 static inline const struct ipt_entry_target *
211 ipt_get_target_c(const struct ipt_entry *e)
213 return ipt_get_target((struct ipt_entry *)e);
216 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
217 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
218 static const char *const hooknames[] = {
219 [NF_INET_PRE_ROUTING] = "PREROUTING",
220 [NF_INET_LOCAL_IN] = "INPUT",
221 [NF_INET_FORWARD] = "FORWARD",
222 [NF_INET_LOCAL_OUT] = "OUTPUT",
223 [NF_INET_POST_ROUTING] = "POSTROUTING",
226 enum nf_ip_trace_comments {
227 NF_IP_TRACE_COMMENT_RULE,
228 NF_IP_TRACE_COMMENT_RETURN,
229 NF_IP_TRACE_COMMENT_POLICY,
232 static const char *const comments[] = {
233 [NF_IP_TRACE_COMMENT_RULE] = "rule",
234 [NF_IP_TRACE_COMMENT_RETURN] = "return",
235 [NF_IP_TRACE_COMMENT_POLICY] = "policy",
238 static struct nf_loginfo trace_loginfo = {
239 .type = NF_LOG_TYPE_LOG,
243 .logflags = NF_LOG_MASK,
248 /* Mildly perf critical (only if packet tracing is on) */
250 get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e,
251 const char *hookname, const char **chainname,
252 const char **comment, unsigned int *rulenum)
254 const struct ipt_standard_target *t = (void *)ipt_get_target_c(s);
256 if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) {
257 /* Head of user chain: ERROR target with chainname */
258 *chainname = t->target.data;
263 if (s->target_offset == sizeof(struct ipt_entry) &&
264 strcmp(t->target.u.kernel.target->name,
265 IPT_STANDARD_TARGET) == 0 &&
267 unconditional(&s->ip)) {
268 /* Tail of chains: STANDARD target (return/policy) */
269 *comment = *chainname == hookname
270 ? comments[NF_IP_TRACE_COMMENT_POLICY]
271 : comments[NF_IP_TRACE_COMMENT_RETURN];
280 static void trace_packet(const struct sk_buff *skb,
282 const struct net_device *in,
283 const struct net_device *out,
284 const char *tablename,
285 const struct xt_table_info *private,
286 const struct ipt_entry *e)
288 const void *table_base;
289 const struct ipt_entry *root;
290 const char *hookname, *chainname, *comment;
291 const struct ipt_entry *iter;
292 unsigned int rulenum = 0;
294 table_base = private->entries[smp_processor_id()];
295 root = get_entry(table_base, private->hook_entry[hook]);
297 hookname = chainname = hooknames[hook];
298 comment = comments[NF_IP_TRACE_COMMENT_RULE];
300 xt_entry_foreach(iter, root, private->size - private->hook_entry[hook])
301 if (get_chainname_rulenum(iter, e, hookname,
302 &chainname, &comment, &rulenum) != 0)
305 nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo,
306 "TRACE: %s:%s:%s:%u ",
307 tablename, chainname, comment, rulenum);
312 struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry)
314 return (void *)entry + entry->next_offset;
317 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
319 ipt_do_table(struct sk_buff *skb,
321 const struct net_device *in,
322 const struct net_device *out,
323 struct xt_table *table)
325 #define tb_comefrom ((struct ipt_entry *)table_base)->comefrom
327 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
328 const struct iphdr *ip;
329 bool hotdrop = false;
330 /* Initializing verdict to NF_DROP keeps gcc happy. */
331 unsigned int verdict = NF_DROP;
332 const char *indev, *outdev;
333 const void *table_base;
334 struct ipt_entry *e, *back;
335 const struct xt_table_info *private;
336 struct xt_match_param mtpar;
337 struct xt_target_param tgpar;
341 indev = in ? in->name : nulldevname;
342 outdev = out ? out->name : nulldevname;
343 /* We handle fragments by dealing with the first fragment as
344 * if it was a normal packet. All other fragments are treated
345 * normally, except that they will NEVER match rules that ask
346 * things we don't know, ie. tcp syn flag or ports). If the
347 * rule is also a fragment-specific rule, non-fragments won't
349 mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
350 mtpar.thoff = ip_hdrlen(skb);
351 mtpar.hotdrop = &hotdrop;
352 mtpar.in = tgpar.in = in;
353 mtpar.out = tgpar.out = out;
354 mtpar.family = tgpar.family = NFPROTO_IPV4;
355 mtpar.hooknum = tgpar.hooknum = hook;
357 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
359 private = table->private;
360 table_base = private->entries[smp_processor_id()];
362 e = get_entry(table_base, private->hook_entry[hook]);
364 /* For return from builtin chain */
365 back = get_entry(table_base, private->underflow[hook]);
368 const struct ipt_entry_target *t;
369 const struct xt_entry_match *ematch;
373 if (!ip_packet_match(ip, indev, outdev,
374 &e->ip, mtpar.fragoff)) {
376 e = ipt_next_entry(e);
380 xt_ematch_foreach(ematch, e)
381 if (do_match(ematch, skb, &mtpar) != 0)
384 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
386 t = ipt_get_target(e);
387 IP_NF_ASSERT(t->u.kernel.target);
389 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
390 defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
391 /* The packet is traced: log it */
392 if (unlikely(skb->nf_trace))
393 trace_packet(skb, hook, in, out,
394 table->name, private, e);
396 /* Standard target? */
397 if (!t->u.kernel.target->target) {
400 v = ((struct ipt_standard_target *)t)->verdict;
402 /* Pop from stack? */
403 if (v != IPT_RETURN) {
404 verdict = (unsigned)(-v) - 1;
408 back = get_entry(table_base, back->comefrom);
411 if (table_base + v != ipt_next_entry(e) &&
412 !(e->ip.flags & IPT_F_GOTO)) {
413 /* Save old back ptr in next entry */
414 struct ipt_entry *next = ipt_next_entry(e);
415 next->comefrom = (void *)back - table_base;
416 /* set back pointer to next entry */
420 e = get_entry(table_base, v);
424 /* Targets which reenter must return
426 tgpar.target = t->u.kernel.target;
427 tgpar.targinfo = t->data;
430 #ifdef CONFIG_NETFILTER_DEBUG
431 tb_comefrom = 0xeeeeeeec;
433 verdict = t->u.kernel.target->target(skb, &tgpar);
434 #ifdef CONFIG_NETFILTER_DEBUG
435 if (tb_comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) {
436 printk("Target %s reentered!\n",
437 t->u.kernel.target->name);
440 tb_comefrom = 0x57acc001;
442 /* Target might have changed stuff. */
444 if (verdict == IPT_CONTINUE)
445 e = ipt_next_entry(e);
450 xt_info_rdunlock_bh();
452 #ifdef DEBUG_ALLOW_ALL
463 /* Figures out from what hook each rule can be called: returns 0 if
464 there are loops. Puts hook bitmask in comefrom. */
466 mark_source_chains(const struct xt_table_info *newinfo,
467 unsigned int valid_hooks, void *entry0)
471 /* No recursion; use packet counter to save back ptrs (reset
472 to 0 as we leave), and comefrom to save source hook bitmask */
473 for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
474 unsigned int pos = newinfo->hook_entry[hook];
475 struct ipt_entry *e = (struct ipt_entry *)(entry0 + pos);
477 if (!(valid_hooks & (1 << hook)))
480 /* Set initial back pointer. */
481 e->counters.pcnt = pos;
484 const struct ipt_standard_target *t
485 = (void *)ipt_get_target_c(e);
486 int visited = e->comefrom & (1 << hook);
488 if (e->comefrom & (1 << NF_INET_NUMHOOKS)) {
489 printk("iptables: loop hook %u pos %u %08X.\n",
490 hook, pos, e->comefrom);
493 e->comefrom |= ((1 << hook) | (1 << NF_INET_NUMHOOKS));
495 /* Unconditional return/END. */
496 if ((e->target_offset == sizeof(struct ipt_entry) &&
497 (strcmp(t->target.u.user.name,
498 IPT_STANDARD_TARGET) == 0) &&
499 t->verdict < 0 && unconditional(&e->ip)) ||
501 unsigned int oldpos, size;
503 if ((strcmp(t->target.u.user.name,
504 IPT_STANDARD_TARGET) == 0) &&
505 t->verdict < -NF_MAX_VERDICT - 1) {
506 duprintf("mark_source_chains: bad "
507 "negative verdict (%i)\n",
512 /* Return: backtrack through the last
515 e->comefrom ^= (1<<NF_INET_NUMHOOKS);
516 #ifdef DEBUG_IP_FIREWALL_USER
518 & (1 << NF_INET_NUMHOOKS)) {
519 duprintf("Back unset "
526 pos = e->counters.pcnt;
527 e->counters.pcnt = 0;
529 /* We're at the start. */
533 e = (struct ipt_entry *)
535 } while (oldpos == pos + e->next_offset);
538 size = e->next_offset;
539 e = (struct ipt_entry *)
540 (entry0 + pos + size);
541 e->counters.pcnt = pos;
544 int newpos = t->verdict;
546 if (strcmp(t->target.u.user.name,
547 IPT_STANDARD_TARGET) == 0 &&
549 if (newpos > newinfo->size -
550 sizeof(struct ipt_entry)) {
551 duprintf("mark_source_chains: "
552 "bad verdict (%i)\n",
556 /* This a jump; chase it. */
557 duprintf("Jump rule %u -> %u\n",
560 /* ... this is a fallthru */
561 newpos = pos + e->next_offset;
563 e = (struct ipt_entry *)
565 e->counters.pcnt = pos;
570 duprintf("Finished chain %u\n", hook);
575 static void cleanup_match(struct ipt_entry_match *m, struct net *net)
577 struct xt_mtdtor_param par;
580 par.match = m->u.kernel.match;
581 par.matchinfo = m->data;
582 par.family = NFPROTO_IPV4;
583 if (par.match->destroy != NULL)
584 par.match->destroy(&par);
585 module_put(par.match->me);
589 check_entry(const struct ipt_entry *e, const char *name)
591 const struct ipt_entry_target *t;
593 if (!ip_checkentry(&e->ip)) {
594 duprintf("ip_tables: ip check failed %p %s.\n", e, name);
598 if (e->target_offset + sizeof(struct ipt_entry_target) >
602 t = ipt_get_target_c(e);
603 if (e->target_offset + t->u.target_size > e->next_offset)
610 check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
612 const struct ipt_ip *ip = par->entryinfo;
615 par->match = m->u.kernel.match;
616 par->matchinfo = m->data;
618 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
619 ip->proto, ip->invflags & IPT_INV_PROTO);
621 duprintf("ip_tables: check failed for `%s'.\n",
629 find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par)
631 struct xt_match *match;
634 match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
636 "ipt_%s", m->u.user.name);
637 if (IS_ERR(match) || !match) {
638 duprintf("find_check_match: `%s' not found\n", m->u.user.name);
639 return match ? PTR_ERR(match) : -ENOENT;
641 m->u.kernel.match = match;
643 ret = check_match(m, par);
649 module_put(m->u.kernel.match->me);
653 static int check_target(struct ipt_entry *e, struct net *net, const char *name)
655 struct ipt_entry_target *t = ipt_get_target(e);
656 struct xt_tgchk_param par = {
660 .target = t->u.kernel.target,
662 .hook_mask = e->comefrom,
663 .family = NFPROTO_IPV4,
667 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
668 e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
670 duprintf("ip_tables: check failed for `%s'.\n",
671 t->u.kernel.target->name);
678 find_check_entry(struct ipt_entry *e, struct net *net, const char *name,
681 struct ipt_entry_target *t;
682 struct xt_target *target;
685 struct xt_mtchk_param mtpar;
686 struct xt_entry_match *ematch;
688 ret = check_entry(e, name);
695 mtpar.entryinfo = &e->ip;
696 mtpar.hook_mask = e->comefrom;
697 mtpar.family = NFPROTO_IPV4;
698 xt_ematch_foreach(ematch, e) {
699 ret = find_check_match(ematch, &mtpar);
701 goto cleanup_matches;
705 t = ipt_get_target(e);
706 target = try_then_request_module(xt_find_target(AF_INET,
709 "ipt_%s", t->u.user.name);
710 if (IS_ERR(target) || !target) {
711 duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
712 ret = target ? PTR_ERR(target) : -ENOENT;
713 goto cleanup_matches;
715 t->u.kernel.target = target;
717 ret = check_target(e, net, name);
722 module_put(t->u.kernel.target->me);
724 xt_ematch_foreach(ematch, e) {
727 cleanup_match(ematch, net);
732 static bool check_underflow(const struct ipt_entry *e)
734 const struct ipt_entry_target *t;
735 unsigned int verdict;
737 if (!unconditional(&e->ip))
739 t = ipt_get_target_c(e);
740 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
742 verdict = ((struct ipt_standard_target *)t)->verdict;
743 verdict = -verdict - 1;
744 return verdict == NF_DROP || verdict == NF_ACCEPT;
748 check_entry_size_and_hooks(struct ipt_entry *e,
749 struct xt_table_info *newinfo,
750 const unsigned char *base,
751 const unsigned char *limit,
752 const unsigned int *hook_entries,
753 const unsigned int *underflows,
754 unsigned int valid_hooks)
758 if ((unsigned long)e % __alignof__(struct ipt_entry) != 0 ||
759 (unsigned char *)e + sizeof(struct ipt_entry) >= limit) {
760 duprintf("Bad offset %p\n", e);
765 < sizeof(struct ipt_entry) + sizeof(struct ipt_entry_target)) {
766 duprintf("checking: element %p size %u\n",
771 /* Check hooks & underflows */
772 for (h = 0; h < NF_INET_NUMHOOKS; h++) {
773 if (!(valid_hooks & (1 << h)))
775 if ((unsigned char *)e - base == hook_entries[h])
776 newinfo->hook_entry[h] = hook_entries[h];
777 if ((unsigned char *)e - base == underflows[h]) {
778 if (!check_underflow(e)) {
779 pr_err("Underflows must be unconditional and "
780 "use the STANDARD target with "
784 newinfo->underflow[h] = underflows[h];
788 /* Clear counters and comefrom */
789 e->counters = ((struct xt_counters) { 0, 0 });
795 cleanup_entry(struct ipt_entry *e, struct net *net)
797 struct xt_tgdtor_param par;
798 struct ipt_entry_target *t;
799 struct xt_entry_match *ematch;
801 /* Cleanup all matches */
802 xt_ematch_foreach(ematch, e)
803 cleanup_match(ematch, net);
804 t = ipt_get_target(e);
807 par.target = t->u.kernel.target;
808 par.targinfo = t->data;
809 par.family = NFPROTO_IPV4;
810 if (par.target->destroy != NULL)
811 par.target->destroy(&par);
812 module_put(par.target->me);
815 /* Checks and translates the user-supplied table segment (held in
818 translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
819 const struct ipt_replace *repl)
821 struct ipt_entry *iter;
825 newinfo->size = repl->size;
826 newinfo->number = repl->num_entries;
828 /* Init all hooks to impossible value. */
829 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
830 newinfo->hook_entry[i] = 0xFFFFFFFF;
831 newinfo->underflow[i] = 0xFFFFFFFF;
834 duprintf("translate_table: size %u\n", newinfo->size);
836 /* Walk through entries, checking offsets. */
837 xt_entry_foreach(iter, entry0, newinfo->size) {
838 ret = check_entry_size_and_hooks(iter, newinfo, entry0,
839 entry0 + repl->size, repl->hook_entry, repl->underflow,
846 if (i != repl->num_entries) {
847 duprintf("translate_table: %u not %u entries\n",
848 i, repl->num_entries);
852 /* Check hooks all assigned */
853 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
854 /* Only hooks which are valid */
855 if (!(repl->valid_hooks & (1 << i)))
857 if (newinfo->hook_entry[i] == 0xFFFFFFFF) {
858 duprintf("Invalid hook entry %u %u\n",
859 i, repl->hook_entry[i]);
862 if (newinfo->underflow[i] == 0xFFFFFFFF) {
863 duprintf("Invalid underflow %u %u\n",
864 i, repl->underflow[i]);
869 if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
872 /* Finally, each sanity check must pass */
874 xt_entry_foreach(iter, entry0, newinfo->size) {
875 ret = find_check_entry(iter, net, repl->name, repl->size);
882 xt_entry_foreach(iter, entry0, newinfo->size) {
885 cleanup_entry(iter, net);
890 /* And one copy for every other CPU */
891 for_each_possible_cpu(i) {
892 if (newinfo->entries[i] && newinfo->entries[i] != entry0)
893 memcpy(newinfo->entries[i], entry0, newinfo->size);
900 get_counters(const struct xt_table_info *t,
901 struct xt_counters counters[])
903 struct ipt_entry *iter;
908 /* Instead of clearing (by a previous call to memset())
909 * the counters and using adds, we set the counters
910 * with data used by 'current' CPU.
912 * Bottom half has to be disabled to prevent deadlock
913 * if new softirq were to run and call ipt_do_table
916 curcpu = smp_processor_id();
919 xt_entry_foreach(iter, t->entries[curcpu], t->size) {
920 SET_COUNTER(counters[i], iter->counters.bcnt,
921 iter->counters.pcnt);
925 for_each_possible_cpu(cpu) {
930 xt_entry_foreach(iter, t->entries[cpu], t->size) {
931 ADD_COUNTER(counters[i], iter->counters.bcnt,
932 iter->counters.pcnt);
933 ++i; /* macro does multi eval of i */
935 xt_info_wrunlock(cpu);
940 static struct xt_counters *alloc_counters(const struct xt_table *table)
942 unsigned int countersize;
943 struct xt_counters *counters;
944 const struct xt_table_info *private = table->private;
946 /* We need atomic snapshot of counters: rest doesn't change
947 (other than comefrom, which userspace doesn't care
949 countersize = sizeof(struct xt_counters) * private->number;
950 counters = vmalloc_node(countersize, numa_node_id());
952 if (counters == NULL)
953 return ERR_PTR(-ENOMEM);
955 get_counters(private, counters);
961 copy_entries_to_user(unsigned int total_size,
962 const struct xt_table *table,
963 void __user *userptr)
965 unsigned int off, num;
966 const struct ipt_entry *e;
967 struct xt_counters *counters;
968 const struct xt_table_info *private = table->private;
970 const void *loc_cpu_entry;
972 counters = alloc_counters(table);
973 if (IS_ERR(counters))
974 return PTR_ERR(counters);
976 /* choose the copy that is on our node/cpu, ...
977 * This choice is lazy (because current thread is
978 * allowed to migrate to another cpu)
980 loc_cpu_entry = private->entries[raw_smp_processor_id()];
981 if (copy_to_user(userptr, loc_cpu_entry, total_size) != 0) {
986 /* FIXME: use iterator macros --RR */
987 /* ... then go back and fix counters and names */
988 for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
990 const struct ipt_entry_match *m;
991 const struct ipt_entry_target *t;
993 e = (struct ipt_entry *)(loc_cpu_entry + off);
994 if (copy_to_user(userptr + off
995 + offsetof(struct ipt_entry, counters),
997 sizeof(counters[num])) != 0) {
1002 for (i = sizeof(struct ipt_entry);
1003 i < e->target_offset;
1004 i += m->u.match_size) {
1007 if (copy_to_user(userptr + off + i
1008 + offsetof(struct ipt_entry_match,
1010 m->u.kernel.match->name,
1011 strlen(m->u.kernel.match->name)+1)
1018 t = ipt_get_target_c(e);
1019 if (copy_to_user(userptr + off + e->target_offset
1020 + offsetof(struct ipt_entry_target,
1022 t->u.kernel.target->name,
1023 strlen(t->u.kernel.target->name)+1) != 0) {
1034 #ifdef CONFIG_COMPAT
1035 static void compat_standard_from_user(void *dst, const void *src)
1037 int v = *(compat_int_t *)src;
1040 v += xt_compat_calc_jump(AF_INET, v);
1041 memcpy(dst, &v, sizeof(v));
1044 static int compat_standard_to_user(void __user *dst, const void *src)
1046 compat_int_t cv = *(int *)src;
1049 cv -= xt_compat_calc_jump(AF_INET, cv);
1050 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
1053 static int compat_calc_entry(const struct ipt_entry *e,
1054 const struct xt_table_info *info,
1055 const void *base, struct xt_table_info *newinfo)
1057 const struct xt_entry_match *ematch;
1058 const struct ipt_entry_target *t;
1059 unsigned int entry_offset;
1062 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1063 entry_offset = (void *)e - base;
1064 xt_ematch_foreach(ematch, e)
1065 off += xt_compat_match_offset(ematch->u.kernel.match);
1066 t = ipt_get_target_c(e);
1067 off += xt_compat_target_offset(t->u.kernel.target);
1068 newinfo->size -= off;
1069 ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1073 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1074 if (info->hook_entry[i] &&
1075 (e < (struct ipt_entry *)(base + info->hook_entry[i])))
1076 newinfo->hook_entry[i] -= off;
1077 if (info->underflow[i] &&
1078 (e < (struct ipt_entry *)(base + info->underflow[i])))
1079 newinfo->underflow[i] -= off;
1084 static int compat_table_info(const struct xt_table_info *info,
1085 struct xt_table_info *newinfo)
1087 struct ipt_entry *iter;
1088 void *loc_cpu_entry;
1091 if (!newinfo || !info)
1094 /* we dont care about newinfo->entries[] */
1095 memcpy(newinfo, info, offsetof(struct xt_table_info, entries));
1096 newinfo->initial_entries = 0;
1097 loc_cpu_entry = info->entries[raw_smp_processor_id()];
1098 xt_entry_foreach(iter, loc_cpu_entry, info->size) {
1099 ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo);
1107 static int get_info(struct net *net, void __user *user,
1108 const int *len, int compat)
1110 char name[IPT_TABLE_MAXNAMELEN];
1114 if (*len != sizeof(struct ipt_getinfo)) {
1115 duprintf("length %u != %zu\n", *len,
1116 sizeof(struct ipt_getinfo));
1120 if (copy_from_user(name, user, sizeof(name)) != 0)
1123 name[IPT_TABLE_MAXNAMELEN-1] = '\0';
1124 #ifdef CONFIG_COMPAT
1126 xt_compat_lock(AF_INET);
1128 t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
1129 "iptable_%s", name);
1130 if (t && !IS_ERR(t)) {
1131 struct ipt_getinfo info;
1132 const struct xt_table_info *private = t->private;
1133 #ifdef CONFIG_COMPAT
1134 struct xt_table_info tmp;
1137 ret = compat_table_info(private, &tmp);
1138 xt_compat_flush_offsets(AF_INET);
1142 info.valid_hooks = t->valid_hooks;
1143 memcpy(info.hook_entry, private->hook_entry,
1144 sizeof(info.hook_entry));
1145 memcpy(info.underflow, private->underflow,
1146 sizeof(info.underflow));
1147 info.num_entries = private->number;
1148 info.size = private->size;
1149 strcpy(info.name, name);
1151 if (copy_to_user(user, &info, *len) != 0)
1159 ret = t ? PTR_ERR(t) : -ENOENT;
1160 #ifdef CONFIG_COMPAT
1162 xt_compat_unlock(AF_INET);
1168 get_entries(struct net *net, struct ipt_get_entries __user *uptr,
1172 struct ipt_get_entries get;
1175 if (*len < sizeof(get)) {
1176 duprintf("get_entries: %u < %zu\n", *len, sizeof(get));
1179 if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1181 if (*len != sizeof(struct ipt_get_entries) + get.size) {
1182 duprintf("get_entries: %u != %zu\n",
1183 *len, sizeof(get) + get.size);
1187 t = xt_find_table_lock(net, AF_INET, get.name);
1188 if (t && !IS_ERR(t)) {
1189 const struct xt_table_info *private = t->private;
1190 duprintf("t->private->number = %u\n", private->number);
1191 if (get.size == private->size)
1192 ret = copy_entries_to_user(private->size,
1193 t, uptr->entrytable);
1195 duprintf("get_entries: I've got %u not %u!\n",
1196 private->size, get.size);
1202 ret = t ? PTR_ERR(t) : -ENOENT;
1208 __do_replace(struct net *net, const char *name, unsigned int valid_hooks,
1209 struct xt_table_info *newinfo, unsigned int num_counters,
1210 void __user *counters_ptr)
1214 struct xt_table_info *oldinfo;
1215 struct xt_counters *counters;
1216 void *loc_cpu_old_entry;
1217 struct ipt_entry *iter;
1220 counters = vmalloc(num_counters * sizeof(struct xt_counters));
1226 t = try_then_request_module(xt_find_table_lock(net, AF_INET, name),
1227 "iptable_%s", name);
1228 if (!t || IS_ERR(t)) {
1229 ret = t ? PTR_ERR(t) : -ENOENT;
1230 goto free_newinfo_counters_untrans;
1234 if (valid_hooks != t->valid_hooks) {
1235 duprintf("Valid hook crap: %08X vs %08X\n",
1236 valid_hooks, t->valid_hooks);
1241 oldinfo = xt_replace_table(t, num_counters, newinfo, &ret);
1245 /* Update module usage count based on number of rules */
1246 duprintf("do_replace: oldnum=%u, initnum=%u, newnum=%u\n",
1247 oldinfo->number, oldinfo->initial_entries, newinfo->number);
1248 if ((oldinfo->number > oldinfo->initial_entries) ||
1249 (newinfo->number <= oldinfo->initial_entries))
1251 if ((oldinfo->number > oldinfo->initial_entries) &&
1252 (newinfo->number <= oldinfo->initial_entries))
1255 /* Get the old counters, and synchronize with replace */
1256 get_counters(oldinfo, counters);
1258 /* Decrease module usage counts and free resource */
1259 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()];
1260 xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size)
1261 cleanup_entry(iter, net);
1263 xt_free_table_info(oldinfo);
1264 if (copy_to_user(counters_ptr, counters,
1265 sizeof(struct xt_counters) * num_counters) != 0)
1274 free_newinfo_counters_untrans:
1281 do_replace(struct net *net, const void __user *user, unsigned int len)
1284 struct ipt_replace tmp;
1285 struct xt_table_info *newinfo;
1286 void *loc_cpu_entry;
1287 struct ipt_entry *iter;
1289 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1292 /* overflow check */
1293 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1296 newinfo = xt_alloc_table_info(tmp.size);
1300 /* choose the copy that is on our node/cpu */
1301 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
1302 if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1308 ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
1312 duprintf("ip_tables: Translated table\n");
1314 ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1315 tmp.num_counters, tmp.counters);
1317 goto free_newinfo_untrans;
1320 free_newinfo_untrans:
1321 xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1322 cleanup_entry(iter, net);
1324 xt_free_table_info(newinfo);
1329 do_add_counters(struct net *net, const void __user *user,
1330 unsigned int len, int compat)
1332 unsigned int i, curcpu;
1333 struct xt_counters_info tmp;
1334 struct xt_counters *paddc;
1335 unsigned int num_counters;
1340 const struct xt_table_info *private;
1342 void *loc_cpu_entry;
1343 struct ipt_entry *iter;
1344 #ifdef CONFIG_COMPAT
1345 struct compat_xt_counters_info compat_tmp;
1349 size = sizeof(struct compat_xt_counters_info);
1354 size = sizeof(struct xt_counters_info);
1357 if (copy_from_user(ptmp, user, size) != 0)
1360 #ifdef CONFIG_COMPAT
1362 num_counters = compat_tmp.num_counters;
1363 name = compat_tmp.name;
1367 num_counters = tmp.num_counters;
1371 if (len != size + num_counters * sizeof(struct xt_counters))
1374 paddc = vmalloc_node(len - size, numa_node_id());
1378 if (copy_from_user(paddc, user + size, len - size) != 0) {
1383 t = xt_find_table_lock(net, AF_INET, name);
1384 if (!t || IS_ERR(t)) {
1385 ret = t ? PTR_ERR(t) : -ENOENT;
1390 private = t->private;
1391 if (private->number != num_counters) {
1393 goto unlock_up_free;
1397 /* Choose the copy that is on our node */
1398 curcpu = smp_processor_id();
1399 loc_cpu_entry = private->entries[curcpu];
1400 xt_info_wrlock(curcpu);
1401 xt_entry_foreach(iter, loc_cpu_entry, private->size) {
1402 ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt);
1405 xt_info_wrunlock(curcpu);
1416 #ifdef CONFIG_COMPAT
1417 struct compat_ipt_replace {
1418 char name[IPT_TABLE_MAXNAMELEN];
1422 u32 hook_entry[NF_INET_NUMHOOKS];
1423 u32 underflow[NF_INET_NUMHOOKS];
1425 compat_uptr_t counters; /* struct ipt_counters * */
1426 struct compat_ipt_entry entries[0];
1430 compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
1431 unsigned int *size, struct xt_counters *counters,
1434 struct ipt_entry_target *t;
1435 struct compat_ipt_entry __user *ce;
1436 u_int16_t target_offset, next_offset;
1437 compat_uint_t origsize;
1438 const struct xt_entry_match *ematch;
1442 ce = (struct compat_ipt_entry __user *)*dstptr;
1443 if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 ||
1444 copy_to_user(&ce->counters, &counters[i],
1445 sizeof(counters[i])) != 0)
1448 *dstptr += sizeof(struct compat_ipt_entry);
1449 *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1451 xt_ematch_foreach(ematch, e) {
1452 ret = xt_compat_match_to_user(ematch, dstptr, size);
1456 target_offset = e->target_offset - (origsize - *size);
1457 t = ipt_get_target(e);
1458 ret = xt_compat_target_to_user(t, dstptr, size);
1461 next_offset = e->next_offset - (origsize - *size);
1462 if (put_user(target_offset, &ce->target_offset) != 0 ||
1463 put_user(next_offset, &ce->next_offset) != 0)
1469 compat_find_calc_match(struct ipt_entry_match *m,
1471 const struct ipt_ip *ip,
1472 unsigned int hookmask,
1475 struct xt_match *match;
1477 match = try_then_request_module(xt_find_match(AF_INET, m->u.user.name,
1478 m->u.user.revision),
1479 "ipt_%s", m->u.user.name);
1480 if (IS_ERR(match) || !match) {
1481 duprintf("compat_check_calc_match: `%s' not found\n",
1483 return match ? PTR_ERR(match) : -ENOENT;
1485 m->u.kernel.match = match;
1486 *size += xt_compat_match_offset(match);
1490 static void compat_release_entry(struct compat_ipt_entry *e)
1492 struct ipt_entry_target *t;
1493 struct xt_entry_match *ematch;
1495 /* Cleanup all matches */
1496 xt_ematch_foreach(ematch, e)
1497 module_put(ematch->u.kernel.match->me);
1498 t = compat_ipt_get_target(e);
1499 module_put(t->u.kernel.target->me);
1503 check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
1504 struct xt_table_info *newinfo,
1506 const unsigned char *base,
1507 const unsigned char *limit,
1508 const unsigned int *hook_entries,
1509 const unsigned int *underflows,
1512 struct xt_entry_match *ematch;
1513 struct ipt_entry_target *t;
1514 struct xt_target *target;
1515 unsigned int entry_offset;
1519 duprintf("check_compat_entry_size_and_hooks %p\n", e);
1520 if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
1521 (unsigned char *)e + sizeof(struct compat_ipt_entry) >= limit) {
1522 duprintf("Bad offset %p, limit = %p\n", e, limit);
1526 if (e->next_offset < sizeof(struct compat_ipt_entry) +
1527 sizeof(struct compat_xt_entry_target)) {
1528 duprintf("checking: element %p size %u\n",
1533 /* For purposes of check_entry casting the compat entry is fine */
1534 ret = check_entry((struct ipt_entry *)e, name);
1538 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1539 entry_offset = (void *)e - (void *)base;
1541 xt_ematch_foreach(ematch, e) {
1542 ret = compat_find_calc_match(ematch, name,
1543 &e->ip, e->comefrom, &off);
1545 goto release_matches;
1549 t = compat_ipt_get_target(e);
1550 target = try_then_request_module(xt_find_target(AF_INET,
1552 t->u.user.revision),
1553 "ipt_%s", t->u.user.name);
1554 if (IS_ERR(target) || !target) {
1555 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
1557 ret = target ? PTR_ERR(target) : -ENOENT;
1558 goto release_matches;
1560 t->u.kernel.target = target;
1562 off += xt_compat_target_offset(target);
1564 ret = xt_compat_add_offset(AF_INET, entry_offset, off);
1568 /* Check hooks & underflows */
1569 for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1570 if ((unsigned char *)e - base == hook_entries[h])
1571 newinfo->hook_entry[h] = hook_entries[h];
1572 if ((unsigned char *)e - base == underflows[h])
1573 newinfo->underflow[h] = underflows[h];
1576 /* Clear counters and comefrom */
1577 memset(&e->counters, 0, sizeof(e->counters));
1582 module_put(t->u.kernel.target->me);
1584 xt_ematch_foreach(ematch, e) {
1587 module_put(ematch->u.kernel.match->me);
1593 compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
1594 unsigned int *size, const char *name,
1595 struct xt_table_info *newinfo, unsigned char *base)
1597 struct ipt_entry_target *t;
1598 struct xt_target *target;
1599 struct ipt_entry *de;
1600 unsigned int origsize;
1602 struct xt_entry_match *ematch;
1606 de = (struct ipt_entry *)*dstptr;
1607 memcpy(de, e, sizeof(struct ipt_entry));
1608 memcpy(&de->counters, &e->counters, sizeof(e->counters));
1610 *dstptr += sizeof(struct ipt_entry);
1611 *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
1613 xt_ematch_foreach(ematch, e) {
1614 ret = xt_compat_match_from_user(ematch, dstptr, size);
1618 de->target_offset = e->target_offset - (origsize - *size);
1619 t = compat_ipt_get_target(e);
1620 target = t->u.kernel.target;
1621 xt_compat_target_from_user(t, dstptr, size);
1623 de->next_offset = e->next_offset - (origsize - *size);
1624 for (h = 0; h < NF_INET_NUMHOOKS; h++) {
1625 if ((unsigned char *)de - base < newinfo->hook_entry[h])
1626 newinfo->hook_entry[h] -= origsize - *size;
1627 if ((unsigned char *)de - base < newinfo->underflow[h])
1628 newinfo->underflow[h] -= origsize - *size;
1634 compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
1636 struct xt_entry_match *ematch;
1637 struct xt_mtchk_param mtpar;
1644 mtpar.entryinfo = &e->ip;
1645 mtpar.hook_mask = e->comefrom;
1646 mtpar.family = NFPROTO_IPV4;
1647 xt_ematch_foreach(ematch, e) {
1648 ret = check_match(ematch, &mtpar);
1650 goto cleanup_matches;
1654 ret = check_target(e, net, name);
1656 goto cleanup_matches;
1660 xt_ematch_foreach(ematch, e) {
1663 cleanup_match(ematch, net);
1669 translate_compat_table(struct net *net,
1671 unsigned int valid_hooks,
1672 struct xt_table_info **pinfo,
1674 unsigned int total_size,
1675 unsigned int number,
1676 unsigned int *hook_entries,
1677 unsigned int *underflows)
1680 struct xt_table_info *newinfo, *info;
1681 void *pos, *entry0, *entry1;
1682 struct compat_ipt_entry *iter0;
1683 struct ipt_entry *iter1;
1690 info->number = number;
1692 /* Init all hooks to impossible value. */
1693 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1694 info->hook_entry[i] = 0xFFFFFFFF;
1695 info->underflow[i] = 0xFFFFFFFF;
1698 duprintf("translate_compat_table: size %u\n", info->size);
1700 xt_compat_lock(AF_INET);
1701 /* Walk through entries, checking offsets. */
1702 xt_entry_foreach(iter0, entry0, total_size) {
1703 ret = check_compat_entry_size_and_hooks(iter0, info, &size,
1704 entry0, entry0 + total_size, hook_entries, underflows,
1713 duprintf("translate_compat_table: %u not %u entries\n",
1718 /* Check hooks all assigned */
1719 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1720 /* Only hooks which are valid */
1721 if (!(valid_hooks & (1 << i)))
1723 if (info->hook_entry[i] == 0xFFFFFFFF) {
1724 duprintf("Invalid hook entry %u %u\n",
1725 i, hook_entries[i]);
1728 if (info->underflow[i] == 0xFFFFFFFF) {
1729 duprintf("Invalid underflow %u %u\n",
1736 newinfo = xt_alloc_table_info(size);
1740 newinfo->number = number;
1741 for (i = 0; i < NF_INET_NUMHOOKS; i++) {
1742 newinfo->hook_entry[i] = info->hook_entry[i];
1743 newinfo->underflow[i] = info->underflow[i];
1745 entry1 = newinfo->entries[raw_smp_processor_id()];
1748 xt_entry_foreach(iter0, entry0, total_size) {
1749 ret = compat_copy_entry_from_user(iter0, &pos,
1750 &size, name, newinfo, entry1);
1754 xt_compat_flush_offsets(AF_INET);
1755 xt_compat_unlock(AF_INET);
1760 if (!mark_source_chains(newinfo, valid_hooks, entry1))
1764 xt_entry_foreach(iter1, entry1, newinfo->size) {
1765 ret = compat_check_entry(iter1, net, name);
1772 * The first i matches need cleanup_entry (calls ->destroy)
1773 * because they had called ->check already. The other j-i
1774 * entries need only release.
1778 xt_entry_foreach(iter0, entry0, newinfo->size) {
1783 compat_release_entry(iter0);
1785 xt_entry_foreach(iter1, entry1, newinfo->size) {
1788 cleanup_entry(iter1, net);
1790 xt_free_table_info(newinfo);
1794 /* And one copy for every other CPU */
1795 for_each_possible_cpu(i)
1796 if (newinfo->entries[i] && newinfo->entries[i] != entry1)
1797 memcpy(newinfo->entries[i], entry1, newinfo->size);
1801 xt_free_table_info(info);
1805 xt_free_table_info(newinfo);
1807 xt_entry_foreach(iter0, entry0, total_size) {
1810 compat_release_entry(iter0);
1814 xt_compat_flush_offsets(AF_INET);
1815 xt_compat_unlock(AF_INET);
1820 compat_do_replace(struct net *net, void __user *user, unsigned int len)
1823 struct compat_ipt_replace tmp;
1824 struct xt_table_info *newinfo;
1825 void *loc_cpu_entry;
1826 struct ipt_entry *iter;
1828 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
1831 /* overflow check */
1832 if (tmp.size >= INT_MAX / num_possible_cpus())
1834 if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters))
1837 newinfo = xt_alloc_table_info(tmp.size);
1841 /* choose the copy that is on our node/cpu */
1842 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
1843 if (copy_from_user(loc_cpu_entry, user + sizeof(tmp),
1849 ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
1850 &newinfo, &loc_cpu_entry, tmp.size,
1851 tmp.num_entries, tmp.hook_entry,
1856 duprintf("compat_do_replace: Translated table\n");
1858 ret = __do_replace(net, tmp.name, tmp.valid_hooks, newinfo,
1859 tmp.num_counters, compat_ptr(tmp.counters));
1861 goto free_newinfo_untrans;
1864 free_newinfo_untrans:
1865 xt_entry_foreach(iter, loc_cpu_entry, newinfo->size)
1866 cleanup_entry(iter, net);
1868 xt_free_table_info(newinfo);
1873 compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user,
1878 if (!capable(CAP_NET_ADMIN))
1882 case IPT_SO_SET_REPLACE:
1883 ret = compat_do_replace(sock_net(sk), user, len);
1886 case IPT_SO_SET_ADD_COUNTERS:
1887 ret = do_add_counters(sock_net(sk), user, len, 1);
1891 duprintf("do_ipt_set_ctl: unknown request %i\n", cmd);
1898 struct compat_ipt_get_entries {
1899 char name[IPT_TABLE_MAXNAMELEN];
1901 struct compat_ipt_entry entrytable[0];
1905 compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
1906 void __user *userptr)
1908 struct xt_counters *counters;
1909 const struct xt_table_info *private = table->private;
1913 const void *loc_cpu_entry;
1915 struct ipt_entry *iter;
1917 counters = alloc_counters(table);
1918 if (IS_ERR(counters))
1919 return PTR_ERR(counters);
1921 /* choose the copy that is on our node/cpu, ...
1922 * This choice is lazy (because current thread is
1923 * allowed to migrate to another cpu)
1925 loc_cpu_entry = private->entries[raw_smp_processor_id()];
1928 xt_entry_foreach(iter, loc_cpu_entry, total_size) {
1929 ret = compat_copy_entry_to_user(iter, &pos,
1930 &size, counters, i++);
1940 compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
1944 struct compat_ipt_get_entries get;
1947 if (*len < sizeof(get)) {
1948 duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
1952 if (copy_from_user(&get, uptr, sizeof(get)) != 0)
1955 if (*len != sizeof(struct compat_ipt_get_entries) + get.size) {
1956 duprintf("compat_get_entries: %u != %zu\n",
1957 *len, sizeof(get) + get.size);
1961 xt_compat_lock(AF_INET);
1962 t = xt_find_table_lock(net, AF_INET, get.name);
1963 if (t && !IS_ERR(t)) {
1964 const struct xt_table_info *private = t->private;
1965 struct xt_table_info info;
1966 duprintf("t->private->number = %u\n", private->number);
1967 ret = compat_table_info(private, &info);
1968 if (!ret && get.size == info.size) {
1969 ret = compat_copy_entries_to_user(private->size,
1970 t, uptr->entrytable);
1972 duprintf("compat_get_entries: I've got %u not %u!\n",
1973 private->size, get.size);
1976 xt_compat_flush_offsets(AF_INET);
1980 ret = t ? PTR_ERR(t) : -ENOENT;
1982 xt_compat_unlock(AF_INET);
1986 static int do_ipt_get_ctl(struct sock *, int, void __user *, int *);
1989 compat_do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
1993 if (!capable(CAP_NET_ADMIN))
1997 case IPT_SO_GET_INFO:
1998 ret = get_info(sock_net(sk), user, len, 1);
2000 case IPT_SO_GET_ENTRIES:
2001 ret = compat_get_entries(sock_net(sk), user, len);
2004 ret = do_ipt_get_ctl(sk, cmd, user, len);
2011 do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
2015 if (!capable(CAP_NET_ADMIN))
2019 case IPT_SO_SET_REPLACE:
2020 ret = do_replace(sock_net(sk), user, len);
2023 case IPT_SO_SET_ADD_COUNTERS:
2024 ret = do_add_counters(sock_net(sk), user, len, 0);
2028 duprintf("do_ipt_set_ctl: unknown request %i\n", cmd);
2036 do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2040 if (!capable(CAP_NET_ADMIN))
2044 case IPT_SO_GET_INFO:
2045 ret = get_info(sock_net(sk), user, len, 0);
2048 case IPT_SO_GET_ENTRIES:
2049 ret = get_entries(sock_net(sk), user, len);
2052 case IPT_SO_GET_REVISION_MATCH:
2053 case IPT_SO_GET_REVISION_TARGET: {
2054 struct ipt_get_revision rev;
2057 if (*len != sizeof(rev)) {
2061 if (copy_from_user(&rev, user, sizeof(rev)) != 0) {
2066 if (cmd == IPT_SO_GET_REVISION_TARGET)
2071 try_then_request_module(xt_find_revision(AF_INET, rev.name,
2074 "ipt_%s", rev.name);
2079 duprintf("do_ipt_get_ctl: unknown request %i\n", cmd);
2086 struct xt_table *ipt_register_table(struct net *net,
2087 const struct xt_table *table,
2088 const struct ipt_replace *repl)
2091 struct xt_table_info *newinfo;
2092 struct xt_table_info bootstrap
2093 = { 0, 0, 0, { 0 }, { 0 }, { } };
2094 void *loc_cpu_entry;
2095 struct xt_table *new_table;
2097 newinfo = xt_alloc_table_info(repl->size);
2103 /* choose the copy on our node/cpu, but dont care about preemption */
2104 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()];
2105 memcpy(loc_cpu_entry, repl->entries, repl->size);
2107 ret = translate_table(net, newinfo, loc_cpu_entry, repl);
2111 new_table = xt_register_table(net, table, &bootstrap, newinfo);
2112 if (IS_ERR(new_table)) {
2113 ret = PTR_ERR(new_table);
2120 xt_free_table_info(newinfo);
2122 return ERR_PTR(ret);
2125 void ipt_unregister_table(struct net *net, struct xt_table *table)
2127 struct xt_table_info *private;
2128 void *loc_cpu_entry;
2129 struct module *table_owner = table->me;
2130 struct ipt_entry *iter;
2132 private = xt_unregister_table(table);
2134 /* Decrease module usage counts and free resources */
2135 loc_cpu_entry = private->entries[raw_smp_processor_id()];
2136 xt_entry_foreach(iter, loc_cpu_entry, private->size)
2137 cleanup_entry(iter, net);
2138 if (private->number > private->initial_entries)
2139 module_put(table_owner);
2140 xt_free_table_info(private);
2143 /* Returns 1 if the type and code is matched by the range, 0 otherwise */
2145 icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2146 u_int8_t type, u_int8_t code,
2149 return ((test_type == 0xFF) ||
2150 (type == test_type && code >= min_code && code <= max_code))
2155 icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
2157 const struct icmphdr *ic;
2158 struct icmphdr _icmph;
2159 const struct ipt_icmp *icmpinfo = par->matchinfo;
2161 /* Must not be a fragment. */
2162 if (par->fragoff != 0)
2165 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2167 /* We've been asked to examine this packet, and we
2168 * can't. Hence, no choice but to drop.
2170 duprintf("Dropping evil ICMP tinygram.\n");
2171 *par->hotdrop = true;
2175 return icmp_type_code_match(icmpinfo->type,
2179 !!(icmpinfo->invflags&IPT_ICMP_INV));
2182 static bool icmp_checkentry(const struct xt_mtchk_param *par)
2184 const struct ipt_icmp *icmpinfo = par->matchinfo;
2186 /* Must specify no unknown invflags */
2187 return !(icmpinfo->invflags & ~IPT_ICMP_INV);
2190 /* The built-in targets: standard (NULL) and error. */
2191 static struct xt_target ipt_standard_target __read_mostly = {
2192 .name = IPT_STANDARD_TARGET,
2193 .targetsize = sizeof(int),
2194 .family = NFPROTO_IPV4,
2195 #ifdef CONFIG_COMPAT
2196 .compatsize = sizeof(compat_int_t),
2197 .compat_from_user = compat_standard_from_user,
2198 .compat_to_user = compat_standard_to_user,
2202 static struct xt_target ipt_error_target __read_mostly = {
2203 .name = IPT_ERROR_TARGET,
2204 .target = ipt_error,
2205 .targetsize = IPT_FUNCTION_MAXNAMELEN,
2206 .family = NFPROTO_IPV4,
2209 static struct nf_sockopt_ops ipt_sockopts = {
2211 .set_optmin = IPT_BASE_CTL,
2212 .set_optmax = IPT_SO_SET_MAX+1,
2213 .set = do_ipt_set_ctl,
2214 #ifdef CONFIG_COMPAT
2215 .compat_set = compat_do_ipt_set_ctl,
2217 .get_optmin = IPT_BASE_CTL,
2218 .get_optmax = IPT_SO_GET_MAX+1,
2219 .get = do_ipt_get_ctl,
2220 #ifdef CONFIG_COMPAT
2221 .compat_get = compat_do_ipt_get_ctl,
2223 .owner = THIS_MODULE,
2226 static struct xt_match icmp_matchstruct __read_mostly = {
2228 .match = icmp_match,
2229 .matchsize = sizeof(struct ipt_icmp),
2230 .checkentry = icmp_checkentry,
2231 .proto = IPPROTO_ICMP,
2232 .family = NFPROTO_IPV4,
2235 static int __net_init ip_tables_net_init(struct net *net)
2237 return xt_proto_init(net, NFPROTO_IPV4);
2240 static void __net_exit ip_tables_net_exit(struct net *net)
2242 xt_proto_fini(net, NFPROTO_IPV4);
2245 static struct pernet_operations ip_tables_net_ops = {
2246 .init = ip_tables_net_init,
2247 .exit = ip_tables_net_exit,
2250 static int __init ip_tables_init(void)
2254 ret = register_pernet_subsys(&ip_tables_net_ops);
2258 /* Noone else will be downing sem now, so we won't sleep */
2259 ret = xt_register_target(&ipt_standard_target);
2262 ret = xt_register_target(&ipt_error_target);
2265 ret = xt_register_match(&icmp_matchstruct);
2269 /* Register setsockopt */
2270 ret = nf_register_sockopt(&ipt_sockopts);
2274 printk(KERN_INFO "ip_tables: (C) 2000-2006 Netfilter Core Team\n");
2278 xt_unregister_match(&icmp_matchstruct);
2280 xt_unregister_target(&ipt_error_target);
2282 xt_unregister_target(&ipt_standard_target);
2284 unregister_pernet_subsys(&ip_tables_net_ops);
2289 static void __exit ip_tables_fini(void)
2291 nf_unregister_sockopt(&ipt_sockopts);
2293 xt_unregister_match(&icmp_matchstruct);
2294 xt_unregister_target(&ipt_error_target);
2295 xt_unregister_target(&ipt_standard_target);
2297 unregister_pernet_subsys(&ip_tables_net_ops);
2300 EXPORT_SYMBOL(ipt_register_table);
2301 EXPORT_SYMBOL(ipt_unregister_table);
2302 EXPORT_SYMBOL(ipt_do_table);
2303 module_init(ip_tables_init);
2304 module_exit(ip_tables_fini);