diff options
author | Neale Ranns <nranns@cisco.com> | 2019-04-18 19:49:13 -0700 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2019-04-19 04:02:59 +0000 |
commit | 84ac8ac369bbe788a3f4eeb913f7927596f696af (patch) | |
tree | a30d3ca3d08ab295bbc4ebd31df4b99731dc69b2 /src/vnet/ipsec/esp_encrypt.c | |
parent | 9fdfcf32741551a0eaf11a27d822a9d8f0607832 (diff) |
IPSEC: IPv6 ESP transport mode incorrect packet length and checksum (VPP-1654)
Change-Id: Ia3474e5bfea5764eae9b2987bf78296535df6778
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet/ipsec/esp_encrypt.c')
-rw-r--r-- | src/vnet/ipsec/esp_encrypt.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index f1153d92e8c..5db10b520e3 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -112,19 +112,26 @@ esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz) static_always_inline void esp_update_ip4_hdr (ip4_header_t * ip4, u16 len, int is_transport, int is_udp) { - ip_csum_t sum = ip4->checksum; - u16 old_len = 0; + ip_csum_t sum; + u16 old_len; + + len = clib_net_to_host_u16 (len); + old_len = ip4->length; if (is_transport) { u8 prot = is_udp ? IP_PROTOCOL_UDP : IP_PROTOCOL_IPSEC_ESP; - old_len = ip4->length; - sum = ip_csum_update (sum, ip4->protocol, prot, ip4_header_t, protocol); + + sum = ip_csum_update (ip4->checksum, ip4->protocol, + prot, ip4_header_t, protocol); ip4->protocol = prot; + + sum = ip_csum_update (sum, old_len, len, ip4_header_t, length); } + else + sum = ip_csum_update (ip4->checksum, old_len, len, ip4_header_t, length); - ip4->length = len = clib_net_to_host_u16 (len); - sum = ip_csum_update (ip4->checksum, old_len, len, ip4_header_t, length); + ip4->length = len; ip4->checksum = ip_csum_fold (sum); } @@ -411,7 +418,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, u16 len; ip4_header_t *ip4 = (ip4_header_t *) (ip_hdr); *next_hdr_ptr = ip4->protocol; - len = payload_len + hdr_len + l2_len; + len = payload_len + hdr_len - l2_len; if (udp) { esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 1); |