aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-28 15:06:58 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-28 15:06:58 -0500
commit2c2aba6c561ac425602f4a0be61422224cb87151 (patch)
tree30b5f2c40b823ca61e2e0930d5e98a89a83222bb /net/core
parent32288eb4d940b10e40c6d4178fe3a40d1437d2f8 (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.c13
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
325static void neigh_get_hash_rnd(u32 *x)
326{
327 get_random_bytes(x, sizeof(*x));
328 *x |= 1;
329}
330
325static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) 331static 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