devices: add cli support for checksum and gso disable

Type: improvement

Signed-off-by: Mohsin Kazmi <sykazmi@cisco.com>
Change-Id: I33a29cf11998736347eca5016eee112619d847c1
diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c
index a8ab944..fd2f6fc 100644
--- a/src/vnet/devices/af_packet/af_packet.c
+++ b/src/vnet/devices/af_packet/af_packet.c
@@ -191,7 +191,7 @@
 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,
+		       u32 fanout_id, u8 is_fanout,
 		       af_packet_if_flags_t *flags)
 {
   af_packet_main_t *apm = &af_packet_main;
@@ -250,16 +250,21 @@
       goto error;
     }
 
-  int opt2 = 1;
-  if (setsockopt (*fd, SOL_PACKET, PACKET_VNET_HDR, &opt2, sizeof (opt2)) < 0)
+  if (*flags & AF_PACKET_IF_FLAGS_CKSUM_GSO)
     {
-      vlib_log_debug (
-	apm->log_class,
-	"Failed to set packet vnet hdr error handling option: %s (errno %d)",
-	strerror (errno), errno);
+
+      int opt2 = 1;
+      if (setsockopt (*fd, SOL_PACKET, PACKET_VNET_HDR, &opt2, sizeof (opt2)) <
+	  0)
+	{
+	  // remove the flag
+	  *flags &= ~AF_PACKET_IF_FLAGS_CKSUM_GSO;
+	  vlib_log_debug (apm->log_class,
+			  "Failed to set packet vnet hdr error handling "
+			  "option: %s (errno %d)",
+			  strerror (errno), errno);
+	}
     }
-  else
-    *is_cksum_gso_enabled = 1;
 
 #if defined(PACKET_QDISC_BYPASS)
   if (*flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS)
@@ -347,7 +352,6 @@
   u32 rx_frames_per_block, tx_frames_per_block;
   u32 rx_frame_size, tx_frame_size;
   u32 i = 0;
-  u8 is_cksum_gso_enabled = 0;
 
   if (rx_queue)
     {
@@ -391,9 +395,9 @@
 
   if (rx_queue || tx_queue)
     {
-      ret = create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd,
-				   &ring, &is_cksum_gso_enabled,
-				   apif->dev_instance, is_fanout, &arg->flags);
+      ret =
+	create_packet_v3_sock (apif->host_if_index, rx_req, tx_req, &fd, &ring,
+			       apif->dev_instance, is_fanout, &arg->flags);
 
       if (ret != 0)
 	goto error;
@@ -434,9 +438,6 @@
       clib_spinlock_init (&tx_queue->lockp);
     }
 
-  if (queue_id == 0)
-    apif->is_cksum_gso_enabled = is_cksum_gso_enabled;
-
   return 0;
 error:
   vlib_log_err (apm->log_class, "Failed to set queue %u error", queue_id);
@@ -648,6 +649,9 @@
   apif->is_qdisc_bypass_enabled =
     (arg->flags & AF_PACKET_IF_FLAGS_QDISC_BYPASS);
 
+  if (arg->flags & AF_PACKET_IF_FLAGS_CKSUM_GSO)
+    apif->is_cksum_gso_enabled = 1;
+
   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;
diff --git a/src/vnet/devices/af_packet/af_packet.h b/src/vnet/devices/af_packet/af_packet.h
index 2b05125..64daaa1 100644
--- a/src/vnet/devices/af_packet/af_packet.h
+++ b/src/vnet/devices/af_packet/af_packet.h
@@ -35,6 +35,7 @@
 typedef enum
 {
   AF_PACKET_IF_FLAGS_QDISC_BYPASS = 1,
+  AF_PACKET_IF_FLAGS_CKSUM_GSO = 2,
 } af_packet_if_flags_t;
 
 typedef struct
diff --git a/src/vnet/devices/af_packet/af_packet_api.c b/src/vnet/devices/af_packet/af_packet_api.c
index 2a58ba7..d991a2e 100644
--- a/src/vnet/devices/af_packet/af_packet_api.c
+++ b/src/vnet/devices/af_packet/af_packet_api.c
@@ -48,7 +48,7 @@
   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;
+  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO;
   rv = af_packet_create_if (arg);
 
   vec_free (arg->host_if_name);
@@ -80,7 +80,7 @@
   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;
+  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO;
 
   if (mp->num_rx_queues > 1)
     arg->num_rxqs = clib_net_to_host_u16 (mp->num_rx_queues);
diff --git a/src/vnet/devices/af_packet/cli.c b/src/vnet/devices/af_packet/cli.c
index 443a1d5..e730659 100644
--- a/src/vnet/devices/af_packet/cli.c
+++ b/src/vnet/devices/af_packet/cli.c
@@ -59,7 +59,7 @@
   arg->num_txqs = 1;
 
   // Default flags
-  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS;
+  arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO;
 
   /* Get a line of input. */
   if (!unformat_user (input, unformat_line_input, line_input))
@@ -85,6 +85,8 @@
 	;
       else if (unformat (line_input, "qdisc-bypass-disable"))
 	arg->flags &= ~AF_PACKET_IF_FLAGS_QDISC_BYPASS;
+      else if (unformat (line_input, "cksum-gso-disable"))
+	arg->flags &= ~AF_PACKET_IF_FLAGS_CKSUM_GSO;
       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,
@@ -160,7 +162,7 @@
   .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] "
-		"[qdisc-bypass-disable]",
+		"[qdisc-bypass-disable] [cksum-gso-disable]",
   .function = af_packet_create_command_fn,
 };
 
diff --git a/src/vnet/devices/af_packet/device.c b/src/vnet/devices/af_packet/device.c
index 214aa01..822dcdc 100644
--- a/src/vnet/devices/af_packet/device.c
+++ b/src/vnet/devices/af_packet/device.c
@@ -95,6 +95,8 @@
   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);
+  if (apif->is_cksum_gso_enabled)
+    s = format (s, "\n%Ucksum-gso-enabled", format_white_space, indent + 2);
 
   vec_foreach (rx_queue, apif->rx_queues)
     {