From 07e6c829507cbb3f842227db66f615dd8a262239 Mon Sep 17 00:00:00 2001 From: Shmuel Hazan Date: Tue, 13 Jun 2023 13:55:04 +0300 Subject: af_xdp: linearize buffer chains before TX The af_xdp plugin does not support chained buffers; attempting to send chain buffers will result truncated packets or even send other packet's data. As a workaround, turn any buffer chain into a single buffer before tx. Type: fix Change-Id: I05dec912455eb2bb6c8122a28cd646f88983aa9a Signed-off-by: Shmuel Hazan --- src/plugins/af_xdp/output.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/plugins') diff --git a/src/plugins/af_xdp/output.c b/src/plugins/af_xdp/output.c index 8136d918a75..bb5d56f2503 100644 --- a/src/plugins/af_xdp/output.c +++ b/src/plugins/af_xdp/output.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -154,6 +155,14 @@ wrap_around: while (n >= 8) { + if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_NEXT_PRESENT || + b[1]->flags & VLIB_BUFFER_NEXT_PRESENT || + b[2]->flags & VLIB_BUFFER_NEXT_PRESENT || + b[3]->flags & VLIB_BUFFER_NEXT_PRESENT)) + { + break; + } + vlib_prefetch_buffer_header (b[4], LOAD); offset = (sizeof (vlib_buffer_t) + @@ -193,6 +202,17 @@ wrap_around: while (n >= 1) { + if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_NEXT_PRESENT)) + { + if (vlib_buffer_chain_linearize (vm, b[0]) != 1) + { + af_xdp_log (VLIB_LOG_LEVEL_ERR, ad, + "vlib_buffer_chain_linearize failed"); + vlib_buffer_free_one (vm, b[0]->buffer_pool_index); + continue; + } + } + offset = (sizeof (vlib_buffer_t) + b[0]->current_data) << XSK_UNALIGNED_BUF_OFFSET_SHIFT; -- cgit 1.2.3-korg