All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leon Romanovsky <leon@kernel.org>
To: Doug Ledford <dledford@redhat.com>, Jason Gunthorpe <jgg@mellanox.com>
Cc: Leon Romanovsky <leonro@mellanox.com>,
	RDMA mailing list <linux-rdma@vger.kernel.org>,
	Guy Levi <guyle@mellanox.com>, Mark Bloch <markb@mellanox.com>,
	Or Gerlitz <ogerlitz@mellanox.com>,
	Saeed Mahameed <saeedm@mellanox.com>,
	linux-netdev <netdev@vger.kernel.org>
Subject: [PATCH rdma-next 13/27] RDMA/mlx5: Add a new flow action verb, modify header
Date: Sun, 29 Jul 2018 15:58:51 +0300	[thread overview]
Message-ID: <20180729125905.31989-14-leon@kernel.org> (raw)
In-Reply-To: <20180729125905.31989-1-leon@kernel.org>

From: Mark Bloch <markb@mellanox.com>

Expose the ability to create a flow action which mutates packet
headers. The data passed from userspace should be modify header actions
as defined by Mellanox's PRM.

Signed-off-by: Mark Bloch <markb@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
---
 drivers/infiniband/hw/mlx5/flow.c         | 128 ++++++++++++++++++++++++++++++
 drivers/infiniband/hw/mlx5/main.c         |   5 +-
 drivers/infiniband/hw/mlx5/mlx5_ib.h      |  15 ++++
 include/uapi/rdma/mlx5_user_ioctl_cmds.h  |  10 +++
 include/uapi/rdma/mlx5_user_ioctl_verbs.h |   5 ++
 5 files changed, 162 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/mlx5/flow.c b/drivers/infiniband/hw/mlx5/flow.c
index ee398a9b5f26..2c7d75cb8ade 100644
--- a/drivers/infiniband/hw/mlx5/flow.c
+++ b/drivers/infiniband/hw/mlx5/flow.c
@@ -8,6 +8,7 @@
 #include <rdma/uverbs_types.h>
 #include <rdma/uverbs_ioctl.h>
 #include <rdma/mlx5_user_ioctl_cmds.h>
+#include <rdma/mlx5_user_ioctl_verbs.h>
 #include <rdma/ib_umem.h>
 #include <linux/mlx5/driver.h>
 #include <linux/mlx5/fs.h>
@@ -177,6 +178,114 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE)(
 	return err;
 }
 
+static int mlx5_ib_ft_type_to_namespace(u8 table_type, u8 *namespace)
+{
+	switch (table_type) {
+	case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX:
+		*namespace = MLX5_FLOW_NAMESPACE_BYPASS;
+		break;
+	case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX:
+		*namespace = MLX5_FLOW_NAMESPACE_EGRESS;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction)
+{
+	switch (maction->flow_action_raw.sub_type) {
+	case MLX5_IB_FLOW_ACTION_MODIFY_HEADER:
+		mlx5_modify_header_dealloc(maction->flow_action_raw.dev->mdev,
+					   maction->flow_action_raw.action_id);
+		break;
+	default:
+		WARN_ON(true);
+		break;
+	}
+}
+
+static struct ib_flow_action *
+mlx5_ib_create_modify_header(struct mlx5_ib_dev *dev, u8 ft_type,
+			     u8 num_actions, void *in)
+{
+	struct mlx5_ib_flow_action *maction;
+	u8 namespace;
+	int ret;
+
+	ret = mlx5_ib_ft_type_to_namespace(ft_type, &namespace);
+	if (ret)
+		return ERR_PTR(-EINVAL);
+
+	maction = kzalloc(sizeof(*maction), GFP_KERNEL);
+	if (!maction)
+		return ERR_PTR(-ENOMEM);
+
+	ret = mlx5_modify_header_alloc(dev->mdev, namespace, num_actions, in,
+				       &maction->flow_action_raw.action_id);
+
+	if (ret) {
+		kfree(maction);
+		return ERR_PTR(ret);
+	}
+	maction->flow_action_raw.sub_type =
+		MLX5_IB_FLOW_ACTION_MODIFY_HEADER;
+	maction->flow_action_raw.dev = dev;
+
+	return &maction->ib_action;
+}
+
+static bool mlx5_ib_modify_header_supported(struct mlx5_ib_dev *dev)
+{
+	return MLX5_CAP_FLOWTABLE_NIC_RX(dev->mdev, max_modify_header_actions) ||
+	       MLX5_CAP_FLOWTABLE_NIC_TX(dev->mdev, max_modify_header_actions);
+}
+
+static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER)(struct ib_device *ib_dev,
+									   struct ib_uverbs_file *file,
+									   struct uverbs_attr_bundle *attrs)
+{
+	struct ib_uobject *uobj = uverbs_attr_get_uobject(attrs,
+					MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE);
+	struct mlx5_ib_dev *mdev = to_mdev(uobj->context->device);
+	enum mlx5_ib_uapi_flow_table_type ft_type;
+	struct ib_flow_action *action;
+	void *in;
+	int len;
+	int ret;
+
+	if (!mlx5_ib_modify_header_supported(mdev))
+		return -EOPNOTSUPP;
+
+	in = uverbs_attr_get_alloced_ptr(attrs,
+					 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM);
+	len = uverbs_attr_get_len(attrs, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM);
+
+	if (len % MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto))
+		return -EINVAL;
+
+	ret = uverbs_get_const(&ft_type, attrs,
+			       MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE);
+	if (ret)
+		return -EINVAL;
+
+	action = mlx5_ib_create_modify_header(mdev, ft_type,
+					      len / MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto),
+					      in);
+	if (IS_ERR(action))
+		return PTR_ERR(action);
+
+	atomic_set(&action->usecnt, 0);
+	action->device = uobj->context->device;
+	action->type = IB_FLOW_ACTION_UNSPECIFIED;
+	action->uobject = uobj;
+	uobj->object = action;
+
+	return 0;
+}
+
 DECLARE_UVERBS_NAMED_METHOD(
 	MLX5_IB_METHOD_CREATE_FLOW,
 	UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE,
@@ -211,6 +320,24 @@ ADD_UVERBS_METHODS(mlx5_ib_fs,
 		   &UVERBS_METHOD(MLX5_IB_METHOD_CREATE_FLOW),
 		   &UVERBS_METHOD(MLX5_IB_METHOD_DESTROY_FLOW));
 
+DECLARE_UVERBS_NAMED_METHOD(
+	MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER,
+	UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE,
+			UVERBS_OBJECT_FLOW_ACTION,
+			UVERBS_ACCESS_NEW,
+			UA_MANDATORY),
+	UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
+			   UVERBS_ATTR_MIN_SIZE(MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto)),
+			   UA_MANDATORY,
+			   UA_ALLOC_AND_COPY),
+	UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE,
+			     enum mlx5_ib_uapi_flow_table_type,
+			     UA_MANDATORY));
+
+ADD_UVERBS_METHODS(mlx5_ib_flow_actions,
+		   UVERBS_OBJECT_FLOW_ACTION,
+		   &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER));
+
 DECLARE_UVERBS_NAMED_METHOD(
 	MLX5_IB_METHOD_FLOW_MATCHER_CREATE,
 	UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE,
@@ -249,6 +376,7 @@ int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root)
 
 	root[i++] = &flow_objects;
 	root[i++] = &mlx5_ib_fs;
