summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShmuel Hazan <shmuel.h@siklu.com>2023-06-13 13:55:04 +0300
committerBeno�t Ganne <bganne@cisco.com>2023-06-14 14:16:27 +0000
commit07e6c829507cbb3f842227db66f615dd8a262239 (patch)
treed0f5ba934c96e5604f4d1ce6af7726c884b7f27a
parent39c40fa349505b584472678318ef8548ab203aed (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.c20
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;