diff options
-rw-r--r-- | net/core/neighbour.c | 12 | ||||
-rw-r--r-- | net/ipv4/arp.c | 3 |
2 files changed, 12 insertions, 3 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 7bb6a9a1256d..a16cf1ec5e5e 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -834,12 +834,18 @@ static void neigh_timer_handler(unsigned long arg) | |||
834 | } | 834 | } |
835 | if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { | 835 | if (neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) { |
836 | struct sk_buff *skb = skb_peek(&neigh->arp_queue); | 836 | struct sk_buff *skb = skb_peek(&neigh->arp_queue); |
837 | 837 | /* keep skb alive even if arp_queue overflows */ | |
838 | if (skb) | ||
839 | skb_get(skb); | ||
840 | write_unlock(&neigh->lock); | ||
838 | neigh->ops->solicit(neigh, skb); | 841 | neigh->ops->solicit(neigh, skb); |
839 | atomic_inc(&neigh->probes); | 842 | atomic_inc(&neigh->probes); |
840 | } | 843 | if (skb) |
844 | kfree_skb(skb); | ||
845 | } else { | ||
841 | out: | 846 | out: |
842 | write_unlock(&neigh->lock); | 847 | write_unlock(&neigh->lock); |
848 | } | ||
843 | 849 | ||
844 | if (notify) | 850 | if (notify) |
845 | neigh_update_notify(neigh); | 851 | neigh_update_notify(neigh); |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index c663fa5339ee..8e17f65f4002 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -368,6 +368,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
368 | if (!(neigh->nud_state&NUD_VALID)) | 368 | if (!(neigh->nud_state&NUD_VALID)) |
369 | printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); | 369 | printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); |
370 | dst_ha = neigh->ha; | 370 | dst_ha = neigh->ha; |
371 | read_lock_bh(&neigh->lock); | ||
371 | } else if ((probes -= neigh->parms->app_probes) < 0) { | 372 | } else if ((probes -= neigh->parms->app_probes) < 0) { |
372 | #ifdef CONFIG_ARPD | 373 | #ifdef CONFIG_ARPD |
373 | neigh_app_ns(neigh); | 374 | neigh_app_ns(neigh); |
@@ -377,6 +378,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) | |||
377 | 378 | ||
378 | arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, | 379 | arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, |
379 | dst_ha, dev->dev_addr, NULL); | 380 | dst_ha, dev->dev_addr, NULL); |
381 | if (dst_ha) | ||
382 | read_unlock_bh(&neigh->lock); | ||
380 | } | 383 | } |
381 | 384 | ||
382 | static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) | 385 | static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) |