dpdk: add support for outer udp and ipv4 checksums 71/32771/5
authorMohsin Kazmi <sykazmi@cisco.com>
Thu, 17 Jun 2021 17:20:02 +0000 (17:20 +0000)
committerDamjan Marion <dmarion@me.com>
Thu, 16 Sep 2021 10:42:59 +0000 (10:42 +0000)
Type: improvement

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

extras/vpp_config/data/startup.conf.template
src/plugins/dpdk/device/device.c
src/plugins/dpdk/device/dpdk.h
src/plugins/dpdk/device/init.c

index 13d86b6..ccd2cf3 100644 (file)
@@ -150,6 +150,10 @@ dpdk {{
        ## Enable UDP / TCP TX checksum offload
        ## This is the reversed option of 'no-tx-checksum-offload'
        # enable-tcp-udp-checksum
+
+        ## Enable outer UDP / IPv4 checksum offload
+        ## This is only enabled when tunnels offload are available
+        # enable-outer-checksum-offload
 }}
 
 ## node variant defaults
index 7c083e1..095036f 100644 (file)
@@ -221,7 +221,8 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
 {
   int is_ip4 = b->flags & VNET_BUFFER_F_IS_IP4;
   u32 tso = b->flags & VNET_BUFFER_F_GSO, max_pkt_len;
-  u32 ip_cksum, tcp_cksum, udp_cksum;
+  u32 ip_cksum, tcp_cksum, udp_cksum, outer_hdr_len = 0;
+  u32 outer_ip_cksum, vxlan_tunnel;
   u64 ol_flags;
   vnet_buffer_oflags_t oflags = 0;
 
@@ -233,23 +234,46 @@ dpdk_buffer_tx_offload (dpdk_device_t * xd, vlib_buffer_t * b,
   ip_cksum = oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM;
   tcp_cksum = oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM;
   udp_cksum = oflags & VNET_BUFFER_OFFLOAD_F_UDP_CKSUM;
+  outer_ip_cksum = oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM;
+  vxlan_tunnel = oflags & VNET_BUFFER_OFFLOAD_F_TNL_VXLAN;
 
-  mb->l2_len = vnet_buffer (b)->l3_hdr_offset - b->current_data;
-  mb->l3_len = vnet_buffer (b)->l4_hdr_offset -
-    vnet_buffer (b)->l3_hdr_offset;
-  mb->outer_l3_len = 0;
-  mb->outer_l2_len = 0;
   ol_flags = is_ip4 ? PKT_TX_IPV4 : PKT_TX_IPV6;
   ol_flags |= ip_cksum ? PKT_TX_IP_CKSUM : 0;
   ol_flags |= tcp_cksum ? PKT_TX_TCP_CKSUM : 0;
   ol_flags |= udp_cksum ? PKT_TX_UDP_CKSUM : 0;
 
+  if (vxlan_tunnel)
+    {
+      ol_flags |= outer_ip_cksum ? PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IP_CKSUM :
+                                  PKT_TX_OUTER_IPV6;
+      ol_flags |= PKT_TX_TUNNEL_VXLAN;
+      mb->l2_len =
+       vnet_buffer (b)->l3_hdr_offset - vnet_buffer2 (b)->outer_l4_hdr_offset;
+      mb->l3_len =
+       vnet_buffer (b)->l4_hdr_offset - vnet_buffer (b)->l3_hdr_offset;
+      mb->outer_l2_len =
+       vnet_buffer2 (b)->outer_l3_hdr_offset - b->current_data;
+      mb->outer_l3_len = vnet_buffer2 (b)->outer_l4_hdr_offset -
+                        vnet_buffer2 (b)->outer_l3_hdr_offset;
+      outer_hdr_len = mb->outer_l2_len + mb->outer_l3_len;
+    }
+  else
+    {
+      mb->l2_len =
+       vnet_buffer (b)->l3_hdr_offset - vnet_buffer (b)->l2_hdr_offset;
+      mb->l3_len =
+       vnet_buffer (b)->l4_hdr_offset - vnet_buffer (b)->l3_hdr_offset;
+      mb->outer_l2_len = 0;
+      mb->outer_l3_len = 0;
+    }
+
   if (tso)
     {
       mb->l4_len = vnet_buffer2 (b)->gso_l4_hdr_sz;
       mb->tso_segsz = vnet_buffer2 (b)->gso_size;
       /* ensure packet is large enough to require tso */
-      max_pkt_len = mb->l2_len + mb->l3_len + mb->l4_len + mb->tso_segsz;
+      max_pkt_len =
+       outer_hdr_len + mb->l2_len + mb->l3_len + mb->l4_len + mb->tso_segsz;
       if (mb->tso_segsz != 0 && mb->pkt_len > max_pkt_len)
        ol_flags |= (tcp_cksum ? PKT_TX_TCP_SEG : PKT_TX_UDP_SEG);
     }
index dd43137..51f80a8 100644 (file)
@@ -304,6 +304,7 @@ typedef struct
   u8 no_multi_seg;
   u8 enable_lro;
   u8 enable_tcp_udp_checksum;
+  u8 enable_outer_checksum_offload;
   u8 no_tx_checksum_offload;
   u8 enable_telemetry;
   u16 max_simd_bitwidth;
index f7c1cc1..18124c3 100644 (file)
@@ -370,6 +370,18 @@ dpdk_lib_init (dpdk_main_t * dm)
            xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_UDP_CKSUM;
          if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
            xd->port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_TCP_CKSUM;
+         if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)
+           xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_IPV4_CKSUM;
+
+         if (dm->conf->enable_outer_checksum_offload)
+           {
+             if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)
+               xd->port_conf.txmode.offloads |=
+                 DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM;
+             if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_UDP_CKSUM)
+               xd->port_conf.txmode.offloads |=
+                 DEV_TX_OFFLOAD_OUTER_UDP_CKSUM;
+           }
        }
 
       if (dm->conf->enable_lro)
