[v2,21/33] net/ice: support IPv4 GRE raw pattern type

Message ID 20220413160932.2074781-22-kevinx.liu@intel.com (mailing list archive)
State Superseded, archived
Headers
Series support full function of DCF |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Kevin Liu April 13, 2022, 4:09 p.m. UTC
  From: Alvin Zhang <alvinx.zhang@intel.com>

Add definitions, matching entries, parsers for below patterns:
ETH/IPV4/GRE/RAW/IPV4
ETH/IPV4/GRE/RAW/IPV4/UDP
ETH/IPV4/GRE/RAW/IPV4/TCP

Signed-off-by: Steven Zou <steven.zou@intel.com>
Signed-off-by: Alvin Zhang <alvinx.zhang@intel.com>
Signed-off-by: Kevin Liu <kevinx.liu@intel.com>
---
 drivers/net/ice/ice_generic_flow.c  | 27 +++++++++
 drivers/net/ice/ice_generic_flow.h  |  9 +++
 drivers/net/ice/ice_switch_filter.c | 90 +++++++++++++++++++++++++++++
 3 files changed, 126 insertions(+)
  

Patch

diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 1433094ed4..6663a85ed0 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1084,6 +1084,33 @@  enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_icmp6[] = {
 	RTE_FLOW_ITEM_TYPE_ICMP6,
 	RTE_FLOW_ITEM_TYPE_END,
 };
+/* IPv4 GRE RAW IPv4 */
+enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_GRE,
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_GRE,
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_GRE,
+	RTE_FLOW_ITEM_TYPE_RAW,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
 
 /*IPv4 GTPU (EH) */
 enum rte_flow_item_type pattern_eth_ipv4_gtpu[] = {
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index def7e2d6d6..12193cbd9d 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -27,6 +27,7 @@ 
 #define ICE_PROT_L2TPV3OIP		BIT_ULL(16)
 #define ICE_PROT_PFCP			BIT_ULL(17)
 #define ICE_PROT_NAT_T_ESP		BIT_ULL(18)
+#define ICE_PROT_GRE            BIT_ULL(19)
 
 /* field */
 
@@ -54,6 +55,7 @@ 
 #define ICE_PFCP_SEID			BIT_ULL(42)
 #define ICE_PFCP_S_FIELD		BIT_ULL(41)
 #define ICE_IP_PK_ID		    BIT_ULL(40)
+#define ICE_RAW_PATTERN			BIT_ULL(39)
 
 /* input set */
 
@@ -104,6 +106,8 @@ 
 	(ICE_PROT_GTPU | ICE_GTPU_TEID)
 #define ICE_INSET_GTPU_QFI \
 	(ICE_PROT_GTPU | ICE_GTPU_QFI)
+#define ICE_INSET_RAW \
+	(ICE_PROT_GRE | ICE_RAW_PATTERN)
 #define ICE_INSET_PPPOE_SESSION \
 	(ICE_PROT_PPPOE_S | ICE_PPPOE_SESSION)
 #define ICE_INSET_PPPOE_PROTO \
@@ -291,6 +295,11 @@  extern enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_udp[];
 extern enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_sctp[];
 extern enum rte_flow_item_type pattern_eth_ipv6_nvgre_eth_ipv6_icmp6[];
 
+/* IPv4 GRE RAW IPv4 */
+extern enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4[];
+extern enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_udp[];
+extern enum rte_flow_item_type pattern_eth_ipv4_gre_raw_ipv4_tcp[];
+
 /* IPv4 GTPU (EH) */
 extern enum rte_flow_item_type pattern_eth_ipv4_gtpu[];
 extern enum rte_flow_item_type pattern_eth_ipv4_gtpu_eh[];
diff --git a/drivers/net/ice/ice_switch_filter.c b/drivers/net/ice/ice_switch_filter.c
index 44046f803c..435ca5a05c 100644
--- a/drivers/net/ice/ice_switch_filter.c
+++ b/drivers/net/ice/ice_switch_filter.c
@@ -196,6 +196,22 @@ 
 #define ICE_SW_INSET_GTPU_IPV6_TCP ( \
 	ICE_SW_INSET_GTPU_IPV6 | ICE_INSET_TCP_SRC_PORT | \
 	ICE_INSET_TCP_DST_PORT)
