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
This commit is contained in:

committed by
Dave Barach

parent
80ae7e5307
commit
da237e8b98
@ -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 (®);
|
||||
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 *
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */ \
|
||||
|
Reference in New Issue
Block a user