带有dpdk的arp数据包的rte流

rte flow for arp packet with dpdk

有没有办法使用 rte_flow 通过 dpdk

将 arp 和 ndp 数据包发送到特定的 rx 队列

在 rte_flow_item_type 中我没有看到 arp 或 ndp 的条目

对于ipv4我做了以下的方式

                                                pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
                                                pattern[0].spec = NULL;

                                                pattern[1].type = RTE_FLOW_ITEM_TYPE_IPV4;
                                                pattern[1].spec = NULL;

我需要为 arp 和 ndp 做什么?没有RTE_FLOW_ITEM_TYPE_ARP

v18.05-rc1 以来,已有项目类型 RTE_FLOW_ITEM_TYPE_ARP_ETH_IPV4。话虽如此,相关 PMD 可能不支持它。

改为考虑在 EtherType 字段上进行匹配:

#include <rte_byteorder.h>
#include <rte_ether.h>
#include <rte_flow.h>
        struct rte_flow_item_eth  item_eth_mask = {};
        struct rte_flow_item_eth  item_eth_spec = {};

        item_eth_spec.hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_ARP);
        item_eth_mask.hdr.ether_type = RTE_BE16(0xFFFF);

        pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
        pattern[0].mask = &item_eth_mask;
        pattern[0].spec = &item_eth_spec;

关于 NDP,也许值得一试 RTE_FLOW_ITEM_TYPE_ICMP6_ND_*。同样,这些可能不受所讨论的 PMD 的支持。如果是这种情况,请考虑使用 RTE_FLOW_ITEM_TYPE_ICMP6 将所有 ICMPv6 重定向到专用队列。

所有供应商 PMD 的无匹配数据包的默认队列(禁用 RSS)是队列 0。除了 TAP PMD,其中 OS 支持多个 RX 队列。

既然你提到 DPDK 版本是 19.11,最好的选择是使用 rte_flow_item_eth 来过滤所需的以太类型。那是在 DPDK 19.11

struct rte_flow_item_eth {
        struct rte_ether_addr dst; /**< Destination MAC. */
        struct rte_ether_addr src; /**< Source MAC. */
        rte_be16_t type; /**< EtherType or TPID. */
};

因此使用以下代码片段,您可以将数据包类型转向所需的队列

        struct rte_flow_attr attr = { .ingress = 1 };
        struct rte_flow_item pattern[10];
        struct rte_flow_action actions[10];
        struct rte_flow_action_queue actionqueue = { .index = 1 };
        struct rte_flow_item_eth eth;
        struct rte_flow_item_vlan vlan;
        struct rte_flow_item_ipv4 ipv4;
        struct rte_flow *flow;
        struct rte_flow_error error;

        struct rte_flow_item_eth  item_eth_mask;
        struct rte_flow_item_eth  item_eth_spec;

        /* memset item_eth_mask and item_eth_spec to 0  */

        item_eth_spec.hdr.ether_type = RTE_BE16(RTE_ETHER_TYPE_ARP);
        item_eth_mask.hdr.ether_type = 0xFFFF;

        /* setting the eth to pass all packets */
        pattern[0].type = RTE_FLOW_ITEM_TYPE_ETH;
        pattern[0].spec = &eth;
        pattern[0].last = &item_eth_mask;
        pattern[0].mask = &item_eth_spec;

        /* end the pattern array */
        pattern[1].type = RTE_FLOW_ITEM_TYPE_END;

        actions[0].type = RTE_FLOW_ACTION_TYPE_QUEUE;
        actions[0].conf = &actionqueue;
        actions[1].type = RTE_FLOW_ACTION_TYPE_END;

        /* validate and create the flow rule */
        if (!rte_flow_validate(port, &attr, pattern, actions, &error))
                flow = rte_flow_create(port, &attr, pattern, actions, &error);
        else
                printf("rte_flow err %s\n", error.message);

注意:这在 Intel X710 和 E810 NIC 上失败,因为它支持 VLAN+IP+UDP|TCP|SCTP​​+Inner。