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/ah_decrypt.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'src/vnet/ipsec/ah_decrypt.c') diff --git a/src/vnet/ipsec/ah_decrypt.c b/src/vnet/ipsec/ah_decrypt.c index f46fa6e2161..22f9a09453e 100644 --- a/src/vnet/ipsec/ah_decrypt.c +++ b/src/vnet/ipsec/ah_decrypt.c @@ -24,10 +24,11 @@ #include #include -#define foreach_ah_decrypt_next \ - _ (DROP, "error-drop") \ - _ (IP4_INPUT, "ip4-input") \ - _ (IP6_INPUT, "ip6-input") +#define foreach_ah_decrypt_next \ + _(DROP, "error-drop") \ + _(IP4_INPUT, "ip4-input") \ + _(IP6_INPUT, "ip6-input") \ + _(HANDOFF, "handoff") #define _(v, s) AH_DECRYPT_NEXT_##v, typedef enum @@ -175,6 +176,21 @@ ah_decrypt_inline (vlib_main_t * vm, thread_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] = AH_DECRYPT_NEXT_HANDOFF; + goto next; + } + pd->sa_index = current_sa_index; ih4 = vlib_buffer_get_current (b[0]); @@ -421,9 +437,10 @@ VLIB_REGISTER_NODE (ah4_decrypt_node) = { .n_next_nodes = AH_DECRYPT_N_NEXT, .next_nodes = { -#define _(s,n) [AH_DECRYPT_NEXT_##s] = n, - foreach_ah_decrypt_next -#undef _ + [AH_DECRYPT_NEXT_DROP] = "ip4-drop", + [AH_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum", + [AH_DECRYPT_NEXT_IP6_INPUT] = "ip6-input", + [AH_DECRYPT_NEXT_HANDOFF] = "esp4-decrypt-tun-handoff", }, }; /* *INDENT-ON* */ @@ -447,9 +464,10 @@ VLIB_REGISTER_NODE (ah6_decrypt_node) = { .n_next_nodes = AH_DECRYPT_N_NEXT, .next_nodes = { -#define _(s,n) [AH_DECRYPT_NEXT_##s] = n, - foreach_ah_decrypt_next -#undef _ + [AH_DECRYPT_NEXT_DROP] = "ip6-drop", + [AH_DECRYPT_NEXT_IP4_INPUT] = "ip4-input-no-checksum", + [AH_DECRYPT_NEXT_IP6_INPUT] = "ip6-input", + [AH_DECRYPT_NEXT_HANDOFF] = "esp6-decrypt-handoff", }, }; /* *INDENT-ON* */ -- cgit 1.2.3-korg