summaryrefslogtreecommitdiffstats
path: root/src/vnet/ipsec/esp_decrypt.c
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-04-02 08:13:33 +0000
committerDamjan Marion <dmarion@me.com>2019-12-17 17:57:24 +0000
commitf62a8c013c6e22c012b9d7df2ef463a6370cf1ce (patch)
tree0448d4b53340b84e1a8aca87ec57133c503026da /src/vnet/ipsec/esp_decrypt.c
parentf2bde7ac51123a0a46334b4ec55e2aceae031db7 (diff)
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 <nranns@cisco.com>
Diffstat (limited to 'src/vnet/ipsec/esp_decrypt.c')
-rw-r--r--src/vnet/ipsec/esp_decrypt.c48
1 files changed, 39 insertions, 9 deletions
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* */