}
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 =
reg.collect_fn = session_stats_collector_fn;
vlib_stats_register_collector_fn (®);
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 *
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);
.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]",
{
clib_memset (&wrk->stats, 0, sizeof (wrk->stats));
}
+ transport_clear_stats ();
return 0;
}
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;
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)
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;
/* Search for first free slot */
for (tries = 0; tries < limit; tries++)
{
- u16 port = 0;
-
/* Find a port in the specified range */
while (1)
{
}
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,
/* 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