IPSEC: move SA counters into the stats segment 31/17631/2
authorNeale Ranns <nranns@cisco.com>
Sun, 17 Feb 2019 18:04:27 +0000 (18:04 +0000)
committerDamjan Marion <dmarion@me.com>
Mon, 18 Feb 2019 13:05:17 +0000 (13:05 +0000)
1) stats are accessed via the stat segment which is more condusive to
   monitoring
2) stats are accurate in the presence of multiple threads. There's no
   guarantee that an SA is access from only one worker.

Change-Id: Id5e217ea253ddfc9480aaedb0d008dea031b1148
Signed-off-by: Neale Ranns <nranns@cisco.com>
18 files changed:
src/plugins/dpdk/ipsec/esp_decrypt.c
src/plugins/dpdk/ipsec/esp_encrypt.c
src/vat/api_format.c
src/vnet/ipsec/ah_decrypt.c
src/vnet/ipsec/ah_encrypt.c
src/vnet/ipsec/esp_decrypt.c
src/vnet/ipsec/esp_encrypt.c
src/vnet/ipsec/ikev2.c
src/vnet/ipsec/ipsec.api
src/vnet/ipsec/ipsec_api.c
src/vnet/ipsec/ipsec_cli.c
src/vnet/ipsec/ipsec_format.c
src/vnet/ipsec/ipsec_sa.c
src/vnet/ipsec/ipsec_sa.h
test/template_ipsec.py
test/test_ipsec_ah.py
test/test_ipsec_esp.py
test/vpp_ipsec.py

index cd35ee7..2004043 100644 (file)
@@ -97,7 +97,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm,
                         vlib_node_runtime_t * node,
                         vlib_frame_t * from_frame, int is_ip6)
 {
                         vlib_node_runtime_t * node,
                         vlib_frame_t * from_frame, int is_ip6)
 {
-  u32 n_left_from, *from, *to_next, next_index;
+  u32 n_left_from, *from, *to_next, next_index, thread_index;
   ipsec_main_t *im = &ipsec_main;
   u32 thread_idx = vlib_get_thread_index ();
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
   ipsec_main_t *im = &ipsec_main;
   u32 thread_idx = vlib_get_thread_index ();
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
@@ -114,6 +114,7 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm,
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
+  thread_index = vm->thread_index;
 
   ret = crypto_alloc_ops (numa, ops, n_left_from);
   if (ret)
 
   ret = crypto_alloc_ops (numa, ops, n_left_from);
   if (ret)
@@ -173,6 +174,8 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm,
          CLIB_PREFETCH (op, op_len, STORE);
 
          sa_index0 = vnet_buffer (b0)->ipsec.sad_index;
          CLIB_PREFETCH (op, op_len, STORE);
 
          sa_index0 = vnet_buffer (b0)->ipsec.sad_index;
+         vlib_prefetch_combined_counter (&ipsec_sa_counters,
+                                         thread_index, sa_index0);
 
          if (sa_index0 != last_sa_index)
            {
 
          if (sa_index0 != last_sa_index)
            {
@@ -266,7 +269,9 @@ dpdk_esp_decrypt_inline (vlib_main_t * vm,
            priv->next = DPDK_CRYPTO_INPUT_NEXT_DECRYPT4_POST;
 
          /* FIXME multi-seg */
            priv->next = DPDK_CRYPTO_INPUT_NEXT_DECRYPT4_POST;
 
          /* FIXME multi-seg */
-         sa0->total_data_size += b0->current_length;
+         vlib_increment_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0,
+            1, b0->current_length);
 
          res->ops[res->n_ops] = op;
          res->bi[res->n_ops] = bi0;
 
          res->ops[res->n_ops] = op;
          res->bi[res->n_ops] = bi0;
index eea99eb..d29ca55 100644 (file)
@@ -112,7 +112,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm,
                         vlib_node_runtime_t * node,
                         vlib_frame_t * from_frame, int is_ip6)
 {
                         vlib_node_runtime_t * node,
                         vlib_frame_t * from_frame, int is_ip6)
 {
-  u32 n_left_from, *from, *to_next, next_index;
+  u32 n_left_from, *from, *to_next, next_index, thread_index;
   ipsec_main_t *im = &ipsec_main;
   u32 thread_idx = vlib_get_thread_index ();
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
   ipsec_main_t *im = &ipsec_main;
   u32 thread_idx = vlib_get_thread_index ();
   dpdk_crypto_main_t *dcm = &dpdk_crypto_main;
@@ -129,6 +129,7 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm,
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
+  thread_index = vm->thread_index;
 
   ret = crypto_alloc_ops (numa, ops, n_left_from);
   if (ret)
 
   ret = crypto_alloc_ops (numa, ops, n_left_from);
   if (ret)
@@ -280,7 +281,9 @@ dpdk_esp_encrypt_inline (vlib_main_t * vm,
          orig_sz = b0->current_length;
 
          /* TODO multi-seg support - total_length_not_including_first_buffer */
          orig_sz = b0->current_length;
 
          /* TODO multi-seg support - total_length_not_including_first_buffer */
-         sa0->total_data_size += b0->current_length;
+         vlib_increment_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0,
+            1, b0->current_length);
 
          res->ops[res->n_ops] = op;
          res->bi[res->n_ops] = bi0;
 
          res->ops[res->n_ops] = op;
          res->bi[res->n_ops] = bi0;
index 1d93cc1..daeec50 100644 (file)
@@ -15218,7 +15218,7 @@ vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
         "crypto_key %U integ_alg %u integ_key %U flags %x "
         "tunnel_src_addr %U tunnel_dst_addr %U "
         "salt %u seq_outbound %lu last_seq_inbound %lu "
         "crypto_key %U integ_alg %u integ_key %U flags %x "
         "tunnel_src_addr %U tunnel_dst_addr %U "
         "salt %u seq_outbound %lu last_seq_inbound %lu "
-        "replay_window %lu total_data_size %lu\n",
+        "replay_window %lu\n",
         ntohl (mp->entry.sad_id),
         ntohl (mp->sw_if_index),
         ntohl (mp->entry.spi),
         ntohl (mp->entry.sad_id),
         ntohl (mp->sw_if_index),
         ntohl (mp->entry.spi),
@@ -15232,8 +15232,7 @@ vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
         &mp->entry.tunnel_dst, ntohl (mp->salt),
         clib_net_to_host_u64 (mp->seq_outbound),
         clib_net_to_host_u64 (mp->last_seq_inbound),
         &mp->entry.tunnel_dst, ntohl (mp->salt),
         clib_net_to_host_u64 (mp->seq_outbound),
         clib_net_to_host_u64 (mp->last_seq_inbound),
-        clib_net_to_host_u64 (mp->replay_window),
-        clib_net_to_host_u64 (mp->total_data_size));
+        clib_net_to_host_u64 (mp->replay_window));
 }
 
 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
 }
 
 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
