Blame SOURCES/0115-netdrv-net-mlx5e-E-switch-Fix-Ingress-ACL-groups-in-.patch

d8f823
From ca0a47bf9d5acf50538cd7f805640169dc595044 Mon Sep 17 00:00:00 2001
d8f823
From: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Date: Sun, 10 May 2020 15:04:39 -0400
d8f823
Subject: [PATCH 115/312] [netdrv] net/mlx5e: E-switch, Fix Ingress ACL groups
d8f823
 in switchdev mode for prio tag
d8f823
d8f823
Message-id: <20200510150452.10307-75-ahleihel@redhat.com>
d8f823
Patchwork-id: 306698
d8f823
Patchwork-instance: patchwork
d8f823
O-Subject: [RHEL8.3 BZ 1789380 v2 74/87] net/mlx5e: E-switch, Fix Ingress ACL groups in switchdev mode for prio tag
d8f823
Bugzilla: 1789380
d8f823
RH-Acked-by: Kamal Heib <kheib@redhat.com>
d8f823
RH-Acked-by: Jarod Wilson <jarod@redhat.com>
d8f823
RH-Acked-by: Tony Camuso <tcamuso@redhat.com>
d8f823
RH-Acked-by: Jonathan Toppins <jtoppins@redhat.com>
d8f823
d8f823
Bugzilla: http://bugzilla.redhat.com/1789380
d8f823
Upstream: v5.5-rc1
d8f823
d8f823
commit b7826076d7ae5928fdd2972a6c3e180148fb74c1
d8f823
Author: Parav Pandit <parav@mellanox.com>
d8f823
Date:   Tue Nov 12 17:06:00 2019 -0600
d8f823
d8f823
    net/mlx5e: E-switch, Fix Ingress ACL groups in switchdev mode for prio tag
d8f823
d8f823
    In cited commit, when prio tag mode is enabled, FTE creation fails
d8f823
    due to missing group with valid match criteria.
d8f823
d8f823
    Hence,
d8f823
    (a) create prio tag group metadata_prio_tag_grp when prio tag is
d8f823
    enabled with match criteria for vlan push FTE.
d8f823
    (b) Rename metadata_grp to metadata_allmatch_grp to reflect its purpose.
d8f823
d8f823
    Also when priority tag is enabled, delete metadata settings after
d8f823
    deleting ingress rules, which are using it.
d8f823
d8f823
    Tide up rest of the ingress config code for unnecessary labels.
d8f823
d8f823
    Fixes: 10652f39943e ("net/mlx5: Refactor ingress acl configuration")
d8f823
    Signed-off-by: Parav Pandit <parav@mellanox.com>
d8f823
    Reviewed-by: Eli Britstein <elibr@mellanox.com>
d8f823
    Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
d8f823
d8f823
Signed-off-by: Alaa Hleihel <ahleihel@redhat.com>
d8f823
Signed-off-by: Frantisek Hrbata <fhrbata@redhat.com>
d8f823
---
d8f823
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.h  |   9 +-
d8f823
 .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 122 ++++++++++++++-------
d8f823
 2 files changed, 93 insertions(+), 38 deletions(-)
d8f823
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
d8f823
index d9c3b8767224..14814f41346e 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
d8f823
@@ -94,7 +94,14 @@ struct vport_ingress {
d8f823
 		struct mlx5_fc *drop_counter;
d8f823
 	} legacy;
d8f823
 	struct {
d8f823
-		struct mlx5_flow_group *metadata_grp;
d8f823
+		/* Optional group to add an FTE to do internal priority
d8f823
+		 * tagging on ingress packets.
d8f823
+		 */
d8f823
+		struct mlx5_flow_group *metadata_prio_tag_grp;
d8f823
+		/* Group to add default match-all FTE entry to tag ingress
d8f823
+		 * packet with metadata.
d8f823
+		 */
d8f823
+		struct mlx5_flow_group *metadata_allmatch_grp;
d8f823
 		struct mlx5_modify_hdr *modify_metadata;
d8f823
 		struct mlx5_flow_handle *modify_metadata_rule;
d8f823
 	} offloads;
