From 568acbb7c980608e238b25b1330d2730b8534599 Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 18 Dec 2019 05:54:40 +0000 Subject: ipsec: Fix decap of IPSEC/GRE in transport mode Type: fix in transport mode the header sequence is: MAC - IP (tun) - ESP - GRE - L2 so popping the GRE header is done in the ESP decrypt node. Change-Id: Ia125eb65b9300368617d2bffca09683851e43be0 Signed-off-by: Neale Ranns --- src/vnet/ipsec/esp_decrypt.c | 50 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) (limited to 'src/vnet/ipsec/esp_decrypt.c') diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c index a56a7843ef5..8afea9b32a0 100644 --- a/src/vnet/ipsec/esp_decrypt.c +++ b/src/vnet/ipsec/esp_decrypt.c @@ -24,10 +24,13 @@ #include #include +#include + #define foreach_esp_decrypt_next \ _(DROP, "error-drop") \ _(IP4_INPUT, "ip4-input-no-checksum") \ _(IP6_INPUT, "ip6-input") \ +_(L2_INPUT, "l2-input") \ _(HANDOFF, "handoff") #define _(v, s) ESP_DECRYPT_NEXT_##v, @@ -487,9 +490,40 @@ esp_decrypt_inline (vlib_main_t * vm, } else { - next[0] = ESP_DECRYPT_NEXT_DROP; - b[0]->error = node->errors[ESP_DECRYPT_ERROR_DECRYPTION_FAILED]; - goto trace; + if (is_tun && f->next_header == IP_PROTOCOL_GRE) + { + gre_header_t *gre; + + b[0]->current_data = pd->current_data + adv; + b[0]->current_length = pd->current_length - adv - tail; + + gre = vlib_buffer_get_current (b[0]); + + vlib_buffer_advance (b[0], sizeof (*gre)); + + switch (clib_net_to_host_u16 (gre->protocol)) + { + case GRE_PROTOCOL_teb: + next[0] = ESP_DECRYPT_NEXT_L2_INPUT; + break; + case GRE_PROTOCOL_ip4: + next[0] = ESP_DECRYPT_NEXT_IP4_INPUT; + break; + case GRE_PROTOCOL_ip6: + next[0] = ESP_DECRYPT_NEXT_IP6_INPUT; + break; + default: + next[0] = ESP_DECRYPT_NEXT_DROP; + break; + } + } + else + { + next[0] = ESP_DECRYPT_NEXT_DROP; + b[0]->error = + node->errors[ESP_DECRYPT_ERROR_DECRYPTION_FAILED]; + goto trace; + } } if (is_tun) { @@ -501,9 +535,9 @@ esp_decrypt_inline (vlib_main_t * vm, */ const ipsec_tun_protect_t *itp; - itp = - ipsec_tun_protect_get (vnet_buffer (b[0])-> - ipsec.protect_index); + itp = ipsec_tun_protect_get + (vnet_buffer (b[0])->ipsec.protect_index); + if (PREDICT_TRUE (f->next_header == IP_PROTOCOL_IP_IN_IP)) { const ip4_header_t *ip4; @@ -614,6 +648,7 @@ VLIB_REGISTER_NODE (esp4_decrypt_node) = { [ESP_DECRYPT_NEXT_DROP] = "ip4-drop", [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum", [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input", + [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input", [ESP_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-handoff", }, }; @@ -632,6 +667,7 @@ VLIB_REGISTER_NODE (esp6_decrypt_node) = { [ESP_DECRYPT_NEXT_DROP] = "ip6-drop", [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum", [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input", + [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input", [ESP_DECRYPT_NEXT_HANDOFF]= "esp6-decrypt-handoff", }, }; @@ -648,6 +684,7 @@ VLIB_REGISTER_NODE (esp4_decrypt_tun_node) = { [ESP_DECRYPT_NEXT_DROP] = "ip4-drop", [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum", [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input", + [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input", [ESP_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-handoff", }, }; @@ -664,6 +701,7 @@ VLIB_REGISTER_NODE (esp6_decrypt_tun_node) = { [ESP_DECRYPT_NEXT_DROP] = "ip6-drop", [ESP_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum", [ESP_DECRYPT_NEXT_IP6_INPUT] = "ip6-input", + [ESP_DECRYPT_NEXT_L2_INPUT] = "l2-input", [ESP_DECRYPT_NEXT_HANDOFF]= "esp6-decrypt-handoff", }, }; -- cgit 1.2.3-korg