Commit 01e6de64d9c8d0e75dca3bb4cf898db73abe00d4

Authored by David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

Showing 33 changed files Side-by-side Diff

include/linux/netfilter/x_tables.h
... ... @@ -437,6 +437,29 @@
437 437 extern void xt_table_entry_swap_rcu(struct xt_table_info *old,
438 438 struct xt_table_info *new);
439 439  
  440 +/*
  441 + * This helper is performance critical and must be inlined
  442 + */
  443 +static inline unsigned long ifname_compare_aligned(const char *_a,
  444 + const char *_b,
  445 + const char *_mask)
  446 +{
  447 + const unsigned long *a = (const unsigned long *)_a;
  448 + const unsigned long *b = (const unsigned long *)_b;
  449 + const unsigned long *mask = (const unsigned long *)_mask;
  450 + unsigned long ret;
  451 +
  452 + ret = (a[0] ^ b[0]) & mask[0];
  453 + if (IFNAMSIZ > sizeof(unsigned long))
  454 + ret |= (a[1] ^ b[1]) & mask[1];
  455 + if (IFNAMSIZ > 2 * sizeof(unsigned long))
  456 + ret |= (a[2] ^ b[2]) & mask[2];
  457 + if (IFNAMSIZ > 3 * sizeof(unsigned long))
  458 + ret |= (a[3] ^ b[3]) & mask[3];
  459 + BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
  460 + return ret;
  461 +}
  462 +
440 463 #ifdef CONFIG_COMPAT
441 464 #include <net/compat.h>
442 465  
include/net/netfilter/nf_conntrack.h
... ... @@ -91,8 +91,7 @@
91 91 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
92 92 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
93 93  
94   -struct nf_conn
95   -{
  94 +struct nf_conn {
96 95 /* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
97 96 plus 1 for any connection(s) we are `master' for */
98 97 struct nf_conntrack ct_general;
... ... @@ -126,7 +125,6 @@
126 125 #ifdef CONFIG_NET_NS
127 126 struct net *ct_net;
128 127 #endif
129   - struct rcu_head rcu;
130 128 };
131 129  
132 130 static inline struct nf_conn *
... ... @@ -190,9 +188,13 @@
190 188 extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
191 189 extern void nf_ct_l3proto_module_put(unsigned short l3proto);
192 190  
193   -extern struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced);
194   -extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
195   - unsigned int size);
  191 +/*
  192 + * Allocate a hashtable of hlist_head (if nulls == 0),
  193 + * or hlist_nulls_head (if nulls == 1)
  194 + */
  195 +extern void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls);
  196 +
  197 +extern void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size);
196 198  
197 199 extern struct nf_conntrack_tuple_hash *
198 200 __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);
include/net/netfilter/nf_conntrack_helper.h
... ... @@ -14,6 +14,8 @@
14 14  
15 15 struct module;
16 16  
  17 +#define NF_CT_HELPER_NAME_LEN 16
  18 +
17 19 struct nf_conntrack_helper
18 20 {
19 21 struct hlist_node hnode; /* Internal use. */
include/net/netfilter/nf_conntrack_l3proto.h
... ... @@ -53,9 +53,16 @@
53 53 int (*tuple_to_nlattr)(struct sk_buff *skb,
54 54 const struct nf_conntrack_tuple *t);
55 55  
  56 + /*
  57 + * Calculate size of tuple nlattr
  58 + */
  59 + int (*nlattr_tuple_size)(void);
  60 +
56 61 int (*nlattr_to_tuple)(struct nlattr *tb[],
57 62 struct nf_conntrack_tuple *t);
58 63 const struct nla_policy *nla_policy;
  64 +
  65 + size_t nla_size;
59 66  
60 67 #ifdef CONFIG_SYSCTL
61 68 struct ctl_table_header *ctl_table_header;
include/net/netfilter/nf_conntrack_l4proto.h
... ... @@ -64,16 +64,22 @@
64 64 /* convert protoinfo to nfnetink attributes */
65 65 int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
66 66 const struct nf_conn *ct);
  67 + /* Calculate protoinfo nlattr size */
  68 + int (*nlattr_size)(void);
67 69  
68 70 /* convert nfnetlink attributes to protoinfo */
69 71 int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct);
70 72  
71 73 int (*tuple_to_nlattr)(struct sk_buff *skb,
72 74 const struct nf_conntrack_tuple *t);
  75 + /* Calculate tuple nlattr size */
  76 + int (*nlattr_tuple_size)(void);
73 77 int (*nlattr_to_tuple)(struct nlattr *tb[],
74 78 struct nf_conntrack_tuple *t);
75 79 const struct nla_policy *nla_policy;
76 80  
  81 + size_t nla_size;
  82 +
77 83 #ifdef CONFIG_SYSCTL
78 84 struct ctl_table_header **ctl_table_header;
79 85 struct ctl_table *ctl_table;
... ... @@ -107,6 +113,7 @@
107 113 const struct nf_conntrack_tuple *tuple);
108 114 extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
109 115 struct nf_conntrack_tuple *t);
  116 +extern int nf_ct_port_nlattr_tuple_size(void);
110 117 extern const struct nla_policy nf_ct_port_nla_policy[];
111 118  
112 119 #ifdef CONFIG_SYSCTL
include/net/netfilter/nf_conntrack_tuple.h
... ... @@ -12,6 +12,7 @@
12 12  
13 13 #include <linux/netfilter/x_tables.h>
14 14 #include <linux/netfilter/nf_conntrack_tuple_common.h>
  15 +#include <linux/list_nulls.h>
15 16  
16 17 /* A `tuple' is a structure containing the information to uniquely
17 18 identify a connection. ie. if two packets have the same tuple, they
... ... @@ -146,9 +147,8 @@
146 147 ((enum ip_conntrack_dir)(h)->tuple.dst.dir)
147 148  
148 149 /* Connections have two entries in the hash table: one for each way */
149   -struct nf_conntrack_tuple_hash
150   -{
151   - struct hlist_node hnode;
  150 +struct nf_conntrack_tuple_hash {
  151 + struct hlist_nulls_node hnnode;
152 152 struct nf_conntrack_tuple tuple;
153 153 };
154 154  
include/net/netlink.h
... ... @@ -230,6 +230,7 @@
230 230 extern int nla_parse(struct nlattr *tb[], int maxtype,
231 231 struct nlattr *head, int len,
232 232 const struct nla_policy *policy);
  233 +extern int nla_policy_len(const struct nla_policy *, int);
233 234 extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
234 235 extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
235 236 size_t dstsize);
include/net/netns/conntrack.h
... ... @@ -2,6 +2,7 @@
2 2 #define __NETNS_CONNTRACK_H
3 3  
4 4 #include <linux/list.h>
  5 +#include <linux/list_nulls.h>
