You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DPDK技术问询:物理端口绑定多data_sender及rte_flow配置方法

DPDK 问题解答

1. 多data_sender绑定单个物理端口的可行性

可以。DPDK支持多线程/多进程共享同一物理网卡端口,核心思路是给端口配置多接收/发送队列,每个data_sender绑定独立队列并运行在不同CPU核心上,以此利用多核算力突破单核心的吞吐量瓶颈。你当前单个sender只能跑7Gb/s,大概率是单核心性能耗尽,通过多sender+多队列+多核扩展,能显著提升整体转发能力。

2. 网卡内部流量均衡到同一IP不同端口的套接字

可以实现,但需明确:网卡负责将流量分发到不同硬件队列,每个队列对应一个独立的data_sender进程/线程,由sender监听不同端口(7001/7002)并处理流量。常用实现方式有两种:

  • RSS(接收端缩放):基于五元组(源IP、目的IP、源端口、目的端口、协议)哈希,将流量均匀分到多个队列,每个队列对应一个sender;
  • 流分类(如rte_flow):精准匹配流量特征,把指定流量定向到对应队列。

3. rte_flow是否支持上述需求

完全支持。rte_flow提供了比RSS更灵活的流量匹配与分发能力,你可以基于目的端口(或其他字段)配置规则,把发往7001的流量定向到队列0,发往7002的流量定向到队列1,再让两个sender分别绑定队列0和队列1处理。

4. 简单配置示例

步骤1:配置网卡多队列

首先初始化DPDK并配置网卡多队列:

// 端口配置结构体
struct rte_eth_conf port_conf = RTE_ETH_CONF_DEFAULT;
port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; // 开启RSS
port_conf.rx_adv_conf.rss_conf.rss_key = NULL;
port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_TCP; // 基于IP+TCP哈希

// 配置端口为2接收队列、2发送队列
int ret = rte_eth_dev_configure(port_id, 2, 2, &port_conf);
if (ret < 0) {
    rte_exit(EXIT_FAILURE, "Failed to configure port %d\n", port_id);
}

// 设置队列所属CPU核心
ret = rte_eth_rx_queue_setup(port_id, 0, 1024, rte_lcore_to_socket_id(0), NULL, NULL);
ret = rte_eth_rx_queue_setup(port_id, 1, 1024, rte_lcore_to_socket_id(1), NULL, NULL);
ret = rte_eth_tx_queue_setup(port_id, 0, 1024, rte_lcore_to_socket_id(0), NULL);
ret = rte_eth_tx_queue_setup(port_id, 1, 1024, rte_lcore_to_socket_id(1), NULL);

// 启动端口
ret = rte_eth_dev_start(port_id);

步骤2:用rte_flow配置流量定向规则

以下示例将目的端口为7001的TCP流量定向到队列0,7002的定向到队列1:

struct rte_flow_attr attr = {
    .group = 0,
    .priority = 1,
};

// 匹配目的端口7001的规则
struct rte_flow_item pattern_7001[] = {
    { // 匹配IPv4
        .type = RTE_FLOW_ITEM_TYPE_IPV4,
    },
    { // 匹配TCP
        .type = RTE_FLOW_ITEM_TYPE_TCP,
        .spec = &(struct rte_flow_item_tcp){
            .dst_port = htons(7001),
        },
        .mask = &(struct rte_flow_item_tcp){
            .dst_port = 0xffff, // 完全匹配目的端口
        },
    },
    { // 结束标记
        .type = RTE_FLOW_ITEM_TYPE_END,
    },
};

// 动作:将流量定向到队列0
struct rte_flow_action action_7001[] = {
    {
        .type = RTE_FLOW_ACTION_TYPE_QUEUE,
        .conf = &(struct rte_flow_action_queue){
            .index = 0,
        },
    },
    {
        .type = RTE_FLOW_ACTION_TYPE_END,
    },
};

// 创建规则
struct rte_flow *flow_7001 = rte_flow_create(port_id, &attr, pattern_7001, action_7001, NULL);

// 同理创建7002的规则,定向到队列1
struct rte_flow_item pattern_7002[] = {
    { .type = RTE_FLOW_ITEM_TYPE_IPV4, },
    {
        .type = RTE_FLOW_ITEM_TYPE_TCP,
        .spec = &(struct rte_flow_item_tcp){ .dst_port = htons(7002), },
        .mask = &(struct rte_flow_item_tcp){ .dst_port = 0xffff, },
    },
    { .type = RTE_FLOW_ITEM_TYPE_END, },
};

struct rte_flow_action action_7002[] = {
    {
        .type = RTE_FLOW_ACTION_TYPE_QUEUE,
        .conf = &(struct rte_flow_action_queue){ .index = 1, },
    },
    { .type = RTE_FLOW_ACTION_TYPE_END, },
};

struct rte_flow *flow_7002 = rte_flow_create(port_id, &attr, pattern_7002, action_7002, NULL);

步骤3:多sender绑定队列处理

每个sender运行在不同核心,从对应队列取包并转发:

// Sender 1(核心0,绑定队列0)
static int sender_lcore_0(void *arg) {
    int port_id = *(int *)arg;
    struct rte_mbuf *bufs[32];
    while (1) {
        // 从队列0接收包
        int nb_rx = rte_eth_rx_burst(port_id, 0, bufs, 32);
        if (nb_rx == 0) continue;

        // 处理并转发到远端服务器(目的端口7001)
        // ... 此处添加包处理逻辑 ...

        // 发送包
        rte_eth_tx_burst(port_id, 0, bufs, nb_rx);
    }
    return 0;
}

// Sender 2(核心1,绑定队列1)
static int sender_lcore_1(void *arg) {
    int port_id = *(int *)arg;
    struct rte_mbuf *bufs[32];
    while (1) {
        int nb_rx = rte_eth_rx_burst(port_id, 1, bufs, 32);
        if (nb_rx == 0) continue;

        // 处理并转发到远端服务器(目的端口7002)
        // ... 此处添加包处理逻辑 ...

        rte_eth_tx_burst(port_id, 1, bufs, nb_rx);
    }
    return 0;
}

// 启动sender线程
rte_eal_remote_launch(sender_lcore_0, &port_id, 0);
rte_eal_remote_launch(sender_lcore_1, &port_id, 1);

内容的提问来源于stack exchange,提问作者Максим

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:42:51