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>
This commit is contained in:
parent
8177a9d79c
commit
3bf74b1aec
|
@ -571,7 +571,6 @@ static void vxlan_snoop(struct net_device *dev,
|
|||
{
|
||||
struct vxlan_dev *vxlan = netdev_priv(dev);
|
||||
struct vxlan_fdb *f;
|
||||
int err;
|
||||
|
||||
f = vxlan_find_mac(vxlan, src_mac);
|
||||
if (likely(f)) {
|
||||
|
@ -588,12 +587,15 @@ static void vxlan_snoop(struct net_device *dev,
|
|||
} 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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue