【C/C++】DPDK 基础使用:从 EAL 初始化到 RX/TX 队列收发数据
2026/7/29 7:56:52 网站建设 项目流程

目录

  • DPDK 基础使用:从 EAL 初始化到 RX/TX 队列收发数据
    • 1. 初始化顺序不能乱
    • 2. 配置端口与队列
    • 3. 从队列取包并解析
    • 4. 组包与发送
    • 5. 验证结果
    • 小结

DPDK 基础使用:从 EAL 初始化到 RX/TX 队列收发数据

标签:DPDKrte_mbufrte_mempool收发队列

课程的receive.csend.cecho.c建立了最小收发闭环:初始化 EAL,创建 mbuf 内存池,配置端口队列,轮询接收,解析以太网帧并组包发送。

1. 初始化顺序不能乱

rte_eal_init -> rte_pktmbuf_pool_create -> rte_eth_dev_configure -> rte_eth_rx_queue_setup / rte_eth_tx_queue_setup -> rte_eth_dev_start -> rte_eth_rx_burst <-> rte_eth_tx_burst

EAL 负责解析 DPDK 参数、初始化大页内存和逻辑核环境。端口启动前,RX/TX 描述符环必须就绪。

if(rte_eal_init(argc,argv)<0)rte_exit(EXIT_FAILURE,"EAL init failed\n");structrte_mempool*pool=rte_pktmbuf_pool_create("MBUF_POOL",NUM_MBUFS,MBUF_CACHE_SIZE,0,RTE_MBUF_DEFAULT_BUF_SIZE,rte_socket_id());if(pool==NULL)rte_exit(EXIT_FAILURE,"mempool create failed\n");

NUM_MBUFS在课程中常取2^n - 1。rte_ring 的容量管理与 2 的幂相关,具体值仍应由队列数、突发大小和内存预算确定。

2. 配置端口与队列

structrte_eth_confport_conf={0};rte_eth_dev_configure(port_id,1,1,&port_conf);rte_eth_rx_queue_setup(port_id,0,1024,rte_eth_dev_socket_id(port_id),NULL,pool);rte_eth_tx_queue_setup(port_id,0,1024,rte_eth_dev_socket_id(port_id),NULL);rte_eth_dev_start(port_id);

一个队列对应一组描述符。多队列网卡可将队列、中断(若使用)和 lcore 进行 CPU 亲和性规划;本课程先以单队列把数据路径跑通。

3. 从队列取包并解析

rte_eth_rx_burst一次取一批rte_mbuf,没有数据时返回 0。这也是 DPDK 轮询模型的核心。

structrte_mbuf*mbufs[BURST_SIZE];uint16_tn=rte_eth_rx_burst(port_id,0,mbufs,BURST_SIZE);for(uint16_ti=0;i<n;i++){structrte_ether_hdr*eth=rte_pktmbuf_mtod(mbufs[i],structrte_ether_hdr*);if(eth->ether_type==rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)){structrte_ipv4_hdr*ip=rte_pktmbuf_mtod_offset(mbufs[i],structrte_ipv4_hdr*,sizeof(*eth));/* 按 ip->next_proto_id 继续分发 */}rte_pktmbuf_free(mbufs[i]);}

rte_pktmbuf_mtod取得数据首地址;rte_pktmbuf_mtod_offset在同一 mbuf 上按字节偏移解释下一个协议头。任何分支处理结束后都要明确释放或转交 mbuf 所有权。

4. 组包与发送

发送方向相反:从内存池申请 mbuf,追加实际数据空间,填充协议头,最后批量入 TX 队列。

structrte_mbuf*tx=rte_pktmbuf_alloc(pool);char*buf=rte_pktmbuf_append(tx,pkt_len);if(buf==NULL){rte_pktmbuf_free(tx);return-ENOMEM;}/* 填充 Ethernet/IP/UDP 或 ICMP 数据 */uint16_tsent=rte_eth_tx_burst(port_id,0,&tx,1);if(sent<1)rte_pktmbuf_free(tx);

注意:data_len是当前分段长度,pkt_len是完整报文长度;多段 mbuf 时二者并不相等。IP/UDP/TCP 校验和必须在字段填完、校验和字段清零后计算。

5. 验证结果

课程用 echo 回包建立了收发验证闭环:

小结

掌握这六个 API 就掌握了 DPDK 的骨架:rte_eal_initrte_pktmbuf_pool_createrte_eth_dev_configure、队列 setup、rte_eth_rx_burstrte_eth_tx_burst。后续 ARP、ICMP、UDP 与 TCP 的区别,主要发生在 mbuf 数据区如何解析和重组。

学习链接: https://github.com/0voice

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询