plugins: odp: Add asynchronous IPsec API nodes 78/10278/3
authorSzymon Sliwa <[email protected]>
Tue, 23 Jan 2018 13:30:49 +0000 (14:30 +0100)
committerSzymon Sliwa <[email protected]>
Mon, 19 Feb 2018 16:47:48 +0000 (17:47 +0100)
To use asynchronous mode put async in the odp section
of the startup.conf file, like this:

odp {
    enable-odp-ipsec
    async
}

Falls back to synchronous mode.

Change-Id: Iacfdc03158228f4385511e6736fb24a97284320c
Signed-off-by: Szymon Sliwa <[email protected]>
src/plugins/odp/ipsec/crypto_input.c
src/plugins/odp/ipsec/esp_decrypt_ipsec_api.c
src/plugins/odp/ipsec/esp_encrypt_ipsec_api.c
src/plugins/odp/ipsec/ipsec.c
src/plugins/odp/odp_packet.c
src/plugins/odp/odp_packet.h
src/vpp/conf/startup.conf

index 0b0fba3..4e91822 100644 (file)
        _(ENCRYPT_POST, "odp-crypto-esp-encrypt-post") \
        _(DECRYPT_POST, "odp-crypto-esp-decrypt-post")
 
+
+#define foreach_odp_ipsec_input_next \
+       _(ENCRYPT_POST, "odp-ipsec-esp-encrypt-post") \
+       _(DECRYPT_POST, "odp-ipsec-esp-decrypt-post")
+
 typedef enum
 {
 #define _(f, s) ODP_CRYPTO_INPUT_NEXT_##f,
   foreach_odp_crypto_input_next
 #undef _
-    ODP_CRYPTO_INPUT_N_NEXT,
+#define _(f, s) ODP_IPSEC_INPUT_NEXT_##f,
+ foreach_odp_ipsec_input_next
+#undef _
+ODP_CRYPTO_INPUT_N_NEXT,
 } odp_crypto_input_next_t;
 
 #define foreach_crypto_input_error \
@@ -124,6 +132,70 @@ odp_dequeue_cops (vlib_main_t * vm, vlib_node_runtime_t * node,
        }
       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     }
+  vlib_node_increment_counter (vm, odp_crypto_input_node.index,
+                              CRYPTO_INPUT_ERROR_DEQUE_COP,
+                              n_deq);
+
+  return n_deq;
+}
+
+static uword
+odp_dequeue_ipsec_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
+               vlib_frame_t * frame, odp_queue_t queue, u32 next_node_index)
+{
+  u32 next_index = next_node_index, n_deq, n_cops, *to_next = 0;
+  const int MAX_EVENTS = (1<<8);
+  odp_event_t events[MAX_EVENTS];
+
+  n_deq = odp_queue_deq_multi(queue, events, MAX_EVENTS);
+
+  n_cops = n_deq;
+
+  int index = 0;
+  while(n_cops > 0) {
+         u32 n_left_to_next;
+
+         vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+         while(n_cops > 0 && n_left_to_next > 0) {
+                 odp_event_t event = events[index++];
+
+                 odp_packet_t pkt;
+                 vlib_buffer_t *b0;
+                 u32 bi0;
+
+                 pkt = odp_packet_from_event(event);
+
+                 b0 = vlib_buffer_from_odp_packet(pkt);
+                 bi0 = vlib_get_buffer_index (vm, b0);
+
+                 b0->current_data =
+                   (i16) ((intptr_t) odp_packet_data (pkt) -
+                          (intptr_t) b0->data +
+                          (intptr_t) odp_packet_l3_offset (pkt));
+                 if (next_index == ODP_IPSEC_INPUT_NEXT_DECRYPT_POST)
+                       b0->current_length = odp_packet_len (pkt) - sizeof (ethernet_header_t);
+                 else
+                       b0->current_length = odp_packet_len (pkt);
+
+                 to_next[0] = bi0;
+                 to_next += 1;
+
+                 n_cops -= 1;
+                 n_left_to_next -= 1;
+
+                 if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+                   {
+                     odp_packet_crypto_trace_t *tr;
+                     tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
+                     tr->next_index = next_index;
+                   }
+
+               vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                       to_next, n_left_to_next, bi0, next_node_index);
+         }
+       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+  }
   vlib_node_increment_counter (vm, odp_crypto_input_node.index,
                               CRYPTO_INPUT_ERROR_DEQUE_COP, n_deq);
 
@@ -139,12 +211,13 @@ odp_crypto_input_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
   odp_crypto_worker_main_t *cwm =
     vec_elt_at_index (ocm->workers, thread_index);
   u32 n_cops_dequeued = 0;
-  n_cops_dequeued +=
-    odp_dequeue_cops (vm, node, frame, cwm->post_encrypt,
-                     ODP_CRYPTO_INPUT_NEXT_ENCRYPT_POST);
-  n_cops_dequeued +=
-    odp_dequeue_cops (vm, node, frame, cwm->post_decrypt,
-                     ODP_CRYPTO_INPUT_NEXT_DECRYPT_POST);
+  if (!ipsec_api) {
+         n_cops_dequeued += odp_dequeue_cops(vm, node, frame, cwm->post_encrypt, ODP_CRYPTO_INPUT_NEXT_ENCRYPT_POST);
+         n_cops_dequeued += odp_dequeue_cops(vm, node, frame, cwm->post_decrypt, ODP_CRYPTO_INPUT_NEXT_DECRYPT_POST);
+  } else {
+         n_cops_dequeued += odp_dequeue_ipsec_ops(vm, node, frame, cwm->post_encrypt, ODP_IPSEC_INPUT_NEXT_ENCRYPT_POST);
+         n_cops_dequeued += odp_dequeue_ipsec_ops(vm, node, frame, cwm->post_decrypt, ODP_IPSEC_INPUT_NEXT_DECRYPT_POST);
+  }
   return n_cops_dequeued;
 }
 
@@ -166,6 +239,9 @@ VLIB_REGISTER_NODE (odp_crypto_input_node) =
   {
 #define _(s, n) [ODP_CRYPTO_INPUT_NEXT_##s] = n,
        foreach_odp_crypto_input_next
+#undef _
+#define _(s, n) [ODP_IPSEC_INPUT_NEXT_##s] = n,
+       foreach_odp_ipsec_input_next
 #undef _
   },
 };
index aa9eeec..87427ea 100644 (file)
@@ -85,6 +85,17 @@ format_esp_decrypt_trace (u8 * s, va_list * args)
   return s;
 }
 
+/* packet trace format function */
+static u8 *
+format_esp_decrypt_post_trace (u8 * s, va_list * args)
+{
+  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+
+  s = format (s, "POST DECRYPT CRYPTO (ODP)");
+  return s;
+}
+
 static uword
 esp_decrypt_node_fn (vlib_main_t * vm,
                     vlib_node_runtime_t * node, vlib_frame_t * from_frame)
