From 2c2aba6c561ac425602f4a0be61422224cb87151 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Dec 2011 15:06:58 -0500 Subject: 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 --- net/core/neighbour.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'net/core') 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: goto out; } +static void neigh_get_hash_rnd(u32 *x) +{ + get_random_bytes(x, sizeof(*x)); + *x |= 1; +} + static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) { size_t size = (1 << shift) * sizeof(struct neighbour *); struct neigh_hash_table *ret; struct neighbour __rcu **buckets; + int i; ret = kmalloc(sizeof(*ret), GFP_ATOMIC); if (!ret) @@ -343,8 +350,8 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) } ret->hash_buckets = buckets; ret->hash_shift = shift; - get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); - ret->hash_rnd |= 1; + for (i = 0; i < NEIGH_NUM_HASH_RND; i++) + neigh_get_hash_rnd(&ret->hash_rnd[i]); return ret; } @@ -1828,7 +1835,7 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, rcu_read_lock_bh(); nht = rcu_dereference_bh(tbl->nht); - ndc.ndtc_hash_rnd = nht->hash_rnd; + ndc.ndtc_hash_rnd = nht->hash_rnd[0]; ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); rcu_read_unlock_bh(); -- cgit v1.2.3