DPDK - rte_mbuf payload/data 初始化或 updation/modification

DPDK - rte_mbuf payload/data initialization or updation/modification

我正在尝试了解DPDK的basicfwd示例的转发机制。谁能帮我初始化和编辑 rte_mbuf 的有效负载? Here 就是 class。 我计划使用 tcpdumprte_pktmbuf_dump 查看数据包内容。

这里是 rte_mbuf 我想添加我自己的 payload 到:

struct rte_mbuf *bufs[BURST_SIZE];

这是正在收到的rte_mbuf

const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);

这是正在传输的rte_mbuf

const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,
                                    bufs, nb_rx);

我修改了 DPDK 示例中的示例应用程序 basicfwd.c 以在文件中打印转发的数据包:

/* Get burst of RX packets, from first port of pair. */

 const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
 FILE *fp;

 fp = fopen("dump.txt", "a");
 fprintf(fp, "\n-----------------------\n fprintf... %d<->%d\n", count, port);

 rte_pktmbuf_dump(fp, bufs[0], 1000);
 fclose(fp);
 if (unlikely(nb_rx == 0))
      continue;

 /* Send burst of TX packets, to second port of pair. */
  const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0,bufs, nb_rx);

这些是我在输出文件中看到的数据包: 我希望能够修改内容以便更好地理解。我试过 rte_pktmbuf_initbufs->userdata =*(unsigned short*) 0xAAAAAAAA 但它对我不起作用。

我通过在内存池中创建自己的数据包解决了这个问题。

  1. 为程序创建一个内存池。
  2. 在内存池中分配一个数据包。
  3. 用数据、源地址、目标地址填充数据包,并初始化数据包字段。

完整的lcore_main函数:

/*
 * The main thread that does the work, reading from
 * an input port and writing to an output port.
 */
struct message {
    char data[DATA_SIZE];
};

static __attribute__(()) void
lcore_main(void)
{
    const uint8_t nb_ports = rte_eth_dev_count();
    uint8_t port;

    for (port = 0; port < nb_ports; port++)
        if (rte_eth_dev_socket_id(port) > 0 &&
            rte_eth_dev_socket_id(port) !=
            (int)rte_socket_id())
            printf("WARNING, port %u is on remote NUMA node to "
            "polling thread.\n\tPerformance will "
            "not be optimal.\n", port);

    struct rte_mbuf *pkt;
    struct ether_hdr *eth_hdr;

    struct message obj;
    struct message *msg;
    int nb_rx = 0, nb_tx = 0, cnt = 0, pkt_size = 0;
    int count = 0;
    int k = 0;
    for (count = 0; count < DATA_SIZE; count++){
        obj.data[count] = (char)(97 + (k++));
        if (k == 26)
            k = 0;
    }
    time_t endtime = time(NULL) + 10;
    port = 0;
    while (time(NULL) < endtime) {
        cnt = rte_eth_rx_burst(port, 0, &pkt, 1);
        nb_rx += cnt;

        if (cnt > 0)
        {
            eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);

            rte_eth_macaddr_get(port, &eth_hdr->s_addr);

            pkt_size = sizeof(struct message) + sizeof(struct ether_hdr);
            msg = (struct message *) (rte_pktmbuf_mtod(pkt, char*)) + sizeof(struct ether_hdr);
            rte_pktmbuf_free(pkt);
        }

        msg = &obj;
        pkt = rte_pktmbuf_alloc(mbuf_pool);
        pkt_size = sizeof(struct message) + sizeof(struct ether_hdr);
        pkt->data_len = pkt_size;
        pkt->pkt_len = pkt_size;
        eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *);
        rte_eth_macaddr_get(port, &eth_hdr->d_addr);
        rte_eth_macaddr_get(port ^ 1, &eth_hdr->s_addr);
        eth_hdr->ether_type = htons(PTP_PROTOCOL);
        char* data;

        data = rte_pktmbuf_append(pkt, sizeof(struct message));
        if (data != NULL)
            rte_memcpy(data, msg, sizeof(struct message));

        nb_tx += rte_eth_tx_burst(port ^ 1, 0, &pkt, 1);
    }
    printf("----\nData size: %d\nPacket size: %d\nRX : %d, TX : %d\n\n", DATA_SIZE, pkt_size, nb_rx, nb_tx);
}