|
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