-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net/mlx5: E-Switch, Refactor eswitch egress acl codes
Refactor the egress acl codes so that offloads and legacy modes can configure specifically their own needs of egress acl table, groups and rules. While at it, restructure the eswitch egress acl codes into eswitch directory and different files: . Acl egress helper functions to acl_helper.c/h . Acl egress functions used in offloads mode to acl_egress_ofld.c . Acl egress functions used in legacy mode to acl_egress_lgy.c This patch does not change any functionality. Signed-off-by: Vu Pham <vuhuong@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
- Loading branch information
Vu Pham
authored and
Saeed Mahameed
committed
May 28, 2020
1 parent
dc0f3ed
commit ea651a8
Showing
10 changed files
with
462 additions
and
275 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
170 changes: 170 additions & 0 deletions
170
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_lgcy.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB | ||
/* Copyright (c) 2020 Mellanox Technologies Inc. All rights reserved. */ | ||
|
||
#include "mlx5_core.h" | ||
#include "eswitch.h" | ||
#include "helper.h" | ||
#include "lgcy.h" | ||
|
||
static void esw_acl_egress_lgcy_rules_destroy(struct mlx5_vport *vport) | ||
{ | ||
esw_acl_egress_vlan_destroy(vport); | ||
if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_rule)) { | ||
mlx5_del_flow_rules(vport->egress.legacy.drop_rule); | ||
vport->egress.legacy.drop_rule = NULL; | ||
} | ||
} | ||
|
||
static int esw_acl_egress_lgcy_groups_create(struct mlx5_eswitch *esw, | ||
struct mlx5_vport *vport) | ||
{ | ||
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); | ||
struct mlx5_core_dev *dev = esw->dev; | ||
struct mlx5_flow_group *drop_grp; | ||
u32 *flow_group_in; | ||
int err = 0; | ||
|
||
err = esw_acl_egress_vlan_grp_create(esw, vport); | ||
if (err) | ||
return err; | ||
|
||
flow_group_in = kvzalloc(inlen, GFP_KERNEL); | ||
if (!flow_group_in) { | ||
err = -ENOMEM; | ||
goto alloc_err; | ||
} | ||
|
||
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 1); | ||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1); | ||
drop_grp = mlx5_create_flow_group(vport->egress.acl, flow_group_in); | ||
if (IS_ERR(drop_grp)) { | ||
err = PTR_ERR(drop_grp); | ||
esw_warn(dev, "Failed to create E-Switch vport[%d] egress drop flow group, err(%d)\n", | ||
vport->vport, err); | ||
goto drop_grp_err; | ||
} | ||
|
||
vport->egress.legacy.drop_grp = drop_grp; | ||
kvfree(flow_group_in); | ||
return 0; | ||
|
||
drop_grp_err: | ||
kvfree(flow_group_in); | ||
alloc_err: | ||
esw_acl_egress_vlan_grp_destroy(vport); | ||
return err; | ||
} | ||
|
||
static void esw_acl_egress_lgcy_groups_destroy(struct mlx5_vport *vport) | ||
{ | ||
if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_grp)) { | ||
mlx5_destroy_flow_group(vport->egress.legacy.drop_grp); | ||
vport->egress.legacy.drop_grp = NULL; | ||
} | ||
esw_acl_egress_vlan_grp_destroy(vport); | ||
} | ||
|
||
int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, | ||
struct mlx5_vport *vport) | ||
{ | ||
struct mlx5_flow_destination drop_ctr_dst = {}; | ||
struct mlx5_flow_destination *dst = NULL; | ||
struct mlx5_fc *drop_counter = NULL; | ||
struct mlx5_flow_act flow_act = {}; | ||
/* The egress acl table contains 2 rules: | ||
* 1)Allow traffic with vlan_tag=vst_vlan_id | ||
* 2)Drop all other traffic. | ||
*/ | ||
int table_size = 2; | ||
int dest_num = 0; | ||
int err = 0; | ||
|
||
if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { | ||
drop_counter = mlx5_fc_create(esw->dev, false); | ||
if (IS_ERR(drop_counter)) | ||
esw_warn(esw->dev, | ||
"vport[%d] configure egress drop rule counter err(%ld)\n", | ||
vport->vport, PTR_ERR(drop_counter)); | ||
vport->egress.legacy.drop_counter = drop_counter; | ||
} | ||
|
||
esw_acl_egress_lgcy_rules_destroy(vport); | ||
|
||
if (!vport->info.vlan && !vport->info.qos) { | ||
esw_acl_egress_lgcy_cleanup(esw, vport); | ||
return 0; | ||
} | ||
|
||
if (!IS_ERR_OR_NULL(vport->egress.acl)) | ||
return 0; | ||
|
||
vport->egress.acl = esw_acl_table_create(esw, vport->vport, | ||
MLX5_FLOW_NAMESPACE_ESW_EGRESS, | ||
table_size); | ||
if (IS_ERR_OR_NULL(vport->egress.acl)) { | ||
err = PTR_ERR(vport->egress.acl); | ||
vport->egress.acl = NULL; | ||
goto out; | ||
} | ||
|
||
err = esw_acl_egress_lgcy_groups_create(esw, vport); | ||
if (err) | ||
goto out; | ||
|
||
esw_debug(esw->dev, | ||
"vport[%d] configure egress rules, vlan(%d) qos(%d)\n", | ||
vport->vport, vport->info.vlan, vport->info.qos); | ||
|
||
/* Allowed vlan rule */ | ||
err = esw_egress_acl_vlan_create(esw, vport, NULL, vport->info.vlan, | ||
MLX5_FLOW_CONTEXT_ACTION_ALLOW); | ||
if (err) | ||
goto out; | ||
|
||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; | ||
|
||
/* Attach egress drop flow counter */ | ||
if (!IS_ERR_OR_NULL(drop_counter)) { | ||
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; | ||
drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; | ||
drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter); | ||
dst = &drop_ctr_dst; | ||
dest_num++; | ||
} | ||
vport->egress.legacy.drop_rule = | ||
mlx5_add_flow_rules(vport->egress.acl, NULL, | ||
&flow_act, dst, dest_num); | ||
if (IS_ERR(vport->egress.legacy.drop_rule)) { | ||
err = PTR_ERR(vport->egress.legacy.drop_rule); | ||
esw_warn(esw->dev, | ||
"vport[%d] configure egress drop rule failed, err(%d)\n", | ||
vport->vport, err); | ||
vport->egress.legacy.drop_rule = NULL; | ||
goto out; | ||
} | ||
|
||
return err; | ||
|
||
out: | ||
esw_acl_egress_lgcy_cleanup(esw, vport); | ||
return err; | ||
} | ||
|
||
void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw, | ||
struct mlx5_vport *vport) | ||
{ | ||
if (IS_ERR_OR_NULL(vport->egress.acl)) | ||
goto clean_drop_counter; | ||
|
||
esw_debug(esw->dev, "Destroy vport[%d] E-Switch egress ACL\n", vport->vport); | ||
|
||
esw_acl_egress_lgcy_rules_destroy(vport); | ||
esw_acl_egress_lgcy_groups_destroy(vport); | ||
esw_acl_egress_table_destroy(vport); | ||
|
||
clean_drop_counter: | ||
if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) { | ||
mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter); | ||
vport->egress.legacy.drop_counter = NULL; | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_ofld.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB | ||
/* Copyright (c) 2020 Mellanox Technologies Inc. All rights reserved. */ | ||
|
||
#include "mlx5_core.h" | ||
#include "eswitch.h" | ||
#include "helper.h" | ||
#include "ofld.h" | ||
|
||
static int esw_acl_egress_ofld_rules_create(struct mlx5_eswitch *esw, | ||
struct mlx5_vport *vport) | ||
{ | ||
if (!MLX5_CAP_GEN(esw->dev, prio_tag_required)) | ||
return 0; | ||
|
||
/* For prio tag mode, there is only 1 FTEs: | ||
* 1) prio tag packets - pop the prio tag VLAN, allow | ||
* Unmatched traffic is allowed by default | ||
*/ | ||
esw_debug(esw->dev, | ||
"vport[%d] configure prio tag egress rules\n", vport->vport); | ||
|
||
/* prio tag vlan rule - pop it so vport receives untagged packets */ | ||
return esw_egress_acl_vlan_create(esw, vport, NULL, 0, | ||
MLX5_FLOW_CONTEXT_ACTION_VLAN_POP | | ||
MLX5_FLOW_CONTEXT_ACTION_ALLOW); | ||
} | ||
|
||
static void esw_acl_egress_ofld_rules_destroy(struct mlx5_vport *vport) | ||
{ | ||
esw_acl_egress_vlan_destroy(vport); | ||
} | ||
|
||
static int esw_acl_egress_ofld_groups_create(struct mlx5_eswitch *esw, | ||
struct mlx5_vport *vport) | ||
{ | ||
if (!MLX5_CAP_GEN(esw->dev, prio_tag_required)) | ||
return 0; | ||
|
||
return esw_acl_egress_vlan_grp_create(esw, vport); | ||
} | ||
|
||
static void esw_acl_egress_ofld_groups_destroy(struct mlx5_vport *vport) | ||
{ | ||
esw_acl_egress_vlan_grp_destroy(vport); | ||
} | ||
|
||
int esw_acl_egress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport) | ||
{ | ||
int err; | ||
|
||
if (!MLX5_CAP_GEN(esw->dev, prio_tag_required)) | ||
return 0; | ||
|
||
esw_acl_egress_ofld_rules_destroy(vport); | ||
|
||
vport->egress.acl = esw_acl_table_create(esw, vport->vport, | ||
MLX5_FLOW_NAMESPACE_ESW_EGRESS, 0); | ||
if (IS_ERR_OR_NULL(vport->egress.acl)) { | ||
err = PTR_ERR(vport->egress.acl); | ||
vport->egress.acl = NULL; | ||
return err; | ||
} | ||
|
||
err = esw_acl_egress_ofld_groups_create(esw, vport); | ||
if (err) | ||
goto group_err; | ||
|
||
esw_debug(esw->dev, "vport[%d] configure egress rules\n", vport->vport); | ||
|
||
err = esw_acl_egress_ofld_rules_create(esw, vport); | ||
if (err) | ||
goto rules_err; | ||
|
||
return 0; | ||
|
||
rules_err: | ||
esw_acl_egress_ofld_groups_destroy(vport); | ||
group_err: | ||
esw_acl_egress_table_destroy(vport); | ||
return err; | ||
} | ||
|
||
void esw_acl_egress_ofld_cleanup(struct mlx5_vport *vport) | ||
{ | ||
esw_acl_egress_ofld_rules_destroy(vport); | ||
esw_acl_egress_ofld_groups_destroy(vport); | ||
esw_acl_egress_table_destroy(vport); | ||
} |
Oops, something went wrong.