aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorstephen hemminger <stephen@networkplumber.org>2013-06-17 15:09:57 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-17 18:55:46 -0400
commit3bf74b1aecdce719f1445200d5db7dfee2297bba (patch)
tree3c219f5bbe142d0e5c096caf9169b546d7d669e1 /drivers/net
parent8177a9d79c0e942dcac3312f15585d0344d505a5 (diff)
vxlan: fix race between flush and incoming learning
It is possible for a packet to arrive during vxlan_stop(), and have a dynamic entry created. Close this by checking if device is up. CPU1 CPU2 vxlan_stop vxlan_flush hash_lock acquired vxlan_encap_recv vxlan_snoop waiting for hash_lock hash_lock relased vxlan_flush done hash_lock acquired vxlan_fdb_create This is a day-one bug in vxlan goes back to 3.7. Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/vxlan.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 3b1d2ee7156b..577a069a6dde 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -571,7 +571,6 @@ static void vxlan_snoop(struct net_device *dev,
571{ 571{
572 struct vxlan_dev *vxlan = netdev_priv(dev); 572 struct vxlan_dev *vxlan = netdev_priv(dev);
573 struct vxlan_fdb *f; 573 struct vxlan_fdb *f;
574 int err;
575 574
576 f = vxlan_find_mac(vxlan, src_mac); 575 f = vxlan_find_mac(vxlan, src_mac);
577 if (likely(f)) { 576 if (likely(f)) {
@@ -588,12 +587,15 @@ static void vxlan_snoop(struct net_device *dev,
588 } else { 587 } else {
589 /* learned new entry */ 588 /* learned new entry */
590 spin_lock(&vxlan->hash_lock); 589 spin_lock(&vxlan->hash_lock);
591 err = vxlan_fdb_create(vxlan, src_mac, src_ip, 590
592 NUD_REACHABLE, 591 /* close off race between vxlan_flush and incoming packets */
593 NLM_F_EXCL|NLM_F_CREATE, 592 if (netif_running(dev))
594 vxlan->dst_port, 593 vxlan_fdb_create(vxlan, src_mac, src_ip,
595 vxlan->default_dst.remote_vni, 594 NUD_REACHABLE,
596 0, NTF_SELF); 595 NLM_F_EXCL|NLM_F_CREATE,
596 vxlan->dst_port,
597 vxlan->default_dst.remote_vni,
598 0, NTF_SELF);
597 spin_unlock(&vxlan->hash_lock); 599 spin_unlock(&vxlan->hash_lock);
598 } 600 }
599} 601}