aboutsummaryrefslogtreecommitdiffstats
path: root/net
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
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')
-rw-r--r--net/core/neighbour.c20
-rw-r--r--net/decnet/dn_neigh.c6
-rw-r--r--net/ipv4/arp.c9
-rw-r--r--net/ipv6/ndisc.c7
4 files changed, 26 insertions, 16 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();
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index f123c6c6748c..ee7d1cef0027 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -93,12 +93,18 @@ static u32 dn_neigh_hash(const void *pkey,
93 return jhash_2words(*(__u16 *)pkey, 0, hash_rnd[0]); 93 return jhash_2words(*(__u16 *)pkey, 0, hash_rnd[0]);
94} 94}
95 95
96static bool dn_key_eq(const struct neighbour *neigh, const void *pkey)
97{
98 return neigh_key_eq16(neigh, pkey);
99}
100
96struct neigh_table dn_neigh_table = { 101struct neigh_table dn_neigh_table = {
97 .family = PF_DECnet, 102 .family = PF_DECnet,
98 .entry_size = NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)), 103 .entry_size = NEIGH_ENTRY_SIZE(sizeof(struct dn_neigh)),
99 .key_len = sizeof(__le16), 104 .key_len = sizeof(__le16),
100 .protocol = cpu_to_be16(ETH_P_DNA_RT), 105 .protocol = cpu_to_be16(ETH_P_DNA_RT),
101 .hash = dn_neigh_hash, 106 .hash = dn_neigh_hash,
107 .key_eq = dn_key_eq,
102 .constructor = dn_neigh_construct, 108 .constructor = dn_neigh_construct,
103 .id = "dn_neigh_cache", 109 .id = "dn_neigh_cache",
104 .parms ={ 110 .parms ={
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 6b8aad6a0d7d..5f5c674e130a 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -122,6 +122,7 @@
122 * Interface to generic neighbour cache. 122 * Interface to generic neighbour cache.
123 */ 123 */
124static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 *hash_rnd); 124static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 *hash_rnd);
125static bool arp_key_eq(const struct neighbour *n, const void *pkey);
125static int arp_constructor(struct neighbour *neigh); 126static int arp_constructor(struct neighbour *neigh);
126static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb); 127static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb);
127static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb); 128static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb);
@@ -154,6 +155,7 @@ struct neigh_table arp_tbl = {
154 .key_len = 4, 155 .key_len = 4,
155 .protocol = cpu_to_be16(ETH_P_IP), 156 .protocol = cpu_to_be16(ETH_P_IP),
156 .hash = arp_hash, 157 .hash = arp_hash,
158 .key_eq = arp_key_eq,
157 .constructor = arp_constructor, 159 .constructor = arp_constructor,
158 .proxy_redo = parp_redo, 160 .proxy_redo = parp_redo,
159 .id = "arp_cache", 161 .id = "arp_cache",
@@ -209,7 +211,12 @@ static u32 arp_hash(const void *pkey,
209 const struct net_device *dev, 211 const struct net_device *dev,
210 __u32 *hash_rnd) 212 __u32 *hash_rnd)
211{ 213{
212 return arp_hashfn(*(u32 *)pkey, dev, *hash_rnd); 214 return arp_hashfn(pkey, dev, hash_rnd);
215}
216
217static bool arp_key_eq(const struct neighbour *neigh, const void *pkey)
218{
219 return neigh_key_eq32(neigh, pkey);
213} 220}
214 221
215static int arp_constructor(struct neighbour *neigh) 222static int arp_constructor(struct neighbour *neigh)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index e363bbc2420d..247ad7c298f7 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -84,6 +84,7 @@ do { \
84static u32 ndisc_hash(const void *pkey, 84static u32 ndisc_hash(const void *pkey,
85 const struct net_device *dev, 85 const struct net_device *dev,
86 __u32 *hash_rnd); 86 __u32 *hash_rnd);
87static bool ndisc_key_eq(const struct neighbour *neigh, const void *pkey);
87static int ndisc_constructor(struct neighbour *neigh); 88static int ndisc_constructor(struct neighbour *neigh);
88static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); 89static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb);
89static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); 90static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb);
@@ -119,6 +120,7 @@ struct neigh_table nd_tbl = {
119 .key_len = sizeof(struct in6_addr), 120 .key_len = sizeof(struct in6_addr),
120 .protocol = cpu_to_be16(ETH_P_IPV6), 121 .protocol = cpu_to_be16(ETH_P_IPV6),
121 .hash = ndisc_hash, 122 .hash = ndisc_hash,
123 .key_eq = ndisc_key_eq,
122 .constructor = ndisc_constructor, 124 .constructor = ndisc_constructor,
123 .pconstructor = pndisc_constructor, 125 .pconstructor = pndisc_constructor,
124 .pdestructor = pndisc_destructor, 126 .pdestructor = pndisc_destructor,
@@ -295,6 +297,11 @@ static u32 ndisc_hash(const void *pkey,
295 return ndisc_hashfn(pkey, dev, hash_rnd); 297 return ndisc_hashfn(pkey, dev, hash_rnd);
296} 298}
297 299
300static bool ndisc_key_eq(const struct neighbour *n, const void *pkey)
301{
302 return neigh_key_eq128(n, pkey);
303}
304
298static int ndisc_constructor(struct neighbour *neigh) 305static int ndisc_constructor(struct neighbour *neigh)
299{ 306{
300 struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key; 307 struct in6_addr *addr = (struct in6_addr *)&neigh->primary_key;