aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2024-05-23 18:22:48 -0700
committerDave Barach <vpp@barachs.net>2024-05-24 17:28:16 +0000
commitfc42280434f669095c63d43b3af8d73e3adce366 (patch)
tree316851f4b5356e0948f705ac4735f54e10c7bd33
parentfe736b2af9366d0cd00ff2f9ab6ccaba50f0ee8b (diff)
udp: fix csum computation when offload disabled
Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I11de9e1156420e0a37d637d8611bb3cf9788d699
-rw-r--r--src/vnet/udp/udp.c35
-rw-r--r--src/vnet/udp/udp_inlines.h4
2 files changed, 32 insertions, 7 deletions
diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c
index b3c02510232..9c1121f7cfb 100644
--- a/src/vnet/udp/udp.c
+++ b/src/vnet/udp/udp.c
@@ -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;
}
diff --git a/src/vnet/udp/udp_inlines.h b/src/vnet/udp/udp_inlines.h
index f0dd44f48b5..ceec0b191b1 100644
--- a/src/vnet/udp/udp_inlines.h
+++ b/src/vnet/udp/udp_inlines.h
@@ -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;