aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2016-05-05 18:51:48 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2016-05-06 05:50:01 -0400
commita9a083c3878f28e9d368f6dfb1a79a6f04ad8123 (patch)
tree8c5180e2114796d711dda849226734768e693c6e
parent03d7dc5cdfe6fd4e5bd04cfc2be7ae259f956428 (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.c17
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
76static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple) 77static 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)) {