aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/esp_encrypt.c
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2020-03-25 10:56:52 -0400
committerNeale Ranns <nranns@cisco.com>2020-03-31 09:06:43 +0000
commitb0d2eda75a268f6afc2b08080a3e00b0a3295702 (patch)
treea090fe622389428cd3db319ea783e8e66416fc09 /src/vnet/ipsec/esp_encrypt.c
parent5484daa001ccbbbf8773b273f428dbcddc4750cc (diff)
ipsec: fix udp-encap in transport mode
Now UDP enacapsulation doesn't work in transport mode with crypto algorithms that have iv_sz=8 like AES GCM or 3DES CBC. That happens because the inserted UDP header overlaps with the old IP header and gets filled before the information from the old IP header can be copied to a new IP header. The result is a broken packet: 00:03:39:620863: esp4-encrypt-tun esp: sa-index 3 spi 3464048590 (0xce792fce) seq 31 sa-seq-hi 0 crypto aes-gcm-128 integrity none udp-encap-enabled 00:03:39:620867: adj-midchain-tx ... 00:03:39:620868: ip4-rewrite ... 00:03:39:620869: GigabitEthernet0/8/0-output GigabitEthernet0/8/0 IP4: 08:00:27:a9:6b:d6 -> 08:00:27:5a:dd:0c UDP: 10.255.0.10 -> 10.255.0.20 version 0, header length 0 tos 0x80, ttl 63, length 0, checksum 0x653e (should be 0xffff) dscp CS4 ecn NON_ECN fragment id 0x0000 UDP: 128 -> 0 length 0, checksum 0x0000 00:03:39:620870: GigabitEthernet0/8/0-tx GigabitEthernet0/8/0 tx queue 0 ... IP4: 08:00:27:a9:6b:d6 -> 08:00:27:5a:dd:0c UDP: 10.255.0.10 -> 10.255.0.20 version 0, header length 0 tos 0x80, ttl 63, length 0, checksum 0x653e (should be 0xffff) dscp CS4 ecn NON_ECN fragment id 0x0000 UDP: 128 -> 0 length 0, checksum 0x0000 With this commit, fill UDP header after copying the IP headers in transport mode. Type: fix Change-Id: Ie9a6e562aa05a8378114329d6a9ff395189fa6a8 Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
Diffstat (limited to 'src/vnet/ipsec/esp_encrypt.c')
-rw-r--r--src/vnet/ipsec/esp_encrypt.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c
index e06babd92ef..4793fddcd5a 100644
--- a/src/vnet/ipsec/esp_encrypt.c
+++ b/src/vnet/ipsec/esp_encrypt.c
@@ -463,6 +463,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
u8 *l2_hdr, l2_len, *ip_hdr, ip_len;
ip6_ext_header_t *ext_hdr;
udp_header_t *udp = 0;
+ u16 udp_len = 0;
u8 *old_ip_hdr = vlib_buffer_get_current (b[0]);
ip_len = is_ip6 ?
@@ -537,7 +538,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (udp)
{
esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 1);
- esp_fill_udp_hdr (sa0, udp, len - ip_len);
+ udp_len = len - ip_len;
}
else
esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 0);
@@ -545,6 +546,11 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
clib_memcpy_le64 (ip_hdr, old_ip_hdr, ip_len);
+ if (udp)
+ {
+ esp_fill_udp_hdr (sa0, udp, udp_len);
+ }
+
if (!is_tun)
next[0] = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
}