aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2015-03-03 18:10:44 -0500
committerDavid S. Miller <davem@davemloft.net>2015-03-04 00:23:23 -0500
commit60395a20ffd74166ea373ea91418d6f98fa7fdfb (patch)
treec4ed2b51ec4f179a48018d86660e6f2bb5b8bd81 /net/core
parent2f56f6be47dbc6883e28107edfe2f9f98f4d5a24 (diff)
neigh: Factor out ___neigh_lookup_noref
While looking at the mpls code I found myself writing yet another version of neigh_lookup_noref. We currently have __ipv4_lookup_noref and __ipv6_lookup_noref. So to make my work a little easier and to make it a smidge easier to verify/maintain the mpls code in the future I stopped and wrote ___neigh_lookup_noref. Then I rewote __ipv4_lookup_noref and __ipv6_lookup_noref in terms of this new function. I tested my new version by verifying that the same code is generated in ip_finish_output2 and ip6_finish_output2 where these functions are inlined. To get to ___neigh_lookup_noref I added a new neighbour cache table function key_eq. So that the static size of the key would be available. I also added __neigh_lookup_noref for people who want to to lookup a neighbour table entry quickly but don't know which neibhgour table they are going to look up. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/neighbour.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0f48ea3affed..fe3c6eac5805 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -397,25 +397,15 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
397 struct net_device *dev) 397 struct net_device *dev)
398{ 398{
399 struct neighbour *n; 399 struct neighbour *n;
400 int key_len = tbl->key_len;
401 u32 hash_val;
402 struct neigh_hash_table *nht;
403 400
404 NEIGH_CACHE_STAT_INC(tbl, lookups); 401 NEIGH_CACHE_STAT_INC(tbl, lookups);
405 402
406 rcu_read_lock_bh(); 403 rcu_read_lock_bh();
407 nht = rcu_dereference_bh(tbl->nht); 404 n = __neigh_lookup_noref(tbl, pkey, dev);
408 hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); 405 if (n) {
409 406 if (!atomic_inc_not_zero(&n->refcnt))
410 for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); 407 n = NULL;
411 n != NULL; 408 NEIGH_CACHE_STAT_INC(tbl, hits);
412 n = rcu_dereference_bh(n->next)) {
413 if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
414 if (!atomic_inc_not_zero(&n->refcnt))
415 n = NULL;
416 NEIGH_CACHE_STAT_INC(tbl, hits);
417 break;
418 }
419 } 409 }
420 410
421 rcu_read_unlock_bh(); 411 rcu_read_unlock_bh();