@@ -15302,8 +15301,6 @@ static void vl_api_ipsec_sa_details_t_handler_json
   vat_json_object_add_address (node, &mp->entry.tunnel_dst);
   vat_json_object_add_uint (node, "replay_window",
                            clib_net_to_host_u64 (mp->replay_window));
   vat_json_object_add_address (node, &mp->entry.tunnel_dst);
   vat_json_object_add_uint (node, "replay_window",
                            clib_net_to_host_u64 (mp->replay_window));
-  vat_json_object_add_uint (node, "total_data_size",
-                           clib_net_to_host_u64 (mp->total_data_size));
 }
 
 static int
 }
 
 static int
index 7d2bf81..629e7f0 100644 (file)
@@ -81,7 +81,7 @@ ah_decrypt_inline (vlib_main_t * vm,
                   vlib_node_runtime_t * node, vlib_frame_t * from_frame,
                   int is_ip6)
 {
                   vlib_node_runtime_t * node, vlib_frame_t * from_frame,
                   int is_ip6)
 {
-  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;
   ipsec_proto_main_t *em = &ipsec_proto_main;
   from = vlib_frame_vector_args (from_frame);
   ipsec_main_t *im = &ipsec_main;
   ipsec_proto_main_t *em = &ipsec_proto_main;
   from = vlib_frame_vector_args (from_frame);
@@ -89,6 +89,7 @@ ah_decrypt_inline (vlib_main_t * vm,
   int icv_size = 0;
 
   next_index = node->cached_next_index;
   int icv_size = 0;
 
   next_index = node->cached_next_index;
+  thread_index = vm->thread_index;
 
   while (n_left_from > 0)
     {
 
   while (n_left_from > 0)
     {
@@ -131,6 +132,9 @@ ah_decrypt_inline (vlib_main_t * vm,
          sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
          sa0 = pool_elt_at_index (im->sad, sa_index0);
 
          sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
          sa0 = pool_elt_at_index (im->sad, sa_index0);
 
+         vlib_prefetch_combined_counter (&ipsec_sa_counters,
+                                         thread_index, sa_index0);
+
          if (is_ip6)
            {
              ip6_ext_header_t *prev = NULL;
          if (is_ip6)
            {
              ip6_ext_header_t *prev = NULL;
@@ -164,8 +168,10 @@ ah_decrypt_inline (vlib_main_t * vm,
                }
            }
 
                }
            }
 
+         vlib_increment_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0,
+            1, i_b0->current_length);
 
 
-         sa0->total_data_size += i_b0->current_length;
          icv_size =
            em->ipsec_proto_main_integ_algs[sa0->integ_alg].trunc_size;
          if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
          icv_size =
            em->ipsec_proto_main_integ_algs[sa0->integ_alg].trunc_size;
          if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
index 6628609..5f6a099 100644 (file)
@@ -84,13 +84,14 @@ ah_encrypt_inline (vlib_main_t * vm,
                   vlib_node_runtime_t * node, vlib_frame_t * from_frame,
                   int is_ip6)
 {
                   vlib_node_runtime_t * node, vlib_frame_t * from_frame,
                   int is_ip6)
 {
-  u32 n_left_from, *from, *to_next = 0, next_index;
+  u32 n_left_from, *from, *to_next = 0, next_index, thread_index;
   int icv_size = 0;
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
   ipsec_main_t *im = &ipsec_main;
   ipsec_proto_main_t *em = &ipsec_proto_main;
   next_index = node->cached_next_index;
   int icv_size = 0;
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
   ipsec_main_t *im = &ipsec_main;
   ipsec_proto_main_t *em = &ipsec_proto_main;
   next_index = node->cached_next_index;
+  thread_index = vm->thread_index;
 
   while (n_left_from > 0)
     {
 
   while (n_left_from > 0)
     {
@@ -131,9 +132,9 @@ ah_encrypt_inline (vlib_main_t * vm,
                                           AH_ENCRYPT_ERROR_SEQ_CYCLED, 1);
              goto trace;
            }
                                           AH_ENCRYPT_ERROR_SEQ_CYCLED, 1);
              goto trace;
            }
-
-
-         sa0->total_data_size += i_b0->current_length;
+         vlib_increment_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0,
+            1, i_b0->current_length);
 
          ssize_t adv;
          ih0 = vlib_buffer_get_current (i_b0);
 
          ssize_t adv;
          ih0 = vlib_buffer_get_current (i_b0);
index 5a3ccdc..0cf31ff 100644 (file)
@@ -193,7 +193,9 @@ esp_decrypt_inline (vlib_main_t * vm,
                }
            }
 
                }
            }
 
