ipsec: bind an SA to a worker
[vpp.git] / src / vnet / ipsec / esp_decrypt.c
index cddda1f..a56a784 100644 (file)
@@ -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* */