[ovs-dev] [PATCH] datapath: Move LRO check from transmit to receive.

Jesse Gross jesse at nicira.com
Mon Jan 21 13:21:19 UTC 2013


Commit 24b019f808211a95078efd916064af0975ca5733 (datapath: Disable
LRO from userspace instead of the kernel.) accidentally moved the
check for LRO packets from the receive path to transmit.  Since
this check is supposed to protect OVS (and other parts of the system)
from packets that it cannot handle it is obviously not useful on
egress.  Therefore, this commit moves it back to the receive side.

The primary problem that this caused is upcalls to userspace tried
to segment the packet even though no segmentation information is
available.  This would later cause NULL pointer dereferences when
skb_gso_segment() did nothing.

Bug #14772

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/vport-netdev.c |   23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c
index 78f1493..fb64fe0 100644
--- a/datapath/vport-netdev.c
+++ b/datapath/vport-netdev.c
@@ -225,10 +225,11 @@ int ovs_netdev_get_ifindex(const struct vport *vport)
 /* Must be called with rcu_read_lock. */
 static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 {
-	if (unlikely(!vport)) {
-		kfree_skb(skb);
-		return;
-	}
+	if (unlikely(!vport))
+		goto error;
+
+	if (unlikely(skb_warn_if_lro(skb)))
+		goto error;
 
 	/* Make our own copy of the packet.  Otherwise we will mangle the
 	 * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
@@ -240,13 +241,16 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 
 	skb_push(skb, ETH_HLEN);
 
-	if (unlikely(compute_ip_summed(skb, false))) {
-		kfree_skb(skb);
-		return;
-	}
+	if (unlikely(compute_ip_summed(skb, false)))
+		goto error;
+
 	vlan_copy_skb_tci(skb);
 
 	ovs_vport_receive(vport, skb);
+	return;
+
+error:
+	kfree_skb(skb);
 }
 
 static unsigned int packet_length(const struct sk_buff *skb)
@@ -285,9 +289,6 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
 		goto error;
 	}
 
-	if (unlikely(skb_warn_if_lro(skb)))
-		goto error;
-
 	skb->dev = netdev_vport->dev;
 	forward_ip_summed(skb, true);
 
-- 
1.7.9.5




More information about the dev mailing list