Stats refactor
- added per-interface simple/combined counters - refactored fib/nbr API to use common registration scheme - refactored "want_stats" and "want_interface" to use per interface registration scheme - fixed issues with SEGV when client disconnects abruptly. Change-Id: Ib701bd8e4105d03548259217bfc809bd738b7c72 Signed-off-by: Keith Burns (alagalah) <alagalah@gmail.com>
This commit is contained in:

committed by
Florin Coras

parent
7c5c40db2a
commit
831fb59f2e
@ -227,16 +227,61 @@ typeonly manual_print manual_endian define vlib_counter
|
||||
u64 bytes; /**< byte counter */
|
||||
};
|
||||
|
||||
/** \brief Combined interface counter data type for vnet_interface_combined_counters
|
||||
@param sw_if_index - interface indexes for counters
|
||||
@param rx_packets - received packet count
|
||||
@param rx_bytes - received byte count
|
||||
@param tx_packets - transmitted packet count
|
||||
@param tx_bytes - transmitted byte count
|
||||
|
||||
*/
|
||||
typeonly manual_print manual_endian define vnet_combined_counter
|
||||
{
|
||||
u32 sw_if_index;
|
||||
u64 rx_packets; /**< packet counter */
|
||||
u64 rx_bytes; /**< byte counter */
|
||||
u64 tx_packets; /**< packet counter */
|
||||
u64 tx_bytes; /**< byte counter */
|
||||
};
|
||||
|
||||
/** \brief Simple interface counter data type for vnet_interface_simple_counters
|
||||
@param sw_if_index - interface indexes for counters
|
||||
@param drop - RX or TX drops due to buffer starvation
|
||||
@param punt - used with VNET "punt" disposition
|
||||
@param rx_ip4 - received IP4 packets
|
||||
@param rx_ip6 - received IP6 packets
|
||||
@param rx_no_buffer - no RX buffers available
|
||||
@param rx_miss - receive misses
|
||||
@param rx_error - receive errors
|
||||
@param tx_error - transmit errors
|
||||
@param rx_mpls - received MPLS packet
|
||||
|
||||
*/
|
||||
typeonly manual_print manual_endian define vnet_simple_counter
|
||||
{
|
||||
u32 sw_if_index;
|
||||
u64 drop;
|
||||
u64 punt;
|
||||
u64 rx_ip4;
|
||||
u64 rx_ip6;
|
||||
u64 rx_no_buffer;
|
||||
u64 rx_miss;
|
||||
u64 rx_error;
|
||||
u64 tx_error;
|
||||
u64 rx_mpls;
|
||||
};
|
||||
|
||||
/** \brief Simple stats counters structure
|
||||
@param vnet_counter_type- such as ip4, ip6, punts, etc
|
||||
@param first_sw_if_index - first sw index in block of index, counts
|
||||
@param count - number of counters, equal to the number of interfaces in
|
||||
this stats block
|
||||
@param data - contiguous block of u64 counters
|
||||
|
||||
vnet_counter_type defined in enums - plural - in vnet/interface.h
|
||||
*/
|
||||
manual_print manual_endian define vnet_interface_simple_counters
|
||||
{
|
||||
/* enums - plural - in vnet/interface.h */
|
||||
u8 vnet_counter_type;
|
||||
u32 first_sw_if_index;
|
||||
u32 count;
|
||||
@ -249,16 +294,43 @@ manual_print manual_endian define vnet_interface_simple_counters
|
||||
@param count - number of counters, equal to the number of interfaces in
|
||||
this stats block
|
||||
@param data - contiguous block of vlib_counter_t structures
|
||||
|
||||
vnet_counter_type defined in enums - plural - in vnet/interface.h
|
||||
*/
|
||||
manual_print manual_endian define vnet_interface_combined_counters
|
||||
{
|
||||
/* enums - plural - in vnet/interface.h */
|
||||
u8 vnet_counter_type;
|
||||
u32 first_sw_if_index;
|
||||
u32 count;
|
||||
vl_api_vlib_counter_t data[count];
|
||||
};
|
||||
|
||||
|
||||
/** \brief Simple per interface stats counters structure
|
||||
@param count - number of elements in message
|
||||
@param timestamp - u32 vlib timestamp for control plane
|
||||
@param data[count] - vl_api_vnet_simple_counter_t
|
||||
|
||||
*/
|
||||
manual_print manual_endian define vnet_per_interface_simple_counters
|
||||
{
|
||||
u32 count;
|
||||
u32 timestamp;
|
||||
vl_api_vnet_simple_counter_t data[count];
|
||||
};
|
||||
|
||||
/** \brief Combined stats counters structure per interface
|
||||
@param count - number of elements in message
|
||||
@param timestamp - u32 vlib timestamp for control plane
|
||||
@param data[count] - vl_api_vnet_combined_counter_t
|
||||
*/
|
||||
manual_print manual_endian define vnet_per_interface_combined_counters
|
||||
{
|
||||
u32 count;
|
||||
u32 timestamp;
|
||||
vl_api_vnet_combined_counter_t data[count];
|
||||
};
|
||||
|
||||
/** \brief Set unnumbered interface add / del request
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
|
@ -38,6 +38,8 @@ autoreply define want_stats
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param enable_disable - 1 = enable stats, 0 = disable
|
||||
@param pid - pid of process requesting stats updates
|
||||
|
||||
Please consider using want_per_interface_simple_stats with sw_if_index=~0
|
||||
*/
|
||||
autoreply define want_interface_simple_stats
|
||||
{
|
||||
@ -47,11 +49,33 @@ autoreply define want_interface_simple_stats
|
||||
u32 pid;
|
||||
};
|
||||
|
||||
/** \brief Want Per Interface simple Stats, register for continuous stats
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param enable_disable - 1 = enable stats, 0 = disable
|
||||
@param pid - pid of process requesting stats updates
|
||||
@param num - number of sw_if_indexes
|
||||
@param sw_ifs - array of sw_if_index
|
||||
*/
|
||||
autoreply define want_per_interface_simple_stats
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 enable_disable;
|
||||
u32 pid;
|
||||
u32 num;
|
||||
u32 sw_ifs[num];
|
||||
|
||||
};
|
||||
|
||||
/** \brief Want Interface Combined Stats, register for continuous stats
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param enable_disable - 1 = enable stats, 0 = disable
|
||||
@param pid - pid of process requesting stats updates
|
||||
|
||||
Please consider using want_per_interface_combined_stats with sw_if_index=~0
|
||||
|
||||
*/
|
||||
autoreply define want_interface_combined_stats
|
||||
{
|
||||
@ -61,6 +85,25 @@ autoreply define want_interface_combined_stats
|
||||
u32 pid;
|
||||
};
|
||||
|
||||
/** \brief Want Per Interface Combined Stats, register for continuous stats
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
@param enable_disable - 1 = enable stats, 0 = disable
|
||||
@param pid - pid of process requesting stats updates
|
||||
@param num - number of sw_if_indexes
|
||||
@param sw_ifs - array of sw_if_index
|
||||
*/
|
||||
autoreply define want_per_interface_combined_stats
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u32 enable_disable;
|
||||
u32 pid;
|
||||
u32 num;
|
||||
u32 sw_ifs[num];
|
||||
|
||||
};
|
||||
|
||||
/** \brief Want IP4 FIB Stats, register for continuous stats
|
||||
@param client_index - opaque cookie to identify the sender
|
||||
@param context - sender context, to match reply w/ request
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -36,19 +36,10 @@ typedef struct
|
||||
int tag;
|
||||
} data_structure_lock_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vpe_client_registration_t client;
|
||||
u8 stats_registrations;
|
||||
#define INTERFACE_SIMPLE_COUNTERS (1 << 0)
|
||||
#define INTERFACE_COMBINED_COUNTERS (1 << 1)
|
||||
#define IP4_FIB_COUNTERS (1 << 2)
|
||||
#define IP4_NBR_COUNTERS (1 << 3)
|
||||
#define IP6_FIB_COUNTERS (1 << 4)
|
||||
#define IP6_NBR_COUNTERS (1 << 5)
|
||||
|
||||
} vpe_client_stats_registration_t;
|
||||
|
||||
/**
|
||||
* @brief stats request registration indexes
|
||||
*
|
||||
*/
|
||||
/* from .../vnet/vnet/ip/lookup.c. Yuck */
|
||||
typedef CLIB_PACKED (struct
|
||||
{
|
||||
@ -57,6 +48,30 @@ u32 address_length: 6;
|
||||
u32 index: 26;
|
||||
}) ip4_route_t;
|
||||
|
||||
/* see interface.api */
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
u64 drop;
|
||||
u64 punt;
|
||||
u64 rx_ip4;
|
||||
u64 rx_ip6;
|
||||
u64 rx_no_buffer;
|
||||
u64 rx_miss;
|
||||
u64 rx_error;
|
||||
u64 tx_error;
|
||||
u64 rx_mpls;
|
||||
} vnet_simple_counter_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sw_if_index;
|
||||
u64 rx_packets; /**< packet counter */
|
||||
u64 rx_bytes; /**< byte counter */
|
||||
u64 tx_packets; /**< packet counter */
|
||||
u64 tx_bytes; /**< byte counter */
|
||||
} vnet_combined_counter_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ip6_address_t address;
|
||||
@ -74,6 +89,33 @@ typedef struct
|
||||
uword *results;
|
||||
} do_ip46_fibs_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 msg_id;
|
||||
u32 size;
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
i32 retval;
|
||||
} client_registration_reply_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
#define stats_reg(n) IDX_##n,
|
||||
#include <vpp/stats/stats.reg>
|
||||
#undef stats_reg
|
||||
STATS_REG_N_IDX,
|
||||
} stats_reg_index_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//Standard client information
|
||||
uword *client_hash;
|
||||
vpe_client_registration_t *clients;
|
||||
u32 item;
|
||||
|
||||
} vpe_client_stats_registration_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *mheap;
|
||||
@ -83,9 +125,41 @@ typedef struct
|
||||
u32 stats_poll_interval_in_seconds;
|
||||
u32 enable_poller;
|
||||
|
||||
uword *stats_registration_hash;
|
||||
vpe_client_stats_registration_t *stats_registrations;
|
||||
vpe_client_stats_registration_t **regs;
|
||||
/*
|
||||
* stats_registrations is a vector, indexed by
|
||||
* IDX_xxxx_COUNTER generated for each streaming
|
||||
* stat a client can register for. (see stats.reg)
|
||||
*
|
||||
* The values in the vector refer to pools.
|
||||
*
|
||||
* The pool is of type vpe_client_stats_registration_t
|
||||
*
|
||||
* This typedef consists of:
|
||||
*
|
||||
* u32 item: This is the instance of the IDX_xxxx_COUNTER a
|
||||
* client is interested in.
|
||||
* vpe_client_registration_t *clients: The list of clients interested.
|
||||
*
|
||||
* e.g.
|
||||
* stats_registrations[IDX_INTERFACE_SIMPLE_COUNTERS] refers to a pool
|
||||
* containing elements:
|
||||
*
|
||||
* u32 item = sw_if_index1
|
||||
* clients = ["clienta","clientb"]
|
||||
*
|
||||
* When clients == NULL the pool element is freed. When the pool is empty
|
||||
*
|
||||
* ie
|
||||
* 0 == pool_elts(stats_registrations[IDX_INTERFACE_SIMPLE_COUNTERS]
|
||||
*
|
||||
* then there is no need to process INTERFACE_SIMPLE_COUNTERS
|
||||
*
|
||||
* Note that u32 item = ~0 is the simple case for ALL interfaces or fibs.
|
||||
*
|
||||
*/
|
||||
|
||||
uword **stats_registration_hash;
|
||||
vpe_client_stats_registration_t **stats_registrations;
|
||||
|
||||
/* control-plane data structure lock */
|
||||
data_structure_lock_t *data_structure_lock;
|
||||
@ -96,6 +170,13 @@ typedef struct
|
||||
/* Vectors for Distribution funcs: do_ip4_fibs and do_ip6_fibs. */
|
||||
do_ip46_fibs_t do_ip46_fibs;
|
||||
|
||||
/*
|
||||
Working vector vars so as to not thrash memory allocator.
|
||||
Has effect of making "static"
|
||||
*/
|
||||
vpe_client_stats_registration_t **regs_tmp;
|
||||
vpe_client_registration_t **clients_tmp;
|
||||
|
||||
/* convenience */
|
||||
vlib_main_t *vlib_main;
|
||||
vnet_main_t *vnet_main;
|
||||
|
42
src/vpp/stats/stats.reg
Normal file
42
src/vpp/stats/stats.reg
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* @brief Client stats registrations
|
||||
*
|
||||
* Each entry is a specific REGISTRATION as
|
||||
* opposed to an API call.
|
||||
*
|
||||
* For instance:
|
||||
* want_stats()
|
||||
* enables/disables ALL stats entries below for all
|
||||
* ITEM.
|
||||
*
|
||||
* An item is the an incident of the thing we want stats for
|
||||
* such as a FIB or sw_if_index for interface. In each case the
|
||||
* value ~0 is treated as ALL ITEMs.
|
||||
*
|
||||
* As such want_interface_simple_counters() is translated to
|
||||
* want_per_interface_simple_counters(item=~0)
|
||||
*/
|
||||
|
||||
|
||||
stats_reg (IP4_FIB_COUNTERS)
|
||||
stats_reg (IP4_NBR_COUNTERS)
|
||||
stats_reg (IP6_FIB_COUNTERS)
|
||||
stats_reg (IP6_NBR_COUNTERS)
|
||||
stats_reg (PER_INTERFACE_COMBINED_COUNTERS)
|
||||
stats_reg (PER_INTERFACE_SIMPLE_COUNTERS)
|
||||
|
Reference in New Issue
Block a user