IPSEC: move SA counters into the stats segment

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>
This commit is contained in:
Neale Ranns
2019-02-17 18:04:27 +00:00
committed by Damjan Marion
parent 684586786e
commit eba31ecebe
18 changed files with 174 additions and 72 deletions
+7 -2
View 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)
{
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;
@@ -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;
thread_index = vm->thread_index;
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;
vlib_prefetch_combined_counter (&ipsec_sa_counters,
thread_index, sa_index0);
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 */
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;
+5 -2
View 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)
{
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;
@@ -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;
thread_index = vm->thread_index;
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 */
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;
+2 -5
View 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 "
"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),
@@ -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),
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
@@ -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_uint (node, "total_data_size",
clib_net_to_host_u64 (mp->total_data_size));
}
static int
+8 -2
View 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)
{
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);
@@ -89,6 +89,7 @@ ah_decrypt_inline (vlib_main_t * vm,
int icv_size = 0;
next_index = node->cached_next_index;
thread_index = vm->thread_index;
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);
vlib_prefetch_combined_counter (&ipsec_sa_counters,
thread_index, sa_index0);
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))
+5 -4
View 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)
{
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;
thread_index = vm->thread_index;
while (n_left_from > 0)
{
@@ -131,9 +132,9 @@ ah_encrypt_inline (vlib_main_t * vm,
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);
+3 -1
View 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))
{
+6 -2
View 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);
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",
@@ -195,8 +198,6 @@ esp_encrypt_inline (vlib_main_t * vm,
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];
@@ -330,6 +331,9 @@ esp_encrypt_inline (vlib_main_t * vm,
}
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))
{
+4 -1
View 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);
vlib_counter_t counts;
/* 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* */
}
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
&& ipsec_sa->total_data_size > fsa->profile->lifetime_maxdata)
&& counts.bytes > fsa->profile->lifetime_maxdata)
{
fchild->time_to_expiration = now;
}
+7 -1
View 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
*/
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;
};
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
+8 -4
View 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;
u32 id, spi;
u32 id, spi, sa_index;
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,
0, &tun_src, &tun_dst, NULL);
0, &tun_src, &tun_dst, &sa_index);
else
rv = ipsec_sa_del (id);
@@ -399,7 +399,12 @@ static void vl_api_ipsec_sad_entry_add_del_t_handler
#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
@@ -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);
mp->total_data_size = clib_host_to_net_u64 (sa->total_data_size);
vl_api_send_msg (reg, (u8 *) mp);
}
+1
View 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_clear_combined_counters (&ipsec_sa_counters);
return (NULL);
}
+3
View 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;
vlib_counter_t counts;
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);
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)
{
+14
View File
@@ -16,6 +16,16 @@
#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)
@@ -106,8 +116,12 @@ ipsec_sa_add (u32 id,
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->stat_index = sa_index;
sa->protocol = proto;
sa->crypto_alg = crypto_alg;
clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key));
+7 -3
View File
@@ -101,6 +101,7 @@ typedef struct
fib_node_t node;
u32 id;
u32 spi;
u32 stat_index;
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;
/* lifetime data */
u64 total_data_size;
} 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,
+36
View File
@@ -304,6 +304,15 @@ class IpsecTraTests(object):
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)
@@ -333,6 +342,14 @@ class IpsecTraTests(object):
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)
@@ -385,6 +402,17 @@ class IpsecTun4Tests(object):
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)
@@ -433,6 +461,14 @@ class IpsecTun6Tests(object):
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)
+26 -22
View File
@@ -86,18 +86,20 @@ class TemplateIpsecAh(TemplateIpsec):
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,
@@ -161,16 +163,18 @@ class TemplateIpsecAh(TemplateIpsec):
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,
+26 -22
View File
@@ -97,18 +97,20 @@ class TemplateIpsecEsp(TemplateIpsec):
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,
@@ -172,16 +174,18 @@ class TemplateIpsecEsp(TemplateIpsec):
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,
+6 -1
View File
@@ -213,7 +213,7 @@ class VppIpsecSA(VppObject):
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,
@@ -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.stat_index = r.stat_index
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
def get_stats(self):
c = self.test.statistics.get_counter("/net/ipsec/sa")
return c[0][self.stat_index]