-         sa0->total_data_size += i_b0->current_length;
+         vlib_increment_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0,
+            1, i_b0->current_length);
 
          if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
            {
 
          if (PREDICT_TRUE (sa0->integ_alg != IPSEC_INTEG_ALG_NONE))
            {
index e169043..ffa0211 100644 (file)
@@ -182,6 +182,9 @@ esp_encrypt_inline (vlib_main_t * vm,
          sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
          sa0 = pool_elt_at_index (im->sad, sa_index0);
 
          sa_index0 = vnet_buffer (i_b0)->ipsec.sad_index;
          sa0 = pool_elt_at_index (im->sad, sa_index0);
 
+         vlib_prefetch_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0);
+
          if (PREDICT_FALSE (esp_seq_advance (sa0)))
            {
              clib_warning ("sequence number counter has cycled SPI %u",
          if (PREDICT_FALSE (esp_seq_advance (sa0)))
            {
              clib_warning ("sequence number counter has cycled SPI %u",
@@ -195,8 +198,6 @@ esp_encrypt_inline (vlib_main_t * vm,
              goto trace;
            }
 
              goto trace;
            }
 
-         sa0->total_data_size += i_b0->current_length;
-
          /* grab free buffer */
          last_empty_buffer = vec_len (empty_buffers) - 1;
          o_bi0 = empty_buffers[last_empty_buffer];
          /* grab free buffer */
          last_empty_buffer = vec_len (empty_buffers) - 1;
          o_bi0 = empty_buffers[last_empty_buffer];
@@ -330,6 +331,9 @@ esp_encrypt_inline (vlib_main_t * vm,
            }
 
          ASSERT (sa0->crypto_alg < IPSEC_CRYPTO_N_ALG);
            }
 
          ASSERT (sa0->crypto_alg < IPSEC_CRYPTO_N_ALG);
+         vlib_increment_combined_counter
+           (&ipsec_sa_counters, thread_index, sa_index0,
+            1, i_b0->current_length);
 
          if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE))
            {
 
          if (PREDICT_TRUE (sa0->crypto_alg != IPSEC_CRYPTO_ALG_NONE))
            {
index 3d5c0f7..d85feee 100644 (file)
@@ -3376,6 +3376,7 @@ ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa)
   ikev2_sa_t *fsa = 0;
   ikev2_child_sa_t *fchild = 0;
   f64 now = vlib_time_now (vm);
   ikev2_sa_t *fsa = 0;
   ikev2_child_sa_t *fchild = 0;
   f64 now = vlib_time_now (vm);
+  vlib_counter_t counts;
 
   /* Search for the SA and child SA */
   vec_foreach (tkm, km->per_thread_data)
 
   /* Search for the SA and child SA */
   vec_foreach (tkm, km->per_thread_data)
@@ -3394,11 +3395,13 @@ ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa)
     }));
     /* *INDENT-ON* */
   }
     }));
     /* *INDENT-ON* */
   }
