From 0f09a828ad2dc53d4f1e69de536f3104eaccc4b0 Mon Sep 17 00:00:00 2001 From: Steven Luong Date: Wed, 7 Aug 2019 12:20:22 -0700 Subject: stats: add /if///state for lacp interface state Add /if/lacp///state is a vector of the bond sw_if_index is a vector of the slave sw_if_index Content is the integer value of the lacp actor state. The state is actually a bitfield as described in the lacp protocol spec. Type: feature Signed-off-by: Steven Luong Change-Id: Ic6eca8ce2a1acd2d858e4e50b7eac1d000ea08e5 Signed-off-by: Ole Troan --- src/vnet/bonding/cli.c | 31 +++++++++++++++++-- src/vnet/bonding/node.h | 2 ++ src/vpp/stats/stat_segment.c | 72 +++++++++++++++++++++++++++++++++++++++++++- src/vpp/stats/stat_segment.h | 5 +++ 4 files changed, 107 insertions(+), 3 deletions(-) diff --git a/src/vnet/bonding/cli.c b/src/vnet/bonding/cli.c index f45a31ce99a..4e0d30aa598 100644 --- a/src/vnet/bonding/cli.c +++ b/src/vnet/bonding/cli.c @@ -20,6 +20,7 @@ #include #include #include +#include void bond_disable_collecting_distributing (vlib_main_t * vm, slave_if_t * sif) @@ -96,7 +97,9 @@ bond_disable_collecting_distributing (vlib_main_t * vm, slave_if_t * sif) } clib_spinlock_unlock_if_init (&bif->lockp); - return; + if (bif->mode == BOND_MODE_LACP) + stat_segment_set_state_counter (bm->stats[bif->sw_if_index] + [sif->sw_if_index], sif->actor.state); } void @@ -165,7 +168,9 @@ bond_enable_collecting_distributing (vlib_main_t * vm, slave_if_t * sif) } clib_spinlock_unlock_if_init (&bif->lockp); - return; + if (bif->mode == BOND_MODE_LACP) + stat_segment_set_state_counter (bm->stats[bif->sw_if_index] + [sif->sw_if_index], sif->actor.state); } int @@ -278,6 +283,10 @@ bond_delete_neighbor (vlib_main_t * vm, bond_if_t * bif, slave_if_t * sif) if ((bif->mode == BOND_MODE_LACP) && bm->lacp_enable_disable) (*bm->lacp_enable_disable) (vm, bif, sif, 0); + if (bif->mode == BOND_MODE_LACP) + stat_segment_deregister_state_counter + (bm->stats[bif->sw_if_index][sif->sw_if_index]); + pool_put (bm->neighbors, sif); } @@ -573,6 +582,24 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args) clib_error_return (0, "bond interface cannot be enslaved"); return; } + if (bif->mode == BOND_MODE_LACP) + { + u8 *name = format (0, "/if/lacp/%u/%u/state", bif->sw_if_index, + args->slave); + + vec_validate (bm->stats, bif->sw_if_index); + vec_validate (bm->stats[bif->sw_if_index], args->slave); + + args->error = stat_segment_register_state_counter + (name, &bm->stats[bif->sw_if_index][args->slave]); + vec_free (name); + if (args->error != 0) + { + args->rv = VNET_API_ERROR_INVALID_INTERFACE; + return; + } + } + pool_get (bm->neighbors, sif); clib_memset (sif, 0, sizeof (*sif)); sw = pool_elt_at_index (im->sw_interfaces, args->slave); diff --git a/src/vnet/bonding/node.h b/src/vnet/bonding/node.h index 94b43dcd1d9..1ad19dec872 100644 --- a/src/vnet/bonding/node.h +++ b/src/vnet/bonding/node.h @@ -367,6 +367,8 @@ typedef struct uword *slave_by_sw_if_index; bond_per_thread_data_t *per_thread_data; + + u32 **stats; } bond_main_t; /* bond packet trace capture */ diff --git a/src/vpp/stats/stat_segment.c b/src/vpp/stats/stat_segment.c index bb533d19118..670d0910d26 100644 --- a/src/vpp/stats/stat_segment.c +++ b/src/vpp/stats/stat_segment.c @@ -358,6 +358,10 @@ format_stat_dir_entry (u8 * s, va_list * args) type_name = "ErrIndex"; break; + case STAT_DIR_TYPE_NAME_VECTOR: + type_name = "NameVector"; + break; + default: type_name = "illegal!"; break; @@ -730,7 +734,6 @@ VLIB_INIT_FUNCTION (statseg_init) = }; /* *INDENT-ON* */ - clib_error_t * stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn, u32 caller_index) @@ -774,6 +777,73 @@ stat_segment_register_gauge (u8 * name, stat_segment_update_fn update_fn, return NULL; } +clib_error_t * +stat_segment_register_state_counter (u8 * name, u32 * index) +{ + stat_segment_main_t *sm = &stat_segment_main; + stat_segment_shared_header_t *shared_header = sm->shared_header; + void *oldheap; + stat_segment_directory_entry_t e; + + ASSERT (shared_header); + ASSERT (vlib_get_thread_index () == 0); + + u32 next_vector_index = vec_len (sm->directory_vector); + u32 vector_index = lookup_or_create_hash_index (name, + next_vector_index); + + if (vector_index < next_vector_index) /* Already registered */ + return clib_error_return (0, "%v is already registered", name); + + oldheap = vlib_stats_push_heap (NULL); + vlib_stat_segment_lock (); + + memset (&e, 0, sizeof (e)); + e.type = STAT_DIR_TYPE_SCALAR_INDEX; + + memcpy (e.name, name, vec_len (name)); + vec_add1 (sm->directory_vector, e); + + shared_header->directory_offset = + stat_segment_offset (shared_header, sm->directory_vector); + + vlib_stat_segment_unlock (); + clib_mem_set_heap (oldheap); + + *index = next_vector_index; + return 0; +} + +clib_error_t * +stat_segment_deregister_state_counter (u32 index) +{ + stat_segment_main_t *sm = &stat_segment_main; + stat_segment_shared_header_t *shared_header = sm->shared_header; + stat_segment_directory_entry_t *e; + + ASSERT (shared_header); + + if (index > vec_len (sm->directory_vector)) + return clib_error_return (0, "%u index does not exist", index); + + e = &sm->directory_vector[index]; + if (e->type != STAT_DIR_TYPE_SCALAR_INDEX) + return clib_error_return (0, "%u index cannot be deleted", index); + + hash_unset (sm->directory_vector_by_name, &e->name); + vec_del1 (sm->directory_vector, index); + return 0; +} + +void +stat_segment_set_state_counter (u32 index, u64 value) +{ + stat_segment_main_t *sm = &stat_segment_main; + + ASSERT (index < vec_len (sm->directory_vector)); + sm->directory_vector[index].index = value; +} + static clib_error_t * statseg_config (vlib_main_t * vm, unformat_input_t * input) { diff --git a/src/vpp/stats/stat_segment.h b/src/vpp/stats/stat_segment.h index 5c55cf94ff9..eae6902dc75 100644 --- a/src/vpp/stats/stat_segment.h +++ b/src/vpp/stats/stat_segment.h @@ -107,5 +107,10 @@ extern stat_segment_main_t stat_segment_main; clib_error_t * stat_segment_register_gauge (u8 *names, stat_segment_update_fn update_fn, u32 index); +clib_error_t * +stat_segment_register_state_counter(u8 *name, u32 *index); +clib_error_t * +stat_segment_deregister_state_counter(u32 index); +void stat_segment_set_state_counter (u32 index, u64 value); #endif -- cgit 1.2.3-korg