[RFC,v1] net/i40e: support customerized VXLAN FDIR and inner RSS

Message ID 20220930063657.1118777-1-stevex.yang@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Qi Zhang
Headers
Series [RFC,v1] net/i40e: support customerized VXLAN FDIR and inner RSS |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Steve Yang Sept. 30, 2022, 6:36 a.m. UTC
  Usage:
flow create <port_id> ingress pattern <pattern_str> / end actions <action_str> / end

Added following pattern_str:
    eth / ipv4 / udp / vxlan / ipv4 / udp
    eth / ipv4 / udp / vxlan / ipv4 / tcp
    eth / ipv4 / udp / vxlan / ipv4 / icmp
    eth / ipv4 / udp / vxlan / ipv6 / udp
    eth / ipv4 / udp / vxlan / ipv6 / tcp
    eth / ipv4 / udp / vxlan / ipv6 / icmp
    eth / ipv4 / icmp
    eth / ipv6 / udp / vxlan / ipv4 / udp
    eth / ipv6 / udp / vxlan / ipv4 / tcp
    eth / ipv6 / udp / vxlan / ipv4 / icmp
    eth / ipv6 / udp / vxlan / ipv6 / udp
    eth / ipv6 / udp / vxlan / ipv6 / tcp
    eth / ipv6 / udp / vxlan / ipv6 / icmp
    eth / ipv6 / icmp

action_str:
    queue index <queue_id>

input set:
    ipv4: src, dst, tos, ttl
    udp: src, dst

For example:
    flow create 0 ingress pattern eth / ipv4 src is 1.0.0.4 dst is 19.9.0.4 tos is 2 ttl is 40 / udp src is 250 dst is 250 / vxlan / ipv4 / udp / end actions queue index 4 / end

Baseline:
    dpdk-stable 20.11 / 73655c6414 (tag: v20.11.6, origin/20.11, 20.11) version: 20.11.6

Dependency:
 - need load vxlan-ip.pkgo before configuring flow filter rule;
 - need add vxlan-gpe port via command:
   'port config <port_id> udp_tunnel_port add vxlan-gpe <vxlan_port_id>'
    e.g.: port config 0 udp_tunnel_port add vxlan-gpe 250
 - enable rss via command 'port config all rss all'

Signed-off-by: Steve Yang <stevex.yang@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  15 ++
 drivers/net/i40e/i40e_ethdev.c    | 168 +++++++++++-
 drivers/net/i40e/i40e_fdir.c      | 431 ++++++++++++++++++++----------
 drivers/net/i40e/i40e_flow.c      | 281 ++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.c      |  28 ++
 lib/librte_ethdev/rte_ethdev.h    |  18 +-
 6 files changed, 799 insertions(+), 142 deletions(-)
  

Patch

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 4674715ed7..66acb3cd7f 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1290,6 +1290,21 @@  struct i40e_filter_program_desc {
 
 /* Packet Classifier Types for filters */
 enum i40e_filter_pctype {
+	I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP     = 1,
+	I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP     = 2,
+	I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP    = 3,
+	I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP     = 4,
+	I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP     = 5,
+	I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP    = 6,
+	I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP     = 7,
+	I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP     = 8,
+	I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP    = 9,
+	I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP     = 10,
+	I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP     = 11,
+	I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP    = 12,
+	I40E_FILTER_PCTYPE_NONF_IPV4_ICMP               = 13,
+	I40E_FILTER_PCTYPE_NONF_IPV6_ICMP               = 14,
+
 	/* Note: Values 0-28 are reserved for future use.
 	 * Value 29, 30, 32 are not supported on XL710 and X710.
 	 */
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index c2d52e4acc..0793750dac 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -7621,6 +7621,10 @@  i40e_config_hena(const struct i40e_adapter *adapter, uint64_t flags)
 			hena |= adapter->pctypes_tbl[i];
 	}
 
+	/* Force enable vxlan relative hash flags */
+	for (i = RTE_ETH_FLOW_IPV4_VXLAN_IPV4_UDP; i < RTE_ETH_FLOW_MAX; i++)
+		hena |= adapter->pctypes_tbl[i];
+
 	return hena;
 }
 
@@ -7861,7 +7865,7 @@  i40e_tunnel_filter_convert(
 	tunnel_filter->input.inner_vlan = cld_filter->element.inner_vlan;
 	if ((rte_le_to_cpu_16(cld_filter->element.flags) &
 	     I40E_AQC_ADD_CLOUD_FLAGS_IPV6) ==
-	    I40E_AQC_ADD_CLOUD_FLAGS_IPV6)
+	     I40E_AQC_ADD_CLOUD_FLAGS_IPV6)
 		tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV6;
 	else
 		tunnel_filter->input.ip_type = I40E_TUNNEL_IPTYPE_IPV4;
@@ -9017,6 +9021,60 @@  i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	uint64_t valid;
 
 	static const uint64_t valid_hash_inset_table[] = {
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
 			I40E_INSET_DMAC | I40E_INSET_SMAC |
 			I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
@@ -9168,6 +9226,60 @@  i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 * union rte_eth_fdir_flow.
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
 		I40E_INSET_VLAN_OUTER | I40E_INSET_VLAN_INNER |
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
@@ -9289,6 +9401,60 @@  uint64_t
 i40e_get_default_input_set(uint16_t pctype)
 {
 	static const uint64_t default_inset_table[] = {
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+			I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] =
+			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+			I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+			I40E_INSET_IPV4_TTL,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] =
+			I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
 			I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 5e2bb64c14..a929ca84b6 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -824,6 +824,8 @@  i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] = IPPROTO_UDP,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] = IPPROTO_SCTP,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] = IPPROTO_NONE,