+  vlib_get_combined_counter (&ipsec_sa_counters,
+                            ipsec_sa->stat_index, &counts);
 
   if (fchild && fsa && fsa->profile && fsa->profile->lifetime_maxdata)
     {
       if (!fchild->is_expired
 
   if (fchild && fsa && fsa->profile && fsa->profile->lifetime_maxdata)
     {
       if (!fchild->is_expired
-         && ipsec_sa->total_data_size > fsa->profile->lifetime_maxdata)
+         && counts.bytes > fsa->profile->lifetime_maxdata)
        {
          fchild->time_to_expiration = now;
        }
        {
          fchild->time_to_expiration = now;
        }
index ece0b02..91d21d4 100644 (file)
@@ -293,13 +293,19 @@ typedef ipsec_sad_entry
     @param context - sender context, to match reply w/ request
     @param entry - Entry to add or delete
  */
     @param context - sender context, to match reply w/ request
     @param entry - Entry to add or delete
  */
-autoreply define ipsec_sad_entry_add_del
+define ipsec_sad_entry_add_del
 {
   u32 client_index;
   u32 context;
   u8 is_add;
   vl_api_ipsec_sad_entry_t entry;
 };
 {
   u32 client_index;
   u32 context;
   u8 is_add;
   vl_api_ipsec_sad_entry_t entry;
 };
+define ipsec_sad_entry_add_del_reply
+{
+  u32 context;
+  i32 retval;
+  u32 stat_index;
+};
 
 /** \brief IPsec: Update Security Association keys
     @param client_index - opaque cookie to identify the sender
 
 /** \brief IPsec: Update Security Association keys
     @param client_index - opaque cookie to identify the sender
index 2d464b3..a26f486 100644 (file)
@@ -354,7 +354,7 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler
   ipsec_integ_alg_t integ_alg;
   ipsec_protocol_t proto;
   ipsec_sa_flags_t flags;
   ipsec_integ_alg_t integ_alg;
   ipsec_protocol_t proto;
   ipsec_sa_flags_t flags;
-  u32 id, spi;
+  u32 id, spi, sa_index;
   int rv;
 
 #if WITH_LIBSSL > 0
   int rv;
 
 #if WITH_LIBSSL > 0
@@ -390,7 +390,7 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler
     rv = ipsec_sa_add (id, spi, proto,
                       crypto_alg, &crypto_key,
                       integ_alg, &integ_key, flags,
     rv = ipsec_sa_add (id, spi, proto,
                       crypto_alg, &crypto_key,
                       integ_alg, &integ_key, flags,
-                      0, &tun_src, &tun_dst, NULL);
+                      0, &tun_src, &tun_dst, &sa_index);
   else
     rv = ipsec_sa_del (id);
 
   else
     rv = ipsec_sa_del (id);
 
@@ -399,7 +399,12 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler
 #endif
 
 out:
 #endif
 
 out:
-  REPLY_MACRO (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY);
+  /* *INDENT-OFF* */
+  REPLY_MACRO2 (VL_API_IPSEC_SAD_ENTRY_ADD_DEL_REPLY,
+  {
+    rmp->stat_index = htonl (sa_index);
+  });
+  /* *INDENT-ON* */
 }
 
 static void
 }
 
 static void