5 6 #include <asm/atomic.h>
6 7  
7 8 struct ctl_table_header;
8 9  
... ... @@ -10,9 +11,9 @@
10 11 struct netns_ct {
11 12 atomic_t count;
12 13 unsigned int expect_count;
13   - struct hlist_head *hash;
  14 + struct hlist_nulls_head *hash;
14 15 struct hlist_head *expect_hash;
15   - struct hlist_head unconfirmed;
  16 + struct hlist_nulls_head unconfirmed;
16 17 struct ip_conntrack_stat *stat;
17 18 #ifdef CONFIG_NF_CONNTRACK_EVENTS
18 19 struct nf_conntrack_ecache *ecache;
... ... @@ -133,6 +133,32 @@
133 133 }
134 134  
135 135 /**
  136 + * nla_policy_len - Determin the max. length of a policy
  137 + * @policy: policy to use
  138 + * @n: number of policies
  139 + *
  140 + * Determines the max. length of the policy. It is currently used
  141 + * to allocated Netlink buffers roughly the size of the actual
  142 + * message.
  143 + *
  144 + * Returns 0 on success or a negative error code.
  145 + */
  146 +int
  147 +nla_policy_len(const struct nla_policy *p, int n)
  148 +{
  149 + int i, len = 0;
  150 +
  151 + for (i = 0; i < n; i++) {
  152 + if (p->len)
  153 + len += nla_total_size(p->len);
  154 + else if (nla_attr_minlen[p->type])
  155 + len += nla_total_size(nla_attr_minlen[p->type]);
  156 + }
  157 +
  158 + return len;
  159 +}
  160 +
  161 +/**
136 162 * nla_parse - Parse a stream of attributes into a tb buffer
137 163 * @tb: destination array with maxtype+1 elements
138 164 * @maxtype: maximum attribute type to be expected
... ... @@ -467,6 +493,7 @@
467 493 #endif
468 494  
469 495 EXPORT_SYMBOL(nla_validate);
  496 +EXPORT_SYMBOL(nla_policy_len);
470 497 EXPORT_SYMBOL(nla_parse);
471 498 EXPORT_SYMBOL(nla_find);
472 499 EXPORT_SYMBOL(nla_strlcpy);
net/ipv4/netfilter/arp_tables.c
... ... @@ -81,19 +81,7 @@
81 81 static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask)
82 82 {
83 83 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
84   - const unsigned long *a = (const unsigned long *)_a;
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));
  84 + unsigned long ret = ifname_compare_aligned(_a, _b, _mask);
97 85 #else
98 86 unsigned long ret = 0;
99 87 const u16 *a = (const u16 *)_a;
... ... @@ -404,7 +392,9 @@
404 392 && unconditional(&e->arp)) || visited) {
405 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 398 duprintf("mark_source_chains: bad "
409 399 "negative verdict (%i)\n",
410 400 t->verdict);
net/ipv4/netfilter/ip_tables.c
... ... @@ -74,25 +74,6 @@
74 74  
75 75 Hence the start of any table is given by get_table() below. */
76 76  
77   -static 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 77 /* Returns whether matches rule or not. */
97 78 /* Performance critical - called for every packet */
98 79 static inline bool
... ... @@ -121,7 +102,7 @@
121 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 107 if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
127 108 dprintf("VIA in mismatch (%s vs %s).%s\n",
... ... @@ -130,7 +111,7 @@
130 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 116 if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
136 117 dprintf("VIA out mismatch (%s vs %s).%s\n",
... ... @@ -507,7 +488,9 @@
507 488 && unconditional(&e->ip)) || visited) {
508 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 494 duprintf("mark_source_chains: bad "
512 495 "negative verdict (%i)\n",
513 496 t->verdict);
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
... ... @@ -328,6 +328,11 @@
328 328  
329 329 return 0;
330 330 }
  331 +
  332 +static int ipv4_nlattr_tuple_size(void)
  333 +{
  334 + return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1);
  335 +}
331 336 #endif
332 337  
333 338 static struct nf_sockopt_ops so_getorigdst = {
... ... @@ -347,6 +352,7 @@
347 352 .get_l4proto = ipv4_get_l4proto,
348 353 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
349 354 .tuple_to_nlattr = ipv4_tuple_to_nlattr,
  355 + .nlattr_tuple_size = ipv4_nlattr_tuple_size,
350 356 .nlattr_to_tuple = ipv4_nlattr_to_tuple,
351 357 .nla_policy = ipv4_nla_policy,
352 358 #endif
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
... ... @@ -25,40 +25,42 @@
25 25 unsigned int bucket;
26 26 };
27 27  
28   -static struct hlist_node *ct_get_first(struct seq_file *seq)
  28 +static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
29 29 {
30 30 struct net *net = seq_file_net(seq);
31 31 struct ct_iter_state *st = seq->private;
32   - struct hlist_node *n;
  32 + struct hlist_nulls_node *n;
33 33  
34 34 for (st->bucket = 0;
35 35 st->bucket < nf_conntrack_htable_size;
36 36 st->bucket++) {
37 37 n = rcu_dereference(net->ct.hash[st->bucket].first);
38   - if (n)
  38 + if (!is_a_nulls(n))
39 39 return n;
40 40 }
41 41 return NULL;
42 42 }
43 43  
44   -static struct hlist_node *ct_get_next(struct seq_file *seq,
45   - struct hlist_node *head)
  44 +static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
  45 + struct hlist_nulls_node *head)
