kern_spec_val = (void *)kern_spec +
                sizeof(struct ib_uverbs_flow_spec_hdr);
        kern_spec_mask = kern_spec_val + kern_filter_sz;
+       if (ib_spec->type == (IB_FLOW_SPEC_INNER | IB_FLOW_SPEC_VXLAN_TUNNEL))
+               return -EINVAL;
 
-       switch (ib_spec->type) {
+       switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {
        case IB_FLOW_SPEC_ETH:
                ib_filter_sz = offsetof(struct ib_flow_eth_filter, real_sz);
                actual_filter_sz = spec_filter_size(kern_spec_mask,
 
        IB_FLOW_SPEC_TCP                = 0x40,
        IB_FLOW_SPEC_UDP                = 0x41,
        IB_FLOW_SPEC_VXLAN_TUNNEL       = 0x50,
+       IB_FLOW_SPEC_INNER              = 0x100,
 };
 #define IB_FLOW_SPEC_LAYER_MASK        0xF0
-#define IB_FLOW_SPEC_SUPPORT_LAYERS 4
+#define IB_FLOW_SPEC_SUPPORT_LAYERS 8
 
 /* Flow steering rule priority is set according to it's domain.
  * Lower domain value means higher priority.
 };
 
 struct ib_flow_spec_eth {
-       enum ib_flow_spec_type    type;
+       u32                       type;
        u16                       size;
        struct ib_flow_eth_filter val;
        struct ib_flow_eth_filter mask;
 };
 
 struct ib_flow_spec_ib {
-       enum ib_flow_spec_type   type;
+       u32                      type;
        u16                      size;
        struct ib_flow_ib_filter val;
        struct ib_flow_ib_filter mask;
 };
 
 struct ib_flow_spec_ipv4 {
-       enum ib_flow_spec_type     type;
+       u32                        type;
        u16                        size;
        struct ib_flow_ipv4_filter val;
        struct ib_flow_ipv4_filter mask;
 };
 
 struct ib_flow_spec_ipv6 {
-       enum ib_flow_spec_type     type;
+       u32                        type;
        u16                        size;
        struct ib_flow_ipv6_filter val;
        struct ib_flow_ipv6_filter mask;
 };
 
 struct ib_flow_spec_tcp_udp {
-       enum ib_flow_spec_type        type;
+       u32                           type;
        u16                           size;
        struct ib_flow_tcp_udp_filter val;
        struct ib_flow_tcp_udp_filter mask;
  * the tunnel_id from val has the vni value
  */
 struct ib_flow_spec_tunnel {
-       enum ib_flow_spec_type        type;
+       u32                           type;
        u16                           size;
        struct ib_flow_tunnel_filter  val;
        struct ib_flow_tunnel_filter  mask;
 
 union ib_flow_spec {
        struct {
-               enum ib_flow_spec_type  type;
+               u32                     type;
                u16                     size;
        };
        struct ib_flow_spec_eth         eth;