summaryrefslogtreecommitdiffstats
path: root/src/vnet/pg/output.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/pg/output.c')
-rw-r--r--src/vnet/pg/output.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/vnet/pg/output.c b/src/vnet/pg/output.c
index d8059fab186..042591a7709 100644
--- a/src/vnet/pg/output.c
+++ b/src/vnet/pg/output.c
@@ -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);