From 2790dd3dcb1f25db41a8e60dce761de577effe30 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 16 Apr 2025 02:02:33 -0400 Subject: [PATCH] udp: add basic stats per connection Type: improvement Change-Id: I95a3b9c85f4b6ab94250fc8fb5f2a4a142a2f833 Signed-off-by: Florin Coras --- src/vnet/udp/udp.c | 2 ++ src/vnet/udp/udp.h | 5 +++++ src/vnet/udp/udp_cli.c | 29 +++++++++++++++++++++++------ src/vnet/udp/udp_input.c | 21 +++++++++++++++++++-- 4 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/vnet/udp/udp.c b/src/vnet/udp/udp.c index 661a0f6e0f0..d997da21edf 100644 --- a/src/vnet/udp/udp.c +++ b/src/vnet/udp/udp.c @@ -303,6 +303,8 @@ udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b, vnet_buffer (b)->tcp.flags |= UDP_CONN_F_LISTEN; } + uc->bytes_out += vlib_buffer_length_in_chain (vm, b); + uc->dgrams_out += 1; uh->checksum = udp_compute_checksum (vm, b, udp_csum_offload (uc), uc->c_is_ip4); diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h index c6f867500e0..2e280f7c2a8 100644 --- a/src/vnet/udp/udp.h +++ b/src/vnet/udp/udp.h @@ -87,6 +87,11 @@ typedef struct u32 sw_if_index; /**< connection sw_if_index */ u32 next_node_index; /**< Can be used to control next node in output */ u32 next_node_opaque; /**< Opaque to pass to next node */ + u64 bytes_in; /**< bytes received */ + u64 dgrams_in; /**< rfc4113 dgrams received */ + u64 bytes_out; /**< bytes sent */ + u64 dgrams_out; /**< rfc4113 dgrams sent */ + u32 errors_in; /**< rfc4113 dgrams in errors */ } udp_connection_t; #define udp_csum_offload(uc) (!((uc)->cfg_flags & UDP_CFG_F_NO_CSUM_OFFLOAD)) diff --git a/src/vnet/udp/udp_cli.c b/src/vnet/udp/udp_cli.c index dd1da0a01d6..adae9934df6 100644 --- a/src/vnet/udp/udp_cli.c +++ b/src/vnet/udp/udp_cli.c @@ -90,19 +90,36 @@ format_udp_connection_flags (u8 * s, va_list * args) return s; } +static u8 * +format_udp_stats (u8 *s, va_list *args) +{ + udp_connection_t *uc = va_arg (*args, udp_connection_t *); + u32 indent = format_get_indent (s); + s = format (s, "in dgrams %lu bytes %lu err %lu\n", uc->dgrams_in, + uc->bytes_in, uc->errors_in); + s = format (s, "%Uout dgrams %lu bytes %lu", format_white_space, indent, + uc->dgrams_out, uc->bytes_out); + return s; +} + static u8 * format_udp_vars (u8 * s, va_list * args) { udp_connection_t *uc = va_arg (*args, udp_connection_t *); - s = format (s, " index %u%U flags: %U\n", uc->c_c_index, + s = format (s, " index %u cfg: %U flags: %U\n", uc->c_c_index, format_udp_cfg_flags, uc, format_udp_connection_flags, uc); - s = format (s, " fib_index: %u next_node: %u opaque: %u ", uc->c_fib_index, + s = format (s, " fib_index %u next_node %u opaque %u", uc->c_fib_index, uc->next_node_index, uc->next_node_opaque); - if (!(uc->flags & UDP_CONN_F_LISTEN)) - s = format (s, " sw_if_index: %d mss: %u\n", uc->sw_if_index, uc->mss); - else - s = format (s, "\n"); + + if (uc->flags & UDP_CONN_F_LISTEN) + { + s = format (s, "\n"); + return s; + } + + s = format (s, " sw_if_index %d mss %u\n", uc->sw_if_index, uc->mss); + s = format (s, " stats: %U\n", format_udp_stats, uc); return s; } diff --git a/src/vnet/udp/udp_input.c b/src/vnet/udp/udp_input.c index 693824f9628..19cc04c2881 100644 --- a/src/vnet/udp/udp_input.c +++ b/src/vnet/udp/udp_input.c @@ -146,7 +146,15 @@ udp_connection_enqueue (udp_connection_t * uc0, session_t * s0, /* Expect cl udp enqueue to fail because fifo enqueue */ if (PREDICT_FALSE (wrote0 == 0)) - *error0 = UDP_ERROR_FIFO_FULL; + { + *error0 = UDP_ERROR_FIFO_FULL; + uc0->errors_in += 1; + } + else + { + uc0->bytes_in += wrote0; + uc0->dgrams_in += 1; + } return; } @@ -155,6 +163,7 @@ udp_connection_enqueue (udp_connection_t * uc0, session_t * s0, < hdr0->data_length + sizeof (session_dgram_hdr_t)) { *error0 = UDP_ERROR_FIFO_FULL; + uc0->errors_in += 1; return; } @@ -175,7 +184,15 @@ udp_connection_enqueue (udp_connection_t * uc0, session_t * s0, /* In some rare cases, session_enqueue_dgram_connection can fail because a * chunk cannot be allocated in the RX FIFO */ if (PREDICT_FALSE (wrote0 == 0)) - *error0 = UDP_ERROR_FIFO_NOMEM; + { + *error0 = UDP_ERROR_FIFO_NOMEM; + uc0->errors_in += 1; + } + else + { + uc0->bytes_in += wrote0; + uc0->dgrams_in += 1; + } } always_inline session_t * -- 2.16.6