diff mbox series

[mlx5-next,7/7] net/mlx5: TC: Offload flow table rules

Message ID 20191111233430.25120-8-pablo@netfilter.org
State Awaiting Upstream
Delegated to: Pablo Neira
Headers show
Series netfilter flowtable hardware offload support | expand

Commit Message

Pablo Neira Ayuso Nov. 11, 2019, 11:34 p.m. UTC
From: Paul Blakey <paulb@mellanox.com>

Since both tc rules and flow table rules are of the same format,
we can re-use tc parsing for that, and move the flow table rules
to their steering domain - In this case, the next chain after
max tc chain.

Issue: 1929510
Change-Id: I68bf14d5398b91cf26cc7c7f19dab64ba8757c01
Signed-off-by: Paul Blakey <paulb@mellanox.com>
Reviewed-by: Mark Bloch <markb@mellanox.com>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 45 ++++++++++++++++++++++--
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c  | 28 ++++++++++++++-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.h  |  3 +-
 3 files changed, 71 insertions(+), 5 deletions(-)

Comments

Saeed Mahameed Nov. 12, 2019, 12:37 a.m. UTC | #1
On Tue, 2019-11-12 at 00:34 +0100, Pablo Neira Ayuso wrote:
> From: Paul Blakey <paulb@mellanox.com>
> 
> Since both tc rules and flow table rules are of the same format,
> we can re-use tc parsing for that, and move the flow table rules
> to their steering domain - In this case, the next chain after
> max tc chain.
> 
> Issue: 1929510
> Change-Id: I68bf14d5398b91cf26cc7c7f19dab64ba8757c01
> Signed-off-by: Paul Blakey <paulb@mellanox.com>
> Reviewed-by: Mark Bloch <markb@mellanox.com>
> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

Series LGTM, 

couple of things:
 
1) Paul should have removed Issue and change-Id tags
I can do this myself when i apply those to my trees.

2) patches #1..#6 can perfectly go mlx5-next,
already tried and i had to resolve some trivial conflicts, but all
good.

3) this patch needs to be on top of net-next, due to dependency with 
TC_SETUP_FT, I will resubmit it through my normal pull request
procedure after applying all other patches in this series to mlx5-next
shared branch. 

All patches will land in net-next in couple of days, i guess there is
no rush to have them there immediately ? 

Thanks,
saeed.
Pablo Neira Ayuso Nov. 12, 2019, 8:32 p.m. UTC | #2
Hi Saeed,

On Tue, Nov 12, 2019 at 12:37:27AM +0000, Saeed Mahameed wrote:
> On Tue, 2019-11-12 at 00:34 +0100, Pablo Neira Ayuso wrote:
> > From: Paul Blakey <paulb@mellanox.com>
> > 
> > Since both tc rules and flow table rules are of the same format,
> > we can re-use tc parsing for that, and move the flow table rules
> > to their steering domain - In this case, the next chain after
> > max tc chain.
> > 
> > Issue: 1929510
> > Change-Id: I68bf14d5398b91cf26cc7c7f19dab64ba8757c01
> > Signed-off-by: Paul Blakey <paulb@mellanox.com>
> > Reviewed-by: Mark Bloch <markb@mellanox.com>
> > Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
> 
> Series LGTM, 
> 
> couple of things:
>  
> 1) Paul should have removed Issue and change-Id tags
> I can do this myself when i apply those to my trees.
>
> 2) patches #1..#6 can perfectly go mlx5-next,
> already tried and i had to resolve some trivial conflicts, but all
> good.

Thanks.

> 3) this patch needs to be on top of net-next, due to dependency with 
> TC_SETUP_FT, I will resubmit it through my normal pull request
> procedure after applying all other patches in this series to mlx5-next
> shared branch. 
>
> All patches will land in net-next in couple of days, i guess there is
> no rush to have them there immediately ?

No rush on my side.

We have to wait for David to tell us if he is fine to apply this
patchset into net-next, then pull from your tree the first client for
this code in a couple of days as you suggest.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index cd9bb7c7b341..c9cb037d7f79 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1243,21 +1243,60 @@  static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
 	}
 }
 
