From f62a8c013c6e22c012b9d7df2ef463a6370cf1ce Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Tue, 2 Apr 2019 08:13:33 +0000 Subject: ipsec: bind an SA to a worker the sequence number increment and the anti-replay window checks must be atomic. Given the vector nature of VPP we can't simply use atomic increments for sequence numbers, since a vector on thread 1 with lower sequence numbers could be 'overtaken' by packets on thread 2 with higher sequence numbers. The anti-replay logic requires a critical section, not just atomics, and we don't want that. So when the SA see the first packet it is bound to that worker all subsequent packets, that arrive on a different worker, are subject to a handoff. Type: feature Change-Id: Ia20a8645fb50622ea6235ab015a537f033d531a4 Signed-off-by: Neale Ranns --- src/vnet/ipsec/esp_decrypt.c | 48 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 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 cddda1f8e54..a56a7843ef5 100644 --- a/src/vnet/ipsec/esp_decrypt.c +++ b/src/vnet/ipsec/esp_decrypt.c @@ -27,7 +27,8 @@ #define foreach_esp_decrypt_next \ _(DROP, "error-drop") \ _(IP4_INPUT, "ip4-input-no-checksum") \ -_(IP6_INPUT, "ip6-input") +_(IP6_INPUT, "ip6-input") \ +_(HANDOFF, "handoff") #define _(v, s) ESP_DECRYPT_NEXT_##v, typedef enum @@ -177,6 +178,21 @@ esp_decrypt_inline (vlib_main_t * vm, cpd.sa_index = current_sa_index; } + if (PREDICT_FALSE (~0 == sa0->decrypt_thread_index)) + { + /* this is the first packet to use this SA, claim the SA + * for this thread. this could happen simultaneously on + * another thread */ + clib_atomic_cmp_and_swap (&sa0->decrypt_thread_index, ~0, + ipsec_sa_assign_thread (thread_index)); + } + + if (PREDICT_TRUE (thread_index != sa0->decrypt_thread_index)) + { + next[0] = ESP_DECRYPT_NEXT_HANDOFF; + goto next; + } + /* store packet data for next round for easier prefetch */ pd->sa_data = cpd.sa_data; pd->current_data = b[0]->current_data; @@ -595,9 +611,10 @@ VLIB_REGISTER_NODE (esp4_decrypt_node) = { .n_next_nodes = ESP_DECRYPT_N_NEXT, .next_nodes = { -#define _(s,n) [ESP_DECRYPT_NEXT_##s] = n, - foreach_esp_decrypt_next -#undef _ + [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_HANDOFF] = "esp4-decrypt-handoff", }, }; @@ -612,9 +629,10 @@ VLIB_REGISTER_NODE (esp6_decrypt_node) = { .n_next_nodes = ESP_DECRYPT_N_NEXT, .next_nodes = { -#define _(s,n) [ESP_DECRYPT_NEXT_##s] = n, - foreach_esp_decrypt_next -#undef _ + [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_HANDOFF]= "esp6-decrypt-handoff", }, }; @@ -625,7 +643,13 @@ VLIB_REGISTER_NODE (esp4_decrypt_tun_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN(esp_decrypt_error_strings), .error_strings = esp_decrypt_error_strings, - .sibling_of = "esp4-decrypt", + .n_next_nodes = ESP_DECRYPT_N_NEXT, + .next_nodes = { + [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_HANDOFF] = "esp4-decrypt-handoff", + }, }; VLIB_REGISTER_NODE (esp6_decrypt_tun_node) = { @@ -635,7 +659,13 @@ VLIB_REGISTER_NODE (esp6_decrypt_tun_node) = { .type = VLIB_NODE_TYPE_INTERNAL, .n_errors = ARRAY_LEN(esp_decrypt_error_strings), .error_strings = esp_decrypt_error_strings, - .sibling_of = "esp6-decrypt", + .n_next_nodes = ESP_DECRYPT_N_NEXT, + .next_nodes = { + [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_HANDOFF]= "esp6-decrypt-handoff", + }, }; /* *INDENT-ON* */ -- cgit 1.2.3-korg