diff options
author | Neale Ranns <nranns@cisco.com> | 2019-04-02 08:13:33 +0000 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2019-12-17 17:57:24 +0000 |
commit | f62a8c013c6e22c012b9d7df2ef463a6370cf1ce (patch) | |
tree | 0448d4b53340b84e1a8aca87ec57133c503026da /src/vnet/ipsec/ah_decrypt.c | |
parent | f2bde7ac51123a0a46334b4ec55e2aceae031db7 (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/ah_decrypt.c')
-rw-r--r-- | src/vnet/ipsec/ah_decrypt.c | 38 |
1 files changed, 28 insertions, 10 deletions
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 <vnet/ipsec/ah.h> #include <vnet/ipsec/ipsec_io.h> -#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* */ |