aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-08-10 11:14:59 -0400
committerPatrick McHardy <kaber@trash.net>2009-08-10 11:14:59 -0400
commitdc05a564ab1b3a1957927da50912964b61f7da69 (patch)
tree489905675f9954e5bf160a2eff6ea6ce93472d61 /net
parentbe39ee11cd1f67b51ac8e71d177a981eb34f2ab2 (diff)
parente2fe35c17fed62d4ab5038fa9bc489e967ff8416 (diff)
Merge branch 'master' of git://dev.medozas.de/linux
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/ebtable_filter.c6
-rw-r--r--net/bridge/netfilter/ebtable_nat.c6
-rw-r--r--net/ipv4/netfilter/arp_tables.c44
-rw-r--r--net/ipv4/netfilter/ip_tables.c48
-rw-r--r--net/ipv4/netfilter/iptable_filter.c8
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c12
-rw-r--r--net/ipv4/netfilter/iptable_raw.c6
-rw-r--r--net/ipv4/netfilter/iptable_security.c8
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c8
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c8
-rw-r--r--net/ipv6/netfilter/ip6_tables.c45
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c8
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c12
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c6
-rw-r--r--net/ipv6/netfilter/ip6table_security.c8
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c12
-rw-r--r--net/netfilter/xt_CONNMARK.c134
-rw-r--r--net/netfilter/xt_DSCP.c46
-rw-r--r--net/netfilter/xt_MARK.c163
-rw-r--r--net/netfilter/xt_connmark.c101
-rw-r--r--net/netfilter/xt_conntrack.c155
-rw-r--r--net/netfilter/xt_dscp.c17
-rw-r--r--net/netfilter/xt_iprange.c45
-rw-r--r--net/netfilter/xt_mark.c86
-rw-r--r--net/netfilter/xt_owner.c130
26 files changed, 204 insertions, 920 deletions
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index a5eea72938a6..4b988db3cd4d 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -77,21 +77,21 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
77 { 77 {
78 .hook = ebt_in_hook, 78 .hook = ebt_in_hook,
79 .owner = THIS_MODULE, 79 .owner = THIS_MODULE,
80 .pf = PF_BRIDGE, 80 .pf = NFPROTO_BRIDGE,
81 .hooknum = NF_BR_LOCAL_IN, 81 .hooknum = NF_BR_LOCAL_IN,
82 .priority = NF_BR_PRI_FILTER_BRIDGED, 82 .priority = NF_BR_PRI_FILTER_BRIDGED,
83 }, 83 },
84 { 84 {
85 .hook = ebt_in_hook, 85 .hook = ebt_in_hook,
86 .owner = THIS_MODULE, 86 .owner = THIS_MODULE,
87 .pf = PF_BRIDGE, 87 .pf = NFPROTO_BRIDGE,
88 .hooknum = NF_BR_FORWARD, 88 .hooknum = NF_BR_FORWARD,
89 .priority = NF_BR_PRI_FILTER_BRIDGED, 89 .priority = NF_BR_PRI_FILTER_BRIDGED,
90 }, 90 },
91 { 91 {
92 .hook = ebt_out_hook, 92 .hook = ebt_out_hook,
93 .owner = THIS_MODULE, 93 .owner = THIS_MODULE,
94 .pf = PF_BRIDGE, 94 .pf = NFPROTO_BRIDGE,
95 .hooknum = NF_BR_LOCAL_OUT, 95 .hooknum = NF_BR_LOCAL_OUT,
96 .priority = NF_BR_PRI_FILTER_OTHER, 96 .priority = NF_BR_PRI_FILTER_OTHER,
97 }, 97 },
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 6024c551f9a9..4a98804203b0 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -77,21 +77,21 @@ static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
77 { 77 {
78 .hook = ebt_nat_out, 78 .hook = ebt_nat_out,
79 .owner = THIS_MODULE, 79 .owner = THIS_MODULE,
80 .pf = PF_BRIDGE, 80 .pf = NFPROTO_BRIDGE,
81 .hooknum = NF_BR_LOCAL_OUT, 81 .hooknum = NF_BR_LOCAL_OUT,
82 .priority = NF_BR_PRI_NAT_DST_OTHER, 82 .priority = NF_BR_PRI_NAT_DST_OTHER,
83 }, 83 },
84 { 84 {
85 .hook = ebt_nat_out, 85 .hook = ebt_nat_out,
86 .owner = THIS_MODULE, 86 .owner = THIS_MODULE,
87 .pf = PF_BRIDGE, 87 .pf = NFPROTO_BRIDGE,
88 .hooknum = NF_BR_POST_ROUTING, 88 .hooknum = NF_BR_POST_ROUTING,
89 .priority = NF_BR_PRI_NAT_SRC, 89 .priority = NF_BR_PRI_NAT_SRC,
90 }, 90 },
91 { 91 {
92 .hook = ebt_nat_in, 92 .hook = ebt_nat_in,
93 .owner = THIS_MODULE, 93 .owner = THIS_MODULE,
94 .pf = PF_BRIDGE, 94 .pf = NFPROTO_BRIDGE,
95 .hooknum = NF_BR_PRE_ROUTING, 95 .hooknum = NF_BR_PRE_ROUTING,
96 .priority = NF_BR_PRI_NAT_DST_BRIDGED, 96 .priority = NF_BR_PRI_NAT_DST_BRIDGED,
97 }, 97 },
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7505dff4ffdf..7bc11ffbb845 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -8,7 +8,7 @@
8 * Copyright (C) 2002 David S. Miller (davem@redhat.com) 8 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
9 * 9 *
10 */ 10 */
11 11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/skbuff.h> 13#include <linux/skbuff.h>
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
@@ -341,15 +341,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
341} 341}
342 342
343/* All zeroes == unconditional rule. */ 343/* All zeroes == unconditional rule. */
344static inline int unconditional(const struct arpt_arp *arp) 344static inline bool unconditional(const struct arpt_arp *arp)
345{ 345{
346 unsigned int i; 346 static const struct arpt_arp uncond;
347 347
348 for (i = 0; i < sizeof(*arp)/sizeof(__u32); i++) 348 return memcmp(arp, &uncond, sizeof(uncond)) == 0;
349 if (((__u32 *)arp)[i])
350 return 0;
351
352 return 1;
353} 349}
354 350
355/* Figures out from what hook each rule can be called: returns 0 if 351/* Figures out from what hook each rule can be called: returns 0 if
@@ -537,12 +533,28 @@ out:
537 return ret; 533 return ret;
538} 534}
539 535
536static bool check_underflow(struct arpt_entry *e)
537{
538 const struct arpt_entry_target *t;
539 unsigned int verdict;
540
541 if (!unconditional(&e->arp))
542 return false;
543 t = arpt_get_target(e);
544 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
545 return false;
546 verdict = ((struct arpt_standard_target *)t)->verdict;
547 verdict = -verdict - 1;
548 return verdict == NF_DROP || verdict == NF_ACCEPT;
549}
550
540static inline int check_entry_size_and_hooks(struct arpt_entry *e, 551static inline int check_entry_size_and_hooks(struct arpt_entry *e,
541 struct xt_table_info *newinfo, 552 struct xt_table_info *newinfo,
542 unsigned char *base, 553 unsigned char *base,
543 unsigned char *limit, 554 unsigned char *limit,
544 const unsigned int *hook_entries, 555 const unsigned int *hook_entries,
545 const unsigned int *underflows, 556 const unsigned int *underflows,
557 unsigned int valid_hooks,
546 unsigned int *i) 558 unsigned int *i)
547{ 559{
548 unsigned int h; 560 unsigned int h;
@@ -562,15 +574,21 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
562 574
563 /* Check hooks & underflows */ 575 /* Check hooks & underflows */
564 for (h = 0; h < NF_ARP_NUMHOOKS; h++) { 576 for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
577 if (!(valid_hooks & (1 << h)))
578 continue;
565 if ((unsigned char *)e - base == hook_entries[h]) 579 if ((unsigned char *)e - base == hook_entries[h])
566 newinfo->hook_entry[h] = hook_entries[h]; 580 newinfo->hook_entry[h] = hook_entries[h];
567 if ((unsigned char *)e - base == underflows[h]) 581 if ((unsigned char *)e - base == underflows[h]) {
582 if (!check_underflow(e)) {
583 pr_err("Underflows must be unconditional and "
584 "use the STANDARD target with "
585 "ACCEPT/DROP\n");
586 return -EINVAL;
587 }
568 newinfo->underflow[h] = underflows[h]; 588 newinfo->underflow[h] = underflows[h];
589 }
569 } 590 }
570 591
571 /* FIXME: underflows must be unconditional, standard verdicts
572 < 0 (not ARPT_RETURN). --RR */
573
574 /* Clear counters and comefrom */ 592 /* Clear counters and comefrom */
575 e->counters = ((struct xt_counters) { 0, 0 }); 593 e->counters = ((struct xt_counters) { 0, 0 });
576 e->comefrom = 0; 594 e->comefrom = 0;
@@ -630,7 +648,7 @@ static int translate_table(const char *name,
630 newinfo, 648 newinfo,
631 entry0, 649 entry0,
632 entry0 + size, 650 entry0 + size,
633 hook_entries, underflows, &i); 651 hook_entries, underflows, valid_hooks, &i);
634 duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); 652 duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
635 if (ret != 0) 653 if (ret != 0)
636 return ret; 654 return ret;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index fdefae6b5dfc..0b43fd7ca04a 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -8,6 +8,7 @@
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11#include <linux/cache.h> 12#include <linux/cache.h>
12#include <linux/capability.h> 13#include <linux/capability.h>
13#include <linux/skbuff.h> 14#include <linux/skbuff.h>
@@ -190,16 +191,11 @@ get_entry(void *base, unsigned int offset)
190 191
191/* All zeroes == unconditional rule. */ 192/* All zeroes == unconditional rule. */
192/* Mildly perf critical (only if packet tracing is on) */ 193/* Mildly perf critical (only if packet tracing is on) */
193static inline int 194static inline bool unconditional(const struct ipt_ip *ip)
194unconditional(const struct ipt_ip *ip)
195{ 195{
196 unsigned int i; 196 static const struct ipt_ip uncond;
197
198 for (i = 0; i < sizeof(*ip)/sizeof(__u32); i++)
199 if (((__u32 *)ip)[i])
200 return 0;
201 197
202 return 1; 198 return memcmp(ip, &uncond, sizeof(uncond)) == 0;
203#undef FWINV 199#undef FWINV
204} 200}
205 201
@@ -315,7 +311,6 @@ ipt_do_table(struct sk_buff *skb,
315 311
316 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 312 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
317 const struct iphdr *ip; 313 const struct iphdr *ip;
318 u_int16_t datalen;
319 bool hotdrop = false; 314 bool hotdrop = false;
320 /* Initializing verdict to NF_DROP keeps gcc happy. */ 315 /* Initializing verdict to NF_DROP keeps gcc happy. */
321 unsigned int verdict = NF_DROP; 316 unsigned int verdict = NF_DROP;
@@ -328,7 +323,6 @@ ipt_do_table(struct sk_buff *skb,
328 323
329 /* Initialization */ 324 /* Initialization */
330 ip = ip_hdr(skb); 325 ip = ip_hdr(skb);
331 datalen = skb->len - ip->ihl * 4;
332 indev = in ? in->name : nulldevname; 326 indev = in ? in->name : nulldevname;
333 outdev = out ? out->name : nulldevname; 327 outdev = out ? out->name : nulldevname;
334 /* We handle fragments by dealing with the first fragment as 328 /* We handle fragments by dealing with the first fragment as
@@ -427,8 +421,6 @@ ipt_do_table(struct sk_buff *skb,
427#endif 421#endif
428 /* Target might have changed stuff. */ 422 /* Target might have changed stuff. */
429 ip = ip_hdr(skb); 423 ip = ip_hdr(skb);
430 datalen = skb->len - ip->ihl * 4;
431
432 if (verdict == IPT_CONTINUE) 424 if (verdict == IPT_CONTINUE)
433 e = ipt_next_entry(e); 425 e = ipt_next_entry(e);
434 else 426 else
@@ -716,6 +708,21 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
716 return ret; 708 return ret;
717} 709}
718 710
711static bool check_underflow(struct ipt_entry *e)
712{
713 const struct ipt_entry_target *t;
714 unsigned int verdict;
715
716 if (!unconditional(&e->ip))
717 return false;
718 t = ipt_get_target(e);
719 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
720 return false;
721 verdict = ((struct ipt_standard_target *)t)->verdict;
722 verdict = -verdict - 1;
723 return verdict == NF_DROP || verdict == NF_ACCEPT;
724}
725
719static int 726static int
720check_entry_size_and_hooks(struct ipt_entry *e, 727check_entry_size_and_hooks(struct ipt_entry *e,
721 struct xt_table_info *newinfo, 728 struct xt_table_info *newinfo,
@@ -723,6 +730,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
723 unsigned char *limit, 730 unsigned char *limit,
724 const unsigned int *hook_entries, 731 const unsigned int *hook_entries,
725 const unsigned int *underflows, 732 const unsigned int *underflows,
733 unsigned int valid_hooks,
726 unsigned int *i) 734 unsigned int *i)
727{ 735{
728 unsigned int h; 736 unsigned int h;
@@ -742,15 +750,21 @@ check_entry_size_and_hooks(struct ipt_entry *e,
742 750
743 /* Check hooks & underflows */ 751 /* Check hooks & underflows */
744 for (h = 0; h < NF_INET_NUMHOOKS; h++) { 752 for (h = 0; h < NF_INET_NUMHOOKS; h++) {
753 if (!(valid_hooks & (1 << h)))
754 continue;
745 if ((unsigned char *)e - base == hook_entries[h]) 755 if ((unsigned char *)e - base == hook_entries[h])
746 newinfo->hook_entry[h] = hook_entries[h]; 756 newinfo->hook_entry[h] = hook_entries[h];
747 if ((unsigned char *)e - base == underflows[h]) 757 if ((unsigned char *)e - base == underflows[h]) {
758 if (!check_underflow(e)) {
759 pr_err("Underflows must be unconditional and "
760 "use the STANDARD target with "
761 "ACCEPT/DROP\n");
762 return -EINVAL;
763 }
748 newinfo->underflow[h] = underflows[h]; 764 newinfo->underflow[h] = underflows[h];
765 }
749 } 766 }
750 767
751 /* FIXME: underflows must be unconditional, standard verdicts
752 < 0 (not IPT_RETURN). --RR */
753
754 /* Clear counters and comefrom */ 768 /* Clear counters and comefrom */
755 e->counters = ((struct xt_counters) { 0, 0 }); 769 e->counters = ((struct xt_counters) { 0, 0 });
756 e->comefrom = 0; 770 e->comefrom = 0;
@@ -813,7 +827,7 @@ translate_table(const char *name,
813 newinfo, 827 newinfo,
814 entry0, 828 entry0,
815 entry0 + size, 829 entry0 + size,
816 hook_entries, underflows, &i); 830 hook_entries, underflows, valid_hooks, &i);
817 if (ret != 0) 831 if (ret != 0)
818 return ret; 832 return ret;
819 833
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index c30a969724f8..97dbd94a8e37 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -57,7 +57,7 @@ static struct xt_table packet_filter = {
57 .name = "filter", 57 .name = "filter",
58 .valid_hooks = FILTER_VALID_HOOKS, 58 .valid_hooks = FILTER_VALID_HOOKS,
59 .me = THIS_MODULE, 59 .me = THIS_MODULE,
60 .af = AF_INET, 60 .af = NFPROTO_IPV4,
61}; 61};
62 62
63/* The work comes in here from netfilter.c. */ 63/* The work comes in here from netfilter.c. */
@@ -102,21 +102,21 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
102 { 102 {
103 .hook = ipt_local_in_hook, 103 .hook = ipt_local_in_hook,
104 .owner = THIS_MODULE, 104 .owner = THIS_MODULE,
105 .pf = PF_INET, 105 .pf = NFPROTO_IPV4,
106 .hooknum = NF_INET_LOCAL_IN, 106 .hooknum = NF_INET_LOCAL_IN,
107 .priority = NF_IP_PRI_FILTER, 107 .priority = NF_IP_PRI_FILTER,
108 }, 108 },
109 { 109 {
110 .hook = ipt_hook, 110 .hook = ipt_hook,
111 .owner = THIS_MODULE, 111 .owner = THIS_MODULE,
112 .pf = PF_INET, 112 .pf = NFPROTO_IPV4,
113 .hooknum = NF_INET_FORWARD, 113 .hooknum = NF_INET_FORWARD,
114 .priority = NF_IP_PRI_FILTER, 114 .priority = NF_IP_PRI_FILTER,
115 }, 115 },
116 { 116 {
117 .hook = ipt_local_out_hook, 117 .hook = ipt_local_out_hook,
118 .owner = THIS_MODULE, 118 .owner = THIS_MODULE,
119 .pf = PF_INET, 119 .pf = NFPROTO_IPV4,
120 .hooknum = NF_INET_LOCAL_OUT, 120 .hooknum = NF_INET_LOCAL_OUT,
121 .priority = NF_IP_PRI_FILTER, 121 .priority = NF_IP_PRI_FILTER,
122 }, 122 },
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 4087614d9519..28647f10aa7e 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -68,7 +68,7 @@ static struct xt_table packet_mangler = {
68 .name = "mangle", 68 .name = "mangle",
69 .valid_hooks = MANGLE_VALID_HOOKS, 69 .valid_hooks = MANGLE_VALID_HOOKS,
70 .me = THIS_MODULE, 70 .me = THIS_MODULE,
71 .af = AF_INET, 71 .af = NFPROTO_IPV4,
72}; 72};
73 73
74/* The work comes in here from netfilter.c. */ 74/* The work comes in here from netfilter.c. */
@@ -162,35 +162,35 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
162 { 162 {
163 .hook = ipt_pre_routing_hook, 163 .hook = ipt_pre_routing_hook,
164 .owner = THIS_MODULE, 164 .owner = THIS_MODULE,
165 .pf = PF_INET, 165 .pf = NFPROTO_IPV4,
166 .hooknum = NF_INET_PRE_ROUTING, 166 .hooknum = NF_INET_PRE_ROUTING,
167 .priority = NF_IP_PRI_MANGLE, 167 .priority = NF_IP_PRI_MANGLE,
168 }, 168 },
169 { 169 {
170 .hook = ipt_local_in_hook, 170 .hook = ipt_local_in_hook,
171 .owner = THIS_MODULE, 171 .owner = THIS_MODULE,
172 .pf = PF_INET, 172 .pf = NFPROTO_IPV4,
173 .hooknum = NF_INET_LOCAL_IN, 173 .hooknum = NF_INET_LOCAL_IN,
174 .priority = NF_IP_PRI_MANGLE, 174 .priority = NF_IP_PRI_MANGLE,
175 }, 175 },
176 { 176 {
177 .hook = ipt_forward_hook, 177 .hook = ipt_forward_hook,
178 .owner = THIS_MODULE, 178 .owner = THIS_MODULE,
179 .pf = PF_INET, 179 .pf = NFPROTO_IPV4,
180 .hooknum = NF_INET_FORWARD, 180 .hooknum = NF_INET_FORWARD,
181 .priority = NF_IP_PRI_MANGLE, 181 .priority = NF_IP_PRI_MANGLE,
182 }, 182 },
183 { 183 {
184 .hook = ipt_local_hook, 184 .hook = ipt_local_hook,
185 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
186 .pf = PF_INET, 186 .pf = NFPROTO_IPV4,
187 .hooknum = NF_INET_LOCAL_OUT, 187 .hooknum = NF_INET_LOCAL_OUT,
188 .priority = NF_IP_PRI_MANGLE, 188 .priority = NF_IP_PRI_MANGLE,
189 }, 189 },
190 { 190 {
191 .hook = ipt_post_routing_hook, 191 .hook = ipt_post_routing_hook,
192 .owner = THIS_MODULE, 192 .owner = THIS_MODULE,
193 .pf = PF_INET, 193 .pf = NFPROTO_IPV4,
194 .hooknum = NF_INET_POST_ROUTING, 194 .hooknum = NF_INET_POST_ROUTING,
195 .priority = NF_IP_PRI_MANGLE, 195 .priority = NF_IP_PRI_MANGLE,
196 }, 196 },
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index e5356da1fb54..494784c999eb 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -40,7 +40,7 @@ static struct xt_table packet_raw = {
40 .name = "raw", 40 .name = "raw",
41 .valid_hooks = RAW_VALID_HOOKS, 41 .valid_hooks = RAW_VALID_HOOKS,
42 .me = THIS_MODULE, 42 .me = THIS_MODULE,
43 .af = AF_INET, 43 .af = NFPROTO_IPV4,
44}; 44};
45 45
46/* The work comes in here from netfilter.c. */ 46/* The work comes in here from netfilter.c. */
@@ -74,14 +74,14 @@ ipt_local_hook(unsigned int hook,
74static struct nf_hook_ops ipt_ops[] __read_mostly = { 74static struct nf_hook_ops ipt_ops[] __read_mostly = {
75 { 75 {
76 .hook = ipt_hook, 76 .hook = ipt_hook,
77 .pf = PF_INET, 77 .pf = NFPROTO_IPV4,
78 .hooknum = NF_INET_PRE_ROUTING, 78 .hooknum = NF_INET_PRE_ROUTING,
79 .priority = NF_IP_PRI_RAW, 79 .priority = NF_IP_PRI_RAW,
80 .owner = THIS_MODULE, 80 .owner = THIS_MODULE,
81 }, 81 },
82 { 82 {
83 .hook = ipt_local_hook, 83 .hook = ipt_local_hook,
84 .pf = PF_INET, 84 .pf = NFPROTO_IPV4,
85 .hooknum = NF_INET_LOCAL_OUT, 85 .hooknum = NF_INET_LOCAL_OUT,
86 .priority = NF_IP_PRI_RAW, 86 .priority = NF_IP_PRI_RAW,
87 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index 29ab630f240a..8804e1a0f915 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -61,7 +61,7 @@ static struct xt_table security_table = {
61 .name = "security", 61 .name = "security",
62 .valid_hooks = SECURITY_VALID_HOOKS, 62 .valid_hooks = SECURITY_VALID_HOOKS,
63 .me = THIS_MODULE, 63 .me = THIS_MODULE,
64 .af = AF_INET, 64 .af = NFPROTO_IPV4,
65}; 65};
66 66
67static unsigned int 67static unsigned int
@@ -105,21 +105,21 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
105 { 105 {
106 .hook = ipt_local_in_hook, 106 .hook = ipt_local_in_hook,
107 .owner = THIS_MODULE, 107 .owner = THIS_MODULE,
108 .pf = PF_INET, 108 .pf = NFPROTO_IPV4,
109 .hooknum = NF_INET_LOCAL_IN, 109 .hooknum = NF_INET_LOCAL_IN,
110 .priority = NF_IP_PRI_SECURITY, 110 .priority = NF_IP_PRI_SECURITY,
111 }, 111 },
112 { 112 {
113 .hook = ipt_forward_hook, 113 .hook = ipt_forward_hook,
114 .owner = THIS_MODULE, 114 .owner = THIS_MODULE,
115 .pf = PF_INET, 115 .pf = NFPROTO_IPV4,
116 .hooknum = NF_INET_FORWARD, 116 .hooknum = NF_INET_FORWARD,
117 .priority = NF_IP_PRI_SECURITY, 117 .priority = NF_IP_PRI_SECURITY,
118 }, 118 },
119 { 119 {
120 .hook = ipt_local_out_hook, 120 .hook = ipt_local_out_hook,
121 .owner = THIS_MODULE, 121 .owner = THIS_MODULE,
122 .pf = PF_INET, 122 .pf = NFPROTO_IPV4,
123 .hooknum = NF_INET_LOCAL_OUT, 123 .hooknum = NF_INET_LOCAL_OUT,
124 .priority = NF_IP_PRI_SECURITY, 124 .priority = NF_IP_PRI_SECURITY,
125 }, 125 },
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 05a9bc8df536..9ac2fdc36ecc 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -158,28 +158,28 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
158 { 158 {
159 .hook = ipv4_conntrack_in, 159 .hook = ipv4_conntrack_in,
160 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
161 .pf = PF_INET, 161 .pf = NFPROTO_IPV4,
162 .hooknum = NF_INET_PRE_ROUTING, 162 .hooknum = NF_INET_PRE_ROUTING,
163 .priority = NF_IP_PRI_CONNTRACK, 163 .priority = NF_IP_PRI_CONNTRACK,
164 }, 164 },
165 { 165 {
166 .hook = ipv4_conntrack_local, 166 .hook = ipv4_conntrack_local,
167 .owner = THIS_MODULE, 167 .owner = THIS_MODULE,
168 .pf = PF_INET, 168 .pf = NFPROTO_IPV4,
169 .hooknum = NF_INET_LOCAL_OUT, 169 .hooknum = NF_INET_LOCAL_OUT,
170 .priority = NF_IP_PRI_CONNTRACK, 170 .priority = NF_IP_PRI_CONNTRACK,
171 }, 171 },
172 { 172 {
173 .hook = ipv4_confirm, 173 .hook = ipv4_confirm,
174 .owner = THIS_MODULE, 174 .owner = THIS_MODULE,
175 .pf = PF_INET, 175 .pf = NFPROTO_IPV4,
176 .hooknum = NF_INET_POST_ROUTING, 176 .hooknum = NF_INET_POST_ROUTING,
177 .priority = NF_IP_PRI_CONNTRACK_CONFIRM, 177 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
178 }, 178 },
179 { 179 {
180 .hook = ipv4_confirm, 180 .hook = ipv4_confirm,
181 .owner = THIS_MODULE, 181 .owner = THIS_MODULE,
182 .pf = PF_INET, 182 .pf = NFPROTO_IPV4,
183 .hooknum = NF_INET_LOCAL_IN, 183 .hooknum = NF_INET_LOCAL_IN,
184 .priority = NF_IP_PRI_CONNTRACK_CONFIRM, 184 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
185 }, 185 },
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 6348a793936e..6448a9b7d6f0 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -62,7 +62,7 @@ static struct xt_table nat_table = {
62 .name = "nat", 62 .name = "nat",
63 .valid_hooks = NAT_VALID_HOOKS, 63 .valid_hooks = NAT_VALID_HOOKS,
64 .me = THIS_MODULE, 64 .me = THIS_MODULE,
65 .af = AF_INET, 65 .af = NFPROTO_IPV4,
66}; 66};
67 67
68/* Source NAT */ 68/* Source NAT */
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
index 5567bd0d0750..5f41d017ddd8 100644
--- a/net/ipv4/netfilter/nf_nat_standalone.c
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -251,7 +251,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
251 { 251 {
252 .hook = nf_nat_in, 252 .hook = nf_nat_in,
253 .owner = THIS_MODULE, 253 .owner = THIS_MODULE,
254 .pf = PF_INET, 254 .pf = NFPROTO_IPV4,
255 .hooknum = NF_INET_PRE_ROUTING, 255 .hooknum = NF_INET_PRE_ROUTING,
256 .priority = NF_IP_PRI_NAT_DST, 256 .priority = NF_IP_PRI_NAT_DST,
257 }, 257 },
@@ -259,7 +259,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
259 { 259 {
260 .hook = nf_nat_out, 260 .hook = nf_nat_out,
261 .owner = THIS_MODULE, 261 .owner = THIS_MODULE,
262 .pf = PF_INET, 262 .pf = NFPROTO_IPV4,
263 .hooknum = NF_INET_POST_ROUTING, 263 .hooknum = NF_INET_POST_ROUTING,
264 .priority = NF_IP_PRI_NAT_SRC, 264 .priority = NF_IP_PRI_NAT_SRC,
265 }, 265 },
@@ -267,7 +267,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
267 { 267 {
268 .hook = nf_nat_local_fn, 268 .hook = nf_nat_local_fn,
269 .owner = THIS_MODULE, 269 .owner = THIS_MODULE,
270 .pf = PF_INET, 270 .pf = NFPROTO_IPV4,
271 .hooknum = NF_INET_LOCAL_OUT, 271 .hooknum = NF_INET_LOCAL_OUT,
272 .priority = NF_IP_PRI_NAT_DST, 272 .priority = NF_IP_PRI_NAT_DST,
273 }, 273 },
@@ -275,7 +275,7 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
275 { 275 {
276 .hook = nf_nat_fn, 276 .hook = nf_nat_fn,
277 .owner = THIS_MODULE, 277 .owner = THIS_MODULE,
278 .pf = PF_INET, 278 .pf = NFPROTO_IPV4,
279 .hooknum = NF_INET_LOCAL_IN, 279 .hooknum = NF_INET_LOCAL_IN,
280 .priority = NF_IP_PRI_NAT_SRC, 280 .priority = NF_IP_PRI_NAT_SRC,
281 }, 281 },
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index ced1f2c0cb65..a5d0c27cc26f 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -8,7 +8,7 @@
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12#include <linux/capability.h> 12#include <linux/capability.h>
13#include <linux/in.h> 13#include <linux/in.h>
14#include <linux/skbuff.h> 14#include <linux/skbuff.h>
@@ -222,16 +222,11 @@ get_entry(void *base, unsigned int offset)
222 222
223/* All zeroes == unconditional rule. */ 223/* All zeroes == unconditional rule. */
224/* Mildly perf critical (only if packet tracing is on) */ 224/* Mildly perf critical (only if packet tracing is on) */
225static inline int 225static inline bool unconditional(const struct ip6t_ip6 *ipv6)
226unconditional(const struct ip6t_ip6 *ipv6)
227{ 226{
228 unsigned int i; 227 static const struct ip6t_ip6 uncond;
229
230 for (i = 0; i < sizeof(*ipv6); i++)
231 if (((char *)ipv6)[i])
232 break;
233 228
234 return (i == sizeof(*ipv6)); 229 return memcmp(ipv6, &uncond, sizeof(uncond)) == 0;
235} 230}
236 231
237#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ 232#if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
@@ -745,6 +740,21 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
745 return ret; 740 return ret;
746} 741}
747 742
743static bool check_underflow(struct ip6t_entry *e)
744{
745 const struct ip6t_entry_target *t;
746 unsigned int verdict;
747
748 if (!unconditional(&e->ipv6))
749 return false;
750 t = ip6t_get_target(e);
751 if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0)
752 return false;
753 verdict = ((struct ip6t_standard_target *)t)->verdict;
754 verdict = -verdict - 1;
755 return verdict == NF_DROP || verdict == NF_ACCEPT;
756}
757
748static int 758static int
749check_entry_size_and_hooks(struct ip6t_entry *e, 759check_entry_size_and_hooks(struct ip6t_entry *e,
750 struct xt_table_info *newinfo, 760 struct xt_table_info *newinfo,
@@ -752,6 +762,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
752 unsigned char *limit, 762 unsigned char *limit,
753 const unsigned int *hook_entries, 763 const unsigned int *hook_entries,
754 const unsigned int *underflows, 764 const unsigned int *underflows,
765 unsigned int valid_hooks,
755 unsigned int *i) 766 unsigned int *i)
756{ 767{
757 unsigned int h; 768 unsigned int h;
@@ -771,15 +782,21 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
771 782
772 /* Check hooks & underflows */ 783 /* Check hooks & underflows */
773 for (h = 0; h < NF_INET_NUMHOOKS; h++) { 784 for (h = 0; h < NF_INET_NUMHOOKS; h++) {
785 if (!(valid_hooks & (1 << h)))
786 continue;
774 if ((unsigned char *)e - base == hook_entries[h]) 787 if ((unsigned char *)e - base == hook_entries[h])
775 newinfo->hook_entry[h] = hook_entries[h]; 788 newinfo->hook_entry[h] = hook_entries[h];
776 if ((unsigned char *)e - base == underflows[h]) 789 if ((unsigned char *)e - base == underflows[h]) {
790 if (!check_underflow(e)) {
791 pr_err("Underflows must be unconditional and "
792 "use the STANDARD target with "
793 "ACCEPT/DROP\n");
794 return -EINVAL;
795 }
777 newinfo->underflow[h] = underflows[h]; 796 newinfo->underflow[h] = underflows[h];
797 }
778 } 798 }
779 799
780 /* FIXME: underflows must be unconditional, standard verdicts
781 < 0 (not IP6T_RETURN). --RR */
782
783 /* Clear counters and comefrom */ 800 /* Clear counters and comefrom */
784 e->counters = ((struct xt_counters) { 0, 0 }); 801 e->counters = ((struct xt_counters) { 0, 0 });
785 e->comefrom = 0; 802 e->comefrom = 0;
@@ -842,7 +859,7 @@ translate_table(const char *name,
842 newinfo, 859 newinfo,
843 entry0, 860 entry0,
844 entry0 + size, 861 entry0 + size,
845 hook_entries, underflows, &i); 862 hook_entries, underflows, valid_hooks, &i);
846 if (ret != 0) 863 if (ret != 0)
847 return ret; 864 return ret;
848 865
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ef5a0a32bf8e..0a3ae48ac4d5 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -55,7 +55,7 @@ static struct xt_table packet_filter = {
55 .name = "filter", 55 .name = "filter",
56 .valid_hooks = FILTER_VALID_HOOKS, 56 .valid_hooks = FILTER_VALID_HOOKS,
57 .me = THIS_MODULE, 57 .me = THIS_MODULE,
58 .af = AF_INET6, 58 .af = NFPROTO_IPV6,
59}; 59};
60 60
61/* The work comes in here from netfilter.c. */ 61/* The work comes in here from netfilter.c. */
@@ -95,21 +95,21 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
95 { 95 {
96 .hook = ip6t_in_hook, 96 .hook = ip6t_in_hook,
97 .owner = THIS_MODULE, 97 .owner = THIS_MODULE,
98 .pf = PF_INET6, 98 .pf = NFPROTO_IPV6,
99 .hooknum = NF_INET_LOCAL_IN, 99 .hooknum = NF_INET_LOCAL_IN,
100 .priority = NF_IP6_PRI_FILTER, 100 .priority = NF_IP6_PRI_FILTER,
101 }, 101 },
102 { 102 {
103 .hook = ip6t_in_hook, 103 .hook = ip6t_in_hook,
104 .owner = THIS_MODULE, 104 .owner = THIS_MODULE,
105 .pf = PF_INET6, 105 .pf = NFPROTO_IPV6,
106 .hooknum = NF_INET_FORWARD, 106 .hooknum = NF_INET_FORWARD,
107 .priority = NF_IP6_PRI_FILTER, 107 .priority = NF_IP6_PRI_FILTER,
108 }, 108 },
109 { 109 {
110 .hook = ip6t_local_out_hook, 110 .hook = ip6t_local_out_hook,
111 .owner = THIS_MODULE, 111 .owner = THIS_MODULE,
112 .pf = PF_INET6, 112 .pf = NFPROTO_IPV6,
113 .hooknum = NF_INET_LOCAL_OUT, 113 .hooknum = NF_INET_LOCAL_OUT,
114 .priority = NF_IP6_PRI_FILTER, 114 .priority = NF_IP6_PRI_FILTER,
115 }, 115 },
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index ab0d398a2ba7..0f49e005a8c5 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -61,7 +61,7 @@ static struct xt_table packet_mangler = {
61 .name = "mangle", 61 .name = "mangle",
62 .valid_hooks = MANGLE_VALID_HOOKS, 62 .valid_hooks = MANGLE_VALID_HOOKS,
63 .me = THIS_MODULE, 63 .me = THIS_MODULE,
64 .af = AF_INET6, 64 .af = NFPROTO_IPV6,
65}; 65};
66 66
67/* The work comes in here from netfilter.c. */ 67/* The work comes in here from netfilter.c. */
@@ -136,35 +136,35 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
136 { 136 {
137 .hook = ip6t_in_hook, 137 .hook = ip6t_in_hook,
138 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
139 .pf = PF_INET6, 139 .pf = NFPROTO_IPV6,
140 .hooknum = NF_INET_PRE_ROUTING, 140 .hooknum = NF_INET_PRE_ROUTING,
141 .priority = NF_IP6_PRI_MANGLE, 141 .priority = NF_IP6_PRI_MANGLE,
142 }, 142 },
143 { 143 {
144 .hook = ip6t_in_hook, 144 .hook = ip6t_in_hook,
145 .owner = THIS_MODULE, 145 .owner = THIS_MODULE,
146 .pf = PF_INET6, 146 .pf = NFPROTO_IPV6,
147 .hooknum = NF_INET_LOCAL_IN, 147 .hooknum = NF_INET_LOCAL_IN,
148 .priority = NF_IP6_PRI_MANGLE, 148 .priority = NF_IP6_PRI_MANGLE,
149 }, 149 },
150 { 150 {
151 .hook = ip6t_in_hook, 151 .hook = ip6t_in_hook,
152 .owner = THIS_MODULE, 152 .owner = THIS_MODULE,
153 .pf = PF_INET6, 153 .pf = NFPROTO_IPV6,
154 .hooknum = NF_INET_FORWARD, 154 .hooknum = NF_INET_FORWARD,
155 .priority = NF_IP6_PRI_MANGLE, 155 .priority = NF_IP6_PRI_MANGLE,
156 }, 156 },
157 { 157 {
158 .hook = ip6t_local_out_hook, 158 .hook = ip6t_local_out_hook,
159 .owner = THIS_MODULE, 159 .owner = THIS_MODULE,
160 .pf = PF_INET6, 160 .pf = NFPROTO_IPV6,
161 .hooknum = NF_INET_LOCAL_OUT, 161 .hooknum = NF_INET_LOCAL_OUT,
162 .priority = NF_IP6_PRI_MANGLE, 162 .priority = NF_IP6_PRI_MANGLE,
163 }, 163 },
164 { 164 {
165 .hook = ip6t_post_routing_hook, 165 .hook = ip6t_post_routing_hook,
166 .owner = THIS_MODULE, 166 .owner = THIS_MODULE,
167 .pf = PF_INET6, 167 .pf = NFPROTO_IPV6,
168 .hooknum = NF_INET_POST_ROUTING, 168 .hooknum = NF_INET_POST_ROUTING,
169 .priority = NF_IP6_PRI_MANGLE, 169 .priority = NF_IP6_PRI_MANGLE,
170 }, 170 },
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 4b792b6ca321..679865e3d5ff 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -39,7 +39,7 @@ static struct xt_table packet_raw = {
39 .name = "raw", 39 .name = "raw",
40 .valid_hooks = RAW_VALID_HOOKS, 40 .valid_hooks = RAW_VALID_HOOKS,
41 .me = THIS_MODULE, 41 .me = THIS_MODULE,
42 .af = AF_INET6, 42 .af = NFPROTO_IPV6,
43}; 43};
44 44
45/* The work comes in here from netfilter.c. */ 45/* The work comes in here from netfilter.c. */
@@ -68,14 +68,14 @@ ip6t_local_out_hook(unsigned int hook,
68static struct nf_hook_ops ip6t_ops[] __read_mostly = { 68static struct nf_hook_ops ip6t_ops[] __read_mostly = {
69 { 69 {
70 .hook = ip6t_pre_routing_hook, 70 .hook = ip6t_pre_routing_hook,
71 .pf = PF_INET6, 71 .pf = NFPROTO_IPV6,
72 .hooknum = NF_INET_PRE_ROUTING, 72 .hooknum = NF_INET_PRE_ROUTING,
73 .priority = NF_IP6_PRI_FIRST, 73 .priority = NF_IP6_PRI_FIRST,
74 .owner = THIS_MODULE, 74 .owner = THIS_MODULE,
75 }, 75 },
76 { 76 {
77 .hook = ip6t_local_out_hook, 77 .hook = ip6t_local_out_hook,
78 .pf = PF_INET6, 78 .pf = NFPROTO_IPV6,
79 .hooknum = NF_INET_LOCAL_OUT, 79 .hooknum = NF_INET_LOCAL_OUT,
80 .priority = NF_IP6_PRI_FIRST, 80 .priority = NF_IP6_PRI_FIRST,
81 .owner = THIS_MODULE, 81 .owner = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 0ea37ff15d56..822afabbdc88 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -60,7 +60,7 @@ static struct xt_table security_table = {
60 .name = "security", 60 .name = "security",
61 .valid_hooks = SECURITY_VALID_HOOKS, 61 .valid_hooks = SECURITY_VALID_HOOKS,
62 .me = THIS_MODULE, 62 .me = THIS_MODULE,
63 .af = AF_INET6, 63 .af = NFPROTO_IPV6,
64}; 64};
65 65
66static unsigned int 66static unsigned int
@@ -101,21 +101,21 @@ static struct nf_hook_ops ip6t_ops[] __read_mostly = {
101 { 101 {
102 .hook = ip6t_local_in_hook, 102 .hook = ip6t_local_in_hook,
103 .owner = THIS_MODULE, 103 .owner = THIS_MODULE,
104 .pf = PF_INET6, 104 .pf = NFPROTO_IPV6,
105 .hooknum = NF_INET_LOCAL_IN, 105 .hooknum = NF_INET_LOCAL_IN,
106 .priority = NF_IP6_PRI_SECURITY, 106 .priority = NF_IP6_PRI_SECURITY,
107 }, 107 },
108 { 108 {
109 .hook = ip6t_forward_hook, 109 .hook = ip6t_forward_hook,
110 .owner = THIS_MODULE, 110 .owner = THIS_MODULE,
111 .pf = PF_INET6, 111 .pf = NFPROTO_IPV6,
112 .hooknum = NF_INET_FORWARD, 112 .hooknum = NF_INET_FORWARD,
113 .priority = NF_IP6_PRI_SECURITY, 113 .priority = NF_IP6_PRI_SECURITY,
114 }, 114 },
115 { 115 {
116 .hook = ip6t_local_out_hook, 116 .hook = ip6t_local_out_hook,
117 .owner = THIS_MODULE, 117 .owner = THIS_MODULE,
118 .pf = PF_INET6, 118 .pf = NFPROTO_IPV6,
119 .hooknum = NF_INET_LOCAL_OUT, 119 .hooknum = NF_INET_LOCAL_OUT,
120 .priority = NF_IP6_PRI_SECURITY, 120 .priority = NF_IP6_PRI_SECURITY,
121 }, 121 },
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 2a15c2d66c69..a7f4cd607356 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -265,42 +265,42 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
265 { 265 {
266 .hook = ipv6_defrag, 266 .hook = ipv6_defrag,
267 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
268 .pf = PF_INET6, 268 .pf = NFPROTO_IPV6,
269 .hooknum = NF_INET_PRE_ROUTING, 269 .hooknum = NF_INET_PRE_ROUTING,
270 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, 270 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
271 }, 271 },
272 { 272 {
273 .hook = ipv6_conntrack_in, 273 .hook = ipv6_conntrack_in,
274 .owner = THIS_MODULE, 274 .owner = THIS_MODULE,
275 .pf = PF_INET6, 275 .pf = NFPROTO_IPV6,
276 .hooknum = NF_INET_PRE_ROUTING, 276 .hooknum = NF_INET_PRE_ROUTING,
277 .priority = NF_IP6_PRI_CONNTRACK, 277 .priority = NF_IP6_PRI_CONNTRACK,
278 }, 278 },
279 { 279 {
280 .hook = ipv6_conntrack_local, 280 .hook = ipv6_conntrack_local,
281 .owner = THIS_MODULE, 281 .owner = THIS_MODULE,
282 .pf = PF_INET6, 282 .pf = NFPROTO_IPV6,
283 .hooknum = NF_INET_LOCAL_OUT, 283 .hooknum = NF_INET_LOCAL_OUT,
284 .priority = NF_IP6_PRI_CONNTRACK, 284 .priority = NF_IP6_PRI_CONNTRACK,
285 }, 285 },
286 { 286 {
287 .hook = ipv6_defrag, 287 .hook = ipv6_defrag,
288 .owner = THIS_MODULE, 288 .owner = THIS_MODULE,
289 .pf = PF_INET6, 289 .pf = NFPROTO_IPV6,
290 .hooknum = NF_INET_LOCAL_OUT, 290 .hooknum = NF_INET_LOCAL_OUT,
291 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, 291 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
292 }, 292 },
293 { 293 {
294 .hook = ipv6_confirm, 294 .hook = ipv6_confirm,
295 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
296 .pf = PF_INET6, 296 .pf = NFPROTO_IPV6,
297 .hooknum = NF_INET_POST_ROUTING, 297 .hooknum = NF_INET_POST_ROUTING,
298 .priority = NF_IP6_PRI_LAST, 298 .priority = NF_IP6_PRI_LAST,
299 }, 299 },
300 { 300 {
301 .hook = ipv6_confirm, 301 .hook = ipv6_confirm,
302 .owner = THIS_MODULE, 302 .owner = THIS_MODULE,
303 .pf = PF_INET6, 303 .pf = NFPROTO_IPV6,
304 .hooknum = NF_INET_LOCAL_IN, 304 .hooknum = NF_INET_LOCAL_IN,
305 .priority = NF_IP6_PRI_LAST-1, 305 .priority = NF_IP6_PRI_LAST-1,
306 }, 306 },
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index d6e5ab463277..593457068ae1 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -36,45 +36,6 @@ MODULE_ALIAS("ip6t_CONNMARK");
36#include <net/netfilter/nf_conntrack_ecache.h> 36#include <net/netfilter/nf_conntrack_ecache.h>
37 37
38static unsigned int 38static unsigned int
39connmark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
40{
41 const struct xt_connmark_target_info *markinfo = par->targinfo;
42 struct nf_conn *ct;
43 enum ip_conntrack_info ctinfo;
44 u_int32_t diff;
45 u_int32_t mark;
46 u_int32_t newmark;
47
48 ct = nf_ct_get(skb, &ctinfo);
49 if (ct) {
50 switch(markinfo->mode) {
51 case XT_CONNMARK_SET:
52 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
53 if (newmark != ct->mark) {
54 ct->mark = newmark;
55 nf_conntrack_event_cache(IPCT_MARK, ct);
56 }
57 break;
58 case XT_CONNMARK_SAVE:
59 newmark = (ct->mark & ~markinfo->mask) |
60 (skb->mark & markinfo->mask);
61 if (ct->mark != newmark) {
62 ct->mark = newmark;
63 nf_conntrack_event_cache(IPCT_MARK, ct);
64 }
65 break;
66 case XT_CONNMARK_RESTORE:
67 mark = skb->mark;
68 diff = (ct->mark ^ mark) & markinfo->mask;
69 skb->mark = mark ^ diff;
70 break;
71 }
72 }
73
74 return XT_CONTINUE;
75}
76
77static unsigned int
78connmark_tg(struct sk_buff *skb, const struct xt_target_param *par) 39connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
79{ 40{
80 const struct xt_connmark_tginfo1 *info = par->targinfo; 41 const struct xt_connmark_tginfo1 *info = par->targinfo;
@@ -112,30 +73,6 @@ connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
112 return XT_CONTINUE; 73 return XT_CONTINUE;
113} 74}
114 75
115static bool connmark_tg_check_v0(const struct xt_tgchk_param *par)
116{
117 const struct xt_connmark_target_info *matchinfo = par->targinfo;
118
119 if (matchinfo->mode == XT_CONNMARK_RESTORE) {
120 if (strcmp(par->table, "mangle") != 0) {
121 printk(KERN_WARNING "CONNMARK: restore can only be "
122 "called from \"mangle\" table, not \"%s\"\n",
123 par->table);
124 return false;
125 }
126 }
127 if (matchinfo->mark > 0xffffffff || matchinfo->mask > 0xffffffff) {
128 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
129 return false;
130 }
131 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
132 printk(KERN_WARNING "can't load conntrack support for "
133 "proto=%u\n", par->family);
134 return false;
135 }
136 return true;
137}
138
139static bool connmark_tg_check(const struct xt_tgchk_param *par) 76static bool connmark_tg_check(const struct xt_tgchk_param *par)
140{ 77{
141 if (nf_ct_l3proto_try_module_get(par->family) < 0) { 78 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
@@ -151,74 +88,25 @@ static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
151 nf_ct_l3proto_module_put(par->family); 88 nf_ct_l3proto_module_put(par->family);
152} 89}
153 90
154#ifdef CONFIG_COMPAT 91static struct xt_target connmark_tg_reg __read_mostly = {
155struct compat_xt_connmark_target_info { 92 .name = "CONNMARK",
156 compat_ulong_t mark, mask; 93 .revision = 1,
157 u_int8_t mode; 94 .family = NFPROTO_UNSPEC,
158 u_int8_t __pad1; 95 .checkentry = connmark_tg_check,
159 u_int16_t __pad2; 96 .target = connmark_tg,
160}; 97 .targetsize = sizeof(struct xt_connmark_tginfo1),
161 98 .destroy = connmark_tg_destroy,
162static void connmark_tg_compat_from_user_v0(void *dst, void *src) 99 .me = THIS_MODULE,
163{
164 const struct compat_xt_connmark_target_info *cm = src;
165 struct xt_connmark_target_info m = {
166 .mark = cm->mark,
167 .mask = cm->mask,
168 .mode = cm->mode,
169 };
170 memcpy(dst, &m, sizeof(m));
171}
172
173static int connmark_tg_compat_to_user_v0(void __user *dst, void *src)
174{
175 const struct xt_connmark_target_info *m = src;
176 struct compat_xt_connmark_target_info cm = {
177 .mark = m->mark,
178 .mask = m->mask,
179 .mode = m->mode,
180 };
181 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
182}
183#endif /* CONFIG_COMPAT */
184
185static struct xt_target connmark_tg_reg[] __read_mostly = {
186 {
187 .name = "CONNMARK",
188 .revision = 0,
189 .family = NFPROTO_UNSPEC,
190 .checkentry = connmark_tg_check_v0,
191 .destroy = connmark_tg_destroy,
192 .target = connmark_tg_v0,
193 .targetsize = sizeof(struct xt_connmark_target_info),
194#ifdef CONFIG_COMPAT
195 .compatsize = sizeof(struct compat_xt_connmark_target_info),
196 .compat_from_user = connmark_tg_compat_from_user_v0,
197 .compat_to_user = connmark_tg_compat_to_user_v0,
198#endif
199 .me = THIS_MODULE
200 },
201 {
202 .name = "CONNMARK",
203 .revision = 1,
204 .family = NFPROTO_UNSPEC,
205 .checkentry = connmark_tg_check,
206 .target = connmark_tg,
207 .targetsize = sizeof(struct xt_connmark_tginfo1),
208 .destroy = connmark_tg_destroy,
209 .me = THIS_MODULE,
210 },
211}; 100};
212 101
213static int __init connmark_tg_init(void) 102static int __init connmark_tg_init(void)
214{ 103{
215 return xt_register_targets(connmark_tg_reg, 104 return xt_register_target(&connmark_tg_reg);
216 ARRAY_SIZE(connmark_tg_reg));
217} 105}
218 106
219static void __exit connmark_tg_exit(void) 107static void __exit connmark_tg_exit(void)
220{ 108{
221 xt_unregister_targets(connmark_tg_reg, ARRAY_SIZE(connmark_tg_reg)); 109 xt_unregister_target(&connmark_tg_reg);
222} 110}
223 111
224module_init(connmark_tg_init); 112module_init(connmark_tg_init);
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 6a347e768f86..74ce89260056 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -18,7 +18,6 @@
18 18
19#include <linux/netfilter/x_tables.h> 19#include <linux/netfilter/x_tables.h>
20#include <linux/netfilter/xt_DSCP.h> 20#include <linux/netfilter/xt_DSCP.h>
21#include <linux/netfilter_ipv4/ipt_TOS.h>
22 21
23MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 22MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
24MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification"); 23MODULE_DESCRIPTION("Xtables: DSCP/TOS field modification");
@@ -73,41 +72,6 @@ static bool dscp_tg_check(const struct xt_tgchk_param *par)
73} 72}
74 73
75static unsigned int 74static unsigned int
76tos_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
77{
78 const struct ipt_tos_target_info *info = par->targinfo;
79 struct iphdr *iph = ip_hdr(skb);
80 u_int8_t oldtos;
81
82 if ((iph->tos & IPTOS_TOS_MASK) != info->tos) {
83 if (!skb_make_writable(skb, sizeof(struct iphdr)))
84 return NF_DROP;
85
86 iph = ip_hdr(skb);
87 oldtos = iph->tos;
88 iph->tos = (iph->tos & IPTOS_PREC_MASK) | info->tos;
89 csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
90 }
91
92 return XT_CONTINUE;
93}
94
95static bool tos_tg_check_v0(const struct xt_tgchk_param *par)
96{
97 const struct ipt_tos_target_info *info = par->targinfo;
98 const uint8_t tos = info->tos;
99
100 if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT &&
101 tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST &&
102 tos != IPTOS_NORMALSVC) {
103 printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
104 return false;
105 }
106
107 return true;
108}
109
110static unsigned int
111tos_tg(struct sk_buff *skb, const struct xt_target_param *par) 75tos_tg(struct sk_buff *skb, const struct xt_target_param *par)
112{ 76{
113 const struct xt_tos_target_info *info = par->targinfo; 77 const struct xt_tos_target_info *info = par->targinfo;
@@ -168,16 +132,6 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
168 }, 132 },
169 { 133 {
170 .name = "TOS", 134 .name = "TOS",
171 .revision = 0,
172 .family = NFPROTO_IPV4,
173 .table = "mangle",
174 .target = tos_tg_v0,
175 .targetsize = sizeof(struct ipt_tos_target_info),
176 .checkentry = tos_tg_check_v0,
177 .me = THIS_MODULE,
178 },
179 {
180 .name = "TOS",
181 .revision = 1, 135 .revision = 1,
182 .family = NFPROTO_IPV4, 136 .family = NFPROTO_IPV4,
183 .table = "mangle", 137 .table = "mangle",
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index 67574bcfb8ac..225f8d11e173 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -25,39 +25,6 @@ MODULE_ALIAS("ipt_MARK");
25MODULE_ALIAS("ip6t_MARK"); 25MODULE_ALIAS("ip6t_MARK");
26 26
27static unsigned int 27static unsigned int
28mark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
29{
30 const struct xt_mark_target_info *markinfo = par->targinfo;
31
32 skb->mark = markinfo->mark;
33 return XT_CONTINUE;
34}
35
36static unsigned int
37mark_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
38{
39 const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
40 int mark = 0;
41
42 switch (markinfo->mode) {
43 case XT_MARK_SET:
44 mark = markinfo->mark;
45 break;
46
47 case XT_MARK_AND:
48 mark = skb->mark & markinfo->mark;
49 break;
50
51 case XT_MARK_OR:
52 mark = skb->mark | markinfo->mark;
53 break;
54 }
55
56 skb->mark = mark;
57 return XT_CONTINUE;
58}
59
60static unsigned int
61mark_tg(struct sk_buff *skb, const struct xt_target_param *par) 28mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
62{ 29{
63 const struct xt_mark_tginfo2 *info = par->targinfo; 30 const struct xt_mark_tginfo2 *info = par->targinfo;
@@ -66,135 +33,23 @@ mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
66 return XT_CONTINUE; 33 return XT_CONTINUE;
67} 34}
68 35
69static bool mark_tg_check_v0(const struct xt_tgchk_param *par) 36static struct xt_target mark_tg_reg __read_mostly = {
70{ 37 .name = "MARK",
71 const struct xt_mark_target_info *markinfo = par->targinfo; 38 .revision = 2,
72 39 .family = NFPROTO_UNSPEC,
73 if (markinfo->mark > 0xffffffff) { 40 .target = mark_tg,
74 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 41 .targetsize = sizeof(struct xt_mark_tginfo2),
75 return false; 42 .me = THIS_MODULE,
76 }
77 return true;
78}
79
80static bool mark_tg_check_v1(const struct xt_tgchk_param *par)
81{
82 const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
83
84 if (markinfo->mode != XT_MARK_SET
85 && markinfo->mode != XT_MARK_AND
86 && markinfo->mode != XT_MARK_OR) {
87 printk(KERN_WARNING "MARK: unknown mode %u\n",
88 markinfo->mode);
89 return false;
90 }
91 if (markinfo->mark > 0xffffffff) {
92 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
93 return false;
94 }
95 return true;
96}
97
98#ifdef CONFIG_COMPAT
99struct compat_xt_mark_target_info {
100 compat_ulong_t mark;
101};
102
103static void mark_tg_compat_from_user_v0(void *dst, void *src)
104{
105 const struct compat_xt_mark_target_info *cm = src;
106 struct xt_mark_target_info m = {
107 .mark = cm->mark,
108 };
109 memcpy(dst, &m, sizeof(m));
110}
111
112static int mark_tg_compat_to_user_v0(void __user *dst, void *src)
113{
114 const struct xt_mark_target_info *m = src;
115 struct compat_xt_mark_target_info cm = {
116 .mark = m->mark,
117 };
118 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
119}
120
121struct compat_xt_mark_target_info_v1 {
122 compat_ulong_t mark;
123 u_int8_t mode;
124 u_int8_t __pad1;
125 u_int16_t __pad2;
126};
127
128static void mark_tg_compat_from_user_v1(void *dst, void *src)
129{
130 const struct compat_xt_mark_target_info_v1 *cm = src;
131 struct xt_mark_target_info_v1 m = {
132 .mark = cm->mark,
133 .mode = cm->mode,
134 };
135 memcpy(dst, &m, sizeof(m));
136}
137
138static int mark_tg_compat_to_user_v1(void __user *dst, void *src)
139{
140 const struct xt_mark_target_info_v1 *m = src;
141 struct compat_xt_mark_target_info_v1 cm = {
142 .mark = m->mark,
143 .mode = m->mode,
144 };
145 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
146}
147#endif /* CONFIG_COMPAT */
148
149static struct xt_target mark_tg_reg[] __read_mostly = {
150 {
151 .name = "MARK",
152 .family = NFPROTO_UNSPEC,
153 .revision = 0,
154 .checkentry = mark_tg_check_v0,
155 .target = mark_tg_v0,
156 .targetsize = sizeof(struct xt_mark_target_info),
157#ifdef CONFIG_COMPAT
158 .compatsize = sizeof(struct compat_xt_mark_target_info),
159 .compat_from_user = mark_tg_compat_from_user_v0,
160 .compat_to_user = mark_tg_compat_to_user_v0,
161#endif
162 .table = "mangle",
163 .me = THIS_MODULE,
164 },
165 {
166 .name = "MARK",
167 .family = NFPROTO_UNSPEC,
168 .revision = 1,
169 .checkentry = mark_tg_check_v1,
170 .target = mark_tg_v1,
171 .targetsize = sizeof(struct xt_mark_target_info_v1),
172#ifdef CONFIG_COMPAT
173 .compatsize = sizeof(struct compat_xt_mark_target_info_v1),
174 .compat_from_user = mark_tg_compat_from_user_v1,
175 .compat_to_user = mark_tg_compat_to_user_v1,
176#endif
177 .table = "mangle",
178 .me = THIS_MODULE,
179 },
180 {
181 .name = "MARK",
182 .revision = 2,
183 .family = NFPROTO_UNSPEC,
184 .target = mark_tg,
185 .targetsize = sizeof(struct xt_mark_tginfo2),
186 .me = THIS_MODULE,
187 },
188}; 43};
189 44
190static int __init mark_tg_init(void) 45static int __init mark_tg_init(void)
191{ 46{
192 return xt_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 47 return xt_register_target(&mark_tg_reg);
193} 48}
194 49
195static void __exit mark_tg_exit(void) 50static void __exit mark_tg_exit(void)
196{ 51{
197 xt_unregister_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg)); 52 xt_unregister_target(&mark_tg_reg);
198} 53}
199 54
200module_init(mark_tg_init); 55module_init(mark_tg_init);
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 86cacab7a4a3..122aa8b0147b 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -47,36 +47,6 @@ connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
47 return ((ct->mark & info->mask) == info->mark) ^ info->invert; 47 return ((ct->mark & info->mask) == info->mark) ^ info->invert;
48} 48}
49 49
50static bool
51connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
52{
53 const struct xt_connmark_info *info = par->matchinfo;
54 const struct nf_conn *ct;
55 enum ip_conntrack_info ctinfo;
56
57 ct = nf_ct_get(skb, &ctinfo);
58 if (!ct)
59 return false;
60
61 return ((ct->mark & info->mask) == info->mark) ^ info->invert;
62}
63
64static bool connmark_mt_check_v0(const struct xt_mtchk_param *par)
65{
66 const struct xt_connmark_info *cm = par->matchinfo;
67
68 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
69 printk(KERN_WARNING "connmark: only support 32bit mark\n");
70 return false;
71 }
72 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
73 printk(KERN_WARNING "can't load conntrack support for "
74 "proto=%u\n", par->family);
75 return false;
76 }
77 return true;
78}
79
80static bool connmark_mt_check(const struct xt_mtchk_param *par) 50static bool connmark_mt_check(const struct xt_mtchk_param *par)
81{ 51{
82 if (nf_ct_l3proto_try_module_get(par->family) < 0) { 52 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
@@ -92,74 +62,25 @@ static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
92 nf_ct_l3proto_module_put(par->family); 62 nf_ct_l3proto_module_put(par->family);
93} 63}
94 64
95#ifdef CONFIG_COMPAT 65static struct xt_match connmark_mt_reg __read_mostly = {
96struct compat_xt_connmark_info { 66 .name = "connmark",
97 compat_ulong_t mark, mask; 67 .revision = 1,
98 u_int8_t invert; 68 .family = NFPROTO_UNSPEC,
99 u_int8_t __pad1; 69 .checkentry = connmark_mt_check,
100 u_int16_t __pad2; 70 .match = connmark_mt,
101}; 71 .matchsize = sizeof(struct xt_connmark_mtinfo1),
102 72 .destroy = connmark_mt_destroy,
103static void connmark_mt_compat_from_user_v0(void *dst, void *src) 73 .me = THIS_MODULE,
104{
105 const struct compat_xt_connmark_info *cm = src;
106 struct xt_connmark_info m = {
107 .mark = cm->mark,
108 .mask = cm->mask,
109 .invert = cm->invert,
110 };
111 memcpy(dst, &m, sizeof(m));
112}
113
114static int connmark_mt_compat_to_user_v0(void __user *dst, void *src)
115{
116 const struct xt_connmark_info *m = src;
117 struct compat_xt_connmark_info cm = {
118 .mark = m->mark,
119 .mask = m->mask,
120 .invert = m->invert,
121 };
122 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
123}
124#endif /* CONFIG_COMPAT */
125
126static struct xt_match connmark_mt_reg[] __read_mostly = {
127 {
128 .name = "connmark",
129 .revision = 0,
130 .family = NFPROTO_UNSPEC,
131 .checkentry = connmark_mt_check_v0,
132 .match = connmark_mt_v0,
133 .destroy = connmark_mt_destroy,
134 .matchsize = sizeof(struct xt_connmark_info),
135#ifdef CONFIG_COMPAT
136 .compatsize = sizeof(struct compat_xt_connmark_info),
137 .compat_from_user = connmark_mt_compat_from_user_v0,
138 .compat_to_user = connmark_mt_compat_to_user_v0,
139#endif
140 .me = THIS_MODULE
141 },
142 {
143 .name = "connmark",
144 .revision = 1,
145 .family = NFPROTO_UNSPEC,
146 .checkentry = connmark_mt_check,
147 .match = connmark_mt,
148 .matchsize = sizeof(struct xt_connmark_mtinfo1),
149 .destroy = connmark_mt_destroy,
150 .me = THIS_MODULE,
151 },
152}; 74};
153 75
154static int __init connmark_mt_init(void) 76static int __init connmark_mt_init(void)
155{ 77{
156 return xt_register_matches(connmark_mt_reg, 78 return xt_register_match(&connmark_mt_reg);
157 ARRAY_SIZE(connmark_mt_reg));
158} 79}
159 80
160static void __exit connmark_mt_exit(void) 81static void __exit connmark_mt_exit(void)
161{ 82{
162 xt_unregister_matches(connmark_mt_reg, ARRAY_SIZE(connmark_mt_reg)); 83 xt_unregister_match(&connmark_mt_reg);
163} 84}
164 85
165module_init(connmark_mt_init); 86module_init(connmark_mt_init);
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index fc581800698e..6dc4652f2fe8 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -19,101 +19,12 @@
19 19
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 21MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
22MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); 22MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
23MODULE_DESCRIPTION("Xtables: connection tracking state match"); 23MODULE_DESCRIPTION("Xtables: connection tracking state match");
24MODULE_ALIAS("ipt_conntrack"); 24MODULE_ALIAS("ipt_conntrack");
25MODULE_ALIAS("ip6t_conntrack"); 25MODULE_ALIAS("ip6t_conntrack");
26 26
27static bool 27static bool
28conntrack_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
29{
30 const struct xt_conntrack_info *sinfo = par->matchinfo;
31 const struct nf_conn *ct;
32 enum ip_conntrack_info ctinfo;
33 unsigned int statebit;
34
35 ct = nf_ct_get(skb, &ctinfo);
36
37#define FWINV(bool, invflg) ((bool) ^ !!(sinfo->invflags & (invflg)))
38
39 if (ct == &nf_conntrack_untracked)
40 statebit = XT_CONNTRACK_STATE_UNTRACKED;
41 else if (ct)
42 statebit = XT_CONNTRACK_STATE_BIT(ctinfo);
43 else
44 statebit = XT_CONNTRACK_STATE_INVALID;
45
46 if (sinfo->flags & XT_CONNTRACK_STATE) {
47 if (ct) {
48 if (test_bit(IPS_SRC_NAT_BIT, &ct->status))
49 statebit |= XT_CONNTRACK_STATE_SNAT;
50 if (test_bit(IPS_DST_NAT_BIT, &ct->status))
51 statebit |= XT_CONNTRACK_STATE_DNAT;
52 }
53 if (FWINV((statebit & sinfo->statemask) == 0,
54 XT_CONNTRACK_STATE))
55 return false;
56 }
57
58 if (ct == NULL) {
59 if (sinfo->flags & ~XT_CONNTRACK_STATE)
60 return false;
61 return true;
62 }
63
64 if (sinfo->flags & XT_CONNTRACK_PROTO &&
65 FWINV(nf_ct_protonum(ct) !=
66 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum,
67 XT_CONNTRACK_PROTO))
68 return false;
69
70 if (sinfo->flags & XT_CONNTRACK_ORIGSRC &&
71 FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip &
72 sinfo->sipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
73 sinfo->tuple[IP_CT_DIR_ORIGINAL].src.ip,
74 XT_CONNTRACK_ORIGSRC))
75 return false;
76
77 if (sinfo->flags & XT_CONNTRACK_ORIGDST &&
78 FWINV((ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip &
79 sinfo->dipmsk[IP_CT_DIR_ORIGINAL].s_addr) !=
80 sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.ip,
81 XT_CONNTRACK_ORIGDST))
82 return false;
83
84 if (sinfo->flags & XT_CONNTRACK_REPLSRC &&
85 FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip &
86 sinfo->sipmsk[IP_CT_DIR_REPLY].s_addr) !=
87 sinfo->tuple[IP_CT_DIR_REPLY].src.ip,
88 XT_CONNTRACK_REPLSRC))
89 return false;
90
91 if (sinfo->flags & XT_CONNTRACK_REPLDST &&
92 FWINV((ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip &
93 sinfo->dipmsk[IP_CT_DIR_REPLY].s_addr) !=
94 sinfo->tuple[IP_CT_DIR_REPLY].dst.ip,
95 XT_CONNTRACK_REPLDST))
96 return false;
97
98 if (sinfo->flags & XT_CONNTRACK_STATUS &&
99 FWINV((ct->status & sinfo->statusmask) == 0,
100 XT_CONNTRACK_STATUS))
101 return false;
102
103 if(sinfo->flags & XT_CONNTRACK_EXPIRES) {
104 unsigned long expires = timer_pending(&ct->timeout) ?
105 (ct->timeout.expires - jiffies)/HZ : 0;
106
107 if (FWINV(!(expires >= sinfo->expires_min &&
108 expires <= sinfo->expires_max),
109 XT_CONNTRACK_EXPIRES))
110 return false;
111 }
112 return true;
113#undef FWINV
114}
115
116static bool
117conntrack_addrcmp(const union nf_inet_addr *kaddr, 28conntrack_addrcmp(const union nf_inet_addr *kaddr,
118 const union nf_inet_addr *uaddr, 29 const union nf_inet_addr *uaddr,
119 const union nf_inet_addr *umask, unsigned int l3proto) 30 const union nf_inet_addr *umask, unsigned int l3proto)
@@ -337,73 +248,9 @@ static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par)
337 conntrack_mt_destroy(par); 248 conntrack_mt_destroy(par);
338} 249}
339 250
340#ifdef CONFIG_COMPAT
341struct compat_xt_conntrack_info
342{
343 compat_uint_t statemask;
344 compat_uint_t statusmask;
345 struct ip_conntrack_old_tuple tuple[IP_CT_DIR_MAX];
346 struct in_addr sipmsk[IP_CT_DIR_MAX];
347 struct in_addr dipmsk[IP_CT_DIR_MAX];
348 compat_ulong_t expires_min;
349 compat_ulong_t expires_max;
350 u_int8_t flags;
351 u_int8_t invflags;
352};
353
354static void conntrack_mt_compat_from_user_v0(void *dst, void *src)
355{
356 const struct compat_xt_conntrack_info *cm = src;
357 struct xt_conntrack_info m = {
358 .statemask = cm->statemask,
359 .statusmask = cm->statusmask,
360 .expires_min = cm->expires_min,
361 .expires_max = cm->expires_max,
362 .flags = cm->flags,
363 .invflags = cm->invflags,
364 };
365 memcpy(m.tuple, cm->tuple, sizeof(m.tuple));
366 memcpy(m.sipmsk, cm->sipmsk, sizeof(m.sipmsk));
367 memcpy(m.dipmsk, cm->dipmsk, sizeof(m.dipmsk));
368 memcpy(dst, &m, sizeof(m));
369}
370
371static int conntrack_mt_compat_to_user_v0(void __user *dst, void *src)
372{
373 const struct xt_conntrack_info *m = src;
374 struct compat_xt_conntrack_info cm = {
375 .statemask = m->statemask,
376 .statusmask = m->statusmask,
377 .expires_min = m->expires_min,
378 .expires_max = m->expires_max,
379 .flags = m->flags,
380 .invflags = m->invflags,
381 };
382 memcpy(cm.tuple, m->tuple, sizeof(cm.tuple));
383 memcpy(cm.sipmsk, m->sipmsk, sizeof(cm.sipmsk));
384 memcpy(cm.dipmsk, m->dipmsk, sizeof(cm.dipmsk));
385 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
386}
387#endif
388
389static struct xt_match conntrack_mt_reg[] __read_mostly = { 251static struct xt_match conntrack_mt_reg[] __read_mostly = {
390 { 252 {
391 .name = "conntrack", 253 .name = "conntrack",
392 .revision = 0,
393 .family = NFPROTO_IPV4,
394 .match = conntrack_mt_v0,
395 .checkentry = conntrack_mt_check,
396 .destroy = conntrack_mt_destroy,
397 .matchsize = sizeof(struct xt_conntrack_info),
398 .me = THIS_MODULE,
399#ifdef CONFIG_COMPAT
400 .compatsize = sizeof(struct compat_xt_conntrack_info),
401 .compat_from_user = conntrack_mt_compat_from_user_v0,
402 .compat_to_user = conntrack_mt_compat_to_user_v0,
403#endif
404 },
405 {
406 .name = "conntrack",
407 .revision = 1, 254 .revision = 1,
408 .family = NFPROTO_UNSPEC, 255 .family = NFPROTO_UNSPEC,
409 .matchsize = sizeof(struct xt_conntrack_mtinfo1), 256 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index c3f8085460d7..0280d3a8c161 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -15,7 +15,6 @@
15 15
16#include <linux/netfilter/x_tables.h> 16#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter/xt_dscp.h> 17#include <linux/netfilter/xt_dscp.h>
18#include <linux/netfilter_ipv4/ipt_tos.h>
19 18
20MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 19MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
21MODULE_DESCRIPTION("Xtables: DSCP/TOS field match"); 20MODULE_DESCRIPTION("Xtables: DSCP/TOS field match");
@@ -55,14 +54,6 @@ static bool dscp_mt_check(const struct xt_mtchk_param *par)
55 return true; 54 return true;
56} 55}
57 56
58static bool
59tos_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
60{
61 const struct ipt_tos_info *info = par->matchinfo;
62
63 return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
64}
65
66static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par) 57static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par)
67{ 58{
68 const struct xt_tos_match_info *info = par->matchinfo; 59 const struct xt_tos_match_info *info = par->matchinfo;
@@ -94,14 +85,6 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
94 }, 85 },
95 { 86 {
96 .name = "tos", 87 .name = "tos",
97 .revision = 0,
98 .family = NFPROTO_IPV4,
99 .match = tos_mt_v0,
100 .matchsize = sizeof(struct ipt_tos_info),
101 .me = THIS_MODULE,
102 },
103 {
104 .name = "tos",
105 .revision = 1, 88 .revision = 1,
106 .family = NFPROTO_IPV4, 89 .family = NFPROTO_IPV4,
107 .match = tos_mt, 90 .match = tos_mt,
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 501f9b623188..ffc96387d556 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -14,40 +14,6 @@
14#include <linux/ipv6.h> 14#include <linux/ipv6.h>
15#include <linux/netfilter/x_tables.h> 15#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter/xt_iprange.h> 16#include <linux/netfilter/xt_iprange.h>
17#include <linux/netfilter_ipv4/ipt_iprange.h>
18
19static bool
20iprange_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
21{
22 const struct ipt_iprange_info *info = par->matchinfo;
23 const struct iphdr *iph = ip_hdr(skb);
24
25 if (info->flags & IPRANGE_SRC) {
26 if ((ntohl(iph->saddr) < ntohl(info->src.min_ip)
27 || ntohl(iph->saddr) > ntohl(info->src.max_ip))
28 ^ !!(info->flags & IPRANGE_SRC_INV)) {
29 pr_debug("src IP %pI4 NOT in range %s%pI4-%pI4\n",
30 &iph->saddr,
31 info->flags & IPRANGE_SRC_INV ? "(INV) " : "",
32 &info->src.min_ip,
33 &info->src.max_ip);
34 return false;
35 }
36 }
37 if (info->flags & IPRANGE_DST) {
38 if ((ntohl(iph->daddr) < ntohl(info->dst.min_ip)
39 || ntohl(iph->daddr) > ntohl(info->dst.max_ip))
40 ^ !!(info->flags & IPRANGE_DST_INV)) {
41 pr_debug("dst IP %pI4 NOT in range %s%pI4-%pI4\n",
42 &iph->daddr,
43 info->flags & IPRANGE_DST_INV ? "(INV) " : "",
44 &info->dst.min_ip,
45 &info->dst.max_ip);
46 return false;
47 }
48 }
49 return true;
50}
51 17
52static bool 18static bool
53iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par) 19iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -127,14 +93,6 @@ iprange_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
127static struct xt_match iprange_mt_reg[] __read_mostly = { 93static struct xt_match iprange_mt_reg[] __read_mostly = {
128 { 94 {
129 .name = "iprange", 95 .name = "iprange",
130 .revision = 0,
131 .family = NFPROTO_IPV4,
132 .match = iprange_mt_v0,
133 .matchsize = sizeof(struct ipt_iprange_info),
134 .me = THIS_MODULE,
135 },
136 {
137 .name = "iprange",
138 .revision = 1, 96 .revision = 1,
139 .family = NFPROTO_IPV4, 97 .family = NFPROTO_IPV4,
140 .match = iprange_mt4, 98 .match = iprange_mt4,
@@ -164,7 +122,8 @@ static void __exit iprange_mt_exit(void)
164module_init(iprange_mt_init); 122module_init(iprange_mt_init);
165module_exit(iprange_mt_exit); 123module_exit(iprange_mt_exit);
166MODULE_LICENSE("GPL"); 124MODULE_LICENSE("GPL");
167MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>, Jan Engelhardt <jengelh@computergmbh.de>"); 125MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
126MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
168MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching"); 127MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching");
169MODULE_ALIAS("ipt_iprange"); 128MODULE_ALIAS("ipt_iprange");
170MODULE_ALIAS("ip6t_iprange"); 129MODULE_ALIAS("ip6t_iprange");
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 10b9e34bbc5b..1db07d8125f8 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * (C) 1999-2001 Marc Boucher <marc@mbsi.ca> 4 * (C) 1999-2001 Marc Boucher <marc@mbsi.ca>
5 * Copyright © CC Computer Consultants GmbH, 2007 - 2008 5 * Copyright © CC Computer Consultants GmbH, 2007 - 2008
6 * Jan Engelhardt <jengelh@computergmbh.de> 6 * Jan Engelhardt <jengelh@medozas.de>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -23,14 +23,6 @@ MODULE_ALIAS("ipt_mark");
23MODULE_ALIAS("ip6t_mark"); 23MODULE_ALIAS("ip6t_mark");
24 24
25static bool 25static bool
26mark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
27{
28 const struct xt_mark_info *info = par->matchinfo;
29
30 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
31}
32
33static bool
34mark_mt(const struct sk_buff *skb, const struct xt_match_param *par) 26mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
35{ 27{
36 const struct xt_mark_mtinfo1 *info = par->matchinfo; 28 const struct xt_mark_mtinfo1 *info = par->matchinfo;
@@ -38,81 +30,23 @@ mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
38 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 30 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
39} 31}
40 32
41static bool mark_mt_check_v0(const struct xt_mtchk_param *par) 33static struct xt_match mark_mt_reg __read_mostly = {
42{ 34 .name = "mark",
43 const struct xt_mark_info *minfo = par->matchinfo; 35 .revision = 1,
44 36 .family = NFPROTO_UNSPEC,
45 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 37 .match = mark_mt,
46 printk(KERN_WARNING "mark: only supports 32bit mark\n"); 38 .matchsize = sizeof(struct xt_mark_mtinfo1),
47 return false; 39 .me = THIS_MODULE,
48 }
49 return true;
50}
51
52#ifdef CONFIG_COMPAT
53struct compat_xt_mark_info {
54 compat_ulong_t mark, mask;
55 u_int8_t invert;
56 u_int8_t __pad1;
57 u_int16_t __pad2;
58};
59
60static void mark_mt_compat_from_user_v0(void *dst, void *src)
61{
62 const struct compat_xt_mark_info *cm = src;
63 struct xt_mark_info m = {
64 .mark = cm->mark,
65 .mask = cm->mask,
66 .invert = cm->invert,
67 };
68 memcpy(dst, &m, sizeof(m));
69}
70
71static int mark_mt_compat_to_user_v0(void __user *dst, void *src)
72{
73 const struct xt_mark_info *m = src;
74 struct compat_xt_mark_info cm = {
75 .mark = m->mark,
76 .mask = m->mask,
77 .invert = m->invert,
78 };
79 return copy_to_user(dst, &cm, sizeof(cm)) ? -EFAULT : 0;
80}
81#endif /* CONFIG_COMPAT */
82
83static struct xt_match mark_mt_reg[] __read_mostly = {
84 {
85 .name = "mark",
86 .revision = 0,
87 .family = NFPROTO_UNSPEC,
88 .checkentry = mark_mt_check_v0,
89 .match = mark_mt_v0,
90 .matchsize = sizeof(struct xt_mark_info),
91#ifdef CONFIG_COMPAT
92 .compatsize = sizeof(struct compat_xt_mark_info),
93 .compat_from_user = mark_mt_compat_from_user_v0,
94 .compat_to_user = mark_mt_compat_to_user_v0,
95#endif
96 .me = THIS_MODULE,
97 },
98 {
99 .name = "mark",
100 .revision = 1,
101 .family = NFPROTO_UNSPEC,
102 .match = mark_mt,
103 .matchsize = sizeof(struct xt_mark_mtinfo1),
104 .me = THIS_MODULE,
105 },
106}; 40};
107 41
108static int __init mark_mt_init(void) 42static int __init mark_mt_init(void)
109{ 43{
110 return xt_register_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg)); 44 return xt_register_match(&mark_mt_reg);
111} 45}
112 46
113static void __exit mark_mt_exit(void) 47static void __exit mark_mt_exit(void)
114{ 48{
115 xt_unregister_matches(mark_mt_reg, ARRAY_SIZE(mark_mt_reg)); 49 xt_unregister_match(&mark_mt_reg);
116} 50}
117 51
118module_init(mark_mt_init); 52module_init(mark_mt_init);
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 22b2a5e881ea..d24c76dffee2 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -5,7 +5,6 @@
5 * (C) 2000 Marc Boucher <marc@mbsi.ca> 5 * (C) 2000 Marc Boucher <marc@mbsi.ca>
6 * 6 *
7 * Copyright © CC Computer Consultants GmbH, 2007 - 2008 7 * Copyright © CC Computer Consultants GmbH, 2007 - 2008
8 * <jengelh@computergmbh.de>
9 * 8 *
10 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
@@ -17,60 +16,6 @@
17#include <net/sock.h> 16#include <net/sock.h>
18#include <linux/netfilter/x_tables.h> 17#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter/xt_owner.h> 18#include <linux/netfilter/xt_owner.h>
20#include <linux/netfilter_ipv4/ipt_owner.h>
21#include <linux/netfilter_ipv6/ip6t_owner.h>
22
23static bool
24owner_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
25{
26 const struct ipt_owner_info *info = par->matchinfo;
27 const struct file *filp;
28
29 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
30 return false;
31
32 filp = skb->sk->sk_socket->file;
33 if (filp == NULL)
34 return false;
35
36 if (info->match & IPT_OWNER_UID)
37 if ((filp->f_cred->fsuid != info->uid) ^
38 !!(info->invert & IPT_OWNER_UID))
39 return false;
40
41 if (info->match & IPT_OWNER_GID)
42 if ((filp->f_cred->fsgid != info->gid) ^
43 !!(info->invert & IPT_OWNER_GID))
44 return false;
45
46 return true;
47}
48
49static bool
50owner_mt6_v0(const struct sk_buff *skb, const struct xt_match_param *par)
51{
52 const struct ip6t_owner_info *info = par->matchinfo;
53 const struct file *filp;
54
55 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
56 return false;
57
58 filp = skb->sk->sk_socket->file;
59 if (filp == NULL)
60 return false;
61
62 if (info->match & IP6T_OWNER_UID)
63 if ((filp->f_cred->fsuid != info->uid) ^
64 !!(info->invert & IP6T_OWNER_UID))
65 return false;
66
67 if (info->match & IP6T_OWNER_GID)
68 if ((filp->f_cred->fsgid != info->gid) ^
69 !!(info->invert & IP6T_OWNER_GID))
70 return false;
71
72 return true;
73}
74 19
75static bool 20static bool
76owner_mt(const struct sk_buff *skb, const struct xt_match_param *par) 21owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -107,81 +52,30 @@ owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
107 return true; 52 return true;
108} 53}
109 54
110static bool owner_mt_check_v0(const struct xt_mtchk_param *par) 55static struct xt_match owner_mt_reg __read_mostly = {
111{ 56 .name = "owner",
112 const struct ipt_owner_info *info = par->matchinfo; 57 .revision = 1,
113 58 .family = NFPROTO_UNSPEC,
114 if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { 59 .match = owner_mt,
115 printk(KERN_WARNING KBUILD_MODNAME 60 .matchsize = sizeof(struct xt_owner_match_info),
116 ": PID, SID and command matching is not " 61 .hooks = (1 << NF_INET_LOCAL_OUT) |
117 "supported anymore\n"); 62 (1 << NF_INET_POST_ROUTING),
118 return false; 63 .me = THIS_MODULE,
119 }
120
121 return true;
122}
123
124static bool owner_mt6_check_v0(const struct xt_mtchk_param *par)
125{
126 const struct ip6t_owner_info *info = par->matchinfo;
127
128 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
129 printk(KERN_WARNING KBUILD_MODNAME
130 ": PID and SID matching is not supported anymore\n");
131 return false;
132 }
133
134 return true;
135}
136
137static struct xt_match owner_mt_reg[] __read_mostly = {
138 {
139 .name = "owner",
140 .revision = 0,
141 .family = NFPROTO_IPV4,
142 .match = owner_mt_v0,
143 .matchsize = sizeof(struct ipt_owner_info),
144 .checkentry = owner_mt_check_v0,
145 .hooks = (1 << NF_INET_LOCAL_OUT) |
146 (1 << NF_INET_POST_ROUTING),
147 .me = THIS_MODULE,
148 },
149 {
150 .name = "owner",
151 .revision = 0,
152 .family = NFPROTO_IPV6,
153 .match = owner_mt6_v0,
154 .matchsize = sizeof(struct ip6t_owner_info),
155 .checkentry = owner_mt6_check_v0,
156 .hooks = (1 << NF_INET_LOCAL_OUT) |
157 (1 << NF_INET_POST_ROUTING),
158 .me = THIS_MODULE,
159 },
160 {
161 .name = "owner",
162 .revision = 1,
163 .family = NFPROTO_UNSPEC,
164 .match = owner_mt,
165 .matchsize = sizeof(struct xt_owner_match_info),
166 .hooks = (1 << NF_INET_LOCAL_OUT) |
167 (1 << NF_INET_POST_ROUTING),
168 .me = THIS_MODULE,
169 },
170}; 64};
171 65
172static int __init owner_mt_init(void) 66static int __init owner_mt_init(void)
173{ 67{
174 return xt_register_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); 68 return xt_register_match(&owner_mt_reg);
175} 69}
176 70
177static void __exit owner_mt_exit(void) 71static void __exit owner_mt_exit(void)
178{ 72{
179 xt_unregister_matches(owner_mt_reg, ARRAY_SIZE(owner_mt_reg)); 73 xt_unregister_match(&owner_mt_reg);
180} 74}
181 75
182module_init(owner_mt_init); 76module_init(owner_mt_init);
183module_exit(owner_mt_exit); 77module_exit(owner_mt_exit);
184MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); 78MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
185MODULE_DESCRIPTION("Xtables: socket owner matching"); 79MODULE_DESCRIPTION("Xtables: socket owner matching");
186MODULE_LICENSE("GPL"); 80MODULE_LICENSE("GPL");
187MODULE_ALIAS("ipt_owner"); 81MODULE_ALIAS("ipt_owner");