+		[I40E_FILTER_PCTYPE_NONF_IPV4_ICMP] = IPPROTO_ICMP,
+		[I40E_FILTER_PCTYPE_NONF_IPV6_ICMP] = IPPROTO_ICMP
 	};
 
 	rte_memcpy(raw_pkt, &fdir_input->flow.l2_flow.dst,
@@ -854,64 +856,81 @@  i40e_flow_fdir_fill_eth_ip_head(struct i40e_pf *pf,
 		}
 	}
 
-	if (pctype == I40E_FILTER_PCTYPE_L2_PAYLOAD)
+	switch (pctype) {
+	case I40E_FILTER_PCTYPE_L2_PAYLOAD:
 		*ether_type = fdir_input->flow.l2_flow.ether_type;
-	else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER ||
-		 pctype == I40E_FILTER_PCTYPE_FRAG_IPV4 ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP ||
-		 pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER ||
-		 pctype == I40E_FILTER_PCTYPE_FRAG_IPV6 ||
-		 is_customized_pctype) {
-		if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP ||
-			pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP ||
-			pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP ||
-			pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER ||
-			pctype == I40E_FILTER_PCTYPE_FRAG_IPV4) {
-			len = fill_ip4_head(fdir_input, raw_pkt,
-					next_proto[pctype], len, ether_type);
-		} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP ||
-			pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP ||
-			pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP ||
-			pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER ||
-			pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) {
-			len = fill_ip6_head(fdir_input, raw_pkt,
-					next_proto[pctype], len,
-					ether_type);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_GTPC ||
-			 cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4 ||
-			 cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 ||
-			 cus_pctype->index == I40E_CUSTOMIZED_GTPU) {
+		break;
+	case I40E_FILTER_PCTYPE_NONF_IPV4_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_ICMP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_SCTP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_OTHER:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP:
+	case I40E_FILTER_PCTYPE_FRAG_IPV4:
+		len = fill_ip4_head(fdir_input, raw_pkt,
+				next_proto[pctype], len, ether_type);
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_ICMP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_SCTP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_OTHER:
+	case I40E_FILTER_PCTYPE_FRAG_IPV6:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP:
+		len = fill_ip6_head(fdir_input, raw_pkt,
+				    next_proto[pctype], len,
+				    ether_type);
+		break;
+	default:
+		if (!is_customized_pctype) {
+			PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype);
+			return -1;
+		}
+
+		switch (cus_pctype->index) {
+		case I40E_CUSTOMIZED_GTPC:
+		case I40E_CUSTOMIZED_GTPU_IPV4:
+		case I40E_CUSTOMIZED_GTPU_IPV6:
+		case I40E_CUSTOMIZED_GTPU:
+		case I40E_CUSTOMIZED_ESP_IPV4_UDP:
 			len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP,
-					len, ether_type);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3) {
-			len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_L2TP,
-					len, ether_type);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4) {
+					    len, ether_type);
+			break;
+		case I40E_CUSTOMIZED_ESP_IPV4:
 			len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_ESP,
-					len, ether_type);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) {
-			len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP,
-					len, ether_type);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP) {
-			len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_UDP,
-					len, ether_type);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6)
+					    len, ether_type);
+			break;
+		case I40E_CUSTOMIZED_IPV4_L2TPV3:
+			len = fill_ip4_head(fdir_input, raw_pkt, IPPROTO_L2TP,
+					    len, ether_type);
+			break;
+		case I40E_CUSTOMIZED_ESP_IPV6:
 			len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_ESP,
-					len, ether_type);
-		else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6_UDP)
+					    len, ether_type);
+			break;
+		case I40E_CUSTOMIZED_ESP_IPV6_UDP:
 			len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_UDP,
-					len, ether_type);
-		else if (cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3)
+					    len, ether_type);
+			break;
+		case I40E_CUSTOMIZED_IPV6_L2TPV3:
 			len = fill_ip6_head(fdir_input, raw_pkt, IPPROTO_L2TP,
-					len, ether_type);
-	} else {
-		PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype);
-		return -1;
+					    len, ether_type);
+			break;
+		default:
+			PMD_DRV_LOG(ERR, "unknown customized pctype: %u.", fdir_input->pctype);
+			return -1;
+		}
 	}
 
 	return len;
@@ -940,13 +959,54 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 	struct rte_flow_item_esp *esp;
 	struct rte_ipv4_hdr *esp_ipv4;
 	struct rte_ipv6_hdr *esp_ipv6;
