tap: fix the tun sndbuf value for kernel 4.20 and later 73/27773/2
authorMohsin Kazmi <sykazmi@cisco.com>
Mon, 6 Jul 2020 18:03:41 +0000 (18:03 +0000)
committerMohsin Kazmi <sykazmi@cisco.com>
Wed, 8 Jul 2020 08:44:44 +0000 (08:44 +0000)
Type: fix

From kernel 4.20, xdp support has been added in tun_sendmsg.
If sndbuf == INT_MAX, kernel executes xdp data path
for tun driver which assumes packets are ethernet frames.
This patch is avoiding the xdp data path in kernel by setting
the sendbuf value < INT_MAX.

Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Change-Id: Ia4aa54b177b96d56a2d513d18d26ca01d5b88929
(cherry picked from commit 4834a66b7b3ef73e486c40ea9d8e36cc2e09c473)

src/vnet/devices/tap/tap.c

index 02cd261..90f19af 100644 (file)
@@ -139,7 +139,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
   tap_main_t *tm = &tap_main;
   vnet_sw_interface_t *sw;
   vnet_hw_interface_t *hw;
-  int i, j, num_vhost_queues;
+  int i, num_vhost_queues;
   int old_netns_fd = -1;
   struct ifreq ifr = {.ifr_flags = IFF_NO_PI | IFF_VNET_HDR };
   struct ifreq get_ifr = {.ifr_flags = 0 };
@@ -151,6 +151,7 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
   int tfd = -1, qfd = -1, vfd = -1, nfd = -1;
   char *host_if_name = 0;
   unsigned int offload = 0;
+  int sndbuf = 0;
 
   if (args->id != ~0)
     {
@@ -180,11 +181,22 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
       vif->type = VIRTIO_IF_TYPE_TUN;
       ifr.ifr_flags |= IFF_TUN;
       args->tap_flags &= ~(TAP_FLAG_GSO | TAP_FLAG_CSUM_OFFLOAD);
+
+      /*
+       * From kernel 4.20, xdp support has been added in tun_sendmsg.
+       * If sndbuf == INT_MAX, vhost batches the packet and processes
+       * them using xdp data path for tun driver. It assumes packets
+       * are ethernet frames (It needs to be fixed).
+       * To avoid xdp data path in tun driver, sndbuf value should
+       * be < INT_MAX.
+       */
+      sndbuf = INT_MAX - 1;
     }
   else
     {
       vif->type = VIRTIO_IF_TYPE_TAP;
       ifr.ifr_flags |= IFF_TAP;
+      sndbuf = INT_MAX;
     }
 
   vif->dev_instance = vif - vim->interfaces;
@@ -331,9 +343,9 @@ tap_create_if (vlib_main_t * vm, tap_create_if_args_t * args)
                   vif->tap_fds[i], hdrsz);
       _IOCTL (vif->tap_fds[i], TUNSETVNETHDRSZ, &hdrsz);
 
-      j = INT_MAX;
-      tap_log_dbg (vif, "TUNSETSNDBUF: fd %d sndbuf %d", vif->tap_fds[i], j);
-      _IOCTL (vif->tap_fds[i], TUNSETSNDBUF, &j);
+      tap_log_dbg (vif, "TUNSETSNDBUF: fd %d sndbuf %d", vif->tap_fds[i],
+                  sndbuf);
+      _IOCTL (vif->tap_fds[i], TUNSETSNDBUF, &sndbuf);
 
       tap_log_dbg (vif, "TUNSETOFFLOAD: fd %d offload 0x%lx", vif->tap_fds[i],
                   offload);