diff options
author | Florian Westphal <fw@strlen.de> | 2016-05-05 18:51:48 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-05-06 05:50:01 -0400 |
commit | a9a083c3878f28e9d368f6dfb1a79a6f04ad8123 (patch) | |
tree | 8c5180e2114796d711dda849226734768e693c6e | |
parent | 03d7dc5cdfe6fd4e5bd04cfc2be7ae259f956428 (diff) |
netfilter: conntrack: make netns address part of expect hash
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/nf_conntrack_expect.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index da95d740e60b..130f1be8db26 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
25 | #include <linux/export.h> | 25 | #include <linux/export.h> |
26 | #include <net/net_namespace.h> | 26 | #include <net/net_namespace.h> |
27 | #include <net/netns/hash.h> | ||
27 | 28 | ||
28 | #include <net/netfilter/nf_conntrack.h> | 29 | #include <net/netfilter/nf_conntrack.h> |
29 | #include <net/netfilter/nf_conntrack_core.h> | 30 | #include <net/netfilter/nf_conntrack_core.h> |
@@ -73,15 +74,17 @@ static void nf_ct_expectation_timed_out(unsigned long ul_expect) | |||
73 | nf_ct_expect_put(exp); | 74 | nf_ct_expect_put(exp); |
74 | } | 75 | } |
75 | 76 | ||
76 | static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple) | 77 | static unsigned int nf_ct_expect_dst_hash(const struct net *n, const struct nf_conntrack_tuple *tuple) |
77 | { | 78 | { |
78 | unsigned int hash; | 79 | unsigned int hash, seed; |
79 | 80 | ||
80 | get_random_once(&nf_ct_expect_hashrnd, sizeof(nf_ct_expect_hashrnd)); | 81 | get_random_once(&nf_ct_expect_hashrnd, sizeof(nf_ct_expect_hashrnd)); |
81 | 82 | ||
83 | seed = nf_ct_expect_hashrnd ^ net_hash_mix(n); | ||
84 | |||
82 | hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all), | 85 | hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all), |
83 | (((tuple->dst.protonum ^ tuple->src.l3num) << 16) | | 86 | (((tuple->dst.protonum ^ tuple->src.l3num) << 16) | |
84 | (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hashrnd); | 87 | (__force __u16)tuple->dst.u.all) ^ seed); |
85 | 88 | ||
86 | return reciprocal_scale(hash, nf_ct_expect_hsize); | 89 | return reciprocal_scale(hash, nf_ct_expect_hsize); |
87 | } | 90 | } |
@@ -108,7 +111,7 @@ __nf_ct_expect_find(struct net *net, | |||
108 | if (!net->ct.expect_count) | 111 | if (!net->ct.expect_count) |
109 | return NULL; | 112 | return NULL; |
110 | 113 | ||
111 | h = nf_ct_expect_dst_hash(tuple); | 114 | h = nf_ct_expect_dst_hash(net, tuple); |
112 | hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) { | 115 | hlist_for_each_entry_rcu(i, &net->ct.expect_hash[h], hnode) { |
113 | if (nf_ct_exp_equal(tuple, i, zone, net)) | 116 | if (nf_ct_exp_equal(tuple, i, zone, net)) |
114 | return i; | 117 | return i; |
@@ -148,7 +151,7 @@ nf_ct_find_expectation(struct net *net, | |||
148 | if (!net->ct.expect_count) | 151 | if (!net->ct.expect_count) |
149 | return NULL; | 152 | return NULL; |
150 | 153 | ||
151 | h = nf_ct_expect_dst_hash(tuple); | 154 | h = nf_ct_expect_dst_hash(net, tuple); |
152 | hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) { | 155 | hlist_for_each_entry(i, &net->ct.expect_hash[h], hnode) { |
153 | if (!(i->flags & NF_CT_EXPECT_INACTIVE) && | 156 | if (!(i->flags & NF_CT_EXPECT_INACTIVE) && |
154 | nf_ct_exp_equal(tuple, i, zone, net)) { | 157 | nf_ct_exp_equal(tuple, i, zone, net)) { |
@@ -352,7 +355,7 @@ static int nf_ct_expect_insert(struct nf_conntrack_expect *exp) | |||
352 | struct nf_conn_help *master_help = nfct_help(exp->master); | 355 | struct nf_conn_help *master_help = nfct_help(exp->master); |
353 | struct nf_conntrack_helper *helper; | 356 | struct nf_conntrack_helper *helper; |
354 | struct net *net = nf_ct_exp_net(exp); | 357 | struct net *net = nf_ct_exp_net(exp); |
355 | unsigned int h = nf_ct_expect_dst_hash(&exp->tuple); | 358 | unsigned int h = nf_ct_expect_dst_hash(net, &exp->tuple); |
356 | 359 | ||
357 | /* two references : one for hash insert, one for the timer */ | 360 | /* two references : one for hash insert, one for the timer */ |
358 | atomic_add(2, &exp->use); | 361 | atomic_add(2, &exp->use); |
@@ -411,7 +414,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) | |||
411 | ret = -ESHUTDOWN; | 414 | ret = -ESHUTDOWN; |
412 | goto out; | 415 | goto out; |
413 | } | 416 | } |
414 | h = nf_ct_expect_dst_hash(&expect->tuple); | 417 | h = nf_ct_expect_dst_hash(net, &expect->tuple); |
415 | hlist_for_each_entry_safe(i, next, &net->ct.expect_hash[h], hnode) { | 418 | hlist_for_each_entry_safe(i, next, &net->ct.expect_hash[h], hnode) { |
416 | if (expect_matches(i, expect)) { | 419 | if (expect_matches(i, expect)) { |
417 | if (del_timer(&i->timeout)) { | 420 | if (del_timer(&i->timeout)) { |