ipsec: bind an SA to a worker
[vpp.git] / src / vnet / ipsec / ah_decrypt.c
index f46fa6e..22f9a09 100644 (file)
 #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* */