system-tests: Disable offloads in userspace tests.
authorDaniele Di Proietto <diproiettod@vmware.com>
Fri, 15 Apr 2016 20:17:50 +0000 (13:17 -0700)
committerDaniele Di Proietto <diproiettod@vmware.com>
Wed, 27 Apr 2016 06:23:22 +0000 (23:23 -0700)
The system userspace testsuite uses the userspace datapath with
netdev-linux devices, connected to veth pairs with the AF_PACKET socket:

             (veth pair)     (AF_PACKET)
TCP stack -> p0 ---> ovs-p0  -------------> netdev-linux (userspace OVS)

Unfortunately this configuration has some problems with offloads: a
packet generated by the TCP stack maybe sent to p0 without being
checksummed or segmented. The AF_PACKET socket, by default, ignores the
offloads and just transmits the data of the packets to userspace, but:

1. The packet may need GSO, so the data will be too big to be received
   by the userspace datapath
2. The packet might have incomplete checksums, so it will likely be
   discarded by the receiver.

Problem 1 causes TCP connections to see a congestion window smaller than
the MTU, which hurts performance but doesn't prevent communication.

Problem 2 was hidden in the testsuite by a Linux kernel bug, fixed by
commit ce8c839b74e3("veth: don’t modify ip_summed; doing so treats
packets with bad checksums as good").  In the kernels that include the
fix, the userspace datapath is able to process pings, but not tcp or udp
data.

Unfortunately I couldn't find a way to ask the AF_PACKET to perform
offloads in kernel.  A possible fix would be to use the PACKET_VNET_HDR
sockopt and perform the offloads in userspace.

Until a proper fix is worked out for netdev-linux, this commit disables
offloads on the non-OVS side of the veth pair, as a workaround.

Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com>
Acked-by: Joe Stringer <joe@ovn.org>
Acked-by: Flavio Leitner <fbl@sysclose.org>
tests/system-common-macros.at
tests/system-kmod-macros.at
tests/system-userspace-macros.at

index 2116f1e..2c8e2a9 100644 (file)
@@ -67,6 +67,7 @@ m4_define([ADD_INT],
 #
 m4_define([ADD_VETH],
     [ AT_CHECK([ip link add $1 type veth peer name ovs-$1 || return 77])
+      CONFIGURE_VETH_OFFLOADS([$1])
       AT_CHECK([ip link set $1 netns $2])
       AT_CHECK([ip link set dev ovs-$1 up])
       AT_CHECK([ovs-vsctl add-port $3 ovs-$1])
index 20ee7bf..8e60929 100644 (file)
@@ -44,6 +44,13 @@ m4_define([OVS_TRAFFIC_VSWITCHD_STOP],
    AT_CHECK([:; $2])
   ])
 
+# CONFIGURE_VETH_OFFLOADS([VETH])
+#
+# The kernel datapath has no problem with offloads and veths. Nothing
+# to do here.
+m4_define([CONFIGURE_VETH_OFFLOADS],
+)
+
 # CHECK_CONNTRACK()
 #
 # Perform requirements checks for running conntrack tests, and flush the
index 4fed777..c09a4aa 100644 (file)
@@ -40,6 +40,24 @@ m4_define([OVS_TRAFFIC_VSWITCHD_STOP],
    AT_CHECK([:; $2])
   ])
 
+# CONFIGURE_VETH_OFFLOADS([VETH])
+#
+# Disable TX offloads for veths.  The userspace datapath uses the AF_PACKET
+# socket to receive packets for veths.  Unfortunately, the AF_PACKET socket
+# doesn't play well with offloads:
+# 1. GSO packets are received without segmentation and therefore discarded.
+# 2. Packets with offloaded partial checksum are received with the wrong
+#    checksum, therefore discarded by the receiver.
+#
+# By disabling tx offloads in the non-OVS side of the veth peer we make sure
+# that the AF_PACKET socket will not receive bad packets.
+#
+# This is a workaround, and should be removed when offloads are properly
+# supported in netdev-linux.
+m4_define([CONFIGURE_VETH_OFFLOADS],
+    [ethtool -K $1 tx off]
+)
+
 # CHECK_CONNTRACK()
 #
 # Perform requirements checks for running conntrack tests, and flush the