aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-27 01:45:23 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-27 01:45:23 -0400
commit01e6de64d9c8d0e75dca3bb4cf898db73abe00d4 (patch)
tree925982e6241e5ac47f268bc2c2942ab0f06775cd /net
parent8f1ead2d1a626ed0c85b3d2c2046a49081d5933f (diff)
parentd271e8bd8c60ce059ee36d836ba063cfc61c3e21 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/netfilter/arp_tables.c18
-rw-r--r--net/ipv4/netfilter/ip_tables.c27
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c63
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c6
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c2
-rw-r--r--net/ipv6/netfilter/ip6_tables.c27
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c6
-rw-r--r--net/netfilter/Kconfig2
-rw-r--r--net/netfilter/nf_conntrack_core.c129
-rw-r--r--net/netfilter/nf_conntrack_expect.c2
-rw-r--r--net/netfilter/nf_conntrack_helper.c8
-rw-r--r--net/netfilter/nf_conntrack_netlink.c94
-rw-r--r--net/netfilter/nf_conntrack_proto.c16
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c9
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c1
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c10
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c15
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c1
-rw-r--r--net/netfilter/nf_conntrack_standalone.c57
-rw-r--r--net/netfilter/xt_connlimit.c6
-rw-r--r--net/netfilter/xt_physdev.c21
24 files changed, 335 insertions, 199 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 84b9c179df51..35c5f6a5cb7c 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -81,19 +81,7 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
81static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask) 81static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask)
82{ 82{
83#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 83#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
84 const unsigned long *a = (const unsigned long *)_a; 84 unsigned long ret = ifname_compare_aligned(_a, _b, _mask);
85 const unsigned long *b = (const unsigned long *)_b;
86 const unsigned long *mask = (const unsigned long *)_mask;
87 unsigned long ret;
88
89 ret = (a[0] ^ b[0]) & mask[0];
90 if (IFNAMSIZ > sizeof(unsigned long))
91 ret |= (a[1] ^ b[1]) & mask[1];
92 if (IFNAMSIZ > 2 * sizeof(unsigned long))
93 ret |= (a[2] ^ b[2]) & mask[2];
94 if (IFNAMSIZ > 3 * sizeof(unsigned long))
95 ret |= (a[3] ^ b[3]) & mask[3];
96 BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
97#else 85#else
98 unsigned long ret = 0; 86 unsigned long ret = 0;
99 const u16 *a = (const u16 *)_a; 87 const u16 *a = (const u16 *)_a;
@@ -404,7 +392,9 @@ static int mark_source_chains(struct xt_table_info *newinfo,
404 && unconditional(&e->arp)) || visited) { 392 && unconditional(&e->arp)) || visited) {
405 unsigned int oldpos, size; 393 unsigned int oldpos, size;
406 394
407 if (t->verdict < -NF_MAX_VERDICT - 1) { 395 if ((strcmp(t->target.u.user.name,
396 ARPT_STANDARD_TARGET) == 0) &&
397 t->verdict < -NF_MAX_VERDICT - 1) {
408 duprintf("mark_source_chains: bad " 398 duprintf("mark_source_chains: bad "
409 "negative verdict (%i)\n", 399 "negative verdict (%i)\n",
410 t->verdict); 400 t->verdict);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index e5294aec967d..82ee7c9049ff 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -74,25 +74,6 @@ do { \
74 74
75 Hence the start of any table is given by get_table() below. */ 75 Hence the start of any table is given by get_table() below. */
76 76
77static unsigned long ifname_compare(const char *_a, const char *_b,
78 const unsigned char *_mask)
79{
80 const unsigned long *a = (const unsigned long *)_a;
81 const unsigned long *b = (const unsigned long *)_b;
82 const unsigned long *mask = (const unsigned long *)_mask;
83 unsigned long ret;
84
85 ret = (a[0] ^ b[0]) & mask[0];
86 if (IFNAMSIZ > sizeof(unsigned long))
87 ret |= (a[1] ^ b[1]) & mask[1];
88 if (IFNAMSIZ > 2 * sizeof(unsigned long))
89 ret |= (a[2] ^ b[2]) & mask[2];
90 if (IFNAMSIZ > 3 * sizeof(unsigned long))
91 ret |= (a[3] ^ b[3]) & mask[3];
92 BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
93 return ret;
94}
95
96/* Returns whether matches rule or not. */ 77/* Returns whether matches rule or not. */
97/* Performance critical - called for every packet */ 78/* Performance critical - called for every packet */
98static inline bool 79static inline bool
@@ -121,7 +102,7 @@ ip_packet_match(const struct iphdr *ip,
121 return false; 102 return false;
122 } 103 }
123 104
124 ret = ifname_compare(indev, ipinfo->iniface, ipinfo->iniface_mask); 105 ret = ifname_compare_aligned(indev, ipinfo->iniface, ipinfo->iniface_mask);
125 106
126 if (FWINV(ret != 0, IPT_INV_VIA_IN)) { 107 if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
127 dprintf("VIA in mismatch (%s vs %s).%s\n", 108 dprintf("VIA in mismatch (%s vs %s).%s\n",
@@ -130,7 +111,7 @@ ip_packet_match(const struct iphdr *ip,
130 return false; 111 return false;
131 } 112 }
132 113
133 ret = ifname_compare(outdev, ipinfo->outiface, ipinfo->outiface_mask); 114 ret = ifname_compare_aligned(outdev, ipinfo->outiface, ipinfo->outiface_mask);
134 115
135 if (FWINV(ret != 0, IPT_INV_VIA_OUT)) { 116 if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
136 dprintf("VIA out mismatch (%s vs %s).%s\n", 117 dprintf("VIA out mismatch (%s vs %s).%s\n",
@@ -507,7 +488,9 @@ mark_source_chains(struct xt_table_info *newinfo,
507 && unconditional(&e->ip)) || visited) { 488 && unconditional(&e->ip)) || visited) {
508 unsigned int oldpos, size; 489 unsigned int oldpos, size;
509 490
510 if (t->verdict < -NF_MAX_VERDICT - 1) { 491 if ((strcmp(t->target.u.user.name,
492 IPT_STANDARD_TARGET) == 0) &&
493 t->verdict < -NF_MAX_VERDICT - 1) {
511 duprintf("mark_source_chains: bad " 494 duprintf("mark_source_chains: bad "
512 "negative verdict (%i)\n", 495 "negative verdict (%i)\n",
513 t->verdict); 496 t->verdict);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8b681f24e271..7d2ead7228ac 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -328,6 +328,11 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
328 328
329 return 0; 329 return 0;
330} 330}
331
332static int ipv4_nlattr_tuple_size(void)
333{
334 return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1);
335}
331#endif 336#endif
332 337
333static struct nf_sockopt_ops so_getorigdst = { 338static struct nf_sockopt_ops so_getorigdst = {
@@ -347,6 +352,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
347 .get_l4proto = ipv4_get_l4proto, 352 .get_l4proto = ipv4_get_l4proto,
348#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 353#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
349 .tuple_to_nlattr = ipv4_tuple_to_nlattr, 354 .tuple_to_nlattr = ipv4_tuple_to_nlattr,
355 .nlattr_tuple_size = ipv4_nlattr_tuple_size,
350 .nlattr_to_tuple = ipv4_nlattr_to_tuple, 356 .nlattr_to_tuple = ipv4_nlattr_to_tuple,
351 .nla_policy = ipv4_nla_policy, 357 .nla_policy = ipv4_nla_policy,
352#endif 358#endif
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 6ba5c557690c..8668a3defda6 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -25,40 +25,42 @@ struct ct_iter_state {
25 unsigned int bucket; 25 unsigned int bucket;
26}; 26};
27 27
28static struct hlist_node *ct_get_first(struct seq_file *seq) 28static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
29{ 29{
30 struct net *net = seq_file_net(seq); 30 struct net *net = seq_file_net(seq);
31 struct ct_iter_state *st = seq->private; 31 struct ct_iter_state *st = seq->private;
32 struct hlist_node *n; 32 struct hlist_nulls_node *n;
33 33
34 for (st->bucket = 0; 34 for (st->bucket = 0;
35 st->bucket < nf_conntrack_htable_size; 35 st->bucket < nf_conntrack_htable_size;
36 st->bucket++) { 36 st->bucket++) {
37 n = rcu_dereference(net->ct.hash[st->bucket].first); 37 n = rcu_dereference(net->ct.hash[st->bucket].first);
38 if (n) 38 if (!is_a_nulls(n))
39 return n; 39 return n;
40 } 40 }
41 return NULL; 41 return NULL;
42} 42}
43 43
44static struct hlist_node *ct_get_next(struct seq_file *seq, 44static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
45 struct hlist_node *head) 45 struct hlist_nulls_node *head)
46{ 46{
47 struct net *net = seq_file_net(seq); 47 struct net *net = seq_file_net(seq);
48 struct ct_iter_state *st = seq->private; 48 struct ct_iter_state *st = seq->private;
49 49
50 head = rcu_dereference(head->next); 50 head = rcu_dereference(head->next);
51 while (head == NULL) { 51 while (is_a_nulls(head)) {
52 if (++st->bucket >= nf_conntrack_htable_size) 52 if (likely(get_nulls_value(head) == st->bucket)) {
53 return NULL; 53 if (++st->bucket >= nf_conntrack_htable_size)
54 return NULL;
55 }
54 head = rcu_dereference(net->ct.hash[st->bucket].first); 56 head = rcu_dereference(net->ct.hash[st->bucket].first);
55 } 57 }
56 return head; 58 return head;
57} 59}
58 60
59static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos) 61static struct hlist_nulls_node *ct_get_idx(struct seq_file *seq, loff_t pos)
60{ 62{
61 struct hlist_node *head = ct_get_first(seq); 63 struct hlist_nulls_node *head = ct_get_first(seq);
62 64
63 if (head) 65 if (head)
64 while (pos && (head = ct_get_next(seq, head))) 66 while (pos && (head = ct_get_next(seq, head)))
@@ -87,69 +89,76 @@ static void ct_seq_stop(struct seq_file *s, void *v)
87 89
88static int ct_seq_show(struct seq_file *s, void *v) 90static int ct_seq_show(struct seq_file *s, void *v)
89{ 91{
90 const struct nf_conntrack_tuple_hash *hash = v; 92 struct nf_conntrack_tuple_hash *hash = v;
91 const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash); 93 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
92 const struct nf_conntrack_l3proto *l3proto; 94 const struct nf_conntrack_l3proto *l3proto;
93 const struct nf_conntrack_l4proto *l4proto; 95 const struct nf_conntrack_l4proto *l4proto;
96 int ret = 0;
94 97
95 NF_CT_ASSERT(ct); 98 NF_CT_ASSERT(ct);
99 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
100 return 0;
101
96 102
97 /* we only want to print DIR_ORIGINAL */ 103 /* we only want to print DIR_ORIGINAL */
98 if (NF_CT_DIRECTION(hash)) 104 if (NF_CT_DIRECTION(hash))
99 return 0; 105 goto release;
100 if (nf_ct_l3num(ct) != AF_INET) 106 if (nf_ct_l3num(ct) != AF_INET)
101 return 0; 107 goto release;
102 108
103 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); 109 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
104 NF_CT_ASSERT(l3proto); 110 NF_CT_ASSERT(l3proto);
105 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); 111 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
106 NF_CT_ASSERT(l4proto); 112 NF_CT_ASSERT(l4proto);
107 113
114 ret = -ENOSPC;
108 if (seq_printf(s, "%-8s %u %ld ", 115 if (seq_printf(s, "%-8s %u %ld ",
109 l4proto->name, nf_ct_protonum(ct), 116 l4proto->name, nf_ct_protonum(ct),
110 timer_pending(&ct->timeout) 117 timer_pending(&ct->timeout)
111 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) 118 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
112 return -ENOSPC; 119 goto release;
113 120
114 if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct)) 121 if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
115 return -ENOSPC; 122 goto release;
116 123
117 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 124 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
118 l3proto, l4proto)) 125 l3proto, l4proto))
119 return -ENOSPC; 126 goto release;
120 127
121 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) 128 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
122 return -ENOSPC; 129 goto release;
123 130
124 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) 131 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
125 if (seq_printf(s, "[UNREPLIED] ")) 132 if (seq_printf(s, "[UNREPLIED] "))
126 return -ENOSPC; 133 goto release;
127 134
128 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, 135 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
129 l3proto, l4proto)) 136 l3proto, l4proto))
130 return -ENOSPC; 137 goto release;
131 138
132 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) 139 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
133 return -ENOSPC; 140 goto release;
134 141
135 if (test_bit(IPS_ASSURED_BIT, &ct->status)) 142 if (test_bit(IPS_ASSURED_BIT, &ct->status))
136 if (seq_printf(s, "[ASSURED] ")) 143 if (seq_printf(s, "[ASSURED] "))
137 return -ENOSPC; 144 goto release;
138 145
139#ifdef CONFIG_NF_CONNTRACK_MARK 146#ifdef CONFIG_NF_CONNTRACK_MARK
140 if (seq_printf(s, "mark=%u ", ct->mark)) 147 if (seq_printf(s, "mark=%u ", ct->mark))
141 return -ENOSPC; 148 goto release;
142#endif 149#endif
143 150
144#ifdef CONFIG_NF_CONNTRACK_SECMARK 151#ifdef CONFIG_NF_CONNTRACK_SECMARK
145 if (seq_printf(s, "secmark=%u ", ct->secmark)) 152 if (seq_printf(s, "secmark=%u ", ct->secmark))
146 return -ENOSPC; 153 goto release;
147#endif 154#endif
148 155
149 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use))) 156 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
150 return -ENOSPC; 157 goto release;
151 158 ret = 0;
152 return 0; 159release:
160 nf_ct_put(ct);
161 return ret;
153} 162}
154 163
155static const struct seq_operations ct_seq_ops = { 164static const struct seq_operations ct_seq_ops = {
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 2a8bee26f43d..23b2c2ee869a 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -262,6 +262,11 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[],
262 262
263 return 0; 263 return 0;
264} 264}
265
266static int icmp_nlattr_tuple_size(void)
267{
268 return nla_policy_len(icmp_nla_policy, CTA_PROTO_MAX + 1);
269}
265#endif 270#endif
266 271
267#ifdef CONFIG_SYSCTL 272#ifdef CONFIG_SYSCTL
@@ -309,6 +314,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
309 .me = NULL, 314 .me = NULL,
310#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 315#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
311 .tuple_to_nlattr = icmp_tuple_to_nlattr, 316 .tuple_to_nlattr = icmp_tuple_to_nlattr,
317 .nlattr_tuple_size = icmp_nlattr_tuple_size,
312 .nlattr_to_tuple = icmp_nlattr_to_tuple, 318 .nlattr_to_tuple = icmp_nlattr_to_tuple,
313 .nla_policy = icmp_nla_policy, 319 .nla_policy = icmp_nla_policy,
314#endif 320#endif
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index a65cf692359f..fe65187810f0 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -679,7 +679,7 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
679static int __net_init nf_nat_net_init(struct net *net) 679static int __net_init nf_nat_net_init(struct net *net)
680{ 680{
681 net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 681 net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
682 &net->ipv4.nat_vmalloced); 682 &net->ipv4.nat_vmalloced, 0);
683 if (!net->ipv4.nat_bysource) 683 if (!net->ipv4.nat_bysource)
684 return -ENOMEM; 684 return -ENOMEM;
685 return 0; 685 return 0;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 34af7bb8df5f..e89cfa3a8f25 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -89,25 +89,6 @@ ip6t_ext_hdr(u8 nexthdr)
89 (nexthdr == IPPROTO_DSTOPTS) ); 89 (nexthdr == IPPROTO_DSTOPTS) );
90} 90}
91 91
92static unsigned long ifname_compare(const char *_a, const char *_b,
93 const unsigned char *_mask)
94{
95 const unsigned long *a = (const unsigned long *)_a;
96 const unsigned long *b = (const unsigned long *)_b;
97 const unsigned long *mask = (const unsigned long *)_mask;
98 unsigned long ret;
99
100 ret = (a[0] ^ b[0]) & mask[0];
101 if (IFNAMSIZ > sizeof(unsigned long))
102 ret |= (a[1] ^ b[1]) & mask[1];
103 if (IFNAMSIZ > 2 * sizeof(unsigned long))
104 ret |= (a[2] ^ b[2]) & mask[2];
105 if (IFNAMSIZ > 3 * sizeof(unsigned long))
106 ret |= (a[3] ^ b[3]) & mask[3];
107 BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
108 return ret;
109}
110
111/* Returns whether matches rule or not. */ 92/* Returns whether matches rule or not. */
112/* Performance critical - called for every packet */ 93/* Performance critical - called for every packet */
113static inline bool 94static inline bool
@@ -138,7 +119,7 @@ ip6_packet_match(const struct sk_buff *skb,
138 return false; 119 return false;
139 } 120 }
140 121
141 ret = ifname_compare(indev, ip6info->iniface, ip6info->iniface_mask); 122 ret = ifname_compare_aligned(indev, ip6info->iniface, ip6info->iniface_mask);
142 123
143 if (FWINV(ret != 0, IP6T_INV_VIA_IN)) { 124 if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
144 dprintf("VIA in mismatch (%s vs %s).%s\n", 125 dprintf("VIA in mismatch (%s vs %s).%s\n",
@@ -147,7 +128,7 @@ ip6_packet_match(const struct sk_buff *skb,
147 return false; 128 return false;
148 } 129 }
149 130
150 ret = ifname_compare(outdev, ip6info->outiface, ip6info->outiface_mask); 131 ret = ifname_compare_aligned(outdev, ip6info->outiface, ip6info->outiface_mask);
151 132
152 if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) { 133 if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
153 dprintf("VIA out mismatch (%s vs %s).%s\n", 134 dprintf("VIA out mismatch (%s vs %s).%s\n",
@@ -536,7 +517,9 @@ mark_source_chains(struct xt_table_info *newinfo,
536 && unconditional(&e->ipv6)) || visited) { 517 && unconditional(&e->ipv6)) || visited) {
537 unsigned int oldpos, size; 518 unsigned int oldpos, size;
538 519
539 if (t->verdict < -NF_MAX_VERDICT - 1) { 520 if ((strcmp(t->target.u.user.name,
521 IP6T_STANDARD_TARGET) == 0) &&
522 t->verdict < -NF_MAX_VERDICT - 1) {
540 duprintf("mark_source_chains: bad " 523 duprintf("mark_source_chains: bad "
541 "negative verdict (%i)\n", 524 "negative verdict (%i)\n",
542 t->verdict); 525 t->verdict);
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e6852f617217..2a15c2d66c69 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -342,6 +342,11 @@ static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
342 342
343 return 0; 343 return 0;
344} 344}
345
346static int ipv6_nlattr_tuple_size(void)
347{
348 return nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1);
349}
345#endif 350#endif
346 351
347struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { 352struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
@@ -353,6 +358,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
353 .get_l4proto = ipv6_get_l4proto, 358 .get_l4proto = ipv6_get_l4proto,
354#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 359#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
355 .tuple_to_nlattr = ipv6_tuple_to_nlattr, 360 .tuple_to_nlattr = ipv6_tuple_to_nlattr,
361 .nlattr_tuple_size = ipv6_nlattr_tuple_size,
356 .nlattr_to_tuple = ipv6_nlattr_to_tuple, 362 .nlattr_to_tuple = ipv6_nlattr_to_tuple,
357 .nla_policy = ipv6_nla_policy, 363 .nla_policy = ipv6_nla_policy,
358#endif 364#endif
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 41b8a956e1be..9903227bf37c 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -269,6 +269,11 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[],
269 269
270 return 0; 270 return 0;
271} 271}
272
273static int icmpv6_nlattr_tuple_size(void)
274{
275 return nla_policy_len(icmpv6_nla_policy, CTA_PROTO_MAX + 1);
276}
272#endif 277#endif
273 278
274#ifdef CONFIG_SYSCTL 279#ifdef CONFIG_SYSCTL
@@ -300,6 +305,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 __read_mostly =
300 .error = icmpv6_error, 305 .error = icmpv6_error,
301#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 306#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
302 .tuple_to_nlattr = icmpv6_tuple_to_nlattr, 307 .tuple_to_nlattr = icmpv6_tuple_to_nlattr,
308 .nlattr_tuple_size = icmpv6_nlattr_tuple_size,
303 .nlattr_to_tuple = icmpv6_nlattr_to_tuple, 309 .nlattr_to_tuple = icmpv6_nlattr_to_tuple,
304 .nla_policy = icmpv6_nla_policy, 310 .nla_policy = icmpv6_nla_policy,
305#endif 311#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 2562d05dbaf5..2c967e4f706c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -374,7 +374,7 @@ config NETFILTER_XT_TARGET_HL
374 374
375config NETFILTER_XT_TARGET_LED 375config NETFILTER_XT_TARGET_LED
376 tristate '"LED" target support' 376 tristate '"LED" target support'
377 depends on LEDS_CLASS 377 depends on LEDS_CLASS && LED_TRIGGERS
378 depends on NETFILTER_ADVANCED 378 depends on NETFILTER_ADVANCED
379 help 379 help
380 This option adds a `LED' target, which allows you to blink LEDs in 380 This option adds a `LED' target, which allows you to blink LEDs in
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index dfb447b584da..8020db6274b8 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -29,6 +29,7 @@
29#include <linux/netdevice.h> 29#include <linux/netdevice.h>
30#include <linux/socket.h> 30#include <linux/socket.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/rculist_nulls.h>
32 33
33#include <net/netfilter/nf_conntrack.h> 34#include <net/netfilter/nf_conntrack.h>
34#include <net/netfilter/nf_conntrack_l3proto.h> 35#include <net/netfilter/nf_conntrack_l3proto.h>
@@ -163,8 +164,8 @@ static void
163clean_from_lists(struct nf_conn *ct) 164clean_from_lists(struct nf_conn *ct)
164{ 165{
165 pr_debug("clean_from_lists(%p)\n", ct); 166 pr_debug("clean_from_lists(%p)\n", ct);
166 hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode); 167 hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
167 hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode); 168 hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode);
168 169
169 /* Destroy all pending expectations */ 170 /* Destroy all pending expectations */
170 nf_ct_remove_expectations(ct); 171 nf_ct_remove_expectations(ct);
@@ -204,8 +205,8 @@ destroy_conntrack(struct nf_conntrack *nfct)
204 205
205 /* We overload first tuple to link into unconfirmed list. */ 206 /* We overload first tuple to link into unconfirmed list. */
206 if (!nf_ct_is_confirmed(ct)) { 207 if (!nf_ct_is_confirmed(ct)) {
207 BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode)); 208 BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode));
208 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode); 209 hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
209 } 210 }
210 211
211 NF_CT_STAT_INC(net, delete); 212 NF_CT_STAT_INC(net, delete);
@@ -242,18 +243,26 @@ static void death_by_timeout(unsigned long ul_conntrack)
242 nf_ct_put(ct); 243 nf_ct_put(ct);
243} 244}
244 245
246/*
247 * Warning :
248 * - Caller must take a reference on returned object
249 * and recheck nf_ct_tuple_equal(tuple, &h->tuple)
250 * OR
251 * - Caller must lock nf_conntrack_lock before calling this function
252 */
245struct nf_conntrack_tuple_hash * 253struct nf_conntrack_tuple_hash *
246__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple) 254__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
247{ 255{
248 struct nf_conntrack_tuple_hash *h; 256 struct nf_conntrack_tuple_hash *h;
249 struct hlist_node *n; 257 struct hlist_nulls_node *n;
250 unsigned int hash = hash_conntrack(tuple); 258 unsigned int hash = hash_conntrack(tuple);
251 259
252 /* Disable BHs the entire time since we normally need to disable them 260 /* Disable BHs the entire time since we normally need to disable them
253 * at least once for the stats anyway. 261 * at least once for the stats anyway.
254 */ 262 */
255 local_bh_disable(); 263 local_bh_disable();
256 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) { 264begin:
265 hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) {
257 if (nf_ct_tuple_equal(tuple, &h->tuple)) { 266 if (nf_ct_tuple_equal(tuple, &h->tuple)) {
258 NF_CT_STAT_INC(net, found); 267 NF_CT_STAT_INC(net, found);
259 local_bh_enable(); 268 local_bh_enable();
@@ -261,6 +270,13 @@ __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
261 } 270 }
262 NF_CT_STAT_INC(net, searched); 271 NF_CT_STAT_INC(net, searched);
263 } 272 }
273 /*
274 * if the nulls value we got at the end of this lookup is
275 * not the expected one, we must restart lookup.
276 * We probably met an item that was moved to another chain.
277 */
278 if (get_nulls_value(n) != hash)
279 goto begin;
264 local_bh_enable(); 280 local_bh_enable();
265 281
266 return NULL; 282 return NULL;
@@ -275,11 +291,18 @@ nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple)
275 struct nf_conn *ct; 291 struct nf_conn *ct;
276 292
277 rcu_read_lock(); 293 rcu_read_lock();
294begin:
278 h = __nf_conntrack_find(net, tuple); 295 h = __nf_conntrack_find(net, tuple);
279 if (h) { 296 if (h) {
280 ct = nf_ct_tuplehash_to_ctrack(h); 297 ct = nf_ct_tuplehash_to_ctrack(h);
281 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) 298 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
282 h = NULL; 299 h = NULL;
300 else {
301 if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple))) {
302 nf_ct_put(ct);
303 goto begin;
304 }
305 }
283 } 306 }
284 rcu_read_unlock(); 307 rcu_read_unlock();
285 308
@@ -293,9 +316,9 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
293{ 316{
294 struct net *net = nf_ct_net(ct); 317 struct net *net = nf_ct_net(ct);
295 318
296 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, 319 hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
297 &net->ct.hash[hash]); 320 &net->ct.hash[hash]);
298 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode, 321 hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode,
299 &net->ct.hash[repl_hash]); 322 &net->ct.hash[repl_hash]);
300} 323}
301 324
@@ -318,7 +341,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
318 struct nf_conntrack_tuple_hash *h; 341 struct nf_conntrack_tuple_hash *h;
319 struct nf_conn *ct; 342 struct nf_conn *ct;
320 struct nf_conn_help *help; 343 struct nf_conn_help *help;
321 struct hlist_node *n; 344 struct hlist_nulls_node *n;
322 enum ip_conntrack_info ctinfo; 345 enum ip_conntrack_info ctinfo;
323 struct net *net; 346 struct net *net;
324 347
@@ -350,17 +373,17 @@ __nf_conntrack_confirm(struct sk_buff *skb)
350 /* See if there's one in the list already, including reverse: 373 /* See if there's one in the list already, including reverse:
351 NAT could have grabbed it without realizing, since we're 374 NAT could have grabbed it without realizing, since we're
352 not in the hash. If there is, we lost race. */ 375 not in the hash. If there is, we lost race. */
353 hlist_for_each_entry(h, n, &net->ct.hash[hash], hnode) 376 hlist_nulls_for_each_entry(h, n, &net->ct.hash[hash], hnnode)
354 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 377 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
355 &h->tuple)) 378 &h->tuple))
356 goto out; 379 goto out;
357 hlist_for_each_entry(h, n, &net->ct.hash[repl_hash], hnode) 380 hlist_nulls_for_each_entry(h, n, &net->ct.hash[repl_hash], hnnode)
358 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, 381 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
359 &h->tuple)) 382 &h->tuple))
360 goto out; 383 goto out;
361 384
362 /* Remove from unconfirmed list */ 385 /* Remove from unconfirmed list */
363 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode); 386 hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
364 387
365 __nf_conntrack_hash_insert(ct, hash, repl_hash); 388 __nf_conntrack_hash_insert(ct, hash, repl_hash);
366 /* Timer relative to confirmation time, not original 389 /* Timer relative to confirmation time, not original
@@ -399,14 +422,14 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
399{ 422{
400 struct net *net = nf_ct_net(ignored_conntrack); 423 struct net *net = nf_ct_net(ignored_conntrack);
401 struct nf_conntrack_tuple_hash *h; 424 struct nf_conntrack_tuple_hash *h;
402 struct hlist_node *n; 425 struct hlist_nulls_node *n;
403 unsigned int hash = hash_conntrack(tuple); 426 unsigned int hash = hash_conntrack(tuple);
404 427
405 /* Disable BHs the entire time since we need to disable them at 428 /* Disable BHs the entire time since we need to disable them at
406 * least once for the stats anyway. 429 * least once for the stats anyway.
407 */ 430 */
408 rcu_read_lock_bh(); 431 rcu_read_lock_bh();
409 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) { 432 hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) {
410 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && 433 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
411 nf_ct_tuple_equal(tuple, &h->tuple)) { 434 nf_ct_tuple_equal(tuple, &h->tuple)) {
412 NF_CT_STAT_INC(net, found); 435 NF_CT_STAT_INC(net, found);
@@ -430,14 +453,14 @@ static noinline int early_drop(struct net *net, unsigned int hash)
430 /* Use oldest entry, which is roughly LRU */ 453 /* Use oldest entry, which is roughly LRU */
431 struct nf_conntrack_tuple_hash *h; 454 struct nf_conntrack_tuple_hash *h;
432 struct nf_conn *ct = NULL, *tmp; 455 struct nf_conn *ct = NULL, *tmp;
433 struct hlist_node *n; 456 struct hlist_nulls_node *n;
434 unsigned int i, cnt = 0; 457 unsigned int i, cnt = 0;
435 int dropped = 0; 458 int dropped = 0;
436 459
437 rcu_read_lock(); 460 rcu_read_lock();
438 for (i = 0; i < nf_conntrack_htable_size; i++) { 461 for (i = 0; i < nf_conntrack_htable_size; i++) {
439 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], 462 hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
440 hnode) { 463 hnnode) {
441 tmp = nf_ct_tuplehash_to_ctrack(h); 464 tmp = nf_ct_tuplehash_to_ctrack(h);
442 if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) 465 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
443 ct = tmp; 466 ct = tmp;
@@ -508,27 +531,19 @@ struct nf_conn *nf_conntrack_alloc(struct net *net,
508#ifdef CONFIG_NET_NS 531#ifdef CONFIG_NET_NS
509 ct->ct_net = net; 532 ct->ct_net = net;
510#endif 533#endif
511 INIT_RCU_HEAD(&ct->rcu);
512 534
513 return ct; 535 return ct;
514} 536}
515EXPORT_SYMBOL_GPL(nf_conntrack_alloc); 537EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
516 538
517static void nf_conntrack_free_rcu(struct rcu_head *head)
518{
519 struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
520
521 nf_ct_ext_free(ct);
522 kmem_cache_free(nf_conntrack_cachep, ct);
523}
524
525void nf_conntrack_free(struct nf_conn *ct) 539void nf_conntrack_free(struct nf_conn *ct)
526{ 540{
527 struct net *net = nf_ct_net(ct); 541 struct net *net = nf_ct_net(ct);
528 542
529 nf_ct_ext_destroy(ct); 543 nf_ct_ext_destroy(ct);
530 atomic_dec(&net->ct.count); 544 atomic_dec(&net->ct.count);
531 call_rcu(&ct->rcu, nf_conntrack_free_rcu); 545 nf_ct_ext_free(ct);
546 kmem_cache_free(nf_conntrack_cachep, ct);
532} 547}
533EXPORT_SYMBOL_GPL(nf_conntrack_free); 548EXPORT_SYMBOL_GPL(nf_conntrack_free);
534 549
@@ -594,7 +609,7 @@ init_conntrack(struct net *net,
594 } 609 }
595 610
596 /* Overload tuple linked list to put us in unconfirmed list. */ 611 /* Overload tuple linked list to put us in unconfirmed list. */
597 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, 612 hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
598 &net->ct.unconfirmed); 613 &net->ct.unconfirmed);
599 614
600 spin_unlock_bh(&nf_conntrack_lock); 615 spin_unlock_bh(&nf_conntrack_lock);
@@ -906,6 +921,12 @@ int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
906 return 0; 921 return 0;
907} 922}
908EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple); 923EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple);
924
925int nf_ct_port_nlattr_tuple_size(void)
926{
927 return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
928}
929EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_tuple_size);
909#endif 930#endif
910 931
911/* Used by ipt_REJECT and ip6t_REJECT. */ 932/* Used by ipt_REJECT and ip6t_REJECT. */
@@ -934,17 +955,17 @@ get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
934{ 955{
935 struct nf_conntrack_tuple_hash *h; 956 struct nf_conntrack_tuple_hash *h;
936 struct nf_conn *ct; 957 struct nf_conn *ct;
937 struct hlist_node *n; 958 struct hlist_nulls_node *n;
938 959
939 spin_lock_bh(&nf_conntrack_lock); 960 spin_lock_bh(&nf_conntrack_lock);
940 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { 961 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
941 hlist_for_each_entry(h, n, &net->ct.hash[*bucket], hnode) { 962 hlist_nulls_for_each_entry(h, n, &net->ct.hash[*bucket], hnnode) {
942 ct = nf_ct_tuplehash_to_ctrack(h); 963 ct = nf_ct_tuplehash_to_ctrack(h);
943 if (iter(ct, data)) 964 if (iter(ct, data))
944 goto found; 965 goto found;
945 } 966 }
946 } 967 }
947 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode) { 968 hlist_nulls_for_each_entry(h, n, &net->ct.unconfirmed, hnnode) {
948 ct = nf_ct_tuplehash_to_ctrack(h); 969 ct = nf_ct_tuplehash_to_ctrack(h);
949 if (iter(ct, data)) 970 if (iter(ct, data))
950 set_bit(IPS_DYING_BIT, &ct->status); 971 set_bit(IPS_DYING_BIT, &ct->status);
@@ -992,7 +1013,7 @@ static int kill_all(struct nf_conn *i, void *data)
992 return 1; 1013 return 1;
993} 1014}
994 1015
995void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int size) 1016void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size)
996{ 1017{
997 if (vmalloced) 1018 if (vmalloced)
998 vfree(hash); 1019 vfree(hash);
@@ -1060,26 +1081,28 @@ void nf_conntrack_cleanup(struct net *net)
1060 } 1081 }
1061} 1082}
1062 1083
1063struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) 1084void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls)
1064{ 1085{
1065 struct hlist_head *hash; 1086 struct hlist_nulls_head *hash;
1066 unsigned int size, i; 1087 unsigned int nr_slots, i;
1088 size_t sz;
1067 1089
1068 *vmalloced = 0; 1090 *vmalloced = 0;
1069 1091
1070 size = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_head)); 1092 BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
1071 hash = (void*)__get_free_pages(GFP_KERNEL|__GFP_NOWARN, 1093 nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
1072 get_order(sizeof(struct hlist_head) 1094 sz = nr_slots * sizeof(struct hlist_nulls_head);
1073 * size)); 1095 hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
1096 get_order(sz));
1074 if (!hash) { 1097 if (!hash) {
1075 *vmalloced = 1; 1098 *vmalloced = 1;
1076 printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); 1099 printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n");
1077 hash = vmalloc(sizeof(struct hlist_head) * size); 1100 hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL);
1078 } 1101 }
1079 1102
1080 if (hash) 1103 if (hash && nulls)
1081 for (i = 0; i < size; i++) 1104 for (i = 0; i < nr_slots; i++)
1082 INIT_HLIST_HEAD(&hash[i]); 1105 INIT_HLIST_NULLS_HEAD(&hash[i], i);
1083 1106
1084 return hash; 1107 return hash;
1085} 1108}
@@ -1090,7 +1113,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1090 int i, bucket, vmalloced, old_vmalloced; 1113 int i, bucket, vmalloced, old_vmalloced;
1091 unsigned int hashsize, old_size; 1114 unsigned int hashsize, old_size;
1092 int rnd; 1115 int rnd;
1093 struct hlist_head *hash, *old_hash; 1116 struct hlist_nulls_head *hash, *old_hash;
1094 struct nf_conntrack_tuple_hash *h; 1117 struct nf_conntrack_tuple_hash *h;
1095 1118
1096 /* On boot, we can set this without any fancy locking. */ 1119 /* On boot, we can set this without any fancy locking. */
@@ -1101,7 +1124,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1101 if (!hashsize) 1124 if (!hashsize)
1102 return -EINVAL; 1125 return -EINVAL;
1103 1126
1104 hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced); 1127 hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced, 1);
1105 if (!hash) 1128 if (!hash)
1106 return -ENOMEM; 1129 return -ENOMEM;
1107 1130
@@ -1116,12 +1139,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1116 */ 1139 */
1117 spin_lock_bh(&nf_conntrack_lock); 1140 spin_lock_bh(&nf_conntrack_lock);
1118 for (i = 0; i < nf_conntrack_htable_size; i++) { 1141 for (i = 0; i < nf_conntrack_htable_size; i++) {
1119 while (!hlist_empty(&init_net.ct.hash[i])) { 1142 while (!hlist_nulls_empty(&init_net.ct.hash[i])) {
1120 h = hlist_entry(init_net.ct.hash[i].first, 1143 h = hlist_nulls_entry(init_net.ct.hash[i].first,
1121 struct nf_conntrack_tuple_hash, hnode); 1144 struct nf_conntrack_tuple_hash, hnnode);
1122 hlist_del_rcu(&h->hnode); 1145 hlist_nulls_del_rcu(&h->hnnode);
1123 bucket = __hash_conntrack(&h->tuple, hashsize, rnd); 1146 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
1124 hlist_add_head(&h->hnode, &hash[bucket]); 1147 hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]);
1125 } 1148 }
1126 } 1149 }
1127 old_size = nf_conntrack_htable_size; 1150 old_size = nf_conntrack_htable_size;
@@ -1172,7 +1195,7 @@ static int nf_conntrack_init_init_net(void)
1172 1195
1173 nf_conntrack_cachep = kmem_cache_create("nf_conntrack", 1196 nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
1174 sizeof(struct nf_conn), 1197 sizeof(struct nf_conn),
1175 0, 0, NULL); 1198 0, SLAB_DESTROY_BY_RCU, NULL);
1176 if (!nf_conntrack_cachep) { 1199 if (!nf_conntrack_cachep) {
1177 printk(KERN_ERR "Unable to create nf_conn slab cache\n"); 1200 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1178 ret = -ENOMEM; 1201 ret = -ENOMEM;
@@ -1202,7 +1225,7 @@ static int nf_conntrack_init_net(struct net *net)
1202 int ret; 1225 int ret;
1203 1226
1204 atomic_set(&net->ct.count, 0); 1227 atomic_set(&net->ct.count, 0);
1205 INIT_HLIST_HEAD(&net->ct.unconfirmed); 1228 INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, 0);
1206 net->ct.stat = alloc_percpu(struct ip_conntrack_stat); 1229 net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1207 if (!net->ct.stat) { 1230 if (!net->ct.stat) {
1208 ret = -ENOMEM; 1231 ret = -ENOMEM;
@@ -1212,7 +1235,7 @@ static int nf_conntrack_init_net(struct net *net)
1212 if (ret < 0) 1235 if (ret < 0)
1213 goto err_ecache; 1236 goto err_ecache;
1214 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size, 1237 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1215 &net->ct.hash_vmalloc); 1238 &net->ct.hash_vmalloc, 1);
1216 if (!net->ct.hash) { 1239 if (!net->ct.hash) {
1217 ret = -ENOMEM; 1240 ret = -ENOMEM;
1218 printk(KERN_ERR "Unable to create nf_conntrack_hash\n"); 1241 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 357ba39d4c8d..3940f996a2e4 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -604,7 +604,7 @@ int nf_conntrack_expect_init(struct net *net)
604 604
605 net->ct.expect_count = 0; 605 net->ct.expect_count = 0;
606 net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 606 net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize,
607 &net->ct.expect_vmalloc); 607 &net->ct.expect_vmalloc, 0);
608 if (net->ct.expect_hash == NULL) 608 if (net->ct.expect_hash == NULL)
609 goto err1; 609 goto err1;
610 610
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index a51bdac9f3a0..30b8e9009f99 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -142,6 +142,7 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
142 142
143 BUG_ON(me->expect_policy == NULL); 143 BUG_ON(me->expect_policy == NULL);
144 BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES); 144 BUG_ON(me->expect_class_max >= NF_CT_MAX_EXPECT_CLASSES);
145 BUG_ON(strlen(me->name) > NF_CT_HELPER_NAME_LEN - 1);
145 146
146 mutex_lock(&nf_ct_helper_mutex); 147 mutex_lock(&nf_ct_helper_mutex);
147 hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]); 148 hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
@@ -158,6 +159,7 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
158 struct nf_conntrack_tuple_hash *h; 159 struct nf_conntrack_tuple_hash *h;
159 struct nf_conntrack_expect *exp; 160 struct nf_conntrack_expect *exp;
160 const struct hlist_node *n, *next; 161 const struct hlist_node *n, *next;
162 const struct hlist_nulls_node *nn;
161 unsigned int i; 163 unsigned int i;
162 164
163 /* Get rid of expectations */ 165 /* Get rid of expectations */
@@ -174,10 +176,10 @@ static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
174 } 176 }
175 177
176 /* Get rid of expecteds, set helpers to NULL. */ 178 /* Get rid of expecteds, set helpers to NULL. */
177 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode) 179 hlist_for_each_entry(h, nn, &net->ct.unconfirmed, hnnode)
178 unhelp(h, me); 180 unhelp(h, me);
179 for (i = 0; i < nf_conntrack_htable_size; i++) { 181 for (i = 0; i < nf_conntrack_htable_size; i++) {
180 hlist_for_each_entry(h, n, &net->ct.hash[i], hnode) 182 hlist_nulls_for_each_entry(h, nn, &net->ct.hash[i], hnnode)
181 unhelp(h, me); 183 unhelp(h, me);
182 } 184 }
183} 185}
@@ -217,7 +219,7 @@ int nf_conntrack_helper_init(void)
217 219
218 nf_ct_helper_hsize = 1; /* gets rounded up to use one page */ 220 nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
219 nf_ct_helper_hash = nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 221 nf_ct_helper_hash = nf_ct_alloc_hashtable(&nf_ct_helper_hsize,
220 &nf_ct_helper_vmalloc); 222 &nf_ct_helper_vmalloc, 0);
221 if (!nf_ct_helper_hash) 223 if (!nf_ct_helper_hash)
222 return -ENOMEM; 224 return -ENOMEM;
223 225
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 7a16bd462f82..c6439c77953c 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/rculist.h> 21#include <linux/rculist.h>
22#include <linux/rculist_nulls.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <linux/timer.h> 24#include <linux/timer.h>
24#include <linux/skbuff.h> 25#include <linux/skbuff.h>
@@ -404,6 +405,78 @@ nla_put_failure:
404} 405}
405 406
406#ifdef CONFIG_NF_CONNTRACK_EVENTS 407#ifdef CONFIG_NF_CONNTRACK_EVENTS
408/*
409 * The general structure of a ctnetlink event is
410 *
411 * CTA_TUPLE_ORIG
412 * <l3/l4-proto-attributes>
413 * CTA_TUPLE_REPLY
414 * <l3/l4-proto-attributes>
415 * CTA_ID
416 * ...
417 * CTA_PROTOINFO
418 * <l4-proto-attributes>
419 * CTA_TUPLE_MASTER
420 * <l3/l4-proto-attributes>
421 *
422 * Therefore the formular is
423 *
424 * size = sizeof(headers) + sizeof(generic_nlas) + 3 * sizeof(tuple_nlas)
425 * + sizeof(protoinfo_nlas)
426 */
427static struct sk_buff *
428ctnetlink_alloc_skb(const struct nf_conntrack_tuple *tuple, gfp_t gfp)
429{
430 struct nf_conntrack_l3proto *l3proto;
431 struct nf_conntrack_l4proto *l4proto;
432 int len;
433
434#define NLA_TYPE_SIZE(type) nla_total_size(sizeof(type))
435
436 /* proto independant part */
437 len = NLMSG_SPACE(sizeof(struct nfgenmsg))
438 + 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
439 + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
440 + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */
441 + 3 * NLA_TYPE_SIZE(u_int8_t) /* CTA_PROTO_NUM */
442 + NLA_TYPE_SIZE(u_int32_t) /* CTA_ID */
443 + NLA_TYPE_SIZE(u_int32_t) /* CTA_STATUS */
444#ifdef CONFIG_NF_CT_ACCT
445 + 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
446 + 2 * NLA_TYPE_SIZE(uint64_t) /* CTA_COUNTERS_PACKETS */
447 + 2 * NLA_TYPE_SIZE(uint64_t) /* CTA_COUNTERS_BYTES */
448#endif
449 + NLA_TYPE_SIZE(u_int32_t) /* CTA_TIMEOUT */
450 + nla_total_size(0) /* CTA_PROTOINFO */
451 + nla_total_size(0) /* CTA_HELP */
452 + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
453#ifdef CONFIG_NF_CONNTRACK_SECMARK
454 + NLA_TYPE_SIZE(u_int32_t) /* CTA_SECMARK */
455#endif
456#ifdef CONFIG_NF_NAT_NEEDED
457 + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
458 + 2 * NLA_TYPE_SIZE(u_int32_t) /* CTA_NAT_SEQ_CORRECTION_POS */
459 + 2 * NLA_TYPE_SIZE(u_int32_t) /* CTA_NAT_SEQ_CORRECTION_BEFORE */
460 + 2 * NLA_TYPE_SIZE(u_int32_t) /* CTA_NAT_SEQ_CORRECTION_AFTER */
461#endif
462#ifdef CONFIG_NF_CONNTRACK_MARK
463 + NLA_TYPE_SIZE(u_int32_t) /* CTA_MARK */
464#endif
465 ;
466
467#undef NLA_TYPE_SIZE
468
469 rcu_read_lock();
470 l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
471 len += l3proto->nla_size;
472
473 l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
474 len += l4proto->nla_size;
475 rcu_read_unlock();
476
477 return alloc_skb(len, gfp);
478}
479
407static int ctnetlink_conntrack_event(struct notifier_block *this, 480static int ctnetlink_conntrack_event(struct notifier_block *this,
408 unsigned long events, void *ptr) 481 unsigned long events, void *ptr)
409{ 482{
@@ -437,7 +510,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
437 if (!item->report && !nfnetlink_has_listeners(group)) 510 if (!item->report && !nfnetlink_has_listeners(group))
438 return NOTIFY_DONE; 511 return NOTIFY_DONE;
439 512
440 skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC); 513 skb = ctnetlink_alloc_skb(tuple(ct, IP_CT_DIR_ORIGINAL), GFP_ATOMIC);
441 if (!skb) 514 if (!skb)
442 return NOTIFY_DONE; 515 return NOTIFY_DONE;
443 516
@@ -536,7 +609,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
536{ 609{
537 struct nf_conn *ct, *last; 610 struct nf_conn *ct, *last;
538 struct nf_conntrack_tuple_hash *h; 611 struct nf_conntrack_tuple_hash *h;
539 struct hlist_node *n; 612 struct hlist_nulls_node *n;
540 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 613 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
541 u_int8_t l3proto = nfmsg->nfgen_family; 614 u_int8_t l3proto = nfmsg->nfgen_family;
542 615
@@ -544,27 +617,27 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
544 last = (struct nf_conn *)cb->args[1]; 617 last = (struct nf_conn *)cb->args[1];
545 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { 618 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
546restart: 619restart:
547 hlist_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]], 620 hlist_nulls_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
548 hnode) { 621 hnnode) {
549 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) 622 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
550 continue; 623 continue;
551 ct = nf_ct_tuplehash_to_ctrack(h); 624 ct = nf_ct_tuplehash_to_ctrack(h);
625 if (!atomic_inc_not_zero(&ct->ct_general.use))
626 continue;
552 /* Dump entries of a given L3 protocol number. 627 /* Dump entries of a given L3 protocol number.
553 * If it is not specified, ie. l3proto == 0, 628 * If it is not specified, ie. l3proto == 0,
554 * then dump everything. */ 629 * then dump everything. */
555 if (l3proto && nf_ct_l3num(ct) != l3proto) 630 if (l3proto && nf_ct_l3num(ct) != l3proto)
556 continue; 631 goto releasect;
557 if (cb->args[1]) { 632 if (cb->args[1]) {
558 if (ct != last) 633 if (ct != last)
559 continue; 634 goto releasect;
560 cb->args[1] = 0; 635 cb->args[1] = 0;
561 } 636 }
562 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, 637 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
563 cb->nlh->nlmsg_seq, 638 cb->nlh->nlmsg_seq,
564 IPCTNL_MSG_CT_NEW, 639 IPCTNL_MSG_CT_NEW,
565 1, ct) < 0) { 640 1, ct) < 0) {
566 if (!atomic_inc_not_zero(&ct->ct_general.use))
567 continue;
568 cb->args[1] = (unsigned long)ct; 641 cb->args[1] = (unsigned long)ct;
569 goto out; 642 goto out;
570 } 643 }
@@ -577,6 +650,8 @@ restart:
577 if (acct) 650 if (acct)
578 memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX])); 651 memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]));
579 } 652 }
653releasect:
654 nf_ct_put(ct);
580 } 655 }
581 if (cb->args[1]) { 656 if (cb->args[1]) {
582 cb->args[1] = 0; 657 cb->args[1] = 0;
@@ -1242,13 +1317,12 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1242 if (err < 0) 1317 if (err < 0)
1243 goto err2; 1318 goto err2;
1244 1319
1245 master_h = __nf_conntrack_find(&init_net, &master); 1320 master_h = nf_conntrack_find_get(&init_net, &master);
1246 if (master_h == NULL) { 1321 if (master_h == NULL) {
1247 err = -ENOENT; 1322 err = -ENOENT;
1248 goto err2; 1323 goto err2;
1249 } 1324 }
1250 master_ct = nf_ct_tuplehash_to_ctrack(master_h); 1325 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
1251 nf_conntrack_get(&master_ct->ct_general);
1252 __set_bit(IPS_EXPECTED_BIT, &ct->status); 1326 __set_bit(IPS_EXPECTED_BIT, &ct->status);
1253 ct->master = master_ct; 1327 ct->master = master_ct;
1254 } 1328 }
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index 9a62b4efa0e1..1a4568bf7ea5 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -167,6 +167,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
167 if (proto->l3proto >= AF_MAX) 167 if (proto->l3proto >= AF_MAX)
168 return -EBUSY; 168 return -EBUSY;
169 169
170 if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
171 return -EINVAL;
172
170 mutex_lock(&nf_ct_proto_mutex); 173 mutex_lock(&nf_ct_proto_mutex);
171 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) { 174 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
172 ret = -EBUSY; 175 ret = -EBUSY;
@@ -177,6 +180,9 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
177 if (ret < 0) 180 if (ret < 0)
178 goto out_unlock; 181 goto out_unlock;
179 182
183 if (proto->nlattr_tuple_size)
184 proto->nla_size = 3 * proto->nlattr_tuple_size();
185
180 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto); 186 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
181 187
182out_unlock: 188out_unlock:
@@ -263,6 +269,10 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
263 if (l4proto->l3proto >= PF_MAX) 269 if (l4proto->l3proto >= PF_MAX)
264 return -EBUSY; 270 return -EBUSY;
265 271
272 if ((l4proto->to_nlattr && !l4proto->nlattr_size)
273 || (l4proto->tuple_to_nlattr && !l4proto->nlattr_tuple_size))
274 return -EINVAL;
275
266 mutex_lock(&nf_ct_proto_mutex); 276 mutex_lock(&nf_ct_proto_mutex);
267 if (!nf_ct_protos[l4proto->l3proto]) { 277 if (!nf_ct_protos[l4proto->l3proto]) {
268 /* l3proto may be loaded latter. */ 278 /* l3proto may be loaded latter. */
@@ -290,6 +300,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
290 if (ret < 0) 300 if (ret < 0)
291 goto out_unlock; 301 goto out_unlock;
292 302
303 l4proto->nla_size = 0;
304 if (l4proto->nlattr_size)
305 l4proto->nla_size += l4proto->nlattr_size();
306 if (l4proto->nlattr_tuple_size)
307 l4proto->nla_size += 3 * l4proto->nlattr_tuple_size();
308
293 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], 309 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
294 l4proto); 310 l4proto);
295 311
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index d3d5a7fd73ce..50dac8dbe7d8 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -669,6 +669,12 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
669 write_unlock_bh(&dccp_lock); 669 write_unlock_bh(&dccp_lock);
670 return 0; 670 return 0;
671} 671}
672
673static int dccp_nlattr_size(void)
674{
675 return nla_total_size(0) /* CTA_PROTOINFO_DCCP */
676 + nla_policy_len(dccp_nla_policy, CTA_PROTOINFO_DCCP_MAX + 1);
677}
672#endif 678#endif
673 679
674#ifdef CONFIG_SYSCTL 680#ifdef CONFIG_SYSCTL
@@ -749,8 +755,10 @@ static struct nf_conntrack_l4proto dccp_proto4 __read_mostly = {
749 .print_conntrack = dccp_print_conntrack, 755 .print_conntrack = dccp_print_conntrack,
750#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 756#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
751 .to_nlattr = dccp_to_nlattr, 757 .to_nlattr = dccp_to_nlattr,
758 .nlattr_size = dccp_nlattr_size,
752 .from_nlattr = nlattr_to_dccp, 759 .from_nlattr = nlattr_to_dccp,
753 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 760 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
761 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
754 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 762 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
755 .nla_policy = nf_ct_port_nla_policy, 763 .nla_policy = nf_ct_port_nla_policy,
756#endif 764#endif
@@ -771,6 +779,7 @@ static struct nf_conntrack_l4proto dccp_proto6 __read_mostly = {
771 .to_nlattr = dccp_to_nlattr, 779 .to_nlattr = dccp_to_nlattr,
772 .from_nlattr = nlattr_to_dccp, 780 .from_nlattr = nlattr_to_dccp,
773 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 781 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
782 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
774 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 783 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
775 .nla_policy = nf_ct_port_nla_policy, 784 .nla_policy = nf_ct_port_nla_policy,
776#endif 785#endif
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 1b279f9d6bf3..117b80112fcb 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -293,6 +293,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
293 .me = THIS_MODULE, 293 .me = THIS_MODULE,
294#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 294#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
295 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 295 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
296 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
296 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 297 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
297 .nla_policy = nf_ct_port_nla_policy, 298 .nla_policy = nf_ct_port_nla_policy,
298#endif 299#endif
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 74e037901199..101b4ad9e817 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -537,6 +537,12 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
537 537
538 return 0; 538 return 0;
539} 539}
540
541static int sctp_nlattr_size(void)
542{
543 return nla_total_size(0) /* CTA_PROTOINFO_SCTP */
544 + nla_policy_len(sctp_nla_policy, CTA_PROTOINFO_SCTP_MAX + 1);
545}
540#endif 546#endif
541 547
542#ifdef CONFIG_SYSCTL 548#ifdef CONFIG_SYSCTL
@@ -668,8 +674,10 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 __read_mostly = {
668 .me = THIS_MODULE, 674 .me = THIS_MODULE,
669#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 675#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
670 .to_nlattr = sctp_to_nlattr, 676 .to_nlattr = sctp_to_nlattr,
677 .nlattr_size = sctp_nlattr_size,
671 .from_nlattr = nlattr_to_sctp, 678 .from_nlattr = nlattr_to_sctp,
672 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 679 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
680 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
673 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 681 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
674 .nla_policy = nf_ct_port_nla_policy, 682 .nla_policy = nf_ct_port_nla_policy,
675#endif 683#endif
@@ -696,8 +704,10 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 __read_mostly = {
696 .me = THIS_MODULE, 704 .me = THIS_MODULE,
697#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 705#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
698 .to_nlattr = sctp_to_nlattr, 706 .to_nlattr = sctp_to_nlattr,
707 .nlattr_size = sctp_nlattr_size,
699 .from_nlattr = nlattr_to_sctp, 708 .from_nlattr = nlattr_to_sctp,
700 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 709 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
710 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
701 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 711 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
702 .nla_policy = nf_ct_port_nla_policy, 712 .nla_policy = nf_ct_port_nla_policy,
703#endif 713#endif
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 0aeb8b09a1f7..b5ccf2b4b2e7 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -1184,6 +1184,17 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
1184 1184
1185 return 0; 1185 return 0;
1186} 1186}
1187
1188static int tcp_nlattr_size(void)
1189{
1190 return nla_total_size(0) /* CTA_PROTOINFO_TCP */
1191 + nla_policy_len(tcp_nla_policy, CTA_PROTOINFO_TCP_MAX + 1);
1192}
1193
1194static int tcp_nlattr_tuple_size(void)
1195{
1196 return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
1197}
1187#endif 1198#endif
1188 1199
1189#ifdef CONFIG_SYSCTL 1200#ifdef CONFIG_SYSCTL
@@ -1399,9 +1410,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
1399 .error = tcp_error, 1410 .error = tcp_error,
1400#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 1411#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
1401 .to_nlattr = tcp_to_nlattr, 1412 .to_nlattr = tcp_to_nlattr,
1413 .nlattr_size = tcp_nlattr_size,
1402 .from_nlattr = nlattr_to_tcp, 1414 .from_nlattr = nlattr_to_tcp,
1403 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 1415 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
1404 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 1416 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
1417 .nlattr_tuple_size = tcp_nlattr_tuple_size,
1405 .nla_policy = nf_ct_port_nla_policy, 1418 .nla_policy = nf_ct_port_nla_policy,
1406#endif 1419#endif
1407#ifdef CONFIG_SYSCTL 1420#ifdef CONFIG_SYSCTL
@@ -1429,9 +1442,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
1429 .error = tcp_error, 1442 .error = tcp_error,
1430#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 1443#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
1431 .to_nlattr = tcp_to_nlattr, 1444 .to_nlattr = tcp_to_nlattr,
1445 .nlattr_size = tcp_nlattr_size,
1432 .from_nlattr = nlattr_to_tcp, 1446 .from_nlattr = nlattr_to_tcp,
1433 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 1447 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
1434 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 1448 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
1449 .nlattr_tuple_size = tcp_nlattr_tuple_size,
1435 .nla_policy = nf_ct_port_nla_policy, 1450 .nla_policy = nf_ct_port_nla_policy,
1436#endif 1451#endif
1437#ifdef CONFIG_SYSCTL 1452#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index d4021179e24e..70809d117b91 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -195,6 +195,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 __read_mostly =
195#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 195#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
196 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 196 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
197 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 197 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
198 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
198 .nla_policy = nf_ct_port_nla_policy, 199 .nla_policy = nf_ct_port_nla_policy,
199#endif 200#endif
200#ifdef CONFIG_SYSCTL 201#ifdef CONFIG_SYSCTL
@@ -222,6 +223,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 __read_mostly =
222#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 223#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
223 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 224 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
224 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 225 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
226 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
225 .nla_policy = nf_ct_port_nla_policy, 227 .nla_policy = nf_ct_port_nla_policy,
226#endif 228#endif
227#ifdef CONFIG_SYSCTL 229#ifdef CONFIG_SYSCTL
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 4579d8de13b1..4614696c1b88 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -180,6 +180,7 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4 __read_mostly =
180 .error = udplite_error, 180 .error = udplite_error,
181#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 181#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
182 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr, 182 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
183 .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
183 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple, 184 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
184 .nla_policy = nf_ct_port_nla_policy, 185 .nla_policy = nf_ct_port_nla_policy,
185#endif 186#endif
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 4da54b0b9233..193515381970 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -44,40 +44,42 @@ struct ct_iter_state {
44 unsigned int bucket; 44 unsigned int bucket;
45}; 45};
46 46
47static struct hlist_node *ct_get_first(struct seq_file *seq) 47static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
48{ 48{
49 struct net *net = seq_file_net(seq); 49 struct net *net = seq_file_net(seq);
50 struct ct_iter_state *st = seq->private; 50 struct ct_iter_state *st = seq->private;
51 struct hlist_node *n; 51 struct hlist_nulls_node *n;
52 52
53 for (st->bucket = 0; 53 for (st->bucket = 0;
54 st->bucket < nf_conntrack_htable_size; 54 st->bucket < nf_conntrack_htable_size;
55 st->bucket++) { 55 st->bucket++) {
56 n = rcu_dereference(net->ct.hash[st->bucket].first); 56 n = rcu_dereference(net->ct.hash[st->bucket].first);
57 if (n) 57 if (!is_a_nulls(n))
58 return n; 58 return n;
59 } 59 }
60 return NULL; 60 return NULL;
61} 61}
62 62
63static struct hlist_node *ct_get_next(struct seq_file *seq, 63static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
64 struct hlist_node *head) 64 struct hlist_nulls_node *head)
65{ 65{
66 struct net *net = seq_file_net(seq); 66 struct net *net = seq_file_net(seq);
67 struct ct_iter_state *st = seq->private; 67 struct ct_iter_state *st = seq->private;
68 68
69 head = rcu_dereference(head->next); 69 head = rcu_dereference(head->next);
70 while (head == NULL) { 70 while (is_a_nulls(head)) {
71 if (++st->bucket >= nf_conntrack_htable_size) 71 if (likely(get_nulls_value(head) == st->bucket)) {
72 return NULL; 72 if (++st->bucket >= nf_conntrack_htable_size)
73 return NULL;
74 }
73 head = rcu_dereference(net->ct.hash[st->bucket].first); 75 head = rcu_dereference(net->ct.hash[st->bucket].first);
74 } 76 }
75 return head; 77 return head;
76} 78}
77 79
78static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos) 80static struct hlist_nulls_node *ct_get_idx(struct seq_file *seq, loff_t pos)
79{ 81{
80 struct hlist_node *head = ct_get_first(seq); 82 struct hlist_nulls_node *head = ct_get_first(seq);
81 83
82 if (head) 84 if (head)
83 while (pos && (head = ct_get_next(seq, head))) 85 while (pos && (head = ct_get_next(seq, head)))
@@ -107,67 +109,74 @@ static void ct_seq_stop(struct seq_file *s, void *v)
107/* return 0 on success, 1 in case of error */ 109/* return 0 on success, 1 in case of error */
108static int ct_seq_show(struct seq_file *s, void *v) 110static int ct_seq_show(struct seq_file *s, void *v)
109{ 111{
110 const struct nf_conntrack_tuple_hash *hash = v; 112 struct nf_conntrack_tuple_hash *hash = v;
111 const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash); 113 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
112 const struct nf_conntrack_l3proto *l3proto; 114 const struct nf_conntrack_l3proto *l3proto;
113 const struct nf_conntrack_l4proto *l4proto; 115 const struct nf_conntrack_l4proto *l4proto;
116 int ret = 0;
114 117
115 NF_CT_ASSERT(ct); 118 NF_CT_ASSERT(ct);
119 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
120 return 0;
116 121
117 /* we only want to print DIR_ORIGINAL */ 122 /* we only want to print DIR_ORIGINAL */
118 if (NF_CT_DIRECTION(hash)) 123 if (NF_CT_DIRECTION(hash))
119 return 0; 124 goto release;
120 125
121 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct)); 126 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
122 NF_CT_ASSERT(l3proto); 127 NF_CT_ASSERT(l3proto);
123 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct)); 128 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
124 NF_CT_ASSERT(l4proto); 129 NF_CT_ASSERT(l4proto);
125 130
131 ret = -ENOSPC;
126 if (seq_printf(s, "%-8s %u %-8s %u %ld ", 132 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
127 l3proto->name, nf_ct_l3num(ct), 133 l3proto->name, nf_ct_l3num(ct),
128 l4proto->name, nf_ct_protonum(ct), 134 l4proto->name, nf_ct_protonum(ct),
129 timer_pending(&ct->timeout) 135 timer_pending(&ct->timeout)
130 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0) 136 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
131 return -ENOSPC; 137 goto release;
132 138
133 if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct)) 139 if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
134 return -ENOSPC; 140 goto release;
135 141
136 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 142 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
137 l3proto, l4proto)) 143 l3proto, l4proto))
138 return -ENOSPC; 144 goto release;
139 145
140 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL)) 146 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
141 return -ENOSPC; 147 goto release;
142 148
143 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status))) 149 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
144 if (seq_printf(s, "[UNREPLIED] ")) 150 if (seq_printf(s, "[UNREPLIED] "))
145 return -ENOSPC; 151 goto release;
146 152
147 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, 153 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
148 l3proto, l4proto)) 154 l3proto, l4proto))
149 return -ENOSPC; 155 goto release;
150 156
151 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY)) 157 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
152 return -ENOSPC; 158 goto release;
153 159
154 if (test_bit(IPS_ASSURED_BIT, &ct->status)) 160 if (test_bit(IPS_ASSURED_BIT, &ct->status))
155 if (seq_printf(s, "[ASSURED] ")) 161 if (seq_printf(s, "[ASSURED] "))
156 return -ENOSPC; 162 goto release;
157 163
158#if defined(CONFIG_NF_CONNTRACK_MARK) 164#if defined(CONFIG_NF_CONNTRACK_MARK)
159 if (seq_printf(s, "mark=%u ", ct->mark)) 165 if (seq_printf(s, "mark=%u ", ct->mark))
160 return -ENOSPC; 166 goto release;
161#endif 167#endif
162 168
163#ifdef CONFIG_NF_CONNTRACK_SECMARK 169#ifdef CONFIG_NF_CONNTRACK_SECMARK
164 if (seq_printf(s, "secmark=%u ", ct->secmark)) 170 if (seq_printf(s, "secmark=%u ", ct->secmark))
165 return -ENOSPC; 171 goto release;
166#endif 172#endif
167 173
168 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use))) 174 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
169 return -ENOSPC; 175 goto release;
170 176
177 ret = 0;
178release:
179 nf_ct_put(ct);
171 return 0; 180 return 0;
172} 181}
173 182
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 7f404cc64c83..680980954395 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -108,7 +108,7 @@ static int count_them(struct xt_connlimit_data *data,
108 const struct nf_conntrack_tuple_hash *found; 108 const struct nf_conntrack_tuple_hash *found;
109 struct xt_connlimit_conn *conn; 109 struct xt_connlimit_conn *conn;
110 struct xt_connlimit_conn *tmp; 110 struct xt_connlimit_conn *tmp;
111 const struct nf_conn *found_ct; 111 struct nf_conn *found_ct;
112 struct list_head *hash; 112 struct list_head *hash;
113 bool addit = true; 113 bool addit = true;
114 int matches = 0; 114 int matches = 0;
@@ -123,7 +123,7 @@ static int count_them(struct xt_connlimit_data *data,
123 123
124 /* check the saved connections */ 124 /* check the saved connections */
125 list_for_each_entry_safe(conn, tmp, hash, list) { 125 list_for_each_entry_safe(conn, tmp, hash, list) {
126 found = __nf_conntrack_find(&init_net, &conn->tuple); 126 found = nf_conntrack_find_get(&init_net, &conn->tuple);
127 found_ct = NULL; 127 found_ct = NULL;
128 128
129 if (found != NULL) 129 if (found != NULL)
@@ -151,6 +151,7 @@ static int count_them(struct xt_connlimit_data *data,
151 * we do not care about connections which are 151 * we do not care about connections which are
152 * closed already -> ditch it 152 * closed already -> ditch it
153 */ 153 */
154 nf_ct_put(found_ct);
154 list_del(&conn->list); 155 list_del(&conn->list);
155 kfree(conn); 156 kfree(conn);
156 continue; 157 continue;
@@ -160,6 +161,7 @@ static int count_them(struct xt_connlimit_data *data,
160 match->family)) 161 match->family))
161 /* same source network -> be counted! */ 162 /* same source network -> be counted! */
162 ++matches; 163 ++matches;
164 nf_ct_put(found_ct);
163 } 165 }
164 166
165 rcu_read_unlock(); 167 rcu_read_unlock();
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 44a234ef4439..8d28ca5848bc 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -20,23 +20,6 @@ MODULE_DESCRIPTION("Xtables: Bridge physical device match");
20MODULE_ALIAS("ipt_physdev"); 20MODULE_ALIAS("ipt_physdev");
21MODULE_ALIAS("ip6t_physdev"); 21MODULE_ALIAS("ip6t_physdev");
22 22
23static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask)
24{
25 const unsigned long *a = (const unsigned long *)_a;
26 const unsigned long *b = (const unsigned long *)_b;
27 const unsigned long *mask = (const unsigned long *)_mask;
28 unsigned long ret;
29
30 ret = (a[0] ^ b[0]) & mask[0];
31 if (IFNAMSIZ > sizeof(unsigned long))
32 ret |= (a[1] ^ b[1]) & mask[1];
33 if (IFNAMSIZ > 2 * sizeof(unsigned long))
34 ret |= (a[2] ^ b[2]) & mask[2];
35 if (IFNAMSIZ > 3 * sizeof(unsigned long))
36 ret |= (a[3] ^ b[3]) & mask[3];
37 BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
38 return ret;
39}
40 23
41static bool 24static bool
42physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par) 25physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
@@ -85,7 +68,7 @@ physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
85 if (!(info->bitmask & XT_PHYSDEV_OP_IN)) 68 if (!(info->bitmask & XT_PHYSDEV_OP_IN))
86 goto match_outdev; 69 goto match_outdev;
87 indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; 70 indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname;
88 ret = ifname_compare(indev, info->physindev, info->in_mask); 71 ret = ifname_compare_aligned(indev, info->physindev, info->in_mask);
89 72
90 if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN)) 73 if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN))
91 return false; 74 return false;
@@ -95,7 +78,7 @@ match_outdev:
95 return true; 78 return true;
96 outdev = nf_bridge->physoutdev ? 79 outdev = nf_bridge->physoutdev ?
97 nf_bridge->physoutdev->name : nulldevname; 80 nf_bridge->physoutdev->name : nulldevname;
98 ret = ifname_compare(outdev, info->physoutdev, info->out_mask); 81 ret = ifname_compare_aligned(outdev, info->physoutdev, info->out_mask);
99 82
100 return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT)); 83 return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT));
101} 84}