All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 net 5/5] vxlan: fix race between flush and incoming learning
       [not found] <20130611002547.346603375@vyatta.com>
@ 2013-06-11  0:37 ` Stephen Hemminger
  2013-06-11  0:37 ` [PATCH v3 net 4/5] vxlan: fix crash from work pending on module removal Stephen Hemminger
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2013-06-11  0:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger

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);
 	}
 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 net 4/5] vxlan: fix crash from work pending on module removal
       [not found] <20130611002547.346603375@vyatta.com>
  2013-06-11  0:37 ` [PATCH v3 net 5/5] vxlan: fix race between flush and incoming learning Stephen Hemminger
@ 2013-06-11  0:37 ` Stephen Hemminger
  2013-06-11  0:37 ` [PATCH v3 net 3/5] vxlan: fix crash " Stephen Hemminger
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2013-06-11  0:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger

Switch to using a per module work queue so that all the socket
deletion callbacks are done when module is removed.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

---
v3 - get rid of destroy_workqueue that snuck in from later patch

Only impacts -net and later; del_work was first introduced 3.10


--- a/drivers/net/vxlan.c	2013-06-10 15:10:11.603785773 -0700
+++ b/drivers/net/vxlan.c	2013-06-10 15:10:43.271357218 -0700
@@ -148,6 +148,7 @@ struct vxlan_dev {
 
 /* salt for hash table */
 static u32 vxlan_salt __read_mostly;
+static struct workqueue_struct *vxlan_wq;
 
 /* Virtual Network hash table head */
 static inline struct hlist_head *vni_head(struct vxlan_sock *vs, u32 id)
@@ -1645,7 +1646,7 @@ static void vxlan_dellink(struct net_dev
 
 	if (--vs->refcnt == 0) {
 		hlist_del_rcu(&vs->hlist);
-		schedule_work(&vs->del_work);
+		queue_work(vxlan_wq, &vs->del_work);
 	}
 }
 
@@ -1764,6 +1765,10 @@ static int __init vxlan_init_module(void
 {
 	int rc;
 
+	vxlan_wq = alloc_workqueue("vxlan", 0, 0);
+	if (!vxlan_wq)
+		return -ENOMEM;
+
 	get_random_bytes(&vxlan_salt, sizeof(vxlan_salt));
 
 	rc = register_pernet_device(&vxlan_net_ops);
@@ -1779,6 +1784,7 @@ static int __init vxlan_init_module(void
 out2:
 	unregister_pernet_device(&vxlan_net_ops);
 out1:
+	destroy_workqueue(vxlan_wq);
 	return rc;
 }
 late_initcall(vxlan_init_module);
@@ -1787,6 +1793,7 @@ static void __exit vxlan_cleanup_module(
 {
 	unregister_pernet_device(&vxlan_net_ops);
 	rtnl_link_unregister(&vxlan_link_ops);
+	destroy_workqueue(vxlan_wq);
 	rcu_barrier();
 }
 module_exit(vxlan_cleanup_module);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 net 3/5] vxlan: fix crash on module removal
       [not found] <20130611002547.346603375@vyatta.com>
  2013-06-11  0:37 ` [PATCH v3 net 5/5] vxlan: fix race between flush and incoming learning Stephen Hemminger
  2013-06-11  0:37 ` [PATCH v3 net 4/5] vxlan: fix crash from work pending on module removal Stephen Hemminger
@ 2013-06-11  0:37 ` Stephen Hemminger
  2013-06-11  0:37 ` [PATCH v3 net 2/5] vxlan: handle skb_clone failure Stephen Hemminger
  2013-06-11  0:37 ` [PATCH v3 net 1/5] vxlan: only migrate dynamic FDB entries Stephen Hemminger
  4 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2013-06-11  0:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger

If vxlan is removed with active vxlan's it would crash because
rtnl_link_unregister (which calls vxlan_dellink), was invoked
before unregister_pernet_device (which calls vxlan_stop).

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v3 - get rid of destroy_workqueue that snuck in from later patch

Should go to stable as well

--- a/drivers/net/vxlan.c	2013-06-10 15:06:15.186973784 -0700
+++ b/drivers/net/vxlan.c	2013-06-10 15:10:11.603785773 -0700
@@ -1785,8 +1785,8 @@ late_initcall(vxlan_init_module);
 
 static void __exit vxlan_cleanup_module(void)
 {
-	rtnl_link_unregister(&vxlan_link_ops);
 	unregister_pernet_device(&vxlan_net_ops);
+	rtnl_link_unregister(&vxlan_link_ops);
 	rcu_barrier();
 }
 module_exit(vxlan_cleanup_module);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 net 2/5] vxlan: handle skb_clone failure
       [not found] <20130611002547.346603375@vyatta.com>
                   ` (2 preceding siblings ...)
  2013-06-11  0:37 ` [PATCH v3 net 3/5] vxlan: fix crash " Stephen Hemminger
