From ff27c9f8ecb08ff0f5b98332975733e8bab125f1 Mon Sep 17 00:00:00 2001 From: Steven Luong Date: Tue, 20 Jun 2023 22:22:45 -0700 Subject: stats: fix duplicate /if/names entry stats entries /if/names are never deleted as it is a vector of the sw_if_index value. When the interface is deleted and then created again later, and if the new interface takes a different sw_if_index, we may end up with duplicate entries for the same interface name. For example, the following configuration sequence causes problem create loopback interface create loopback interface delete loopback interface intfc loop0 delete loopback interface intfc loop1 create loopback interface vpp_get_stats dump /if/names [0]: local0 /if/names [1]: loop0 /if/names [2]: loop0 /if/names The fix is to set the delete /if/names entry to deleted when the interface is deleted. Type: fix Change-Id: I7d811b12d56e3cf8c7deffe14736ea0f24814d02 Signed-off-by: Steven Luong --- src/vnet/interface/stats.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/vnet/interface') diff --git a/src/vnet/interface/stats.c b/src/vnet/interface/stats.c index f58ffa32586..cb0eda001d7 100644 --- a/src/vnet/interface/stats.c +++ b/src/vnet/interface/stats.c @@ -25,6 +25,8 @@ static struct static clib_error_t * statseg_sw_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add) { + u8 *name; + if (if_names == 0) { if_names = vlib_stats_add_string_vector ("/if/names"); @@ -42,7 +44,6 @@ statseg_sw_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add) { vnet_sw_interface_t *si, *si_sup; vnet_hw_interface_t *hi_sup; - u8 *name; si = vnet_get_sw_interface (vnm, sw_if_index); si_sup = vnet_get_sup_sw_interface (vnm, si->sw_if_index); @@ -57,22 +58,25 @@ statseg_sw_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add) for (u32 index, i = 0; i < ARRAY_LEN (if_counters); i++) { + name = format (0, "%v", hi_sup->name); index = vlib_stats_add_symlink ( if_counters[i].index, sw_if_index, "/interfaces/%U/%s", format_vlib_stats_symlink, name, if_counters[i].name); ASSERT (index != ~0); vec_add1 (dir_entry_indices[sw_if_index], index); } - - vec_free (name); } else { + name = format (0, "%s", "deleted"); + vlib_stats_set_string_vector (&if_names, sw_if_index, "%v", name); for (u32 i = 0; i < vec_len (dir_entry_indices[sw_if_index]); i++) vlib_stats_remove_entry (dir_entry_indices[sw_if_index][i]); vec_free (dir_entry_indices[sw_if_index]); } + vec_free (name); + vlib_stats_segment_unlock (); return 0; -- cgit 1.2.3-korg