/
phprus
/
github_dpdk
Обзор
Документация
Войти
/
phprus
/
github_dpdk
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
drivers/net/sxe2/sxe2_flow_parse_pattern.c
1 935 строк
77 KB
Jie Liu
net/sxe2: support custom UDP tunnel ports
30 июн 2026, 17:11
30 июн 2026, 17:11
fff2488
Код
Авторство
О чём код?
/* SPDX-License-Identifier: BSD-3-Clause * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd. */ #include "sxe2_flow_parse_pattern.h" #include "rte_common.h" #include "rte_flow.h" #include "sxe2_common_log.h" #include "sxe2_ethdev.h" #include "sxe2_cmd_chnl.h" #include "sxe2_flow_define.h" const struct sxe2_flow_expand_node sxe2_support_expansion[SXE2_EXPANSION_MAX] = { [SXE2_EXPANSION_OUTER_ETH] = { .type = RTE_FLOW_ITEM_TYPE_ETH, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "eth", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_VLAN, SXE2_EXPANSION_OUTER_IPV4, SXE2_EXPANSION_OUTER_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_OUTER_VLAN] = { .type = RTE_FLOW_ITEM_TYPE_VLAN, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "vlan", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_QINQ, SXE2_EXPANSION_OUTER_IPV4, SXE2_EXPANSION_OUTER_IPV6, SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_QINQ] = { .type = RTE_FLOW_ITEM_TYPE_VLAN, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "vlan", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_IPV4, SXE2_EXPANSION_OUTER_IPV6, SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_IPV4] = { .type = RTE_FLOW_ITEM_TYPE_IPV4, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_IPIP, .is_tunnel = false, .name = "ipv4", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_UDP, SXE2_EXPANSION_OUTER_TCP, SXE2_EXPANSION_OUTER_SCTP, SXE2_EXPANSION_GRE, SXE2_EXPANSION_NVGRE, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_IPV6] = { .type = RTE_FLOW_ITEM_TYPE_IPV6, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_IPIP, .is_tunnel = false, .name = "ipv6", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_IPV6_FRAG_EXT, SXE2_EXPANSION_OUTER_UDP, SXE2_EXPANSION_OUTER_TCP, SXE2_EXPANSION_OUTER_SCTP, SXE2_EXPANSION_GRE, SXE2_EXPANSION_NVGRE, SXE2_EXPANSION_ETH, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_IPV6_FRAG_EXT] = { .type = RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "ipv6_frag_ext", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_UDP] = { .type = RTE_FLOW_ITEM_TYPE_UDP, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "udp", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_VXLAN, SXE2_EXPANSION_VXLAN_GPE, SXE2_EXPANSION_GENEVE, SXE2_EXPANSION_GTPU, SXE2_EXPANSION_GRE, SXE2_EXPANSION_NVGRE, SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_TCP] = { .type = RTE_FLOW_ITEM_TYPE_TCP, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "tcp", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_SCTP] = { .type = RTE_FLOW_ITEM_TYPE_SCTP, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "sctp", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_OUTER_END), }, [SXE2_EXPANSION_OUTER_END] = { .type = RTE_FLOW_ITEM_TYPE_END, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE, .is_tunnel = false, .name = "end", .next = SXE2_FLOW_EXPAND_NEXT(0), }, [SXE2_EXPANSION_VXLAN] = { .type = RTE_FLOW_ITEM_TYPE_VXLAN, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_VXLAN, .is_tunnel = true, .name = "vxlan", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_ETH, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_VXLAN_GPE] = { .type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_VXLAN, .is_tunnel = true, .name = "vxlan_gpe", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_ETH, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_GRE] = { .type = RTE_FLOW_ITEM_TYPE_GRE, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_GRE, .is_tunnel = true, .name = "gre", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_ETH, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_NVGRE] = { .type = RTE_FLOW_ITEM_TYPE_NVGRE, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_GRE, .is_tunnel = true, .name = "nvgre", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_ETH, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_GENEVE] = { .type = RTE_FLOW_ITEM_TYPE_GENEVE, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_GENEVE, .is_tunnel = true, .name = "geneve", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_ETH, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_GTPU] = { .type = RTE_FLOW_ITEM_TYPE_GTPU, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_GTPU, .is_tunnel = true, .name = "gtpu", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_ETH] = { .type = RTE_FLOW_ITEM_TYPE_ETH, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "eth", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_VLAN, SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_VLAN] = { .type = RTE_FLOW_ITEM_TYPE_VLAN, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "vlan", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_IPV4, SXE2_EXPANSION_IPV6, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_IPV4] = { .type = RTE_FLOW_ITEM_TYPE_IPV4, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "ipv4", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_UDP, SXE2_EXPANSION_TCP, SXE2_EXPANSION_SCTP, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_IPV6] = { .type = RTE_FLOW_ITEM_TYPE_IPV6, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "ipv6", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_UDP, SXE2_EXPANSION_TCP, SXE2_EXPANSION_SCTP, SXE2_EXPANSION_IPV6_FRAG_EXT, SXE2_EXPANSION_END), }, [SXE2_EXPANSION_UDP] = { .type = RTE_FLOW_ITEM_TYPE_UDP, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "udp", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_END), }, [SXE2_EXPANSION_TCP] = { .type = RTE_FLOW_ITEM_TYPE_TCP, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "tcp", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_END), }, [SXE2_EXPANSION_SCTP] = { .type = RTE_FLOW_ITEM_TYPE_SCTP, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "sctp", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_END), }, [SXE2_EXPANSION_IPV6_FRAG_EXT] = { .type = RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "ipv6_frag_ext", .next = SXE2_FLOW_EXPAND_NEXT(SXE2_EXPANSION_END), }, [SXE2_EXPANSION_END] = { .type = RTE_FLOW_ITEM_TYPE_END, .tunnel_type = SXE2_FLOW_TUNNEL_TYPE_PARENT, .is_tunnel = true, .name = "end", .next = SXE2_FLOW_EXPAND_NEXT(0), } }; const char *sxe2_flow_type_name[SXE2_FLOW_TYPE_MAX] = { [SXE2_FLOW_MAC_PAY] = "SXE2_FLOW_MAC_PAY", [SXE2_FLOW_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_GRE_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_GRE_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GTPU_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GTPU_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_VLAN_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_VXGEN_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_VXGEN_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV6_UDP_GRE_MAC_IPV6_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV4_SCTP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_FRAG_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_FRAG_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_UDP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_UDP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_TCP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_TCP_PAY", [SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_SCTP_PAY] = "SXE2_FLOW_MAC_IPV4_UDP_GRE_MAC_IPV6_SCTP_PAY", }; #define SXE2_FLOW_TYPE_NAME_MAX_LEN 128 static int32_t sxe2_flow_get_flow_type(struct sxe2_flow *flow) { int32_t ret = -EINVAL; uint16_t i = 0; uint16_t len = 0; char flow_type_name[SXE2_FLOW_TYPE_NAME_MAX_LEN] = {0}; len = snprintf(flow_type_name, sizeof(flow_type_name), "SXE2_FLOW_"); i += len; if (sxe2_test_bit(SXE2_FLOW_HDR_ETH, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "MAC_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_IPV4, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "IPV4_"); i += len; } else if (sxe2_test_bit(SXE2_FLOW_HDR_IPV6, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "IPV6_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_IPV_FRAG, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "FRAG_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_UDP, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "UDP_"); i += len; } else if (sxe2_test_bit(SXE2_FLOW_HDR_TCP, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "TCP_"); i += len; } else if (sxe2_test_bit(SXE2_FLOW_HDR_SCTP, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "SCTP_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_VXLAN, flow->pattern_outer.hdrs) || sxe2_test_bit(SXE2_FLOW_HDR_GENEVE, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "VXGEN_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_GRE, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "GRE_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_GTPU, flow->pattern_outer.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "GTPU_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_ETH, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "MAC_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_VLAN, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "VLAN_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_IPV4, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "IPV4_"); i += len; } else if (sxe2_test_bit(SXE2_FLOW_HDR_IPV6, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "IPV6_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_IPV_FRAG, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "FRAG_"); i += len; } if (sxe2_test_bit(SXE2_FLOW_HDR_UDP, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "UDP_"); i += len; } else if (sxe2_test_bit(SXE2_FLOW_HDR_TCP, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "TCP_"); i += len; } else if (sxe2_test_bit(SXE2_FLOW_HDR_SCTP, flow->pattern_inner.hdrs)) { len = snprintf(flow_type_name + i, sizeof(flow_type_name) - i, "SCTP_"); i += len; } len = snprintf(flow_type_name + i, sizeof(flow_type_name), "PAY"); i += len; for (i = 0; i < SXE2_FLOW_TYPE_MAX; i++) { if (sxe2_flow_type_name[i] == NULL) continue; if (strcmp(flow_type_name, sxe2_flow_type_name[i]) == 0) { flow->meta.flow_type = i; ret = 0; break; } } if (ret != 0) PMD_LOG_ERR(DRV, "Unsupported flow type. %s is not supported.", flow_type_name); return ret; } static int32_t sxe2_flow_is_expandable_item(const struct rte_flow_item *item) { int32_t ret = -EINVAL; switch (item->type) { case RTE_FLOW_ITEM_TYPE_ETH: case RTE_FLOW_ITEM_TYPE_VLAN: case RTE_FLOW_ITEM_TYPE_IPV4: case RTE_FLOW_ITEM_TYPE_IPV6: case RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT: case RTE_FLOW_ITEM_TYPE_UDP: case RTE_FLOW_ITEM_TYPE_TCP: case RTE_FLOW_ITEM_TYPE_SCTP: case RTE_FLOW_ITEM_TYPE_VXLAN: case RTE_FLOW_ITEM_TYPE_VXLAN_GPE: case RTE_FLOW_ITEM_TYPE_GRE: case RTE_FLOW_ITEM_TYPE_NVGRE: case RTE_FLOW_ITEM_TYPE_GENEVE: case RTE_FLOW_ITEM_TYPE_GTPU: case RTE_FLOW_ITEM_TYPE_VOID: case RTE_FLOW_ITEM_TYPE_END: ret = 0; break; default: break; } return ret; } static int32_t sxe2_flow_valid_next_expansion(enum sxe2_expansion *current, const struct rte_flow_item *item, enum sxe2_flow_tunnel_type *tunnel_type, BITMAP_TYPE *flow_type) { int32_t ret = -EINVAL; const struct rte_flow_item *next; const enum sxe2_expansion *next_expansion = current; const struct sxe2_flow_expand_node *node; uint8_t len = 0; char typelist[512] = {0}; char error[1024] = {0}; enum sxe2_flow_tunnel_type tunnel_type_now = SXE2_FLOW_TUNNEL_TYPE_NONE; enum sxe2_flow_tunnel_type tunnel_type_next = SXE2_FLOW_TUNNEL_TYPE_NONE; uint8_t is_tunnel_now = 0; uint8_t is_tunnel_next = 0; if (item->type != sxe2_support_expansion[*current].type) { ret = -EINVAL; goto l_end; } next = item; do { next++; if (next->type == RTE_FLOW_ITEM_TYPE_VOID) continue; break; } while (1); node = &sxe2_support_expansion[*current]; next_expansion = node->next; while (*next_expansion != 0) { len = strlen(typelist); snprintf(typelist + len, sizeof(typelist) - len, "%s|", sxe2_support_expansion[*next_expansion].name); if (sxe2_support_expansion[*next_expansion].type == next->type) { ret = 0; break; } next_expansion++; } if (ret != 0) { snprintf(error, sizeof(error), "The next item of %s only can be one of [%s].", sxe2_support_expansion[*current].name, typelist); PMD_LOG_ERR(INIT, "Invalid pattern sequence. %s", error); goto l_end; } tunnel_type_now = sxe2_support_expansion[*current].tunnel_type; tunnel_type_next = sxe2_support_expansion[*next_expansion].tunnel_type; is_tunnel_now = sxe2_support_expansion[*current].is_tunnel; is_tunnel_next = sxe2_support_expansion[*next_expansion].is_tunnel; if (!is_tunnel_now && is_tunnel_next) { if (tunnel_type_next == SXE2_FLOW_TUNNEL_TYPE_PARENT) *tunnel_type = tunnel_type_now; else *tunnel_type = tunnel_type_next; } l_end: sxe2_set_bit(*current, flow_type); *current = *next_expansion; return ret; } static int32_t sxe2_flow_parse_pattern_eth(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next, bool is_inner) { const struct rte_flow_item_eth *eth_spec; const struct rte_flow_item_eth *eth_mask; const struct rte_ether_addr *dst_addr_mask; const struct rte_ether_addr *src_addr_mask; const struct rte_ether_addr *dst_addr_spec; const struct rte_ether_addr *src_addr_spec; rte_be16_t type_mask; rte_be16_t type_spec; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; uint16_t ether_type; eth_spec = item->spec; eth_mask = item->mask; if (eth_spec == NULL && eth_mask == NULL) goto l_end; dst_addr_mask = ð_mask->hdr.dst_addr; src_addr_mask = ð_mask->hdr.src_addr; dst_addr_spec = ð_spec->hdr.dst_addr; src_addr_spec = ð_spec->hdr.src_addr; type_mask = eth_mask->hdr.ether_type; type_spec = eth_spec->hdr.ether_type; if (eth_mask->has_vlan) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported eth mask has_vlan."); PMD_LOG_ERR(DRV, "Unsupported eth mask has_vlan"); ret = -EINVAL; goto l_end; } if (!rte_is_zero_ether_addr(dst_addr_mask)) { if (!rte_is_broadcast_ether_addr(dst_addr_mask)) sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_DA, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_DA, pattern->map_spec); rte_memcpy(pattern->item_spec.eth.dst_addr, dst_addr_spec, RTE_ETHER_ADDR_LEN); rte_memcpy(pattern->item_mask.eth.dst_addr, dst_addr_mask, RTE_ETHER_ADDR_LEN); } if (!rte_is_zero_ether_addr(src_addr_mask)) { if (!rte_is_broadcast_ether_addr(src_addr_mask)) sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_SA, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_SA, pattern->map_spec); rte_memcpy(pattern->item_spec.eth.src_addr, src_addr_spec, RTE_ETHER_ADDR_LEN); rte_memcpy(pattern->item_mask.eth.src_addr, src_addr_mask, RTE_ETHER_ADDR_LEN); } if (type_mask != 0) { if (type_mask != UINT16_MAX) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported eth ether_type mask"); PMD_LOG_ERR(DRV, "unsupported eth ether_type mask[0x%x].", type_mask); ret = -EINVAL; goto l_end; } if (next != SXE2_EXPANSION_OUTER_END && next != SXE2_EXPANSION_END) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported eth ether_type match with next item."); PMD_LOG_ERR(DRV, "unsupported eth ether_type match with next item."); ret = -EINVAL; goto l_end; } ether_type = rte_be_to_cpu_16(type_spec); if (ether_type == RTE_ETHER_TYPE_IPV4 || ether_type == RTE_ETHER_TYPE_IPV6) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Ether_type unsupported ipv4/ipv6(0x0800/0x86DD)."); PMD_LOG_ERR(DRV, "Ether_type unsupported ipv4/ipv6(0x0800/0x86DD)."); ret = -EINVAL; goto l_end; } if (ether_type == RTE_ETHER_TYPE_VLAN || ether_type == RTE_ETHER_TYPE_QINQ || ether_type == RTE_ETHER_TYPE_QINQ1) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Ether_type unsupported vlan(0x8100/0x88a8/0x9100)."); PMD_LOG_ERR(DRV, "Ether_type unsupported vlan(0x8100/0x88a8/0x9100)."); ret = -EINVAL; goto l_end; } if (ether_type <= SXE2_FLOW_ETH_TYPE_MIN) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Ether_type need max 1500."); PMD_LOG_ERR(DRV, "Ether_type need max 1500."); ret = -EINVAL; goto l_end; } sxe2_set_bit(SXE2_FLOW_FLD_ID_ETH_TYPE, pattern->map_spec); pattern->item_spec.eth.ether_type = type_spec; pattern->item_mask.eth.ether_type = type_mask; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_ETH, pattern->hdrs); pattern->rss_type_allow |= RTE_ETH_RSS_ETH; pattern->rss_type_allow |= RTE_ETH_RSS_L2_DST_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L2_SRC_ONLY; if (next == SXE2_EXPANSION_OUTER_END || next == SXE2_EXPANSION_END) pattern->rss_type_allow |= RTE_ETH_RSS_L2_PAYLOAD; return ret; } static int32_t sxe2_flow_parse_pattern_vlan(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_vlan *vlan_spec; const struct rte_flow_item_vlan *vlan_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; rte_be16_t vlan_tci_mask; rte_be16_t vlan_tci_spec; rte_be16_t eth_proto_mask; rte_be16_t eth_proto_spec; int32_t ret = 0; vlan_spec = item->spec; vlan_mask = item->mask; bool is_qinq = false; if (sxe2_test_bit(SXE2_FLOW_HDR_VLAN, pattern->hdrs)) is_qinq = true; if (vlan_spec == NULL && vlan_mask == NULL) goto l_end; vlan_tci_mask = vlan_mask->hdr.vlan_tci; vlan_tci_spec = vlan_spec->hdr.vlan_tci; eth_proto_mask = vlan_mask->hdr.eth_proto; eth_proto_spec = vlan_spec->hdr.eth_proto; if (vlan_mask->has_more_vlan || vlan_mask->reserved) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported vlan mask has_qinq."); PMD_LOG_ERR(DRV, "Unsupported vlan mask has_qinq"); ret = -EINVAL; goto l_end; } if (vlan_tci_mask) { if (vlan_tci_spec == 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "vlan id can't be 0."); ret = -EINVAL; goto l_end; } } if (eth_proto_mask) { if (eth_proto_mask != UINT16_MAX) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported vlan ether_type mask"); PMD_LOG_ERR(DRV, "unsupported vlan ether_type mask."); ret = -EINVAL; goto l_end; } if (eth_proto_spec != RTE_BE16(0x8100) && eth_proto_spec != RTE_BE16(0x88a8) && eth_proto_spec != RTE_BE16(0x9100)) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported vlan ether_type, only support 0x8100, 0x88a8 and 0x9100."); PMD_LOG_ERR(DRV, "Unsupported vlan ether_type, only support 0x8100, 0x88a8 and 0x9100."); ret = -EINVAL; goto l_end; } } if (!is_qinq) { if (vlan_tci_mask) { if (vlan_tci_mask == RTE_BE16(0x0fff)) { sxe2_set_bit(SXE2_FLOW_FLD_ID_S_VID, pattern->map_spec); } else if (vlan_tci_mask == UINT16_MAX) { sxe2_set_bit(SXE2_FLOW_FLD_ID_S_TCI, pattern->map_spec); } else { sxe2_set_bit(SXE2_FLOW_FLD_ID_S_TCI, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_S_TCI, pattern->map_spec); } } if (eth_proto_mask) sxe2_set_bit(SXE2_FLOW_FLD_ID_S_TPID, pattern->map_spec); } else { if (vlan_tci_mask) { if (vlan_tci_mask == RTE_BE16(0x0fff)) { sxe2_set_bit(SXE2_FLOW_FLD_ID_C_VID, pattern->map_spec); } else if (vlan_tci_mask == UINT16_MAX) { sxe2_set_bit(SXE2_FLOW_FLD_ID_C_TCI, pattern->map_spec); } else { sxe2_set_bit(SXE2_FLOW_FLD_ID_C_TCI, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_C_TCI, pattern->map_spec); } } if (eth_proto_mask) sxe2_set_bit(SXE2_FLOW_FLD_ID_C_TPID, pattern->map_spec); } if (is_qinq) { pattern->item_spec.qinq.type = eth_proto_spec; pattern->item_mask.qinq.type = eth_proto_mask; pattern->item_spec.qinq.vlan = vlan_tci_spec; pattern->item_mask.qinq.vlan = vlan_tci_mask; } else { pattern->item_spec.vlan.type = eth_proto_spec; pattern->item_mask.vlan.type = eth_proto_mask; pattern->item_spec.vlan.vlan = vlan_tci_spec; pattern->item_mask.vlan.vlan = vlan_tci_mask; } l_end: pattern->rss_type_allow |= RTE_ETH_RSS_S_VLAN; pattern->rss_type_allow |= RTE_ETH_RSS_C_VLAN; if (!is_qinq) sxe2_set_bit(SXE2_FLOW_HDR_VLAN, pattern->hdrs); else sxe2_set_bit(SXE2_FLOW_HDR_QINQ, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_ipv4(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next, bool is_inner) { const struct rte_flow_item_ipv4 *ipv4_spec; const struct rte_flow_item_ipv4 *ipv4_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; ipv4_spec = item->spec; ipv4_mask = item->mask; if (ipv4_mask == NULL && ipv4_spec == NULL) goto l_end; if (ipv4_mask->hdr.version_ihl || ipv4_mask->hdr.total_length || ipv4_mask->hdr.hdr_checksum || ipv4_mask->hdr.packet_id) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some IPv4 mask."); PMD_LOG_ERR(DRV, "Unsupported some IPv4 mask"); ret = -EINVAL; goto l_end; } if (ipv4_mask->hdr.src_addr) { if (ipv4_mask->hdr.src_addr != UINT32_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_SA, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_SA, pattern->map_spec); pattern->item_spec.ipv4.saddr = ipv4_spec->hdr.src_addr; pattern->item_mask.ipv4.saddr = ipv4_mask->hdr.src_addr; } if (ipv4_mask->hdr.dst_addr) { if (ipv4_mask->hdr.dst_addr != UINT32_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_DA, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_DA, pattern->map_spec); pattern->item_spec.ipv4.daddr = ipv4_spec->hdr.dst_addr; pattern->item_mask.ipv4.daddr = ipv4_mask->hdr.dst_addr; } if (ipv4_mask->hdr.next_proto_id) { if (next != SXE2_EXPANSION_OUTER_END && next != SXE2_EXPANSION_END) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "IPv4 proto id must be the last partten."); PMD_LOG_ERR(DRV, "IPv4 proto id must be the last partten."); ret = -EINVAL; goto l_end; } if (ipv4_mask->hdr.next_proto_id != UINT8_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec); pattern->item_spec.ipv4.protocol = ipv4_spec->hdr.next_proto_id; pattern->item_mask.ipv4.protocol = ipv4_mask->hdr.next_proto_id; } if (ipv4_mask->hdr.time_to_live) { if (ipv4_mask->hdr.time_to_live != UINT8_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_TTL, pattern->map_mask); if (ipv4_spec->hdr.time_to_live == 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "ipv4 ttl must be not 0."); PMD_LOG_ERR(DRV, "ipv4 ttl must be not 0."); ret = -EINVAL; goto l_end; } sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_TTL, pattern->map_spec); pattern->item_spec.ipv4.ttl = ipv4_spec->hdr.time_to_live; pattern->item_mask.ipv4.ttl = ipv4_mask->hdr.time_to_live; } if (ipv4_mask->hdr.type_of_service) { if (ipv4_mask->hdr.type_of_service != UINT8_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_TOS, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_TOS, pattern->map_spec); pattern->item_spec.ipv4.tos = ipv4_spec->hdr.type_of_service; pattern->item_mask.ipv4.tos = ipv4_mask->hdr.type_of_service; } if (ipv4_mask->hdr.fragment_offset) { if (ipv4_spec->hdr.fragment_offset == rte_cpu_to_be_16(RTE_IPV4_HDR_MF_FLAG) && ipv4_mask->hdr.fragment_offset == rte_cpu_to_be_16(RTE_IPV4_HDR_MF_FLAG)) { if (next != SXE2_EXPANSION_OUTER_END && next != SXE2_EXPANSION_END) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "IPv4 frag offset must be the last partten."); PMD_LOG_ERR(DRV, "IPv4 frag offset must be the last partten."); ret = -EINVAL; goto l_end; } sxe2_set_bit(SXE2_FLOW_HDR_IPV_FRAG, pattern->hdrs); } else { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported ipv4 fragment_offset cfg."); PMD_LOG_ERR(DRV, "Unsupported ipv4 fragment_offset cfg."); ret = -EINVAL; goto l_end; } } l_end: sxe2_set_bit(SXE2_FLOW_HDR_IPV4, pattern->hdrs); pattern->rss_type_allow |= RTE_ETH_RSS_IPV4; pattern->rss_type_allow |= RTE_ETH_RSS_L3_SRC_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L3_DST_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_IPV4_CHKSUM; if (next == SXE2_EXPANSION_OUTER_END || next == SXE2_EXPANSION_END) { pattern->rss_type_allow |= RTE_ETH_RSS_FRAG_IPV4; pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV4_OTHER; } return ret; } static int32_t sxe2_flow_parse_pattern_ipv6(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_ipv6 *ipv6_spec; const struct rte_flow_item_ipv6 *ipv6_mask; uint32_t vtc_flow_mask; uint32_t tc_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; ipv6_spec = item->spec; ipv6_mask = item->mask; uint8_t ipv6_addr_mask[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; uint8_t ipv6_addr_empty[16] = { 0 }; if (ipv6_mask == NULL && ipv6_spec == NULL) goto l_end; if (ipv6_mask->hdr.payload_len || ipv6_mask->has_hop_ext || ipv6_mask->has_route_ext || ipv6_mask->has_frag_ext || ipv6_mask->has_auth_ext || ipv6_mask->has_esp_ext || ipv6_mask->has_dest_ext || ipv6_mask->has_mobil_ext || ipv6_mask->has_hip_ext || ipv6_mask->has_shim6_ext) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some IPv6 mask"); PMD_LOG_ERR(DRV, "Unsupported some IPv6 mask"); ret = -EINVAL; goto l_end; } if (memcmp(&ipv6_mask->hdr.src_addr, ipv6_addr_empty, sizeof(ipv6_addr_empty)) != 0) { if (memcmp(&ipv6_mask->hdr.src_addr, ipv6_addr_mask, sizeof(ipv6_addr_mask)) != 0) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_SA, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_SA, pattern->map_spec); rte_memcpy(&pattern->item_spec.ipv6.saddr, &ipv6_spec->hdr.src_addr, sizeof(ipv6_spec->hdr.src_addr)); rte_memcpy(&pattern->item_mask.ipv6.saddr, &ipv6_mask->hdr.src_addr, sizeof(ipv6_mask->hdr.src_addr)); } if (memcmp(&ipv6_mask->hdr.dst_addr, ipv6_addr_empty, sizeof(ipv6_addr_empty)) != 0) { if (memcmp(&ipv6_mask->hdr.dst_addr, ipv6_addr_mask, sizeof(ipv6_addr_mask)) != 0) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_DA, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_DA, pattern->map_spec); rte_memcpy(&pattern->item_spec.ipv6.daddr, &ipv6_spec->hdr.dst_addr, sizeof(ipv6_spec->hdr.dst_addr)); rte_memcpy(&pattern->item_mask.ipv6.daddr, &ipv6_mask->hdr.dst_addr, sizeof(ipv6_mask->hdr.dst_addr)); } if (ipv6_mask->hdr.vtc_flow) { vtc_flow_mask = rte_be_to_cpu_32(ipv6_mask->hdr.vtc_flow); tc_mask = vtc_flow_mask & (SXE2_IPV6_TC_MASK << SXE2_IPV6_TC_SHIFT); if (tc_mask != vtc_flow_mask) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "ipv6 vtc_flow only support TC mask."); ret = -EINVAL; goto l_end; } if (tc_mask != (SXE2_IPV6_TC_MASK << SXE2_IPV6_TC_SHIFT)) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_DSCP, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_DSCP, pattern->map_spec); pattern->item_spec.ipv6.pri_ver_flow = ipv6_spec->hdr.vtc_flow; pattern->item_mask.ipv6.pri_ver_flow = ipv6_mask->hdr.vtc_flow; } if (ipv6_mask->hdr.proto) { if (next != SXE2_EXPANSION_OUTER_END && next != SXE2_EXPANSION_END) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "IPv6 proto id must be the last partten."); PMD_LOG_ERR(DRV, "IPv6 proto id must be the last partten."); ret = -EINVAL; goto l_end; } if (ipv6_mask->hdr.proto != UINT8_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec); pattern->item_spec.ipv6.nexthdr = ipv6_spec->hdr.proto; pattern->item_mask.ipv6.nexthdr = ipv6_mask->hdr.proto; } if (ipv6_mask->hdr.hop_limits) { if (ipv6_mask->hdr.hop_limits != UINT8_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_TTL, pattern->map_mask); if (ipv6_spec->hdr.hop_limits == 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "ipv6 hop must be not 0."); PMD_LOG_ERR(DRV, "ipv6 hop must be not 0."); ret = -EINVAL; goto l_end; } sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_TTL, pattern->map_spec); pattern->item_spec.ipv6.hop_limit = ipv6_spec->hdr.hop_limits; pattern->item_mask.ipv6.hop_limit = ipv6_mask->hdr.hop_limits; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_IPV6, pattern->hdrs); pattern->rss_type_allow |= RTE_ETH_RSS_IPV6; pattern->rss_type_allow |= RTE_ETH_RSS_L3_SRC_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L3_DST_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L3_PRE32; pattern->rss_type_allow |= RTE_ETH_RSS_L3_PRE48; pattern->rss_type_allow |= RTE_ETH_RSS_L3_PRE64; if (next == SXE2_EXPANSION_OUTER_END || next == SXE2_EXPANSION_END) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV6_OTHER; return ret; } static int32_t sxe2_flow_parse_pattern_ipv6_frag_ext(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_spec; const struct rte_flow_item_ipv6_frag_ext *ipv6_frag_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; ipv6_frag_spec = item->spec; ipv6_frag_mask = item->mask; if (ipv6_frag_mask == NULL && ipv6_frag_spec == NULL) goto l_end; if (ipv6_frag_mask->hdr.reserved || ipv6_frag_mask->hdr.frag_data || ipv6_frag_mask->hdr.id || ipv6_frag_mask->hdr.next_header) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some IPv6 frag ext mask"); PMD_LOG_ERR(DRV, "Unsupported some IPv6 frag ext mask"); ret = -EINVAL; goto l_end; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_IPV_FRAG, pattern->hdrs); pattern->rss_type_allow |= RTE_ETH_RSS_FRAG_IPV6; return ret; } static int32_t sxe2_flow_parse_pattern_tcp(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_tcp *tcp_spec; const struct rte_flow_item_tcp *tcp_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; tcp_spec = item->spec; tcp_mask = item->mask; if (tcp_mask == NULL && tcp_spec == NULL) goto l_end; if (tcp_mask->hdr.sent_seq || tcp_mask->hdr.recv_ack || tcp_mask->hdr.data_off || tcp_mask->hdr.tcp_flags || tcp_mask->hdr.rx_win || tcp_mask->hdr.cksum || tcp_mask->hdr.tcp_urp) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some TCP mask"); PMD_LOG_ERR(DRV, "Unsupported some TCP mask"); ret = -EINVAL; goto l_end; } if (tcp_mask->hdr.src_port) { if (tcp_mask->hdr.src_port != UINT16_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_TCP_SRC_PORT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_TCP_SRC_PORT, pattern->map_spec); pattern->item_spec.tcp.source = tcp_spec->hdr.src_port; pattern->item_mask.tcp.source = tcp_mask->hdr.src_port; } if (tcp_mask->hdr.dst_port) { if (tcp_mask->hdr.dst_port != UINT16_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_TCP_DST_PORT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_TCP_DST_PORT, pattern->map_spec); pattern->item_spec.tcp.dest = tcp_spec->hdr.dst_port; pattern->item_mask.tcp.dest = tcp_mask->hdr.dst_port; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_TCP, pattern->hdrs); if (sxe2_test_bit(SXE2_FLOW_HDR_IPV4, pattern->hdrs)) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV4_TCP; else if (sxe2_test_bit(SXE2_FLOW_HDR_IPV6, pattern->hdrs)) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV6_TCP; pattern->rss_type_allow |= RTE_ETH_RSS_L4_SRC_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L4_DST_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L4_CHKSUM; return ret; } static int32_t sxe2_flow_parse_pattern_udp(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_udp *udp_spec; const struct rte_flow_item_udp *udp_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; udp_spec = item->spec; udp_mask = item->mask; if (udp_mask == NULL && udp_spec == NULL) goto l_end; if (udp_mask->hdr.dgram_len || udp_mask->hdr.dgram_cksum) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some UDP mask"); PMD_LOG_ERR(DRV, "Unsupported some UDP mask"); ret = -EINVAL; goto l_end; } if (udp_mask->hdr.src_port) { if (udp_mask->hdr.src_port != UINT16_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_SRC_PORT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_SRC_PORT, pattern->map_spec); pattern->item_spec.udp.source = udp_spec->hdr.src_port; pattern->item_mask.udp.source = udp_mask->hdr.src_port; } if (udp_mask->hdr.dst_port) { if (udp_mask->hdr.dst_port != UINT16_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, pattern->map_spec); pattern->item_spec.udp.dest = udp_spec->hdr.dst_port; pattern->item_mask.udp.dest = udp_mask->hdr.dst_port; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_UDP, pattern->hdrs); if (sxe2_test_bit(SXE2_FLOW_HDR_IPV4, pattern->hdrs)) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV4_UDP; else if (sxe2_test_bit(SXE2_FLOW_HDR_IPV6, pattern->hdrs)) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV6_UDP; pattern->rss_type_allow |= RTE_ETH_RSS_L4_SRC_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L4_DST_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L4_CHKSUM; return ret; } static int32_t sxe2_flow_parse_pattern_sctp(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_sctp *sctp_spec; const struct rte_flow_item_sctp *sctp_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; sctp_spec = item->spec; sctp_mask = item->mask; if (sctp_mask == NULL && sctp_spec == NULL) goto l_end; if (sctp_mask->hdr.cksum || sctp_mask->hdr.tag) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some SCTP mask"); PMD_LOG_ERR(DRV, "Unsupported some SCTP mask"); ret = -EINVAL; goto l_end; } if (sctp_mask->hdr.src_port) { if (sctp_mask->hdr.src_port != UINT16_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_SCTP_SRC_PORT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_SCTP_SRC_PORT, pattern->map_spec); pattern->item_spec.sctp.src_port = sctp_spec->hdr.src_port; pattern->item_mask.sctp.src_port = sctp_mask->hdr.src_port; } if (sctp_mask->hdr.dst_port) { if (sctp_mask->hdr.dst_port != UINT16_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_SCTP_DST_PORT, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_SCTP_DST_PORT, pattern->map_spec); pattern->item_spec.sctp.dst_port = sctp_spec->hdr.dst_port; pattern->item_mask.sctp.dst_port = sctp_mask->hdr.dst_port; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_SCTP, pattern->hdrs); if (sxe2_test_bit(SXE2_FLOW_HDR_IPV4, pattern->hdrs)) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV4_SCTP; else if (sxe2_test_bit(SXE2_FLOW_HDR_IPV6, pattern->hdrs)) pattern->rss_type_allow |= RTE_ETH_RSS_NONFRAG_IPV6_SCTP; pattern->rss_type_allow |= RTE_ETH_RSS_L4_SRC_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L4_DST_ONLY; pattern->rss_type_allow |= RTE_ETH_RSS_L4_CHKSUM; return ret; } static int32_t sxe2_flow_parse_pattern_geneve(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_geneve *geneve_spec; const struct rte_flow_item_geneve *geneve_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; geneve_spec = item->spec; geneve_mask = item->mask; if (!(geneve_spec && geneve_mask)) goto l_end; if (geneve_mask->protocol || geneve_mask->ver_opt_len_o_c_rsvd0 || geneve_mask->rsvd1) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some Geneve mask"); PMD_LOG_ERR(DRV, "Unsupported some Geneve mask"); ret = -EINVAL; goto l_end; } if (geneve_mask->vni[0] || geneve_mask->vni[1] || geneve_mask->vni[2]) { if (strcmp((const char *)geneve_mask->vni, "\xFF\xFF\xFF") != 0) sxe2_set_bit(SXE2_FLOW_FLD_ID_GENEVE_VNI, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_GENEVE_VNI, pattern->map_spec); pattern->item_spec.geneve.vni = (geneve_spec->vni[2] << 16) | (geneve_spec->vni[1] << 8) | geneve_spec->vni[0]; pattern->item_mask.geneve.vni = (geneve_mask->vni[2] << 16) | (geneve_mask->vni[1] << 8) | geneve_mask->vni[0]; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_GENEVE, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_gtpu(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_gtp *gtpu_spec; const struct rte_flow_item_gtp *gtpu_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; gtpu_spec = item->spec; gtpu_mask = item->mask; if (gtpu_mask == NULL && gtpu_spec == NULL) goto l_end; if (gtpu_mask->v_pt_rsv_flags || gtpu_mask->msg_type || gtpu_mask->msg_len) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some GTPU mask"); PMD_LOG_ERR(DRV, "Unsupported some GTPU mask"); ret = -EINVAL; goto l_end; } if (gtpu_mask->teid) { if (gtpu_mask->teid != UINT32_MAX) sxe2_set_bit(SXE2_FLOW_FLD_ID_GTPU_TEID, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_GTPU_TEID, pattern->map_spec); pattern->item_spec.gtpu.teid = gtpu_spec->teid; pattern->item_mask.gtpu.teid = gtpu_mask->teid; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_GTPU, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_gre(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_gre *gre_spec; const struct rte_flow_item_gre *gre_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; gre_spec = item->spec; gre_mask = item->mask; if (gre_mask == NULL && gre_spec == NULL) goto l_end; if (gre_mask->c_rsvd0_ver || gre_mask->protocol) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some GRE mask"); PMD_LOG_ERR(DRV, "Unsupported some GRE mask"); ret = -EINVAL; goto l_end; } l_end: sxe2_set_bit(SXE2_FLOW_HDR_GRE, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_nvgre(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_nvgre *nvgre_spec; const struct rte_flow_item_nvgre *nvgre_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; nvgre_spec = item->spec; nvgre_mask = item->mask; if (nvgre_mask == NULL && nvgre_spec == NULL) goto l_end; if (nvgre_mask->c_k_s_rsvd0_ver || nvgre_mask->protocol || nvgre_mask->flow_id) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some NVGRE mask"); PMD_LOG_ERR(DRV, "Unsupported some NVGRE mask"); ret = -EINVAL; goto l_end; } if (nvgre_mask->tni[0] || nvgre_mask->tni[1] || nvgre_mask->tni[2]) { if (strcmp((const char *)nvgre_mask->tni, "\xFF\xFF\xFF") != 0) sxe2_set_bit(SXE2_FLOW_FLD_ID_NVGRE_TNI, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_NVGRE_TNI, pattern->map_spec); pattern->item_spec.nvgre.tni = (nvgre_spec->tni[2] << 16) | (nvgre_spec->tni[1] << 8) | (nvgre_spec->tni[0]); pattern->item_mask.nvgre.tni = (nvgre_mask->tni[2] << 16) | (nvgre_mask->tni[1] << 8) | (nvgre_mask->tni[0]); } l_end: sxe2_set_bit(SXE2_FLOW_HDR_GRE, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_vxlan(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_vxlan *vxlan_spec; const struct rte_flow_item_vxlan *vxlan_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; vxlan_spec = item->spec; vxlan_mask = item->mask; if (vxlan_mask == NULL && vxlan_spec == NULL) goto l_end; if (vxlan_mask->flags || vxlan_mask->rsvd1 || vxlan_mask->rsvd0[0] || vxlan_mask->rsvd0[1] || vxlan_mask->rsvd0[2]) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some VXLAN mask"); PMD_LOG_ERR(DRV, "Unsupported some VXLAN mask"); ret = -EINVAL; goto l_end; } if (vxlan_mask->vni[0] || vxlan_mask->vni[1] || vxlan_mask->vni[2]) { if (strcmp((const char *)vxlan_mask->vni, "\xFF\xFF\xFF") != 0) sxe2_set_bit(SXE2_FLOW_FLD_ID_VXLAN_VNI, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_VXLAN_VNI, pattern->map_spec); pattern->item_spec.vxlan.vni = (vxlan_spec->vni[2] << 16) | (vxlan_spec->vni[1] << 8) | (vxlan_spec->vni[0]); pattern->item_mask.vxlan.vni = (vxlan_mask->vni[2] << 16) | (vxlan_mask->vni[1] << 8) | (vxlan_mask->vni[0]); } l_end: sxe2_set_bit(SXE2_FLOW_HDR_VXLAN, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_vxlan_gpe(const struct rte_flow_item *item, struct rte_flow_error *error, struct sxe2_flow *flow, enum sxe2_expansion next __rte_unused, bool is_inner) { const struct rte_flow_item_vxlan_gpe *vxlan_gpe_spec; const struct rte_flow_item_vxlan_gpe *vxlan_gpe_mask; struct sxe2_flow_pattern *pattern = is_inner ? &flow->pattern_inner : &flow->pattern_outer; int32_t ret = 0; vxlan_gpe_spec = item->spec; vxlan_gpe_mask = item->mask; if (vxlan_gpe_mask == NULL && vxlan_gpe_spec == NULL) goto l_end; if (vxlan_gpe_mask->flags || vxlan_gpe_mask->protocol || vxlan_gpe_mask->rsvd1 || vxlan_gpe_mask->rsvd0[0] || vxlan_gpe_mask->rsvd0[1]) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported some VXLAN-GPE mask"); PMD_LOG_ERR(DRV, "Unsupported some VXLAN-GPE mask"); ret = -EINVAL; goto l_end; } if (vxlan_gpe_mask->vni[0] || vxlan_gpe_mask->vni[1] || vxlan_gpe_mask->vni[2]) { if (strcmp((const char *)vxlan_gpe_mask->vni, "\xFF\xFF\xFF") != 0) sxe2_set_bit(SXE2_FLOW_FLD_ID_VXLAN_VNI, pattern->map_mask); sxe2_set_bit(SXE2_FLOW_FLD_ID_VXLAN_VNI, pattern->map_spec); pattern->item_spec.vxlan.vni = (vxlan_gpe_spec->vni[2] << 16) | (vxlan_gpe_spec->vni[1] << 8) | (vxlan_gpe_spec->vni[0]); pattern->item_mask.vxlan.vni = (vxlan_gpe_mask->vni[2] << 16) | (vxlan_gpe_mask->vni[1] << 8) | (vxlan_gpe_mask->vni[0]); } l_end: sxe2_set_bit(SXE2_FLOW_HDR_VXLAN, pattern->hdrs); return ret; } static int32_t sxe2_flow_parse_pattern_ipip(struct sxe2_flow *flow, BITMAP_TYPE *flow_type) { sxe2_set_bit(SXE2_EXPANSION_IPIP, flow_type); if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) { sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, flow->pattern_outer.map_spec); if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type)) flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV4; if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) flow->pattern_outer.item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_IPV6; } if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) { sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, flow->pattern_outer.map_spec); if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) { flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_ETH; } else { if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type)) flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_IPV4; if (sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) flow->pattern_outer.item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_IPV6; } } return 0; } static int32_t sxe2_flow_add_udp_tunnel_port(struct sxe2_adapter *adapter, enum sxe2_flow_udp_tunnel_protocol proto, struct sxe2_flow *flow, BITMAP_TYPE *flow_type) { int32_t ret = 0; uint16_t tun_port; tun_port = adapter->flow_ctxt.tunnel_port_list[proto]; if (tun_port == 0xffff || tun_port == 0) { ret = -EINVAL; PMD_LOG_ERR(DRV, "UDP tunnel port not initialized, proto: %d", proto); goto l_end; } if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) { ret = -EINVAL; PMD_LOG_ERR(DRV, "UDP must be over tunnel"); goto l_end; } sxe2_set_bit(SXE2_FLOW_FLD_ID_UDP_DST_PORT, flow->pattern_outer.map_spec); flow->pattern_outer.item_spec.udp.dest = rte_cpu_to_be_16(tun_port); l_end: return ret; } int32_t sxe2_flow_add_tunnel_port(struct rte_eth_dev *dev, struct rte_flow_error *error, struct sxe2_flow *flow, BITMAP_TYPE *flow_type, enum sxe2_flow_tunnel_type tunnel_type) { int32_t ret = 0; enum sxe2_flow_udp_tunnel_protocol proto = SXE2_FLOW_UDP_TUNNEL_MAX; struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev); struct sxe2_flow_pattern *pattern = &flow->pattern_outer; switch (tunnel_type) { case SXE2_FLOW_TUNNEL_TYPE_VXLAN: if (sxe2_test_bit(SXE2_EXPANSION_ETH, flow_type)) { proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN; } else if (sxe2_test_bit(SXE2_EXPANSION_IPV4, flow_type) || sxe2_test_bit(SXE2_EXPANSION_IPV6, flow_type)) { proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_VXLAN_GPE; } break; case SXE2_FLOW_TUNNEL_TYPE_GTPU: proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GTP_U; break; case SXE2_FLOW_TUNNEL_TYPE_GENEVE: proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_GENEVE; break; case SXE2_FLOW_TUNNEL_TYPE_GRE: if (sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) { proto = SXE2_FLOW_UDP_TUNNEL_PROTOCOL_NVGRE; } else { if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV4, flow_type)) { pattern->item_spec.ipv4.protocol = SXE2_FLOW_IP_PROTOCOL_GRE; sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV4_PROT, pattern->map_spec); } if (sxe2_test_bit(SXE2_EXPANSION_OUTER_IPV6, flow_type)) { pattern->item_spec.ipv6.nexthdr = SXE2_FLOW_IP_PROTOCOL_GRE; sxe2_set_bit(SXE2_FLOW_FLD_ID_IPV6_PROT, pattern->map_spec); } } break; case SXE2_FLOW_TUNNEL_TYPE_IPIP: ret = sxe2_flow_parse_pattern_ipip(flow, flow_type); break; default: break; } if (proto != SXE2_FLOW_UDP_TUNNEL_MAX) { ret = sxe2_flow_add_udp_tunnel_port(adapter, proto, flow, flow_type); if (ret != 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, NULL, "Failed to add udp port for tunnel."); PMD_LOG_ERR(DRV, "Failed to add udp port for tunnel, ret %d.", ret); goto l_end; } } if (tunnel_type != SXE2_FLOW_TUNNEL_TYPE_NONE) { if (!sxe2_test_bit(SXE2_EXPANSION_OUTER_UDP, flow_type)) sxe2_set_bit(SXE2_FLOW_HDR_IPV_OTHER, pattern->hdrs); } l_end: return ret; } struct sxe2_flow_parse_pattern_ops sxe2_flow_parse_pattern_list[] = { [SXE2_EXPANSION_OUTER_ETH] = { .is_inner = false, .func = sxe2_flow_parse_pattern_eth, }, [SXE2_EXPANSION_OUTER_VLAN] = { .is_inner = false, .func = sxe2_flow_parse_pattern_vlan, }, [SXE2_EXPANSION_OUTER_QINQ] = { .is_inner = false, .func = sxe2_flow_parse_pattern_vlan, }, [SXE2_EXPANSION_OUTER_IPV4] = { .is_inner = false, .func = sxe2_flow_parse_pattern_ipv4, }, [SXE2_EXPANSION_OUTER_IPV6] = { .is_inner = false, .func = sxe2_flow_parse_pattern_ipv6, }, [SXE2_EXPANSION_OUTER_IPV6_FRAG_EXT] = { .is_inner = false, .func = sxe2_flow_parse_pattern_ipv6_frag_ext, }, [SXE2_EXPANSION_OUTER_TCP] = { .is_inner = false, .func = sxe2_flow_parse_pattern_tcp, }, [SXE2_EXPANSION_OUTER_UDP] = { .is_inner = false, .func = sxe2_flow_parse_pattern_udp, }, [SXE2_EXPANSION_OUTER_SCTP] = { .is_inner = false, .func = sxe2_flow_parse_pattern_sctp, }, [SXE2_EXPANSION_GENEVE] = { .is_inner = false, .func = sxe2_flow_parse_pattern_geneve, }, [SXE2_EXPANSION_GTPU] = { .is_inner = false, .func = sxe2_flow_parse_pattern_gtpu, }, [SXE2_EXPANSION_GRE] = { .is_inner = false, .func = sxe2_flow_parse_pattern_gre, }, [SXE2_EXPANSION_NVGRE] = { .is_inner = false, .func = sxe2_flow_parse_pattern_nvgre, }, [SXE2_EXPANSION_VXLAN] = { .is_inner = false, .func = sxe2_flow_parse_pattern_vxlan, }, [SXE2_EXPANSION_VXLAN_GPE] = { .is_inner = false, .func = sxe2_flow_parse_pattern_vxlan_gpe, }, [SXE2_EXPANSION_ETH] = { .is_inner = true, .func = sxe2_flow_parse_pattern_eth, }, [SXE2_EXPANSION_VLAN] = { .is_inner = true, .func = sxe2_flow_parse_pattern_vlan, }, [SXE2_EXPANSION_IPV4] = { .is_inner = true, .func = sxe2_flow_parse_pattern_ipv4, }, [SXE2_EXPANSION_IPV6] = { .is_inner = true, .func = sxe2_flow_parse_pattern_ipv6, }, [SXE2_EXPANSION_IPV6_FRAG_EXT] = { .is_inner = true, .func = sxe2_flow_parse_pattern_ipv6_frag_ext, }, [SXE2_EXPANSION_TCP] = { .is_inner = true, .func = sxe2_flow_parse_pattern_tcp, }, [SXE2_EXPANSION_UDP] = { .is_inner = true, .func = sxe2_flow_parse_pattern_udp, }, [SXE2_EXPANSION_SCTP] = { .is_inner = true, .func = sxe2_flow_parse_pattern_sctp, }, }; int32_t sxe2_flow_parse_pattern(struct rte_eth_dev *dev __rte_unused, const struct rte_flow_item patterns[], struct rte_flow_error *error, struct sxe2_flow *flow) { int32_t ret = 0; const struct rte_flow_item *item = patterns; enum sxe2_expansion now = SXE2_EXPANSION_OUTER_ETH; enum sxe2_expansion next = SXE2_EXPANSION_OUTER_ETH; enum sxe2_flow_tunnel_type tunnel_type = SXE2_FLOW_TUNNEL_TYPE_NONE; DECLARE_BITMAP(flow_type, SXE2_EXPANSION_MAX); sxe2_bitmap_zero(flow_type, SXE2_EXPANSION_MAX); sxe2_flow_parse_pattern_func_t func; bool is_inner = false; for (item = patterns; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { if (item->type == RTE_FLOW_ITEM_TYPE_VOID) continue; if (item->last) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "FANV not support range pattern."); PMD_LOG_ERR(DRV, "flow not supported range pattern."); ret = -EINVAL; goto l_end; } ret = sxe2_flow_is_expandable_item(item); if (ret != 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Unsupported item type."); PMD_LOG_ERR(DRV, "Unsupported item type: %d", item->type); goto l_end; } next = now; ret = sxe2_flow_valid_next_expansion(&next, item, &tunnel_type, flow_type); if (ret != 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid pattern sequence for rule."); PMD_LOG_ERR(DRV, "Invalid pattern sequence for rule."); goto l_end; } if ((item->spec != NULL && item->mask == NULL) || (item->spec == NULL && item->mask != NULL)) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, "Invalid pattern spec miss macth mask for rule."); PMD_LOG_ERR(DRV, "Invalid pattern spec miss macth mask for rule."); goto l_end; } func = sxe2_flow_parse_pattern_list[now].func; is_inner = sxe2_flow_parse_pattern_list[now].is_inner; ret = func(item, error, flow, next, is_inner); if (ret != 0) goto l_end; now = next; } if (sxe2_bitmap_weight(flow->pattern_outer.hdrs, SXE2_FLOW_HDR_MAX) > 0) flow->has_hdr = 1; if (sxe2_bitmap_weight(flow->pattern_inner.map_mask, SXE2_FLOW_FLD_ID_MAX) > 0 || sxe2_bitmap_weight(flow->pattern_outer.map_mask, SXE2_FLOW_FLD_ID_MAX) > 0) flow->has_mask = 1; if (sxe2_bitmap_weight(flow->pattern_inner.map_spec, SXE2_FLOW_FLD_ID_MAX) > 0 || sxe2_bitmap_weight(flow->pattern_outer.map_spec, SXE2_FLOW_FLD_ID_MAX) > 0) flow->has_spec = 1; flow->meta.tunnel_type = tunnel_type; if (flow->has_hdr) { ret = sxe2_flow_get_flow_type(flow); if (ret != 0) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, NULL, "Unsupported flow type."); goto l_end; } } sxe2_bitmap_copy(flow->flow_type, flow_type, SXE2_EXPANSION_MAX); l_end: return ret; }