ipsec: go straight to lookup after esp encrypt
[vpp.git] / vnet / vnet / ipsec / ipsec_input.c
index 2bc4e2b..4662c1a 100644 (file)
 #include <vnet/vnet.h>
 #include <vnet/api_errno.h>
 #include <vnet/ip/ip.h>
+#include <vnet/feature/feature.h>
 
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/ipsec/esp.h>
 
+#if DPDK_CRYPTO==1
+#define ESP_NODE "dpdk-esp-decrypt"
+#else
+#define ESP_NODE "esp-decrypt"
+#endif
+
 #define foreach_ipsec_input_next                \
 _(DROP, "error-drop")                           \
-_(ESP_DECRYPT, "esp-decrypt")
+_(ESP_DECRYPT, ESP_NODE)
 
 #define _(v, s) IPSEC_INPUT_NEXT_##v,
 typedef enum
@@ -56,7 +63,7 @@ static char *ipsec_input_error_strings[] = {
 
 typedef struct
 {
-  u32 tunnel_index;
+  u32 sa_id;
   u32 spi;
   u32 seq;
 } ipsec_input_trace_t;
@@ -69,15 +76,19 @@ format_ipsec_input_trace (u8 * s, va_list * args)
   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
   ipsec_input_trace_t *t = va_arg (*args, ipsec_input_trace_t *);
 
-  if (t->tunnel_index != ~0)
+  if (t->spi == 0 && t->seq == 0)
+    {
+      s = format (s, "esp: no esp packet");
+      return s;
+    }
+
+  if (t->sa_id != 0)
     {
-      s =
-       format (s, "esp: tunnel %u spi %u seq %u", t->tunnel_index, t->spi,
-               t->seq);
+      s = format (s, "esp: sa_id %u spi %u seq %u", t->sa_id, t->spi, t->seq);
     }
   else
     {
-      s = format (s, "esp: no tunnel spi %u seq %u", t->spi, t->seq);
+      s = format (s, "esp: no sa spi %u seq %u", t->spi, t->seq);
     }
   return s;
 }
@@ -183,9 +194,6 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm,
                         vlib_node_runtime_t * node,
                         vlib_frame_t * from_frame)
 {
-  ip4_main_t *i4m = &ip4_main;
-  ip_lookup_main_t *lm = &i4m->lookup_main;
-  ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST];
   u32 n_left_from, *from, next_index, *to_next;
   ipsec_main_t *im = &ipsec_main;
 
@@ -207,8 +215,8 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm,
          ip4_header_t *ip0;
          esp_header_t *esp0;
          ip4_ipsec_config_t *c0;
-         u32 tunnel_index0 = ~0;
          ipsec_spd_t *spd0;
+         ipsec_policy_t *p0 = 0;
 
          bi0 = to_next[0] = from[0];
          from += 1;
@@ -217,9 +225,10 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm,
          n_left_to_next -= 1;
 
          b0 = vlib_get_buffer (vm, bi0);
-         c0 = vnet_get_config_data (&cm->config_main,
-                                    &b0->current_config_index,
-                                    &next0, sizeof (c0[0]));
+         c0 =
+           vnet_feature_next_with_data (vnet_buffer (b0)->sw_if_index
+                                        [VLIB_RX], &next0, b0,
+                                        sizeof (c0[0]));
 
          spd0 = pool_elt_at_index (im->spds, c0->spd_index);
 
@@ -236,7 +245,7 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm,
                 clib_net_to_host_u32 (esp0->spi),
                 clib_net_to_host_u16 (ip0->length), spd0->id);
 #endif
