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: 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>
This commit is contained in:
Родитель
3b70508a6b
Коммит
52438be441
|
@ -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:
|
case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX:
|
||||||
*namespace = MLX5_FLOW_NAMESPACE_EGRESS;
|
*namespace = MLX5_FLOW_NAMESPACE_EGRESS;
|
||||||
break;
|
break;
|
||||||
|
case MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB:
|
||||||
|
*namespace = MLX5_FLOW_NAMESPACE_FDB;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -93,6 +96,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)(
|
||||||
((dest_devx && dest_qp) || (!dest_devx && !dest_qp)))
|
((dest_devx && dest_qp) || (!dest_devx && !dest_qp)))
|
||||||
return -EINVAL;
|
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) {
|
if (dest_devx) {
|
||||||
devx_obj = uverbs_attr_get_obj(
|
devx_obj = uverbs_attr_get_obj(
|
||||||
attrs, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
|
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))
|
if (!mlx5_ib_devx_is_flow_dest(devx_obj, &dest_id, &dest_type))
|
||||||
return -EINVAL;
|
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) {
|
} else if (dest_qp) {
|
||||||
struct mlx5_ib_qp *mqp;
|
struct mlx5_ib_qp *mqp;
|
||||||
|
|
||||||
|
@ -203,6 +214,54 @@ static int flow_matcher_cleanup(struct ib_uobject *uobject,
|
||||||
return 0;
|
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)(
|
static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
|
||||||
struct uverbs_attr_bundle *attrs)
|
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);
|
attrs, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE);
|
||||||
struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata);
|
struct mlx5_ib_dev *dev = mlx5_udata_to_mdev(&attrs->driver_udata);
|
||||||
struct mlx5_ib_flow_matcher *obj;
|
struct mlx5_ib_flow_matcher *obj;
|
||||||
u32 flags;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
obj = kzalloc(sizeof(struct mlx5_ib_flow_matcher), GFP_KERNEL);
|
obj = kzalloc(sizeof(struct mlx5_ib_flow_matcher), GFP_KERNEL);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
obj->ns_type = MLX5_FLOW_NAMESPACE_BYPASS;
|
|
||||||
obj->mask_len = uverbs_attr_get_len(
|
obj->mask_len = uverbs_attr_get_len(
|
||||||
attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
|
attrs, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK);
|
||||||
err = uverbs_copy_from(&obj->matcher_mask,
|
err = uverbs_copy_from(&obj->matcher_mask,
|
||||||
|
@ -243,19 +300,10 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
|
||||||
if (err)
|
if (err)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
err = uverbs_get_flags32(&flags, attrs,
|
err = mlx5_ib_matcher_ns(attrs, obj);
|
||||||
MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
|
|
||||||
IB_FLOW_ATTR_FLAGS_EGRESS);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto end;
|
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;
|
uobj->object = obj;
|
||||||
obj->mdev = dev->mdev;
|
obj->mdev = dev->mdev;
|
||||||
atomic_set(&obj->usecnt, 0);
|
atomic_set(&obj->usecnt, 0);
|
||||||
|
@ -605,6 +653,9 @@ DECLARE_UVERBS_NAMED_METHOD(
|
||||||
UA_MANDATORY),
|
UA_MANDATORY),
|
||||||
UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
|
UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
|
||||||
enum ib_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));
|
UA_OPTIONAL));
|
||||||
|
|
||||||
DECLARE_UVERBS_NAMED_METHOD_DESTROY(
|
DECLARE_UVERBS_NAMED_METHOD_DESTROY(
|
||||||
|
|
|
@ -144,6 +144,7 @@ enum mlx5_ib_flow_matcher_create_attrs {
|
||||||
MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
|
MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE,
|
||||||
MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
|
MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA,
|
||||||
MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
|
MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS,
|
||||||
|
MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum mlx5_ib_flow_matcher_destroy_attrs {
|
enum mlx5_ib_flow_matcher_destroy_attrs {
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum mlx5_ib_uapi_flow_action_flags {
|
||||||
enum mlx5_ib_uapi_flow_table_type {
|
enum mlx5_ib_uapi_flow_table_type {
|
||||||
MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX = 0x0,
|
MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX = 0x0,
|
||||||
MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX = 0x1,
|
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 {
|
enum mlx5_ib_uapi_flow_action_packet_reformat_type {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче