summaryrefslogtreecommitdiffstats
path: root/src/vnet/tcp/tcp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/tcp/tcp_output.c')
-rw-r--r--src/vnet/tcp/tcp_output.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index ff281b5661d..15aa85712e3 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -2126,11 +2126,33 @@ tcp_output_push_ip (vlib_main_t * vm, vlib_buffer_t * b0,
b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM;
vnet_buffer (b0)->l3_hdr_offset = (u8 *) ih0 - b0->data;
vnet_buffer (b0)->l4_hdr_offset = (u8 *) th0 - b0->data;
+ b0->flags |=
+ VNET_BUFFER_F_L3_HDR_OFFSET_VALID | VNET_BUFFER_F_L4_HDR_OFFSET_VALID;
th0->checksum = 0;
}
}
always_inline void
+tcp_check_if_gso (tcp_connection_t * tc, vlib_buffer_t * b)
+{
+ if (PREDICT_TRUE (!(b->flags & VLIB_BUFFER_TOTAL_LENGTH_VALID)))
+ return;
+ u16 data_len =
+ b->current_length + b->total_length_not_including_first_buffer -
+ sizeof (tcp_header_t) - tc->snd_opts_len;
+
+ if (data_len > tc->snd_mss)
+ {
+ ASSERT ((b->flags & VNET_BUFFER_F_L3_HDR_OFFSET_VALID) != 0);
+ ASSERT ((b->flags & VNET_BUFFER_F_L4_HDR_OFFSET_VALID) != 0);
+ b->flags |= VNET_BUFFER_F_GSO;
+ vnet_buffer2 (b)->gso_l4_hdr_sz =
+ sizeof (tcp_header_t) + tc->snd_opts_len;
+ vnet_buffer2 (b)->gso_size = tc->snd_mss;
+ }
+}
+
+always_inline void
tcp_output_handle_packet (tcp_connection_t * tc0, vlib_buffer_t * b0,
vlib_node_runtime_t * error_node, u16 * next0,
u8 is_ip4)
@@ -2213,6 +2235,9 @@ tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
tcp_output_push_ip (vm, b[1], tc1, is_ip4);
+ tcp_check_if_gso (tc0, b[0]);
+ tcp_check_if_gso (tc1, b[1]);
+
tcp_output_handle_packet (tc0, b[0], error_node, &next[0], is_ip4);
tcp_output_handle_packet (tc1, b[1], error_node, &next[1], is_ip4);
}
@@ -2221,6 +2246,7 @@ tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (tc0 != 0)
{
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
+ tcp_check_if_gso (tc0, b[0]);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0],
is_ip4);
}
@@ -2232,6 +2258,7 @@ tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (tc1 != 0)
{
tcp_output_push_ip (vm, b[1], tc1, is_ip4);
+ tcp_check_if_gso (tc1, b[1]);
tcp_output_handle_packet (tc1, b[1], error_node, &next[1],
is_ip4);
}
@@ -2262,6 +2289,7 @@ tcp46_output_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
if (PREDICT_TRUE (tc0 != 0))
{
tcp_output_push_ip (vm, b[0], tc0, is_ip4);
+ tcp_check_if_gso (tc0, b[0]);
tcp_output_handle_packet (tc0, b[0], error_node, &next[0], is_ip4);
}
else