+	root[i++] = &mlx5_ib_flow_actions;
 
 	return i;
 }
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index b3281e408d2a..b56ac6614be6 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -3997,6 +3997,9 @@ static int mlx5_ib_destroy_flow_action(struct ib_flow_action *action)
 		 */
 		mlx5_accel_esp_destroy_xfrm(maction->esp_aes_gcm.ctx);
 		break;
+	case IB_FLOW_ACTION_UNSPECIFIED:
+		mlx5_ib_destroy_flow_action_raw(maction);
+		break;
 	default:
 		WARN_ON(true);
 		break;
@@ -5533,7 +5536,7 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
 	UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_CREATE_FLOW_ACTION_FLAGS,
 			     enum mlx5_ib_uapi_flow_action_flags));
 
-#define NUM_TREES	5
+#define NUM_TREES	6
 static int populate_specs_root(struct mlx5_ib_dev *dev)
 {
 	const struct uverbs_object_tree_def *default_root[NUM_TREES + 1] = {
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 01bef4c2d396..b5dd68114588 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -151,6 +151,10 @@ struct mlx5_ib_pd {
 	u32			pdn;
 };
 
+enum {
+	MLX5_IB_FLOW_ACTION_MODIFY_HEADER,
+};
+
 #define MLX5_IB_FLOW_MCAST_PRIO		(MLX5_BY_PASS_NUM_PRIOS - 1)
 #define MLX5_IB_FLOW_LAST_PRIO		(MLX5_BY_PASS_NUM_REGULAR_PRIOS - 1)
 #if (MLX5_IB_FLOW_LAST_PRIO <= 0)
@@ -815,6 +819,11 @@ struct mlx5_ib_flow_action {
 			u64			    ib_flags;
 			struct mlx5_accel_esp_xfrm *ctx;
 		} esp_aes_gcm;
+		struct {
+			struct mlx5_ib_dev *dev;
+			u32 sub_type;
+			u32 action_id;
+		} flow_action_raw;
 	};
 };
 
@@ -1238,6 +1247,7 @@ struct mlx5_ib_flow_handler *mlx5_ib_raw_fs_rule_add(
 	void *cmd_in, int inlen, int dest_id, int dest_type);
 bool mlx5_ib_devx_is_flow_dest(void *obj, int *dest_id, int *dest_type);
 int mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root);
