diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index 2ebe9a1cce..2d7e4c19f8 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1085,6 +1085,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 7c2038d089..a61d3d0aaa 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
@@ -609,6 +628,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)
@@ -1101,6 +1125,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;
@@ -1634,6 +1722,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)