@@ -115,7 +126,6 @@ esp_decrypt_node_fn (vlib_main_t * vm,
   while (n_left_from > 0)
     {
       u32 n_left_to_next;
-      u32 buffers_passed = 0;
 
       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
 
@@ -180,11 +190,16 @@ esp_decrypt_node_fn (vlib_main_t * vm,
          to_next[0] = bi0;
          to_next += 1;
 
+         vnet_buffer (i_b0)->post_crypto.next_index = (u8) next0;
+
          int processed = 1;
 
-         int ret = odp_ipsec_in (&pkt, 1, &out_pkt, &processed, &oiopt);
+         int ret;
 
-         o_b0 = vlib_buffer_from_odp_packet (out_pkt);
+          if (!is_async)
+            ret = odp_ipsec_in (&pkt, 1, &out_pkt, &processed, &oiopt);
+          else
+            ret = odp_ipsec_in_enq(&pkt, 1, &oiopt);
 
          if (ret < 1)
            {
@@ -192,36 +207,40 @@ esp_decrypt_node_fn (vlib_main_t * vm,
              goto trace;
            }
 
-         /* add the change of the ODP data offset
-            and the offset to IP within the packet data */
-         o_b0->current_data =
-           (i16) ((intptr_t) odp_packet_data (out_pkt) -
-                  (intptr_t) o_b0->data +
-                  (intptr_t) odp_packet_l3_offset (out_pkt));
-         o_b0->current_length =
-           odp_packet_len (out_pkt) - sizeof (ethernet_header_t);
+         if (!is_async)
+           {
+             o_b0 = vlib_buffer_from_odp_packet (out_pkt);
+
+             /* add the change of the ODP data offset
+                and the offset to IP within the packet data */
+             o_b0->current_data =
+               (i16) ((intptr_t) odp_packet_data (out_pkt) -
+                      (intptr_t) o_b0->data +
+                      (intptr_t) odp_packet_l3_offset (out_pkt));
+             o_b0->current_length =
+               odp_packet_len (out_pkt) - sizeof (ethernet_header_t);
 
-         vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+             vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
 
-         vnet_buffer (o_b0)->unused[0] = next0;
+             vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+                                              n_left_to_next, bi0, next0);
+           }
+         else
+           {
+             to_next -= 1;
+             n_left_to_next += 1;
+           }
 
        trace:
-         if (PREDICT_FALSE (o_b0->flags & VLIB_BUFFER_IS_TRACED))
+         if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED))
            {
-             o_b0->flags |= VLIB_BUFFER_IS_TRACED;
-             o_b0->trace_index = o_b0->trace_index;
              esp_decrypt_trace_t *tr =
-               vlib_add_trace (vm, node, o_b0, sizeof (*tr));
+               vlib_add_trace (vm, node, i_b0, sizeof (*tr));
              tr->crypto_alg = sa0->crypto_alg;
              tr->integ_alg = sa0->integ_alg;
            }
-
-         vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
-                                          n_left_to_next, bi0, next0);
-         buffers_passed += 1;
        }
-      if (buffers_passed > 0)
-       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     }
   vlib_node_increment_counter (vm, odp_ipsec_esp_decrypt_node.index,
                               ESP_DECRYPT_ERROR_RX_PKTS,
@@ -251,6 +270,77 @@ VLIB_REGISTER_NODE (odp_ipsec_esp_decrypt_node) = {
   },
 };
 
