From 5ac8c6f1f34e96890ccd08dc43b0b896a3b7bf43 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Mon, 6 Jul 2020 18:03:41 +0000 Subject: [PATCH] tap: fix the tun sndbuf value for kernel 4.20 and later 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 Change-Id: Ia4aa54b177b96d56a2d513d18d26ca01d5b88929 (cherry picked from commit 4834a66b7b3ef73e486c40ea9d8e36cc2e09c473) --- src/vnet/devices/tap/tap.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/vnet/devices/tap/tap.c b/src/vnet/devices/tap/tap.c index 02cd2610a7d..90f19af8744 100644 --- a/src/vnet/devices/tap/tap.c +++ b/src/vnet/devices/tap/tap.c @@ -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); -- 2.16.6