From 04a6f4417bfd17c3860e8fb37387cb78265ffe44 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 3 Dec 2011 18:29:30 -0500 Subject: ipv6: Kill ndisc_get_neigh() inline helper. It's only used in net/ipv6/route.c and the NULL device check is superfluous for all of the existing call sites. Just expand the __ndisc_lookup_errno() call at each location. Signed-off-by: David S. Miller --- include/net/ndisc.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/net/ndisc.h') diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 62beeb97c4b1..c977c377c015 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -145,13 +145,4 @@ int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, extern void inet6_ifinfo_notify(int event, struct inet6_dev *idev); -static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, const struct in6_addr *addr) -{ - - if (dev) - return __neigh_lookup_errno(&nd_tbl, addr, dev); - - return ERR_PTR(-ENODEV); -} - #endif -- cgit v1.2.3 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 --- include/net/ndisc.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/net/ndisc.h') diff --git a/include/net/ndisc.h b/include/net/ndisc.h index c977c377c015..e9c30023b784 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -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); -- cgit v1.2.3 From f83c7790dc0025fffbd8684f3803a7571f624baa Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 28 Dec 2011 15:41:23 -0500 Subject: ipv6: Create fast inline ipv6 neigh lookup just like ipv4. Also, create and use an rt6_bind_neighbour() in net/ipv6/route.c to consolidate some common logic. Signed-off-by: David S. Miller --- include/net/ndisc.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'include/net/ndisc.h') diff --git a/include/net/ndisc.h b/include/net/ndisc.h index e9c30023b784..e3133c23980e 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -89,6 +89,33 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _ (p32[3] * hash_rnd[3])); } +static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const void *pkey) +{ + struct neigh_hash_table *nht; + const u32 *p32 = pkey; + struct neighbour *n; + u32 hash_val; + + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); + for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); + n != NULL; + n = rcu_dereference_bh(n->next)) { + u32 *n32 = (u32 *) n->primary_key; + if (n->dev == dev && + ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | + (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) { + if (!atomic_inc_not_zero(&n->refcnt)) + n = NULL; + break; + } + } + rcu_read_unlock_bh(); + + return n; +} + extern int ndisc_init(void); extern void ndisc_cleanup(void); -- cgit v1.2.3