下面是一个用 DPDK 发送 10 个长度依次递增的报文的示例代码:
#include <rte_mbuf.h>
#include <rte_ethdev.h>
#define NUM_PACKETS 10
int main(int argc, char *argv[]) {
int ret;
uint16_t port_id = 0; // 网口 ID,假设为 0
uint16_t queue_id = 0; // 队列 ID,假设为 0
struct rte_mempool *mbuf_pool;
// 初始化 EAL
ret = rte_eal_init(argc, argv);
if (ret < 0) {
rte_exit(EXIT_FAILURE, "Error: Failed to initialize EAL.\n");
}
// 创建内存池,用于分配 mbuf 结构体
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_PACKETS*2,
RTE_CACHE_LINE_SIZE, 0,
RTE_MBUF_DEFAULT_BUF_SIZE,
rte_socket_id());
if (mbuf_pool == NULL) {
rte_exit(EXIT_FAILURE, "Error: Failed to create mbuf pool.\n");
}
// 配置网口
ret = rte_eth_dev_configure(port_id, 1, 1, NULL);
if (ret < 0) {
rte_exit(EXIT_FAILURE, "Error: Failed to configure Ethernet device.\n");
}
// 激活网口
ret = rte_eth_dev_start(port_id);
if (ret < 0) {
rte_exit(EXIT_FAILURE, "Error: Failed to start Ethernet device.\n");
}
// 构造并发送数据包
struct ether_hdr *eth_hdr;
struct rte_mbuf *mbuf;
uint16_t data_len = 0;
for (int i = 0; i < NUM_PACKETS; i++) {
// 创建 mbuf 结构体
mbuf = rte_pktmbuf_alloc(mbuf_pool);
if (mbuf == NULL) {
rte_exit(EXIT_FAILURE, "Error: Failed to allocate mbuf.\n");
}
// 设置以太网头部
eth_hdr = rte_pktmbuf_mtod(mbuf, struct ether_hdr *);
memset(eth_hdr->d_addr.addr_bytes, 0xFF, ETHER_ADDR_LEN); // 目的地址为广播地址
memset(eth_hdr->s_addr.addr_bytes, 0x00, ETHER_ADDR_LEN); // 源地址为全零地址
eth_hdr->ether_type = htons(ETHER_TYPE_IPv4); // 假设使用 IPv4 协议
// 设置数据长度并复制数据到 mbuf 中
data_len += i + 1; // 数据长度递增
char *data = (char *)rte_pktmbuf_append(mbuf, data_len);
memset(data, 'A' + i, data_len); // 将数据填充成 A~J 的字符序列
mbuf->pkt_len = RTE_BE16(data_len + sizeof(struct ether_hdr));
mbuf->data_len = RTE_BE16(data_len);
ret = rte_eth_tx_burst(port_id, queue_id, &mbuf, 1);
if (ret != 1) {
printf("Warning: Failed to send packet %d.\n", i+1);
} else {
printf("Packet %d sent successfully.\n", i+1);
}
}
rte_eth_dev_stop(port_id); // 停止网口
rte_eth_dev_close(port_id); // 关闭网口
return 0;
}
在这个示例代码中,首先使用 DPDK 初始化 EAL,并创建一个大小为 NUM_PACKETS*2
的内存池。然后,配置并激活网口,构造数据包并递增数据长度发送。注意,在构造数据包时需要设置以太网头部和 pkt_len
和 data_len
字段。
每个数据包的有效载荷都是逐渐增加的,从 A 一直到 J。输出结果类似于:
Packet 1 sent successfully.
Packet 2 sent successfully.
Packet 3 sent successfully.
Packet 4 sent successfully.
Packet 5 sent successfully.
Packet 6 sent successfully.
Packet 7 sent successfully.
Packet 8 sent successfully.
Packet 9 sent successfully.
Packet 10 sent successfully.