@@ -480,9 +492,8 @@ dpdk_lib_init (dpdk_main_t * dm)
                {
                  xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_CKSUM;
                  xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_UDP_CKSUM;
-                 xd->flags |=
-                   DPDK_DEVICE_FLAG_TX_OFFLOAD |
-                   DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
+                 xd->flags |= DPDK_DEVICE_FLAG_TX_OFFLOAD |
+                              DPDK_DEVICE_FLAG_INTEL_PHDR_CKSUM;
                }
 
              xd->port_conf.intr_conf.rxq = 1;
@@ -816,6 +827,11 @@ dpdk_lib_init (dpdk_main_t * dm)
            hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_IP4_CKSUM |
                        VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM |
                        VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM;
+           if (dm->conf->enable_outer_checksum_offload)
+             {
+               hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TX_IP4_OUTER_CKSUM |
+                           VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_OUTER_CKSUM;
+             }
          }
       if (devconf->tso == DPDK_DEVICE_TSO_ON && hi != NULL)
        {
@@ -823,10 +839,16 @@ dpdk_lib_init (dpdk_main_t * dm)
          if ((dm->conf->enable_tcp_udp_checksum) &&
              (hi->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TX_CKSUM))
            {
-             hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
-                         VNET_HW_INTERFACE_CAP_SUPPORTS_UDP_GSO;
-             xd->port_conf.txmode.offloads |=
-               DEV_TX_OFFLOAD_TCP_TSO | DEV_TX_OFFLOAD_UDP_TSO;
+             hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO;
+             xd->port_conf.txmode.offloads |= DEV_TX_OFFLOAD_TCP_TSO;
+
+             if (dm->conf->enable_outer_checksum_offload &&
+                 (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO))
+               {
+                 xd->port_conf.txmode.offloads |=
+                   DEV_TX_OFFLOAD_VXLAN_TNL_TSO;
+                 hi->caps |= VNET_HW_INTERFACE_CAP_SUPPORTS_VXLAN_TNL_GSO;
+               }
            }
          else
            clib_warning ("%s: TCP/UDP checksum offload must be enabled",
@@ -1391,8 +1413,11 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
        conf->enable_telemetry = 1;
 
       else if (unformat (input, "enable-tcp-udp-checksum"))
-       conf->enable_tcp_udp_checksum = 1;
-
+       {
+         conf->enable_tcp_udp_checksum = 1;
+         if (unformat (input, "enable-outer-checksum-offload"))
+           conf->enable_outer_checksum_offload = 1;
+       }
       else if (unformat (input, "no-tx-checksum-offload"))
        conf->no_tx_checksum_offload = 1;