summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2019-08-27 12:15:43 -0700
committerAndrew Yourtchenko <ayourtch@gmail.com>2019-09-29 10:17:57 +0000
commite7e56def2ef154c3ef20baf91251d7acf0d765b1 (patch)
tree25c925da5a3dea359e7a1f6b205985a40cdd1ef6
parent1b13beb84556bb288b04ce36cc6b73d980f84a63 (diff)
tcp: improve mss computation
Type: fix Use different mss for v4 and v6 packets. Change-Id: Ifcd322c1fd74f749a42bae671dd6cfed8c32b150 Signed-off-by: Florin Coras <fcoras@cisco.com> (cherry picked from commit cedcf608fefc5bdeff13bb0914fa15266e971d7c)
-rw-r--r--src/vnet/tcp/tcp.c44
-rw-r--r--src/vnet/tcp/tcp.h1
-rw-r--r--src/vnet/tcp/tcp_output.c46
3 files changed, 48 insertions, 43 deletions
diff --git a/src/vnet/tcp/tcp.c b/src/vnet/tcp/tcp.c
index bfab1d6f0c5..cd7b9e80c7a 100644
--- a/src/vnet/tcp/tcp.c
+++ b/src/vnet/tcp/tcp.c
@@ -638,6 +638,47 @@ tcp_generate_random_iss (tcp_connection_t * tc)
}
/**
+ * Initialize max segment size we're able to process.
+ *
+ * The value is constrained by the output interface's MTU and by the size
+ * of the IP and TCP headers (see RFC6691). It is also what we advertise
+ * to our peer.
+ */
+static void
+tcp_init_rcv_mss (tcp_connection_t * tc)
+{
+ u8 ip_hdr_len;
+
+ ip_hdr_len = tc->c_is_ip4 ? sizeof (ip4_header_t) : sizeof (ip6_header_t);
+ tc->mss = tcp_cfg.default_mtu - sizeof (tcp_header_t) - ip_hdr_len;
+}
+
+static void
+tcp_init_mss (tcp_connection_t * tc)
+{
+ u16 default_min_mss = 536;
+
+ tcp_init_rcv_mss (tc);
+
+ /* TODO consider PMTU discovery */
+ tc->snd_mss = clib_min (tc->rcv_opts.mss, tc->mss);
+
+ if (tc->snd_mss < 45)
+ {
+ /* Assume that at least the min default mss works */
+ tc->snd_mss = default_min_mss;
+ tc->rcv_opts.mss = default_min_mss;
+ }
+
+ /* We should have enough space for 40 bytes of options */
+ ASSERT (tc->snd_mss > 45);
+
+ /* If we use timestamp option, account for it */
+ if (tcp_opts_tstamp (&tc->rcv_opts))
+ tc->snd_mss -= TCP_OPTION_LEN_TIMESTAMP;
+}
+
+/**
* Initialize connection send variables.
*/
void
@@ -651,6 +692,7 @@ tcp_init_snd_vars (tcp_connection_t * tc)
*/
tcp_set_time_now (tcp_get_worker (vlib_get_thread_index ()));
+ tcp_init_rcv_mss (tc);
tc->iss = tcp_generate_random_iss (tc);
tc->snd_una = tc->iss;
tc->snd_nxt = tc->iss + 1;
@@ -1541,7 +1583,7 @@ tcp_configuration_init (void)
tcp_cfg.max_rx_fifo = 32 << 20;
tcp_cfg.min_rx_fifo = 4 << 10;
- tcp_cfg.default_mtu = 1460;
+ tcp_cfg.default_mtu = 1500;
tcp_cfg.initial_cwnd_multiplier = 0;
tcp_cfg.enable_tx_pacing = 1;
tcp_cfg.cc_algo = TCP_CC_NEWRENO;
diff --git a/src/vnet/tcp/tcp.h b/src/vnet/tcp/tcp.h
index cad105b0c23..d55ff801c00 100644
--- a/src/vnet/tcp/tcp.h
+++ b/src/vnet/tcp/tcp.h
@@ -743,7 +743,6 @@ void tcp_send_reset (tcp_connection_t * tc);
void tcp_send_syn (tcp_connection_t * tc);
void tcp_send_synack (tcp_connection_t * tc);
void tcp_send_fin (tcp_connection_t * tc);
-void tcp_init_mss (tcp_connection_t * tc);
void tcp_update_burst_snd_vars (tcp_connection_t * tc);
void tcp_update_rto (tcp_connection_t * tc);
void tcp_flush_frame_to_output (tcp_worker_ctx_t * wrk, u8 is_ip4);
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index 862f4a2f307..239f6035d5f 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -76,19 +76,6 @@ tcp_window_compute_scale (u32 window)
}
/**
- * Update max segment size we're able to process.
- *
- * The value is constrained by our interface's MTU and IP options. It is
- * also what we advertise to our peer.
- */
-void
-tcp_update_rcv_mss (tcp_connection_t * tc)
-{
- /* TODO find our iface MTU */
- tc->mss = tcp_cfg.default_mtu - sizeof (tcp_header_t);
-}
-
-/**
* TCP's initial window
*/
always_inline u32
@@ -263,16 +250,16 @@ tcp_options_write (u8 * data, tcp_options_t * opts)
}
static int
-tcp_make_syn_options (tcp_options_t * opts, u8 wnd_scale)
+tcp_make_syn_options (tcp_connection_t * tc, tcp_options_t * opts)
{
u8 len = 0;
opts->flags |= TCP_OPTS_FLAG_MSS;
- opts->mss = tcp_cfg.default_mtu; /*XXX discover that */
+ opts->mss = tc->mss;
len += TCP_OPTION_LEN_MSS;
opts->flags |= TCP_OPTS_FLAG_WSCALE;
- opts->wscale = wnd_scale;
+ opts->wscale = tc->rcv_wscale;
len += TCP_OPTION_LEN_WINDOW_SCALE;
opts->flags |= TCP_OPTS_FLAG_TSTAMP;
@@ -379,7 +366,7 @@ tcp_make_options (tcp_connection_t * tc, tcp_options_t * opts,
case TCP_STATE_SYN_RCVD:
return tcp_make_synack_options (tc, opts);
case TCP_STATE_SYN_SENT:
- return tcp_make_syn_options (opts, tc->rcv_wscale);
+ return tcp_make_syn_options (tc, opts);
default:
clib_warning ("State not handled! %d", state);
return 0;
@@ -422,29 +409,6 @@ tcp_update_burst_snd_vars (tcp_connection_t * tc)
tcp_cc_event (tc, TCP_CC_EVT_START_TX);
}
-void
-tcp_init_mss (tcp_connection_t * tc)
-{
- u16 default_min_mss = 536;
- tcp_update_rcv_mss (tc);
-
- /* TODO cache mss and consider PMTU discovery */
- tc->snd_mss = clib_min (tc->rcv_opts.mss, tc->mss);
-
- if (tc->snd_mss < 45)
- {
- /* Assume that at least the min default mss works */
- tc->snd_mss = default_min_mss;
- tc->rcv_opts.mss = default_min_mss;
- }
-
- /* We should have enough space for 40 bytes of options */
- ASSERT (tc->snd_mss > 45);
-
- /* If we use timestamp option, account for it */
- if (tcp_opts_tstamp (&tc->rcv_opts))
- tc->snd_mss -= TCP_OPTION_LEN_TIMESTAMP;
-}
#endif /* CLIB_MARCH_VARIANT */
static void *
@@ -542,7 +506,7 @@ tcp_make_syn (tcp_connection_t * tc, vlib_buffer_t * b)
/* Make and write options */
clib_memset (&snd_opts, 0, sizeof (snd_opts));
- tcp_opts_len = tcp_make_syn_options (&snd_opts, tc->rcv_wscale);
+ tcp_opts_len = tcp_make_syn_options (tc, &snd_opts);
tcp_hdr_opts_len = tcp_opts_len + sizeof (tcp_header_t);
th = vlib_buffer_push_tcp (b, tc->c_lcl_port, tc->c_rmt_port, tc->iss,