aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/session
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2024-11-13 22:54:14 -0800
committerDave Barach <vpp@barachs.net>2024-11-18 17:13:30 +0000
commitda237e8b983dbde5cf7c1a27d82030313b4db3ee (patch)
treeedcbcf73830377f34a5e0a587d3a99af64a5f8db /src/vnet/session
parent80ae7e5307fc73077c6291ccfd2f5bf4888ca5e1 (diff)
session: track number of tries to alloc lcl port
Track number of tries to alloc local port and report it in stats segment. Could be used to gauge how busy the port allocator is. Also add cli to dump trasport sub-layer state. Type: improvement Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I3736a48488c491dee85aa2b074b87519a3857057
Diffstat (limited to 'src/vnet/session')
-rw-r--r--src/vnet/session/session.c7
-rw-r--r--src/vnet/session/session.h6
-rw-r--r--src/vnet/session/session_cli.c8
-rw-r--r--src/vnet/session/transport.c55
-rw-r--r--src/vnet/session/transport.h2
-rw-r--r--src/vnet/session/transport_types.h1
6 files changed, 71 insertions, 8 deletions
diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c
index ac02281cf5c..8a9fc4b2371 100644
--- a/src/vnet/session/session.c
+++ b/src/vnet/session/session.c
@@ -1981,11 +1981,14 @@ session_stats_collector_fn (vlib_stats_collector_data_t *d)
}
vlib_stats_set_gauge (d->private_data, n_sessions);
+ vlib_stats_set_gauge (smm->stats_seg_idx.tp_port_alloc_max_tries,
+ transport_port_alloc_max_tries ());
}
static void
session_stats_collector_init (void)
{
+ session_main_t *smm = &session_main;
vlib_stats_collector_reg_t reg = {};
reg.entry_index =
@@ -1994,6 +1997,10 @@ session_stats_collector_init (void)
reg.collect_fn = session_stats_collector_fn;
vlib_stats_register_collector_fn (&reg);
vlib_stats_validate (reg.entry_index, 0, vlib_get_n_threads ());
+
+ smm->stats_seg_idx.tp_port_alloc_max_tries =
+ vlib_stats_add_gauge ("/sys/session/transport_port_alloc_max_tries");
+ vlib_stats_set_gauge (smm->stats_seg_idx.tp_port_alloc_max_tries, 0);
}
static clib_error_t *
diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h
index 24150fbbcd1..823bdcb02af 100644
--- a/src/vnet/session/session.h
+++ b/src/vnet/session/session.h
@@ -197,6 +197,11 @@ typedef enum
#undef _
} session_rt_engine_type_t;
+typedef struct session_stats_seg_indices_
+{
+ u32 tp_port_alloc_max_tries;
+} session_stats_segs_indicies_t;
+
typedef struct session_main_
{
/** Worker contexts */
@@ -294,6 +299,7 @@ typedef struct session_main_
/** Query nat44-ed session to get original dst ip4 & dst port. */
nat44_original_dst_lookup_fn original_dst_lookup;
+ session_stats_segs_indicies_t stats_seg_idx;
} session_main_t;
extern session_main_t session_main;
diff --git a/src/vnet/session/session_cli.c b/src/vnet/session/session_cli.c
index c29a465d056..0ed2876469b 100644
--- a/src/vnet/session/session_cli.c
+++ b/src/vnet/session/session_cli.c
@@ -613,6 +613,11 @@ show_session_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_output (vm, "%U", format_transport_protos);
goto done;
}
+ else if (unformat (input, "transport"))
+ {
+ vlib_cli_output (vm, "%U", format_transport_state);
+ goto done;
+ }
else if (unformat (input, "rt-backend"))
{
vlib_cli_output (vm, "%U", format_rt_backend, smm->rt_engine_type);
@@ -799,7 +804,7 @@ VLIB_CLI_COMMAND (vlib_cli_show_session_command) = {
.path = "show session",
.short_help =
"show session [protos][states][rt-backend][verbose [n]] "
- "[events][listeners <proto>] "
+ "[transport][events][listeners <proto>] "
"[<session-id>][thread <n> [[proto <p>] index <n>]][elog] "
"[thread <n>][proto <proto>][state <state>][range <min> [<max>]] "
"[lcl|rmt|ep <ip>[:<port>]][force-print]",
@@ -1061,6 +1066,7 @@ clear_session_stats_fn (vlib_main_t *vm, unformat_input_t *input,
{
clib_memset (&wrk->stats, 0, sizeof (wrk->stats));
}
+ transport_clear_stats ();
return 0;
}
diff --git a/src/vnet/session/transport.c b/src/vnet/session/transport.c
index 1c2a9261d3c..e8c9490decb 100644
--- a/src/vnet/session/transport.c
+++ b/src/vnet/session/transport.c
@@ -35,6 +35,7 @@ typedef struct transport_main_
local_endpoint_t *local_endpoints;
u32 *lcl_endpts_freelist;
u32 port_allocator_seed;
+ u16 port_alloc_max_tries;
u16 port_allocator_min_src_port;
u16 port_allocator_max_src_port;
u8 lcl_endpts_cleanup_pending;
@@ -212,14 +213,39 @@ unformat_transport_proto (unformat_input_t * input, va_list * args)
u8 *
format_transport_protos (u8 * s, va_list * args)
{
+ u32 indent = format_get_indent (s) + 1;
transport_proto_vft_t *tp_vft;
vec_foreach (tp_vft, tp_vfts)
- s = format (s, "%s\n", tp_vft->transport_options.name);
+ if (tp_vft->transport_options.name)
+ s = format (s, "%U%s\n", format_white_space, indent,
+ tp_vft->transport_options.name);
return s;
}
+u8 *
+format_transport_state (u8 *s, va_list *args)
+{
+ transport_main_t *tm = &tp_main;
+
+ s = format (s, "registered protos:\n%U", format_transport_protos);
+
+ s = format (s, "configs:\n");
+ s =
+ format (s, " min_lcl_port: %u max_lcl_port: %u\n",
+ tm->port_allocator_min_src_port, tm->port_allocator_max_src_port);
+
+ s = format (s, "state:\n");
+ s = format (s, " lcl ports alloced: %u\n lcl ports freelist: %u \n",
+ pool_elts (tm->local_endpoints),
+ vec_len (tm->lcl_endpts_freelist));
+ s =
+ format (s, " port_alloc_max_tries: %u\n lcl_endpts_cleanup_pending: %u\n",
+ tm->port_alloc_max_tries, tm->lcl_endpts_cleanup_pending);
+ return s;
+}
+
u32
transport_endpoint_lookup (transport_endpoint_table_t * ht, u8 proto,
ip46_address_t * ip, u16 port)
@@ -606,7 +632,7 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
transport_main_t *tm = &tp_main;
u16 min = tm->port_allocator_min_src_port;
u16 max = tm->port_allocator_max_src_port;
- int tries, limit;
+ int tries, limit, port = -1;
limit = max - min;
@@ -616,8 +642,6 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
/* Search for first free slot */
for (tries = 0; tries < limit; tries++)
{
- u16 port = 0;
-
/* Find a port in the specified range */
while (1)
{
@@ -630,7 +654,7 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
}
if (!transport_endpoint_mark_used (proto, lcl_addr, port))
- return port;
+ break;
/* IP:port pair already in use, check if 6-tuple available */
if (session_lookup_connection (rmt->fib_index, lcl_addr, &rmt->ip, port,
@@ -640,9 +664,26 @@ transport_alloc_local_port (u8 proto, ip46_address_t *lcl_addr,
/* 6-tuple is available so increment lcl endpoint refcount */
transport_share_local_endpoint (proto, lcl_addr, port);
- return port;
+ break;
}
- return -1;
+
+ tm->port_alloc_max_tries = clib_max (tm->port_alloc_max_tries, tries);
+
+ return port;
+}
+
+u16
+transport_port_alloc_max_tries ()
+{
+ transport_main_t *tm = &tp_main;
+ return tm->port_alloc_max_tries;
+}
+
+void
+transport_clear_stats ()
+{
+ transport_main_t *tm = &tp_main;
+ tm->port_alloc_max_tries = 0;
}
static session_error_t
diff --git a/src/vnet/session/transport.h b/src/vnet/session/transport.h
index e6ba1ecbc5f..289bf471af0 100644
--- a/src/vnet/session/transport.h
+++ b/src/vnet/session/transport.h
@@ -252,6 +252,8 @@ void transport_share_local_endpoint (u8 proto, ip46_address_t * lcl_ip,
u16 port);
int transport_release_local_endpoint (u8 proto, ip46_address_t *lcl_ip,
u16 port);
+u16 transport_port_alloc_max_tries ();
+void transport_clear_stats ();
void transport_enable_disable (vlib_main_t * vm, u8 is_en);
void transport_init (void);
diff --git a/src/vnet/session/transport_types.h b/src/vnet/session/transport_types.h
index f3b84998743..4a2f861814f 100644
--- a/src/vnet/session/transport_types.h
+++ b/src/vnet/session/transport_types.h
@@ -196,6 +196,7 @@ u8 *format_transport_half_open_connection (u8 * s, va_list * args);
uword unformat_transport_proto (unformat_input_t * input, va_list * args);
u8 *format_transport_protos (u8 * s, va_list * args);
+u8 *format_transport_state (u8 *s, va_list *args);
#define foreach_transport_endpoint_fields \
_(ip46_address_t, ip) /**< ip address in net order */ \