d8f823
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
d8f823
index 0f0d8decb04c..121abcae993a 100644
d8f823
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
d8f823
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
d8f823
@@ -88,6 +88,14 @@ u16 mlx5_eswitch_get_prio_range(struct mlx5_eswitch *esw)
d8f823
 	return 1;
d8f823
 }
d8f823
 
d8f823
+static bool
d8f823
+esw_check_ingress_prio_tag_enabled(const struct mlx5_eswitch *esw,
d8f823
+				   const struct mlx5_vport *vport)
d8f823
+{
d8f823
+	return (MLX5_CAP_GEN(esw->dev, prio_tag_required) &&
d8f823
+		mlx5_eswitch_is_vf_vport(esw, vport->vport));
d8f823
+}
d8f823
+
d8f823
 static void
d8f823
 mlx5_eswitch_set_rule_source_port(struct mlx5_eswitch *esw,
d8f823
 				  struct mlx5_flow_spec *spec,
d8f823
@@ -1763,12 +1771,9 @@ static int esw_vport_ingress_prio_tag_config(struct mlx5_eswitch *esw,
d8f823
 	 * required, allow
d8f823
 	 * Unmatched traffic is allowed by default
d8f823
 	 */
d8f823
-
d8f823
 	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
d8f823
-	if (!spec) {
d8f823
-		err = -ENOMEM;
d8f823
-		goto out_no_mem;
d8f823
-	}
d8f823
+	if (!spec)
d8f823
+		return -ENOMEM;
d8f823
 
d8f823
 	/* Untagged packets - push prio tag VLAN, allow */
d8f823
 	MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.cvlan_tag);
d8f823
@@ -1794,14 +1799,9 @@ static int esw_vport_ingress_prio_tag_config(struct mlx5_eswitch *esw,
d8f823
 			 "vport[%d] configure ingress untagged allow rule, err(%d)\n",
d8f823
 			 vport->vport, err);
d8f823
 		vport->ingress.allow_rule = NULL;
d8f823
-		goto out;
d8f823
 	}
d8f823
 
d8f823
-out:
d8f823
 	kvfree(spec);
d8f823
-out_no_mem:
d8f823
-	if (err)
d8f823
-		esw_vport_cleanup_ingress_rules(esw, vport);
d8f823
 	return err;
d8f823
 }
d8f823
 
d8f823
@@ -1839,13 +1839,9 @@ static int esw_vport_add_ingress_acl_modify_metadata(struct mlx5_eswitch *esw,
d8f823
 		esw_warn(esw->dev,
d8f823
 			 "failed to add setting metadata rule for vport %d ingress acl, err(%d)\n",
d8f823
 			 vport->vport, err);
d8f823
+		mlx5_modify_header_dealloc(esw->dev, vport->ingress.offloads.modify_metadata);
d8f823
 		vport->ingress.offloads.modify_metadata_rule = NULL;
d8f823
-		goto out;
d8f823
 	}
d8f823
-
d8f823
-out:
d8f823
-	if (err)
d8f823
-		mlx5_modify_header_dealloc(esw->dev, vport->ingress.offloads.modify_metadata);
d8f823
 	return err;
d8f823
 }
d8f823
 
