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