The flow rule parser was based on a fixed hardcoded pattern table that was hard to extend. Replace it with a simpler protocol-graph classifier, and add IP-in-IP and Geneve tunnel patterns.
Signed-off-by: Jiacheng Ye <[email protected]> --- drivers/net/hinic3/base/hinic3_nic_cfg.h | 2 +- drivers/net/hinic3/hinic3_ethdev.h | 12 + drivers/net/hinic3/hinic3_fdir.c | 158 ++++-- drivers/net/hinic3/hinic3_fdir.h | 19 +- drivers/net/hinic3/hinic3_flow.c | 581 +++++++++++++++++------ drivers/net/hinic3/hinic3_flow.h | 196 -------- 6 files changed, 573 insertions(+), 395 deletions(-) delete mode 100644 drivers/net/hinic3/hinic3_flow.h diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.h b/drivers/net/hinic3/base/hinic3_nic_cfg.h index ecd410785f..ef139b25b9 100644 --- a/drivers/net/hinic3/base/hinic3_nic_cfg.h +++ b/drivers/net/hinic3/base/hinic3_nic_cfg.h @@ -938,7 +938,7 @@ struct hinic3_set_fdir_ethertype_rule { uint8_t pkt_type_en; uint8_t pkt_type; uint8_t qid; - uint8_t rsvd2; + uint8_t flags; }; struct hinic3_cmd_set_rq_flush { diff --git a/drivers/net/hinic3/hinic3_ethdev.h b/drivers/net/hinic3/hinic3_ethdev.h index b38853f556..34c74f95d9 100644 --- a/drivers/net/hinic3/hinic3_ethdev.h +++ b/drivers/net/hinic3/hinic3_ethdev.h @@ -107,6 +107,13 @@ enum nic_feature_cap { TAILQ_HEAD(hinic3_ethertype_filter_list, rte_flow); TAILQ_HEAD(hinic3_fdir_rule_filter_list, rte_flow); +enum nic_type { + NIC_SP620 = 0, + NIC_SP560 = 1, + NIC_SP230 = 2, + NIC_UNKNOWN = 3, +}; + struct hinic3_nic_dev { struct hinic3_hwdev *hwdev; /**< Hardware device. */ struct hinic3_txq **txqs; @@ -156,12 +163,17 @@ struct hinic3_nic_dev { struct hinic3_nic_rx_ops *rx_ops; struct hinic3_nic_tx_ops *tx_ops; uint32_t fec_mode; /**< Current FEC mode for ethdev. */ + enum nic_type nic_type; /**< NIC type. */ }; #define SELECT_OTHER_COS_ID(cos_id) ((cos_id) ^ 4) #define ODD_NUMBER_QUEUE_ID(q_id) ((q_id) & 1) +#define HINIC3_IS_SP620_NIC(nic_dev) ((nic_dev)->nic_type == NIC_SP620) +#define HINIC3_IS_SP560_NIC(nic_dev) ((nic_dev)->nic_type == NIC_SP560) +#define HINIC3_IS_SP230_NIC(nic_dev) ((nic_dev)->nic_type == NIC_SP230) + extern const struct rte_flow_ops hinic3_flow_ops; /** diff --git a/drivers/net/hinic3/hinic3_fdir.c b/drivers/net/hinic3/hinic3_fdir.c index 71d50a3d22..baa86c0c81 100644 --- a/drivers/net/hinic3/hinic3_fdir.c +++ b/drivers/net/hinic3/hinic3_fdir.c @@ -77,8 +77,6 @@ hinic3_fdir_tcam_ipv4_init(struct hinic3_fdir_filter *rule, /* Fill type of ip. */ tcam_key->key_mask.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; - tcam_key->key_mask.vlan_flag = HINIC3_UINT1_MAX; - tcam_key->key_info.vlan_flag = 0; /* Fill src IPv4. */ tcam_key->key_mask.sipv4_h = @@ -101,8 +99,9 @@ hinic3_fdir_tcam_ipv4_init(struct hinic3_fdir_filter *rule, HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv4.dst_ip); } -static void hinic3_fdir_ipv6_tcam_key_init_sip(struct hinic3_fdir_filter *rule, - struct hinic3_tcam_key *tcam_key) +static inline void +hinic3_fdir_ipv6_tcam_key_init_sip(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) { tcam_key->key_mask_ipv6.sipv6_key0 = HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.src_ip[0]); @@ -138,8 +137,9 @@ static void hinic3_fdir_ipv6_tcam_key_init_sip(struct hinic3_fdir_filter *rule, HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.src_ip[0x3]); } -static void hinic3_fdir_ipv6_tcam_key_init_dip(struct hinic3_fdir_filter *rule, - struct hinic3_tcam_key *tcam_key) +static inline void +hinic3_fdir_ipv6_tcam_key_init_dip(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) { tcam_key->key_mask_ipv6.dipv6_key0 = HINIC3_32_UPPER_16_BITS(rule->key_mask.ipv6.dst_ip[0]); @@ -175,8 +175,9 @@ static void hinic3_fdir_ipv6_tcam_key_init_dip(struct hinic3_fdir_filter *rule, HINIC3_32_LOWER_16_BITS(rule->key_spec.ipv6.dst_ip[0x3]); } -static void hinic3_fdir_ipv6_tcam_key_init(struct hinic3_fdir_filter *rule, - struct hinic3_tcam_key *tcam_key) +static void +hinic3_fdir_ipv6_tcam_key_init(struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) { hinic3_fdir_ipv6_tcam_key_init_sip(rule, tcam_key); hinic3_fdir_ipv6_tcam_key_init_dip(rule, tcam_key); @@ -189,8 +190,6 @@ hinic3_fdir_tcam_ipv6_init(struct hinic3_fdir_filter *rule, /* Fill type of ip. */ tcam_key->key_mask_ipv6.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; - tcam_key->key_mask_ipv6.vlan_flag = HINIC3_UINT1_MAX; - tcam_key->key_info_ipv6.vlan_flag = 0; hinic3_fdir_ipv6_tcam_key_init(rule, tcam_key); } @@ -240,15 +239,11 @@ hinic3_fdir_tcam_notunnel_init(struct rte_eth_dev *dev, } static void -hinic3_fdir_tcam_vxlan_ipv4_init(struct hinic3_fdir_filter *rule, +hinic3_fdir_tcam_vxlan_geneve_ipv4_init(struct hinic3_fdir_filter *rule, struct hinic3_tcam_key *tcam_key) { - /* Fill type of ip. */ tcam_key->key_mask.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; - tcam_key->key_mask.vlan_flag = HINIC3_UINT1_MAX; - tcam_key->key_info.vlan_flag = 0; - /* Fill src ipv4. */ tcam_key->key_mask.sipv4_h = HINIC3_32_UPPER_16_BITS(rule->key_mask.inner_ipv4.src_ip); @@ -271,14 +266,12 @@ hinic3_fdir_tcam_vxlan_ipv4_init(struct hinic3_fdir_filter *rule, } static void -hinic3_fdir_tcam_vxlan_ipv6_init(struct hinic3_fdir_filter *rule, +hinic3_fdir_tcam_vxlan_geneve_ipv6_init(struct hinic3_fdir_filter *rule, struct hinic3_tcam_key *tcam_key) { /* Fill type of ip. */ tcam_key->key_mask_vxlan_ipv6.ip_type = HINIC3_UINT1_MAX; tcam_key->key_info_vxlan_ipv6.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; - tcam_key->key_mask_vxlan_ipv6.vlan_flag = HINIC3_UINT1_MAX; - tcam_key->key_info_vxlan_ipv6.vlan_flag = 0; /* Use inner dst ipv6 to fill the dst ipv6 of tcam_key. */ tcam_key->key_mask_vxlan_ipv6.dipv6_key0 = @@ -359,7 +352,7 @@ hinic3_fdir_tcam_ipv6_vxlan_init(struct rte_eth_dev *dev, * Pointer to the TCAM key. */ static void -hinic3_fdir_tcam_vxlan_init(struct rte_eth_dev *dev, +hinic3_fdir_tcam_vxlan_geneve_init(struct rte_eth_dev *dev, struct hinic3_fdir_filter *rule, struct hinic3_tcam_key *tcam_key) { @@ -416,10 +409,10 @@ hinic3_fdir_tcam_vxlan_init(struct rte_eth_dev *dev, HINIC3_UINT15_MAX; if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV4) - hinic3_fdir_tcam_vxlan_ipv4_init(rule, tcam_key); + hinic3_fdir_tcam_vxlan_geneve_ipv4_init(rule, tcam_key); else if (rule->ip_type == HINIC3_FDIR_IP_TYPE_IPV6) - hinic3_fdir_tcam_vxlan_ipv6_init(rule, tcam_key); + hinic3_fdir_tcam_vxlan_geneve_ipv6_init(rule, tcam_key); } static void @@ -432,7 +425,7 @@ hinic3_fdir_tcam_info_init(struct rte_eth_dev *dev, if (rule->tunnel_type == HINIC3_FDIR_TUNNEL_MODE_NORMAL) hinic3_fdir_tcam_notunnel_init(dev, rule, tcam_key); else - hinic3_fdir_tcam_vxlan_init(dev, rule, tcam_key); + hinic3_fdir_tcam_vxlan_geneve_init(dev, rule, tcam_key); /* Set the queue index. */ fdir_tcam_rule->data.qid = rule->rq_index; @@ -693,6 +686,16 @@ hinic3_fdir_tcam_info_htn_init(struct rte_eth_dev *dev, tcam_key_calculate(tcam_key, fdir_tcam_rule); } +static void hinic3_fdir_tcam_key_get(struct rte_eth_dev *dev, + struct hinic3_fdir_filter *rule, + struct hinic3_tcam_key *tcam_key) +{ + if (rule->tunnel_type == HINIC3_FDIR_TUNNEL_MODE_NORMAL) + hinic3_fdir_tcam_notunnel_init(dev, rule, tcam_key); + else + hinic3_fdir_tcam_vxlan_geneve_init(dev, rule, tcam_key); +} + /** * Find filter in given ethertype filter list. * @@ -841,7 +844,7 @@ hinic3_dynamic_lookup_tcam_filter(struct hinic3_nic_dev *nic_dev, * capacity of dynamic TCAM blocks. */ if (rule_nums >= block_cnt * HINIC3_TCAM_DYNAMIC_BLOCK_SIZE) { - if (block_cnt >= (HINIC3_TCAM_DYNAMIC_MAX_FILTERS / + if (block_cnt >= (HINIC3_TCAM_DYNAMIC_MAX_FILTERS(nic_dev) / HINIC3_TCAM_DYNAMIC_BLOCK_SIZE)) { PMD_DRV_LOG(ERR, "Dynamic tcam block is full, alloc failed!"); @@ -992,6 +995,10 @@ hinic3_set_fdir_ethertype_filter(void *hwdev, uint8_t pkt_type, void *filter, ui ethertype_cmd.pkt_type_en = en; ethertype_cmd.index = index; ethertype_cmd.qid = (uint8_t)ethertype_filter->queue; + if (en == 0) + ethertype_cmd.flags = 0; + else + ethertype_cmd.flags = (uint8_t)ethertype_filter->flags; err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC, HINIC3_NIC_CMD_SET_FDIR_STATUS, @@ -1001,6 +1008,9 @@ hinic3_set_fdir_ethertype_filter(void *hwdev, uint8_t pkt_type, void *filter, ui PMD_DRV_LOG(ERR, "set fdir ethertype rule failed, err: %d, status: 0x%x, out size: 0x%x, func_id %d", err, ethertype_cmd.head.status, out_size, ethertype_cmd.func_id); + if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) != 0 && en != 0) + hinic3_tcam_index_free(nic_dev, HINIC3_TCAM_GET_INDEX_IN_BLOCK(index), + HINIC3_TCAM_GET_DYNAMIC_BLOCK_INDEX(index)); return -EIO; } if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) != 0) { @@ -1213,24 +1223,16 @@ hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev, else hinic3_fdir_tcam_info_htn_init(dev, fdir_filter, &tcam_key, &fdir_tcam_rule); - /* Search for a filter. */ - tcam_filter = - hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key, - HINIC3_ACTION_ADD, HINIC3_INVALID_INDEX); - if (tcam_filter != NULL && add) { - PMD_DRV_LOG(ERR, "Filter exists."); - return -EEXIST; - } - if (tcam_filter == NULL && !add) { - PMD_DRV_LOG(ERR, "Filter doesn't exist."); - return -ENOENT; - } - - /* - * If the value of Add is true, the system performs the adding - * operation. - */ if (add) { + /* Search for a filter. */ + tcam_filter = + hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key, + HINIC3_ACTION_ADD, HINIC3_INVALID_INDEX); + if (tcam_filter != NULL) { + PMD_DRV_LOG(ERR, "Filter exists."); + return -EEXIST; + } + ret = hinic3_add_tcam_filter(dev, &tcam_key, &fdir_tcam_rule); if (ret) goto cfg_tcam_filter_err; @@ -1594,6 +1596,11 @@ hinic3_flow_add_del_ethertype_filter(struct rte_eth_dev *dev, /* Get dev private info. */ struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); int ret; + + if (!ethertype_filter) { + PMD_DRV_LOG(ERR, "ethertype_filter is NULL"); + return -EINVAL; + } /* Add or remove an Ethernet type filter rule. */ ret = hinic3_flow_add_del_ethertype_filter_rule(dev, ethertype_filter, add); @@ -1641,3 +1648,74 @@ hinic3_flow_add_del_ethertype_filter(struct rte_eth_dev *dev, hinic3_flow_add_del_ethertype_filter_rule(dev, ethertype_filter, !add); return ret; } + +int +hinic3_flow_query_fdir_filter(struct rte_eth_dev *dev, struct hinic3_fdir_filter *fdir_filter, + __rte_unused uint64_t *hits, __rte_unused uint64_t *bytes_count) +{ + struct hinic3_tcam_info *tcam_info = + HINIC3_DEV_PRIVATE_TO_TCAM_INFO(dev->data->dev_private); + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct hinic3_tcam_filter *tcam_filter; + struct hinic3_tcam_key tcam_key; + + memset((void *)&tcam_key, 0, sizeof(struct hinic3_tcam_key)); + hinic3_fdir_tcam_key_get(dev, fdir_filter, &tcam_key); + tcam_filter = hinic3_tcam_filter_lookup(&tcam_info->tcam_list, &tcam_key, + HINIC3_ACTION_NOT_ADD, fdir_filter->tcam_index); + if (tcam_filter == NULL) { + PMD_DRV_LOG(ERR, "Filter doesn't exist."); + return -EINVAL; + } + + if (fdir_filter->ip_type == HINIC3_FDIR_IP_TYPE_IPV4) { + PMD_DRV_LOG(INFO, "fdir ipv4 flow get:"); + PMD_DRV_LOG(INFO, "glb index:%d", fdir_filter->tcam_index); + PMD_DRV_LOG(INFO, "ether_type mask: 0x%x", fdir_filter->key_mask.ether_type); + PMD_DRV_LOG(INFO, "ether_type spec: 0x%x", fdir_filter->key_spec.ether_type); + PMD_DRV_LOG(INFO, "protocol mask: 0x%x", fdir_filter->key_mask.ipv4.proto); + PMD_DRV_LOG(INFO, "protocol spec: 0x%x", fdir_filter->key_spec.ipv4.proto); + PMD_DRV_LOG(INFO, "src_ip mask: 0x%x", fdir_filter->key_mask.ipv4.src_ip); + PMD_DRV_LOG(INFO, "src_ip spec: 0x%x", fdir_filter->key_spec.ipv4.src_ip); + PMD_DRV_LOG(INFO, "dst_ip mask: 0x%x", fdir_filter->key_mask.ipv4.dst_ip); + PMD_DRV_LOG(INFO, "dst_ip spec: 0x%x", fdir_filter->key_spec.ipv4.dst_ip); + PMD_DRV_LOG(INFO, "src_port mask: 0x%x", fdir_filter->key_mask.src_port); + PMD_DRV_LOG(INFO, "src_port spec: 0x%x", fdir_filter->key_spec.src_port); + PMD_DRV_LOG(INFO, "dst_port mask: 0x%x", fdir_filter->key_mask.dst_port); + PMD_DRV_LOG(INFO, "dst_port spec: 0x%x", fdir_filter->key_spec.dst_port); + PMD_DRV_LOG(INFO, "rule_nums: 0x%x", nic_dev->tcam_rule_nums); + PMD_DRV_LOG(INFO, "mark_id: 0x%x", fdir_filter->rq_index); + } else { + PMD_DRV_LOG(INFO, "fdir ipv6 flow get:"); + PMD_DRV_LOG(INFO, "glb index:%d", fdir_filter->tcam_index); + PMD_DRV_LOG(INFO, "protocol mask: 0x%x", fdir_filter->key_mask.ipv6.proto); + PMD_DRV_LOG(INFO, "protocol spec: 0x%x", fdir_filter->key_spec.ipv6.proto); + PMD_DRV_LOG(INFO, "src_ip mask: 0x%08x:%08x:%08x:%08x", + fdir_filter->key_mask.ipv6.src_ip[0], + fdir_filter->key_mask.ipv6.src_ip[1], + fdir_filter->key_mask.ipv6.src_ip[2], + fdir_filter->key_mask.ipv6.src_ip[3]); + PMD_DRV_LOG(INFO, "src_ip spec: 0x%08x:%08x:%08x:%08x", + fdir_filter->key_spec.ipv6.src_ip[0], + fdir_filter->key_spec.ipv6.src_ip[1], + fdir_filter->key_spec.ipv6.src_ip[2], + fdir_filter->key_spec.ipv6.src_ip[3]); + PMD_DRV_LOG(INFO, "dst_ip mask: 0x%08x:%08x:%08x:%08x", + fdir_filter->key_mask.ipv6.dst_ip[0], + fdir_filter->key_mask.ipv6.dst_ip[1], + fdir_filter->key_mask.ipv6.dst_ip[2], + fdir_filter->key_mask.ipv6.dst_ip[3]); + PMD_DRV_LOG(INFO, "dst_ip spec: 0x%08x:%08x:%08x:%08x", + fdir_filter->key_spec.ipv6.dst_ip[0], + fdir_filter->key_spec.ipv6.dst_ip[1], + fdir_filter->key_spec.ipv6.dst_ip[2], + fdir_filter->key_spec.ipv6.dst_ip[3]); + PMD_DRV_LOG(INFO, "src_port mask: 0x%x", fdir_filter->key_mask.src_port); + PMD_DRV_LOG(INFO, "src_port spec: 0x%x", fdir_filter->key_spec.src_port); + PMD_DRV_LOG(INFO, "dst_port mask: 0x%x", fdir_filter->key_mask.dst_port); + PMD_DRV_LOG(INFO, "dst_port spec: 0x%x", fdir_filter->key_spec.dst_port); + PMD_DRV_LOG(INFO, "rule_nums: 0x%x", nic_dev->tcam_rule_nums); + PMD_DRV_LOG(INFO, "mark_id: 0x%x", fdir_filter->rq_index); + } + return 0; +} diff --git a/drivers/net/hinic3/hinic3_fdir.h b/drivers/net/hinic3/hinic3_fdir.h index 277d89d4fd..73600788fe 100644 --- a/drivers/net/hinic3/hinic3_fdir.h +++ b/drivers/net/hinic3/hinic3_fdir.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2025 Huawei Technologies Co., Ltd + * Copyright (c) 2025-2026 Huawei Technologies Co., Ltd */ #ifndef _HINIC3_FDIR_H_ @@ -8,8 +8,13 @@ #define HINIC3_FLOW_MAX_PATTERN_NUM 16 #define HINIC3_TCAM_DYNAMIC_BLOCK_SIZE 16 +#define HINIC3_TCAM_DYNAMIC_MAX_FILTERS(nic_dev) \ + (HINIC3_IS_SP230_NIC(nic_dev) \ + ? HINIC3_TCAM_DYNAMIC_MAX_FILTERS_HTN \ + : HINIC3_TCAM_DYNAMIC_MAX_FILTERS_STN) -#define HINIC3_TCAM_DYNAMIC_MAX_FILTERS 1024 +#define HINIC3_TCAM_DYNAMIC_MAX_FILTERS_STN 2048 +#define HINIC3_TCAM_DYNAMIC_MAX_FILTERS_HTN 1024 #define HINIC3_PKT_TCAM_DYNAMIC_INDEX_START(block_index) \ (HINIC3_TCAM_DYNAMIC_BLOCK_SIZE * (block_index)) @@ -22,6 +27,8 @@ #define HINIC3_TCAM_INVALID_INDEX 0xFFFF +#define HINIC3_RSS_QUEUE_BUF 128 + enum hinic3_ether_type { HINIC3_PKT_TYPE_ARP = 1, HINIC3_PKT_TYPE_ARP_REQ, @@ -71,6 +78,7 @@ struct hinic3_fdir_filter { struct hinic3_ethertype_filter { int tcam_index[HINIC3_PKT_TYPE_BUTT]; uint16_t ether_type; /**< Ether type to match */ + uint16_t flags; uint16_t queue; /**< Queue assigned to when match*/ }; @@ -96,6 +104,7 @@ enum hinic3_fdir_tunnel_mode { HINIC3_FDIR_TUNNEL_MODE_GENEVE = 5, HINIC3_FDIR_TUNNEL_MODE_NSH = 6, HINIC3_FDIR_TUNNEL_MODE_IPIP = 7, + HINIC3_FDIR_TUNNEL_MODE_MAX = 8, }; enum hinic3_fdir_ip_type { @@ -186,7 +195,7 @@ struct hinic3_tcam_key_mem_htn { uint32_t rsvd0 : 16; uint32_t ip_proto : 8; uint32_t tunnel_type : 3; - uint32_t function_id_h: 5; + uint32_t function_id_h : 5; uint32_t function_id_l : 5; uint32_t ip_type : 2; @@ -250,7 +259,7 @@ struct hinic3_tcam_key_mem_htn { uint32_t rsvd8 : 16; uint32_t sport : 16; - uint32_t dipv4_l :16; + uint32_t dipv4_l : 16; uint32_t rsvd9 : 16; uint32_t dport : 16; @@ -668,6 +677,8 @@ int hinic3_flow_add_del_fdir_filter(struct rte_eth_dev *dev, int hinic3_flow_add_del_ethertype_filter(struct rte_eth_dev *dev, struct hinic3_ethertype_filter *ethertype_filter, bool add); +int hinic3_flow_query_fdir_filter(struct rte_eth_dev *dev, struct hinic3_fdir_filter *fdir_filter, + __rte_unused uint64_t *hits, __rte_unused uint64_t *bytes_count); void hinic3_free_fdir_filter(struct rte_eth_dev *dev); int hinic3_enable_rxq_fdir_filter(struct rte_eth_dev *dev, uint32_t queue_id, uint32_t able); diff --git a/drivers/net/hinic3/hinic3_flow.c b/drivers/net/hinic3/hinic3_flow.c index 5c255619e3..e88787452d 100644 --- a/drivers/net/hinic3/hinic3_flow.c +++ b/drivers/net/hinic3/hinic3_flow.c @@ -8,7 +8,6 @@ #include "base/hinic3_hwdev.h" #include "base/hinic3_nic_cfg.h" #include "hinic3_ethdev.h" -#include "hinic3_flow.h" #define HINIC3_UINT8_MAX 0xff @@ -19,12 +18,6 @@ typedef int (*hinic3_parse_filter_t)(struct rte_eth_dev *dev, struct rte_flow_error *error, struct hinic3_filter_t *filter); -/* Indicate valid filter mode . */ -struct hinic3_valid_pattern { - enum rte_flow_item_type *items; - hinic3_parse_filter_t parse_filter; -}; - static int hinic3_flow_parse_fdir_filter(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, const struct rte_flow_item pattern[], @@ -39,65 +32,12 @@ static int hinic3_flow_parse_ethertype_filter(struct rte_eth_dev *dev, struct rte_flow_error *error, struct hinic3_filter_t *filter); -static int hinic3_flow_parse_fdir_vxlan_filter(struct rte_eth_dev *dev, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error, - struct hinic3_filter_t *filter); - -/* - * Define a supported pattern array, including the matching patterns of - * various network protocols and corresponding parsing functions. - */ -static const struct hinic3_valid_pattern hinic3_supported_patterns[] = { - /* Support ethertype. */ - {pattern_ethertype, hinic3_flow_parse_ethertype_filter}, - /* Support ipv4 but not tunnel, and any field can be masked. */ - {pattern_ipv4, hinic3_flow_parse_fdir_filter}, - {pattern_ipv4_any, hinic3_flow_parse_fdir_filter}, - /* Support ipv4 + l4 but not tunnel, and any field can be masked. */ - {pattern_ipv4_udp, hinic3_flow_parse_fdir_filter}, - {pattern_ipv4_tcp, hinic3_flow_parse_fdir_filter}, - /* Support ipv4 + icmp not tunnel, and any field can be masked. */ - {pattern_ipv4_icmp, hinic3_flow_parse_fdir_filter}, - - /* Support ipv4 + l4 but not tunnel, and any field can be masked. */ - {pattern_ethertype_udp, hinic3_flow_parse_fdir_filter}, - {pattern_ethertype_tcp, hinic3_flow_parse_fdir_filter}, - - /* Support ipv4 + vxlan + any, and any field can be masked. */ - {pattern_ipv4_vxlan, hinic3_flow_parse_fdir_vxlan_filter}, - /* Support ipv4 + vxlan + ipv4, and any field can be masked. */ - {pattern_ipv4_vxlan_ipv4, hinic3_flow_parse_fdir_vxlan_filter}, - /* Support ipv4 + vxlan + ipv4 + l4, and any field can be masked. */ - {pattern_ipv4_vxlan_ipv4_tcp, hinic3_flow_parse_fdir_vxlan_filter}, - {pattern_ipv4_vxlan_ipv4_udp, hinic3_flow_parse_fdir_vxlan_filter}, - /* Support ipv4 + vxlan + ipv6, and any field can be masked. */ - {pattern_ipv4_vxlan_ipv6, hinic3_flow_parse_fdir_vxlan_filter}, - /* Support ipv4 + vxlan + ipv6 + l4, and any field can be masked. */ - {pattern_ipv4_vxlan_ipv6_tcp, hinic3_flow_parse_fdir_vxlan_filter}, - {pattern_ipv4_vxlan_ipv6_udp, hinic3_flow_parse_fdir_vxlan_filter}, - /* Support ipv4 + vxlan + l4, and any field can be masked. */ - {pattern_ipv4_vxlan_tcp, hinic3_flow_parse_fdir_vxlan_filter}, - {pattern_ipv4_vxlan_udp, hinic3_flow_parse_fdir_vxlan_filter}, - {pattern_ipv4_vxlan_any, hinic3_flow_parse_fdir_vxlan_filter}, - - /* Support ipv6 but not tunnel, and any field can be masked. */ - {pattern_ipv6, hinic3_flow_parse_fdir_filter}, - /* Support ipv6 + l4 but not tunnel, and any field can be masked. */ - {pattern_ipv6_udp, hinic3_flow_parse_fdir_filter}, - {pattern_ipv6_tcp, hinic3_flow_parse_fdir_filter}, - - /* Support ipv6 + vxlan + any, and any field can be masked. */ - {pattern_ipv6_vxlan, hinic3_flow_parse_fdir_vxlan_filter}, - {pattern_ipv6_vxlan_any, hinic3_flow_parse_fdir_vxlan_filter}, - - /* Support ipv6 + vxlan + l4, and any field can be masked. */ - {pattern_ipv6_vxlan_tcp, hinic3_flow_parse_fdir_vxlan_filter}, - {pattern_ipv6_vxlan_udp, hinic3_flow_parse_fdir_vxlan_filter}, - -}; +static int hinic3_flow_parse_fdir_vxlan_geneve_filter(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error, + struct hinic3_filter_t *filter); static inline void net_addr_to_host(uint32_t *dst, const uint32_t *src, size_t len) @@ -107,30 +47,243 @@ net_addr_to_host(uint32_t *dst, const uint32_t *src, size_t len) dst[i] = rte_be_to_cpu_32(src[i]); } -static bool -hinic3_match_pattern(enum rte_flow_item_type *item_array, - const struct rte_flow_item *pattern) -{ - const struct rte_flow_item *item = pattern; +/* IPINIP and GPE are split out due to chip support differences. */ +enum hinic3_flow_filter_kind { + HINIC3_FLOW_KIND_ETHERTYPE, /* [ETH]. */ + HINIC3_FLOW_KIND_NON_TUNNEL, /* single L3/L4 or ethertype L4. */ + HINIC3_FLOW_KIND_VXLAN_GENEVE, /* vxlan/geneve. */ + HINIC3_FLOW_KIND_GPE, /* vxlan-gpe. */ + HINIC3_FLOW_KIND_IPINIP, /* ip-in-ip. */ + HINIC3_FLOW_KIND_INVALID, +}; - /* skip the first void item. */ +/* + * The pattern is parsed as a small protocol graph. Every supported pattern + * starts with ETH and then follows one of the supported encapsulation paths + * (plain L3/L4, tunneled, or ip-in-ip). VOID items are transparent. + */ + +/* Peek at the next non-VOID item type. */ +static enum rte_flow_item_type +hinic3_flow_next(const struct rte_flow_item *item) +{ while (item->type == RTE_FLOW_ITEM_TYPE_VOID) item++; - /* Find no void item. */ - while (((*item_array == item->type) && - (*item_array != RTE_FLOW_ITEM_TYPE_END)) || - (item->type == RTE_FLOW_ITEM_TYPE_VOID)) { - if (item->type == RTE_FLOW_ITEM_TYPE_VOID) { - item++; - } else { - item_array++; - item++; + return item->type; +} + +/* Consume the next non-VOID item when it matches @p type. */ +static bool +hinic3_flow_take(const struct rte_flow_item **item, + enum rte_flow_item_type type) +{ + while ((*item)->type == RTE_FLOW_ITEM_TYPE_VOID) + (*item)++; + + if ((*item)->type != type) + return false; + + (*item)++; + return true; +} + +/* Return true when only the END item remains. */ +static bool +hinic3_flow_at_end(const struct rte_flow_item *item) +{ + return hinic3_flow_next(item) == RTE_FLOW_ITEM_TYPE_END; +} + +/* Finish a branch, which is valid only when END is reached. */ +static enum hinic3_flow_filter_kind +hinic3_flow_finish(const struct rte_flow_item *item, + enum hinic3_flow_filter_kind kind) +{ + return hinic3_flow_at_end(item) ? kind : HINIC3_FLOW_KIND_INVALID; +} + +/* Classify an inner L3 (IPv4/IPv6) with an optional L4, returning @p kind. */ +static enum hinic3_flow_filter_kind +hinic3_flow_classify_inner(const struct rte_flow_item **item, + enum hinic3_flow_filter_kind kind, + enum rte_flow_item_type outer_ip) +{ + enum rte_flow_item_type next = hinic3_flow_next(*item); + + if (next != RTE_FLOW_ITEM_TYPE_IPV4 && + next != RTE_FLOW_ITEM_TYPE_IPV6) + return HINIC3_FLOW_KIND_INVALID; + + /* + * An outer IPv6 plus any inner L3 does not fit in the TCAM, so only + * an IPv4 outer (or no outer at all) may carry an inner L3. + */ + if (outer_ip == RTE_FLOW_ITEM_TYPE_IPV6) + return HINIC3_FLOW_KIND_INVALID; + + hinic3_flow_take(item, next); + + switch (hinic3_flow_next(*item)) { + case RTE_FLOW_ITEM_TYPE_END: + return kind; + case RTE_FLOW_ITEM_TYPE_TCP: + case RTE_FLOW_ITEM_TYPE_UDP: + hinic3_flow_take(item, hinic3_flow_next(*item)); + return hinic3_flow_finish(*item, kind); + default: + return HINIC3_FLOW_KIND_INVALID; + } +} + +/* Consume a tunnel header and classify the payload that follows it. */ +static enum hinic3_flow_filter_kind +hinic3_flow_classify_tunnel(const struct rte_flow_item **item, + enum rte_flow_item_type tunnel_type, + enum rte_flow_item_type outer_ip) +{ + enum hinic3_flow_filter_kind kind = + tunnel_type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE ? + HINIC3_FLOW_KIND_GPE : HINIC3_FLOW_KIND_VXLAN_GENEVE; + enum rte_flow_item_type next; + + if (!hinic3_flow_take(item, tunnel_type)) + return HINIC3_FLOW_KIND_INVALID; + + next = hinic3_flow_next(*item); + + /* A bare tunnel with nothing after the header is valid. */ + if (next == RTE_FLOW_ITEM_TYPE_END) + return kind; + + /* GPE: an optional inner ETH (which may be terminal), then an L3(+L4). */ + if (tunnel_type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE) { + if (next == RTE_FLOW_ITEM_TYPE_ETH) { + hinic3_flow_take(item, RTE_FLOW_ITEM_TYPE_ETH); + if (hinic3_flow_at_end(*item)) + return kind; } + return hinic3_flow_classify_inner(item, kind, outer_ip); } - return (*item_array == RTE_FLOW_ITEM_TYPE_END && - item->type == RTE_FLOW_ITEM_TYPE_END); + /* vxlan/geneve: a bare L4/ANY, or an inner L3(+L4). */ + switch (next) { + case RTE_FLOW_ITEM_TYPE_TCP: + case RTE_FLOW_ITEM_TYPE_UDP: + case RTE_FLOW_ITEM_TYPE_ANY: + hinic3_flow_take(item, next); + return hinic3_flow_finish(*item, kind); + case RTE_FLOW_ITEM_TYPE_ETH: + case RTE_FLOW_ITEM_TYPE_IPV4: + case RTE_FLOW_ITEM_TYPE_IPV6: + if (next == RTE_FLOW_ITEM_TYPE_ETH) { + hinic3_flow_take(item, RTE_FLOW_ITEM_TYPE_ETH); + break; + } + /* Geneve accepts a bare inner L3; vxlan requires the inner ETH. */ + if (tunnel_type != RTE_FLOW_ITEM_TYPE_GENEVE) + return HINIC3_FLOW_KIND_INVALID; + break; + default: + return HINIC3_FLOW_KIND_INVALID; + } + + return hinic3_flow_classify_inner(item, kind, outer_ip); +} + +/* Classify the payload that follows the outer L3. */ +static enum hinic3_flow_filter_kind +hinic3_flow_classify_ip(const struct rte_flow_item **item, + enum rte_flow_item_type ip_type) +{ + enum rte_flow_item_type next = hinic3_flow_next(*item); + + switch (next) { + case RTE_FLOW_ITEM_TYPE_END: + return HINIC3_FLOW_KIND_NON_TUNNEL; + case RTE_FLOW_ITEM_TYPE_TCP: + hinic3_flow_take(item, RTE_FLOW_ITEM_TYPE_TCP); + return hinic3_flow_finish(*item, HINIC3_FLOW_KIND_NON_TUNNEL); + case RTE_FLOW_ITEM_TYPE_UDP: + hinic3_flow_take(item, RTE_FLOW_ITEM_TYPE_UDP); + next = hinic3_flow_next(*item); + switch (next) { + case RTE_FLOW_ITEM_TYPE_END: + return HINIC3_FLOW_KIND_NON_TUNNEL; + case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_GENEVE: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + return hinic3_flow_classify_tunnel(item, next, ip_type); + default: + return HINIC3_FLOW_KIND_INVALID; + } + case RTE_FLOW_ITEM_TYPE_ICMP: + case RTE_FLOW_ITEM_TYPE_ANY: + /* ICMP and ANY are valid only right after an IPv4 outer. */ + if (ip_type != RTE_FLOW_ITEM_TYPE_IPV4) + return HINIC3_FLOW_KIND_INVALID; + hinic3_flow_take(item, next); + return hinic3_flow_finish(*item, HINIC3_FLOW_KIND_NON_TUNNEL); + case RTE_FLOW_ITEM_TYPE_IPV4: + case RTE_FLOW_ITEM_TYPE_IPV6: + /* Ip-in-ip: a second L3 with an optional L4 (or ANY). */ + hinic3_flow_take(item, next); + switch (hinic3_flow_next(*item)) { + case RTE_FLOW_ITEM_TYPE_END: + return HINIC3_FLOW_KIND_IPINIP; + case RTE_FLOW_ITEM_TYPE_TCP: + case RTE_FLOW_ITEM_TYPE_UDP: + case RTE_FLOW_ITEM_TYPE_ANY: + hinic3_flow_take(item, hinic3_flow_next(*item)); + return hinic3_flow_finish(*item, HINIC3_FLOW_KIND_IPINIP); + default: + return HINIC3_FLOW_KIND_INVALID; + } + default: + return HINIC3_FLOW_KIND_INVALID; + } +} + +/* Classify a pattern into one of the supported filter kinds. */ +static enum hinic3_flow_filter_kind +hinic3_flow_classify(const struct rte_flow_item *pattern) +{ + const struct rte_flow_item *item = pattern; + enum rte_flow_item_type next; + + if (!hinic3_flow_take(&item, RTE_FLOW_ITEM_TYPE_ETH)) + return HINIC3_FLOW_KIND_INVALID; + + switch (hinic3_flow_next(item)) { + case RTE_FLOW_ITEM_TYPE_END: + return HINIC3_FLOW_KIND_ETHERTYPE; + case RTE_FLOW_ITEM_TYPE_TCP: + hinic3_flow_take(&item, RTE_FLOW_ITEM_TYPE_TCP); + return hinic3_flow_finish(item, HINIC3_FLOW_KIND_NON_TUNNEL); + case RTE_FLOW_ITEM_TYPE_UDP: + hinic3_flow_take(&item, RTE_FLOW_ITEM_TYPE_UDP); + next = hinic3_flow_next(item); + switch (next) { + case RTE_FLOW_ITEM_TYPE_END: + return HINIC3_FLOW_KIND_NON_TUNNEL; + case RTE_FLOW_ITEM_TYPE_VXLAN: + case RTE_FLOW_ITEM_TYPE_GENEVE: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + /* No outer IP: pass END so classify_inner allows it. */ + return hinic3_flow_classify_tunnel(&item, next, + RTE_FLOW_ITEM_TYPE_END); + default: + return HINIC3_FLOW_KIND_INVALID; + } + case RTE_FLOW_ITEM_TYPE_IPV4: + hinic3_flow_take(&item, RTE_FLOW_ITEM_TYPE_IPV4); + return hinic3_flow_classify_ip(&item, RTE_FLOW_ITEM_TYPE_IPV4); + case RTE_FLOW_ITEM_TYPE_IPV6: + hinic3_flow_take(&item, RTE_FLOW_ITEM_TYPE_IPV6); + return hinic3_flow_classify_ip(&item, RTE_FLOW_ITEM_TYPE_IPV6); + default: + return HINIC3_FLOW_KIND_INVALID; + } } /** @@ -142,20 +295,28 @@ hinic3_match_pattern(enum rte_flow_item_type *item_array, * Matched resolution filter. If no resolution filter is found, return NULL. */ static hinic3_parse_filter_t -hinic3_find_parse_filter_func(const struct rte_flow_item *pattern) +hinic3_find_parse_filter_func(struct rte_eth_dev *dev, + const struct rte_flow_item *pattern) { - hinic3_parse_filter_t parse_filter = NULL; - uint8_t i; - /* Traverse all supported patterns. */ - for (i = 0; i < RTE_DIM(hinic3_supported_patterns); i++) { - if (hinic3_match_pattern(hinic3_supported_patterns[i].items, pattern)) { - parse_filter = - hinic3_supported_patterns[i].parse_filter; - break; - } - } + struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); - return parse_filter; + switch (hinic3_flow_classify(pattern)) { + case HINIC3_FLOW_KIND_ETHERTYPE: + return hinic3_flow_parse_ethertype_filter; + case HINIC3_FLOW_KIND_NON_TUNNEL: + return hinic3_flow_parse_fdir_filter; + case HINIC3_FLOW_KIND_VXLAN_GENEVE: + return hinic3_flow_parse_fdir_vxlan_geneve_filter; + case HINIC3_FLOW_KIND_GPE: + return HINIC3_IS_SP620_NIC(nic_dev) ? + hinic3_flow_parse_fdir_vxlan_geneve_filter : NULL; + case HINIC3_FLOW_KIND_IPINIP: + return HINIC3_IS_SP620_NIC(nic_dev) ? + hinic3_flow_parse_fdir_filter : + hinic3_flow_parse_fdir_vxlan_geneve_filter; + default: + return NULL; + } } /** @@ -182,12 +343,29 @@ hinic3_flow_parse_action(struct rte_eth_dev *dev, const struct rte_flow_action_queue *act_q; const struct rte_flow_action *act = actions; - /* skip the first void item. */ - while (act->type == RTE_FLOW_ACTION_TYPE_VOID) - act++; + /* Find the last non-VOID action before END */ + const struct rte_flow_action *last_act = NULL; + for (act = actions; act->type != RTE_FLOW_ACTION_TYPE_END; act++) { + if (act->type != RTE_FLOW_ACTION_TYPE_VOID) + last_act = act; + } + if (last_act == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, actions, + "No valid action."); + return -rte_errno; + } + + act = last_act; switch (act->type) { case RTE_FLOW_ACTION_TYPE_QUEUE: + if (act->conf == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, "Invalid action queue config."); + return -rte_errno; + } act_q = (const struct rte_flow_action_queue *)act->conf; filter->fdir_filter.rq_index = act_q->index; if (filter->fdir_filter.rq_index >= dev->data->nb_rx_queues) { @@ -230,6 +408,14 @@ hinic3_flow_fdir_ipv4(const struct rte_flow_item *flow_item, mask_ipv4 = (const struct rte_flow_item_ipv4 *)flow_item->mask; spec_ipv4 = (const struct rte_flow_item_ipv4 *)flow_item->spec; + + filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + filter->fdir_filter.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL; + + /* When both L3 mask and spec are empty, return 0, then proceed to evaluate L4. */ + if (!mask_ipv4 && !spec_ipv4) + return 0; + if (!mask_ipv4 || !spec_ipv4) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, @@ -251,9 +437,6 @@ hinic3_flow_fdir_ipv4(const struct rte_flow_item *flow_item, return -rte_errno; } - /* Set the filter information. */ - filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; - filter->fdir_filter.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL; filter->fdir_filter.key_mask.ipv4.src_ip = rte_be_to_cpu_32(mask_ipv4->hdr.src_addr); filter->fdir_filter.key_spec.ipv4.src_ip = @@ -277,6 +460,14 @@ hinic3_flow_fdir_ipv6(const struct rte_flow_item *flow_item, mask_ipv6 = (const struct rte_flow_item_ipv6 *)flow_item->mask; spec_ipv6 = (const struct rte_flow_item_ipv6 *)flow_item->spec; + + filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + filter->fdir_filter.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL; + + /* When both L3 mask and spec are empty, return 0, then proceed to evaluate L4. */ + if (!mask_ipv6 && !spec_ipv6) + return 0; + if (!mask_ipv6 || !spec_ipv6) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, @@ -293,9 +484,6 @@ hinic3_flow_fdir_ipv6(const struct rte_flow_item *flow_item, return -rte_errno; } - /* Set the filter information. */ - filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; - filter->fdir_filter.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_NORMAL; net_addr_to_host(filter->fdir_filter.key_mask.ipv6.src_ip, (const uint32_t *)mask_ipv6->hdr.src_addr.a, 4); net_addr_to_host(filter->fdir_filter.key_spec.ipv6.src_ip, @@ -639,6 +827,12 @@ hinic3_flow_parse_ethertype_pattern(__rte_unused struct rte_eth_dev *dev, case RTE_ETHER_TYPE_LLDP: break; + case RTE_ETHER_TYPE_CNM: + break; + + case RTE_ETHER_TYPE_ECP: + break; + default: rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, @@ -686,14 +880,15 @@ static int hinic3_flow_fdir_tunnel_ipv4(struct rte_flow_error *error, struct hinic3_filter_t *filter, const struct rte_flow_item *flow_item, - enum hinic3_fdir_tunnel_mode tunnel_mode) + enum hinic3_fdir_tunnel_mode *tunnel_mode) { const struct rte_flow_item_ipv4 *spec_ipv4, *mask_ipv4; mask_ipv4 = (const struct rte_flow_item_ipv4 *)flow_item->mask; spec_ipv4 = (const struct rte_flow_item_ipv4 *)flow_item->spec; - if (tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { + if (*tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_MAX) { filter->fdir_filter.outer_ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + *tunnel_mode = HINIC3_FDIR_TUNNEL_MODE_NORMAL; if (!mask_ipv4 && !spec_ipv4) return 0; @@ -702,7 +897,7 @@ hinic3_flow_fdir_tunnel_ipv4(struct rte_flow_error *error, rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Invalid fdir filter, vxlan outer ipv4 mask or spec"); + "Invalid fdir filter, vxlan/geneve outer ipv4 mask or spec"); return -rte_errno; } @@ -718,7 +913,7 @@ hinic3_flow_fdir_tunnel_ipv4(struct rte_flow_error *error, mask_ipv4->hdr.next_proto_id || mask_ipv4->hdr.hdr_checksum) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Not supported by fdir filter, vxlan outer ipv4 only support src ip, dst ip"); + "Not supported by fdir filter, vxlan/geneve outer ipv4 only support src ip,dst ip"); return -rte_errno; } @@ -733,6 +928,10 @@ hinic3_flow_fdir_tunnel_ipv4(struct rte_flow_error *error, rte_be_to_cpu_32(spec_ipv4->hdr.dst_addr); } else { filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_IPV4; + if (*tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { + *tunnel_mode = HINIC3_FDIR_TUNNEL_MODE_IPIP; + filter->fdir_filter.tunnel_type = *tunnel_mode; + } if (!mask_ipv4 && !spec_ipv4) return 0; @@ -741,7 +940,7 @@ hinic3_flow_fdir_tunnel_ipv4(struct rte_flow_error *error, rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Invalid fdir filter, vxlan inner ipv4 mask or spec"); + "Invalid fdir filter, vxlan/geneve inner ipv4 mask or spec"); return -rte_errno; } @@ -758,7 +957,7 @@ hinic3_flow_fdir_tunnel_ipv4(struct rte_flow_error *error, rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Not supported by fdir filter, vxlan inner ipv4 only support src ip, dst ip, proto"); + "Not supported by fdir filter, vxlan/geneve inner ipv4 only support src ip,dst ip, proto"); return -rte_errno; } @@ -783,15 +982,16 @@ static int hinic3_flow_fdir_tunnel_ipv6(struct rte_flow_error *error, struct hinic3_filter_t *filter, const struct rte_flow_item *flow_item, - enum hinic3_fdir_tunnel_mode tunnel_mode) + enum hinic3_fdir_tunnel_mode *tunnel_mode) { const struct rte_flow_item_ipv6 *spec_ipv6, *mask_ipv6; mask_ipv6 = (const struct rte_flow_item_ipv6 *)flow_item->mask; spec_ipv6 = (const struct rte_flow_item_ipv6 *)flow_item->spec; - if (tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { + if (*tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_MAX) { filter->fdir_filter.outer_ip_type = HINIC3_FDIR_IP_TYPE_IPV6; + *tunnel_mode = HINIC3_FDIR_TUNNEL_MODE_NORMAL; if (!mask_ipv6 && !spec_ipv6) return 0; @@ -822,7 +1022,10 @@ hinic3_flow_fdir_tunnel_ipv6(struct rte_flow_error *error, (const uint32_t *)spec_ipv6->hdr.dst_addr.a, 4); } else { filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_IPV6; - + if (*tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { + *tunnel_mode = HINIC3_FDIR_TUNNEL_MODE_IPIP; + filter->fdir_filter.tunnel_type = *tunnel_mode; + } if (!mask_ipv6 && !spec_ipv6) return 0; @@ -869,7 +1072,7 @@ hinic3_flow_fdir_tunnel_tcp(struct rte_flow_error *error, if (tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Not supported by fdir filter, vxlan only support inner tcp"); + "Not supported by fdir filter, vxlan/geneve only support inner tcp"); return -rte_errno; } @@ -894,7 +1097,7 @@ hinic3_flow_fdir_tunnel_tcp(struct rte_flow_error *error, mask_tcp->hdr.tcp_urp) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Not supported by fdir filter, vxlan inner tcp only support src port,dst port"); + "Not supported by fdir filter, vxlan/geneve inner tcp only support src port,dst port"); return -rte_errno; } @@ -921,7 +1124,8 @@ hinic3_flow_fdir_tunnel_udp(struct rte_flow_error *error, mask_udp = (const struct rte_flow_item_udp *)flow_item->mask; spec_udp = (const struct rte_flow_item_udp *)flow_item->spec; - if (tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { + if (tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_MAX || + tunnel_mode == HINIC3_FDIR_TUNNEL_MODE_NORMAL) { /* * UDP is used to describe protocol, * spec and mask should be NULL. @@ -942,7 +1146,7 @@ hinic3_flow_fdir_tunnel_udp(struct rte_flow_error *error, rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Invalid fdir filter vxlan inner udp mask or spec"); + "Invalid fdir filter vxlan/geneve inner udp mask or spec"); return -rte_errno; } @@ -960,53 +1164,74 @@ hinic3_flow_fdir_tunnel_udp(struct rte_flow_error *error, return 0; } +static inline enum hinic3_fdir_tunnel_mode +hinic3_flow_tunnel_mode(enum rte_flow_item_type type) +{ + switch (type) { + case RTE_FLOW_ITEM_TYPE_GENEVE: + return HINIC3_FDIR_TUNNEL_MODE_GENEVE; + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + return HINIC3_FDIR_TUNNEL_MODE_GPE; + default: + return HINIC3_FDIR_TUNNEL_MODE_VXLAN; + } +} + static int -hinic3_flow_fdir_vxlan(struct rte_flow_error *error, - struct hinic3_filter_t *filter, - const struct rte_flow_item *flow_item) +hinic3_flow_fdir_vxlan_geneve(struct rte_flow_error *error, + struct hinic3_filter_t *filter, + enum hinic3_fdir_tunnel_mode tunnel_mode, + const struct rte_flow_item *flow_item) { const struct rte_flow_item_vxlan *spec_vxlan, *mask_vxlan; uint32_t vxlan_vni_id = 0; + uint32_t vxlan_vni_id_mask = 0; spec_vxlan = (const struct rte_flow_item_vxlan *)flow_item->spec; mask_vxlan = (const struct rte_flow_item_vxlan *)flow_item->mask; - filter->fdir_filter.tunnel_type = HINIC3_FDIR_TUNNEL_MODE_VXLAN; + filter->fdir_filter.tunnel_type = tunnel_mode; if (!spec_vxlan && !mask_vxlan) { return 0; } else if (filter->fdir_filter.outer_ip_type == HINIC3_FDIR_IP_TYPE_IPV6) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Invalid fdir filter vxlan mask or spec, ipv6 vxlan, don't support vni"); + "Invalid fdir filter vxlan/geneve mask or spec, ipv6 vxlan/geneve, don't support vni"); return -rte_errno; } if (!spec_vxlan || !mask_vxlan) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, flow_item, - "Invalid fdir filter vxlan mask or spec"); + "Invalid fdir filter vxlan/geneve mask or spec"); return -rte_errno; } memcpy(((uint8_t *)&vxlan_vni_id + 1), spec_vxlan->vni, 3); - filter->fdir_filter.key_mask.tunnel.tunnel_id = - rte_be_to_cpu_32(vxlan_vni_id); + filter->fdir_filter.key_spec.tunnel.tunnel_id = rte_be_to_cpu_32(vxlan_vni_id); + memcpy(((uint8_t *)&vxlan_vni_id_mask + 1), mask_vxlan->vni, 3); + filter->fdir_filter.key_mask.tunnel.tunnel_id = rte_be_to_cpu_32(vxlan_vni_id_mask); return 0; } static int -hinic3_flow_parse_fdir_vxlan_pattern(__rte_unused struct rte_eth_dev *dev, - const struct rte_flow_item *pattern, - struct rte_flow_error *error, - struct hinic3_filter_t *filter) +hinic3_flow_parse_fdir_vxlan_geneve_pattern(__rte_unused struct rte_eth_dev *dev, + const struct rte_flow_item *pattern, + struct rte_flow_error *error, + struct hinic3_filter_t *filter) { const struct rte_flow_item *flow_item = pattern; - enum hinic3_fdir_tunnel_mode tunnel_mode = - HINIC3_FDIR_TUNNEL_MODE_NORMAL; + enum hinic3_fdir_tunnel_mode tunnel_mode = HINIC3_FDIR_TUNNEL_MODE_MAX; enum rte_flow_item_type type; int err; + if (pattern == NULL) { + rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "Invalid pattern"); + return -rte_errno; + } + /* Inner and outer ip type, set it to any by default */ filter->fdir_filter.ip_type = HINIC3_FDIR_IP_TYPE_ANY; filter->fdir_filter.outer_ip_type = HINIC3_FDIR_IP_TYPE_ANY; @@ -1034,14 +1259,14 @@ hinic3_flow_parse_fdir_vxlan_pattern(__rte_unused struct rte_eth_dev *dev, case RTE_FLOW_ITEM_TYPE_IPV4: err = hinic3_flow_fdir_tunnel_ipv4(error, - filter, flow_item, tunnel_mode); + filter, flow_item, &tunnel_mode); if (err) return -rte_errno; break; case RTE_FLOW_ITEM_TYPE_IPV6: err = hinic3_flow_fdir_tunnel_ipv6(error, - filter, flow_item, tunnel_mode); + filter, flow_item, &tunnel_mode); if (err) return -rte_errno; break; @@ -1061,10 +1286,12 @@ hinic3_flow_parse_fdir_vxlan_pattern(__rte_unused struct rte_eth_dev *dev, break; case RTE_FLOW_ITEM_TYPE_VXLAN: - err = hinic3_flow_fdir_vxlan(error, filter, flow_item); + case RTE_FLOW_ITEM_TYPE_GENEVE: + case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: + tunnel_mode = hinic3_flow_tunnel_mode(type); + err = hinic3_flow_fdir_vxlan_geneve(error, filter, tunnel_mode, flow_item); if (err) return -rte_errno; - tunnel_mode = HINIC3_FDIR_TUNNEL_MODE_VXLAN; break; default: @@ -1095,16 +1322,16 @@ hinic3_flow_parse_fdir_vxlan_pattern(__rte_unused struct rte_eth_dev *dev, * 0 on success, non-zero on failure. */ static int -hinic3_flow_parse_fdir_vxlan_filter(struct rte_eth_dev *dev, - const struct rte_flow_attr *attr, - const struct rte_flow_item pattern[], - const struct rte_flow_action actions[], - struct rte_flow_error *error, - struct hinic3_filter_t *filter) +hinic3_flow_parse_fdir_vxlan_geneve_filter(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], + const struct rte_flow_action actions[], + struct rte_flow_error *error, + struct hinic3_filter_t *filter) { int ret; - ret = hinic3_flow_parse_fdir_vxlan_pattern(dev, pattern, error, filter); + ret = hinic3_flow_parse_fdir_vxlan_geneve_pattern(dev, pattern, error, filter); if (ret) return ret; @@ -1149,11 +1376,25 @@ hinic3_flow_parse(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, hinic3_parse_filter_t parse_filter; uint32_t pattern_num = 0; int ret = 0; - /* Check whether the parameter is valid. */ - if (!pattern || !actions || !attr) { + + if (!pattern) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "Pattern is NULL."); + return -rte_errno; + } + + if (!actions) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "Actions is NULL."); + return -rte_errno; + } + + if (!attr) { rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, - "NULL param."); + RTE_FLOW_ERROR_TYPE_ATTR, + NULL, "Attr is NULL."); return -rte_errno; } @@ -1170,7 +1411,7 @@ hinic3_flow_parse(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, * The corresponding filter is returned. If the filter is not found, * NULL is returned. */ - parse_filter = hinic3_find_parse_filter_func(pattern); + parse_filter = hinic3_find_parse_filter_func(dev, pattern); if (!parse_filter) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, pattern, "Unsupported pattern"); @@ -1299,9 +1540,7 @@ hinic3_flow_create(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, NULL, "Unsupported filter type."); goto free_flow; } - return flow; - free_flow: rte_free(flow); rte_free(filter_rules); @@ -1332,10 +1571,6 @@ hinic3_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, &rules->ethertype_filter, false); if (!ret) TAILQ_REMOVE(&nic_dev->filter_ethertype_list, flow, node); - - flow->rule = rules; - flow->filter_type = rules->filter_type; - TAILQ_REMOVE(&nic_dev->filter_ethertype_list, flow, node); break; case RTE_ETH_FILTER_FDIR: @@ -1467,10 +1702,48 @@ hinic3_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) return ret; } -/* Structure for managing flow table operations. */ +static int +hinic3_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, + __rte_unused const struct rte_flow_action *actions, + void *data, struct rte_flow_error *error) +{ + int ret = -EINVAL; + enum rte_filter_type filter_type; + struct hinic3_filter_t *filter_rules = NULL; + struct rte_flow_query_count *flow_count = NULL; + + if (!flow || !data) { + PMD_DRV_LOG(ERR, "Invalid flow parameter!"); + return -EPERM; + } + + flow_count = (struct rte_flow_query_count *)data; + filter_type = flow->filter_type; + switch (filter_type) { + case RTE_ETH_FILTER_ETHERTYPE: + PMD_DRV_LOG(ERR, "Ethertype type %d, current not to process", filter_type); + break; + case RTE_ETH_FILTER_FDIR: + filter_rules = (struct hinic3_filter_t *)flow->rule; + ret = hinic3_flow_query_fdir_filter(dev, &filter_rules->fdir_filter, + &flow_count->hits, &flow_count->bytes); + break; + default: + PMD_DRV_LOG(ERR, "Filter type %d not support to query", filter_type); + ret = -EINVAL; + break; + } + + if (ret) + rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "Failed to query flow."); + + return ret; +} + const struct rte_flow_ops hinic3_flow_ops = { .validate = hinic3_flow_validate, .create = hinic3_flow_create, .destroy = hinic3_flow_destroy, .flush = hinic3_flow_flush, + .query = hinic3_flow_query, }; diff --git a/drivers/net/hinic3/hinic3_flow.h b/drivers/net/hinic3/hinic3_flow.h deleted file mode 100644 index c4b38e44e7..0000000000 --- a/drivers/net/hinic3/hinic3_flow.h +++ /dev/null @@ -1,196 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2025 Huawei Technologies Co., Ltd - */ - -#ifndef _HINIC3_FLOW_H_ -#define _HINIC3_FLOW_H_ - -#include <rte_flow.h> - -/* Indicate the type of the IPv4 ICPM matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_icmp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_ICMP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 any protocol matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_any[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_ANY, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the Ether matching pattern. */ -static enum rte_flow_item_type pattern_ethertype[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the TCP matching pattern. */ -static enum rte_flow_item_type pattern_ethertype_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the UDP matching pattern. */ -static enum rte_flow_item_type pattern_ethertype_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan any protocol matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_any[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ANY, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_TCP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan UDP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan IPv4 matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_ipv4[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan IPv4 TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_ipv4_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan IPv4 UDP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_ipv4_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan IPv6 matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_ipv6[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan IPv6 TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_ipv6_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_TCP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 vxlan IPv6 UDP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_vxlan_ipv6_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 matching pattern. */ -static enum rte_flow_item_type pattern_ipv4[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 UDP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv4 TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv4_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 matching pattern. */ -static enum rte_flow_item_type pattern_ipv6[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 UDP matching pattern. */ -static enum rte_flow_item_type pattern_ipv6_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv6_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, - RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_TCP, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv6_vxlan[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 VXLAN any protocol matching pattern. */ -static enum rte_flow_item_type pattern_ipv6_vxlan_any[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_ANY, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 VXLAN TCP matching pattern. */ -static enum rte_flow_item_type pattern_ipv6_vxlan_tcp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_TCP, RTE_FLOW_ITEM_TYPE_END, -}; - -/* Indicate the type of the IPv6 VXLAN UDP matching pattern. */ -static enum rte_flow_item_type pattern_ipv6_vxlan_udp[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV6, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_VXLAN, - RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_END, -}; - -#endif /**< _HINIC3_FLOW_H_ */ -- 2.33.0