-             ipsec_policy_t *p0;
+
              p0 = ipsec_input_protect_policy_match (spd0,
                                                     clib_net_to_host_u32
                                                     (ip0->src_address.
@@ -251,8 +260,8 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm,
                {
                  p0->counter.packets++;
                  p0->counter.bytes += clib_net_to_host_u16 (ip0->length);
-                 vnet_buffer (b0)->output_features.ipsec_sad_index =
-                   p0->sa_index;
+                 vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
+                 vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = IPSEC_INPUT_NEXT_ESP_DECRYPT;
                  vlib_buffer_advance (b0, ip4_header_bytes (ip0));
                  goto trace0;
@@ -266,9 +275,13 @@ ipsec_input_ip4_node_fn (vlib_main_t * vm,
            {
              ipsec_input_trace_t *tr =
                vlib_add_trace (vm, node, b0, sizeof (*tr));
-             tr->tunnel_index = tunnel_index0;
-             tr->spi = clib_host_to_net_u32 (esp0->spi);
-             tr->seq = clib_host_to_net_u32 (esp0->seq);
+             if (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)
+               {
+                 if (p0)
+                   tr->sa_id = p0->sa_id;
+                 tr->spi = clib_host_to_net_u32 (esp0->spi);
+                 tr->seq = clib_host_to_net_u32 (esp0->seq);
+               }
            }
 
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
@@ -313,9 +326,6 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
                                vlib_node_runtime_t * node,
                                vlib_frame_t * from_frame)
 {
-  ip6_main_t *i6m = &ip6_main;
-  ip_lookup_main_t *lm = &i6m->lookup_main;
-  ip_config_main_t *cm = &lm->rx_config_mains[VNET_UNICAST];
   u32 n_left_from, *from, next_index, *to_next;
   ipsec_main_t *im = &ipsec_main;
 
@@ -337,8 +347,8 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
          ip6_header_t *ip0;
          esp_header_t *esp0;
          ip4_ipsec_config_t *c0;
-         u32 tunnel_index0 = ~0;
          ipsec_spd_t *spd0;
+         ipsec_policy_t *p0 = 0;
          u32 header_size = sizeof (ip0[0]);
 
          bi0 = to_next[0] = from[0];
@@ -348,9 +358,10 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
          n_left_to_next -= 1;
 
          b0 = vlib_get_buffer (vm, bi0);
-         c0 = vnet_get_config_data (&cm->config_main,
-                                    &b0->current_config_index,
-                                    &next0, sizeof (c0[0]));
+         c0 =
+           vnet_feature_next_with_data (vnet_buffer (b0)->sw_if_index
+                                        [VLIB_RX], &next0, b0,
+                                        sizeof (c0[0]));
 
          spd0 = pool_elt_at_index (im->spds, c0->spd_index);
 
@@ -367,7 +378,6 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
                 clib_net_to_host_u16 (ip0->payload_length) + header_size,
                 spd0->id);
 #endif
-             ipsec_policy_t *p0;
              p0 = ipsec_input_ip6_protect_policy_match (spd0,
                                                         &ip0->src_address,
                                                         &ip0->dst_address,
@@ -380,8 +390,8 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
                  p0->counter.bytes +=
                    clib_net_to_host_u16 (ip0->payload_length);
                  p0->counter.bytes += header_size;
-                 vnet_buffer (b0)->output_features.ipsec_sad_index =
-                   p0->sa_index;
+                 vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
+                 vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = IPSEC_INPUT_NEXT_ESP_DECRYPT;
                  vlib_buffer_advance (b0, header_size);
                  goto trace0;
@@ -393,9 +403,13 @@ VLIB_NODE_FUNCTION_MULTIARCH (ipsec_input_ip4_node, ipsec_input_ip4_node_fn)
            {
              ipsec_input_trace_t *tr =
                vlib_add_trace (vm, node, b0, sizeof (*tr));
-             tr->tunnel_index = tunnel_index0;
-             tr->spi = clib_host_to_net_u32 (esp0->spi);
-             tr->seq = clib_host_to_net_u32 (esp0->seq);
+             if (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)
+               {
+                 if (p0)
+                   tr->sa_id = p0->sa_id;
+                 tr->spi = clib_host_to_net_u32 (esp0->spi);
+                 tr->seq = clib_host_to_net_u32 (esp0->seq);
+               }
            }
 
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,