IPSEC: SPD counters in the stats sgement
[vpp.git] / src / vnet / ipsec / ipsec_input.c
index 1f3d6d0..e3fd4aa 100644 (file)
@@ -44,7 +44,9 @@ static char *ipsec_input_error_strings[] = {
 
 typedef struct
 {
+  ip_protocol_t proto;
   u32 spd;
+  u32 policy_index;
   u32 sa_id;
   u32 spi;
   u32 seq;
@@ -58,23 +60,10 @@ 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->spi == 0 && t->seq == 0)
-    {
-      s = format (s, "esp: no esp packet");
-      return s;
-    }
+  s = format (s, "%U: sa_id %u spd %u policy %d spi %u seq %u",
+             format_ip_protocol, t->proto, t->sa_id,
+             t->spd, t->policy_index, t->spi, t->seq);
 
-  if (t->sa_id != 0)
-    {
-      s =
-       format (s, "esp: sa_id %u spd %u spi %u seq %u", t->sa_id, t->spd,
-               t->spi, t->seq);
-    }
-  else
-    {
-      s =
-       format (s, "esp: no sa spd %u spi %u seq %u", t->spd, t->spi, t->seq);
-    }
   return s;
 }
 
@@ -86,9 +75,9 @@ ipsec_input_protect_policy_match (ipsec_spd_t * spd, u32 sa, u32 da, u32 spi)
   ipsec_sa_t *s;
   u32 *i;
 
-  vec_foreach (i, spd->ipv4_inbound_protect_policy_indices)
+  vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP4_INBOUND_PROTECT])
   {
-    p = pool_elt_at_index (spd->policies, *i);
+    p = pool_elt_at_index (im->policies, *i);
     s = pool_elt_at_index (im->sad, p->sa_index);
 
     if (spi != s->spi)
@@ -142,9 +131,9 @@ ipsec6_input_protect_policy_match (ipsec_spd_t * spd,
   ipsec_sa_t *s;
   u32 *i;
 
-  vec_foreach (i, spd->ipv6_inbound_protect_policy_indices)
+  vec_foreach (i, spd->policies[IPSEC_SPD_POLICY_IP6_INBOUND_PROTECT])
   {
-    p = pool_elt_at_index (spd->policies, *i);
+    p = pool_elt_at_index (im->policies, *i);
     s = pool_elt_at_index (im->sad, p->sa_index);
 
     if (spi != s->spi)
@@ -178,11 +167,12 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                                  vlib_node_runtime_t * node,
                                  vlib_frame_t * from_frame)
 {
-  u32 n_left_from, *from, next_index, *to_next;
+  u32 n_left_from, *from, next_index, *to_next, thread_index;
   ipsec_main_t *im = &ipsec_main;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
+  thread_index = vm->thread_index;
 
   next_index = node->cached_next_index;
 
@@ -194,7 +184,7 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
 
       while (n_left_from > 0 && n_left_to_next > 0)
        {
-         u32 bi0, next0;
+         u32 bi0, next0, pi0;
          vlib_buffer_t *b0;
          ip4_header_t *ip0;
          esp_header_t *esp0;
@@ -249,37 +239,43 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
                                                     clib_net_to_host_u32
                                                     (esp0->spi));
 
-             if (PREDICT_TRUE (p0 != 0))
+             if (PREDICT_TRUE (p0 != NULL))
                {
-                 p0->counter.packets++;
-                 p0->counter.bytes += clib_net_to_host_u16 (ip0->length);
+                 pi0 = p0 - im->policies;
+                 vlib_increment_combined_counter
+                   (&ipsec_spd_policy_counters,
+                    thread_index, pi0, 1,
+                    clib_net_to_host_u16 (ip0->length));
+
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
                  vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->esp4_decrypt_next_index;
                  vlib_buffer_advance (b0, ((u8 *) esp0 - (u8 *) ip0));
                  goto trace0;
                }
+             else
+               {
+                 pi0 = ~0;
+               };
 
              /* FIXME bypass and discard */
            trace0:
-             if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+             if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
+                 PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
                {
                  ipsec_input_trace_t *tr =
                    vlib_add_trace (vm, node, b0, sizeof (*tr));
-                 if (ip0->protocol == IP_PROTOCOL_IPSEC_ESP ||
-                     ip0->protocol == IP_PROTOCOL_UDP)
-                   {
-                     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);
-                     tr->spd = spd0->id;
-                   }
-               }
 
+                 tr->proto = ip0->protocol;
+                 if (p0)
+                   tr->sa_id = p0->sa_id;
+                 tr->spi = clib_net_to_host_u32 (esp0->spi);
+                 tr->seq = clib_net_to_host_u32 (esp0->seq);
+                 tr->spd = spd0->id;
+                 tr->policy_index = pi0;
+               }
            }
 