-static LIST_HEAD(mlx5e_rep_block_cb_list);
+static int mlx5e_rep_setup_ft_cb(enum tc_setup_type type, void *type_data,
+				 void *cb_priv)
+{
+	struct flow_cls_offload *f = type_data;
+	struct flow_cls_offload cls_flower;
+	struct mlx5e_priv *priv = cb_priv;
+	struct mlx5_eswitch *esw;
+	unsigned long flags;
+	int err;
+
+	flags = MLX5_TC_FLAG(INGRESS) |
+		MLX5_TC_FLAG(ESW_OFFLOAD) |
+		MLX5_TC_FLAG(FT_OFFLOAD);
+	esw = priv->mdev->priv.eswitch;
 
+	switch (type) {
+	case TC_SETUP_CLSFLOWER:
+		if (!mlx5_eswitch_prios_supported(esw) || f->common.chain_index)
+			return -EOPNOTSUPP;
+
+		/* Re-use tc offload path by moving the ft flow to the
+		 * reserved ft chain.
+		 */
+		memcpy(&cls_flower, f, sizeof(*f));
+		cls_flower.common.chain_index = FDB_FT_CHAIN;
+		err = mlx5e_rep_setup_tc_cls_flower(priv, &cls_flower, flags);
+		memcpy(&f->stats, &cls_flower.stats, sizeof(f->stats));
+		return err;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static LIST_HEAD(mlx5e_rep_block_tc_cb_list);
+static LIST_HEAD(mlx5e_rep_block_ft_cb_list);
 static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
 			      void *type_data)
 {
 	struct mlx5e_priv *priv = netdev_priv(dev);
 	struct flow_block_offload *f = type_data;
 
+	f->unlocked_driver_cb = true;
+
 	switch (type) {
 	case TC_SETUP_BLOCK:
-		f->unlocked_driver_cb = true;
 		return flow_block_cb_setup_simple(type_data,
-						  &mlx5e_rep_block_cb_list,
+						  &mlx5e_rep_block_tc_cb_list,
 						  mlx5e_rep_setup_tc_cb,
 						  priv, priv, true);
+	case TC_SETUP_FT:
+		return flow_block_cb_setup_simple(type_data,
+						  &mlx5e_rep_block_ft_cb_list,
+						  mlx5e_rep_setup_ft_cb,
+						  priv, priv, true);
 	default:
 		return -EOPNOTSUPP;
 	}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 0c1022cda128..3a707d788022 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -74,6 +74,7 @@  enum {
 	MLX5E_TC_FLOW_FLAG_INGRESS	= MLX5E_TC_FLAG_INGRESS_BIT,
 	MLX5E_TC_FLOW_FLAG_EGRESS	= MLX5E_TC_FLAG_EGRESS_BIT,
 	MLX5E_TC_FLOW_FLAG_ESWITCH	= MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
+	MLX5E_TC_FLOW_FLAG_FT		= MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
 	MLX5E_TC_FLOW_FLAG_NIC		= MLX5E_TC_FLAG_NIC_OFFLOAD_BIT,
 	MLX5E_TC_FLOW_FLAG_OFFLOADED	= MLX5E_TC_FLOW_BASE,
 	MLX5E_TC_FLOW_FLAG_HAIRPIN	= MLX5E_TC_FLOW_BASE + 1,
@@ -276,6 +277,11 @@  static bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow)
 	return flow_flag_test(flow, ESWITCH);
 }
 
+static bool mlx5e_is_ft_flow(struct mlx5e_tc_flow *flow)
+{
+	return flow_flag_test(flow, FT);
+}
+
 static bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow)
 {
 	return flow_flag_test(flow, OFFLOADED);
@@ -1168,7 +1174,12 @@  mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
 		return -EOPNOTSUPP;
 	}
 
-	if (attr->chain > max_chain) {
+	/* We check chain range only for tc flows.
+	 * For ft flows, we checked attr->chain was originally 0 and set it to
+	 * FDB_FT_CHAIN which is outside tc range.
+	 * See mlx5e_rep_setup_ft_cb().
+	 */
+	if (!mlx5e_is_ft_flow(flow) && attr->chain > max_chain) {
 		NL_SET_ERR_MSG(extack, "Requested chain is out of supported range");
 		return -EOPNOTSUPP;
 	}
@@ -3217,6 +3228,7 @@  static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
 	struct mlx5e_tc_flow_parse_attr *parse_attr = attr->parse_attr;
 	struct mlx5e_rep_priv *rpriv = priv->ppriv;
 	const struct ip_tunnel_info *info = NULL;
+	bool ft_flow = mlx5e_is_ft_flow(flow);
 	const struct flow_action_entry *act;
 	bool encap = false;
 	u32 action = 0;
@@ -3261,6 +3273,14 @@  static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
 				return -EINVAL;
 			}
 
+			if (ft_flow && out_dev == priv->netdev) {
+				/* Ignore forward to self rules generated
+				 * by adding both mlx5 devs to the flow table
+				 * block on a normal nft offload setup.
+				 */
+				return -EOPNOTSUPP;
+			}
+
 			if (attr->out_count >= MLX5_MAX_FLOW_FWD_VPORTS) {
 				NL_SET_ERR_MSG_MOD(extack,
 						   "can't support more output ports, can't offload forwarding");
@@ -3385,6 +3405,10 @@  static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
 			u32 dest_chain = act->chain_index;
 			u32 max_chain = mlx5_eswitch_get_chain_range(esw);
 
+			if (ft_flow) {
+				NL_SET_ERR_MSG_MOD(extack, "Goto action is not supported");
+				return -EOPNOTSUPP;
+			}
 			if (dest_chain <= attr->chain) {
 				NL_SET_ERR_MSG(extack, "Goto earlier chain isn't supported");
 				return -EOPNOTSUPP;
@@ -3475,6 +3499,8 @@  static void get_flags(int flags, unsigned long *flow_flags)
 		__flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_ESWITCH);
 	if (flags & MLX5_TC_FLAG(NIC_OFFLOAD))
 		__flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_NIC);
+	if (flags & MLX5_TC_FLAG(FT_OFFLOAD))
+		__flow_flags |= BIT(MLX5E_TC_FLOW_FLAG_FT);
 
 	*flow_flags = __flow_flags;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
index 924c6ef86a14..262cdb7b69b1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.h
@@ -44,7 +44,8 @@  enum {
 	MLX5E_TC_FLAG_EGRESS_BIT,
 	MLX5E_TC_FLAG_NIC_OFFLOAD_BIT,
 	MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
-	MLX5E_TC_FLAG_LAST_EXPORTED_BIT = MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
+	MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
+	MLX5E_TC_FLAG_LAST_EXPORTED_BIT = MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
 };
 
 #define MLX5_TC_FLAG(flag) BIT(MLX5E_TC_FLAG_##flag##_BIT)