+	struct rte_icmp_hdr *icmp;
+	struct rte_ipv4_hdr *ip;
+	struct rte_ipv6_hdr *ip6;
+	static char packet_4_4[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0, 0x45, 0,
+				    0, 0x62, 0, 0x01, 0, 0, 0x40, 0x11, 0x11, 0xb9, 0xac, 0x10, 0xd4, 0x16, 0xc0, 0xa8,
+				    0x28, 0x02, 0, 0x35, 0x12, 0xb5, 0, 0x4e, 0x55, 0x4a, 0x08, 0, 0, 0, 0, 0,
+				    0x22, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0,
+				    0x45, 0, 0, 0x30, 0, 0x01, 0, 0, 0x40, 0x11, 0x11, 0xeb, 0xac, 0x10, 0xd4, 0x16,
+				    0xc0, 0xa8, 0x28, 0x02, 0, 0x23, 0, 0x05, 0, 0x1c, 0xe2, 0x07, 0x78, 0x78, 0x78, 0x78,
+				    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};
+	static char packet_4_6[] = {0x68, 0x05, 0xCA, 0x34, 0x8B, 0x98, 0xA4, 0xBF, 0x01, 0x16, 0xB2, 0xA6, 0x08, 0x00, 0x45, 0x00,
+				    0x00, 0x76, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0x38, 0x03, 0xC0, 0xA8, 0x00, 0x04, 0xC0, 0xA8,
+				    0x00, 0x04, 0x12, 0xB5, 0x12, 0xB5, 0, 0x62, 0x05, 0xC5, 0x04, 0, 0, 0x03, 0, 0,
+				    0, 0, 0x1D, 0x44, 0x9D, 0x54, 0xDA, 0xDE, 0, 0, 0, 0, 0, 0, 0x86, 0xDD,
+				    0x60, 0, 0, 0, 0, 0x1C, 0x11, 0x40, 0, 0, 0, 0, 0, 0, 0, 0,
+				    0, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0,
+				    0, 0, 0, 0, 0, 0, 0, 0x01, 0x04, 0, 0x04, 0, 0, 0x1C, 0x43, 0,
+				    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+				    0x78, 0x78, 0x78, 0x78};
+	static char packet_6_4[] = {0x68, 0x05, 0xCA, 0x34, 0x8B, 0x98, 0xA4, 0xBF, 0x01, 0x16, 0xB2, 0xA6, 0x86, 0xDD, 0x60, 0x00,
+				    0x00, 0x00, 0x00, 0x3A, 0x11, 0x40, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x56,
+				    0xB9, 0x14, 0x4F, 0xFC, 0x11, 0x98, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
+				    0x54, 0xFF, 0xFE, 0xF5, 0x00, 0x00, 0x12, 0xB5, 0x12, 0xB5, 0, 0x4e, 0x55, 0x4a, 0x08, 0, 0, 0, 0, 0,
+				    0x22, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0,
+				    0x45, 0, 0, 0x30, 0, 0x01, 0, 0, 0x40, 0x11, 0x11, 0xeb, 0xac, 0x10, 0xd4, 0x16,
+				    0xc0, 0xa8, 0x28, 0x02, 0, 0x23, 0, 0x05, 0, 0x1c, 0xe2, 0x07, 0x78, 0x78, 0x78, 0x78,
+				    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78};
+	static char packet_6_6[] = {0x68, 0x05, 0xCA, 0x34, 0x8B, 0x98, 0xA4, 0xBF, 0x01, 0x16, 0xB2, 0xA6, 0x86, 0xDD, 0x60, 0x00,
+				    0x00, 0x00, 0x00, 0x3A, 0x11, 0x40, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x56,
+				    0xB9, 0x14, 0x4F, 0xFC, 0x11, 0x98, 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,
+				    0x54, 0xFF, 0xFE, 0xF5, 0x00, 0x00, 0x12, 0xB5, 0x12, 0xB5, 0, 0x62, 0x05, 0xC5, 0x04, 0, 0, 0x03, 0, 0,
+				    0, 0, 0x1D, 0x44, 0x9D, 0x54, 0xDA, 0xDE, 0, 0, 0, 0, 0, 0, 0x86, 0xDD,
+				    0x60, 0, 0, 0, 0, 0x1C, 0x11, 0x40, 0, 0, 0, 0, 0, 0, 0, 0,
+				    0, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0, 0, 0, 0, 0,
+				    0, 0, 0, 0, 0, 0, 0, 0x01, 0x04, 0, 0x04, 0, 0, 0x1C, 0x43, 0,
+				    0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
+				    0x78, 0x78, 0x78, 0x78};
 
+	/* fill the ethernet and IP head */
 	uint8_t size, dst = 0;
 	uint8_t i, pit_idx, set_idx = I40E_FLXPLD_L4_IDX; /* use l4 by default*/
 	int len;
 	uint8_t pctype = fdir_input->pctype;
 	struct i40e_customized_pctype *cus_pctype;
 
