summary refs log tree commit diff
path: root/net/core
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-03-28 12:46:53 +0900
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-03-28 13:43:16 +0900
commitbe01d655d9b07c1350b19bf3d80eae0059254b4b (patch)
treef77499cd889646405d6293108a620d4ccf7a202b /net/core
parent0a204500f913974b4ca9b6f509a43e1544239c6d (diff)
downloadlinux-be01d655d9b07c1350b19bf3d80eae0059254b4b.tar.gz
[NET] NEIGHBOUR: Extract hash/lookup functions for pneigh entries.
Extract hash function for pneigh entries from pneigh_lookup(),
__pneigh_lookup() and pneigh_delete() as pneigh_hash().
Extract core of pneigh_lookup() and __pneigh_lookup() as
__pneigh_lookup_1().

Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/neighbour.c61
1 files changed, 29 insertions, 32 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d4fae81e5d0d..75075c303c44 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -472,26 +472,40 @@ out_neigh_release:
 }
 EXPORT_SYMBOL(neigh_create);
 
-struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl,
-		struct net *net, const void *pkey, struct net_device *dev)
+static u32 pneigh_hash(const void *pkey, int key_len)
 {
-	struct pneigh_entry *n;
-	int key_len = tbl->key_len;
 	u32 hash_val = *(u32 *)(pkey + key_len - 4);
-
 	hash_val ^= (hash_val >> 16);
 	hash_val ^= hash_val >> 8;
 	hash_val ^= hash_val >> 4;
 	hash_val &= PNEIGH_HASHMASK;
+	return hash_val;
+}
 
-	for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
+static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n,
+					      struct net *net,
+					      const void *pkey,
+					      int key_len,
+					      struct net_device *dev)
+{
+	while (n) {
 		if (!memcmp(n->key, pkey, key_len) &&
-		    (pneigh_net(n) == net) &&
+		    net_eq(pneigh_net(n), net) &&
 		    (n->dev == dev || !n->dev))
-			break;
+			return n;
+		n = n->next;
 	}
+	return NULL;
+}
 
-	return n;
+struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl,
+		struct net *net, const void *pkey, struct net_device *dev)
+{
+	int key_len = tbl->key_len;
+	u32 hash_val = pneigh_hash(pkey, key_len);
+
+	return __pneigh_lookup_1(tbl->phash_buckets[hash_val],
+				 net, pkey, key_len, dev);
 }
 EXPORT_SYMBOL_GPL(__pneigh_lookup);
 
@@ -501,26 +515,14 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
 {
 	struct pneigh_entry *n;
 	int key_len = tbl->key_len;
-	u32 hash_val = *(u32 *)(pkey + key_len - 4);
-
-	hash_val ^= (hash_val >> 16);
-	hash_val ^= hash_val >> 8;
-	hash_val ^= hash_val >> 4;
-	hash_val &= PNEIGH_HASHMASK;
+	u32 hash_val = pneigh_hash(pkey, key_len);
 
 	read_lock_bh(&tbl->lock);
-
-	for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
-		if (!memcmp(n->key, pkey, key_len) &&
-		    net_eq(pneigh_net(n), net) &&
-		    (n->dev == dev || !n->dev)) {
-			read_unlock_bh(&tbl->lock);
-			goto out;
-		}
-	}
+	n = __pneigh_lookup_1(tbl->phash_buckets[hash_val],
+			      net, pkey, key_len, dev);
 	read_unlock_bh(&tbl->lock);
-	n = NULL;
-	if (!creat)
+
+	if (n || !creat)
 		goto out;
 
 	ASSERT_RTNL();
@@ -561,12 +563,7 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey,
 {
 	struct pneigh_entry *n, **np;
 	int key_len = tbl->key_len;
-	u32 hash_val = *(u32 *)(pkey + key_len - 4);
-
-	hash_val ^= (hash_val >> 16);
-	hash_val ^= hash_val >> 8;
-	hash_val ^= hash_val >> 4;
-	hash_val &= PNEIGH_HASHMASK;
+	u32 hash_val = pneigh_hash(pkey, key_len);
 
 	write_lock_bh(&tbl->lock);
 	for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL;