diff options
author | Steven Luong <sluong@cisco.com> | 2023-06-20 22:22:45 -0700 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2023-07-07 16:55:31 +0000 |
commit | ff27c9f8ecb08ff0f5b98332975733e8bab125f1 (patch) | |
tree | 343fcf4968bbf31039b2c2b9d09e2d18294375b6 | |
parent | becfab0f178ffd21b79404495806a72e1222257f (diff) |
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 <sluong@cisco.com>
-rw-r--r-- | src/vnet/interface/stats.c | 10 |
1 files changed, 7 insertions, 3 deletions
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; |