All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yongseok Koh <yskoh@mellanox.com>
To: Adrien Mazarguil <adrien.mazarguil@6wind.com>,
	Shahaf Shuler <shahafs@mellanox.com>
Cc: "dev@dpdk.org" <dev@dpdk.org>, Yongseok Koh <yskoh@mellanox.com>
Subject: [PATCH 2/2] net/mlx5: support multiple groups and jump action
Date: Wed, 3 Oct 2018 01:56:54 +0000	[thread overview]
Message-ID: <20181003015640.36306-3-yskoh@mellanox.com> (raw)
In-Reply-To: <20181003015640.36306-1-yskoh@mellanox.com>

rte_flow has 'group' attribute and 'jump' action in order to support
multiple groups. This feature is known as multi-table support ('chain' in
linux TC flower) in general because a group means a table of flows. Example
commands are:

	flow create 0 transfer priority 1 ingress
	     pattern eth / vlan vid is 100 / end
	     actions jump group 1 / end

	flow create 0 transfer priority 1 ingress
	     pattern eth / vlan vid is 200 / end
	     actions jump group 2 / end

	flow create 0 transfer group 1 priority 2 ingress
	     pattern eth / vlan vid is 100 /
	     	     ipv4 dst spec 192.168.40.0 dst prefix 24 / end
	     actions drop / end

	flow create 0 transfer group 1 priority 2 ingress
	     pattern end
	     actions of_pop_vlan / port_id id 1 / end

	flow create 0 transfer group 2 priority 2 ingress
	     pattern eth / vlan vid is 200 /
	     	     ipv4 dst spec 192.168.40.0 dst prefix 24 / end
	     actions of_pop_vlan / port_id id 2 / end

	flow create 0 transfer group 2 priority 2 ingress
	     pattern end
	     actions port_id id 2 / end

With theses flows, if a packet having vlan 200 and src_ip as 192.168.40.1,
this packet will firstly hit the 1st flow. Then it will hit the 5th flow
because of the 'jump' action. As a result, the packet will be forwarded to
port 2 (VF representor) with vlan tag being stripped off. If the packet had
vlan 100 instead, it would be dropped by the 3rd flow.

Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
---
 drivers/net/mlx5/Makefile        | 10 ++++++
 drivers/net/mlx5/meson.build     |  4 +++
 drivers/net/mlx5/mlx5_flow.h     |  5 +++
 drivers/net/mlx5/mlx5_flow_tcf.c | 78 +++++++++++++++++++++++++++++++++++-----
 4 files changed, 88 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile
index ca1de9f21..92bae9dfc 100644
--- a/drivers/net/mlx5/Makefile
+++ b/drivers/net/mlx5/Makefile
@@ -347,6 +347,16 @@ mlx5_autoconf.h.new: $(RTE_SDK)/buildtools/auto-config-h.sh
 		enum TCA_VLAN_PUSH_VLAN_PRIORITY \
 		$(AUTOCONF_OUTPUT)
 	$Q sh -- '$<' '$@' \
+		HAVE_TCA_CHAIN \
+		linux/rtnetlink.h \
+		enum TCA_CHAIN \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
+		HAVE_TC_ACT_GOTO_CHAIN \
+		linux/pkt_cls.h \
+		define TC_ACT_GOTO_CHAIN \
+		$(AUTOCONF_OUTPUT)
+	$Q sh -- '$<' '$@' \
 		HAVE_SUPPORTED_40000baseKR4_Full \
 		/usr/include/linux/ethtool.h \
 		define SUPPORTED_40000baseKR4_Full \
diff --git a/drivers/net/mlx5/meson.build b/drivers/net/mlx5/meson.build
index fd93ac162..696624838 100644
--- a/drivers/net/mlx5/meson.build
+++ b/drivers/net/mlx5/meson.build
@@ -182,6 +182,10 @@ if build
 		'TCA_FLOWER_KEY_VLAN_ETH_TYPE' ],
 		[ 'HAVE_TC_ACT_VLAN', 'linux/tc_act/tc_vlan.h',
 		'TCA_VLAN_PUSH_VLAN_PRIORITY' ],
