tcp: enable gso in tcp hoststack

Type: feature

Change-Id: If68d07fbe8c6f7fffd2f93c7e854367082927e4f
Signed-off-by: Simon Zhang <yuwei1.zhang@intel.com>
diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c
index ff281b5..15aa857 100644
--- a/src/vnet/tcp/tcp_output.c
+++ b/src/vnet/tcp/tcp_output.c
@@ -2126,11 +2126,33 @@
       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 @@
 	  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 @@
 	  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 @@
 	  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 @@
       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