ikev2: add support for custom ipsec-over-udp port
[vpp.git] / src / vnet / ipsec / ah_decrypt.c
index bbe6b64..682f6cc 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]);
@@ -184,7 +200,8 @@ ah_decrypt_inline (vlib_main_t * vm,
       if (is_ip6)
        {
          ip6_ext_header_t *prev = NULL;
-         ip6_ext_header_find_t (ih6, prev, ah0, IP_PROTOCOL_IPSEC_AH);
+         ah0 =
+           ip6_ext_header_find (vm, b[0], ih6, IP_PROTOCOL_IPSEC_AH, &prev);
          pd->ip_hdr_size = sizeof (ip6_header_t);
          ASSERT ((u8 *) ah0 - (u8 *) ih6 == pd->ip_hdr_size);
        }
@@ -420,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] = "ah4-decrypt-handoff",
   },
 };
 /* *INDENT-ON* */
@@ -446,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] = "ah6-decrypt-handoff",
   },
 };
 /* *INDENT-ON* */