+		[ 'HAVE_TCA_CHAIN', 'linux/rtnetlink.h',
+		'TCA_CHAIN' ],
+		[ 'HAVE_TC_ACT_GOTO_CHAIN', 'linux/pkt_cls.h',
+		'TC_ACT_GOTO_CHAIN' ],
 		[ 'HAVE_RDMA_NL_NLDEV', 'rdma/rdma_netlink.h',
 		'RDMA_NL_NLDEV' ],
 		[ 'HAVE_RDMA_NLDEV_CMD_GET', 'rdma/rdma_netlink.h',
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 7117f1471..d4253110c 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -78,6 +78,7 @@
 #define MLX5_FLOW_ACTION_OF_PUSH_VLAN (1u << 8)
 #define MLX5_FLOW_ACTION_OF_SET_VLAN_VID (1u << 9)
 #define MLX5_FLOW_ACTION_OF_SET_VLAN_PCP (1u << 10)
+#define MLX5_FLOW_ACTION_JUMP (1u << 11)
 
 #define MLX5_FLOW_FATE_ACTIONS \
 	(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | MLX5_FLOW_ACTION_RSS)
@@ -125,6 +126,10 @@
 /* Max number of actions per DV flow. */
 #define MLX5_DV_MAX_NUMBER_OF_ACTIONS 8
 
+/* Due to a limitation on driver/FW. */
+#define MLX5_FLOW_GROUP_ID_MAX 3
+#define MLX5_FLOW_GROUP_PRIORITY_MAX 14
+
 enum mlx5_flow_drv_type {
 	MLX5_FLOW_TYPE_MIN,
 	MLX5_FLOW_TYPE_DV,
diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c
index b78998ec0..4adc6bd6e 100644
--- a/drivers/net/mlx5/mlx5_flow_tcf.c
+++ b/drivers/net/mlx5/mlx5_flow_tcf.c
@@ -148,6 +148,12 @@ struct tc_vlan {
 #ifndef HAVE_TCA_FLOWER_KEY_VLAN_ETH_TYPE
 #define TCA_FLOWER_KEY_VLAN_ETH_TYPE 25
 #endif
+#ifndef HAVE_TCA_CHAIN
+#define TCA_CHAIN 11
+#endif
+#ifndef HAVE_TC_ACT_GOTO_CHAIN
+#define TC_ACT_GOTO_CHAIN 0x20000000
+#endif
 
 #ifndef IPV6_ADDR_LEN
 #define IPV6_ADDR_LEN 16
@@ -225,7 +231,9 @@ struct flow_tcf_ptoi {
 	unsigned int ifindex; /**< Network interface index. */
 };
 
-#define MLX5_TCF_FATE_ACTIONS (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_PORT_ID)
+#define MLX5_TCF_FATE_ACTIONS \
+	(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_PORT_ID | \
+	 MLX5_FLOW_ACTION_JUMP)
 #define MLX5_TCF_VLAN_ACTIONS \
 	(MLX5_FLOW_ACTION_OF_POP_VLAN | MLX5_FLOW_ACTION_OF_PUSH_VLAN | \
 	 MLX5_FLOW_ACTION_OF_SET_VLAN_VID | MLX5_FLOW_ACTION_OF_SET_VLAN_PCP)
@@ -370,14 +378,25 @@ flow_tcf_validate_attributes(const struct rte_flow_attr *attr,
 			     struct rte_flow_error *error)
 {
 	/*
-	 * Supported attributes: no groups, some priorities and ingress only.
-	 * Don't care about transfer as it is the caller's problem.
+	 * Supported attributes: groups, some priorities and ingress only.
+	 * group is supported only if kernel supports chain. Don't care about
+	 * transfer as it is the caller's problem.
 	 */
-	if (attr->group)
+	if (attr->group > MLX5_FLOW_GROUP_ID_MAX)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ATTR_GROUP, attr,
-					  "groups are not supported");
-	if (attr->priority > 0xfffe)
+					  "group ID larger than "
+					  RTE_STR(MLX5_FLOW_GROUP_ID_MAX)
+					  " isn't supported");
+	else if (attr->group > 0 &&
+		 attr->priority > MLX5_FLOW_GROUP_PRIORITY_MAX)
+		return rte_flow_error_set(error, ENOTSUP,
+					  RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+					  attr,
+					  "lowest priority level is "
+					  RTE_STR(MLX5_FLOW_GROUP_PRIORITY_MAX)
+					  " when group is configured");
+	else if (attr->priority > 0xfffe)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
 					  attr,
@@ -428,6 +447,7 @@ flow_tcf_validate(struct rte_eth_dev *dev,
 	} spec, mask;
 	union {
 		const struct rte_flow_action_port_id *port_id;
+		const struct rte_flow_action_jump *jump;
 		const struct rte_flow_action_of_push_vlan *of_push_vlan;
 		const struct rte_flow_action_of_set_vlan_vid *
 			of_set_vlan_vid;
@@ -675,6 +695,16 @@ flow_tcf_validate(struct rte_eth_dev *dev,
 			action_flags |= MLX5_FLOW_ACTION_PORT_ID;
 			port_id_dev = &rte_eth_devices[conf.port_id->id];
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP:
+			conf.jump = actions->conf;
+			if (attr->group >= conf.jump->group)
+				return rte_flow_error_set
+					(error, ENOTSUP,
+					 RTE_FLOW_ERROR_TYPE_ACTION,
+					 actions,
+					 "can't jump to a group backward");
+			action_flags |= MLX5_FLOW_ACTION_JUMP;
+			break;
 		case RTE_FLOW_ACTION_TYPE_DROP:
 			if (action_flags & MLX5_TCF_FATE_ACTIONS)
 				return rte_flow_error_set
@@ -755,7 +785,8 @@ flow_tcf_validate(struct rte_eth_dev *dev,
  *   Maximum size of memory for items.
  */
 static int
-flow_tcf_get_items_and_size(const struct rte_flow_item items[],
+flow_tcf_get_items_and_size(const struct rte_flow_attr *attr,
+			    const struct rte_flow_item items[],
 			    uint64_t *item_flags)
 {
 	int size = 0;
@@ -764,6 +795,8 @@ flow_tcf_get_items_and_size(const struct rte_flow_item items[],
 	size += SZ_NLATTR_STRZ_OF("flower") +
 		SZ_NLATTR_NEST + /* TCA_OPTIONS. */
 		SZ_NLATTR_TYPE_OF(uint32_t); /* TCA_CLS_FLAGS_SKIP_SW. */
+	if (attr->group > 0)
+		size += SZ_NLATTR_TYPE_OF(uint32_t); /* TCA_CHAIN. */
 	for (; items->type != RTE_FLOW_ITEM_TYPE_END; items++) {
 		switch (items->type) {
 		case RTE_FLOW_ITEM_TYPE_VOID:
@@ -853,6 +886,13 @@ flow_tcf_get_actions_and_size(const struct rte_flow_action actions[],
 				SZ_NLATTR_TYPE_OF(struct tc_mirred);
 			flags |= MLX5_FLOW_ACTION_PORT_ID;
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP:
+			size += SZ_NLATTR_NEST + /* na_act_index. */
+				SZ_NLATTR_STRZ_OF("gact") +
+				SZ_NLATTR_NEST + /* TCA_ACT_OPTIONS. */
+				SZ_NLATTR_TYPE_OF(struct tc_gact);
+			flags |= MLX5_FLOW_ACTION_JUMP;
+			break;
 		case RTE_FLOW_ACTION_TYPE_DROP:
 			size += SZ_NLATTR_NEST + /* na_act_index. */
 				SZ_NLATTR_STRZ_OF("gact") +
@@ -938,7 +978,7 @@ flow_tcf_nl_brand(struct nlmsghdr *nlh, uint32_t handle)
  *   otherwise NULL and rte_ernno is set.
  */
 static struct mlx5_flow *
-flow_tcf_prepare(const struct rte_flow_attr *attr __rte_unused,
+flow_tcf_prepare(const struct rte_flow_attr *attr,
 		 const struct rte_flow_item items[],
 		 const struct rte_flow_action actions[],
 		 uint64_t *item_flags, uint64_t *action_flags,
@@ -951,7 +991,7 @@ flow_tcf_prepare(const struct rte_flow_attr *attr __rte_unused,
 	struct nlmsghdr *nlh;
 	struct tcmsg *tcm;
 
-	size += flow_tcf_get_items_and_size(items, item_flags);
+	size += flow_tcf_get_items_and_size(attr, items, item_flags);
 	size += flow_tcf_get_actions_and_size(actions, action_flags);
 	dev_flow = rte_zmalloc(__func__, size, MNL_ALIGNTO);
 	if (!dev_flow) {
@@ -1022,6 +1062,7 @@ flow_tcf_translate(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow,
 	} spec, mask;
 	union {
 		const struct rte_flow_action_port_id *port_id;
+		const struct rte_flow_action_jump *jump;
 		const struct rte_flow_action_of_push_vlan *of_push_vlan;
 		const struct rte_flow_action_of_set_vlan_vid *
 			of_set_vlan_vid;
@@ -1056,6 +1097,8 @@ flow_tcf_translate(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow,
 	 */
 	tcm->tcm_info = TC_H_MAKE((attr->priority + 1) << 16,
 				  RTE_BE16(ETH_P_ALL));
+	if (attr->group > 0)
+		mnl_attr_put_u32(nlh, TCA_CHAIN, attr->group);
 	mnl_attr_put_strz(nlh, TCA_KIND, "flower");
 	na_flower = mnl_attr_nest_start(nlh, TCA_OPTIONS);
 	mnl_attr_put_u32(nlh, TCA_FLOWER_FLAGS, TCA_CLS_FLAGS_SKIP_SW);
@@ -1330,6 +1373,23 @@ flow_tcf_translate(struct rte_eth_dev *dev, struct mlx5_flow *dev_flow,
 			mnl_attr_nest_end(nlh, na_act);
 			mnl_attr_nest_end(nlh, na_act_index);
 			break;
+		case RTE_FLOW_ACTION_TYPE_JUMP:
+			conf.jump = actions->conf;
+			na_act_index =
+				mnl_attr_nest_start(nlh, na_act_index_cur++);
+			assert(na_act_index);
+			mnl_attr_put_strz(nlh, TCA_ACT_KIND, "gact");
+			na_act = mnl_attr_nest_start(nlh, TCA_ACT_OPTIONS);
+			assert(na_act);
+			mnl_attr_put(nlh, TCA_GACT_PARMS,
+				     sizeof(struct tc_gact),
+				     &(struct tc_gact){
+					.action = TC_ACT_GOTO_CHAIN |
+						  conf.jump->group,
+				     });
+			mnl_attr_nest_end(nlh, na_act);
+			mnl_attr_nest_end(nlh, na_act_index);
+			break;
 		case RTE_FLOW_ACTION_TYPE_DROP:
 			na_act_index =
 				mnl_attr_nest_start(nlh, na_act_index_cur++);
-- 
2.11.0

  parent reply	other threads:[~2018-10-03  1:56 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-03  1:56 [PATCH 0/2] net/mlx5: support multiple groups and jump action Yongseok Koh
2018-10-03  1:56 ` [PATCH 1/2] ethdev: add jump action to description table Yongseok Koh
2018-10-03  7:12   ` Andrew Rybchenko
2018-10-03  7:31     ` Yongseok Koh
2018-10-03  1:56 ` Yongseok Koh [this message]
2018-10-08 18:06 ` [PATCH v2] net/mlx5: support multiple groups and jump action Yongseok Koh
2018-10-09  8:18   ` Ori Kam
2018-10-09 12:50   ` Shahaf Shuler
2018-10-10  2:47     ` Yongseok Koh
2018-10-10  5:35       ` Shahaf Shuler
2018-10-10  2:54 ` [PATCH v3] " Yongseok Koh
2018-10-12  8:42 ` [PATCH v4] " Yongseok Koh
2018-10-14  5:55   ` Shahaf Shuler

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=20181003015640.36306-3-yskoh@mellanox.com \
    --to=yskoh@mellanox.com \
    --cc=adrien.mazarguil@6wind.com \
    --cc=dev@dpdk.org \
    --cc=shahafs@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.