diff options
Diffstat (limited to 'src/vnet/tcp/tcp_output.c')
-rw-r--r-- | src/vnet/tcp/tcp_output.c | 28 |
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 |