diff options
Diffstat (limited to 'src/vnet/tcp')
-rw-r--r-- | src/vnet/tcp/tcp.c | 9 | ||||
-rw-r--r-- | src/vnet/tcp/tcp.h | 32 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_cli.c | 85 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_output.c | 6 | ||||
-rw-r--r-- | src/vnet/tcp/tcp_timer.c | 1 |
5 files changed, 119 insertions, 14 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c index efc72a227e8..1afc07918b7 100644 --- a/src/vnet/tcp/tcp.c +++ b/src/vnet/tcp/tcp.c @@ -879,6 +879,8 @@ format_tcp_listener_session (u8 * s, va_list * args) if (verbose) s = format (s, "%-" SESSION_CLI_STATE_LEN "U", format_tcp_state, tc->state); + if (verbose == 2) + s = format (s, "\n%U", format_tcp_listener_connection, tc); return s; } @@ -1512,6 +1514,10 @@ tcp_main_enable (vlib_main_t * vm) clib_error_t *error = 0; int thread; + /* Already initialized */ + if (tm->wrk_ctx) + return 0; + if ((error = vlib_call_init_function (vm, ip_main_init))) return error; if ((error = vlib_call_init_function (vm, ip4_lookup_init))) @@ -1642,6 +1648,9 @@ tcp_configuration_init (void) /* This value is seconds */ tcp_cfg.cleanup_time = 0.1; /* 100ms */ + + /* Time constants defined as tcp tick (1us) multiples */ + tcp_cfg.syn_rcvd_time = TCP_ESTABLISH_TIME; } static clib_error_t * diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h index 2362a8bb857..8676db413a0 100644 --- a/src/vnet/tcp/tcp.h +++ b/src/vnet/tcp/tcp.h @@ -45,19 +45,21 @@ typedef struct _tcp_lookup_dispatch u8 next, error; } tcp_lookup_dispatch_t; -#define foreach_tcp_wrk_stat \ - _(timer_expirations, u64, "timer expirations") \ - _(rxt_segs, u64, "segments retransmitted") \ - _(tr_events, u32, "timer retransmit events") \ - _(to_closewait, u32, "timeout close-wait") \ - _(to_closewait2, u32, "timeout close-wait w/data") \ - _(to_finwait1, u32, "timeout fin-wait-1") \ - _(to_finwait2, u32, "timeout fin-wait-2") \ - _(to_lastack, u32, "timeout last-ack") \ - _(to_closing, u32, "timeout closing") \ - _(tr_abort, u32, "timer retransmit abort") \ - _(rst_unread, u32, "reset on close due to unread data") \ - _(no_buffer, u32, "out of buffers") \ +#define foreach_tcp_wrk_stat \ + _ (timer_expirations, u64, "timer expirations") \ + _ (rxt_segs, u64, "segments retransmitted") \ + _ (tr_events, u32, "timer retransmit events") \ + _ (to_establish, u32, "timeout establish") \ + _ (to_persist, u32, "timeout persist") \ + _ (to_closewait, u32, "timeout close-wait") \ + _ (to_closewait2, u32, "timeout close-wait w/data") \ + _ (to_finwait1, u32, "timeout fin-wait-1") \ + _ (to_finwait2, u32, "timeout fin-wait-2") \ + _ (to_lastack, u32, "timeout last-ack") \ + _ (to_closing, u32, "timeout closing") \ + _ (tr_abort, u32, "timer retransmit abort") \ + _ (rst_unread, u32, "reset on close due to unread data") \ + _ (no_buffer, u32, "out of buffers") typedef struct tcp_wrk_stats_ { @@ -197,6 +199,9 @@ typedef struct tcp_configuration_ /** Time to wait (sec) before cleaning up the connection */ f32 cleanup_time; + /** Time to wait (tcp ticks) for syn-rcvd connection to establish */ + u32 syn_rcvd_time; + /** Number of preallocated connections */ u32 preallocated_connections; @@ -354,6 +359,7 @@ format_function_t format_tcp_flags; format_function_t format_tcp_sacks; format_function_t format_tcp_rcv_sacks; format_function_t format_tcp_connection; +format_function_t format_tcp_listener_connection; format_function_t format_tcp_connection_id; #define tcp_validate_txf_size(_tc, _a) \ diff --git a/src/vnet/tcp/tcp_cli.c b/src/vnet/tcp/tcp_cli.c index b04c0bdc0cf..55bc5764df2 100644 --- a/src/vnet/tcp/tcp_cli.c +++ b/src/vnet/tcp/tcp_cli.c @@ -250,6 +250,21 @@ format_tcp_connection_id (u8 * s, va_list * args) } u8 * +format_tcp_listener_connection (u8 *s, va_list *args) +{ + tcp_connection_t *tc = va_arg (*args, tcp_connection_t *); + + s = format (s, " index: %u cfg_flags: %U cong_algo: %s snd_mss: %u\n", + tc->c_c_index, format_tcp_cfg_flags, tc, tc->cc_algo->name, + tc->snd_mss); + s = format (s, " next_node %u opaque 0x%x fib_index %u sw_if_index %d", + tc->next_node_index, tc->next_node_opaque, tc->c_fib_index, + tc->sw_if_index); + + return s; +} + +u8 * format_tcp_connection (u8 * s, va_list * args) { tcp_connection_t *tc = va_arg (*args, tcp_connection_t *); @@ -825,6 +840,74 @@ VLIB_CLI_COMMAND (show_tcp_punt_command, static) = .function = show_tcp_punt_fn, }; +static u8 * +format_tcp_cfg (u8 *s, va_list *args) +{ + tcp_configuration_t tm_cfg = va_arg (*args, tcp_configuration_t); + + s = format (s, "max rx fifo size: %U\n", format_memory_size, + tm_cfg.max_rx_fifo); + s = format (s, "min rx fifo size: %U\n", format_memory_size, + tm_cfg.min_rx_fifo); + s = format (s, "default mtu: %u\n", tm_cfg.default_mtu); + s = format (s, "initial cwnd multiplier: %u\n", + tm_cfg.initial_cwnd_multiplier); + s = format (s, "tx pacing: %s\n", + tm_cfg.enable_tx_pacing ? "enabled" : "disabled"); + s = format (s, "tso: %s\n", tm_cfg.allow_tso ? "allowed" : "disallowed"); + s = format (s, "checksum offload: %s\n", + tm_cfg.csum_offload ? "enabled" : "disabled"); + s = format (s, "congestion control algorithm: %s\n", + tcp_cc_algo_get (tm_cfg.cc_algo)->name); + s = format (s, "min rwnd update ack: %u\n", tm_cfg.rwnd_min_update_ack); + s = format (s, "max gso packet size: %U\n", format_memory_size, + tm_cfg.max_gso_size); + s = format (s, "close_wait time: %u sec\n", + (u32) (tm_cfg.closewait_time * TCP_TIMER_TICK)); + s = format (s, "time_wait time: %u sec\n", + (u32) (tm_cfg.timewait_time * TCP_TIMER_TICK)); + s = format (s, "fin_wait1 time: %u sec\n", + (u32) (tm_cfg.finwait1_time * TCP_TIMER_TICK)); + s = format (s, "fin_wait2 time: %u sec\n", + (u32) (tm_cfg.finwait2_time * TCP_TIMER_TICK)); + s = format (s, "last_ack time: %u sec\n", + (u32) (tm_cfg.lastack_time * TCP_TIMER_TICK)); + s = format (s, "fin_ack time: %u sec\n", + (u32) (tm_cfg.closing_time * TCP_TIMER_TICK)); + s = format (s, "syn_rcvd time: %u sec\n", + (u32) (tm_cfg.syn_rcvd_time * TCP_TICK)); + s = format (s, "tcp allocation error cleanup time: %0.2f sec\n", + (f32) (tm_cfg.alloc_err_timeout * TCP_TIMER_TICK)); + s = format (s, "connection cleanup time: %.2f sec\n", tm_cfg.cleanup_time); + s = format (s, "tcp preallocated connections: %u", + tm_cfg.preallocated_connections); + + return s; +} + +static clib_error_t * +show_tcp_cfg_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + tcp_main_t *tm = vnet_get_tcp_main (); + + if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + return clib_error_return (0, "unknown input `%U'", format_unformat_error, + input); + vlib_cli_output (vm, "-----------"); + vlib_cli_output (vm, "tcp config"); + vlib_cli_output (vm, "-----------"); + vlib_cli_output (vm, "%U\n", format_tcp_cfg, tm->cfg); + + return 0; +} + +VLIB_CLI_COMMAND (show_tcp_cfg_command, static) = { + .path = "show tcp config", + .short_help = "show tcp config", + .function = show_tcp_cfg_fn, +}; + static clib_error_t * show_tcp_stats_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -1009,6 +1092,8 @@ tcp_config_fn (vlib_main_t * vm, unformat_input_t * input) tcp_cfg.alloc_err_timeout = tmp_time / TCP_TIMER_TICK; else if (unformat (input, "cleanup-time %u", &tmp_time)) tcp_cfg.cleanup_time = tmp_time / 1000.0; + else if (unformat (input, "syn-rcvd-time %u", &tmp_time)) + tcp_cfg.syn_rcvd_time = tmp_time * THZ; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index 78148cd5695..dd1ec555902 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -1391,7 +1391,7 @@ tcp_timer_retransmit_handler (tcp_connection_t * tc) tc->rtt_ts = 0; /* Passive open establish timeout */ - if (tc->rto > TCP_ESTABLISH_TIME >> 1) + if (tc->rto > tcp_cfg.syn_rcvd_time >> 1) { tcp_connection_set_state (tc, TCP_STATE_CLOSED); tcp_connection_timers_reset (tc); @@ -1458,6 +1458,8 @@ tcp_timer_retransmit_syn_handler (tcp_connection_t * tc) TCP_EVT (TCP_EVT_CC_EVT, tc, 2); tc->rtt_ts = 0; + tcp_worker_stats_inc (wrk, to_establish, 1); + /* Active open establish timeout */ if (tc->rto >= TCP_ESTABLISH_TIME >> 1) { @@ -1507,6 +1509,8 @@ tcp_timer_persist_handler (tcp_connection_t * tc) int n_bytes = 0; u8 *data; + tcp_worker_stats_inc (wrk, to_persist, 1); + /* Problem already solved or worse */ if (tc->state == TCP_STATE_CLOSED || tc->snd_wnd > tc->snd_mss || (tc->flags & TCP_CONN_FINSNT)) diff --git a/src/vnet/tcp/tcp_timer.c b/src/vnet/tcp/tcp_timer.c index d98d0d14b17..4d1c0624fee 100644 --- a/src/vnet/tcp/tcp_timer.c +++ b/src/vnet/tcp/tcp_timer.c @@ -20,6 +20,7 @@ void tcp_timer_initialize_wheel (tcp_timer_wheel_t * tw, void (*expired_timer_cb) (u32 *), f64 now) { + ASSERT (tw->timers == 0); tw_timer_wheel_init_tcp_twsl (tw, expired_timer_cb, TCP_TIMER_TICK, ~0); tw->last_run_time = now; } |