case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX:
                *namespace = MLX5_FLOW_NAMESPACE_EGRESS;
                break;
+       case MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB:
+               *namespace = MLX5_FLOW_NAMESPACE_FDB;
+               break;
        default:
                return -EINVAL;
        }
            ((dest_devx && dest_qp) || (!dest_devx && !dest_qp)))
                return -EINVAL;
 
+       /* Allow only DEVX object as dest when inserting to FDB */
+       if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB && !dest_devx)
+               return -EINVAL;
+
        if (dest_devx) {
                devx_obj = uverbs_attr_get_obj(
                        attrs, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
                 */
                if (!mlx5_ib_devx_is_flow_dest(devx_obj, &dest_id, &dest_type))
                        return -EINVAL;
+               /* Allow only flow table as dest when inserting to FDB */
+               if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB &&
+                   dest_type != MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE)
+                       return -EINVAL;
        } else if (dest_qp) {
                struct mlx5_ib_qp *mqp;
 
        return 0;
 }
 
+static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle *attrs,
+                             struct mlx5_ib_flow_matcher *obj)
+{
+       enum mlx5_ib_uapi_flow_table_type ft_type =
+               MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX;
+       u32 flags;
+       int err;
+
+       /* New users should use MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE and older
+        * users should switch to it. We leave this to not break userspace
+        */
+       if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE) &&
+           uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS))
+               return -EINVAL;
+
+       if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE)) {
+               err = uverbs_get_const(&ft_type, attrs,
+                                      MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE);
+               if (err)
+                       return err;
+
+               err = mlx5_ib_ft_type_to_namespace(ft_type, &obj->ns_type);
+               if (err)
+                       return err;
+
+               return 0;
+       }
+
+       if (uverbs_attr_is_valid(attrs, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS)) {
+               err = uverbs_get_flags32(&flags, attrs,
+                                        MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
+                                        IB_FLOW_ATTR_FLAGS_EGRESS);
+               if (err)
+                       return err;
+
+               if (flags) {
+                       mlx5_ib_ft_type_to_namespace(
+                               MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX,
+                               &obj->ns_type);
+                       return 0;
+               }
+       }
+
+       obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
+
+       return 0;
+}
+
 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
        struct uverbs_attr_bundle *attrs)
 {
                attrs, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE);
        struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata);
        struct mlx5_ib_flow_matcher *obj;
-       u32 flags;
        int err;
 
        obj = kzalloc(sizeof(struct mlx5_ib_flow_matcher), GFP_KERNEL);
        if (!obj)
                return -ENOMEM;
 
-       obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
        obj->mask_len = uverbs_attr_get_len(
                attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
        err = uverbs_copy_from(&obj->matcher_mask,
        if (err)
                goto end;
 
-       err = uverbs_get_flags32(&flags, attrs,
-                                MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
-                                IB_FLOW_ATTR_FLAGS_EGRESS);
+       err = mlx5_ib_matcher_ns(attrs, obj);
        if (err)
                goto end;
 
-       if (flags) {
-               err = mlx5_ib_ft_type_to_namespace(
-                       MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX, &obj->ns_type);
-               if (err)
-                       goto end;
-       }
-
        uobj->object = obj;
        obj->mdev = dev->mdev;
        atomic_set(&obj->usecnt, 0);
                           UA_MANDATORY),
        UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
                             enum ib_flow_flags,
+                            UA_OPTIONAL),
+       UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE,
+                            enum mlx5_ib_uapi_flow_table_type,
                             UA_OPTIONAL));
 
 DECLARE_UVERBS_NAMED_METHOD_DESTROY(