gso: packet coalesce library
[vpp.git] / src / vnet / pg / output.c
index d8059fa..042591a 100644 (file)
@@ -42,6 +42,7 @@
 #include <vnet/vnet.h>
 #include <vnet/pg/pg.h>
 #include <vnet/ethernet/ethernet.h>
+#include <vnet/gso/gro_func.h>
 
 uword
 pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
@@ -50,6 +51,8 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
   u32 *buffers = vlib_frame_vector_args (frame);
   uword n_buffers = frame->n_vectors;
   uword n_left = n_buffers;
+  u32 to[GRO_TO_VECTOR_SIZE (n_buffers)];
+  uword n_to = 0;
   vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
   pg_interface_t *pif = pool_elt_at_index (pg->interfaces, rd->dev_instance);
 
@@ -57,6 +60,13 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
     while (clib_atomic_test_and_set (pif->lockp))
       ;
 
+  if (PREDICT_FALSE (pif->coalesce_enabled))
+    {
+      n_to = vnet_gro_inline (vm, pif->flow_table, buffers, n_left, to);
+      buffers = to;
+      n_left = n_to;
+    }
+
   while (n_left > 0)
     {
       n_left--;
@@ -84,7 +94,13 @@ pg_output (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
       pif->pcap_main.n_packets_to_capture)
     pcap_close (&pif->pcap_main);
 
-  vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_buffers);
+  if (PREDICT_FALSE (pif->coalesce_enabled))
+    {
+      n_buffers = n_to;
+      vlib_buffer_free (vm, to, n_to);
+    }
+  else
+    vlib_buffer_free (vm, vlib_frame_vector_args (frame), n_buffers);
   if (PREDICT_FALSE (pif->lockp != 0))
     clib_atomic_release (pif->lockp);