summaryrefslogtreecommitdiffstats
path: root/src/vnet/udp/udp_inlines.h
diff options
context:
space:
mode:
authorMauro Sardara <msardara@cisco.com>2022-03-22 17:53:46 +0000
committerNeale Ranns <neale@graphiant.com>2022-03-30 17:51:33 +0000
commit9539647b895c456ca53892a9259e3127c6b92d35 (patch)
treef4c0a345a2dc27eb5aff092e3b6cdc1be2d66dfe /src/vnet/udp/udp_inlines.h
parent591efc2f573baed38d79a0b9937ca4ff50732c1b (diff)
udp: fix inner packet checksum calculation in udp-encap
When computing the inner packet checksum, the code wrongly assumes that the IP version of the inner packet is the same of the outer one. On the contrary, it is perfectly possible to encapsulate v6 packets into v4 and viceversa, so we need to check the IP format of the inner header before calling vnet_calc_checksums_inline. Ticket: VPP-2020 Type: fix Signed-off-by: Mauro Sardara <msardara@cisco.com> Change-Id: Ia4515563c164f6dd5096832c831a48cb0a29b3ad Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'src/vnet/udp/udp_inlines.h')
-rw-r--r--src/vnet/udp/udp_inlines.h30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/vnet/udp/udp_inlines.h b/src/vnet/udp/udp_inlines.h
index e4eb0c88e83..d79dc9a2bad 100644
--- a/src/vnet/udp/udp_inlines.h
+++ b/src/vnet/udp/udp_inlines.h
@@ -97,14 +97,20 @@ ip_udp_fixup_one (vlib_main_t * vm, vlib_buffer_t * b0, u8 is_ip4)
}
always_inline void
-ip_udp_encap_one (vlib_main_t * vm, vlib_buffer_t * b0, u8 * ec0, word ec_len,
- u8 is_ip4)
+ip_udp_encap_one (vlib_main_t *vm, vlib_buffer_t *b0, u8 *ec0, word ec_len,
+ ip_address_family_t encap_family,
+ ip_address_family_t payload_family)
{
- vnet_calc_checksums_inline (vm, b0, is_ip4, !is_ip4);
+
+ if (payload_family < N_AF)
+ {
+ vnet_calc_checksums_inline (vm, b0, payload_family == AF_IP4,
+ payload_family == AF_IP6);
+ }
vlib_buffer_advance (b0, -ec_len);
- if (is_ip4)
+ if (encap_family == AF_IP4)
{
ip4_header_t *ip0;
@@ -127,21 +133,27 @@ ip_udp_encap_one (vlib_main_t * vm, vlib_buffer_t * b0, u8 * ec0, word ec_len,
}
always_inline void
-ip_udp_encap_two (vlib_main_t * vm, vlib_buffer_t * b0, vlib_buffer_t * b1,
- u8 * ec0, u8 * ec1, word ec_len, u8 is_v4)
+ip_udp_encap_two (vlib_main_t *vm, vlib_buffer_t *b0, vlib_buffer_t *b1,
+ u8 *ec0, u8 *ec1, word ec_len,
+ ip_address_family_t encap_family,
+ ip_address_family_t payload_family)
{
u16 new_l0, new_l1;
udp_header_t *udp0, *udp1;
+ int payload_ip4 = (payload_family == AF_IP4);
ASSERT (_vec_len (ec0) == _vec_len (ec1));
- vnet_calc_checksums_inline (vm, b0, is_v4, !is_v4);
- vnet_calc_checksums_inline (vm, b1, is_v4, !is_v4);
+ if (payload_family < N_AF)
+ {
+ vnet_calc_checksums_inline (vm, b0, payload_ip4, !payload_ip4);
+ vnet_calc_checksums_inline (vm, b1, payload_ip4, !payload_ip4);
+ }
vlib_buffer_advance (b0, -ec_len);
vlib_buffer_advance (b1, -ec_len);
- if (is_v4)
+ if (encap_family == AF_IP4)
{
ip4_header_t *ip0, *ip1;
ip_csum_t sum0, sum1;