+	if (!raw_pkt)
+		return -ENOMEM;
+
 	/* raw packet template - just copy contents of the raw packet */
 	if (fdir_input->flow_ext.pkt_template) {
 		memcpy(raw_pkt, fdir_input->flow.raw_flow.packet,
@@ -961,7 +1021,52 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		return -EINVAL;
 
 	/* fill the L4 head */
-	if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_UDP) {
+	switch (pctype) {
+	case I40E_FILTER_PCTYPE_NONF_IPV4_ICMP:
+		icmp = (struct rte_icmp_hdr *)(raw_pkt + len);
+		payload = (unsigned char *)icmp + sizeof(struct rte_icmp_hdr);
+		icmp->icmp_type = 8;
+		icmp->icmp_cksum = 63487;
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_ICMP:
+		icmp = (struct rte_icmp_hdr *)(raw_pkt + len);
+		payload = (unsigned char *)icmp + sizeof(struct rte_icmp_hdr);
+		icmp->icmp_type = 8;
+		icmp->icmp_cksum = 63487;
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP:
+		if (!raw_pkt)
+			return -ENOMEM;
+		memcpy(raw_pkt, packet_4_4, sizeof(packet_4_4));
+		ip = (struct rte_ipv4_hdr *)(raw_pkt + 14);
+		udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv4_hdr));
+		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
+		ip->dst_addr = fdir_input->flow.udp4_flow.ip.dst_ip;
+		ip->src_addr = fdir_input->flow.udp4_flow.ip.src_ip;
+		udp->src_port = fdir_input->flow.udp4_flow.src_port;
+		udp->dst_port = fdir_input->flow.udp4_flow.dst_port;
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP:
+		if (!raw_pkt)
+			return -ENOMEM;
+		memcpy(raw_pkt, packet_4_6, sizeof(packet_4_6));
+		ip = (struct rte_ipv4_hdr *)(raw_pkt + 14);
+		udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv4_hdr));
+		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
+		ip->dst_addr = fdir_input->flow.udp4_flow.ip.dst_ip;
+		ip->src_addr = fdir_input->flow.udp4_flow.ip.src_ip;
+		udp->src_port = fdir_input->flow.udp4_flow.src_port;
+		udp->dst_port = fdir_input->flow.udp4_flow.dst_port;
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV4_UDP:
 		udp = (struct rte_udp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
 		/**
@@ -972,7 +1077,9 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		udp->src_port = fdir_input->flow.udp4_flow.dst_port;
 		udp->dst_port = fdir_input->flow.udp4_flow.src_port;
 		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_TCP) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV4_TCP:
 		tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr);
 		/**
@@ -983,7 +1090,9 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		tcp->src_port = fdir_input->flow.tcp4_flow.dst_port;
 		tcp->dst_port = fdir_input->flow.tcp4_flow.src_port;
 		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_SCTP) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV4_SCTP:
 		sctp = (struct rte_sctp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr);
 		/**
@@ -994,11 +1103,52 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		sctp->src_port = fdir_input->flow.sctp4_flow.dst_port;
 		sctp->dst_port = fdir_input->flow.sctp4_flow.src_port;
 		sctp->tag = fdir_input->flow.sctp4_flow.verify_tag;
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV4_OTHER ||
-		   pctype == I40E_FILTER_PCTYPE_FRAG_IPV4) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV4_OTHER:
+	case I40E_FILTER_PCTYPE_FRAG_IPV4:
 		payload = raw_pkt + len;
 		set_idx = I40E_FLXPLD_L3_IDX;
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_UDP) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP:
+		if (!raw_pkt)
+			return -ENOMEM;
+		memcpy(raw_pkt, packet_6_4, sizeof(packet_6_4));
+		ip6 = (struct rte_ipv6_hdr *)(raw_pkt + 14);
+		udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv6_hdr));
+		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
+		rte_memcpy(&ip6->src_addr,
+			   &fdir_input->flow.ipv6_flow.src_ip,
+			   IPV6_ADDR_LEN);
+		rte_memcpy(&ip6->dst_addr,
+			   &fdir_input->flow.ipv6_flow.dst_ip,
+			   IPV6_ADDR_LEN);
+		udp->src_port = fdir_input->flow.udp6_flow.src_port;
+		udp->dst_port = fdir_input->flow.udp6_flow.dst_port;
+		break;
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP:
+	case I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP:
+		if (!raw_pkt)
+			return -ENOMEM;
+		memcpy(raw_pkt, packet_6_6, sizeof(packet_6_6));
+		ip6 = (struct rte_ipv6_hdr *)(raw_pkt + 14);
+		udp = (struct rte_udp_hdr *)(raw_pkt + 14 + sizeof(struct rte_ipv6_hdr));
+		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
+		rte_memcpy(&ip6->src_addr,
+			   &fdir_input->flow.ipv6_flow.src_ip,
+			   IPV6_ADDR_LEN);
+		rte_memcpy(&ip6->dst_addr,
+			   &fdir_input->flow.ipv6_flow.dst_ip,
+			   IPV6_ADDR_LEN);
+		udp->src_port = fdir_input->flow.udp6_flow.src_port;
+		udp->dst_port = fdir_input->flow.udp6_flow.dst_port;
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_UDP:
 		udp = (struct rte_udp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)udp + sizeof(struct rte_udp_hdr);
 		/**
@@ -1009,7 +1159,9 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		udp->src_port = fdir_input->flow.udp6_flow.dst_port;
 		udp->dst_port = fdir_input->flow.udp6_flow.src_port;
 		udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_TCP) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_TCP:
 		tcp = (struct rte_tcp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)tcp + sizeof(struct rte_tcp_hdr);
 		/**
@@ -1020,7 +1172,9 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		tcp->data_off = I40E_FDIR_TCP_DEFAULT_DATAOFF;
 		tcp->src_port = fdir_input->flow.udp6_flow.dst_port;
 		tcp->dst_port = fdir_input->flow.udp6_flow.src_port;
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_SCTP) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_SCTP:
 		sctp = (struct rte_sctp_hdr *)(raw_pkt + len);
 		payload = (unsigned char *)sctp + sizeof(struct rte_sctp_hdr);
 		/**
@@ -1031,11 +1185,15 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 		sctp->src_port = fdir_input->flow.sctp6_flow.dst_port;
 		sctp->dst_port = fdir_input->flow.sctp6_flow.src_port;
 		sctp->tag = fdir_input->flow.sctp6_flow.verify_tag;
-	} else if (pctype == I40E_FILTER_PCTYPE_NONF_IPV6_OTHER ||
-		   pctype == I40E_FILTER_PCTYPE_FRAG_IPV6) {
+		break;
+
+	case I40E_FILTER_PCTYPE_NONF_IPV6_OTHER:
+	case I40E_FILTER_PCTYPE_FRAG_IPV6:
 		payload = raw_pkt + len;
 		set_idx = I40E_FLXPLD_L3_IDX;
-	} else if (pctype == I40E_FILTER_PCTYPE_L2_PAYLOAD) {
+		break;
+
+	case I40E_FILTER_PCTYPE_L2_PAYLOAD:
 		payload = raw_pkt + len;
 		/**
 		 * ARP packet is a special case on which the payload
@@ -1045,13 +1203,21 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 				rte_cpu_to_be_16(RTE_ETHER_TYPE_ARP))
 			payload += sizeof(struct rte_arp_hdr);
 		set_idx = I40E_FLXPLD_L2_IDX;
-	} else if (fdir_input->flow_ext.customized_pctype) {
+		break;
+
+	default:
+		if (!fdir_input->flow_ext.customized_pctype) {
+			PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype);
+			return -1;
+		}
+
 		/* If customized pctype is used */
 		cus_pctype = i40e_flow_fdir_find_customized_pctype(pf, pctype);
-		if (cus_pctype->index == I40E_CUSTOMIZED_GTPC ||
-		    cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV4 ||
-		    cus_pctype->index == I40E_CUSTOMIZED_GTPU_IPV6 ||
-		    cus_pctype->index == I40E_CUSTOMIZED_GTPU) {
+		switch (cus_pctype->index) {
+		case I40E_CUSTOMIZED_GTPC:
+		case I40E_CUSTOMIZED_GTPU_IPV4:
+		case I40E_CUSTOMIZED_GTPU_IPV6:
+		case I40E_CUSTOMIZED_GTPU:
 			udp = (struct rte_udp_hdr *)(raw_pkt + len);
 			udp->dgram_len =
 				rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
@@ -1111,8 +1277,10 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 			} else
 				payload = (unsigned char *)gtp +
 					sizeof(struct rte_flow_item_gtp);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_IPV4_L2TPV3 ||
-			   cus_pctype->index == I40E_CUSTOMIZED_IPV6_L2TPV3) {
+			break;
+
+		case I40E_CUSTOMIZED_IPV4_L2TPV3:
+		case I40E_CUSTOMIZED_IPV6_L2TPV3:
 			l2tpv3oip = (struct rte_flow_item_l2tpv3oip *)(raw_pkt
 								       + len);
 
@@ -1124,72 +1292,62 @@  i40e_flow_fdir_construct_pkt(struct i40e_pf *pf,
 				 fdir_input->flow.ip6_l2tpv3oip_flow.session_id;
 			payload = (unsigned char *)l2tpv3oip +
 				sizeof(struct rte_flow_item_l2tpv3oip);
-		} else if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4 ||
-			cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6 ||
-			cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4_UDP ||
-			cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV6_UDP) {
-			if (cus_pctype->index == I40E_CUSTOMIZED_ESP_IPV4) {
-				esp_ipv4 = (struct rte_ipv4_hdr *)
-					(raw_pkt + len);
-				esp = (struct rte_flow_item_esp *)esp_ipv4;
-				esp->hdr.spi =
-					fdir_input->flow.esp_ipv4_flow.spi;
-				payload = (unsigned char *)esp +
-					sizeof(struct rte_esp_hdr);
-				len += sizeof(struct rte_esp_hdr);
-			} else if (cus_pctype->index ==
-					I40E_CUSTOMIZED_ESP_IPV4_UDP) {
-				esp_ipv4 = (struct rte_ipv4_hdr *)
-					(raw_pkt + len);
-				udp = (struct rte_udp_hdr *)esp_ipv4;
-				udp->dst_port = rte_cpu_to_be_16
-					(I40E_FDIR_ESP_DST_PORT);
-
-				udp->dgram_len = rte_cpu_to_be_16
-						(I40E_FDIR_UDP_DEFAULT_LEN);
-				esp = (struct rte_flow_item_esp *)
-					((unsigned char *)esp_ipv4 +
-						sizeof(struct rte_udp_hdr));
-				esp->hdr.spi =
-					fdir_input->flow.esp_ipv4_udp_flow.spi;
-				payload = (unsigned char *)esp +
-					sizeof(struct rte_esp_hdr);
-				len += sizeof(struct rte_udp_hdr) +
-						sizeof(struct rte_esp_hdr);
-			} else if (cus_pctype->index ==
-					I40E_CUSTOMIZED_ESP_IPV6) {
-				esp_ipv6 = (struct rte_ipv6_hdr *)
-					(raw_pkt + len);
-				esp = (struct rte_flow_item_esp *)esp_ipv6;
-				esp->hdr.spi =
-					fdir_input->flow.esp_ipv6_flow.spi;
-				payload = (unsigned char *)esp +
-					sizeof(struct rte_esp_hdr);
-				len += sizeof(struct rte_esp_hdr);
-			} else if (cus_pctype->index ==
-					I40E_CUSTOMIZED_ESP_IPV6_UDP) {
-				esp_ipv6 = (struct rte_ipv6_hdr *)
-					(raw_pkt + len);
-				udp = (struct rte_udp_hdr *)esp_ipv6;
-				udp->dst_port =	rte_cpu_to_be_16
-					(I40E_FDIR_ESP_DST_PORT);
-
-				udp->dgram_len = rte_cpu_to_be_16
-					(I40E_FDIR_UDP_DEFAULT_LEN);
-				esp = (struct rte_flow_item_esp *)
-					((unsigned char *)esp_ipv6 +
-						sizeof(struct rte_udp_hdr));
-				esp->hdr.spi =
-					fdir_input->flow.esp_ipv6_udp_flow.spi;
-				payload = (unsigned char *)esp +
-					sizeof(struct rte_esp_hdr);
-				len += sizeof(struct rte_udp_hdr) +
-						sizeof(struct rte_esp_hdr);
-			}
+			break;
+
+		case I40E_CUSTOMIZED_ESP_IPV4:
+			esp_ipv4 = (struct rte_ipv4_hdr *)(raw_pkt + len);
+			esp = (struct rte_flow_item_esp *)esp_ipv4;
+			esp->hdr.spi =
+			    fdir_input->flow.esp_ipv4_flow.spi;
+			payload = (unsigned char *)esp +
+				  sizeof(struct rte_esp_hdr);
+			len += sizeof(struct rte_esp_hdr);
+			break;
+		case I40E_CUSTOMIZED_ESP_IPV6:
+			esp_ipv6 = (struct rte_ipv6_hdr *)(raw_pkt + len);
+			esp = (struct rte_flow_item_esp *)esp_ipv6;
+			esp->hdr.spi =
+			    fdir_input->flow.esp_ipv6_flow.spi;
+			payload = (unsigned char *)esp +
+				  sizeof(struct rte_esp_hdr);
+			len += sizeof(struct rte_esp_hdr);
+			break;
+		case I40E_CUSTOMIZED_ESP_IPV4_UDP:
+			esp_ipv4 = (struct rte_ipv4_hdr *)(raw_pkt + len);
+			udp = (struct rte_udp_hdr *)esp_ipv4;
+			udp->dst_port = rte_cpu_to_be_16(I40E_FDIR_ESP_DST_PORT);
+
+			udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
+			esp = (struct rte_flow_item_esp *)((unsigned char *)esp_ipv4 +
+							   sizeof(struct rte_udp_hdr));
+			esp->hdr.spi =
+			    fdir_input->flow.esp_ipv4_udp_flow.spi;
+			payload = (unsigned char *)esp +
+				  sizeof(struct rte_esp_hdr);
+			len += sizeof(struct rte_udp_hdr) +
+			       sizeof(struct rte_esp_hdr);
+			break;
+
+		case I40E_CUSTOMIZED_ESP_IPV6_UDP:
+			esp_ipv6 = (struct rte_ipv6_hdr *)(raw_pkt + len);
+			udp = (struct rte_udp_hdr *)esp_ipv6;
+			udp->dst_port = rte_cpu_to_be_16(I40E_FDIR_ESP_DST_PORT);
+
+			udp->dgram_len = rte_cpu_to_be_16(I40E_FDIR_UDP_DEFAULT_LEN);
+			esp = (struct rte_flow_item_esp *)((unsigned char *)esp_ipv6 +
+							   sizeof(struct rte_udp_hdr));
+			esp->hdr.spi =
+			    fdir_input->flow.esp_ipv6_udp_flow.spi;
+			payload = (unsigned char *)esp +
+				  sizeof(struct rte_esp_hdr);
+			len += sizeof(struct rte_udp_hdr) +
+			       sizeof(struct rte_esp_hdr);
+			break;
+
+		default:
+			PMD_DRV_LOG(ERR, "unknown customized pctype %u.", fdir_input->pctype);
+			return -1;
 		}
-	} else {
-		PMD_DRV_LOG(ERR, "unknown pctype %u.", fdir_input->pctype);
-		return -1;
 	}
 
 	/* fill the flexbytes to payload */
