aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-02-17 21:39:54 -0500
committerDavid S. Miller <davem@davemloft.net>2008-02-17 21:39:54 -0500
commit9ff566074689e3aed1488780b97714ec43ba361d (patch)
tree10bfc8ab214696ba08e5e25018d24c3de8018801
parent93b2d4a208eeb19bff95e98c34503ce4b03cd0f9 (diff)
Revert "[NDISC]: Fix race in generic address resolution"
This reverts commit 69cc64d8d92bf852f933e90c888dfff083bd4fc9. It causes recursive locking in IPV6 because unlike other neighbour layer clients, it even needs neighbour cache entries to send neighbour soliciation messages :-( We'll have to find another way to fix this race. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/neighbour.c12
-rw-r--r--net/ipv4/arp.c3
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 {
841out: 846out:
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
382static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip) 385static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)