af_xdp: linearize buffer chains before TX 33/39033/5
authorShmuel Hazan <shmuel.h@siklu.com>
Tue, 13 Jun 2023 10:55:04 +0000 (13:55 +0300)
committerBeno�t Ganne <bganne@cisco.com>
Wed, 14 Jun 2023 14:16:27 +0000 (14:16 +0000)
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>
src/plugins/af_xdp/output.c

index 8136d91..bb5d56f 100644 (file)
@@ -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;