欢迎来到 DPDK交流社区 ,有什么问题可以尽管在这里提问,您将会收到社区其他成员的回答;也可以将您的总结写在这里,为社区其他成员提供帮助。 (QQ交流群:127163755)

ixgbe 流分类功能fdir 实现方式

+2 投票

背景:

由于业务需要,dpdk上面加上kni,本机报文上kernel其他处理完以后转发走。由于网卡报文负载的时候默认按照ETH_RSS_IP 方式负载,流量按照hash算法分到不同的queue上面,内核关心的流量同样都会分到不同的queue上面,软件层面只能core与core之间加锁。非常浪费性能。

所以需要考虑让网卡自身进行流分类,自己关心的流量统一分类到queue0上面。参考的文档位置如下:

http://blog.csdn.net/vah101/article/details/40077937

http://dpdk.org/doc/guides/testpmd_app_ug/testpmd_funcs.html#ethertype-filter

具体在dpdk中的实现方法:

rte_eth_dev_configure(port, rx_rings, tx_rings, &r_ports->dev_conf);

r_ports 是初始化的fdir结构,可以参考 testpmd 的 init_port_config  

  struct rte_eth_ntuple_filter ntuple;
    struct rte_eth_ethertype_filter l2filter;

    int port,ret = 0;

    memset(&ntuple, 0, sizeof(struct rte_eth_ntuple_filter));
    memset(&l2filter, 0, sizeof(struct rte_eth_ethertype_filter));

    ntuple.flags = RTE_5TUPLE_FLAGS;
    ntuple.dst_ip_mask = UINT32_MAX;
    ntuple.src_ip_mask = 0;
    ntuple.dst_port_mask = 0;
    ntuple.src_port_mask = 0;
    ntuple.proto_mask = 0;
    ntuple.proto = 0;
    ntuple.priority = 7;
    ntuple.dst_ip = 0x1010101;
    ntuple.src_ip = 0;
    /* need convert to big endian. */
    ntuple.dst_port = 0;
    ntuple.src_port = 0;
    ntuple.queue = 0;

    l2filter.ether_type = 0x806;
    l2filter.queue = 0;

    for(port = 0;port < num_port;port++){
        ret = rte_eth_dev_filter_ctrl(port,
                RTE_ETH_FILTER_ETHERTYPE,
                RTE_ETH_FILTER_ADD,
                &l2filter);
        if (ret < 0)
            printf("l2filter ntuple programming error: (%s)\n",
                strerror(-ret));

        ret = rte_eth_dev_filter_ctrl(port,
                RTE_ETH_FILTER_NTUPLE,
                RTE_ETH_FILTER_ADD,
                &ntuple);

 

最新提问 4月 21, 2016 分类:经验之谈 | 用户: oops (2,160 分)

1个回答

0 投票

楼主,请问下你的rte_fdir_conf初始化值能不能贴一下呢?
struct rte_fdir_conf g_fdir_conf;
memset(&g_fdir_conf, 0, sizeof(g_fdir_conf));
g_fdir_conf.mode = RTE_FDIR_MODE_PERFECT;
g_fdir_conf.pballoc = RTE_FDIR_PBALLOC_256K;
g_fdir_conf.status = RTE_FDIR_REPORT_STATUS_ALWAYS;
g_fdir_conf.drop_queue = -1;
g_fdir_conf.mask.vlan_tci_mask = 0x0;
g_fdir_conf.mask.ipv4_mask.src_ip = 0xFFFFFFFF;
g_fdir_conf.mask.ipv4_mask.dst_ip = 0xFFFFFFFF;
g_fdir_conf.mask.ipv6_mask.src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
g_fdir_conf.mask.ipv6_mask.dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
g_fdir_conf.mask.src_port_mask = 0xFFFF;
g_fdir_conf.mask.dst_port_mask = 0xFFFF;

然后再使用 struct rte_eth_ntuple_filter ,初始化的和你的一样,但是看网卡信息fdir_match 只有fdir_miss值在增加,排查了好久一着没有头绪,google也找不到太多信息,麻烦了。

最新回答 4月 19, 2017 用户: TomatoShield (200 分)
代码很简单的,参考这个函数cmd_5tuple_filter_parsed
,举个例子来说,
5tuple_filter 1 add dst_ip 2.2.2.2 src_ip 3.3.3.3 dst_port 1 src_port 2 protocol 17 mask 14 tcp_flags 1 priority 1 queue 1
这个例子将上述的五元组放到队列1 里面,代码cmd_5tuple_filter_parsed通过解析,最终会到这个地方
    if (!strcmp(res->ops, "add"))
        ret = rte_eth_dev_filter_ctrl(res->port_id,
                RTE_ETH_FILTER_NTUPLE,
                RTE_ETH_FILTER_ADD,
                &filter);
    else
        ret = rte_eth_dev_filter_ctrl(res->port_id,
                RTE_ETH_FILTER_NTUPLE,
                RTE_ETH_FILTER_DELETE,
                &filter);

然后一步一步往下跟就行了。
...