46 46 {
47 47 struct net *net = seq_file_net(seq);
48 48 struct ct_iter_state *st = seq->private;
49 49  
50 50 head = rcu_dereference(head->next);
51   - while (head == NULL) {
52   - if (++st->bucket >= nf_conntrack_htable_size)
53   - return NULL;
  51 + while (is_a_nulls(head)) {
  52 + if (likely(get_nulls_value(head) == st->bucket)) {
  53 + if (++st->bucket >= nf_conntrack_htable_size)
  54 + return NULL;
  55 + }
54 56 head = rcu_dereference(net->ct.hash[st->bucket].first);
55 57 }
56 58 return head;
57 59 }
58 60  
59   -static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
  61 +static 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 65 if (head)
64 66 while (pos && (head = ct_get_next(seq, head)))
65 67  
66 68  
67 69  
68 70  
69 71  
70 72  
71 73  
72 74  
73 75  
74 76  
75 77  
76 78  
77 79  
78 80  
79 81  
80 82  
81 83  
... ... @@ -87,69 +89,76 @@
87 89  
88 90 static int ct_seq_show(struct seq_file *s, void *v)
89 91 {
90   - const struct nf_conntrack_tuple_hash *hash = v;
91   - const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
  92 + struct nf_conntrack_tuple_hash *hash = v;
  93 + struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
92 94 const struct nf_conntrack_l3proto *l3proto;
93 95 const struct nf_conntrack_l4proto *l4proto;
  96 + int ret = 0;
94 97  
95 98 NF_CT_ASSERT(ct);
  99 + if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
  100 + return 0;
96 101  
  102 +
97 103 /* we only want to print DIR_ORIGINAL */
98 104 if (NF_CT_DIRECTION(hash))
99   - return 0;
  105 + goto release;
100 106 if (nf_ct_l3num(ct) != AF_INET)
101   - return 0;
  107 + goto release;
102 108  
103 109 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
104 110 NF_CT_ASSERT(l3proto);
105 111 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
106 112 NF_CT_ASSERT(l4proto);
107 113  
  114 + ret = -ENOSPC;
108 115 if (seq_printf(s, "%-8s %u %ld ",
109 116 l4proto->name, nf_ct_protonum(ct),
110 117 timer_pending(&ct->timeout)
111 118 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
112   - return -ENOSPC;
  119 + goto release;
113 120  
114 121 if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
115   - return -ENOSPC;
  122 + goto release;
116 123  
117 124 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
118 125 l3proto, l4proto))
119   - return -ENOSPC;
  126 + goto release;
120 127  
121 128 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
122   - return -ENOSPC;
  129 + goto release;
123 130  
124 131 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
125 132 if (seq_printf(s, "[UNREPLIED] "))
126   - return -ENOSPC;
  133 + goto release;
127 134  
128 135 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
129 136 l3proto, l4proto))
130   - return -ENOSPC;
  137 + goto release;
131 138  
132 139 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
133   - return -ENOSPC;
  140 + goto release;
134 141  
135 142 if (test_bit(IPS_ASSURED_BIT, &ct->status))
136 143 if (seq_printf(s, "[ASSURED] "))
137   - return -ENOSPC;
  144 + goto release;
138 145  
139 146 #ifdef CONFIG_NF_CONNTRACK_MARK
140 147 if (seq_printf(s, "mark=%u ", ct->mark))
141   - return -ENOSPC;
  148 + goto release;
142 149 #endif
143 150  
144 151 #ifdef CONFIG_NF_CONNTRACK_SECMARK
145 152 if (seq_printf(s, "secmark=%u ", ct->secmark))
146   - return -ENOSPC;
  153 + goto release;
147 154 #endif
148 155  
149 156 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
150   - return -ENOSPC;
151   -
152   - return 0;
  157 + goto release;
  158 + ret = 0;
  159 +release:
  160 + nf_ct_put(ct);
  161 + return ret;
153 162 }
154 163  
155 164 static const struct seq_operations ct_seq_ops = {
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
... ... @@ -262,6 +262,11 @@
262 262  
263 263 return 0;
264 264 }
  265 +
  266 +static int icmp_nlattr_tuple_size(void)
  267 +{
  268 + return nla_policy_len(icmp_nla_policy, CTA_PROTO_MAX + 1);
  269 +}
265 270 #endif
266 271  
267 272 #ifdef CONFIG_SYSCTL
... ... @@ -309,6 +314,7 @@
309 314 .me = NULL,
310 315 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
311 316 .tuple_to_nlattr = icmp_tuple_to_nlattr,
  317 + .nlattr_tuple_size = icmp_nlattr_tuple_size,
312 318 .nlattr_to_tuple = icmp_nlattr_to_tuple,
313 319 .nla_policy = icmp_nla_policy,
314 320 #endif
net/ipv4/netfilter/nf_nat_core.c
... ... @@ -679,7 +679,7 @@
679 679 static int __net_init nf_nat_net_init(struct net *net)
680 680 {
681 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 683 if (!net->ipv4.nat_bysource)
684 684 return -ENOMEM;
685 685 return 0;
net/ipv6/netfilter/ip6_tables.c
... ... @@ -89,25 +89,6 @@
89 89 (nexthdr == IPPROTO_DSTOPTS) );
90 90 }
91 91  
92   -static 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 92 /* Returns whether matches rule or not. */
112 93 /* Performance critical - called for every packet */
113 94 static inline bool
... ... @@ -138,7 +119,7 @@
138 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 124 if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
144 125 dprintf("VIA in mismatch (%s vs %s).%s\n",
... ... @@ -147,7 +128,7 @@
147 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 133 if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
153 134 dprintf("VIA out mismatch (%s vs %s).%s\n",
... ... @@ -536,7 +517,9 @@
536 517 && unconditional(&e->ipv6)) || visited) {
537 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 523 duprintf("mark_source_chains: bad "
541 524 "negative verdict (%i)\n",
542 525 t->verdict);
net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
... ... @@ -342,6 +342,11 @@
342 342  
343 343 return 0;
344 344 }
  345 +
  346 +static int ipv6_nlattr_tuple_size(void)
  347 +{
  348 + return nla_policy_len(ipv6_nla_policy, CTA_IP_MAX + 1);
  349 +}
