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>
This commit is contained in:
David S. Miller
2011-12-28 15:06:58 -05:00
parent 32288eb4d9
commit 2c2aba6c56
7 changed files with 32 additions and 21 deletions

View File

@@ -23,7 +23,7 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct neigh_table *tbl, str
rcu_read_lock_bh();
nht = rcu_dereference_bh(tbl->nht);
hash_val = arp_hashfn(key, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
hash_val = arp_hashfn(key, dev, nht->hash_rnd[0]) >> (32 - nht->hash_shift);
for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
n != NULL;
n = rcu_dereference_bh(n->next)) {

View File

@@ -79,6 +79,15 @@ struct nd_opt_hdr {
__u8 nd_opt_len;
} __packed;
static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd)
{
const u32 *p32 = pkey;
return (((p32[0] ^ dev->ifindex) * hash_rnd[0]) +
(p32[1] * hash_rnd[1]) +
(p32[2] * hash_rnd[2]) +
(p32[3] * hash_rnd[3]));
}
extern int ndisc_init(void);

View File

@@ -139,10 +139,12 @@ struct pneigh_entry {
* neighbour table manipulation
*/
#define NEIGH_NUM_HASH_RND 4
struct neigh_hash_table {
struct neighbour __rcu **hash_buckets;
unsigned int hash_shift;
__u32 hash_rnd;
__u32 hash_rnd[NEIGH_NUM_HASH_RND];
struct rcu_head rcu;
};
@@ -154,7 +156,7 @@ struct neigh_table {
int key_len;
__u32 (*hash)(const void *pkey,
const struct net_device *dev,
__u32 hash_rnd);
__u32 *hash_rnd);
int (*constructor)(struct neighbour *);
int (*pconstructor)(struct pneigh_entry *);
void (*pdestructor)(struct pneigh_entry *);