diff options
author | David S. Miller <davem@davemloft.net> | 2011-12-28 15:41:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-12-28 15:41:23 -0500 |
commit | f83c7790dc0025fffbd8684f3803a7571f624baa (patch) | |
tree | 9e745f6b44b1947033a143423560af6a3157fce7 /include | |
parent | 2c2aba6c561ac425602f4a0be61422224cb87151 (diff) |
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 <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/ndisc.h | 27 |
1 files changed, 27 insertions, 0 deletions
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, _ | |||
89 | (p32[3] * hash_rnd[3])); | 89 | (p32[3] * hash_rnd[3])); |
90 | } | 90 | } |
91 | 91 | ||
92 | static inline struct neighbour *__ipv6_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const void *pkey) | ||
93 | { | ||
94 | struct neigh_hash_table *nht; | ||
95 | const u32 *p32 = pkey; | ||
96 | struct neighbour *n; | ||
97 | u32 hash_val; | ||
98 | |||
99 | rcu_read_lock_bh(); | ||
100 | nht = rcu_dereference_bh(tbl->nht); | ||
101 | hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); | ||
102 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | ||
103 | n != NULL; | ||
104 | n = rcu_dereference_bh(n->next)) { | ||
105 | u32 *n32 = (u32 *) n->primary_key; | ||
106 | if (n->dev == dev && | ||
107 | ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | | ||
108 | (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) { | ||
109 | if (!atomic_inc_not_zero(&n->refcnt)) | ||
110 | n = NULL; | ||
111 | break; | ||
112 | } | ||
113 | } | ||
114 | rcu_read_unlock_bh(); | ||
115 | |||
116 | return n; | ||
117 | } | ||
118 | |||
92 | extern int ndisc_init(void); | 119 | extern int ndisc_init(void); |
93 | 120 | ||
94 | extern void ndisc_cleanup(void); | 121 | extern void ndisc_cleanup(void); |