[PATCH v3 net 5/5] vxlan: fix race between flush and incoming learning
From: Stephen Hemminger <stephen@networkplumber.org>
Date: 2013-06-11 00:37:40
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
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v3 - no changes
Should go to -net. Too much of a "theoritical race" for stable.
--- a/drivers/net/vxlan.c 2013-06-10 15:10:43.271357218 -0700
+++ b/drivers/net/vxlan.c 2013-06-10 15:23:19.541044803 -0700@@ -611,7 +611,6 @@ static bool vxlan_snoop(struct net_devic { struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_fdb *f; - int err; f = vxlan_find_mac(vxlan, src_mac); if (likely(f)) {
@@ -632,12 +631,15 @@ static bool vxlan_snoop(struct net_devic } else { /* learned new entry */ spin_lock(&vxlan->hash_lock); - err = vxlan_fdb_create(vxlan, src_mac, src_ip, - NUD_REACHABLE, - NLM_F_EXCL|NLM_F_CREATE, - vxlan->dst_port, - vxlan->default_dst.remote_vni, - 0, NTF_SELF); + + /* close off race between vxlan_flush and incoming packets */ + if (netif_running(dev)) + vxlan_fdb_create(vxlan, src_mac, src_ip, + NUD_REACHABLE, + NLM_F_EXCL|NLM_F_CREATE, + vxlan->dst_port, + vxlan->default_dst.remote_vni, + 0, NTF_SELF); spin_unlock(&vxlan->hash_lock); }