d8f823
@@ -1865,50 +1861,103 @@ static int esw_vport_create_ingress_acl_group(struct mlx5_eswitch *esw,
d8f823
 {
d8f823
 	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
d8f823
 	struct mlx5_flow_group *g;
d8f823
+	void *match_criteria;
d8f823
 	u32 *flow_group_in;
d8f823
+	u32 flow_index = 0;
d8f823
 	int ret = 0;
d8f823
 
d8f823
 	flow_group_in = kvzalloc(inlen, GFP_KERNEL);
d8f823
 	if (!flow_group_in)
d8f823
 		return -ENOMEM;
d8f823
 
d8f823
-	memset(flow_group_in, 0, inlen);
d8f823
-	MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 0);
d8f823
-	MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 0);
d8f823
+	if (esw_check_ingress_prio_tag_enabled(esw, vport)) {
d8f823
+		/* This group is to hold FTE to match untagged packets when prio_tag
d8f823
+		 * is enabled.
d8f823
+		 */
d8f823
+		memset(flow_group_in, 0, inlen);
d8f823
 
d8f823
-	g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
d8f823
-	if (IS_ERR(g)) {
d8f823
-		ret = PTR_ERR(g);
d8f823
-		esw_warn(esw->dev,
d8f823
-			 "Failed to create vport[%d] ingress metadata group, err(%d)\n",
d8f823
-			 vport->vport, ret);
d8f823
-		goto grp_err;
d8f823
+		match_criteria = MLX5_ADDR_OF(create_flow_group_in,
d8f823
+					      flow_group_in, match_criteria);
d8f823
+		MLX5_SET(create_flow_group_in, flow_group_in,
d8f823
+			 match_criteria_enable, MLX5_MATCH_OUTER_HEADERS);
d8f823
+		MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.cvlan_tag);
d8f823
+		MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
d8f823
+		MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);
d8f823
+
d8f823
+		g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
d8f823
+		if (IS_ERR(g)) {
d8f823
+			ret = PTR_ERR(g);
d8f823
+			esw_warn(esw->dev, "vport[%d] ingress create untagged flow group, err(%d)\n",
d8f823
+				 vport->vport, ret);
d8f823
+			goto prio_tag_err;
d8f823
+		}
d8f823
+		vport->ingress.offloads.metadata_prio_tag_grp = g;
d8f823
+		flow_index++;
d8f823
+	}
d8f823
+
d8f823
+	if (mlx5_eswitch_vport_match_metadata_enabled(esw)) {
d8f823
+		/* This group holds an FTE with no matches for add metadata for
d8f823
+		 * tagged packets, if prio-tag is enabled (as a fallthrough),
d8f823
+		 * or all traffic in case prio-tag is disabled.
d8f823
+		 */
d8f823
+		memset(flow_group_in, 0, inlen);
d8f823
+		MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, flow_index);
d8f823
+		MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, flow_index);
d8f823
+
d8f823
+		g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in);
d8f823
+		if (IS_ERR(g)) {
d8f823
+			ret = PTR_ERR(g);
d8f823
+			esw_warn(esw->dev, "vport[%d] ingress create drop flow group, err(%d)\n",
d8f823
+				 vport->vport, ret);
d8f823
+			goto metadata_err;
d8f823
+		}
d8f823
+		vport->ingress.offloads.metadata_allmatch_grp = g;
d8f823
+	}
d8f823
+
d8f823
+	kvfree(flow_group_in);
d8f823
+	return 0;
d8f823
+
d8f823
+metadata_err:
d8f823
+	if (!IS_ERR_OR_NULL(vport->ingress.offloads.metadata_prio_tag_grp)) {
d8f823
+		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_prio_tag_grp);
d8f823
+		vport->ingress.offloads.metadata_prio_tag_grp = NULL;
d8f823
 	}
d8f823
-	vport->ingress.offloads.metadata_grp = g;
d8f823
-grp_err:
d8f823
+prio_tag_err:
d8f823
 	kvfree(flow_group_in);
d8f823
 	return ret;
d8f823
 }
d8f823
 
d8f823
 static void esw_vport_destroy_ingress_acl_group(struct mlx5_vport *vport)
d8f823
 {
d8f823
-	if (vport->ingress.offloads.metadata_grp) {
d8f823
-		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_grp);
d8f823
-		vport->ingress.offloads.metadata_grp = NULL;
d8f823
+	if (vport->ingress.offloads.metadata_allmatch_grp) {
d8f823
+		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_allmatch_grp);
d8f823
+		vport->ingress.offloads.metadata_allmatch_grp = NULL;
d8f823
+	}
d8f823
+
d8f823
+	if (vport->ingress.offloads.metadata_prio_tag_grp) {
d8f823
+		mlx5_destroy_flow_group(vport->ingress.offloads.metadata_prio_tag_grp);
d8f823
+		vport->ingress.offloads.metadata_prio_tag_grp = NULL;
d8f823
 	}
