|
@@ -474,8 +474,8 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
|
|
|
}
|
|
|
EXPORT_SYMBOL(neigh_lookup_nodev);
|
|
|
|
|
|
-struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey,
|
|
|
- struct net_device *dev)
|
|
|
+struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
|
|
|
+ struct net_device *dev, bool want_ref)
|
|
|
{
|
|
|
u32 hash_val;
|
|
|
int key_len = tbl->key_len;
|
|
@@ -535,14 +535,16 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey,
|
|
|
n1 = rcu_dereference_protected(n1->next,
|
|
|
lockdep_is_held(&tbl->lock))) {
|
|
|
if (dev == n1->dev && !memcmp(n1->primary_key, pkey, key_len)) {
|
|
|
- neigh_hold(n1);
|
|
|
+ if (want_ref)
|
|
|
+ neigh_hold(n1);
|
|
|
rc = n1;
|
|
|
goto out_tbl_unlock;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
n->dead = 0;
|
|
|
- neigh_hold(n);
|
|
|
+ if (want_ref)
|
|
|
+ neigh_hold(n);
|
|
|
rcu_assign_pointer(n->next,
|
|
|
rcu_dereference_protected(nht->hash_buckets[hash_val],
|
|
|
lockdep_is_held(&tbl->lock)));
|
|
@@ -558,7 +560,7 @@ out_neigh_release:
|
|
|
neigh_release(n);
|
|
|
goto out;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(neigh_create);
|
|
|
+EXPORT_SYMBOL(__neigh_create);
|
|
|
|
|
|
static u32 pneigh_hash(const void *pkey, int key_len)
|
|
|
{
|