From: Maor Gottlieb <maorg@mellanox.com>
Date: Mon, 4 May 2020 08:30:12 +0300
Subject: RDMA/mlx5: Add support in steering default miss
Patch-mainline: v5.8-rc1
Git-commit: 8c112a5f29a343f89072bed4b9fa176fea226798
References: jsc#SLE-15175
User can configure default miss rule in order to skip matching in the user
domain and forward the packet to the kernel steering domain. When user
requests a default miss rule, we add steering rule to forward the traffic
to the next namespace.
Link: https://lore.kernel.org/r/20200504053012.270689-5-leon@kernel.org
Signed-off-by: Maor Gottlieb <maorg@mellanox.com>
Reviewed-by: Mark Zhang <markz@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
drivers/infiniband/hw/mlx5/flow.c | 32 +++++++++++++++++++++++++------
drivers/infiniband/hw/mlx5/main.c | 9 +++-----
include/uapi/rdma/mlx5_user_ioctl_cmds.h | 5 ++++
3 files changed, 35 insertions(+), 11 deletions(-)
--- a/drivers/infiniband/hw/mlx5/flow.c
+++ b/drivers/infiniband/hw/mlx5/flow.c
@@ -69,19 +69,32 @@ static const struct uverbs_attr_spec mlx
static int get_dests(struct uverbs_attr_bundle *attrs,
struct mlx5_ib_flow_matcher *fs_matcher, int *dest_id,
- int *dest_type, struct ib_qp **qp)
+ int *dest_type, struct ib_qp **qp, bool *def_miss)
{
bool dest_devx, dest_qp;
void *devx_obj;
+ u32 flags;
+ int err;
dest_devx = uverbs_attr_is_valid(attrs,
MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX);
dest_qp = uverbs_attr_is_valid(attrs,
MLX5_IB_ATTR_CREATE_FLOW_DEST_QP);
- if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS &&
- ((dest_devx && dest_qp) || (!dest_devx && !dest_qp)))
- return -EINVAL;
+ *def_miss = false;
+ err = uverbs_get_flags32(&flags, attrs,
+ MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
+ MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS);
+ if (err)
+ return err;
+ *def_miss = flags & MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS;
+
+ if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_BYPASS) {
+ if (dest_devx && (dest_qp || *def_miss))
+ return -EINVAL;
+ else if (dest_qp && *def_miss)
+ return -EINVAL;
+ }
/* Allow only DEVX object as dest when inserting to FDB */
if (fs_matcher->ns_type == MLX5_FLOW_NAMESPACE_FDB && !dest_devx)
@@ -153,6 +166,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD
void *devx_obj, *cmd_in;
struct ib_uobject *uobj;
struct mlx5_ib_dev *dev;
+ bool def_miss;
if (!capable(CAP_NET_RAW))
return -EPERM;
@@ -162,9 +176,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD
uobj = uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE);
dev = mlx5_udata_to_mdev(&attrs->driver_udata);
- if (get_dests(attrs, fs_matcher, &dest_id, &dest_type, &qp))
+ if (get_dests(attrs, fs_matcher, &dest_id, &dest_type, &qp, &def_miss))
return -EINVAL;
+ if (def_miss)
+ flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
+
len = uverbs_attr_get_uobjs_arr(attrs,
MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX, &arr_flow_actions);
if (len) {
@@ -639,7 +656,10 @@ DECLARE_UVERBS_NAMED_METHOD(
UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
UVERBS_ATTR_MIN_SIZE(sizeof(u32)),
UA_OPTIONAL,
- UA_ALLOC_AND_COPY));
+ UA_ALLOC_AND_COPY),
+ UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
+ enum mlx5_ib_create_flow_flags,
+ UA_OPTIONAL));
DECLARE_UVERBS_NAMED_METHOD_DESTROY(
MLX5_IB_METHOD_DESTROY_FLOW,
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -4200,18 +4200,17 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_d
if (dest_type == MLX5_FLOW_DESTINATION_TYPE_TIR) {
dst[dst_num].type = dest_type;
- dst[dst_num].tir_num = dest_id;
+ dst[dst_num++].tir_num = dest_id;
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
} else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE) {
dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE_NUM;
- dst[dst_num].ft_num = dest_id;
+ dst[dst_num++].ft_num = dest_id;
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
- } else {
- dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_PORT;
+ } else if (dest_type == MLX5_FLOW_DESTINATION_TYPE_PORT) {
+ dst[dst_num++].type = MLX5_FLOW_DESTINATION_TYPE_PORT;
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
}
- dst_num++;
if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_COUNT) {
dst[dst_num].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -241,6 +241,10 @@ enum mlx5_ib_flow_type {
MLX5_IB_FLOW_TYPE_MC_DEFAULT,
};
+enum mlx5_ib_create_flow_flags {
+ MLX5_IB_ATTR_CREATE_FLOW_FLAGS_DEFAULT_MISS = 1 << 0,
+};
+
enum mlx5_ib_create_flow_attrs {
MLX5_IB_ATTR_CREATE_FLOW_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE,
@@ -251,6 +255,7 @@ enum mlx5_ib_create_flow_attrs {
MLX5_IB_ATTR_CREATE_FLOW_TAG,
MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX,
MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET,
+ MLX5_IB_ATTR_CREATE_FLOW_FLAGS,
};
enum mlx5_ib_destoy_flow_attrs {