diff options
author | David S. Miller <davem@davemloft.net> | 2011-12-28 15:06:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-28 15:06:58 -0500 |
commit | 2c2aba6c561ac425602f4a0be61422224cb87151 (patch) | |
tree | 30b5f2c40b823ca61e2e0930d5e98a89a83222bb /net/core | |
parent | 32288eb4d940b10e40c6d4178fe3a40d1437d2f8 (diff) |
ipv6: Use universal hash for NDISC.
In order to perform a proper universal hash on a vector of integers,
we have to use different universal hashes on each vector element.
Which means we need 4 different hash randoms for ipv6.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/neighbour.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 4af151e1bf5d..e287346e0934 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -322,11 +322,18 @@ out_entries: | |||
322 | goto out; | 322 | goto out; |
323 | } | 323 | } |
324 | 324 | ||
325 | static void neigh_get_hash_rnd(u32 *x) | ||
326 | { | ||
327 | get_random_bytes(x, sizeof(*x)); | ||
328 | *x |= 1; | ||
329 | } | ||
330 | |||
325 | static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) | 331 | static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) |
326 | { | 332 | { |
327 | size_t size = (1 << shift) * sizeof(struct neighbour *); | 333 | size_t size = (1 << shift) * sizeof(struct neighbour *); |
328 | struct neigh_hash_table *ret; | 334 | struct neigh_hash_table *ret; |
329 | struct neighbour __rcu **buckets; | 335 | struct neighbour __rcu **buckets; |
336 | int i; | ||
330 | 337 | ||
331 | ret = kmalloc(sizeof(*ret), GFP_ATOMIC); | 338 | ret = kmalloc(sizeof(*ret), GFP_ATOMIC); |
332 | if (!ret) | 339 | if (!ret) |
@@ -343,8 +350,8 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) | |||
343 | } | 350 | } |
344 | ret->hash_buckets = buckets; | 351 | ret->hash_buckets = buckets; |
345 | ret->hash_shift = shift; | 352 | ret->hash_shift = shift; |
346 | get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); | 353 | for (i = 0; i < NEIGH_NUM_HASH_RND; i++) |
347 | ret->hash_rnd |= 1; | 354 | neigh_get_hash_rnd(&ret->hash_rnd[i]); |
348 | return ret; | 355 | return ret; |
349 | } | 356 | } |
350 | 357 | ||
@@ -1828,7 +1835,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, | |||
1828 | 1835 | ||
1829 | rcu_read_lock_bh(); | 1836 | rcu_read_lock_bh(); |
1830 | nht = rcu_dereference_bh(tbl->nht); | 1837 | nht = rcu_dereference_bh(tbl->nht); |
1831 | ndc.ndtc_hash_rnd = nht->hash_rnd; | 1838 | ndc.ndtc_hash_rnd = nht->hash_rnd[0]; |
1832 | ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); | 1839 | ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); |
1833 | rcu_read_unlock_bh(); | 1840 | rcu_read_unlock_bh(); |
1834 | 1841 | ||