summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 */ \