以下是使用DPDK 20.11版本发送巨型帧的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rte_eal.h>
#include <rte_mbuf.h>
#include <rte_ethdev.h>
#define RX_RING_SIZE 1024
#define TX_RING_SIZE 1024
#define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250
static const struct rte_eth_conf port_conf_default = {
.rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
};
int main(int argc, char *argv[])
{
int ret;
uint16_t nb_ports;
uint16_t portid;
struct rte_mempool *mbuf_pool;
struct rte_eth_dev_info dev_info;
/* 初始化 EAL */
ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
argc -= ret;
argv += ret;
/* 获取网口数量 */
nb_ports = rte_eth_dev_count_avail();
/* 创建内存池 */
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
/* 配置端口并启动 */
for (portid = 0; portid < nb_ports; portid++) {
if (!rte_eth_dev_is_valid_port(portid))
continue;
/* 获取网卡信息 */
memset(&dev_info, 0, sizeof(dev_info));
rte_eth_dev_info_get(portid, &dev_info);
/* 配置网卡 */
ret = rte_eth_dev_configure(portid, 1, 1, &port_conf_default);
if (ret < 0)
rte_exit(EXIT_FAILURE, "Cannot configure device: err=%d, port=%u\n",
ret, portid);
/* 启用 Jumbo Frame 支持 */
if (dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME) {
struct rte_eth_rxconf rx_conf;
rte_eth_rxmode_get(portid, &rx_conf); // 获取当前网卡的 RX 配置
rx_conf.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME; // 开启 Jumbo Frame 支持
rte_eth_rxmode_set(portid, &rx_conf); // 更新 RX 配置
}
/* 启动设备 */
ret = rte_eth_dev_start(portid);
if (ret < 0)
rte_exit(EXIT_FAILURE,
"rte_eth_dev_start:err=%d,port=%u\n",
ret,(unsigned)portid);
printf("Ethernet device %u successfully configured.\n", portid);
}
/* 创建一个 MBUF 包 */
struct rte_mbuf *pkt = rte_pktmbuf_alloc(mbuf_pool); // 从内存池中获取一个 MBUF 包
if (pkt == NULL)
rte_exit(EXIT_FAILURE, "Cannot allocate mbuf\n");
/* 设置包头 */
pkt->data_len = ETHER_MAX_LEN; // 数据长度为最大以太网帧长度
pkt->pkt_len = ETHER_MAX_LEN;
/* 发送 MBUF 包 */
uint64_t tx_time = 0;
int nb_tx = rte_eth_tx_burst(0, 0, &pkt, 1);
if (nb_tx == 1) {
/* 等待数据发送完毕 */
do {
nb_tx = rte_eth_tx_done_cleanup(0, BURST_SIZE);
tx_time += rte_get_timer_cycles();
rte_delay_us(5);
} while (nb_tx);
printf("TX time: %lu cycles\n", tx_time);
} else {
rte_pktmbuf_free(pkt); // 如果发送失败则释放 MBUF 包
}
return 0;
}
以上代码在创建MBUF包时设置了最大以太网帧长度,并通过开启DEV_RX_OFFLOAD_JUMBO_FRAME选项来支持Jumbo Frame。需要注意的是,实际应用中可能需要更加复杂的逻辑来处理巨型帧。