aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/bridge/netfilter/ebt_log.c29
-rw-r--r--net/bridge/netfilter/ebt_ulog.c2
-rw-r--r--net/bridge/netfilter/ebtable_broute.c2
-rw-r--r--net/bridge/netfilter/ebtable_filter.c8
-rw-r--r--net/bridge/netfilter/ebtable_nat.c6
-rw-r--r--net/bridge/netfilter/ebtables.c13
-rw-r--r--net/ipv4/netfilter/arp_tables.c47
-rw-r--r--net/ipv4/netfilter/arptable_filter.c4
-rw-r--r--net/ipv4/netfilter/ip_tables.c51
-rw-r--r--net/ipv4/netfilter/iptable_filter.c10
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c16
-rw-r--r--net/ipv4/netfilter/iptable_raw.c10
-rw-r--r--net/ipv4/netfilter/iptable_security.c12
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c22
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c8
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c6
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c8
-rw-r--r--net/ipv6/netfilter/ip6_tables.c48
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c9
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c10
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c16
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c10
-rw-r--r--net/ipv6/netfilter/ip6table_security.c12
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c18
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c29
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c7
-rw-r--r--net/netfilter/nf_conntrack_core.c8
-rw-r--r--net/netfilter/nf_conntrack_netlink.c54
-rw-r--r--net/netfilter/nfnetlink.c2
-rw-r--r--net/netfilter/nfnetlink_log.c6
-rw-r--r--net/netfilter/nfnetlink_queue.c9
-rw-r--r--net/netfilter/x_tables.c7
-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_osf.c6
-rw-r--r--net/netfilter/xt_owner.c130
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/sched/act_api.c2
45 files changed, 348 insertions, 1040 deletions
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 4fde7425077d..907a82e9023d 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -359,7 +359,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
359 }, 359 },
360 .proto = 0, 360 .proto = 0,
361 }; 361 };
362 struct in_device *in_dev = in_dev_get(dev); 362 struct in_device *in_dev = __in_dev_get_rcu(dev);
363 363
364 /* If err equals -EHOSTUNREACH the error is due to a 364 /* If err equals -EHOSTUNREACH the error is due to a
365 * martian destination or due to the fact that 365 * martian destination or due to the fact that
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index a94f3cc377c0..e4ea3fdd1d41 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -50,14 +50,6 @@ struct arppayload
50 unsigned char ip_dst[4]; 50 unsigned char ip_dst[4];
51}; 51};
52 52
53static void print_MAC(const unsigned char *p)
54{
55 int i;
56
57 for (i = 0; i < ETH_ALEN; i++, p++)
58 printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':');
59}
60
61static void 53static void
62print_ports(const struct sk_buff *skb, uint8_t protocol, int offset) 54print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
63{ 55{
@@ -88,14 +80,11 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
88 unsigned int bitmask; 80 unsigned int bitmask;
89 81
90 spin_lock_bh(&ebt_log_lock); 82 spin_lock_bh(&ebt_log_lock);
91 printk("<%c>%s IN=%s OUT=%s MAC source = ", '0' + loginfo->u.log.level, 83 printk("<%c>%s IN=%s OUT=%s MAC source = %pM MAC dest = %pM proto = 0x%04x",
92 prefix, in ? in->name : "", out ? out->name : ""); 84 '0' + loginfo->u.log.level, prefix,
93 85 in ? in->name : "", out ? out->name : "",
94 print_MAC(eth_hdr(skb)->h_source); 86 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
95 printk("MAC dest = "); 87 ntohs(eth_hdr(skb)->h_proto));
96 print_MAC(eth_hdr(skb)->h_dest);
97
98 printk("proto = 0x%04x", ntohs(eth_hdr(skb)->h_proto));
99 88
100 if (loginfo->type == NF_LOG_TYPE_LOG) 89 if (loginfo->type == NF_LOG_TYPE_LOG)
101 bitmask = loginfo->u.log.logflags; 90 bitmask = loginfo->u.log.logflags;
@@ -171,12 +160,8 @@ ebt_log_packet(u_int8_t pf, unsigned int hooknum,
171 printk(" INCOMPLETE ARP payload"); 160 printk(" INCOMPLETE ARP payload");
172 goto out; 161 goto out;
173 } 162 }
174 printk(" ARP MAC SRC="); 163 printk(" ARP MAC SRC=%pM ARP IP SRC=%pI4 ARP MAC DST=%pM ARP IP DST=%pI4",
175 print_MAC(ap->mac_src); 164 ap->mac_src, ap->ip_src, ap->mac_dst, ap->ip_dst);
176 printk(" ARP IP SRC=%pI4", ap->ip_src);
177 printk(" ARP MAC DST=");
178 print_MAC(ap->mac_dst);
179 printk(" ARP IP DST=%pI4", ap->ip_dst);
180 } 165 }
181 } 166 }
182out: 167out:
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 133eeae45a4f..ce50688a6431 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -266,7 +266,7 @@ static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
266 if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN) 266 if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
267 uloginfo->qthreshold = EBT_ULOG_MAX_QLEN; 267 uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
268 268
269 return 0; 269 return true;
270} 270}
271 271
272static struct xt_target ebt_ulog_tg_reg __read_mostly = { 272static struct xt_target ebt_ulog_tg_reg __read_mostly = {
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index c751111440f8..d32ab13e728c 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -41,7 +41,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
41 return 0; 41 return 0;
42} 42}
43 43
44static struct ebt_table broute_table = 44static const struct ebt_table broute_table =
45{ 45{
46 .name = "broute", 46 .name = "broute",
47 .table = &initial_table, 47 .table = &initial_table,
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index a5eea72938a6..60b1a6ca7185 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -50,7 +50,7 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
50 return 0; 50 return 0;
51} 51}
52 52
53static struct ebt_table frame_filter = 53static const struct ebt_table frame_filter =
54{ 54{
55 .name = "filter", 55 .name = "filter",
56 .table = &initial_table, 56 .table = &initial_table,
@@ -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/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 37928d5f2840..bd1c65425d4f 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -1103,23 +1103,24 @@ free_newinfo:
1103 return ret; 1103 return ret;
1104} 1104}
1105 1105
1106struct ebt_table *ebt_register_table(struct net *net, struct ebt_table *table) 1106struct ebt_table *
1107ebt_register_table(struct net *net, const struct ebt_table *input_table)
1107{ 1108{
1108 struct ebt_table_info *newinfo; 1109 struct ebt_table_info *newinfo;
1109 struct ebt_table *t; 1110 struct ebt_table *t, *table;
1110 struct ebt_replace_kernel *repl; 1111 struct ebt_replace_kernel *repl;
1111 int ret, i, countersize; 1112 int ret, i, countersize;
1112 void *p; 1113 void *p;
1113 1114
1114 if (!table || !(repl = table->table) || !repl->entries || 1115 if (input_table == NULL || (repl = input_table->table) == NULL ||
1115 repl->entries_size == 0 || 1116 repl->entries == 0 || repl->entries_size == 0 ||
1116 repl->counters || table->private) { 1117 repl->counters != NULL || input_table->private != NULL) {
1117 BUGPRINT("Bad table data for ebt_register_table!!!\n"); 1118 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1118 return ERR_PTR(-EINVAL); 1119 return ERR_PTR(-EINVAL);
1119 } 1120 }
1120 1121
1121 /* Don't add one table to multiple lists. */ 1122 /* Don't add one table to multiple lists. */
1122 table = kmemdup(table, sizeof(struct ebt_table), GFP_KERNEL); 1123 table = kmemdup(input_table, sizeof(struct ebt_table), GFP_KERNEL);
1123 if (!table) { 1124 if (!table) {
1124 ret = -ENOMEM; 1125 ret = -ENOMEM;
1125 goto out; 1126 goto out;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 7505dff4ffdf..27774c99d888 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;
@@ -1760,7 +1778,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
1760 return ret; 1778 return ret;
1761} 1779}
1762 1780
1763struct xt_table *arpt_register_table(struct net *net, struct xt_table *table, 1781struct xt_table *arpt_register_table(struct net *net,
1782 const struct xt_table *table,
1764 const struct arpt_replace *repl) 1783 const struct arpt_replace *repl)
1765{ 1784{
1766 int ret; 1785 int ret;
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 6ecfdae7c589..97337601827a 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -15,7 +15,7 @@ MODULE_DESCRIPTION("arptables filter table");
15#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \ 15#define FILTER_VALID_HOOKS ((1 << NF_ARP_IN) | (1 << NF_ARP_OUT) | \
16 (1 << NF_ARP_FORWARD)) 16 (1 << NF_ARP_FORWARD))
17 17
18static struct 18static const struct
19{ 19{
20 struct arpt_replace repl; 20 struct arpt_replace repl;
21 struct arpt_standard entries[3]; 21 struct arpt_standard entries[3];
@@ -45,7 +45,7 @@ static struct
45 .term = ARPT_ERROR_INIT, 45 .term = ARPT_ERROR_INIT,
46}; 46};
47 47
48static struct xt_table packet_filter = { 48static const struct xt_table packet_filter = {
49 .name = "filter", 49 .name = "filter",
50 .valid_hooks = FILTER_VALID_HOOKS, 50 .valid_hooks = FILTER_VALID_HOOKS,
51 .me = THIS_MODULE, 51 .me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index fdefae6b5dfc..cde755d5eeab 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
@@ -2051,7 +2065,8 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2051 return ret; 2065 return ret;
2052} 2066}
2053 2067
2054struct xt_table *ipt_register_table(struct net *net, struct xt_table *table, 2068struct xt_table *ipt_register_table(struct net *net,
2069 const struct xt_table *table,
2055 const struct ipt_replace *repl) 2070 const struct ipt_replace *repl)
2056{ 2071{
2057 int ret; 2072 int ret;
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index c30a969724f8..df566cbd68e5 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -53,11 +53,11 @@ static struct
53 .term = IPT_ERROR_INIT, /* ERROR */ 53 .term = IPT_ERROR_INIT, /* ERROR */
54}; 54};
55 55
56static struct xt_table packet_filter = { 56static const 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..036047f9b0f2 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -28,7 +28,7 @@ MODULE_DESCRIPTION("iptables mangle table");
28 (1 << NF_INET_POST_ROUTING)) 28 (1 << NF_INET_POST_ROUTING))
29 29
30/* Ouch - five different hooks? Maybe this should be a config option..... -- BC */ 30/* Ouch - five different hooks? Maybe this should be a config option..... -- BC */
31static struct 31static const struct
32{ 32{
33 struct ipt_replace repl; 33 struct ipt_replace repl;
34 struct ipt_standard entries[5]; 34 struct ipt_standard entries[5];
@@ -64,11 +64,11 @@ static struct
64 .term = IPT_ERROR_INIT, /* ERROR */ 64 .term = IPT_ERROR_INIT, /* ERROR */
65}; 65};
66 66
67static struct xt_table packet_mangler = { 67static const 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..993edc23be09 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -9,7 +9,7 @@
9 9
10#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 10#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
11 11
12static struct 12static const struct
13{ 13{
14 struct ipt_replace repl; 14 struct ipt_replace repl;
15 struct ipt_standard entries[2]; 15 struct ipt_standard entries[2];
@@ -36,11 +36,11 @@ static struct
36 .term = IPT_ERROR_INIT, /* ERROR */ 36 .term = IPT_ERROR_INIT, /* ERROR */
37}; 37};
38 38
39static struct xt_table packet_raw = { 39static const 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..99eb76c65d25 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("iptables security table, for MAC rules");
27 (1 << NF_INET_FORWARD) | \ 27 (1 << NF_INET_FORWARD) | \
28 (1 << NF_INET_LOCAL_OUT) 28 (1 << NF_INET_LOCAL_OUT)
29 29
30static struct 30static const struct
31{ 31{
32 struct ipt_replace repl; 32 struct ipt_replace repl;
33 struct ipt_standard entries[3]; 33 struct ipt_standard entries[3];
@@ -57,11 +57,11 @@ static struct
57 .term = IPT_ERROR_INIT, /* ERROR */ 57 .term = IPT_ERROR_INIT, /* ERROR */
58}; 58};
59 59
60static struct xt_table security_table = { 60static const 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 7d2ead7228ac..aa95bb82ee6c 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -26,6 +26,7 @@
26#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 26#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
27#include <net/netfilter/nf_nat_helper.h> 27#include <net/netfilter/nf_nat_helper.h>
28#include <net/netfilter/ipv4/nf_defrag_ipv4.h> 28#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
29#include <net/netfilter/nf_log.h>
29 30
30int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, 31int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
31 struct nf_conn *ct, 32 struct nf_conn *ct,
@@ -113,8 +114,11 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
113 114
114 ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb), 115 ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
115 ct, ctinfo); 116 ct, ctinfo);
116 if (ret != NF_ACCEPT) 117 if (ret != NF_ACCEPT) {
118 nf_log_packet(NFPROTO_IPV4, hooknum, skb, in, out, NULL,
119 "nf_ct_%s: dropping packet", helper->name);
117 return ret; 120 return ret;
121 }
118 122
119 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) { 123 if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
120 typeof(nf_nat_seq_adjust_hook) seq_adjust; 124 typeof(nf_nat_seq_adjust_hook) seq_adjust;
@@ -158,28 +162,28 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
158 { 162 {
159 .hook = ipv4_conntrack_in, 163 .hook = ipv4_conntrack_in,
160 .owner = THIS_MODULE, 164 .owner = THIS_MODULE,
161 .pf = PF_INET, 165 .pf = NFPROTO_IPV4,
162 .hooknum = NF_INET_PRE_ROUTING, 166 .hooknum = NF_INET_PRE_ROUTING,
163 .priority = NF_IP_PRI_CONNTRACK, 167 .priority = NF_IP_PRI_CONNTRACK,
164 }, 168 },
165 { 169 {
166 .hook = ipv4_conntrack_local, 170 .hook = ipv4_conntrack_local,
167 .owner = THIS_MODULE, 171 .owner = THIS_MODULE,
168 .pf = PF_INET, 172 .pf = NFPROTO_IPV4,
169 .hooknum = NF_INET_LOCAL_OUT, 173 .hooknum = NF_INET_LOCAL_OUT,
170 .priority = NF_IP_PRI_CONNTRACK, 174 .priority = NF_IP_PRI_CONNTRACK,
171 }, 175 },
172 { 176 {
173 .hook = ipv4_confirm, 177 .hook = ipv4_confirm,
174 .owner = THIS_MODULE, 178 .owner = THIS_MODULE,
175 .pf = PF_INET, 179 .pf = NFPROTO_IPV4,
176 .hooknum = NF_INET_POST_ROUTING, 180 .hooknum = NF_INET_POST_ROUTING,
177 .priority = NF_IP_PRI_CONNTRACK_CONFIRM, 181 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
178 }, 182 },
179 { 183 {
180 .hook = ipv4_confirm, 184 .hook = ipv4_confirm,
181 .owner = THIS_MODULE, 185 .owner = THIS_MODULE,
182 .pf = PF_INET, 186 .pf = NFPROTO_IPV4,
183 .hooknum = NF_INET_LOCAL_IN, 187 .hooknum = NF_INET_LOCAL_IN,
184 .priority = NF_IP_PRI_CONNTRACK_CONFIRM, 188 .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
185 }, 189 },
@@ -256,11 +260,11 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
256 tuple.dst.u3.ip = inet->daddr; 260 tuple.dst.u3.ip = inet->daddr;
257 tuple.dst.u.tcp.port = inet->dport; 261 tuple.dst.u.tcp.port = inet->dport;
258 tuple.src.l3num = PF_INET; 262 tuple.src.l3num = PF_INET;
259 tuple.dst.protonum = IPPROTO_TCP; 263 tuple.dst.protonum = sk->sk_protocol;
260 264
261 /* We only do TCP at the moment: is there a better way? */ 265 /* We only do TCP and SCTP at the moment: is there a better way? */
262 if (strcmp(sk->sk_prot->name, "TCP")) { 266 if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) {
263 pr_debug("SO_ORIGINAL_DST: Not a TCP socket\n"); 267 pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n");
264 return -ENOPROTOOPT; 268 return -ENOPROTOOPT;
265 } 269 }
266 270
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 3229e0a81ba6..68afc6ecd343 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -212,7 +212,7 @@ find_best_ips_proto(struct nf_conntrack_tuple *tuple,
212 maxip = ntohl(range->max_ip); 212 maxip = ntohl(range->max_ip);
213 j = jhash_2words((__force u32)tuple->src.u3.ip, 213 j = jhash_2words((__force u32)tuple->src.u3.ip,
214 range->flags & IP_NAT_RANGE_PERSISTENT ? 214 range->flags & IP_NAT_RANGE_PERSISTENT ?
215 (__force u32)tuple->dst.u3.ip : 0, 0); 215 0 : (__force u32)tuple->dst.u3.ip, 0);
216 j = ((u64)j * (maxip - minip + 1)) >> 32; 216 j = ((u64)j * (maxip - minip + 1)) >> 32;
217 *var_ipp = htonl(minip + j); 217 *var_ipp = htonl(minip + j);
218} 218}
@@ -620,7 +620,7 @@ static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
620}; 620};
621 621
622static int 622static int
623nfnetlink_parse_nat(struct nlattr *nat, 623nfnetlink_parse_nat(const struct nlattr *nat,
624 const struct nf_conn *ct, struct nf_nat_range *range) 624 const struct nf_conn *ct, struct nf_nat_range *range)
625{ 625{
626 struct nlattr *tb[CTA_NAT_MAX+1]; 626 struct nlattr *tb[CTA_NAT_MAX+1];
@@ -656,7 +656,7 @@ nfnetlink_parse_nat(struct nlattr *nat,
656static int 656static int
657nfnetlink_parse_nat_setup(struct nf_conn *ct, 657nfnetlink_parse_nat_setup(struct nf_conn *ct,
658 enum nf_nat_manip_type manip, 658 enum nf_nat_manip_type manip,
659 struct nlattr *attr) 659 const struct nlattr *attr)
660{ 660{
661 struct nf_nat_range range; 661 struct nf_nat_range range;
662 662
@@ -671,7 +671,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
671static int 671static int
672nfnetlink_parse_nat_setup(struct nf_conn *ct, 672nfnetlink_parse_nat_setup(struct nf_conn *ct,
673 enum nf_nat_manip_type manip, 673 enum nf_nat_manip_type manip,
674 struct nlattr *attr) 674 const struct nlattr *attr)
675{ 675{
676 return -EOPNOTSUPP; 676 return -EOPNOTSUPP;
677} 677}
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index 6348a793936e..9e81e0dfb4ec 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -28,7 +28,7 @@
28 (1 << NF_INET_POST_ROUTING) | \ 28 (1 << NF_INET_POST_ROUTING) | \
29 (1 << NF_INET_LOCAL_OUT)) 29 (1 << NF_INET_LOCAL_OUT))
30 30
31static struct 31static const struct
32{ 32{
33 struct ipt_replace repl; 33 struct ipt_replace repl;
34 struct ipt_standard entries[3]; 34 struct ipt_standard entries[3];
@@ -58,11 +58,11 @@ static struct
58 .term = IPT_ERROR_INIT, /* ERROR */ 58 .term = IPT_ERROR_INIT, /* ERROR */
59}; 59};
60 60
61static struct xt_table nat_table = { 61static const 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..cc9f8ef303fd 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
@@ -2083,7 +2100,8 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2083 return ret; 2100 return ret;
2084} 2101}
2085 2102
2086struct xt_table *ip6t_register_table(struct net *net, struct xt_table *table, 2103struct xt_table *ip6t_register_table(struct net *net,
2104 const struct xt_table *table,
2087 const struct ip6t_replace *repl) 2105 const struct ip6t_replace *repl)
2088{ 2106{
2089 int ret; 2107 int ret;
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index db610bacbcce..ca287f6d2bce 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -23,7 +23,6 @@ static bool
23eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par) 23eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
24{ 24{
25 unsigned char eui64[8]; 25 unsigned char eui64[8];
26 int i = 0;
27 26
28 if (!(skb_mac_header(skb) >= skb->head && 27 if (!(skb_mac_header(skb) >= skb->head &&
29 skb_mac_header(skb) + ETH_HLEN <= skb->data) && 28 skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
@@ -42,12 +41,8 @@ eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
42 eui64[4] = 0xfe; 41 eui64[4] = 0xfe;
43 eui64[0] ^= 0x02; 42 eui64[0] ^= 0x02;
44 43
45 i = 0; 44 if (!memcmp(ipv6_hdr(skb)->saddr.s6_addr + 8, eui64,
46 while (ipv6_hdr(skb)->saddr.s6_addr[8 + i] == eui64[i] 45 sizeof(eui64)))
47 && i < 8)
48 i++;
49
50 if (i == 8)
51 return true; 46 return true;
52 } 47 }
53 } 48 }
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index ef5a0a32bf8e..6f4383ad86f9 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -51,11 +51,11 @@ static struct
51 .term = IP6T_ERROR_INIT, /* ERROR */ 51 .term = IP6T_ERROR_INIT, /* ERROR */
52}; 52};
53 53
54static struct xt_table packet_filter = { 54static const 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..0ad91433ed61 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -21,7 +21,7 @@ MODULE_DESCRIPTION("ip6tables mangle table");
21 (1 << NF_INET_LOCAL_OUT) | \ 21 (1 << NF_INET_LOCAL_OUT) | \
22 (1 << NF_INET_POST_ROUTING)) 22 (1 << NF_INET_POST_ROUTING))
23 23
24static struct 24static const struct
25{ 25{
26 struct ip6t_replace repl; 26 struct ip6t_replace repl;
27 struct ip6t_standard entries[5]; 27 struct ip6t_standard entries[5];
@@ -57,11 +57,11 @@ static struct
57 .term = IP6T_ERROR_INIT, /* ERROR */ 57 .term = IP6T_ERROR_INIT, /* ERROR */
58}; 58};
59 59
60static struct xt_table packet_mangler = { 60static const 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..ed1a1180f3b3 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -8,7 +8,7 @@
8 8
9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 9#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
10 10
11static struct 11static const struct
12{ 12{
13 struct ip6t_replace repl; 13 struct ip6t_replace repl;
14 struct ip6t_standard entries[2]; 14 struct ip6t_standard entries[2];
@@ -35,11 +35,11 @@ static struct
35 .term = IP6T_ERROR_INIT, /* ERROR */ 35 .term = IP6T_ERROR_INIT, /* ERROR */
36}; 36};
37 37
38static struct xt_table packet_raw = { 38static const 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..41b444c60934 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -26,7 +26,7 @@ MODULE_DESCRIPTION("ip6tables security table, for MAC rules");
26 (1 << NF_INET_FORWARD) | \ 26 (1 << NF_INET_FORWARD) | \
27 (1 << NF_INET_LOCAL_OUT) 27 (1 << NF_INET_LOCAL_OUT)
28 28
29static struct 29static const struct
30{ 30{
31 struct ip6t_replace repl; 31 struct ip6t_replace repl;
32 struct ip6t_standard entries[3]; 32 struct ip6t_standard entries[3];
@@ -56,11 +56,11 @@ static struct
56 .term = IP6T_ERROR_INIT, /* ERROR */ 56 .term = IP6T_ERROR_INIT, /* ERROR */
57}; 57};
58 58
59static struct xt_table security_table = { 59static const 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..5f2ec208a8c3 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -27,6 +27,7 @@
27#include <net/netfilter/nf_conntrack_l3proto.h> 27#include <net/netfilter/nf_conntrack_l3proto.h>
28#include <net/netfilter/nf_conntrack_core.h> 28#include <net/netfilter/nf_conntrack_core.h>
29#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> 29#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
30#include <net/netfilter/nf_log.h>
30 31
31static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 32static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
32 struct nf_conntrack_tuple *tuple) 33 struct nf_conntrack_tuple *tuple)
@@ -176,8 +177,11 @@ static unsigned int ipv6_confirm(unsigned int hooknum,
176 } 177 }
177 178
178 ret = helper->help(skb, protoff, ct, ctinfo); 179 ret = helper->help(skb, protoff, ct, ctinfo);
179 if (ret != NF_ACCEPT) 180 if (ret != NF_ACCEPT) {
181 nf_log_packet(NFPROTO_IPV6, hooknum, skb, in, out, NULL,
182 "nf_ct_%s: dropping packet", helper->name);
180 return ret; 183 return ret;
184 }
181out: 185out:
182 /* We've seen it coming out the other side: confirm it */ 186 /* We've seen it coming out the other side: confirm it */
183 return nf_conntrack_confirm(skb); 187 return nf_conntrack_confirm(skb);
@@ -265,42 +269,42 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
265 { 269 {
266 .hook = ipv6_defrag, 270 .hook = ipv6_defrag,
267 .owner = THIS_MODULE, 271 .owner = THIS_MODULE,
268 .pf = PF_INET6, 272 .pf = NFPROTO_IPV6,
269 .hooknum = NF_INET_PRE_ROUTING, 273 .hooknum = NF_INET_PRE_ROUTING,
270 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, 274 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
271 }, 275 },
272 { 276 {
273 .hook = ipv6_conntrack_in, 277 .hook = ipv6_conntrack_in,
274 .owner = THIS_MODULE, 278 .owner = THIS_MODULE,
275 .pf = PF_INET6, 279 .pf = NFPROTO_IPV6,
276 .hooknum = NF_INET_PRE_ROUTING, 280 .hooknum = NF_INET_PRE_ROUTING,
277 .priority = NF_IP6_PRI_CONNTRACK, 281 .priority = NF_IP6_PRI_CONNTRACK,
278 }, 282 },
279 { 283 {
280 .hook = ipv6_conntrack_local, 284 .hook = ipv6_conntrack_local,
281 .owner = THIS_MODULE, 285 .owner = THIS_MODULE,
282 .pf = PF_INET6, 286 .pf = NFPROTO_IPV6,
283 .hooknum = NF_INET_LOCAL_OUT, 287 .hooknum = NF_INET_LOCAL_OUT,
284 .priority = NF_IP6_PRI_CONNTRACK, 288 .priority = NF_IP6_PRI_CONNTRACK,
285 }, 289 },
286 { 290 {
287 .hook = ipv6_defrag, 291 .hook = ipv6_defrag,
288 .owner = THIS_MODULE, 292 .owner = THIS_MODULE,
289 .pf = PF_INET6, 293 .pf = NFPROTO_IPV6,
290 .hooknum = NF_INET_LOCAL_OUT, 294 .hooknum = NF_INET_LOCAL_OUT,
291 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, 295 .priority = NF_IP6_PRI_CONNTRACK_DEFRAG,
292 }, 296 },
293 { 297 {
294 .hook = ipv6_confirm, 298 .hook = ipv6_confirm,
295 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
296 .pf = PF_INET6, 300 .pf = NFPROTO_IPV6,
297 .hooknum = NF_INET_POST_ROUTING, 301 .hooknum = NF_INET_POST_ROUTING,
298 .priority = NF_IP6_PRI_LAST, 302 .priority = NF_IP6_PRI_LAST,
299 }, 303 },
300 { 304 {
301 .hook = ipv6_confirm, 305 .hook = ipv6_confirm,
302 .owner = THIS_MODULE, 306 .owner = THIS_MODULE,
303 .pf = PF_INET6, 307 .pf = NFPROTO_IPV6,
304 .hooknum = NF_INET_LOCAL_IN, 308 .hooknum = NF_INET_LOCAL_IN,
305 .priority = NF_IP6_PRI_LAST-1, 309 .priority = NF_IP6_PRI_LAST-1,
306 }, 310 },
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index b227750af752..b95699f00545 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1259,7 +1259,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
1259 struct ip_vs_iphdr iph; 1259 struct ip_vs_iphdr iph;
1260 struct ip_vs_protocol *pp; 1260 struct ip_vs_protocol *pp;
1261 struct ip_vs_conn *cp; 1261 struct ip_vs_conn *cp;
1262 int ret, restart, af; 1262 int ret, restart, af, pkts;
1263 1263
1264 af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; 1264 af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
1265 1265
@@ -1277,13 +1277,24 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
1277 return NF_ACCEPT; 1277 return NF_ACCEPT;
1278 } 1278 }
1279 1279
1280 if (unlikely(iph.protocol == IPPROTO_ICMP)) { 1280#ifdef CONFIG_IP_VS_IPV6
1281 int related, verdict = ip_vs_in_icmp(skb, &related, hooknum); 1281 if (af == AF_INET6) {
1282 if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
1283 int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum);
1282 1284
1283 if (related) 1285 if (related)
1284 return verdict; 1286 return verdict;
1285 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); 1287 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1286 } 1288 }
1289 } else
1290#endif
1291 if (unlikely(iph.protocol == IPPROTO_ICMP)) {
1292 int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
1293
1294 if (related)
1295 return verdict;
1296 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
1297 }
1287 1298
1288 /* Protocol supported? */ 1299 /* Protocol supported? */
1289 pp = ip_vs_proto_get(iph.protocol); 1300 pp = ip_vs_proto_get(iph.protocol);
@@ -1346,12 +1357,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
1346 * Sync connection if it is about to close to 1357 * Sync connection if it is about to close to
1347 * encorage the standby servers to update the connections timeout 1358 * encorage the standby servers to update the connections timeout
1348 */ 1359 */
1349 atomic_inc(&cp->in_pkts); 1360 pkts = atomic_add_return(1, &cp->in_pkts);
1350 if (af == AF_INET && 1361 if (af == AF_INET &&
1351 (ip_vs_sync_state & IP_VS_STATE_MASTER) && 1362 (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
1352 (((cp->protocol != IPPROTO_TCP || 1363 (((cp->protocol != IPPROTO_TCP ||
1353 cp->state == IP_VS_TCP_S_ESTABLISHED) && 1364 cp->state == IP_VS_TCP_S_ESTABLISHED) &&
1354 (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1] 1365 (pkts % sysctl_ip_vs_sync_threshold[1]
1355 == sysctl_ip_vs_sync_threshold[0])) || 1366 == sysctl_ip_vs_sync_threshold[0])) ||
1356 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && 1367 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
1357 ((cp->state == IP_VS_TCP_S_FIN_WAIT) || 1368 ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 70ff82cda57d..6182e8ea0be7 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -77,11 +77,12 @@ static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
77static int ip_vs_wrr_max_weight(struct ip_vs_service *svc) 77static int ip_vs_wrr_max_weight(struct ip_vs_service *svc)
78{ 78{
79 struct ip_vs_dest *dest; 79 struct ip_vs_dest *dest;
80 int weight = 0; 80 int new_weight, weight = 0;
81 81
82 list_for_each_entry(dest, &svc->destinations, n_list) { 82 list_for_each_entry(dest, &svc->destinations, n_list) {
83 if (atomic_read(&dest->weight) > weight) 83 new_weight = atomic_read(&dest->weight);
84 weight = atomic_read(&dest->weight); 84 if (new_weight > weight)
85 weight = new_weight;
85 } 86 }
86 87
87 return weight; 88 return weight;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index b5869b9574b0..b37109817a98 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -47,7 +47,7 @@
47 47
48int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct, 48int (*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
49 enum nf_nat_manip_type manip, 49 enum nf_nat_manip_type manip,
50 struct nlattr *attr) __read_mostly; 50 const struct nlattr *attr) __read_mostly;
51EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook); 51EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
52 52
53DEFINE_SPINLOCK(nf_conntrack_lock); 53DEFINE_SPINLOCK(nf_conntrack_lock);
@@ -1089,14 +1089,14 @@ void nf_conntrack_flush_report(struct net *net, u32 pid, int report)
1089} 1089}
1090EXPORT_SYMBOL_GPL(nf_conntrack_flush_report); 1090EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
1091 1091
1092static void nf_ct_release_dying_list(void) 1092static void nf_ct_release_dying_list(struct net *net)
1093{ 1093{
1094 struct nf_conntrack_tuple_hash *h; 1094 struct nf_conntrack_tuple_hash *h;
1095 struct nf_conn *ct; 1095 struct nf_conn *ct;
1096 struct hlist_nulls_node *n; 1096 struct hlist_nulls_node *n;
1097 1097
1098 spin_lock_bh(&nf_conntrack_lock); 1098 spin_lock_bh(&nf_conntrack_lock);
1099 hlist_nulls_for_each_entry(h, n, &init_net.ct.dying, hnnode) { 1099 hlist_nulls_for_each_entry(h, n, &net->ct.dying, hnnode) {
1100 ct = nf_ct_tuplehash_to_ctrack(h); 1100 ct = nf_ct_tuplehash_to_ctrack(h);
1101 /* never fails to remove them, no listeners at this point */ 1101 /* never fails to remove them, no listeners at this point */
1102 nf_ct_kill(ct); 1102 nf_ct_kill(ct);
@@ -1115,7 +1115,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
1115{ 1115{
1116 i_see_dead_people: 1116 i_see_dead_people:
1117 nf_ct_iterate_cleanup(net, kill_all, NULL); 1117 nf_ct_iterate_cleanup(net, kill_all, NULL);
1118 nf_ct_release_dying_list(); 1118 nf_ct_release_dying_list(net);
1119 if (atomic_read(&net->ct.count) != 0) { 1119 if (atomic_read(&net->ct.count) != 0) {
1120 schedule(); 1120 schedule();
1121 goto i_see_dead_people; 1121 goto i_see_dead_people;
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 49479d194570..59d8064eb522 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -704,7 +704,8 @@ ctnetlink_parse_tuple_proto(struct nlattr *attr,
704} 704}
705 705
706static int 706static int
707ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple, 707ctnetlink_parse_tuple(const struct nlattr * const cda[],
708 struct nf_conntrack_tuple *tuple,
708 enum ctattr_tuple type, u_int8_t l3num) 709 enum ctattr_tuple type, u_int8_t l3num)
709{ 710{
710 struct nlattr *tb[CTA_TUPLE_MAX+1]; 711 struct nlattr *tb[CTA_TUPLE_MAX+1];
@@ -740,7 +741,7 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
740} 741}
741 742
742static inline int 743static inline int
743ctnetlink_parse_help(struct nlattr *attr, char **helper_name) 744ctnetlink_parse_help(const struct nlattr *attr, char **helper_name)
744{ 745{
745 struct nlattr *tb[CTA_HELP_MAX+1]; 746 struct nlattr *tb[CTA_HELP_MAX+1];
746 747
@@ -764,7 +765,8 @@ static const struct nla_policy ct_nla_policy[CTA_MAX+1] = {
764 765
765static int 766static int
766ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb, 767ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
767 struct nlmsghdr *nlh, struct nlattr *cda[]) 768 const struct nlmsghdr *nlh,
769 const struct nlattr * const cda[])
768{ 770{
769 struct nf_conntrack_tuple_hash *h; 771 struct nf_conntrack_tuple_hash *h;
770 struct nf_conntrack_tuple tuple; 772 struct nf_conntrack_tuple tuple;
@@ -823,7 +825,8 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
823 825
824static int 826static int
825ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, 827ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
826 struct nlmsghdr *nlh, struct nlattr *cda[]) 828 const struct nlmsghdr *nlh,
829 const struct nlattr * const cda[])
827{ 830{
828 struct nf_conntrack_tuple_hash *h; 831 struct nf_conntrack_tuple_hash *h;
829 struct nf_conntrack_tuple tuple; 832 struct nf_conntrack_tuple tuple;
@@ -884,7 +887,7 @@ out:
884static int 887static int
885ctnetlink_parse_nat_setup(struct nf_conn *ct, 888ctnetlink_parse_nat_setup(struct nf_conn *ct,
886 enum nf_nat_manip_type manip, 889 enum nf_nat_manip_type manip,
887 struct nlattr *attr) 890 const struct nlattr *attr)
888{ 891{
889 typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup; 892 typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
890 893
@@ -914,7 +917,7 @@ ctnetlink_parse_nat_setup(struct nf_conn *ct,
914#endif 917#endif
915 918
916static int 919static int
917ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) 920ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
918{ 921{
919 unsigned long d; 922 unsigned long d;
920 unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS])); 923 unsigned int status = ntohl(nla_get_be32(cda[CTA_STATUS]));
@@ -940,7 +943,7 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
940} 943}
941 944
942static int 945static int
943ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[]) 946ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[])
944{ 947{
945#ifdef CONFIG_NF_NAT_NEEDED 948#ifdef CONFIG_NF_NAT_NEEDED
946 int ret; 949 int ret;
@@ -966,7 +969,7 @@ ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
966} 969}
967 970
968static inline int 971static inline int
969ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[]) 972ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[])
970{ 973{
971 struct nf_conntrack_helper *helper; 974 struct nf_conntrack_helper *helper;
972 struct nf_conn_help *help = nfct_help(ct); 975 struct nf_conn_help *help = nfct_help(ct);
@@ -1028,7 +1031,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
1028} 1031}
1029 1032
1030static inline int 1033static inline int
1031ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[]) 1034ctnetlink_change_timeout(struct nf_conn *ct, const struct nlattr * const cda[])
1032{ 1035{
1033 u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT])); 1036 u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT]));
1034 1037
@@ -1042,9 +1045,10 @@ ctnetlink_change_timeout(struct nf_conn *ct, struct nlattr *cda[])
1042} 1045}
1043 1046
1044static inline int 1047static inline int
1045ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[]) 1048ctnetlink_change_protoinfo(struct nf_conn *ct, const struct nlattr * const cda[])
1046{ 1049{
1047 struct nlattr *tb[CTA_PROTOINFO_MAX+1], *attr = cda[CTA_PROTOINFO]; 1050 const struct nlattr *attr = cda[CTA_PROTOINFO];
1051 struct nlattr *tb[CTA_PROTOINFO_MAX+1];
1048 struct nf_conntrack_l4proto *l4proto; 1052 struct nf_conntrack_l4proto *l4proto;
1049 int err = 0; 1053 int err = 0;
1050 1054
@@ -1061,7 +1065,7 @@ ctnetlink_change_protoinfo(struct nf_conn *ct, struct nlattr *cda[])
1061 1065
1062#ifdef CONFIG_NF_NAT_NEEDED 1066#ifdef CONFIG_NF_NAT_NEEDED
1063static inline int 1067static inline int
1064change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr) 1068change_nat_seq_adj(struct nf_nat_seq *natseq, const struct nlattr * const attr)
1065{ 1069{
1066 struct nlattr *cda[CTA_NAT_SEQ_MAX+1]; 1070 struct nlattr *cda[CTA_NAT_SEQ_MAX+1];
1067 1071
@@ -1089,7 +1093,8 @@ change_nat_seq_adj(struct nf_nat_seq *natseq, struct nlattr *attr)
1089} 1093}
1090 1094
1091static int 1095static int
1092ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[]) 1096ctnetlink_change_nat_seq_adj(struct nf_conn *ct,
1097 const struct nlattr * const cda[])
1093{ 1098{
1094 int ret = 0; 1099 int ret = 0;
1095 struct nf_conn_nat *nat = nfct_nat(ct); 1100 struct nf_conn_nat *nat = nfct_nat(ct);
@@ -1120,7 +1125,8 @@ ctnetlink_change_nat_seq_adj(struct nf_conn *ct, struct nlattr *cda[])
1120#endif 1125#endif
1121 1126
1122static int 1127static int
1123ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[]) 1128ctnetlink_change_conntrack(struct nf_conn *ct,
1129 const struct nlattr * const cda[])
1124{ 1130{
1125 int err; 1131 int err;
1126 1132
@@ -1169,7 +1175,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nlattr *cda[])
1169} 1175}
1170 1176
1171static struct nf_conn * 1177static struct nf_conn *
1172ctnetlink_create_conntrack(struct nlattr *cda[], 1178ctnetlink_create_conntrack(const struct nlattr * const cda[],
1173 struct nf_conntrack_tuple *otuple, 1179 struct nf_conntrack_tuple *otuple,
1174 struct nf_conntrack_tuple *rtuple, 1180 struct nf_conntrack_tuple *rtuple,
1175 u8 u3) 1181 u8 u3)
@@ -1304,7 +1310,8 @@ err1:
1304 1310
1305static int 1311static int
1306ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, 1312ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1307 struct nlmsghdr *nlh, struct nlattr *cda[]) 1313 const struct nlmsghdr *nlh,
1314 const struct nlattr * const cda[])
1308{ 1315{
1309 struct nf_conntrack_tuple otuple, rtuple; 1316 struct nf_conntrack_tuple otuple, rtuple;
1310 struct nf_conntrack_tuple_hash *h = NULL; 1317 struct nf_conntrack_tuple_hash *h = NULL;
@@ -1629,7 +1636,8 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
1629 1636
1630static int 1637static int
1631ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, 1638ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1632 struct nlmsghdr *nlh, struct nlattr *cda[]) 1639 const struct nlmsghdr *nlh,
1640 const struct nlattr * const cda[])
1633{ 1641{
1634 struct nf_conntrack_tuple tuple; 1642 struct nf_conntrack_tuple tuple;
1635 struct nf_conntrack_expect *exp; 1643 struct nf_conntrack_expect *exp;
@@ -1689,7 +1697,8 @@ out:
1689 1697
1690static int 1698static int
1691ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, 1699ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1692 struct nlmsghdr *nlh, struct nlattr *cda[]) 1700 const struct nlmsghdr *nlh,
1701 const struct nlattr * const cda[])
1693{ 1702{
1694 struct nf_conntrack_expect *exp; 1703 struct nf_conntrack_expect *exp;
1695 struct nf_conntrack_tuple tuple; 1704 struct nf_conntrack_tuple tuple;
@@ -1767,13 +1776,15 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1767 return 0; 1776 return 0;
1768} 1777}
1769static int 1778static int
1770ctnetlink_change_expect(struct nf_conntrack_expect *x, struct nlattr *cda[]) 1779ctnetlink_change_expect(struct nf_conntrack_expect *x,
1780 const struct nlattr * const cda[])
1771{ 1781{
1772 return -EOPNOTSUPP; 1782 return -EOPNOTSUPP;
1773} 1783}
1774 1784
1775static int 1785static int
1776ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3, u32 pid, int report) 1786ctnetlink_create_expect(const struct nlattr * const cda[], u_int8_t u3,
1787 u32 pid, int report)
1777{ 1788{
1778 struct nf_conntrack_tuple tuple, mask, master_tuple; 1789 struct nf_conntrack_tuple tuple, mask, master_tuple;
1779 struct nf_conntrack_tuple_hash *h = NULL; 1790 struct nf_conntrack_tuple_hash *h = NULL;
@@ -1831,7 +1842,8 @@ out:
1831 1842
1832static int 1843static int
1833ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb, 1844ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1834 struct nlmsghdr *nlh, struct nlattr *cda[]) 1845 const struct nlmsghdr *nlh,
1846 const struct nlattr * const cda[])
1835{ 1847{
1836 struct nf_conntrack_tuple tuple; 1848 struct nf_conntrack_tuple tuple;
1837 struct nf_conntrack_expect *exp; 1849 struct nf_conntrack_expect *exp;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 92761a988375..eedc0c1ac7a4 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -170,7 +170,7 @@ replay:
170 if (err < 0) 170 if (err < 0)
171 return err; 171 return err;
172 172
173 err = nc->call(nfnl, skb, nlh, cda); 173 err = nc->call(nfnl, skb, nlh, (const struct nlattr **)cda);
174 if (err == -EAGAIN) 174 if (err == -EAGAIN)
175 goto replay; 175 goto replay;
176 return err; 176 return err;
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 66a6dd5c519a..f900dc3194af 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -694,7 +694,8 @@ static struct notifier_block nfulnl_rtnl_notifier = {
694 694
695static int 695static int
696nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb, 696nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
697 struct nlmsghdr *nlh, struct nlattr *nfqa[]) 697 const struct nlmsghdr *nlh,
698 const struct nlattr * const nfqa[])
698{ 699{
699 return -ENOTSUPP; 700 return -ENOTSUPP;
700} 701}
@@ -716,7 +717,8 @@ static const struct nla_policy nfula_cfg_policy[NFULA_CFG_MAX+1] = {
716 717
717static int 718static int
718nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, 719nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
719 struct nlmsghdr *nlh, struct nlattr *nfula[]) 720 const struct nlmsghdr *nlh,
721 const struct nlattr * const nfula[])
720{ 722{
721 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 723 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
722 u_int16_t group_num = ntohs(nfmsg->res_id); 724 u_int16_t group_num = ntohs(nfmsg->res_id);
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 71daa0934b6c..7a9dec9fb822 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -608,7 +608,8 @@ static const struct nla_policy nfqa_verdict_policy[NFQA_MAX+1] = {
608 608
609static int 609static int
610nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, 610nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
611 struct nlmsghdr *nlh, struct nlattr *nfqa[]) 611 const struct nlmsghdr *nlh,
612 const struct nlattr * const nfqa[])
612{ 613{
613 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 614 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
614 u_int16_t queue_num = ntohs(nfmsg->res_id); 615 u_int16_t queue_num = ntohs(nfmsg->res_id);
@@ -670,7 +671,8 @@ err_out_unlock:
670 671
671static int 672static int
672nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb, 673nfqnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
673 struct nlmsghdr *nlh, struct nlattr *nfqa[]) 674 const struct nlmsghdr *nlh,
675 const struct nlattr * const nfqa[])
674{ 676{
675 return -ENOTSUPP; 677 return -ENOTSUPP;
676} 678}
@@ -687,7 +689,8 @@ static const struct nf_queue_handler nfqh = {
687 689
688static int 690static int
689nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, 691nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
690 struct nlmsghdr *nlh, struct nlattr *nfqa[]) 692 const struct nlmsghdr *nlh,
693 const struct nlattr * const nfqa[])
691{ 694{
692 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); 695 struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
693 u_int16_t queue_num = ntohs(nfmsg->res_id); 696 u_int16_t queue_num = ntohs(nfmsg->res_id);
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 025d1a0af78b..a6ac83a93348 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -736,16 +736,17 @@ xt_replace_table(struct xt_table *table,
736} 736}
737EXPORT_SYMBOL_GPL(xt_replace_table); 737EXPORT_SYMBOL_GPL(xt_replace_table);
738 738
739struct xt_table *xt_register_table(struct net *net, struct xt_table *table, 739struct xt_table *xt_register_table(struct net *net,
740 const struct xt_table *input_table,
740 struct xt_table_info *bootstrap, 741 struct xt_table_info *bootstrap,
741 struct xt_table_info *newinfo) 742 struct xt_table_info *newinfo)
742{ 743{
743 int ret; 744 int ret;
744 struct xt_table_info *private; 745 struct xt_table_info *private;
745 struct xt_table *t; 746 struct xt_table *t, *table;
746 747
747 /* Don't add one object to multiple lists. */ 748 /* Don't add one object to multiple lists. */
748 table = kmemdup(table, sizeof(struct xt_table), GFP_KERNEL); 749 table = kmemdup(input_table, sizeof(struct xt_table), GFP_KERNEL);
749 if (!table) { 750 if (!table) {
750 ret = -ENOMEM; 751 ret = -ENOMEM;
751 goto out; 752 goto out;
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_osf.c b/net/netfilter/xt_osf.c
index 0f482e2440b4..63e190504656 100644
--- a/net/netfilter/xt_osf.c
+++ b/net/netfilter/xt_osf.c
@@ -70,7 +70,8 @@ static void xt_osf_finger_free_rcu(struct rcu_head *rcu_head)
70} 70}
71 71
72static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb, 72static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
73 struct nlmsghdr *nlh, struct nlattr *osf_attrs[]) 73 const struct nlmsghdr *nlh,
74 const struct nlattr * const osf_attrs[])
74{ 75{
75 struct xt_osf_user_finger *f; 76 struct xt_osf_user_finger *f;
76 struct xt_osf_finger *kf = NULL, *sf; 77 struct xt_osf_finger *kf = NULL, *sf;
@@ -112,7 +113,8 @@ static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
112} 113}
113 114
114static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb, 115static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
115 struct nlmsghdr *nlh, struct nlattr *osf_attrs[]) 116 const struct nlmsghdr *nlh,
117 const struct nlattr * const osf_attrs[])
116{ 118{
117 struct xt_osf_user_finger *f; 119 struct xt_osf_user_finger *f;
118 struct xt_osf_finger *sf; 120 struct xt_osf_finger *sf;
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");
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index da3163d15ef0..d0ff382c40ca 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1705,7 +1705,7 @@ errout:
1705} 1705}
1706 1706
1707int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, 1707int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1708 struct nlmsghdr *nlh, 1708 const struct nlmsghdr *nlh,
1709 int (*dump)(struct sk_buff *skb, 1709 int (*dump)(struct sk_buff *skb,
1710 struct netlink_callback *), 1710 struct netlink_callback *),
1711 int (*done)(struct netlink_callback *)) 1711 int (*done)(struct netlink_callback *))
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9d03cc33b6cc..2dfb3e7a040d 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1011,7 +1011,7 @@ replay:
1011} 1011}
1012 1012
1013static struct nlattr * 1013static struct nlattr *
1014find_dump_kind(struct nlmsghdr *n) 1014find_dump_kind(const struct nlmsghdr *n)
1015{ 1015{
1016 struct nlattr *tb1, *tb2[TCA_ACT_MAX+1]; 1016 struct nlattr *tb1, *tb2[TCA_ACT_MAX+1];
1017 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; 1017 struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];