Commit 52438be4 authored by Mark Bloch's avatar Mark Bloch Committed by Jason Gunthorpe
Browse files

RDMA/mlx5: Allow inserting a steering rule to the FDB



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: default avatarMark Bloch <markb@mellanox.com>
Reviewed-by: default avatarMaor Gottlieb <maorg@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 3b70508a
Loading
Loading
Loading
Loading
+63 −12
Original line number Diff line number Diff line
@@ -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,18 +300,9 @@ 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);
	if (err)
		goto end;

	if (flags) {
		err = mlx5_ib_ft_type_to_namespace(
			MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX, &obj->ns_type);
	err = mlx5_ib_matcher_ns(attrs, obj);
	if (err)
		goto end;
	}

	uobj->object = obj;
	obj->mdev = dev->mdev;
@@ -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(
+1 −0
Original line number Diff line number Diff line
@@ -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 {
+1 −0
Original line number Diff line number Diff line
@@ -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 {