diff options
author | Shmuel Hazan <shmuel.h@siklu.com> | 2023-06-13 13:55:04 +0300 |
---|---|---|
committer | Beno�t Ganne <bganne@cisco.com> | 2023-06-14 14:16:27 +0000 |
commit | 07e6c829507cbb3f842227db66f615dd8a262239 (patch) | |
tree | d0f5ba934c96e5604f4d1ce6af7726c884b7f27a | |
parent | 39c40fa349505b584472678318ef8548ab203aed (diff) |
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 <shmuel.h@siklu.com>
-rw-r--r-- | src/plugins/af_xdp/output.c | 20 |
1 files changed, 20 insertions, 0 deletions
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 <string.h> +#include <vppinfra/clib.h> #include <vlib/vlib.h> #include <vlib/unix/unix.h> #include <vnet/ethernet/ethernet.h> @@ -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; |