hs-test: added filenames to test names
[vpp.git] / src / vnet / gso / node.c
index 109d178..c1d4459 100644 (file)
@@ -80,113 +80,108 @@ format_gso_trace (u8 * s, va_list * args)
   return s;
 }
 
-static_always_inline u16
-tso_segment_ipip_tunnel_fixup (vlib_main_t * vm,
-                              vnet_interface_per_thread_data_t * ptd,
-                              vlib_buffer_t * sb0,
-                              generic_header_offset_t * gho)
+static_always_inline void
+tso_segment_ipip_tunnel_fixup (vlib_main_t *vm,
+                              vnet_interface_per_thread_data_t *ptd,
+                              vlib_buffer_t *sb0)
 {
   u16 n_tx_bufs = vec_len (ptd->split_buffers);
-  u16 i = 0, n_tx_bytes = 0;
+  u16 i = 0;
 
   while (i < n_tx_bufs)
     {
       vlib_buffer_t *b0 = vlib_get_buffer (vm, ptd->split_buffers[i]);
+      i16 outer_l3_hdr_offset = vnet_buffer2 (b0)->outer_l3_hdr_offset;
+      i16 l3_hdr_offset = vnet_buffer (b0)->l3_hdr_offset;
 
-      ip4_header_t *ip4 =
-       (ip4_header_t *) (vlib_buffer_get_current (b0) +
-                         gho->outer_l3_hdr_offset);
-      ip6_header_t *ip6 =
-       (ip6_header_t *) (vlib_buffer_get_current (b0) +
-                         gho->outer_l3_hdr_offset);
+      ip4_header_t *ip4 = (ip4_header_t *) (b0->data + outer_l3_hdr_offset);
+      ip6_header_t *ip6 = (ip6_header_t *) (b0->data + outer_l3_hdr_offset);
 
-      if (gho->gho_flags & GHO_F_OUTER_IP4)
+      if (vnet_buffer (b0)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM)
        {
-         ip4->length =
-           clib_host_to_net_u16 (b0->current_length -
-                                 gho->outer_l3_hdr_offset);
+         ip4->length = clib_host_to_net_u16 (
+           b0->current_length - (outer_l3_hdr_offset - b0->current_data));
          ip4->checksum = ip4_header_checksum (ip4);
+         vnet_buffer_offload_flags_clear (
+           b0, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
+                 VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
        }
-      else if (gho->gho_flags & GHO_F_OUTER_IP6)
+      else
        {
-         ip6->payload_length =
-           clib_host_to_net_u16 (b0->current_length -
-                                 gho->outer_l4_hdr_offset);
+         ip6->payload_length = clib_host_to_net_u16 (
+           b0->current_length - (l3_hdr_offset - b0->current_data));
+         vnet_buffer_offload_flags_clear (b0, VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
        }
 
-      n_tx_bytes += gho->outer_hdr_sz;
       i++;
     }
-  return n_tx_bytes;
 }
 
 static_always_inline void
-tso_segment_vxlan_tunnel_headers_fixup (vlib_main_t * vm, vlib_buffer_t * b,
-                                       generic_header_offset_t * gho)
+tso_segment_vxlan_tunnel_headers_fixup (vlib_main_t *vm, vlib_buffer_t *b)
 {
-  u8 proto = 0;
   ip4_header_t *ip4 = 0;
   ip6_header_t *ip6 = 0;
   udp_header_t *udp = 0;
+  i16 outer_l3_hdr_offset = vnet_buffer2 (b)->outer_l3_hdr_offset;
+  i16 outer_l4_hdr_offset = vnet_buffer2 (b)->outer_l4_hdr_offset;
 
-  ip4 =
-    (ip4_header_t *) (vlib_buffer_get_current (b) + gho->outer_l3_hdr_offset);
-  ip6 =
-    (ip6_header_t *) (vlib_buffer_get_current (b) + gho->outer_l3_hdr_offset);
-  udp =
-    (udp_header_t *) (vlib_buffer_get_current (b) + gho->outer_l4_hdr_offset);
+  ip4 = (ip4_header_t *) (b->data + outer_l3_hdr_offset);
+  ip6 = (ip6_header_t *) (b->data + outer_l3_hdr_offset);
+  udp = (udp_header_t *) (b->data + outer_l4_hdr_offset);
 
-  if (gho->gho_flags & GHO_F_OUTER_IP4)
+  if (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM)
     {
-      proto = ip4->protocol;
-      ip4->length =
-       clib_host_to_net_u16 (b->current_length - gho->outer_l3_hdr_offset);
+      ip4->length = clib_host_to_net_u16 (
+       b->current_length - (outer_l3_hdr_offset - b->current_data));
       ip4->checksum = ip4_header_checksum (ip4);
+      if (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM)
+       {
+         udp->length = clib_host_to_net_u16 (
+           b->current_length - (outer_l4_hdr_offset - b->current_data));
+         // udp checksum is 0, in udp tunnel
+         udp->checksum = 0;
+       }
+      vnet_buffer_offload_flags_clear (
+       b, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
+            VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM |
+            VNET_BUFFER_OFFLOAD_F_TNL_VXLAN);
     }
-  else if (gho->gho_flags & GHO_F_OUTER_IP6)
-    {
-      proto = ip6->protocol;
-      ip6->payload_length =
-       clib_host_to_net_u16 (b->current_length - gho->outer_l4_hdr_offset);
-    }
-  if (proto == IP_PROTOCOL_UDP)
+  else
     {
-      int bogus;
-      udp->length =
-       clib_host_to_net_u16 (b->current_length - gho->outer_l4_hdr_offset);
-      udp->checksum = 0;
-      if (gho->gho_flags & GHO_F_OUTER_IP6)
+      ip6->payload_length = clib_host_to_net_u16 (
+       b->current_length - (outer_l4_hdr_offset - b->current_data));
+
+      if (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM)
        {
+         int bogus;
+         udp->length = ip6->payload_length;
+         // udp checksum is 0, in udp tunnel
+         udp->checksum = 0;
          udp->checksum =
            ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus);
+         vnet_buffer_offload_flags_clear (
+           b, VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM |
+                VNET_BUFFER_OFFLOAD_F_TNL_VXLAN);
        }
-      else if (gho->gho_flags & GHO_F_OUTER_IP4)
-       {
-         udp->checksum = ip4_tcp_udp_compute_checksum (vm, b, ip4);
-       }
-      /* FIXME: it should be OUTER_UDP_CKSUM */
-      vnet_buffer_offload_flags_clear (b, VNET_BUFFER_OFFLOAD_F_UDP_CKSUM);
     }
 }
 
-static_always_inline u16
-tso_segment_vxlan_tunnel_fixup (vlib_main_t * vm,
-                               vnet_interface_per_thread_data_t * ptd,
-                               vlib_buffer_t * sb0,
-                               generic_header_offset_t * gho)
+static_always_inline void
+tso_segment_vxlan_tunnel_fixup (vlib_main_t *vm,
+                               vnet_interface_per_thread_data_t *ptd,
+                               vlib_buffer_t *sb0)
 {
   u16 n_tx_bufs = vec_len (ptd->split_buffers);
-  u16 i = 0, n_tx_bytes = 0;
+  u16 i = 0;
 
   while (i < n_tx_bufs)
     {
       vlib_buffer_t *b0 = vlib_get_buffer (vm, ptd->split_buffers[i]);
 
-      tso_segment_vxlan_tunnel_headers_fixup (vm, b0, gho);
-      n_tx_bytes += gho->outer_hdr_sz;
+      tso_segment_vxlan_tunnel_headers_fixup (vm, b0);
       i++;
     }
-  return n_tx_bytes;
 }
 
 static_always_inline u16
@@ -549,30 +544,28 @@ vnet_gso_node_inline (vlib_main_t * vm,
            if (PREDICT_FALSE (hi->sw_if_index != swif0))
              {
                hi0 = vnet_get_sup_hw_interface (vnm, swif0);
-               if ((hi0->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) ==
-                     0 &&
+               if ((hi0->caps & VNET_HW_IF_CAP_TCP_GSO) == 0 &&
                    (b[0]->flags & VNET_BUFFER_F_GSO))
                  break;
              }
            if (PREDICT_FALSE (hi->sw_if_index != swif1))
              {
                hi1 = vnet_get_sup_hw_interface (vnm, swif1);
-               if (!(hi1->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) &&
+               if (!(hi1->caps & VNET_HW_IF_CAP_TCP_GSO) &&
                    (b[1]->flags & VNET_BUFFER_F_GSO))
                  break;
              }
            if (PREDICT_FALSE (hi->sw_if_index != swif2))
              {
                hi2 = vnet_get_sup_hw_interface (vnm, swif2);
-               if ((hi2->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) ==
-                     0 &&
+               if ((hi2->caps & VNET_HW_IF_CAP_TCP_GSO) == 0 &&
                    (b[2]->flags & VNET_BUFFER_F_GSO))
                  break;
              }
            if (PREDICT_FALSE (hi->sw_if_index != swif3))
              {
                hi3 = vnet_get_sup_hw_interface (vnm, swif3);
-               if (!(hi3->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) &&
+               if (!(hi3->caps & VNET_HW_IF_CAP_TCP_GSO) &&
                    (b[3]->flags & VNET_BUFFER_F_GSO))
                  break;
              }
@@ -583,6 +576,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
                t0->flags = b[0]->flags & VNET_BUFFER_F_GSO;
                t0->gso_size = vnet_buffer2 (b[0])->gso_size;
                t0->gso_l4_hdr_sz = vnet_buffer2 (b[0])->gso_l4_hdr_sz;
+               clib_memset (&t0->gho, 0, sizeof (t0->gho));
                vnet_generic_header_offset_parser (b[0], &t0->gho, is_l2,
                                                   is_ip4, is_ip6);
              }
@@ -592,6 +586,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
                t1->flags = b[1]->flags & VNET_BUFFER_F_GSO;
                t1->gso_size = vnet_buffer2 (b[1])->gso_size;
                t1->gso_l4_hdr_sz = vnet_buffer2 (b[1])->gso_l4_hdr_sz;
+               clib_memset (&t1->gho, 0, sizeof (t1->gho));
                vnet_generic_header_offset_parser (b[1], &t1->gho, is_l2,
                                                   is_ip4, is_ip6);
              }
@@ -601,6 +596,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
                t2->flags = b[2]->flags & VNET_BUFFER_F_GSO;
                t2->gso_size = vnet_buffer2 (b[2])->gso_size;
                t2->gso_l4_hdr_sz = vnet_buffer2 (b[2])->gso_l4_hdr_sz;
+               clib_memset (&t2->gho, 0, sizeof (t2->gho));
                vnet_generic_header_offset_parser (b[2], &t2->gho, is_l2,
                                                   is_ip4, is_ip6);
              }
@@ -610,6 +606,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
                t3->flags = b[3]->flags & VNET_BUFFER_F_GSO;
                t3->gso_size = vnet_buffer2 (b[3])->gso_size;
                t3->gso_l4_hdr_sz = vnet_buffer2 (b[3])->gso_l4_hdr_sz;
+               clib_memset (&t3->gho, 0, sizeof (t3->gho));
                vnet_generic_header_offset_parser (b[3], &t3->gho, is_l2,
                                                   is_ip4, is_ip6);
              }
@@ -643,7 +640,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
          if (PREDICT_FALSE (hi->sw_if_index != swif0))
            {
              hi0 = vnet_get_sup_hw_interface (vnm, swif0);
-             if ((hi0->caps & VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO) == 0 &&
+             if ((hi0->caps & VNET_HW_IF_CAP_TCP_GSO) == 0 &&
                  (b[0]->flags & VNET_BUFFER_F_GSO))
                do_segmentation0 = 1;
            }
@@ -663,6 +660,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
              t0->flags = b[0]->flags & VNET_BUFFER_F_GSO;
              t0->gso_size = vnet_buffer2 (b[0])->gso_size;
              t0->gso_l4_hdr_sz = vnet_buffer2 (b[0])->gso_l4_hdr_sz;
+             clib_memset (&t0->gho, 0, sizeof (t0->gho));
              vnet_generic_header_offset_parser (b[0], &t0->gho, is_l2,
                                                 is_ip4, is_ip6);
            }
@@ -679,32 +677,10 @@ vnet_gso_node_inline (vlib_main_t * vm,
                  to_next -= 1;
                  n_left_to_next += 1;
                  /* undo the counting. */
-                 generic_header_offset_t gho = { 0 };
                  u32 n_tx_bytes = 0;
-                 u32 inner_is_ip6 = is_ip6;
-
-                 vnet_generic_header_offset_parser (b[0], &gho, is_l2,
-                                                    is_ip4, is_ip6);
-
-                 if (PREDICT_FALSE (gho.gho_flags & GHO_F_TUNNEL))
-                   {
-                     if (PREDICT_FALSE
-                         (gho.gho_flags & (GHO_F_GRE_TUNNEL |
-                                           GHO_F_GENEVE_TUNNEL)))
-                       {
-                         /* not supported yet */
-                         drop_one_buffer_and_count (vm, vnm, node, from - 1,
-                                                    hi->sw_if_index,
-                                                    GSO_ERROR_UNHANDLED_TYPE);
-                         b += 1;
-                         continue;
-                       }
 
-                     inner_is_ip6 = (gho.gho_flags & GHO_F_IP6) != 0;
-                   }
-
-                 n_tx_bytes = gso_segment_buffer_inline (vm, ptd, b[0], &gho,
-                                                         is_l2, inner_is_ip6);
+                 n_tx_bytes =
+                   gso_segment_buffer_inline (vm, ptd, b[0], is_l2);
 
                  if (PREDICT_FALSE (n_tx_bytes == 0))
                    {
@@ -715,19 +691,15 @@ vnet_gso_node_inline (vlib_main_t * vm,
                      continue;
                    }
 
-
-                 if (PREDICT_FALSE (gho.gho_flags & GHO_F_VXLAN_TUNNEL))
+                 if (PREDICT_FALSE (vnet_buffer (b[0])->oflags &
+                                    VNET_BUFFER_OFFLOAD_F_TNL_VXLAN))
                    {
-                     n_tx_bytes +=
-                       tso_segment_vxlan_tunnel_fixup (vm, ptd, b[0], &gho);
+                     tso_segment_vxlan_tunnel_fixup (vm, ptd, b[0]);
                    }
-                 else
-                   if (PREDICT_FALSE
-                       (gho.gho_flags & (GHO_F_IPIP_TUNNEL |
-                                         GHO_F_IPIP6_TUNNEL)))
+                 else if (PREDICT_FALSE (vnet_buffer (b[0])->oflags &
+                                         VNET_BUFFER_OFFLOAD_F_TNL_IPIP))
                    {
-                     n_tx_bytes +=
-                       tso_segment_ipip_tunnel_fixup (vm, ptd, b[0], &gho);
+                     tso_segment_ipip_tunnel_fixup (vm, ptd, b[0]);
                    }
 
                  u16 n_tx_bufs = vec_len (ptd->split_buffers);
@@ -761,7 +733,7 @@ vnet_gso_node_inline (vlib_main_t * vm,
                                             to_next, n_left_to_next);
                    }
                  /* The buffers were enqueued. Reset the length */
-                 _vec_len (ptd->split_buffers) = 0;
+                 vec_set_len (ptd->split_buffers, 0);
                  /* Free the now segmented buffer */
                  vlib_buffer_free_one (vm, bi0);
                  b += 1;
@@ -795,8 +767,7 @@ vnet_gso_inline (vlib_main_t * vm,
       hi = vnet_get_sup_hw_interface (vnm,
                                      vnet_buffer (b)->sw_if_index[VLIB_TX]);
 
-      if (hi->caps & (VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO |
-                     VNET_HW_INTERFACE_CAP_SUPPORTS_VXLAN_TNL_GSO))
+      if (hi->caps & (VNET_HW_IF_CAP_TCP_GSO | VNET_HW_IF_CAP_VXLAN_TNL_GSO))
        return vnet_gso_node_inline (vm, node, frame, vnm, hi,
                                     is_l2, is_ip4, is_ip6,
                                     /* do_segmentation */ 0);
@@ -836,7 +807,6 @@ VLIB_NODE_FN (gso_ip6_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
                          1 /* ip6 */ );
 }
 
-/* *INDENT-OFF* */
 
 VLIB_REGISTER_NODE (gso_l2_ip4_node) = {
   .vector_size = sizeof (u32),