diff options
-rw-r--r-- | src/vnet/session/session.c | 7 | ||||
-rw-r--r-- | src/vnet/session/session.h | 6 | ||||
-rw-r--r-- | src/vnet/session/session_cli.c | 8 | ||||
-rw-r--r-- | src/vnet/session/transport.c | 55 | ||||
-rw-r--r-- | src/vnet/session/transport.h | 2 | ||||
-rw-r--r-- | src/vnet/session/transport_types.h | 1 |
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 (®); 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 */ \ |