RDMA/mlx5: Allow inserting a steering rule to the FDB
authorMark Bloch <markb@mellanox.com>
Thu, 28 Mar 2019 13:46:23 +0000 (15:46 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Mon, 22 Apr 2019 18:24:05 +0000 (15:24 -0300)
Allow this only via mlx5 raw create flow API, legacy verbs are not
supported. To accommodate that, we add a new attribute to matcher creation
to indicate the type of flow table to be used.
MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
With this new attribute MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS is no longer
needed, we keep it for compatibility but at most only a single attribute can
be passed of the two.

When inserting a flow rule to the FDB we require that a DEVX FT is
provided as a destination, no other configuration is allowed.

Signed-off-by: Mark Bloch <markb@mellanox.com>
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/hw/mlx5/flow.c
include/uapi/rdma/mlx5_user_ioctl_cmds.h
include/uapi/rdma/mlx5_user_ioctl_verbs.h

index 09f5bc6..71a8d46 100644 (file)
@@ -29,6 +29,9 @@ mlx5_ib_ft_type_to_namespace(enum mlx5_ib_uapi_flow_table_type table_type,
        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;
        }
@@ -93,6 +96,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
            ((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);
@@ -104,6 +111,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
                 */
                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;
 
@@ -203,6 +214,54 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject,
        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)
 {
@@ -210,14 +269,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
                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,
@@ -243,19 +300,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
        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);
@@ -605,6 +653,9 @@ DECLARE_UVERBS_NAMED_METHOD(
                           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(
index 8149d22..0d8f564 100644 (file)
@@ -144,6 +144,7 @@ enum mlx5_ib_flow_matcher_create_attrs {
        MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
        MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
        MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
+       MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE,
 };
 
 enum mlx5_ib_flow_matcher_destroy_attrs {
index 4a70103..0a126a6 100644 (file)
@@ -42,6 +42,7 @@ enum mlx5_ib_uapi_flow_action_flags {
 enum mlx5_ib_uapi_flow_table_type {
        MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX     = 0x0,
        MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX     = 0x1,
+       MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB        = 0x2,
 };
 
 enum mlx5_ib_uapi_flow_action_packet_reformat_type {