345 350 #endif
346 351  
347 352 struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = {
... ... @@ -353,6 +358,7 @@
353 358 .get_l4proto = ipv6_get_l4proto,
354 359 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
355 360 .tuple_to_nlattr = ipv6_tuple_to_nlattr,
  361 + .nlattr_tuple_size = ipv6_nlattr_tuple_size,
356 362 .nlattr_to_tuple = ipv6_nlattr_to_tuple,
357 363 .nla_policy = ipv6_nla_policy,
358 364 #endif
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
... ... @@ -269,6 +269,11 @@
269 269  
270 270 return 0;
271 271 }
  272 +
  273 +static int icmpv6_nlattr_tuple_size(void)
  274 +{
  275 + return nla_policy_len(icmpv6_nla_policy, CTA_PROTO_MAX + 1);
  276 +}
272 277 #endif
273 278  
274 279 #ifdef CONFIG_SYSCTL
... ... @@ -300,6 +305,7 @@
300 305 .error = icmpv6_error,
301 306 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
302 307 .tuple_to_nlattr = icmpv6_tuple_to_nlattr,
  308 + .nlattr_tuple_size = icmpv6_nlattr_tuple_size,
303 309 .nlattr_to_tuple = icmpv6_nlattr_to_tuple,
304 310 .nla_policy = icmpv6_nla_policy,
305 311 #endif
net/netfilter/Kconfig
... ... @@ -374,7 +374,7 @@
374 374  
375 375 config NETFILTER_XT_TARGET_LED
376 376 tristate '"LED" target support'
377   - depends on LEDS_CLASS
  377 + depends on LEDS_CLASS && LED_TRIGGERS