@@ -1764,7 +1922,8 @@  i40e_flow_add_del_fdir_filter(struct rte_eth_dev *dev,
 	if (add) {
 		/* configure the input set for common PCTYPEs*/
 		if (!filter->input.flow_ext.customized_pctype &&
-		    !filter->input.flow_ext.pkt_template) {
+		    !filter->input.flow_ext.pkt_template &&
+		     filter->input.pctype > I40E_FILTER_PCTYPE_NONF_IPV6_ICMP) {
 			ret = i40e_flow_set_fdir_inset(pf, pctype,
 					filter->input.flow_ext.input_set);
 			if (ret < 0)
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index b41a1fd3ca..35ab2ebd3f 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -1558,6 +1558,142 @@  static enum rte_flow_item_type pattern_vxlan_4[] = {
 	RTE_FLOW_ITEM_TYPE_END,
 };
 
+/* VXLAN outer IPv4 */
+static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv4_icmp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_ICMP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv4_vxlan_ipv6_icmp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_ICMP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv4_icmp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_ICMP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+/* VXLAN outer IPv6 */
+static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv4_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv4_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv4_icmp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV4,
+	RTE_FLOW_ITEM_TYPE_ICMP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv6_udp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv6_tcp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_TCP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv6_vxlan_ipv6_icmp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_UDP,
+	RTE_FLOW_ITEM_TYPE_VXLAN,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_ICMP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
+static enum rte_flow_item_type pattern_fdir_ipv6_icmp[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_IPV6,
+	RTE_FLOW_ITEM_TYPE_ICMP,
+	RTE_FLOW_ITEM_TYPE_END,
+};
+
 static enum rte_flow_item_type pattern_nvgre_1[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
 	RTE_FLOW_ITEM_TYPE_IPV4,
@@ -1837,6 +1973,25 @@  static struct i40e_valid_pattern i40e_supported_patterns[] = {
 	{ pattern_fdir_vlan_ipv6_sctp_raw_1_vf, i40e_flow_parse_fdir_filter },
 	{ pattern_fdir_vlan_ipv6_sctp_raw_2_vf, i40e_flow_parse_fdir_filter },
 	{ pattern_fdir_vlan_ipv6_sctp_raw_3_vf, i40e_flow_parse_fdir_filter },
+
+	/* VXLAN outer IPv4 */
+	{ pattern_fdir_ipv4_vxlan_ipv4_udp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv4_vxlan_ipv4_tcp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv4_vxlan_ipv4_icmp, i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv4_vxlan_ipv6_udp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv4_vxlan_ipv6_tcp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv4_vxlan_ipv6_icmp, i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv4_icmp,            i40e_flow_parse_fdir_filter },
+
+	/* VXLAN outer IPv6 */
+	{ pattern_fdir_ipv6_vxlan_ipv4_udp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv6_vxlan_ipv4_tcp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv6_vxlan_ipv4_icmp, i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv6_vxlan_ipv6_udp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv6_vxlan_ipv6_tcp,  i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv6_vxlan_ipv6_icmp, i40e_flow_parse_fdir_filter },
+	{ pattern_fdir_ipv6_icmp,            i40e_flow_parse_fdir_filter },
+
 	/* VXLAN */
 	{ pattern_vxlan_1, i40e_flow_parse_vxlan_filter },
 	{ pattern_vxlan_2, i40e_flow_parse_vxlan_filter },
@@ -2361,6 +2516,7 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 	const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask;
 	const struct rte_flow_item_tcp *tcp_spec, *tcp_mask;
 	const struct rte_flow_item_udp *udp_spec, *udp_mask;
+	const struct rte_flow_item_icmp *icmp_spec, *icmp_mask;
 	const struct rte_flow_item_sctp *sctp_spec, *sctp_mask;
 	const struct rte_flow_item_gtp *gtp_spec, *gtp_mask;
 	const struct rte_flow_item_esp *esp_spec, *esp_mask;
@@ -2388,8 +2544,15 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 	uint16_t ether_type;
 	uint32_t vtc_flow_cpu;
 	bool outer_ip = true;
+	bool is_vxlan = false;
 	uint8_t field_idx;
 	int ret;
+	enum out_inner_ip_type {
+		I40E_OIIP_IP4_IP4 = 0,
+		I40E_OIIP_IP4_IP6 = 1,
+		I40E_OIIP_IP6_IP4 = 2,
+		I40E_OIIP_IP6_IP6 = 3,
+	} oiip_type = I40E_OIIP_IP4_IP4;
 
 	memset(off_arr, 0, sizeof(off_arr));
 	memset(len_arr, 0, sizeof(len_arr));
@@ -2531,7 +2694,6 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV4:
-			l3 = RTE_FLOW_ITEM_TYPE_IPV4;
 			ipv4_spec = item->spec;
 			ipv4_mask = item->mask;
 			ipv4_last = item->last;
@@ -2682,12 +2844,16 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 				return -rte_errno;
 			}
 
-			if (outer_ip)
+			if (outer_ip) {
+				l3 = RTE_FLOW_ITEM_TYPE_IPV4;
 				outer_ip = false;
+			} else {
+				oiip_type = (l3 == RTE_FLOW_ITEM_TYPE_IPV4) ?
+					I40E_OIIP_IP4_IP4 : I40E_OIIP_IP6_IP4;
+			}
 
 			break;
 		case RTE_FLOW_ITEM_TYPE_IPV6:
-			l3 = RTE_FLOW_ITEM_TYPE_IPV6;
 			ipv6_spec = item->spec;
 			ipv6_mask = item->mask;
 			pctype = I40E_FILTER_PCTYPE_NONF_IPV6_OTHER;
@@ -2761,19 +2927,55 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 				return -rte_errno;
 			}
 
-			if (outer_ip)
+			if (outer_ip) {
+				l3 = RTE_FLOW_ITEM_TYPE_IPV6;
 				outer_ip = false;
+			} else {
+				oiip_type = (l3 == RTE_FLOW_ITEM_TYPE_IPV4) ?
+					I40E_OIIP_IP4_IP6 : I40E_OIIP_IP6_IP6;
+			}
+
 			break;
 		case RTE_FLOW_ITEM_TYPE_TCP:
 			tcp_spec = item->spec;
 			tcp_mask = item->mask;
 
+			if (is_vxlan) {
+				switch (oiip_type) {
+				case I40E_OIIP_IP4_IP4:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP;
+					break;
+				case I40E_OIIP_IP4_IP6:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP;
+					break;
+				case I40E_OIIP_IP6_IP4:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP;
+					break;
+				case I40E_OIIP_IP6_IP6:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP;
+					break;
+				}
+
+				/* Check TCP mask and update input set */
+				if (tcp_spec || tcp_mask) {
+					rte_flow_error_set(error, EINVAL,
+							RTE_FLOW_ERROR_TYPE_ITEM,
+							item,
+							"Invalid TCP mask");
+					return -rte_errno;
+				}
+
+				layer_idx = I40E_FLXPLD_L4_IDX;
+				break;
+			}
+
 			if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
 				pctype =
 					I40E_FILTER_PCTYPE_NONF_IPV4_TCP;
 			else if (l3 == RTE_FLOW_ITEM_TYPE_IPV6)
 				pctype =
 					I40E_FILTER_PCTYPE_NONF_IPV6_TCP;
+
 			if (tcp_spec && tcp_mask) {
 				/* Check TCP mask and update input set */
 				if (tcp_mask->hdr.sent_seq ||
@@ -2827,6 +3029,36 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 			udp_spec = item->spec;
 			udp_mask = item->mask;
 
+			if (is_vxlan) {
+				switch (oiip_type) {
+				case I40E_OIIP_IP4_IP4:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP;
+					break;
+				case I40E_OIIP_IP4_IP6:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP;
+					break;
+				case I40E_OIIP_IP6_IP4:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP;
+					break;
+				case I40E_OIIP_IP6_IP6:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP;
+					break;
+				}
+
+				/* Check UDP mask and update input set */
+				if (udp_spec || udp_mask) {
+					rte_flow_error_set(error, EINVAL,
+							RTE_FLOW_ERROR_TYPE_ITEM,
+							item,
+							"Invalid UDP mask");
+					return -rte_errno;
+				}
+
+				filter->input.flow_ext.is_udp = true;
+				layer_idx = I40E_FLXPLD_L4_IDX;
+				break;
+			}
+
 			if (l3 == RTE_FLOW_ITEM_TYPE_IPV4)
 				pctype =
 					I40E_FILTER_PCTYPE_NONF_IPV4_UDP;
@@ -2878,6 +3110,47 @@  i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
 			layer_idx = I40E_FLXPLD_L4_IDX;
 
 			break;
+
+		case RTE_FLOW_ITEM_TYPE_ICMP:
+			icmp_spec = item->spec;
+			icmp_mask = item->mask;
+
+			pctype = (l3 == RTE_FLOW_ITEM_TYPE_IPV4) ?
+				 I40E_FILTER_PCTYPE_NONF_IPV4_ICMP :
+				 I40E_FILTER_PCTYPE_NONF_IPV6_ICMP;
+
+			if (is_vxlan) {
+				switch (oiip_type) {
+				case I40E_OIIP_IP4_IP4:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP;
+					break;
+				case I40E_OIIP_IP4_IP6:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP;
+					break;
+				case I40E_OIIP_IP6_IP4:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP;
+					break;
+				case I40E_OIIP_IP6_IP6:
+					pctype = I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP;
+					break;
+				}
+
+				/* Check ICMP mask and update input set */
+				if (icmp_spec || icmp_mask) {
+					rte_flow_error_set(error, EINVAL,
+							RTE_FLOW_ERROR_TYPE_ITEM,
+							item,
+							"Invalid ICMP mask");
+					return -rte_errno;
+				}
+			}
+
+			layer_idx = I40E_FLXPLD_L4_IDX;
+			break;
+		case RTE_FLOW_ITEM_TYPE_VXLAN:
+		case RTE_FLOW_ITEM_TYPE_VXLAN_GPE:
+			is_vxlan = true;
+			break;
 		case RTE_FLOW_ITEM_TYPE_GTPC:
 		case RTE_FLOW_ITEM_TYPE_GTPU:
 			if (!pf->gtp_support) {
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 8a687803b9..f73d0335c6 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -3449,6 +3449,34 @@  i40e_set_default_pctype_table(struct rte_eth_dev *dev)
 				(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
 	ad->pctypes_tbl[RTE_ETH_FLOW_L2_PAYLOAD] =
 				(1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV4_UDP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV4_TCP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV4_ICMP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV4_ICMP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV6_UDP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV6_TCP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_VXLAN_IPV6_ICMP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_VXLAN_IPV6_ICMP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV4_UDP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV4_TCP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV4_ICMP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV4_ICMP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV6_UDP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_UDP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV6_TCP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_TCP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_VXLAN_IPV6_ICMP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_VXLAN_IPV6_ICMP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV4_ICMP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_ICMP);
+	ad->pctypes_tbl[RTE_ETH_FLOW_IPV6_ICMP] =
+			(1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_ICMP);
 
 	if (hw->mac.type == I40E_MAC_X722 ||
 		hw->mac.type == I40E_MAC_X722_VF) {
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 5e8331da1c..e9dbfc43d5 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -490,7 +490,23 @@  struct rte_eth_rss_conf {
 #define RTE_ETH_FLOW_NVGRE              21 /**< NVGRE protocol based flow */
 #define RTE_ETH_FLOW_VXLAN_GPE          22 /**< VXLAN-GPE protocol based flow */
 #define RTE_ETH_FLOW_GTPU               23 /**< GTPU protocol based flow */
-#define RTE_ETH_FLOW_MAX                24
+
+#define RTE_ETH_FLOW_IPV4_VXLAN_IPV4_UDP    24
+#define RTE_ETH_FLOW_IPV4_VXLAN_IPV4_TCP    25
+#define RTE_ETH_FLOW_IPV4_VXLAN_IPV4_ICMP   26
+#define RTE_ETH_FLOW_IPV4_VXLAN_IPV6_UDP    27
+#define RTE_ETH_FLOW_IPV4_VXLAN_IPV6_TCP    28
+#define RTE_ETH_FLOW_IPV4_VXLAN_IPV6_ICMP   29
+#define RTE_ETH_FLOW_IPV6_VXLAN_IPV4_UDP    30
+#define RTE_ETH_FLOW_IPV6_VXLAN_IPV4_TCP    31
+#define RTE_ETH_FLOW_IPV6_VXLAN_IPV4_ICMP   32
+#define RTE_ETH_FLOW_IPV6_VXLAN_IPV6_UDP    33
+#define RTE_ETH_FLOW_IPV6_VXLAN_IPV6_TCP    34
+#define RTE_ETH_FLOW_IPV6_VXLAN_IPV6_ICMP   35
+#define RTE_ETH_FLOW_IPV4_ICMP              36
+#define RTE_ETH_FLOW_IPV6_ICMP              37
+
+#define RTE_ETH_FLOW_MAX                38
 
 /*
  * Below macros are defined for RSS offload types, they can be used to