@@ -708,7 +713,6 @@ send_ipsec_sa_details (ipsec_sa_t * sa, vl_api_registration_t * reg,
     }
   if (sa->use_anti_replay)
     mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
     }
   if (sa->use_anti_replay)
     mp->replay_window = clib_host_to_net_u64 (sa->replay_window);
-  mp->total_data_size = clib_host_to_net_u64 (sa->total_data_size);
 
   vl_api_send_msg (reg, (u8 *) mp);
 }
 
   vl_api_send_msg (reg, (u8 *) mp);
 }
index 52a30a4..22fbcdf 100644 (file)
@@ -594,6 +594,7 @@ clear_ipsec_counters_command_fn (vlib_main_t * vm,
                                 vlib_cli_command_t * cmd)
 {
   vlib_clear_combined_counters (&ipsec_spd_policy_counters);
                                 vlib_cli_command_t * cmd)
 {
   vlib_clear_combined_counters (&ipsec_spd_policy_counters);
+  vlib_clear_combined_counters (&ipsec_sa_counters);
 
   return (NULL);
 }
 
   return (NULL);
 }
index 04a2a0b..dc66569 100644 (file)
@@ -238,6 +238,7 @@ format_ipsec_sa (u8 * s, va_list * args)
 {
   u32 sai = va_arg (*args, u32);
   ipsec_main_t *im = &ipsec_main;
 {
   u32 sai = va_arg (*args, u32);
   ipsec_main_t *im = &ipsec_main;
+  vlib_counter_t counts;
   u32 tx_table_id;
   ipsec_sa_t *sa;
 
   u32 tx_table_id;
   ipsec_sa_t *sa;
 
@@ -261,6 +262,8 @@ format_ipsec_sa (u8 * s, va_list * args)
   s = format (s, "\n   integrity alg %U%s%U",
              format_ipsec_integ_alg, sa->integ_alg,
              sa->integ_alg ? " key " : "", format_ipsec_key, &sa->integ_key);
   s = format (s, "\n   integrity alg %U%s%U",
              format_ipsec_integ_alg, sa->integ_alg,
              sa->integ_alg ? " key " : "", format_ipsec_key, &sa->integ_key);
+  vlib_get_combined_counter (&ipsec_sa_counters, sai, &counts);
+  s = format (s, "\n   packets %u bytes %u", counts.packets, counts.bytes);
 
   if (sa->is_tunnel)
     {
 
   if (sa->is_tunnel)
     {
index c4721c7..fc8520d 100644 (file)
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/fib/fib_table.h>
 
 #include <vnet/ipsec/ipsec.h>
 #include <vnet/fib/fib_table.h>
 
+/**
+ * @brief
+ * SA packet & bytes counters
+ */
+vlib_combined_counter_main_t ipsec_sa_counters = {
+  .name = "SA",
+  .stat_segment_name = "/net/ipsec/sa",
+};
+
+
 static clib_error_t *
 ipsec_call_add_del_callbacks (ipsec_main_t * im, ipsec_sa_t * sa,
                              u32 sa_index, int is_add)
 static clib_error_t *
 ipsec_call_add_del_callbacks (ipsec_main_t * im, ipsec_sa_t * sa,
                              u32 sa_index, int is_add)
@@ -106,8 +116,12 @@ ipsec_sa_add (u32 id,
   fib_node_init (&sa->node, FIB_NODE_TYPE_IPSEC_SA);
   sa_index = sa - im->sad;
 
   fib_node_init (&sa->node, FIB_NODE_TYPE_IPSEC_SA);
   sa_index = sa - im->sad;
 
+  vlib_validate_combined_counter (&ipsec_sa_counters, sa_index);
+  vlib_zero_combined_counter (&ipsec_sa_counters, sa_index);
+
   sa->id = id;
   sa->spi = spi;
   sa->id = id;
   sa->spi = spi;
+  sa->stat_index = sa_index;
   sa->protocol = proto;
   sa->crypto_alg = crypto_alg;
   clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
   sa->protocol = proto;
   sa->crypto_alg = crypto_alg;
   clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
index 2e39566..2601f51 100644 (file)
@@ -101,6 +101,7 @@ typedef struct
   fib_node_t node;
   u32 id;
   u32 spi;
   fib_node_t node;
   u32 id;
   u32 spi;
+  u32 stat_index;
   ipsec_protocol_t protocol;
 
   ipsec_crypto_alg_t crypto_alg;
   ipsec_protocol_t protocol;
 
   ipsec_crypto_alg_t crypto_alg;
@@ -131,11 +132,14 @@ typedef struct
   u32 last_seq;
   u32 last_seq_hi;
   u64 replay_window;
   u32 last_seq;
   u32 last_seq_hi;
   u64 replay_window;
-
-  /* lifetime data */
-  u64 total_data_size;
 } ipsec_sa_t;
 
 } ipsec_sa_t;
 
+/**
+ * @brief
+ * SA packet & bytes counters
+ */
+extern vlib_combined_counter_main_t ipsec_sa_counters;
+
 extern void ipsec_mk_key (ipsec_key_t * key, const u8 * data, u8 len);
 
 extern int ipsec_sa_add (u32 id,
 extern void ipsec_mk_key (ipsec_key_t * key, const u8 * data, u8 len);
 
 extern int ipsec_sa_add (u32 id,
index 77461d4..53b6cec 100644 (file)
@@ -304,6 +304,15 @@ class IpsecTraTests(object):
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
+        pkts = p.tra_sa_in.get_stats()['packets']
+        self.assertEqual(pkts, count,
+                         "incorrect SA in counts: expected %d != %d" %
+                         (count, pkts))
+        pkts = p.tra_sa_out.get_stats()['packets']
+        self.assertEqual(pkts, count,
+                         "incorrect SA out counts: expected %d != %d" %
+                         (count, pkts))
+
         self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tra4_decrypt_node_name, count)
 
         self.assert_packet_counter_equal(self.tra4_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tra4_decrypt_node_name, count)
 
@@ -333,6 +342,14 @@ class IpsecTraTests(object):
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
+        pkts = p.tra_sa_in.get_stats()['packets']
+        self.assertEqual(pkts, count,
+                         "incorrect SA in counts: expected %d != %d" %
+                         (count, pkts))
+        pkts = p.tra_sa_out.get_stats()['packets']
+        self.assertEqual(pkts, count,
+                         "incorrect SA out counts: expected %d != %d" %
+                         (count, pkts))
         self.assert_packet_counter_equal(self.tra6_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tra6_decrypt_node_name, count)
 
         self.assert_packet_counter_equal(self.tra6_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tra6_decrypt_node_name, count)
 
@@ -385,6 +402,17 @@ class IpsecTun4Tests(object):
             self.assertEqual(pkts, count,
                              "incorrect SPD any policy: expected %d != %d" %
                              (count, pkts))
             self.assertEqual(pkts, count,
                              "incorrect SPD any policy: expected %d != %d" %
                              (count, pkts))
+
+        if (hasattr(p, "tun_sa_in")):
+            pkts = p.tun_sa_in.get_stats()['packets']
+            self.assertEqual(pkts, count,
+                             "incorrect SA in counts: expected %d != %d" %
+                             (count, pkts))
+            pkts = p.tun_sa_out.get_stats()['packets']
+            self.assertEqual(pkts, count,
+                             "incorrect SA out counts: expected %d != %d" %
+                             (count, pkts))
+
         self.assert_packet_counter_equal(self.tun4_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tun4_decrypt_node_name, count)
 
         self.assert_packet_counter_equal(self.tun4_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tun4_decrypt_node_name, count)
 
@@ -433,6 +461,14 @@ class IpsecTun6Tests(object):
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
             self.logger.info(self.vapi.ppcli("show error"))
             self.logger.info(self.vapi.ppcli("show ipsec"))
 
+        pkts = p.tun_sa_in.get_stats()['packets']
+        self.assertEqual(pkts, count,
+                         "incorrect SA in counts: expected %d != %d" %
+                         (count, pkts))
+        pkts = p.tun_sa_out.get_stats()['packets']
+        self.assertEqual(pkts, count,
+                         "incorrect SA out counts: expected %d != %d" %
+                         (count, pkts))
         self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tun6_decrypt_node_name, count)
 
         self.assert_packet_counter_equal(self.tun6_encrypt_node_name, count)
         self.assert_packet_counter_equal(self.tun6_decrypt_node_name, count)
 
index f8add0d..f99bb85 100644 (file)
@@ -86,18 +86,20 @@ class TemplateIpsecAh(TemplateIpsec):
         addr_bcast = params.addr_bcast
         e = VppEnum.vl_api_ipsec_spd_action_t
 
         addr_bcast = params.addr_bcast
         e = VppEnum.vl_api_ipsec_spd_action_t
 
-        VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_ah_protocol,
-                   self.tun_if.local_addr[addr_type],
-                   self.tun_if.remote_addr[addr_type]).add_vpp_config()
-        VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_ah_protocol,
-                   self.tun_if.remote_addr[addr_type],
-                   self.tun_if.local_addr[addr_type]).add_vpp_config()
+        params.tun_sa_in = VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi,
+                                      auth_algo_vpp_id, auth_key,
+                                      crypt_algo_vpp_id, crypt_key,
+                                      self.vpp_ah_protocol,
+                                      self.tun_if.local_addr[addr_type],
+                                      self.tun_if.remote_addr[addr_type])
+        params.tun_sa_in.add_vpp_config()
+        params.tun_sa_out = VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi,
+                                       auth_algo_vpp_id, auth_key,
+                                       crypt_algo_vpp_id, crypt_key,
+                                       self.vpp_ah_protocol,
+                                       self.tun_if.remote_addr[addr_type],
+                                       self.tun_if.local_addr[addr_type])
+        params.tun_sa_out.add_vpp_config()
 
         params.spd_policy_in_any = VppIpsecSpdEntry(self, self.tun_spd,
                                                     vpp_tun_sa_id,
 
         params.spd_policy_in_any = VppIpsecSpdEntry(self, self.tun_spd,
                                                     vpp_tun_sa_id,
@@ -161,16 +163,18 @@ class TemplateIpsecAh(TemplateIpsec):
                  IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
         e = VppEnum.vl_api_ipsec_spd_action_t
 
                  IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
         e = VppEnum.vl_api_ipsec_spd_action_t
 
-        VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_ah_protocol,
-                   flags=flags).add_vpp_config()
-        VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_ah_protocol,
-                   flags=flags).add_vpp_config()
+        params.tra_sa_in = VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi,
+                                      auth_algo_vpp_id, auth_key,
+                                      crypt_algo_vpp_id, crypt_key,
+                                      self.vpp_ah_protocol,
+                                      flags=flags)
+        params.tra_sa_in.add_vpp_config()
+        params.tra_sa_out = VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi,
+                                       auth_algo_vpp_id, auth_key,
+                                       crypt_algo_vpp_id, crypt_key,
+                                       self.vpp_ah_protocol,
+                                       flags=flags)
+        params.tra_sa_out.add_vpp_config()
 
         VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
                          addr_any, addr_bcast,
 
         VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
                          addr_any, addr_bcast,
