aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/tcp')
-rw-r--r--src/vnet/tcp/tcp.c9
-rw-r--r--src/vnet/tcp/tcp.h32
-rw-r--r--src/vnet/tcp/tcp_cli.c85
-rw-r--r--src/vnet/tcp/tcp_output.c6
-rw-r--r--src/vnet/tcp/tcp_timer.c1
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;
}