aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/esp_decrypt.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-12-18 05:54:40 +0000
committerNeale Ranns <nranns@cisco.com>2019-12-18 05:54:40 +0000
commit568acbb7c980608e238b25b1330d2730b8534599 (patch)
tree1044b7dc36f8779286d47ae5c6bce6eb977fec77 /src/vnet/ipsec/esp_decrypt.c
parent6461b7a319e53490e04e5e59d7909766fca86209 (diff)
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 <nranns@cisco.com>
Diffstat (limited to 'src/vnet/ipsec/esp_decrypt.c')
-rw-r--r--src/vnet/ipsec/esp_decrypt.c50
1 files changed, 44 insertions, 6 deletions
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 <vnet/ipsec/ipsec_io.h>
#include <vnet/ipsec/ipsec_tun.h>
+#include <vnet/gre/gre.h>
+
#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",
},
};