aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/neighbour.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/neighbour.c')
-rw-r--r--net/core/neighbour.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 7bb6a9a1256d..2328acbd16cd 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -358,11 +358,12 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
358{ 358{
359 struct neighbour *n; 359 struct neighbour *n;
360 int key_len = tbl->key_len; 360 int key_len = tbl->key_len;
361 u32 hash_val = tbl->hash(pkey, dev); 361 u32 hash_val;
362 362
363 NEIGH_CACHE_STAT_INC(tbl, lookups); 363 NEIGH_CACHE_STAT_INC(tbl, lookups);
364 364
365 read_lock_bh(&tbl->lock); 365 read_lock_bh(&tbl->lock);
366 hash_val = tbl->hash(pkey, dev);
366 for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { 367 for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
367 if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { 368 if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) {
368 neigh_hold(n); 369 neigh_hold(n);
@@ -379,11 +380,12 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net,
379{ 380{
380 struct neighbour *n; 381 struct neighbour *n;
381 int key_len = tbl->key_len; 382 int key_len = tbl->key_len;
382 u32 hash_val = tbl->hash(pkey, NULL); 383 u32 hash_val;
383 384
384 NEIGH_CACHE_STAT_INC(tbl, lookups); 385 NEIGH_CACHE_STAT_INC(tbl, lookups);
385 386
386 read_lock_bh(&tbl->lock); 387 read_lock_bh(&tbl->lock);
388 hash_val = tbl->hash(pkey, NULL);
387 for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { 389 for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) {
388 if (!memcmp(n->primary_key, pkey, key_len) && 390 if (!memcmp(n->primary_key, pkey, key_len) &&
389 (net == n->dev->nd_net)) { 391 (net == n->dev->nd_net)) {
@@ -507,6 +509,7 @@ struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
507 if (tbl->pconstructor && tbl->pconstructor(n)) { 509 if (tbl->pconstructor && tbl->pconstructor(n)) {
508 if (dev) 510 if (dev)
509 dev_put(dev); 511 dev_put(dev);
512 release_net(net);
510 kfree(n); 513 kfree(n);
511 n = NULL; 514 n = NULL;
512 goto out; 515 goto out;
@@ -834,12 +837,18 @@ static void neigh_timer_handler(unsigned long arg)
834 } 837 }
835 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { 838 if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) {
836 struct sk_buff *skb = skb_peek(&neigh->arp_queue); 839 struct sk_buff *skb = skb_peek(&neigh->arp_queue);
837 840 /* keep skb alive even if arp_queue overflows */
841 if (skb)
842 skb_get(skb);
843 write_unlock(&neigh->lock);
838 neigh->ops->solicit(neigh, skb); 844 neigh->ops->solicit(neigh, skb);
839 atomic_inc(&neigh->probes); 845 atomic_inc(&neigh->probes);
840 } 846 if (skb)
847 kfree_skb(skb);
848 } else {
841out: 849out:
842 write_unlock(&neigh->lock); 850 write_unlock(&neigh->lock);
851 }
843 852
844 if (notify) 853 if (notify)
845 neigh_update_notify(neigh); 854 neigh_update_notify(neigh);