diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2008-03-27 23:46:53 -0400 |
---|---|---|
committer | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2008-03-28 00:43:16 -0400 |
commit | be01d655d9b07c1350b19bf3d80eae0059254b4b (patch) | |
tree | f77499cd889646405d6293108a620d4ccf7a202b /net/core/neighbour.c | |
parent | 0a204500f913974b4ca9b6f509a43e1544239c6d (diff) |
[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/neighbour.c')
-rw-r--r-- | net/core/neighbour.c | 61 |
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: | |||
472 | } | 472 | } |
473 | EXPORT_SYMBOL(neigh_create); | 473 | EXPORT_SYMBOL(neigh_create); |
474 | 474 | ||
475 | struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, | 475 | static u32 pneigh_hash(const void *pkey, int key_len) |
476 | struct net *net, const void *pkey, struct net_device *dev) | ||
477 | { | 476 | { |
478 | struct pneigh_entry *n; | ||
479 | int key_len = tbl->key_len; | ||
480 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | 477 | u32 hash_val = *(u32 *)(pkey + key_len - 4); |
481 | |||
482 | hash_val ^= (hash_val >> 16); | 478 | hash_val ^= (hash_val >> 16); |
483 | hash_val ^= hash_val >> 8; | 479 | hash_val ^= hash_val >> 8; |
484 | hash_val ^= hash_val >> 4; | 480 | hash_val ^= hash_val >> 4; |
485 | hash_val &= PNEIGH_HASHMASK; | 481 | hash_val &= PNEIGH_HASHMASK; |
482 | return hash_val; | ||
483 | } | ||
486 | 484 | ||
487 | for (n = tbl->phash_buckets[hash_val]; n; n = n->next) { | 485 | static struct pneigh_entry *__pneigh_lookup_1(struct pneigh_entry *n, |
486 | struct net *net, | ||
487 | const void *pkey, | ||
488 | int key_len, | ||
489 | struct net_device *dev) | ||
490 | { | ||
491 | while (n) { | ||
488 | if (!memcmp(n->key, pkey, key_len) && | 492 | if (!memcmp(n->key, pkey, key_len) && |
489 | (pneigh_net(n) == net) && | 493 | net_eq(pneigh_net(n), net) && |
490 | (n->dev == dev || !n->dev)) | 494 | (n->dev == dev || !n->dev)) |
491 | break; | 495 | return n; |
496 | n = n->next; | ||
492 | } | 497 | } |
498 | return NULL; | ||
499 | } | ||
493 | 500 | ||
494 | return n; | 501 | struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl, |
502 | struct net *net, const void *pkey, struct net_device *dev) | ||
503 | { | ||
504 | int key_len = tbl->key_len; | ||
505 | u32 hash_val = pneigh_hash(pkey, key_len); | ||
506 | |||
507 | return __pneigh_lookup_1(tbl->phash_buckets[hash_val], | ||
508 | net, pkey, key_len, dev); | ||
495 | } | 509 | } |
496 | EXPORT_SYMBOL_GPL(__pneigh_lookup); | 510 | EXPORT_SYMBOL_GPL(__pneigh_lookup); |
497 | 511 | ||
@@ -501,26 +515,14 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl, | |||
501 | { | 515 | { |
502 | struct pneigh_entry *n; | 516 | struct pneigh_entry *n; |
503 | int key_len = tbl->key_len; | 517 | int key_len = tbl->key_len; |
504 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | 518 | u32 hash_val = pneigh_hash(pkey, key_len); |
505 | |||
506 | hash_val ^= (hash_val >> 16); | ||
507 | hash_val ^= hash_val >> 8; | ||
508 | hash_val ^= hash_val >> 4; | ||
509 | hash_val &= PNEIGH_HASHMASK; | ||
510 | 519 | ||
511 | read_lock_bh(&tbl->lock); | 520 | read_lock_bh(&tbl->lock); |
512 | 521 | n = __pneigh_lookup_1(tbl->phash_buckets[hash_val], | |
513 | for (n = tbl->phash_buckets[hash_val]; n; n = n->next) { | 522 | net, pkey, key_len, dev); |
514 | if (!memcmp(n->key, pkey, key_len) && | ||
515 | net_eq(pneigh_net(n), net) && | ||
516 | (n->dev == dev || !n->dev)) { | ||
517 | read_unlock_bh(&tbl->lock); | ||
518 | goto out; | ||
519 | } | ||
520 | } | ||
521 | read_unlock_bh(&tbl->lock); | 523 | read_unlock_bh(&tbl->lock); |
522 | n = NULL; | 524 | |
523 | if (!creat) | 525 | if (n || !creat) |
524 | goto out; | 526 | goto out; |
525 | 527 | ||
526 | ASSERT_RTNL(); | 528 | ASSERT_RTNL(); |
@@ -561,12 +563,7 @@ int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *pkey, | |||
561 | { | 563 | { |
562 | struct pneigh_entry *n, **np; | 564 | struct pneigh_entry *n, **np; |
563 | int key_len = tbl->key_len; | 565 | int key_len = tbl->key_len; |
564 | u32 hash_val = *(u32 *)(pkey + key_len - 4); | 566 | u32 hash_val = pneigh_hash(pkey, key_len); |
565 | |||
566 | hash_val ^= (hash_val >> 16); | ||
567 | hash_val ^= hash_val >> 8; | ||
568 | hash_val ^= hash_val >> 4; | ||
569 | hash_val &= PNEIGH_HASHMASK; | ||
570 | 567 | ||
571 | write_lock_bh(&tbl->lock); | 568 | write_lock_bh(&tbl->lock); |
572 | for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL; | 569 | for (np = &tbl->phash_buckets[hash_val]; (n = *np) != NULL; |