RDMA/mlx5: Add support in steering default miss
authorMaor Gottlieb <maorg@mellanox.com>
Mon, 4 May 2020 05:30:12 +0000 (08:30 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 13 May 2020 18:55:41 +0000 (15:55 -0300)
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>
drivers/infiniband/hw/mlx5/flow.c
drivers/infiniband/hw/mlx5/main.c
include/uapi/rdma/mlx5_user_ioctl_cmds.h

index 5533b50..3fa6647 100644 (file)
@@ -69,19 +69,32 @@ static const struct uverbs_attr_spec mlx5_ib_flow_type[] = {
 
 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_CREATE_FLOW)(
        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_CREATE_FLOW)(
        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) {
@@ -636,7 +653,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,
index 3af57df..38bf384 100644 (file)
@@ -4200,18 +4200,17 @@ mlx5_ib_raw_fs_rule_add(struct mlx5_ib_dev *dev,
 
        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;
index 24f3388..07cf543 100644 (file)
@@ -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 {