+#define ICE_SW_INSET_DIST_GRE_RAW_IPV4 ( \
+	ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | \
+	ICE_INSET_RAW)
+#define ICE_SW_INSET_DIST_GRE_RAW_IPV4_TCP ( \
+	ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | \
+	ICE_INSET_TCP_SRC_PORT | ICE_INSET_TCP_DST_PORT | \
+	ICE_INSET_RAW)
+#define ICE_SW_INSET_DIST_GRE_RAW_IPV4_UDP ( \
+	ICE_INSET_IPV4_SRC | ICE_INSET_IPV4_DST | \
+	ICE_INSET_UDP_SRC_PORT | ICE_INSET_UDP_DST_PORT | \
+	ICE_INSET_RAW)
+
+#define CUSTOM_GRE_KEY_OFFSET	4
+#define GRE_CFLAG		0x80
+#define GRE_KFLAG		0x20
+#define GRE_SFLAG		0x10
 
 struct sw_meta {
 	struct ice_adv_lkup_elem *list;
@@ -317,6 +333,9 @@  ice_pattern_match_item ice_switch_pattern_dist_list[] = {
 	{pattern_eth_ipv6_gtpu_eh_ipv6_udp,		ICE_SW_INSET_MAC_GTPU_EH_OUTER,		ICE_SW_INSET_GTPU_IPV6_UDP,		ICE_INSET_NONE},
 	{pattern_eth_ipv6_gtpu_ipv6_tcp,		ICE_SW_INSET_MAC_GTPU_OUTER,		ICE_SW_INSET_GTPU_IPV6_TCP,		ICE_INSET_NONE},
 	{pattern_eth_ipv6_gtpu_eh_ipv6_tcp,		ICE_SW_INSET_MAC_GTPU_EH_OUTER,		ICE_SW_INSET_GTPU_IPV6_TCP,		ICE_INSET_NONE},
+	{pattern_eth_ipv4_gre_raw_ipv4,			ICE_SW_INSET_DIST_GRE_RAW_IPV4,		ICE_INSET_NONE,		ICE_INSET_NONE},
+	{pattern_eth_ipv4_gre_raw_ipv4_tcp,		ICE_SW_INSET_DIST_GRE_RAW_IPV4_TCP,		ICE_INSET_NONE,		ICE_INSET_NONE},
+	{pattern_eth_ipv4_gre_raw_ipv4_udp,		ICE_SW_INSET_DIST_GRE_RAW_IPV4_UDP,		ICE_INSET_NONE,		ICE_INSET_NONE},
 };
 
 static struct
@@ -608,6 +627,11 @@  ice_switch_parse_pattern(const struct rte_flow_item pattern[],
 	bool ipv6_ipv6_valid = 0;
 	bool any_valid = 0;
 	uint16_t j, k, t = 0;
+	uint16_t c_rsvd0_ver = 0;
+	bool gre_valid = 0;
+
+#define set_cur_item_einval(msg) \
+	rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, (msg))
 
 	if (*tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ ||
 	    *tun_type == ICE_NON_TUN_QINQ)
@@ -1100,6 +1124,70 @@  ice_switch_parse_pattern(const struct rte_flow_item pattern[],
 			}
 			break;
 
+		case RTE_FLOW_ITEM_TYPE_GRE: {
+			const struct rte_flow_item_gre *gre_spec = item->spec;
+			const struct rte_flow_item_gre *gre_mask = item->mask;
+
+			gre_valid = 1;
+			tunnel_valid = 1;
+			if (gre_spec && gre_mask) {
+				list[t].type = ICE_GRE;
+				if (gre_mask->c_rsvd0_ver) {
+					/* GRE RFC1701 */
+					list[t].h_u.gre_hdr.flags =
+							gre_spec->c_rsvd0_ver;
+					list[t].m_u.gre_hdr.flags =
+							gre_mask->c_rsvd0_ver;
+					c_rsvd0_ver = gre_spec->c_rsvd0_ver &
+						      gre_mask->c_rsvd0_ver;
+				}
+			}
+			break;
+		}
+
+		case RTE_FLOW_ITEM_TYPE_RAW: {
+			const struct rte_flow_item_raw *raw_spec;
+			char *endp = NULL;
+			unsigned long key;
+			char s[sizeof("0x12345678")];
+
+			raw_spec = item->spec;
+
+			if (list[t].type != ICE_GRE)
+				return set_cur_item_einval("RAW must follow GRE.");
+
+			if (!(c_rsvd0_ver & GRE_KFLAG)) {
+				if (!raw_spec)
+					break;
+
+				return set_cur_item_einval("Invalid pattern! k_bit is 0 while raw pattern exists.");
+			}
+
+			if (!raw_spec)
+				return set_cur_item_einval("Invalid pattern! k_bit is 1 while raw pattern doesn't exist.");
+
+			if ((c_rsvd0_ver & GRE_CFLAG) == GRE_CFLAG &&
+			    raw_spec->offset != CUSTOM_GRE_KEY_OFFSET)
+				return set_cur_item_einval("Invalid pattern! c_bit is 1 while offset is not 4.");
+
+			if (raw_spec->length >= sizeof(s))
+				return set_cur_item_einval("Invalid key");
+
+			memcpy(s, raw_spec->pattern, raw_spec->length);
+			s[raw_spec->length] = '\0';
+			key = strtol(s, &endp, 16);
+			if (*endp != '\0' || key > UINT32_MAX)
+				return set_cur_item_einval("Invalid key");
+
+			list[t].h_u.gre_hdr.key = (uint32_t)key;
+			list[t].m_u.gre_hdr.key = UINT32_MAX;
+			*input |= ICE_INSET_RAW;
+			input_set_byte += 2;
+			t++;
+
+			break;
+		}
+
 		case RTE_FLOW_ITEM_TYPE_VLAN:
 			vlan_spec = item->spec;
 			vlan_mask = item->mask;
@@ -1633,6 +1721,8 @@  ice_switch_parse_pattern(const struct rte_flow_item pattern[],
 	if (*tun_type == ICE_NON_TUN) {
 		if (nvgre_valid)
 			*tun_type = ICE_SW_TUN_NVGRE;
+		else if (gre_valid)
+			*tun_type = ICE_SW_TUN_GRE;
 		else if (ipv4_valid && tcp_valid)
 			*tun_type = ICE_SW_IPV4_TCP;
 		else if (ipv4_valid && udp_valid)