diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/vnet/bfd/bfd_udp.c | 17 | ||||
-rw-r--r-- | src/vnet/bonding/cli.c | 39 | ||||
-rw-r--r-- | src/vnet/devices/devices.c | 25 | ||||
-rw-r--r-- | src/vnet/interface/stats.c | 95 |
5 files changed, 147 insertions, 30 deletions
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 88ef4cca7b9..1cd5b58f85a 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -41,6 +41,7 @@ list(APPEND VNET_SOURCES interface/tx_queue.c interface/runtime.c interface/monitor.c + interface/stats.c interface_stats.c misc.c ) diff --git a/src/vnet/bfd/bfd_udp.c b/src/vnet/bfd/bfd_udp.c index 074d546c37b..c89dd7cfa4d 100644 --- a/src/vnet/bfd/bfd_udp.c +++ b/src/vnet/bfd/bfd_udp.c @@ -35,7 +35,7 @@ #include <vnet/dpo/receive_dpo.h> #include <vnet/fib/fib_entry.h> #include <vnet/fib/fib_table.h> -#include <vpp/stats/stat_segment.h> +#include <vlib/stats/stats.h> #include <vnet/bfd/bfd_debug.h> #include <vnet/bfd/bfd_udp.h> #include <vnet/bfd/bfd_main.h> @@ -85,9 +85,9 @@ bfd_udp_main_t bfd_udp_main; void bfd_udp_update_stat_segment_entry (u32 entry, u64 value) { - vlib_stat_segment_lock (); - stat_segment_set_state_counter (entry, value); - vlib_stat_segment_unlock (); + vlib_stats_segment_lock (); + vlib_stats_set_gauge (entry, value); + vlib_stats_segment_unlock (); } vnet_api_error_t @@ -1694,19 +1694,18 @@ clib_error_t * bfd_udp_stats_init (bfd_udp_main_t *bum) { const char *name4 = "/bfd/udp4/sessions"; - bum->udp4_sessions_count_stat_seg_entry = - stat_segment_new_entry ((u8 *) name4, STAT_DIR_TYPE_SCALAR_INDEX); + bum->udp4_sessions_count_stat_seg_entry = vlib_stats_add_gauge ("%s", name4); - stat_segment_set_state_counter (bum->udp4_sessions_count_stat_seg_entry, 0); + vlib_stats_set_gauge (bum->udp4_sessions_count_stat_seg_entry, 0); if (~0 == bum->udp4_sessions_count_stat_seg_entry) { return clib_error_return ( 0, "Could not create stat segment entry for %s", name4); } const char *name6 = "/bfd/udp6/sessions"; - bum->udp6_sessions_count_stat_seg_entry = - stat_segment_new_entry ((u8 *) name6, STAT_DIR_TYPE_SCALAR_INDEX); + bum->udp6_sessions_count_stat_seg_entry = vlib_stats_add_gauge ("%s", name6); + vlib_stats_set_gauge (bum->udp6_sessions_count_stat_seg_entry, 0); if (~0 == bum->udp6_sessions_count_stat_seg_entry) { return clib_error_return ( diff --git a/src/vnet/bonding/cli.c b/src/vnet/bonding/cli.c index c3593ab663e..b0ded4734dd 100644 --- a/src/vnet/bonding/cli.c +++ b/src/vnet/bonding/cli.c @@ -20,7 +20,7 @@ #include <vlib/unix/unix.h> #include <vnet/ethernet/ethernet.h> #include <vnet/bonding/node.h> -#include <vpp/stats/stat_segment.h> +#include <vlib/stats/stats.h> void bond_disable_collecting_distributing (vlib_main_t * vm, member_if_t * mif) @@ -323,10 +323,10 @@ bond_delete_neighbor (vlib_main_t * vm, bond_if_t * bif, member_if_t * mif) if (bif->mode == BOND_MODE_LACP) { - stat_segment_deregister_state_counter - (bm->stats[bif->sw_if_index][mif->sw_if_index].actor_state); - stat_segment_deregister_state_counter - (bm->stats[bif->sw_if_index][mif->sw_if_index].partner_state); + vlib_stats_remove_entry ( + bm->stats[bif->sw_if_index][mif->sw_if_index].actor_state); + vlib_stats_remove_entry ( + bm->stats[bif->sw_if_index][mif->sw_if_index].partner_state); } pool_put (bm->neighbors, mif); @@ -650,32 +650,29 @@ bond_add_member (vlib_main_t * vm, bond_add_member_args_t * args) } if (bif->mode == BOND_MODE_LACP) { - u8 *name = format (0, "/if/lacp/%u/%u/state%c", bif->sw_if_index, - args->member, 0); + u32 actor_idx, partner_idx; - vec_validate (bm->stats, bif->sw_if_index); - vec_validate (bm->stats[bif->sw_if_index], args->member); - - args->error = stat_segment_register_state_counter - (name, &bm->stats[bif->sw_if_index][args->member].actor_state); - if (args->error != 0) + actor_idx = vlib_stats_add_gauge ("/if/lacp/%u/%u/state", + bif->sw_if_index, args->member); + if (actor_idx == ~0) { args->rv = VNET_API_ERROR_INVALID_INTERFACE; - vec_free (name); return; } - vec_reset_length (name); - name = format (0, "/if/lacp/%u/%u/partner-state%c", bif->sw_if_index, - args->member, 0); - args->error = stat_segment_register_state_counter - (name, &bm->stats[bif->sw_if_index][args->member].partner_state); - vec_free (name); - if (args->error != 0) + partner_idx = vlib_stats_add_gauge ("/if/lacp/%u/%u/partner-state", + bif->sw_if_index, args->member); + if (partner_idx == ~0) { + vlib_stats_remove_entry (actor_idx); args->rv = VNET_API_ERROR_INVALID_INTERFACE; return; } + + vec_validate (bm->stats, bif->sw_if_index); + vec_validate (bm->stats[bif->sw_if_index], args->member); + bm->stats[bif->sw_if_index][args->member].actor_state = actor_idx; + bm->stats[bif->sw_if_index][args->member].partner_state = partner_idx; } pool_get (bm->neighbors, mif); diff --git a/src/vnet/devices/devices.c b/src/vnet/devices/devices.c index 5c28cadc03c..1a4f02df6a8 100644 --- a/src/vnet/devices/devices.c +++ b/src/vnet/devices/devices.c @@ -18,6 +18,7 @@ #include <vnet/feature/feature.h> #include <vnet/ip/ip.h> #include <vnet/ethernet/ethernet.h> +#include <vlib/stats/stats.h> vnet_device_main_t vnet_device_main; @@ -101,12 +102,30 @@ VNET_FEATURE_INIT (ethernet_input, static) = { }; /* *INDENT-ON* */ +static void +input_rate_collector_fn (vlib_stats_collector_data_t *d) +{ + vlib_stats_segment_t *sm = vlib_stats_get_segment (); + vlib_stats_entry_t *e2 = sm->directory_vector + d->private_data; + static u64 last_input_packets = 0; + f64 dt, now; + + now = vlib_time_now (vlib_get_main ()); + u64 input_packets = vnet_get_aggregate_rx_packets (); + + dt = now - e2->value; + d->entry->value = (f64) (input_packets - last_input_packets) / dt; + last_input_packets = input_packets; + e2->value = now; +} + static clib_error_t * vnet_device_init (vlib_main_t * vm) { vnet_device_main_t *vdm = &vnet_device_main; vlib_thread_main_t *tm = vlib_get_thread_main (); vlib_thread_registration_t *tr; + vlib_stats_collector_reg_t reg = {}; uword *p; vec_validate_aligned (vdm->workers, tm->n_vlib_mains - 1, @@ -120,6 +139,12 @@ vnet_device_init (vlib_main_t * vm) vdm->next_worker_thread_index = tr->first_index; vdm->last_worker_thread_index = tr->first_index + tr->count - 1; } + + reg.private_data = vlib_stats_add_timestamp ("/sys/last_update"); + reg.entry_index = vlib_stats_add_gauge ("/sys/input_rate"); + reg.collect_fn = input_rate_collector_fn; + vlib_stats_register_collector_fn (®); + return 0; } diff --git a/src/vnet/interface/stats.c b/src/vnet/interface/stats.c new file mode 100644 index 00000000000..55e49eb1bc2 --- /dev/null +++ b/src/vnet/interface/stats.c @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright(c) 2022 Cisco Systems, Inc. + */ + +#include <vlib/vlib.h> +#include <vlib/unix/unix.h> +#include <vlib/stats/stats.h> +#include <vnet/vnet.h> +#include <vnet/devices/devices.h> /* vnet_get_aggregate_rx_packets */ +#include <vnet/interface.h> + +static u32 if_names_stats_entry_index = ~0; +static u32 **dir_entry_indices = 0; + +static struct +{ + char *prefix, *name; + u32 index; +} if_counters[] = { +#define _(e, n, p) { .prefix = #p, .name = #n }, + foreach_simple_interface_counter_name foreach_combined_interface_counter_name +#undef _ +}; + +static clib_error_t * +statseg_sw_interface_add_del (vnet_main_t *vnm, u32 sw_if_index, u32 is_add) +{ + vlib_stats_segment_t *sm = vlib_stats_get_segment (); + vlib_stats_entry_t *e; + void *oldheap; + + if (if_names_stats_entry_index == ~0) + { + if_names_stats_entry_index = vlib_stats_add_string_vector ("/if/names"); + + for (int i = 0; i < ARRAY_LEN (if_counters); i++) + if_counters[i].index = vlib_stats_find_entry_index ( + "/%s/%s", if_counters[i].prefix, if_counters[i].name); + } + + e = sm->directory_vector + if_names_stats_entry_index; + + vec_validate (dir_entry_indices, sw_if_index); + + vlib_stats_segment_lock (); + + if (is_add) + { + vnet_sw_interface_t *si, *si_sup; + vnet_hw_interface_t *hi_sup; + u8 *s; + + si = vnet_get_sw_interface (vnm, sw_if_index); + si_sup = vnet_get_sup_sw_interface (vnm, si->sw_if_index); + ASSERT (si_sup->type == VNET_SW_INTERFACE_TYPE_HARDWARE); + hi_sup = vnet_get_hw_interface (vnm, si_sup->hw_if_index); + + oldheap = clib_mem_set_heap (sm->heap); + s = format (0, "%v", hi_sup->name); + if (si->type != VNET_SW_INTERFACE_TYPE_HARDWARE) + s = format (s, ".%d", si->sub.id); + s = format (s, "%c", 0); + + vec_validate (e->string_vector, sw_if_index); + + ASSERT (e->string_vector[sw_if_index] == 0); + e->string_vector[sw_if_index] = s; + clib_mem_set_heap (oldheap); + + s = format (0, "/interfaces/%U", format_vlib_stats_symlink, s); + for (u32 index, i = 0; i < ARRAY_LEN (if_counters); i++) + { + index = vlib_stats_add_symlink (if_counters[i].index, sw_if_index, + "%v/%s", s, if_counters[i].name); + ASSERT (index != ~0); + vec_add1 (dir_entry_indices[sw_if_index], index); + } + vec_free (s); + } + else + { + oldheap = clib_mem_set_heap (sm->heap); + vec_free (e->string_vector[sw_if_index]); + clib_mem_set_heap (oldheap); + 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]); + } + + vlib_stats_segment_unlock (); + + return 0; +} + +VNET_SW_INTERFACE_ADD_DEL_FUNCTION (statseg_sw_interface_add_del); |