devices: add cli support to disable qdisc bypass 90/35890/4
authorMohsin Kazmi <sykazmi@cisco.com>
Tue, 5 Apr 2022 12:03:47 +0000 (12:03 +0000)
committerBeno�t Ganne <bganne@cisco.com>
Wed, 6 Apr 2022 11:42:08 +0000 (11:42 +0000)
Type: improvement

Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Change-Id: Ie5f2bdb8fb559680bab863a7c24a49360e005b58

src/vnet/devices/af_packet/af_packet.c
src/vnet/devices/af_packet/af_packet.h
src/vnet/devices/af_packet/af_packet_api.c
src/vnet/devices/af_packet/cli.c
src/vnet/devices/af_packet/device.c

index c941d37..a8ab944 100644 (file)
@@ -191,7 +191,8 @@ af_packet_set_tx_queues (vlib_main_t *vm, af_packet_if_t *apif)
 static int
 create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req,
                       tpacket_req3_t *tx_req, int *fd, af_packet_ring_t *ring,
-                      u8 *is_cksum_gso_enabled, u32 fanout_id, u8 is_fanout)
+                      u8 *is_cksum_gso_enabled, u32 fanout_id, u8 is_fanout,
+                      af_packet_if_flags_t *flags)
 {
   af_packet_main_t *apm = &af_packet_main;
   struct sockaddr_ll sll;
@@ -261,15 +262,18 @@ create_packet_v3_sock (int host_if_index, tpacket_req3_t *rx_req,
     *is_cksum_gso_enabled = 1;
 
 #if defined(PACKET_QDISC_BYPASS)
-  /* Introduced with Linux 3.14 so the ifdef should eventually be removed  */
-  if (setsockopt (*fd, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof (opt)) <
-      0)
-    {
-      vlib_log_debug (apm->log_class,
-                     "Failed to set qdisc bypass error "
-                     "handling option: %s (errno %d)",
-                     strerror (errno), errno);
-    }
+  if (*flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS)
+    /* Introduced with Linux 3.14 so the ifdef should eventually be removed  */
+    if (setsockopt (*fd, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof (opt)) <
+       0)
+      {
+       // remove the flag
+       *flags &= ~AF_PACKET_IF_FLAGS_QDISC_BYPASS;
+       vlib_log_debug (apm->log_class,
+                       "Failed to set qdisc bypass error "
+                       "handling option: %s (errno %d)",
+                       strerror (errno), errno);
+      }
 #endif
 
   if (is_fanout)
@@ -389,7 +393,7 @@ af_packet_queue_init (vlib_main_t *vm, af_packet_if_t *apif,
     {
       ret = create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd,
                                   &ring, &is_cksum_gso_enabled,
-                                  apif->dev_instance, is_fanout);
+                                  apif->dev_instance, is_fanout, &arg->flags);
 
       if (ret != 0)
        goto error;
@@ -641,6 +645,9 @@ af_packet_create_if (af_packet_create_if_arg_t *arg)
   af_packet_set_rx_queues (vm, apif);
   af_packet_set_tx_queues (vm, apif);
 
+  apif->is_qdisc_bypass_enabled =
+    (arg->flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS);
+
   if (apif->is_cksum_gso_enabled)
     caps |= VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_TX_IP4_CKSUM |
            VNET_HW_IF_CAP_TX_TCP_CKSUM | VNET_HW_IF_CAP_TX_UDP_CKSUM;
index 1b24eef..2b05125 100644 (file)
@@ -32,6 +32,11 @@ typedef enum
   AF_PACKET_IF_MODE_IP = 2
 } af_packet_if_mode_t;
 
+typedef enum
+{
+  AF_PACKET_IF_FLAGS_QDISC_BYPASS = 1,
+} af_packet_if_flags_t;
+
 typedef struct
 {
   u32 sw_if_index;
@@ -101,6 +106,7 @@ typedef struct
   u32 dev_instance;
 
   af_packet_ring_t *rings;
+  u8 is_qdisc_bypass_enabled;
 } af_packet_if_t;
 
 typedef struct
@@ -129,6 +135,7 @@ typedef struct
   u8 num_rxqs;
   u8 num_txqs;
   af_packet_if_mode_t mode;
+  af_packet_if_flags_t flags;
 
   /* return */
   u32 sw_if_index;
index 693380d..2a58ba7 100644 (file)
@@ -47,6 +47,8 @@ vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp)
 
   arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr;
   arg->mode = AF_PACKET_IF_MODE_ETHERNET;
+  // Default flags
+  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS;
   rv = af_packet_create_if (arg);
 
   vec_free (arg->host_if_name);
@@ -77,6 +79,8 @@ vl_api_af_packet_create_v2_t_handler (vl_api_af_packet_create_v2_t *mp)
   arg->tx_frames_per_block = clib_net_to_host_u32 (mp->tx_frames_per_block);
   arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr;
   arg->mode = AF_PACKET_IF_MODE_ETHERNET;
+  // Default flags
+  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS;
 
   if (mp->num_rx_queues > 1)
     arg->num_rxqs = clib_net_to_host_u16 (mp->num_rx_queues);
index c90d525..443a1d5 100644 (file)
@@ -58,6 +58,9 @@ af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
   arg->num_rxqs = 1;
   arg->num_txqs = 1;
 
+  // Default flags
+  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS;
+
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
     return 0;
@@ -80,6 +83,8 @@ af_packet_create_command_fn (vlib_main_t * vm, unformat_input_t * input,
        ;
       else if (unformat (line_input, "num-tx-queues %u", &arg->num_txqs))
        ;
+      else if (unformat (line_input, "qdisc-bypass-disable"))
+       arg->flags &= ~AF_PACKET_IF_FLAGS_QDISC_BYPASS;
       else if (unformat (line_input, "mode ip"))
        arg->mode = AF_PACKET_IF_MODE_IP;
       else if (unformat (line_input, "hw-addr %U", unformat_ethernet_address,
@@ -154,7 +159,8 @@ done:
 VLIB_CLI_COMMAND (af_packet_create_command, static) = {
   .path = "create host-interface",
   .short_help = "create host-interface name <ifname> [num-rx-queues <n>] "
-               "[num-tx-queues <n>] [hw-addr <mac-addr>] [mode ip]",
+               "[num-tx-queues <n>] [hw-addr <mac-addr>] [mode ip] "
+               "[qdisc-bypass-disable]",
   .function = af_packet_create_command_fn,
 };
 
index 013d9f7..214aa01 100644 (file)
@@ -92,6 +92,9 @@ format_af_packet_device (u8 * s, va_list * args)
   af_packet_queue_t *tx_queue = 0;
 
   s = format (s, "Linux PACKET socket interface");
+  s = format (s, "\n%UFEATURES:", format_white_space, indent);
+  if (apif->is_qdisc_bypass_enabled)
+    s = format (s, "\n%Uqdisc-bpass-enabled", format_white_space, indent + 2);
 
   vec_foreach (rx_queue, apif->rx_queues)
     {