index ba67b60..7a05f0d 100644 (file)
@@ -97,18 +97,20 @@ class TemplateIpsecEsp(TemplateIpsec):
         addr_bcast = params.addr_bcast
         e = VppEnum.vl_api_ipsec_spd_action_t
 
         addr_bcast = params.addr_bcast
         e = VppEnum.vl_api_ipsec_spd_action_t
 
-        VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_esp_protocol,
-                   self.tun_if.local_addr[addr_type],
-                   self.tun_if.remote_addr[addr_type]).add_vpp_config()
-        VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_esp_protocol,
-                   self.tun_if.remote_addr[addr_type],
-                   self.tun_if.local_addr[addr_type]).add_vpp_config()
+        params.tun_sa_in = VppIpsecSA(self, scapy_tun_sa_id, scapy_tun_spi,
+                                      auth_algo_vpp_id, auth_key,
+                                      crypt_algo_vpp_id, crypt_key,
+                                      self.vpp_esp_protocol,
+                                      self.tun_if.local_addr[addr_type],
+                                      self.tun_if.remote_addr[addr_type])
+        params.tun_sa_in.add_vpp_config()
+        params.tun_sa_out = VppIpsecSA(self, vpp_tun_sa_id, vpp_tun_spi,
+                                       auth_algo_vpp_id, auth_key,
+                                       crypt_algo_vpp_id, crypt_key,
+                                       self.vpp_esp_protocol,
+                                       self.tun_if.remote_addr[addr_type],
+                                       self.tun_if.local_addr[addr_type])
+        params.tun_sa_out.add_vpp_config()
 
         params.spd_policy_in_any = VppIpsecSpdEntry(self, self.tun_spd,
                                                     scapy_tun_sa_id,
 
         params.spd_policy_in_any = VppIpsecSpdEntry(self, self.tun_spd,
                                                     scapy_tun_sa_id,
@@ -172,16 +174,18 @@ class TemplateIpsecEsp(TemplateIpsec):
                  IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
         e = VppEnum.vl_api_ipsec_spd_action_t
 
                  IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY)
         e = VppEnum.vl_api_ipsec_spd_action_t
 
-        VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_esp_protocol,
-                   flags=flags).add_vpp_config()
-        VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi,
-                   auth_algo_vpp_id, auth_key,
-                   crypt_algo_vpp_id, crypt_key,
-                   self.vpp_esp_protocol,
-                   flags=flags).add_vpp_config()
+        params.tra_sa_in = VppIpsecSA(self, scapy_tra_sa_id, scapy_tra_spi,
+                                      auth_algo_vpp_id, auth_key,
+                                      crypt_algo_vpp_id, crypt_key,
+                                      self.vpp_esp_protocol,
+                                      flags=flags)
+        params.tra_sa_in.add_vpp_config()
+        params.tra_sa_out = VppIpsecSA(self, vpp_tra_sa_id, vpp_tra_spi,
+                                       auth_algo_vpp_id, auth_key,
+                                       crypt_algo_vpp_id, crypt_key,
+                                       self.vpp_esp_protocol,
+                                       flags=flags)
+        params.tra_sa_out.add_vpp_config()
 
         VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
                          addr_any, addr_bcast,
 
         VppIpsecSpdEntry(self, self.tra_spd, vpp_tra_sa_id,
                          addr_any, addr_bcast,
index 917574e..0241fdf 100644 (file)
@@ -213,7 +213,7 @@ class VppIpsecSA(VppObject):
             self.tun_dst = ip_address(text_type(tun_dst))
 
     def add_vpp_config(self):
             self.tun_dst = ip_address(text_type(tun_dst))
 
     def add_vpp_config(self):
-        self.test.vapi.ipsec_sad_entry_add_del(
+        r = self.test.vapi.ipsec_sad_entry_add_del(
             self.id,
             self.spi,
             self.integ_alg,
             self.id,
             self.spi,
             self.integ_alg,
@@ -224,6 +224,7 @@ class VppIpsecSA(VppObject):
             (self.tun_src if self.tun_src else []),
             (self.tun_dst if self.tun_dst else []),
             flags=self.flags)
             (self.tun_src if self.tun_src else []),
             (self.tun_dst if self.tun_dst else []),
             flags=self.flags)
+        self.stat_index = r.stat_index
         self.test.registry.register(self, self.test.logger)
 
     def remove_vpp_config(self):
         self.test.registry.register(self, self.test.logger)
 
     def remove_vpp_config(self):
@@ -252,3 +253,7 @@ class VppIpsecSA(VppObject):
             if b.entry.sad_id == self.id:
                 return True
         return False
             if b.entry.sad_id == self.id:
                 return True
         return False
+
+    def get_stats(self):
+        c = self.test.statistics.get_counter("/net/ipsec/sa")
+        return c[0][self.stat_index]