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.y...@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(-)

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
-- 
2.25.1

Reply via email to