|
54 | 54 | #include <net/netfilter/nf_nat.h> |
55 | 55 | #include <net/netfilter/nf_nat_core.h> |
56 | 56 | #include <net/netfilter/nf_nat_helper.h> |
| 57 | +#include <net/netns/hash.h> |
57 | 58 |
|
58 | 59 | #define NF_CONNTRACK_VERSION "0.5.0" |
59 | 60 |
|
@@ -144,42 +145,41 @@ EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked); |
144 | 145 |
|
145 | 146 | static unsigned int nf_conntrack_hash_rnd __read_mostly; |
146 | 147 |
|
147 | | -static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple) |
| 148 | +static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, |
| 149 | + const struct net *net) |
148 | 150 | { |
149 | 151 | unsigned int n; |
| 152 | + u32 seed; |
150 | 153 |
|
151 | 154 | get_random_once(&nf_conntrack_hash_rnd, sizeof(nf_conntrack_hash_rnd)); |
152 | 155 |
|
153 | 156 | /* The direction must be ignored, so we hash everything up to the |
154 | 157 | * destination ports (which is a multiple of 4) and treat the last |
155 | 158 | * three bytes manually. |
156 | 159 | */ |
| 160 | + seed = nf_conntrack_hash_rnd ^ net_hash_mix(net); |
157 | 161 | n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32); |
158 | | - return jhash2((u32 *)tuple, n, nf_conntrack_hash_rnd ^ |
| 162 | + return jhash2((u32 *)tuple, n, seed ^ |
159 | 163 | (((__force __u16)tuple->dst.u.all << 16) | |
160 | 164 | tuple->dst.protonum)); |
161 | 165 | } |
162 | 166 |
|
163 | | -static u32 __hash_bucket(u32 hash, unsigned int size) |
164 | | -{ |
165 | | - return reciprocal_scale(hash, size); |
166 | | -} |
167 | | - |
168 | 167 | static u32 hash_bucket(u32 hash, const struct net *net) |
169 | 168 | { |
170 | | - return __hash_bucket(hash, net->ct.htable_size); |
| 169 | + return reciprocal_scale(hash, net->ct.htable_size); |
171 | 170 | } |
172 | 171 |
|
173 | | -static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple, |
174 | | - unsigned int size) |
| 172 | +static u32 __hash_conntrack(const struct net *net, |
| 173 | + const struct nf_conntrack_tuple *tuple, |
| 174 | + unsigned int size) |
175 | 175 | { |
176 | | - return __hash_bucket(hash_conntrack_raw(tuple), size); |
| 176 | + return reciprocal_scale(hash_conntrack_raw(tuple, net), size); |
177 | 177 | } |
178 | 178 |
|
179 | | -static inline u_int32_t hash_conntrack(const struct net *net, |
180 | | - const struct nf_conntrack_tuple *tuple) |
| 179 | +static u32 hash_conntrack(const struct net *net, |
| 180 | + const struct nf_conntrack_tuple *tuple) |
181 | 181 | { |
182 | | - return __hash_conntrack(tuple, net->ct.htable_size); |
| 182 | + return __hash_conntrack(net, tuple, net->ct.htable_size); |
183 | 183 | } |
184 | 184 |
|
185 | 185 | bool |
@@ -535,7 +535,7 @@ nf_conntrack_find_get(struct net *net, const struct nf_conntrack_zone *zone, |
535 | 535 | const struct nf_conntrack_tuple *tuple) |
536 | 536 | { |
537 | 537 | return __nf_conntrack_find_get(net, zone, tuple, |
538 | | - hash_conntrack_raw(tuple)); |
| 538 | + hash_conntrack_raw(tuple, net)); |
539 | 539 | } |
540 | 540 | EXPORT_SYMBOL_GPL(nf_conntrack_find_get); |
541 | 541 |
|
@@ -1041,7 +1041,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, |
1041 | 1041 |
|
1042 | 1042 | /* look for tuple match */ |
1043 | 1043 | zone = nf_ct_zone_tmpl(tmpl, skb, &tmp); |
1044 | | - hash = hash_conntrack_raw(&tuple); |
| 1044 | + hash = hash_conntrack_raw(&tuple, net); |
1045 | 1045 | h = __nf_conntrack_find_get(net, zone, &tuple, hash); |
1046 | 1046 | if (!h) { |
1047 | 1047 | h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto, |
@@ -1605,7 +1605,8 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) |
1605 | 1605 | struct nf_conntrack_tuple_hash, hnnode); |
1606 | 1606 | ct = nf_ct_tuplehash_to_ctrack(h); |
1607 | 1607 | hlist_nulls_del_rcu(&h->hnnode); |
1608 | | - bucket = __hash_conntrack(&h->tuple, hashsize); |
| 1608 | + bucket = __hash_conntrack(nf_ct_net(ct), |
| 1609 | + &h->tuple, hashsize); |
1609 | 1610 | hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]); |
1610 | 1611 | } |
1611 | 1612 | } |
|
0 commit comments