udp: fix csum computation when offload disabled 25/40925/4
authorFlorin Coras <fcoras@cisco.com>
Fri, 24 May 2024 01:22:48 +0000 (18:22 -0700)
committerDave Barach <vpp@barachs.net>
Fri, 24 May 2024 17:28:16 +0000 (17:28 +0000)
Type: fix

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I11de9e1156420e0a37d637d8611bb3cf9788d699

src/vnet/udp/udp.c
src/vnet/udp/udp_inlines.h

index b3c0251..9c1121f 100644 (file)
@@ -232,18 +232,43 @@ udp_session_get_listener (u32 listener_index)
   return &us->connection;
 }
 
+always_inline u16
+udp_compute_checksum (vlib_main_t *vm, vlib_buffer_t *b, u8 csum_offload,
+                     u8 is_ip4)
+{
+  u16 csum = 0;
+
+  if (csum_offload)
+    vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_UDP_CKSUM);
+  else
+    {
+      if (is_ip4)
+       csum =
+         ip4_tcp_udp_compute_checksum (vm, b, vlib_buffer_get_current (b));
+      else
+       {
+         int bogus = 0;
+         csum = ip6_tcp_udp_icmp_compute_checksum (
+           vm, b, vlib_buffer_get_current (b), &bogus);
+       }
+    }
+
+  return csum;
+}
+
 always_inline u32
 udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b,
                     u8 is_cless)
 {
+  udp_header_t *uh;
+
   b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
   /* reuse tcp medatada for now */
   vnet_buffer (b)->tcp.connection_index = uc->c_c_index;
 
   if (!is_cless)
     {
-      vlib_buffer_push_udp (b, uc->c_lcl_port, uc->c_rmt_port,
-                           udp_csum_offload (uc));
+      uh = vlib_buffer_push_udp (b, uc->c_lcl_port, uc->c_rmt_port);
 
       if (uc->c_is_ip4)
        vlib_buffer_push_ip4_custom (vm, b, &uc->c_lcl_ip4, &uc->c_rmt_ip4,
@@ -263,8 +288,7 @@ udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b,
       hdr = *(session_dgram_hdr_t *) (data - sizeof (hdr));
 
       /* Local port assumed to be bound, not overwriting it */
-      vlib_buffer_push_udp (b, uc->c_lcl_port, hdr.rmt_port,
-                           udp_csum_offload (uc));
+      uh = vlib_buffer_push_udp (b, uc->c_lcl_port, hdr.rmt_port);
 
       if (uc->c_is_ip4)
        vlib_buffer_push_ip4_custom (vm, b, &hdr.lcl_ip.ip4, &hdr.rmt_ip.ip4,
@@ -279,6 +303,9 @@ udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b,
       vnet_buffer (b)->tcp.flags |= UDP_CONN_F_LISTEN;
     }
 
+  uh->checksum =
+    udp_compute_checksum (vm, b, udp_csum_offload (uc), uc->c_is_ip4);
+
   return 0;
 }
 
index f0dd44f..ceec0b1 100644 (file)
@@ -26,7 +26,7 @@
 #include <vnet/udp/udp_encap.h>
 
 always_inline void *
-vlib_buffer_push_udp (vlib_buffer_t * b, u16 sp, u16 dp, u8 offload_csum)
+vlib_buffer_push_udp (vlib_buffer_t *b, u16 sp, u16 dp)
 {
   udp_header_t *uh;
   u16 udp_len = sizeof (udp_header_t) + b->current_length;
@@ -38,8 +38,6 @@ vlib_buffer_push_udp (vlib_buffer_t * b, u16 sp, u16 dp, u8 offload_csum)
   uh->dst_port = dp;
   uh->checksum = 0;
   uh->length = clib_host_to_net_u16 (udp_len);
-  if (offload_csum)
-    vnet_buffer_offload_flags_set (b, VNET_BUFFER_OFFLOAD_F_UDP_CKSUM);
   vnet_buffer (b)->l4_hdr_offset = (u8 *) uh - b->data;
   b->flags |= VNET_BUFFER_F_L4_HDR_OFFSET_VALID;
   return uh;