OpenDataPlane / odp

The ODP project is an open-source, cross-platform set of application programming interfaces (APIs) for the networking data plane

Home Page:https://opendataplane.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

XDP pktio sends malformed packets

bogdanPricope opened this issue · comments

odp(odp-dpdk) platform linux-generic 1.37.1

It looks like xdp pktio is sending data starting with "buffer start address" instead of "data start address".

Steps:

  1. alloc a packet of 'len' size
    pkt = odp_packet_alloc(pool, len);

  2. pull head 4 bytes
    odp_packet_pull_head(pkt, 4);

  3. send packet

My understanding is that odp should send 'len - 4' bytes, starting with byte 4th. However, I can see in the packet capture that the first 4 bytes are sent as well...

0000 00 00 00 00 90 1b 0e 9a c7 fc 80 61 5f 0c d5 f5
0010 08 00 45 00 00 54 00 09 00 00 ff 01 72 30 c0 a8
0020 64 0a c0 a8 64 14 08 00 63 99 e0 57 00 01 16 4e
0030 fd 07 fc 06 2a bb bc 36 1b 6c 20 49 4d c6 87 c1
0040 5a de c9 82 0b 82 8e 95 9f c8 b7 bb f2 eb b1 19
0050 36 26 ca f2 9e f3 be ab 09 b5 64 fe fc a9 20 39
0060 2e 00

I'll have a look at this.

Thanks for the report. This patch seems to fix this issue and the freeze from #1623 if you want to try it out in your environment as well.

diff --git a/platform/linux-generic/pktio/socket_xdp.c b/platform/linux-generic/pktio/socket_xdp.c
index 7e8877359..2b4abf66c 100644
--- a/platform/linux-generic/pktio/socket_xdp.c
+++ b/platform/linux-generic/pktio/socket_xdp.c
@@ -675,8 +675,8 @@ static inline void populate_tx_desc(odp_packet_hdr_t *pkt_hdr, pool_t *pool,
        uint64_t pkt_off;
 
        frame_off = pkt_hdr->event_hdr.index.event * pool->block_size;
-       pkt_off = (uint64_t)(uintptr_t)pkt_hdr->event_hdr.base_data
-                 - (uint64_t)(uintptr_t)pool->base_addr - frame_off;
+       pkt_off = (uint64_t)(uintptr_t)pkt_hdr->seg_data - (uint64_t)(uintptr_t)pool->base_addr
+                 - frame_off;
        pkt_off <<= XSK_UNALIGNED_BUF_OFFSET_SHIFT;
        tx_desc->addr = frame_off | pkt_off;
        tx_desc->len = len;
@@ -934,7 +934,7 @@ static int sock_xdp_output_queues_config(pktio_entry_t *pktio_entry,
        bind_q = priv->bind_q;
        umem = priv->umem_info->umem;
 
-       for (i = 0U; i < param->num_queues; ++i) {
+       for (i = 0U; i < param->num_queues;) {
                sock = &priv->qs[i];
                ret = xsk_socket__create_shared(&sock->xsk, devname, bind_q, umem, &sock->rx,
                                                &sock->tx, &sock->fill_q, &sock->compl_q, &config);
@@ -944,6 +944,8 @@ static int sock_xdp_output_queues_config(pktio_entry_t *pktio_entry,
                        goto err;
                }
 
+               ++i;
+
                if (!reserve_fill_queue_elements(priv, sock, config.rx_size)) {
                        ODP_ERR("Unable to reserve fill queue descriptors for queue: %u.\n",
                                bind_q);

Looks good.
Merci.