@ 2013-06-11  0:37 ` Stephen Hemminger
  2013-06-11  0:37 ` [PATCH v3 net 1/5] vxlan: only migrate dynamic FDB entries Stephen Hemminger
  4 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2013-06-11  0:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger

skb_clone can fail if out of memory. Just skip the fanout.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

---
v3 - no change

Needs be in -net. Not needed for stable.

--- a/drivers/net/vxlan.c	2013-06-10 15:04:59.239993130 -0700
+++ b/drivers/net/vxlan.c	2013-06-10 15:06:15.186973784 -0700
@@ -1198,9 +1198,11 @@ static netdev_tx_t vxlan_xmit(struct sk_
 		struct sk_buff *skb1;
 
 		skb1 = skb_clone(skb, GFP_ATOMIC);
-		rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
-		if (rc == NETDEV_TX_OK)
-			rc = rc1;
+		if (skb1) {
+			rc1 = vxlan_xmit_one(skb1, dev, rdst, did_rsc);
+			if (rc == NETDEV_TX_OK)
+				rc = rc1;
+		}
 	}
 
 	rc1 = vxlan_xmit_one(skb, dev, rdst0, did_rsc);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 net 1/5] vxlan: only migrate dynamic FDB entries
       [not found] <20130611002547.346603375@vyatta.com>
                   ` (3 preceding siblings ...)
  2013-06-11  0:37 ` [PATCH v3 net 2/5] vxlan: handle skb_clone failure Stephen Hemminger
@ 2013-06-11  0:37 ` Stephen Hemminger
  4 siblings, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2013-06-11  0:37 UTC (permalink / raw)
  To: davem; +Cc: netdev, Stephen Hemminger

Only migrate dynamic forwarding table entries, don't modify
static entries. If packet received from incorrect source IP address
assume it is an imposter and drop it.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

---
v3 - fix indentation

Should go to -stable as well.

--- a/drivers/net/vxlan.c	2013-06-10 15:04:56.392031305 -0700
+++ b/drivers/net/vxlan.c	2013-06-10 15:04:59.239993130 -0700
@@ -603,8 +603,9 @@ skip:
 
 /* Watch incoming packets to learn mapping between Ethernet address
  * and Tunnel endpoint.
+ * Return true if packet is bogus and should be droppped.
  */
-static void vxlan_snoop(struct net_device *dev,
+static bool vxlan_snoop(struct net_device *dev,
 			__be32 src_ip, const u8 *src_mac)
 {
 	struct vxlan_dev *vxlan = netdev_priv(dev);
@@ -614,7 +615,11 @@ static void vxlan_snoop(struct net_devic
 	f = vxlan_find_mac(vxlan, src_mac);
 	if (likely(f)) {
 		if (likely(f->remote.remote_ip == src_ip))
-			return;
+			return false;
+
+		/* Don't migrate static entries, drop packets */
+		if (!(f->flags & NTF_SELF))
+			return true;
 
 		if (net_ratelimit())
 			netdev_info(dev,
@@ -634,6 +639,8 @@ static void vxlan_snoop(struct net_devic
 				       0, NTF_SELF);
 		spin_unlock(&vxlan->hash_lock);
 	}
+
+	return false;
 }
 
 
@@ -766,8 +773,9 @@ static int vxlan_udp_encap_recv(struct s
 			       vxlan->dev->dev_addr) == 0)
 		goto drop;
 
-	if (vxlan->flags & VXLAN_F_LEARN)
-		vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source);
+	if ((vxlan->flags & VXLAN_F_LEARN) &&
+	    vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source))
+		goto drop;
 
 	__skb_tunnel_rx(skb, vxlan->dev);
 	skb_reset_network_header(skb);

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-06-11  0:37 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20130611002547.346603375@vyatta.com>
2013-06-11  0:37 ` [PATCH v3 net 5/5] vxlan: fix race between flush and incoming learning Stephen Hemminger
2013-06-11  0:37 ` [PATCH v3 net 4/5] vxlan: fix crash from work pending on module removal Stephen Hemminger
2013-06-11  0:37 ` [PATCH v3 net 3/5] vxlan: fix crash " Stephen Hemminger
2013-06-11  0:37 ` [PATCH v3 net 2/5] vxlan: handle skb_clone failure Stephen Hemminger
2013-06-11  0:37 ` [PATCH v3 net 1/5] vxlan: only migrate dynamic FDB entries Stephen Hemminger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.