378 378 depends on NETFILTER_ADVANCED
379 379 help
380 380 This option adds a `LED' target, which allows you to blink LEDs in
net/netfilter/nf_conntrack_core.c
... ... @@ -29,6 +29,7 @@
29 29 #include <linux/netdevice.h>
30 30 #include <linux/socket.h>
31 31 #include <linux/mm.h>
  32 +#include <linux/rculist_nulls.h>
32 33  
33 34 #include <net/netfilter/nf_conntrack.h>
34 35 #include <net/netfilter/nf_conntrack_l3proto.h>
... ... @@ -163,8 +164,8 @@
163 164 clean_from_lists(struct nf_conn *ct)
164 165 {
165 166 pr_debug("clean_from_lists(%p)\n", ct);
166   - hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
167   - hlist_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode);
  167 + hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
  168 + hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode);
168 169  
169 170 /* Destroy all pending expectations */
170 171 nf_ct_remove_expectations(ct);
... ... @@ -204,8 +205,8 @@
204 205  
205 206 /* We overload first tuple to link into unconfirmed list. */
206 207 if (!nf_ct_is_confirmed(ct)) {
207   - BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode));
208   - hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
  208 + BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode));
  209 + hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
209 210 }
210 211  
211 212 NF_CT_STAT_INC(net, delete);
212 213  
213 214  
... ... @@ -242,18 +243,26 @@
242 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 + */
245 253 struct nf_conntrack_tuple_hash *
246 254 __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
247 255 {
248 256 struct nf_conntrack_tuple_hash *h;
249   - struct hlist_node *n;
  257 + struct hlist_nulls_node *n;
250 258 unsigned int hash = hash_conntrack(tuple);
251 259  
252 260 /* Disable BHs the entire time since we normally need to disable them
253 261 * at least once for the stats anyway.
254 262 */
255 263 local_bh_disable();
256   - hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
  264 +begin:
  265 + hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) {
257 266 if (nf_ct_tuple_equal(tuple, &h->tuple)) {
258 267 NF_CT_STAT_INC(net, found);
259 268 local_bh_enable();
... ... @@ -261,6 +270,13 @@
261 270 }
262 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 280 local_bh_enable();
265 281  
266 282 return NULL;
267 283  
... ... @@ -275,11 +291,18 @@
275 291 struct nf_conn *ct;
276 292  
277 293 rcu_read_lock();
  294 +begin:
278 295 h = __nf_conntrack_find(net, tuple);
279 296 if (h) {
280 297 ct = nf_ct_tuplehash_to_ctrack(h);
281 298 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
282 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 307 rcu_read_unlock();
285 308  
286 309  
... ... @@ -293,9 +316,9 @@
293 316 {
294 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 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 322 &net->ct.hash[repl_hash]);
300 323 }
301 324  
... ... @@ -318,7 +341,7 @@
318 341 struct nf_conntrack_tuple_hash *h;
319 342 struct nf_conn *ct;
320 343 struct nf_conn_help *help;
321   - struct hlist_node *n;
  344 + struct hlist_nulls_node *n;
322 345 enum ip_conntrack_info ctinfo;
323 346 struct net *net;
324 347  
325 348  
326 349  
... ... @@ -350,17 +373,17 @@
350 373 /* See if there's one in the list already, including reverse:
351 374 NAT could have grabbed it without realizing, since we're
352 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 377 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
355 378 &h->tuple))
356 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 381 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
359 382 &h->tuple))
360 383 goto out;
361 384  
362 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 388 __nf_conntrack_hash_insert(ct, hash, repl_hash);
366 389 /* Timer relative to confirmation time, not original
367 390  
... ... @@ -399,14 +422,14 @@
399 422 {
400 423 struct net *net = nf_ct_net(ignored_conntrack);
401 424 struct nf_conntrack_tuple_hash *h;
402   - struct hlist_node *n;
  425 + struct hlist_nulls_node *n;
403 426 unsigned int hash = hash_conntrack(tuple);
404 427  
405 428 /* Disable BHs the entire time since we need to disable them at
406 429 * least once for the stats anyway.
407 430 */
408 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 433 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
411 434 nf_ct_tuple_equal(tuple, &h->tuple)) {
412 435 NF_CT_STAT_INC(net, found);
413 436  
... ... @@ -430,14 +453,14 @@
430 453 /* Use oldest entry, which is roughly LRU */
431 454 struct nf_conntrack_tuple_hash *h;
432 455 struct nf_conn *ct = NULL, *tmp;
433   - struct hlist_node *n;
  456 + struct hlist_nulls_node *n;
434 457 unsigned int i, cnt = 0;
435 458 int dropped = 0;
436 459  
437 460 rcu_read_lock();
438 461 for (i = 0; i < nf_conntrack_htable_size; i++) {
439   - hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash],
440   - hnode) {
  462 + hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash],
  463 + hnnode) {
441 464 tmp = nf_ct_tuplehash_to_ctrack(h);
442 465 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
443 466 ct = tmp;
444 467  
445 468  
... ... @@ -508,27 +531,19 @@
508 531 #ifdef CONFIG_NET_NS
509 532 ct->ct_net = net;
510 533 #endif
511   - INIT_RCU_HEAD(&ct->rcu);
512 534  
513 535 return ct;
514 536 }
515 537 EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
516 538  
517   -static 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   -
525 539 void nf_conntrack_free(struct nf_conn *ct)
526 540 {
527 541 struct net *net = nf_ct_net(ct);
528 542  
529 543 nf_ct_ext_destroy(ct);
530 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 }
533 548 EXPORT_SYMBOL_GPL(nf_conntrack_free);
534 549  
... ... @@ -594,7 +609,7 @@
594 609 }
595 610  
596 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 613 &net->ct.unconfirmed);
599 614  
600 615 spin_unlock_bh(&nf_conntrack_lock);
... ... @@ -906,6 +921,12 @@
906 921 return 0;
907 922 }
908 923 EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_to_tuple);
  924 +
  925 +int nf_ct_port_nlattr_tuple_size(void)
  926 +{
  927 + return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
  928 +}
  929 +EXPORT_SYMBOL_GPL(nf_ct_port_nlattr_tuple_size);
909 930 #endif
910 931  
911 932 /* Used by ipt_REJECT and ip6t_REJECT. */
912 933  
913 934  
... ... @@ -934,17 +955,17 @@
934 955 {
935 956 struct nf_conntrack_tuple_hash *h;
936 957 struct nf_conn *ct;
937   - struct hlist_node *n;
  958 + struct hlist_nulls_node *n;
938 959  
939 960 spin_lock_bh(&nf_conntrack_lock);
940 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 963 ct = nf_ct_tuplehash_to_ctrack(h);
943 964 if (iter(ct, data))
944 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 969 ct = nf_ct_tuplehash_to_ctrack(h);
949 970 if (iter(ct, data))
950 971 set_bit(IPS_DYING_BIT, &ct->status);
... ... @@ -992,7 +1013,7 @@
992 1013 return 1;
993 1014 }
994 1015  
995   -void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int size)
  1016 +void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size)
996 1017 {
997 1018 if (vmalloced)
998 1019 vfree(hash);
999 1020  
1000 1021  
1001 1022  
1002 1023  
... ... @@ -1060,26 +1081,28 @@
1060 1081 }
1061 1082 }
1062 1083  
1063   -struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
  1084 +void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls)
1064 1085 {
1065   - struct hlist_head *hash;
1066   - unsigned int size, i;
  1086 + struct hlist_nulls_head *hash;
  1087 + unsigned int nr_slots, i;
  1088 + size_t sz;
1067 1089  
1068 1090 *vmalloced = 0;
1069 1091  
1070   - size = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_head));
1071   - hash = (void*)__get_free_pages(GFP_KERNEL|__GFP_NOWARN,
1072   - get_order(sizeof(struct hlist_head)
1073   - * size));
  1092 + BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
  1093 + nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
  1094 + sz = nr_slots * sizeof(struct hlist_nulls_head);
  1095 + hash = (void *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO,
  1096 + get_order(sz));
1074 1097 if (!hash) {
1075 1098 *vmalloced = 1;
1076 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)
1081   - for (i = 0; i < size; i++)
1082   - INIT_HLIST_HEAD(&hash[i]);
  1103 + if (hash && nulls)
  1104 + for (i = 0; i < nr_slots; i++)
  1105 + INIT_HLIST_NULLS_HEAD(&hash[i], i);
1083 1106  
1084 1107 return hash;
1085 1108 }
... ... @@ -1090,7 +1113,7 @@
1090 1113 int i, bucket, vmalloced, old_vmalloced;
1091 1114 unsigned int hashsize, old_size;
1092 1115 int rnd;
1093   - struct hlist_head *hash, *old_hash;
  1116 + struct hlist_nulls_head *hash, *old_hash;
1094 1117 struct nf_conntrack_tuple_hash *h;
1095 1118  
1096 1119 /* On boot, we can set this without any fancy locking. */
... ... @@ -1101,7 +1124,7 @@
1101 1124 if (!hashsize)
1102 1125 return -EINVAL;
1103 1126  
1104   - hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced);
  1127 + hash = nf_ct_alloc_hashtable(&hashsize, &vmalloced, 1);
1105 1128 if (!hash)
1106 1129 return -ENOMEM;
1107 1130  
1108 1131  
... ... @@ -1116,12 +1139,12 @@
1116 1139 */
1117 1140 spin_lock_bh(&nf_conntrack_lock);
1118 1141 for (i = 0; i < nf_conntrack_htable_size; i++) {
1119   - while (!hlist_empty(&init_net.ct.hash[i])) {
1120   - h = hlist_entry(init_net.ct.hash[i].first,
1121   - struct nf_conntrack_tuple_hash, hnode);
1122   - hlist_del_rcu(&h->hnode);
  1142 + while (!hlist_nulls_empty(&init_net.ct.hash[i])) {
  1143 + h = hlist_nulls_entry(init_net.ct.hash[i].first,
  1144 + struct nf_conntrack_tuple_hash, hnnode);
  1145 + hlist_nulls_del_rcu(&h->hnnode);
1123 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 1150 old_size = nf_conntrack_htable_size;
... ... @@ -1172,7 +1195,7 @@
1172 1195  
1173 1196 nf_conntrack_cachep = kmem_cache_create("nf_conntrack",
1174 1197 sizeof(struct nf_conn),
1175   - 0, 0, NULL);
  1198 + 0, SLAB_DESTROY_BY_RCU, NULL);
1176 1199 if (!nf_conntrack_cachep) {
1177 1200 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1178 1201 ret = -ENOMEM;
... ... @@ -1202,7 +1225,7 @@
1202 1225 int ret;
1203 1226  
1204 1227 atomic_set(&net->ct.count, 0);
1205   - INIT_HLIST_HEAD(&net->ct.unconfirmed);
  1228 + INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, 0);
1206 1229 net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1207 1230 if (!net->ct.stat) {
1208 1231 ret = -ENOMEM;
... ... @@ -1212,7 +1235,7 @@
1212 1235 if (ret < 0)
1213 1236 goto err_ecache;
1214 1237 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1215   - &net->ct.hash_vmalloc);
  1238 + &net->ct.hash_vmalloc, 1);
1216 1239 if (!net->ct.hash) {
1217 1240 ret = -ENOMEM;
1218 1241 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
net/netfilter/nf_conntrack_expect.c
... ... @@ -604,7 +604,7 @@
604 604  
605 605 net->ct.expect_count = 0;
606 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 608 if (net->ct.expect_hash == NULL)
609 609 goto err1;
610 610  
net/netfilter/nf_conntrack_helper.c
... ... @@ -142,6 +142,7 @@
142 142  
143 143 BUG_ON(me->expect_policy == NULL);
144 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 147 mutex_lock(&nf_ct_helper_mutex);
147 148 hlist_add_head_rcu(&me->hnode, &nf_ct_helper_hash[h]);
... ... @@ -158,6 +159,7 @@
158 159 struct nf_conntrack_tuple_hash *h;
159 160 struct nf_conntrack_expect *exp;
160 161 const struct hlist_node *n, *next;
  162 + const struct hlist_nulls_node *nn;
161 163 unsigned int i;
162 164  
163 165 /* Get rid of expectations */
164 166  
... ... @@ -174,10 +176,10 @@
174 176 }
175 177  
176 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 180 unhelp(h, me);
179 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 183 unhelp(h, me);
182 184 }
183 185 }
... ... @@ -217,7 +219,7 @@
217 219  
218 220 nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
219 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 223 if (!nf_ct_helper_hash)
222 224 return -ENOMEM;
223 225  
net/netfilter/nf_conntrack_netlink.c
... ... @@ -19,6 +19,7 @@
19 19 #include <linux/module.h>
20 20 #include <linux/kernel.h>
21 21 #include <linux/rculist.h>
  22 +#include <linux/rculist_nulls.h>
22 23 #include <linux/types.h>
23 24 #include <linux/timer.h>
24 25 #include <linux/skbuff.h>
... ... @@ -404,6 +405,78 @@
404 405 }
405 406  
406 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 + */
  427 +static struct sk_buff *
  428 +ctnetlink_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 +
407 480 static int ctnetlink_conntrack_event(struct notifier_block *this,
408 481 unsigned long events, void *ptr)
409 482 {
... ... @@ -437,7 +510,7 @@
437 510 if (!item->report && !nfnetlink_has_listeners(group))
438 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 514 if (!skb)
442 515 return NOTIFY_DONE;
443 516  
... ... @@ -536,7 +609,7 @@
536 609 {
537 610 struct nf_conn *ct, *last;
538 611 struct nf_conntrack_tuple_hash *h;
539   - struct hlist_node *n;
  612 + struct hlist_nulls_node *n;
540 613 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
541 614 u_int8_t l3proto = nfmsg->nfgen_family;
542 615  
543 616  
544 617  
545 618  
546 619  
... ... @@ -544,27 +617,27 @@
544 617 last = (struct nf_conn *)cb->args[1];
545 618 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
546 619 restart:
547   - hlist_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
548   - hnode) {
  620 + hlist_nulls_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
  621 + hnnode) {
549 622 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
550 623 continue;
551 624 ct = nf_ct_tuplehash_to_ctrack(h);
  625 + if (!atomic_inc_not_zero(&ct->ct_general.use))
  626 + continue;
552 627 /* Dump entries of a given L3 protocol number.
553 628 * If it is not specified, ie. l3proto == 0,
554 629 * then dump everything. */
555 630 if (l3proto && nf_ct_l3num(ct) != l3proto)
556   - continue;
  631 + goto releasect;
557 632 if (cb->args[1]) {
558 633 if (ct != last)
559   - continue;
  634 + goto releasect;
560 635 cb->args[1] = 0;
561 636 }
562 637 if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
563 638 cb->nlh->nlmsg_seq,
564 639 IPCTNL_MSG_CT_NEW,
565 640 1, ct) < 0) {
566   - if (!atomic_inc_not_zero(&ct->ct_general.use))
567   - continue;
568 641 cb->args[1] = (unsigned long)ct;
569 642 goto out;
570 643 }
... ... @@ -577,6 +650,8 @@
577 650 if (acct)
578 651 memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]));
579 652 }
  653 +releasect:
  654 + nf_ct_put(ct);
580 655 }
581 656 if (cb->args[1]) {
582 657 cb->args[1] = 0;
583 658  
... ... @@ -1242,13 +1317,12 @@
1242 1317 if (err < 0)
1243 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 1321 if (master_h == NULL) {
1247 1322 err = -ENOENT;
1248 1323 goto err2;
1249 1324 }
1250 1325 master_ct = nf_ct_tuplehash_to_ctrack(master_h);
1251   - nf_conntrack_get(&master_ct->ct_general);
1252 1326 __set_bit(IPS_EXPECTED_BIT, &ct->status);
1253 1327 ct->master = master_ct;
1254 1328 }
net/netfilter/nf_conntrack_proto.c
... ... @@ -167,6 +167,9 @@
167 167 if (proto->l3proto >= AF_MAX)
168 168 return -EBUSY;
169 169  
  170 + if (proto->tuple_to_nlattr && !proto->nlattr_tuple_size)
  171 + return -EINVAL;
  172 +
170 173 mutex_lock(&nf_ct_proto_mutex);
171 174 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
172 175 ret = -EBUSY;
... ... @@ -177,6 +180,9 @@
177 180 if (ret < 0)
178 181 goto out_unlock;
179 182  
  183 + if (proto->nlattr_tuple_size)
  184 + proto->nla_size = 3 * proto->nlattr_tuple_size();
  185 +
180 186 rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto);
181 187  
182 188 out_unlock:
... ... @@ -263,6 +269,10 @@
263 269 if (l4proto->l3proto >= PF_MAX)
264 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 276 mutex_lock(&nf_ct_proto_mutex);
267 277 if (!nf_ct_protos[l4proto->l3proto]) {
268 278 /* l3proto may be loaded latter. */
... ... @@ -289,6 +299,12 @@
289 299 ret = nf_ct_l4proto_register_sysctl(l4proto);
290 300 if (ret < 0)
291 301 goto out_unlock;
  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();
292 308  
293 309 rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
294 310 l4proto);
net/netfilter/nf_conntrack_proto_dccp.c
... ... @@ -669,6 +669,12 @@
669 669 write_unlock_bh(&dccp_lock);
670 670 return 0;
671 671 }
  672 +
  673 +static 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 678 #endif
673 679  
674 680 #ifdef CONFIG_SYSCTL
675 681  
... ... @@ -749,8 +755,10 @@
749 755 .print_conntrack = dccp_print_conntrack,
750 756 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
751 757 .to_nlattr = dccp_to_nlattr,
  758 + .nlattr_size = dccp_nlattr_size,
752 759 .from_nlattr = nlattr_to_dccp,
753 760 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
  761 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
754 762 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
755 763 .nla_policy = nf_ct_port_nla_policy,
756 764 #endif
... ... @@ -771,6 +779,7 @@
771 779 .to_nlattr = dccp_to_nlattr,
772 780 .from_nlattr = nlattr_to_dccp,
773 781 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
  782 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
774 783 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
775 784 .nla_policy = nf_ct_port_nla_policy,
776 785 #endif
net/netfilter/nf_conntrack_proto_gre.c
... ... @@ -293,6 +293,7 @@
293 293 .me = THIS_MODULE,
294 294 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
295 295 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
  296 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
296 297 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
297 298 .nla_policy = nf_ct_port_nla_policy,
298 299 #endif
net/netfilter/nf_conntrack_proto_sctp.c
... ... @@ -537,6 +537,12 @@
537 537  
538 538 return 0;
539 539 }
  540 +
  541 +static 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 546 #endif
541 547  
542 548 #ifdef CONFIG_SYSCTL
543 549  
... ... @@ -668,8 +674,10 @@
668 674 .me = THIS_MODULE,
669 675 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
670 676 .to_nlattr = sctp_to_nlattr,
  677 + .nlattr_size = sctp_nlattr_size,
671 678 .from_nlattr = nlattr_to_sctp,
672 679 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
  680 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
673 681 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
674 682 .nla_policy = nf_ct_port_nla_policy,
675 683 #endif
676 684  
... ... @@ -696,8 +704,10 @@
696 704 .me = THIS_MODULE,
697 705 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
698 706 .to_nlattr = sctp_to_nlattr,
  707 + .nlattr_size = sctp_nlattr_size,
699 708 .from_nlattr = nlattr_to_sctp,
700 709 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
  710 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
701 711 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
702 712 .nla_policy = nf_ct_port_nla_policy,
703 713 #endif
net/netfilter/nf_conntrack_proto_tcp.c
... ... @@ -1184,6 +1184,17 @@
1184 1184  
1185 1185 return 0;
1186 1186 }
  1187 +
  1188 +static 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 +
  1194 +static int tcp_nlattr_tuple_size(void)
  1195 +{
  1196 + return nla_policy_len(nf_ct_port_nla_policy, CTA_PROTO_MAX + 1);
  1197 +}
1187 1198 #endif
1188 1199  
1189 1200 #ifdef CONFIG_SYSCTL
1190 1201  
... ... @@ -1399,9 +1410,11 @@
1399 1410 .error = tcp_error,
1400 1411 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
1401 1412 .to_nlattr = tcp_to_nlattr,
  1413 + .nlattr_size = tcp_nlattr_size,
1402 1414 .from_nlattr = nlattr_to_tcp,
1403 1415 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
1404 1416 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
  1417 + .nlattr_tuple_size = tcp_nlattr_tuple_size,
1405 1418 .nla_policy = nf_ct_port_nla_policy,
1406 1419 #endif
1407 1420 #ifdef CONFIG_SYSCTL
1408 1421  
... ... @@ -1429,9 +1442,11 @@
1429 1442 .error = tcp_error,
1430 1443 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
1431 1444 .to_nlattr = tcp_to_nlattr,
  1445 + .nlattr_size = tcp_nlattr_size,
1432 1446 .from_nlattr = nlattr_to_tcp,
1433 1447 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
1434 1448 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
  1449 + .nlattr_tuple_size = tcp_nlattr_tuple_size,
1435 1450 .nla_policy = nf_ct_port_nla_policy,
1436 1451 #endif
1437 1452 #ifdef CONFIG_SYSCTL
net/netfilter/nf_conntrack_proto_udp.c
... ... @@ -195,6 +195,7 @@
195 195 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
196 196 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
197 197 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
  198 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
198 199 .nla_policy = nf_ct_port_nla_policy,
199 200 #endif
200 201 #ifdef CONFIG_SYSCTL
... ... @@ -222,6 +223,7 @@
222 223 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
223 224 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
224 225 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
  226 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
225 227 .nla_policy = nf_ct_port_nla_policy,
226 228 #endif
227 229 #ifdef CONFIG_SYSCTL
net/netfilter/nf_conntrack_proto_udplite.c
... ... @@ -180,6 +180,7 @@
180 180 .error = udplite_error,
181 181 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
182 182 .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
  183 + .nlattr_tuple_size = nf_ct_port_nlattr_tuple_size,
183 184 .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
184 185 .nla_policy = nf_ct_port_nla_policy,
185 186 #endif
net/netfilter/nf_conntrack_standalone.c
... ... @@ -44,40 +44,42 @@
44 44 unsigned int bucket;
45 45 };
46 46  
47   -static struct hlist_node *ct_get_first(struct seq_file *seq)
  47 +static struct hlist_nulls_node *ct_get_first(struct seq_file *seq)
48 48 {
49 49 struct net *net = seq_file_net(seq);
50 50 struct ct_iter_state *st = seq->private;
51   - struct hlist_node *n;
  51 + struct hlist_nulls_node *n;
52 52  
53 53 for (st->bucket = 0;
54 54 st->bucket < nf_conntrack_htable_size;
55 55 st->bucket++) {
56 56 n = rcu_dereference(net->ct.hash[st->bucket].first);
57   - if (n)
  57 + if (!is_a_nulls(n))
58 58 return n;
59 59 }
60 60 return NULL;
61 61 }
62 62  
63   -static struct hlist_node *ct_get_next(struct seq_file *seq,
64   - struct hlist_node *head)
  63 +static struct hlist_nulls_node *ct_get_next(struct seq_file *seq,
  64 + struct hlist_nulls_node *head)
65 65 {
66 66 struct net *net = seq_file_net(seq);
67 67 struct ct_iter_state *st = seq->private;
68 68  
69 69 head = rcu_dereference(head->next);
70   - while (head == NULL) {
71   - if (++st->bucket >= nf_conntrack_htable_size)
72   - return NULL;
  70 + while (is_a_nulls(head)) {
  71 + if (likely(get_nulls_value(head) == st->bucket)) {
  72 + if (++st->bucket >= nf_conntrack_htable_size)
  73 + return NULL;
  74 + }
73 75 head = rcu_dereference(net->ct.hash[st->bucket].first);
74 76 }
75 77 return head;
76 78 }
77 79  
78   -static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
  80 +static 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 84 if (head)
83 85 while (pos && (head = ct_get_next(seq, head)))
84 86  
85 87  
86 88  
87 89  
88 90  
89 91  
90 92  
91 93  
92 94  
93 95  
94 96  
95 97  
96 98  
97 99  
98 100  
99 101  
... ... @@ -107,67 +109,74 @@
107 109 /* return 0 on success, 1 in case of error */
108 110 static int ct_seq_show(struct seq_file *s, void *v)
109 111 {
110   - const struct nf_conntrack_tuple_hash *hash = v;
111   - const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
  112 + struct nf_conntrack_tuple_hash *hash = v;
  113 + struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
112 114 const struct nf_conntrack_l3proto *l3proto;
113 115 const struct nf_conntrack_l4proto *l4proto;
  116 + int ret = 0;
114 117  
115 118 NF_CT_ASSERT(ct);
  119 + if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
  120 + return 0;
116 121  
117 122 /* we only want to print DIR_ORIGINAL */
118 123 if (NF_CT_DIRECTION(hash))
119   - return 0;
  124 + goto release;
120 125  
121 126 l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
122 127 NF_CT_ASSERT(l3proto);
123 128 l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
124 129 NF_CT_ASSERT(l4proto);
125 130  
  131 + ret = -ENOSPC;
126 132 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
127 133 l3proto->name, nf_ct_l3num(ct),
128 134 l4proto->name, nf_ct_protonum(ct),
129 135 timer_pending(&ct->timeout)
130 136 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
131   - return -ENOSPC;
  137 + goto release;
132 138  
133 139 if (l4proto->print_conntrack && l4proto->print_conntrack(s, ct))
134   - return -ENOSPC;
  140 + goto release;
135 141  
136 142 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
137 143 l3proto, l4proto))
138   - return -ENOSPC;
  144 + goto release;
139 145  
140 146 if (seq_print_acct(s, ct, IP_CT_DIR_ORIGINAL))
141   - return -ENOSPC;
  147 + goto release;
142 148  
143 149 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
144 150 if (seq_printf(s, "[UNREPLIED] "))
145   - return -ENOSPC;
  151 + goto release;
146 152  
147 153 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
148 154 l3proto, l4proto))
149   - return -ENOSPC;
  155 + goto release;
150 156  
151 157 if (seq_print_acct(s, ct, IP_CT_DIR_REPLY))
152   - return -ENOSPC;
  158 + goto release;
153 159  
154 160 if (test_bit(IPS_ASSURED_BIT, &ct->status))
155 161 if (seq_printf(s, "[ASSURED] "))
156   - return -ENOSPC;
  162 + goto release;
157 163  
158 164 #if defined(CONFIG_NF_CONNTRACK_MARK)
159 165 if (seq_printf(s, "mark=%u ", ct->mark))
160   - return -ENOSPC;
  166 + goto release;
161 167 #endif
162 168  
163 169 #ifdef CONFIG_NF_CONNTRACK_SECMARK
164 170 if (seq_printf(s, "secmark=%u ", ct->secmark))
165   - return -ENOSPC;
  171 + goto release;
166 172 #endif
167 173  
168 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;
  178 +release:
  179 + nf_ct_put(ct);
171 180 return 0;
172 181 }
173 182  
net/netfilter/xt_connlimit.c
... ... @@ -108,7 +108,7 @@
108 108 const struct nf_conntrack_tuple_hash *found;
109 109 struct xt_connlimit_conn *conn;
110 110 struct xt_connlimit_conn *tmp;
111   - const struct nf_conn *found_ct;
  111 + struct nf_conn *found_ct;
112 112 struct list_head *hash;
113 113 bool addit = true;
114 114 int matches = 0;
... ... @@ -123,7 +123,7 @@
123 123  
124 124 /* check the saved connections */
125 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 127 found_ct = NULL;
128 128  
129 129 if (found != NULL)
... ... @@ -151,6 +151,7 @@
151 151 * we do not care about connections which are
152 152 * closed already -> ditch it
153 153 */
  154 + nf_ct_put(found_ct);
154 155 list_del(&conn->list);
155 156 kfree(conn);
156 157 continue;
... ... @@ -160,6 +161,7 @@
160 161 match->family))
161 162 /* same source network -> be counted! */
162 163 ++matches;
  164 + nf_ct_put(found_ct);
163 165 }
164 166  
165 167 rcu_read_unlock();
net/netfilter/xt_physdev.c
... ... @@ -20,24 +20,7 @@
20 20 MODULE_ALIAS("ipt_physdev");
21 21 MODULE_ALIAS("ip6t_physdev");
22 22  
23   -static 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 23  
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   -
41 24 static bool
42 25 physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
43 26 {
... ... @@ -85,7 +68,7 @@
85 68 if (!(info->bitmask & XT_PHYSDEV_OP_IN))
86 69 goto match_outdev;
87 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 73 if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN))
91 74 return false;
... ... @@ -95,7 +78,7 @@
95 78 return true;
96 79 outdev = nf_bridge->physoutdev ?
97 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 83 return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT));
101 84 }