+VLIB_NODE_FUNCTION_MULTIARCH (odp_ipsec_esp_decrypt_node, esp_decrypt_node_fn)
+
+     static uword
+       esp_decrypt_post_node_fn (vlib_main_t * vm,
+                                vlib_node_runtime_t * node,
+                                vlib_frame_t * from_frame)
+{
+  u32 n_left_from, *from, *to_next = 0, next_index;
+  from = vlib_frame_vector_args (from_frame);
+  n_left_from = from_frame->n_vectors;
+
+  next_index = node->cached_next_index;
+
+  while (n_left_from > 0)
+    {
+      u32 n_left_to_next;
+
+      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+      while (n_left_from > 0 && n_left_to_next > 0)
+       {
+         u32 bi0, next0;
+         vlib_buffer_t *b0 = 0;
+
+         bi0 = from[0];
+         from += 1;
+         n_left_from -= 1;
+         n_left_to_next -= 1;
+
+         b0 = vlib_get_buffer (vm, bi0);
+
+         to_next[0] = bi0;
+         to_next += 1;
+
+         next0 = vnet_buffer (b0)->post_crypto.next_index;
+
+         vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                          to_next, n_left_to_next, bi0,
+                                          next0);
+         if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+           vlib_add_trace (vm, node, b0, 0);
+       }
+      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+
+    }
+  vlib_node_increment_counter (vm, odp_ipsec_esp_decrypt_post_node.index,
+                              ESP_DECRYPT_ERROR_RX_PKTS,
+                              from_frame->n_vectors);
+
+  return from_frame->n_vectors;
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (odp_ipsec_esp_decrypt_post_node) = {
+  .function = esp_decrypt_post_node_fn,
+  .name = "odp-ipsec-esp-decrypt-post",
+  .vector_size = sizeof (u32),
+  .format_trace = format_esp_decrypt_post_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = ARRAY_LEN(esp_decrypt_error_strings),
+  .error_strings = esp_decrypt_error_strings,
+
+  .n_next_nodes = ESP_DECRYPT_N_NEXT,
+  .next_nodes = {
+#define _(s,n) [ESP_DECRYPT_NEXT_##s] = n,
+    foreach_esp_decrypt_next
+#undef _
+  },
+};
+
 /* *INDENT-ON* */
 
 /*
index a41f282..4753ff8 100644 (file)
@@ -86,6 +86,16 @@ format_esp_encrypt_trace (u8 * s, va_list * args)
   return s;
 }
 
+/* packet trace format function */
+static u8 *
+format_esp_encrypt_post_trace (u8 * s, va_list * args)
+{
+  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+
+  s = format (s, "POST ENCRYPT CRYPTO (ODP) esp");
+  return s;
+}
 
 static uword
 esp_encrypt_node_fn (vlib_main_t * vm,
@@ -118,7 +128,6 @@ esp_encrypt_node_fn (vlib_main_t * vm,
   while (n_left_from > 0)
     {
       u32 n_left_to_next;
-      u32 buffers_passed = 0;
 
       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
 
@@ -129,8 +138,7 @@ esp_encrypt_node_fn (vlib_main_t * vm,
          u32 sa_index0;
          ipsec_sa_t *sa0;
          ip6_header_t *h6 = 0;
-         ethernet_header_t old_eth_hdr;
-         u8 transport_mode = 0;
+         //u8 transport_mode = 0;
          sa_data_t *sa_sess_data;
          u32 flow_label;
 
@@ -147,16 +155,18 @@ esp_encrypt_node_fn (vlib_main_t * vm,
 
          sa0->total_data_size += i_b0->current_length;
 
-         old_eth_hdr = *((ethernet_header_t *)
-                         ((u8 *) vlib_buffer_get_current (i_b0) -
-                          sizeof (ethernet_header_t)));
-
          h6 = vlib_buffer_get_current (i_b0);
 
          flow_label =
            (0xFFFFF & h6->ip_version_traffic_class_and_flow_label);
 
          sa_sess_data = pool_elt_at_index (cwm->sa_sess_d[1], sa_index0);
+
+         clib_memcpy (&vnet_buffer (i_b0)->post_crypto.dst_mac,
+                      ((u8 *) vlib_buffer_get_current (i_b0) -
+                       sizeof (ethernet_header_t)),
+                      sizeof (ethernet_header_t));
+
          if (PREDICT_FALSE (!(sa_sess_data->is_odp_sa_present)))
            {
              int ret = create_odp_sa (sa0, sa_sess_data, flow_label, 1);
@@ -172,6 +182,18 @@ esp_encrypt_node_fn (vlib_main_t * vm,
          to_next[0] = bi0;
          to_next += 1;
 
+         if (!sa0->is_tunnel)
+           {
+             next0 = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
+           }
+         else
+           {
+             if (sa0->is_tunnel_ip6)
+               next0 = ESP_ENCRYPT_NEXT_IP6_LOOKUP;
+             else
+               next0 = ESP_ENCRYPT_NEXT_IP4_LOOKUP;
+             vnet_buffer (i_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+           }
 
          ASSERT (sa0->crypto_alg < IPSEC_CRYPTO_N_ALG);
 
@@ -190,13 +212,16 @@ esp_encrypt_node_fn (vlib_main_t * vm,
 
              odp_packet_l3_offset_set (pkt, 0);
 
-             int processed = 1;
+             vnet_buffer (i_b0)->post_crypto.next_index = (u8) next0;
 
-             int ret = odp_ipsec_out (&pkt, 1, &out_pkt, &processed, &oiopt);
+             int processed = 1;
 
-             o_b0 = vlib_buffer_from_odp_packet (out_pkt);
+             int ret;
 
-             vnet_buffer (o_b0)->unused[0] = next0;
+              if (is_async)
+               ret = odp_ipsec_out_enq (&pkt, 1, &oiopt);
+             else
+               ret = odp_ipsec_out (&pkt, 1, &out_pkt, &processed, &oiopt);
 
              if (ret < 1)
                {
@@ -204,67 +229,61 @@ esp_encrypt_node_fn (vlib_main_t * vm,
                  goto trace;
                }
 
-             o_b0->current_data =
-               (i16) ((intptr_t) odp_packet_data (out_pkt) -
-                      (intptr_t) o_b0->data +
-                      (intptr_t) odp_packet_l3_offset (out_pkt));
-             o_b0->current_length = odp_packet_len (out_pkt);
+
+             if (!is_async)
+               {
+                 o_b0 = vlib_buffer_from_odp_packet (out_pkt);
 
 
+                 o_b0->current_data =
+                   (i16) ((intptr_t) odp_packet_data (out_pkt) -
+                          (intptr_t) o_b0->data +
+                          (intptr_t) odp_packet_l3_offset (out_pkt));
+                 o_b0->current_length = odp_packet_len (out_pkt);
+               }
+
            }
 
-         if (!sa0->is_tunnel)
+         if (!is_async)
            {
-             if (vnet_buffer (o_b0)->sw_if_index[VLIB_TX] != ~0)
+             if (!sa0->is_tunnel)
                {
-                 transport_mode = 1;
-                 ethernet_header_t *ieh0, *oeh0;
-                 ieh0 = &old_eth_hdr;
-                 oeh0 =
-                   (ethernet_header_t *) ((uintptr_t)
-                                          vlib_buffer_get_current (o_b0) -
-                                          sizeof (ethernet_header_t));
-                 clib_memcpy (oeh0, ieh0, sizeof (ethernet_header_t));
-                 next0 = ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT;
+                 if (vnet_buffer (o_b0)->sw_if_index[VLIB_TX] != ~0)
+                   {
+                     ethernet_header_t *ieh0, *oeh0;
+                     ieh0 =
+                       (ethernet_header_t *) & vnet_buffer (i_b0)->post_crypto.dst_mac;
+                     oeh0 =
+                       (ethernet_header_t *) ((uintptr_t)
+                                              vlib_buffer_get_current (o_b0)
+                                              - sizeof (ethernet_header_t));
+                     clib_memcpy (oeh0, ieh0, sizeof (ethernet_header_t));
+                   }
+                 o_b0->current_data -= sizeof (ethernet_header_t);
+                 o_b0->current_length += sizeof (ethernet_header_t);
                }
-           }
 
-         if (transport_mode)
-           {
-             o_b0->current_data -= sizeof (ethernet_header_t);
-             o_b0->current_length += sizeof (ethernet_header_t);
+             vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                              to_next, n_left_to_next, bi0,
+                                              next0);
            }
          else
            {
-             if (sa0->is_tunnel_ip6)
-               next0 = ESP_ENCRYPT_NEXT_IP6_LOOKUP;
-             else
-               next0 = ESP_ENCRYPT_NEXT_IP4_LOOKUP;
-
-             vnet_buffer (o_b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+             to_next -= 1;
+             n_left_to_next += 1;
            }
-
        trace:
-         if (PREDICT_FALSE (o_b0->flags & VLIB_BUFFER_IS_TRACED))
+         if (PREDICT_FALSE (i_b0->flags & VLIB_BUFFER_IS_TRACED))
            {
-             o_b0->flags |= VLIB_BUFFER_IS_TRACED;
-             o_b0->trace_index = o_b0->trace_index;
              esp_encrypt_trace_t *tr =
-               vlib_add_trace (vm, node, o_b0, sizeof (*tr));
+               vlib_add_trace (vm, node, i_b0, sizeof (*tr));
              tr->spi = sa0->spi;
              tr->seq = sa0->seq - 1;
              tr->crypto_alg = sa0->crypto_alg;
              tr->integ_alg = sa0->integ_alg;
            }
-
-         vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
-                                          to_next, n_left_to_next, bi0,
-                                          next0);
-         buffers_passed += 1;
-
        }
-      if (buffers_passed > 0)
-       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     }
   vlib_node_increment_counter (vm, odp_ipsec_esp_encrypt_node.index,
                               ESP_ENCRYPT_ERROR_RX_PKTS,
@@ -294,6 +313,91 @@ VLIB_REGISTER_NODE (odp_ipsec_esp_encrypt_node) = {
   },
 };
 
+VLIB_NODE_FUNCTION_MULTIARCH (odp_ipsec_esp_encrypt_node, esp_encrypt_node_fn)
+
+     static uword
+       esp_encrypt_post_node_fn (vlib_main_t * vm,
+                                vlib_node_runtime_t * node,
+                                vlib_frame_t * from_frame)
+{
+  u32 n_left_from, *from, *to_next = 0, next_index;
+  from = vlib_frame_vector_args (from_frame);
+  n_left_from = from_frame->n_vectors;
+
+  next_index = node->cached_next_index;
+
+  while (n_left_from > 0)
+    {
+      u32 n_left_to_next;
+
+      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+      while (n_left_from > 0 && n_left_to_next > 0)
+       {
+         u32 bi0, next0;
+         vlib_buffer_t *b0 = 0;
+
+         bi0 = from[0];
+         from += 1;
+         n_left_from -= 1;
+         n_left_to_next -= 1;
+
+         b0 = vlib_get_buffer (vm, bi0);
+
+         to_next[0] = bi0;
+         to_next += 1;
+
+         next0 = vnet_buffer (b0)->post_crypto.next_index;
+
+         if (next0 == ESP_ENCRYPT_NEXT_INTERFACE_OUTPUT)
+           {
+
+             ethernet_header_t *ieh0, *oeh0;
+             ieh0 = (ethernet_header_t *) & vnet_buffer (b0)->post_crypto.dst_mac;
+             oeh0 =
+               (ethernet_header_t *) ((uintptr_t)
+                                      vlib_buffer_get_current (b0) -
+                                      sizeof (ethernet_header_t));
+             clib_memcpy (oeh0, ieh0, sizeof (ethernet_header_t));
+             b0->current_data -= sizeof (ethernet_header_t);
+             b0->current_length += sizeof (ethernet_header_t);
+           }
+
+
+         if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+           vlib_add_trace (vm, node, b0, 0);
+         vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
+                                          to_next, n_left_to_next, bi0,
+                                          next0);
+       }
+      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+    }
+  vlib_node_increment_counter (vm, odp_ipsec_esp_encrypt_post_node.index,
+                              ESP_ENCRYPT_ERROR_RX_PKTS,
+                              from_frame->n_vectors);
+
+  return from_frame->n_vectors;
+}
+
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (odp_ipsec_esp_encrypt_post_node) = {
+  .function = esp_encrypt_post_node_fn,
+  .name = "odp-ipsec-esp-encrypt-post",
+  .vector_size = sizeof (u32),
+  .format_trace = format_esp_encrypt_post_trace,
+  .type = VLIB_NODE_TYPE_INTERNAL,
+
+  .n_errors = ARRAY_LEN(esp_encrypt_error_strings),
+  .error_strings = esp_encrypt_error_strings,
+
+  .n_next_nodes = ESP_ENCRYPT_N_NEXT,
+  .next_nodes = {
+#define _(s,n) [ESP_ENCRYPT_NEXT_##s] = n,
+    foreach_esp_encrypt_next
+#undef _
+  },
+};
+
 /* *INDENT-ON* */
 
 /*
index 44a7714..62a074f 100644 (file)
@@ -20,6 +20,7 @@
 #include <vnet/ip/ip.h>
 #include <vnet/interface.h>
 
+#include <odp/odp_packet.h>
 #include <odp/ipsec/ipsec.h>
 #include <odp/ipsec/esp.h>
 
@@ -84,6 +85,11 @@ int                          // should flow_label be here?
 create_odp_sa (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int flow_label,
               int is_outbound)
 {
+  odp_crypto_main_t *ocm = &odp_crypto_main;
+  u32 thread_index = vlib_get_thread_index ();
+  odp_crypto_worker_main_t *cwm =
+    vec_elt_at_index (ocm->workers, thread_index);
+
   odp_ipsec_sa_param_t sa_params;
   odp_ipsec_sa_param_init (&sa_params);
 
@@ -139,7 +145,8 @@ create_odp_sa (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int flow_label,
 
   sa_params.spi = sa->spi;
 
-  sa_params.dest_queue = ODP_QUEUE_INVALID;
+  sa_params.dest_queue =
+    (is_outbound ? cwm->post_encrypt : cwm->post_decrypt);
   sa_params.context = NULL;
   sa_params.context_len = 0;
 
@@ -174,7 +181,7 @@ create_sess (ipsec_sa_t * sa, sa_data_t * sa_sess_data, int is_outbound)
 
   crypto_params.auth_cipher_text = 1;
 
-  crypto_params.pref_mode = ODP_CRYPTO_ASYNC;
+  crypto_params.pref_mode = (is_async ? ODP_CRYPTO_ASYNC : ODP_CRYPTO_SYNC);
   crypto_params.compl_queue =
     (is_outbound ? cwm->post_encrypt : cwm->post_decrypt);
   crypto_params.output_pool = ODP_POOL_INVALID;
@@ -315,9 +322,11 @@ ipsec_init (vlib_main_t * vm, u8 ipsec_api)
   ipsec_node = vlib_get_node_by_name (vm, (u8 *) "ipsec-output-ip4");
   ASSERT (ipsec_node);
   if (ipsec_api)
-    crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-ipsec-esp-encrypt");
+      crypto_node =
+       vlib_get_node_by_name (vm, (u8 *) "odp-ipsec-esp-encrypt");
   else
-    crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-encrypt");
+      crypto_node =
+       vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-encrypt");
   ASSERT (crypto_node);
   im->esp_encrypt_node_index = crypto_node->index;
   im->esp_encrypt_next_index =
@@ -328,7 +337,8 @@ ipsec_init (vlib_main_t * vm, u8 ipsec_api)
   if (ipsec_api)
     crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-ipsec-esp-decrypt");
   else
-    crypto_node = vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-decrypt");
+      crypto_node =
+       vlib_get_node_by_name (vm, (u8 *) "odp-crypto-esp-decrypt");
   ASSERT (crypto_node);
   im->esp_decrypt_node_index = crypto_node->index;
   im->esp_decrypt_next_index =
index 5a43a44..7f5f05c 100755 (executable)
@@ -25,6 +25,7 @@ odp_if_config_t *if_config;
 odp_crypto_main_t odp_crypto_main;
 u8 enable_odp_crypto;
 u8 ipsec_api;
+u8 is_async;
 
 static u32
 odp_packet_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi,
@@ -435,6 +436,10 @@ odp_config (vlib_main_t * vm, unformat_input_t * input)
        {
          ipsec_api = 1;
        }
+      else if (unformat (input, "async"))
+        {
+          is_async = 1;
+        }
       else if (unformat (input, "%s", &param))
        {
          clib_warning ("%s: Unknown option %s\n", __func__, param);
index 73972cb..e840947 100755 (executable)
@@ -81,6 +81,8 @@ extern u32 tx_burst_size;
 extern u32 num_pkts_in_pool;
 extern odp_if_mode_t def_if_mode;
 extern u8 enable_odp_crypto;
+extern u8 ipsec_api;
+extern u8 is_async;
 
 u32 odp_packet_create_if (vlib_main_t * vm, u8 * host_if_name,
                          u8 * hw_addr_set, u32 * sw_if_index,
index 6ae0dc1..8b05286 100644 (file)
@@ -136,7 +136,7 @@ cpu {
        ## Use ODP ipsec API instead of ODP crypto API
        # enable-odp-ipsec
 
-       ## To use asynchronous mode of the crypto operations
+       ## To use asynchronous mode of the crypto/ipsec operations
        # async
 # }