Commit ac3175fe authored by YOSHIFUJI Hideaki / 吉藤英明's avatar YOSHIFUJI Hideaki / 吉藤英明 Committed by David S. Miller

ndisc: Introduce __ipv6_neigh_lookup_noref().

This function, which looks up neighbour entry for an IPv6 address
without touching refcnt, will be used for patches to remove
dependency on rt->n (neighbour entry in rt6_info).
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent dd0cbf29
...@@ -148,14 +148,13 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _ ...@@ -148,14 +148,13 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _
(p32[3] * hash_rnd[3])); (p32[3] * hash_rnd[3]));
} }
static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey) static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
{ {
struct neigh_hash_table *nht; struct neigh_hash_table *nht;
const u32 *p32 = pkey; const u32 *p32 = pkey;
struct neighbour *n; struct neighbour *n;
u32 hash_val; u32 hash_val;
rcu_read_lock_bh();
nht = rcu_dereference_bh(nd_tbl.nht); nht = rcu_dereference_bh(nd_tbl.nht);
hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift);
for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]);
...@@ -164,12 +163,21 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons ...@@ -164,12 +163,21 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
u32 *n32 = (u32 *) n->primary_key; u32 *n32 = (u32 *) n->primary_key;
if (n->dev == dev && if (n->dev == dev &&
((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) |
(n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) { (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0)
if (!atomic_inc_not_zero(&n->refcnt)) return n;
n = NULL;
break;
}
} }
return NULL;
}
static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey)
{
struct neighbour *n;
rcu_read_lock_bh();
n = __ipv6_neigh_lookup_noref(dev, pkey);
if (n && !atomic_inc_not_zero(&n->refcnt))
n = NULL;
rcu_read_unlock_bh(); rcu_read_unlock_bh();
return n; return n;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment