dpdk tap设备不能转发大于1500报文问题分析

背景

在使用dpdk做流转发的时候,期望将部分流量转到tap设备,以供Linux协议栈消费。
做测试的时候发现两个问题,
问题一: 报文超过MTU 1500的报文,在tap设备上抓不到报文。
问题二: ifconfig 修改tap设备的MTU为 2000,在tap设备上依旧抓不到报文,猜测这个地方只是修改了Linux本身的限制,并没有修改dpdk运行时代码的限制。
dpdk版本: 22.11

发包分析

dpdk发送报文到tap设备的接口为rte_eth_tx_burst,对应的tap pmd的接口为 pmd_tx_burst,查看代码发现报文长度大于MTU长度是直接返回,不执行后面的发包操作。所以问题一,问题二都得到了解释,dpdk发包报文大小是根据自己的MTU配置来的。

pmd_tx_burst 代码位置 drivers/net/tap/rte_eth_tap.c

static uint16_t
pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
{
...
    max_size = *txq->mtu + (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + 4);
    for (i = 0; i < nb_pkts; i++) {
            /* stats.errs will be incremented */
            if (rte_pktmbuf_pkt_len(mbuf_in) > max_size) 
                break; //报文长度大于MTU长度是直接返回,不执行后面的发包操作
    

            ret = tap_write_mbufs(txq, num_mbufs, mbuf,
                    &num_packets, &num_tx_bytes);
    }
...
}

解决方法

修改tap设备的MTU为2000。
通过调用 rte_eth_dev_configure 来修改MTU,结果MTU合法性检查失败,导致MTU修改失败。

int
rte_eth_dev_configure(uint16_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
              const struct rte_eth_conf *dev_conf)
{
...
    ret = rte_eth_dev_info_get(port_id, &dev_info); //获取设备信息
    
...
    ret = eth_dev_validate_mtu(port_id, &dev_info,
            dev->data->dev_conf.rxmode.mtu); //MTU合法性检查失败,导致MTU修改失败
    if (ret != 0)
        goto rollback;
...
}

//MTU合法性检查函数
static int
eth_dev_validate_mtu(uint16_t port_id, struct rte_eth_dev_info *dev_info,
        uint16_t mtu) {
...
    overhead_len = eth_dev_get_overhead_len(dev_info->max_rx_pktlen,
            dev_info->max_mtu);
    frame_size = mtu + overhead_len;
    if (frame_size > dev_info->max_rx_pktlen) { //修改后报文的大小比设备支持的最大报文长度还大,非法
        RTE_ETHDEV_LOG(ERR,
            "Frame size (%u) > device max frame size (%u) for port_id %u\n",
            frame_size, dev_info->max_rx_pktlen, port_id);
        return -EINVAL;
    }
...
}


static int
tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
...
    dev_info->max_rx_pktlen = (uint32_t)RTE_ETHER_MAX_VLAN_FRAME_LEN; //tap设备支持的最大报文长度
...
}

最终方案

需要修改tap设备支持的最大报文长度,才能修改tap设备的MTU值。

static int
tap_dev_info(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
{
...
    dev_info->max_rx_pktlen = (uint32_t)UINT32_MAX;
...
}  
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值