From: Chengwen Feng <fengcheng...@huawei.com> In the current driver implementation, if you want to configure the same action for all tunnel packets, you need to configure a rule for each specific tunnel packet. e.g:
flow create 0 ingress pattern ipv4 / udp / vxlan / end actions ... flow create 0 ingress pattern ipv4 / udp / vxlan-gpe / end actions ... flow create 0 ingress pattern ipv4 / udp / geneve / end actions ... flow create 0 ingress pattern ipv4 / nvgre / end actions ... flow create 0 ingress pattern ipv6 / udp / vxlan / end actions ... flow create 0 ingress pattern ipv6 / udp / vxlan-gpe / end actions ... flow create 0 ingress pattern ipv6 / udp / geneve / end actions ... flow create 0 ingress pattern ipv6 / nvgre / end actions ... It occupies entry rule resources and is inconvenient to use. The hardware supports 'tunnel packet' meta-data bit, this bit was set when the hardware detects any type of supported tunnel packets. This commit supports general tunnel match by identify RTE_FLOW_ITEM_TYPE_PTYPE, and only support PTYPE_TUNNEL (0xf000). We will treat it (0xf000) as a general tunnel, all tunnel types that hardware recognized will match it. After this commit, we could just create one rule per case: case1: match all tunnel packets rule1: flow create 0 ingress pattern ptype packet_type is 0xf000 / end actions ... case2: match all ipv4 tunnel packets rule2: flow create 0 ingress pattern ipv4 ptype packet_type is 0xf000 / end actions ... case3: match all ipv6 tunnel packets rule3: flow create 0 ingress pattern ipv6 ptype packet_type is 0xf000 / end actions ... Signed-off-by: Chengwen Feng <fengcheng...@huawei.com> Signed-off-by: Jie Hai <haij...@huawei.com> --- doc/guides/nics/features/hns3.ini | 1 + drivers/net/hns3/hns3_flow.c | 45 ++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/doc/guides/nics/features/hns3.ini b/doc/guides/nics/features/hns3.ini index 8b623d30778c..d4472f904bc1 100644 --- a/doc/guides/nics/features/hns3.ini +++ b/doc/guides/nics/features/hns3.ini @@ -59,6 +59,7 @@ icmp = Y ipv4 = Y ipv6 = Y nvgre = Y +ptype = P sctp = Y tcp = Y udp = Y diff --git a/drivers/net/hns3/hns3_flow.c b/drivers/net/hns3/hns3_flow.c index e287420fb0f8..89ee2c6c6614 100644 --- a/drivers/net/hns3/hns3_flow.c +++ b/drivers/net/hns3/hns3_flow.c @@ -155,13 +155,15 @@ static enum rte_flow_item_type first_items[] = { RTE_FLOW_ITEM_TYPE_NVGRE, RTE_FLOW_ITEM_TYPE_VXLAN, RTE_FLOW_ITEM_TYPE_GENEVE, - RTE_FLOW_ITEM_TYPE_VXLAN_GPE + RTE_FLOW_ITEM_TYPE_VXLAN_GPE, + RTE_FLOW_ITEM_TYPE_PTYPE }; static enum rte_flow_item_type L2_next_items[] = { RTE_FLOW_ITEM_TYPE_VLAN, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_IPV6 + RTE_FLOW_ITEM_TYPE_IPV6, + RTE_FLOW_ITEM_TYPE_PTYPE }; static enum rte_flow_item_type L3_next_items[] = { @@ -169,7 +171,8 @@ static enum rte_flow_item_type L3_next_items[] = { RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_SCTP, RTE_FLOW_ITEM_TYPE_NVGRE, - RTE_FLOW_ITEM_TYPE_ICMP + RTE_FLOW_ITEM_TYPE_ICMP, + RTE_FLOW_ITEM_TYPE_PTYPE }; static enum rte_flow_item_type L4_next_items[] = { @@ -1204,6 +1207,32 @@ hns3_parse_geneve(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, return 0; } +static int +hns3_parse_ptype(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, + struct rte_flow_error *error) +{ + const struct rte_flow_item_ptype *spec = item->spec; + const struct rte_flow_item_ptype *mask = item->mask; + + if (spec == NULL || mask == NULL) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "PTYPE must set spec and mask at the same time!"); + + if (spec->packet_type != RTE_PTYPE_TUNNEL_MASK || + (mask->packet_type & RTE_PTYPE_TUNNEL_MASK) != RTE_PTYPE_TUNNEL_MASK) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_MASK, item, + "PTYPE only support general tunnel!"); + + /* + * Set tunnel_type to non-zero, so that meta-data's tunnel packet bit + * will be set, then hardware will match tunnel packet. + */ + rule->key_conf.spec.tunnel_type = 1; + return 0; +} + static int hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, struct rte_flow_error *error) @@ -1237,6 +1266,9 @@ hns3_parse_tunnel(const struct rte_flow_item *item, struct hns3_fdir_rule *rule, case RTE_FLOW_ITEM_TYPE_GENEVE: ret = hns3_parse_geneve(item, rule, error); break; + case RTE_FLOW_ITEM_TYPE_PTYPE: + ret = hns3_parse_ptype(item, rule, error); + break; default: return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, @@ -1336,7 +1368,12 @@ is_tunnel_packet(enum rte_flow_item_type type) if (type == RTE_FLOW_ITEM_TYPE_VXLAN_GPE || type == RTE_FLOW_ITEM_TYPE_VXLAN || type == RTE_FLOW_ITEM_TYPE_NVGRE || - type == RTE_FLOW_ITEM_TYPE_GENEVE) + type == RTE_FLOW_ITEM_TYPE_GENEVE || + /* + * Here treat PTYPE as tunnel type because driver only support PTYPE_TUNNEL, + * other PTYPE will return error in hns3_parse_ptype() later. + */ + type == RTE_FLOW_ITEM_TYPE_PTYPE) return true; return false; } -- 2.22.0