d8f823
 }
d8f823
 
d8f823
 static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
d8f823
 				    struct mlx5_vport *vport)
d8f823
 {
d8f823
+	int num_ftes = 0;
d8f823
 	int err;
d8f823
 
d8f823
 	if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
d8f823
-	    !MLX5_CAP_GEN(esw->dev, prio_tag_required))
d8f823
+	    !esw_check_ingress_prio_tag_enabled(esw, vport))
d8f823
 		return 0;
d8f823
 
d8f823
 	esw_vport_cleanup_ingress_rules(esw, vport);
d8f823
-	err = esw_vport_create_ingress_acl_table(esw, vport, 1);
d8f823
+
d8f823
+	if (mlx5_eswitch_vport_match_metadata_enabled(esw))
d8f823
+		num_ftes++;
d8f823
+	if (esw_check_ingress_prio_tag_enabled(esw, vport))
d8f823
+		num_ftes++;
d8f823
+
d8f823
+	err = esw_vport_create_ingress_acl_table(esw, vport, num_ftes);
d8f823
 	if (err) {
d8f823
 		esw_warn(esw->dev,
d8f823
 			 "failed to enable ingress acl (%d) on vport[%d]\n",
d8f823
@@ -1929,8 +1978,7 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
d8f823
 			goto metadata_err;
d8f823
 	}
d8f823
 
d8f823
-	if (MLX5_CAP_GEN(esw->dev, prio_tag_required) &&
d8f823
-	    mlx5_eswitch_is_vf_vport(esw, vport->vport)) {
d8f823
+	if (esw_check_ingress_prio_tag_enabled(esw, vport)) {
d8f823
 		err = esw_vport_ingress_prio_tag_config(esw, vport);
d8f823
 		if (err)
d8f823
 			goto prio_tag_err;
d8f823
@@ -1940,7 +1988,6 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw,
d8f823
 prio_tag_err:
d8f823
 	esw_vport_del_ingress_acl_modify_metadata(esw, vport);
d8f823
 metadata_err:
d8f823
-	esw_vport_cleanup_ingress_rules(esw, vport);
d8f823
 	esw_vport_destroy_ingress_acl_group(vport);
d8f823
 group_err:
d8f823
 	esw_vport_destroy_ingress_acl_table(vport);
d8f823
@@ -2023,8 +2070,9 @@ esw_vport_create_offloads_acl_tables(struct mlx5_eswitch *esw,
d8f823
 	if (mlx5_eswitch_is_vf_vport(esw, vport->vport)) {
d8f823
 		err = esw_vport_egress_config(esw, vport);
d8f823
 		if (err) {
d8f823
-			esw_vport_del_ingress_acl_modify_metadata(esw, vport);
d8f823
 			esw_vport_cleanup_ingress_rules(esw, vport);
d8f823
+			esw_vport_del_ingress_acl_modify_metadata(esw, vport);
d8f823
+			esw_vport_destroy_ingress_acl_group(vport);
d8f823
 			esw_vport_destroy_ingress_acl_table(vport);
d8f823
 		}
d8f823
 	}
d8f823
@@ -2036,8 +2084,8 @@ esw_vport_destroy_offloads_acl_tables(struct mlx5_eswitch *esw,
d8f823
 				      struct mlx5_vport *vport)
d8f823
 {
d8f823
 	esw_vport_disable_egress_acl(esw, vport);
d8f823
-	esw_vport_del_ingress_acl_modify_metadata(esw, vport);
d8f823
 	esw_vport_cleanup_ingress_rules(esw, vport);
d8f823
+	esw_vport_del_ingress_acl_modify_metadata(esw, vport);
d8f823
 	esw_vport_destroy_ingress_acl_group(vport);
d8f823
 	esw_vport_destroy_ingress_acl_table(vport);
d8f823
 }
d8f823
-- 
d8f823
2.13.6
d8f823