-
          if (PREDICT_TRUE (ip0->protocol == IP_PROTOCOL_IPSEC_AH))
            {
              ah0 = (ah_header_t *) ((u8 *) ip0 + ip4_header_bytes (ip0));
@@ -295,27 +291,35 @@ VLIB_NODE_FN (ipsec4_input_node) (vlib_main_t * vm,
 
              if (PREDICT_TRUE (p0 != 0))
                {
-                 p0->counter.packets++;
-                 p0->counter.bytes += clib_net_to_host_u16 (ip0->length);
+                 pi0 = p0 - im->policies;
+                 vlib_increment_combined_counter
+                   (&ipsec_spd_policy_counters,
+                    thread_index, pi0, 1,
+                    clib_net_to_host_u16 (ip0->length));
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
                  vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->ah4_decrypt_next_index;
                  goto trace1;
                }
+             else
+               {
+                 pi0 = ~0;
+               }
              /* FIXME bypass and discard */
            trace1:
-             if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+             if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
+                 PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
                {
                  ipsec_input_trace_t *tr =
                    vlib_add_trace (vm, node, b0, sizeof (*tr));
-                 if (ip0->protocol == IP_PROTOCOL_IPSEC_ESP)
-                   {
-                     if (p0)
-                       tr->sa_id = p0->sa_id;
-                     tr->spi = clib_host_to_net_u32 (ah0->spi);
-                     tr->seq = clib_host_to_net_u32 (ah0->seq_no);
-                     tr->spd = spd0->id;
-                   }
+
+                 tr->proto = ip0->protocol;
+                 if (p0)
+                   tr->sa_id = p0->sa_id;
+                 tr->spi = clib_net_to_host_u32 (ah0->spi);
+                 tr->seq = clib_net_to_host_u32 (ah0->seq_no);
+                 tr->spd = spd0->id;
+                 tr->policy_index = pi0;
                }
            }
 
@@ -359,11 +363,12 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
                                  vlib_node_runtime_t * node,
                                  vlib_frame_t * from_frame)
 {
-  u32 n_left_from, *from, next_index, *to_next;
+  u32 n_left_from, *from, next_index, *to_next, thread_index;
   ipsec_main_t *im = &ipsec_main;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
+  thread_index = vm->thread_index;
 
   next_index = node->cached_next_index;
 
@@ -375,7 +380,7 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
 
       while (n_left_from > 0 && n_left_to_next > 0)
        {
-         u32 bi0, next0;
+         u32 bi0, next0, pi0;
          vlib_buffer_t *b0;
          ip6_header_t *ip0;
          esp_header_t *esp0;
@@ -420,16 +425,22 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
 
              if (PREDICT_TRUE (p0 != 0))
                {
-                 p0->counter.packets++;
-                 p0->counter.bytes +=
-                   clib_net_to_host_u16 (ip0->payload_length);
-                 p0->counter.bytes += header_size;
+                 pi0 = p0 - im->policies;
+                 vlib_increment_combined_counter
+                   (&ipsec_spd_policy_counters,
+                    thread_index, pi0, 1,
+                    clib_net_to_host_u16 (ip0->payload_length) +
+                    header_size);
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
                  vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->esp6_decrypt_next_index;
                  vlib_buffer_advance (b0, header_size);
                  goto trace0;
                }
+             else
+               {
+                 pi0 = ~0;
+               }
            }
          else if (ip0->protocol == IP_PROTOCOL_IPSEC_AH)
            {
@@ -441,30 +452,36 @@ VLIB_NODE_FN (ipsec6_input_node) (vlib_main_t * vm,
 
              if (PREDICT_TRUE (p0 != 0))
                {
-                 p0->counter.packets++;
-                 p0->counter.bytes +=
-                   clib_net_to_host_u16 (ip0->payload_length);
-                 p0->counter.bytes += header_size;
+                 pi0 = p0 - im->policies;
+                 vlib_increment_combined_counter
+                   (&ipsec_spd_policy_counters,
+                    thread_index, pi0, 1,
+                    clib_net_to_host_u16 (ip0->payload_length) +
+                    header_size);
                  vnet_buffer (b0)->ipsec.sad_index = p0->sa_index;
                  vnet_buffer (b0)->ipsec.flags = 0;
                  next0 = im->ah6_decrypt_next_index;
                  goto trace0;
                }
+             else
+               {
+                 pi0 = ~0;
+               }
            }
 
        trace0:
-         if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
+         if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) &&
+             PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
            {
              ipsec_input_trace_t *tr =
                vlib_add_trace (vm, node, b0, sizeof (*tr));
-             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);
-                 tr->spd = spd0->id;
-               }
+
+             if (p0)
+               tr->sa_id = p0->sa_id;
+             tr->proto = ip0->protocol;
+             tr->spi = clib_net_to_host_u32 (esp0->spi);
+             tr->seq = clib_net_to_host_u32 (esp0->seq);
+             tr->spd = spd0->id;
            }
 
          vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,