+void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction);
 #else
 static inline int
 mlx5_ib_devx_create(struct mlx5_ib_dev *dev,
@@ -1256,6 +1266,11 @@ mlx5_ib_get_flow_trees(const struct uverbs_object_tree_def **root)
 {
 	return 0;
 }
+static inline void
+mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action *maction)
+{
+	return;
+};
 #endif
 static inline void init_query_mad(struct ib_smp *mad)
 {
diff --git a/include/uapi/rdma/mlx5_user_ioctl_cmds.h b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
index 9c51801b9e64..9c83e13c0e89 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_cmds.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_cmds.h
@@ -166,4 +166,14 @@ enum mlx5_ib_flow_methods {
 	MLX5_IB_METHOD_DESTROY_FLOW,
 };
 
+enum mlx5_ib_flow_action_methods {
+	MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER = (1U << UVERBS_ID_NS_SHIFT),
+};
+
+enum mlx5_ib_create_flow_action_create_modify_header_attrs {
+	MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+	MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM,
+	MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE,
+};
+
 #endif
diff --git a/include/uapi/rdma/mlx5_user_ioctl_verbs.h b/include/uapi/rdma/mlx5_user_ioctl_verbs.h
index 8a2fb33f3ed4..ceb6d0d8529a 100644
--- a/include/uapi/rdma/mlx5_user_ioctl_verbs.h
+++ b/include/uapi/rdma/mlx5_user_ioctl_verbs.h
@@ -39,5 +39,10 @@ enum mlx5_ib_uapi_flow_action_flags {
 	MLX5_IB_UAPI_FLOW_ACTION_FLAGS_REQUIRE_METADATA	= 1 << 0,
 };
 
+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,
+};
+
 #endif
 
-- 
2.14.4

  parent reply	other threads:[~2018-07-29 12:58 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-29 12:58 [PATCH rdma-next 00/27] Flow actions to mutate packets Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 01/27] net/mlx5: Cleanup flow namespace getter switch logic Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 02/27] net/mlx5: Add proper NIC TX steering flow tables support Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 03/27] net/mlx5: Export modify header alloc/dealloc functions Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 04/27] net/mlx5: Add support for more namespaces when allocating modify header Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 05/27] net/mlx5: Break encap/decap into two separated flow table creation flags Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 06/27] net/mlx5: Move header encap type to IFC header file Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 07/27] {net, RDMA}/mlx5: Rename encap to reformat packet Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 08/27] net/mlx5: Expose new packet reformat capabilities Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 09/27] net/mlx5: Pass a namespace for packet reformat ID allocation Leon Romanovsky
2018-07-29 12:58 ` [PATCH mlx5-next 10/27] net/mlx5: Export packet reformat alloc/dealloc functions Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 11/27] RDMA/mlx5: Add NIC TX steering support Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 12/27] RDMA/uverbs: Add UVERBS_ATTR_CONST_IN to the specs language Leon Romanovsky
2018-07-29 12:58 ` Leon Romanovsky [this message]
2018-07-29 12:58 ` [PATCH rdma-next 14/27] RDMA/mlx5: Enable attaching modify header to steering flows Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 15/27] RDMA/mlx5: Enable decap and packet reformat on flow tables Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 16/27] RDMA/uverbs: Add generic function to fill in flow action object Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 17/27] RDMA/mlx5: Add new flow action verb, packet reformat Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 18/27] RDMA/mlx5: Enable attaching DECAP action to steering flows Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 19/27] RDMA/mlx5: Extend packet reformat verbs Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 20/27] RDMA/mlx5: Enable reformat on NIC RX if supported Leon Romanovsky
2018-07-29 12:58 ` [PATCH rdma-next 21/27] RDMA/mlx5: Enable attaching packet reformat action to steering flows Leon Romanovsky
2018-07-29 12:59 ` [PATCH rdma-next 22/27] IB/uverbs: Add IDRs array attribute type to ioctl() interface Leon Romanovsky
2018-07-29 12:59 ` [PATCH rdma-next 23/27] RDMA/mlx5: Refactor flow action parsing to be more generic Leon Romanovsky
2018-07-29 12:59 ` [PATCH rdma-next 24/27] RDMA/mlx5: Refactor DEVX flow creation Leon Romanovsky
2018-07-29 12:59 ` [PATCH rdma-next 25/27] RDMA/mlx5: Add flow actions support to DEVX create flow Leon Romanovsky
2018-07-29 12:59 ` [PATCH rdma-next 26/27] RDMA/mlx5: Add NIC TX namespace when getting a flow table Leon Romanovsky
2018-07-29 12:59 ` [PATCH rdma-next 27/27] RDMA/mlx5: Allow creating a matcher for a NIC TX " Leon Romanovsky
2018-07-30 17:09 ` [PATCH rdma-next 00/27] Flow actions to mutate packets Jason Gunthorpe
2018-07-30 17:37   ` Mark Bloch
2018-07-31 14:11 ` Leon Romanovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180729125905.31989-14-leon@kernel.org \
    --to=leon@kernel.org \
    --cc=dledford@redhat.com \
    --cc=guyle@mellanox.com \
    --cc=jgg@mellanox.com \
    --cc=leonro@mellanox.com \
    --cc=linux-rdma@vger.kernel.org \
    --cc=markb@mellanox.com \
    --cc=netdev@vger.kernel.org \
    --cc=ogerlitz@mellanox.com \
    --cc=saeedm@mellanox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.