-
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 ingress acl codes
Restructure the eswitch ingress acl codes into eswitch directory and different files: . Acl ingress helper functions to acl_helper.c/h . Acl ingress functions used in offloads mode to acl_ingress_ofld.c . Acl ingress functions used in legacy mode to acl_ingress_lgy.c This patch does not change any functionality. Signed-off-by: Vu Pham <vuhuong@mellanox.com>
- Loading branch information
Vu Pham
authored and
Saeed Mahameed
committed
May 28, 2020
1 parent
ea651a8
commit 07bab95
Showing
10 changed files
with
619 additions
and
583 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
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
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
279 changes: 279 additions & 0 deletions
279
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_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,279 @@ | ||
// 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_ingress_lgcy_rules_destroy(struct mlx5_vport *vport) | ||
{ | ||
if (vport->ingress.legacy.drop_rule) { | ||
mlx5_del_flow_rules(vport->ingress.legacy.drop_rule); | ||
vport->ingress.legacy.drop_rule = NULL; | ||
} | ||
esw_acl_ingress_allow_rule_destroy(vport); | ||
} | ||
|
||
static int esw_acl_ingress_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 *g; | ||
void *match_criteria; | ||
u32 *flow_group_in; | ||
int err; | ||
|
||
flow_group_in = kvzalloc(inlen, GFP_KERNEL); | ||
if (!flow_group_in) | ||
return -ENOMEM; | ||
|
||
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_TO_ONES(fte_match_param, match_criteria, outer_headers.smac_47_16); | ||
MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.smac_15_0); | ||
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); | ||
|
||
g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in); | ||
if (IS_ERR(g)) { | ||
err = PTR_ERR(g); | ||
esw_warn(dev, "vport[%d] ingress create untagged spoofchk flow group, err(%d)\n", | ||
vport->vport, err); | ||
goto spoof_err; | ||
} | ||
vport->ingress.legacy.allow_untagged_spoofchk_grp = g; | ||
|
||
memset(flow_group_in, 0, inlen); | ||
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, 1); | ||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 1); | ||
|
||
g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in); | ||
if (IS_ERR(g)) { | ||
err = PTR_ERR(g); | ||
esw_warn(dev, "vport[%d] ingress create untagged flow group, err(%d)\n", | ||
vport->vport, err); | ||
goto untagged_err; | ||
} | ||
vport->ingress.legacy.allow_untagged_only_grp = g; | ||
|
||
memset(flow_group_in, 0, inlen); | ||
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.smac_47_16); | ||
MLX5_SET_TO_ONES(fte_match_param, match_criteria, outer_headers.smac_15_0); | ||
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 2); | ||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 2); | ||
|
||
g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in); | ||
if (IS_ERR(g)) { | ||
err = PTR_ERR(g); | ||
esw_warn(dev, "vport[%d] ingress create spoofchk flow group, err(%d)\n", | ||
vport->vport, err); | ||
goto allow_spoof_err; | ||
} | ||
vport->ingress.legacy.allow_spoofchk_only_grp = g; | ||
|
||
memset(flow_group_in, 0, inlen); | ||
MLX5_SET(create_flow_group_in, flow_group_in, start_flow_index, 3); | ||
MLX5_SET(create_flow_group_in, flow_group_in, end_flow_index, 3); | ||
|
||
g = mlx5_create_flow_group(vport->ingress.acl, flow_group_in); | ||
if (IS_ERR(g)) { | ||
err = PTR_ERR(g); | ||
esw_warn(dev, "vport[%d] ingress create drop flow group, err(%d)\n", | ||
vport->vport, err); | ||
goto drop_err; | ||
} | ||
vport->ingress.legacy.drop_grp = g; | ||
kvfree(flow_group_in); | ||
return 0; | ||
|
||
drop_err: | ||
if (!IS_ERR_OR_NULL(vport->ingress.legacy.allow_spoofchk_only_grp)) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.allow_spoofchk_only_grp); | ||
vport->ingress.legacy.allow_spoofchk_only_grp = NULL; | ||
} | ||
allow_spoof_err: | ||
if (!IS_ERR_OR_NULL(vport->ingress.legacy.allow_untagged_only_grp)) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.allow_untagged_only_grp); | ||
vport->ingress.legacy.allow_untagged_only_grp = NULL; | ||
} | ||
untagged_err: | ||
if (!IS_ERR_OR_NULL(vport->ingress.legacy.allow_untagged_spoofchk_grp)) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.allow_untagged_spoofchk_grp); | ||
vport->ingress.legacy.allow_untagged_spoofchk_grp = NULL; | ||
} | ||
spoof_err: | ||
kvfree(flow_group_in); | ||
return err; | ||
} | ||
|
||
static void esw_acl_ingress_lgcy_groups_destroy(struct mlx5_vport *vport) | ||
{ | ||
if (vport->ingress.legacy.allow_spoofchk_only_grp) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.allow_spoofchk_only_grp); | ||
vport->ingress.legacy.allow_spoofchk_only_grp = NULL; | ||
} | ||
if (vport->ingress.legacy.allow_untagged_only_grp) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.allow_untagged_only_grp); | ||
vport->ingress.legacy.allow_untagged_only_grp = NULL; | ||
} | ||
if (vport->ingress.legacy.allow_untagged_spoofchk_grp) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.allow_untagged_spoofchk_grp); | ||
vport->ingress.legacy.allow_untagged_spoofchk_grp = NULL; | ||
} | ||
if (vport->ingress.legacy.drop_grp) { | ||
mlx5_destroy_flow_group(vport->ingress.legacy.drop_grp); | ||
vport->ingress.legacy.drop_grp = NULL; | ||
} | ||
} | ||
|
||
int esw_acl_ingress_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_flow_act flow_act = {}; | ||
struct mlx5_flow_spec *spec = NULL; | ||
struct mlx5_fc *counter = NULL; | ||
/* The ingress acl table contains 4 groups | ||
* (2 active rules at the same time - | ||
* 1 allow rule from one of the first 3 groups. | ||
* 1 drop rule from the last group): | ||
* 1)Allow untagged traffic with smac=original mac. | ||
* 2)Allow untagged traffic. | ||
* 3)Allow traffic with smac=original mac. | ||
* 4)Drop all other traffic. | ||
*/ | ||
int table_size = 4; | ||
int dest_num = 0; | ||
int err = 0; | ||
u8 *smac_v; | ||
|
||
esw_acl_ingress_lgcy_rules_destroy(vport); | ||
|
||
if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { | ||
counter = mlx5_fc_create(esw->dev, false); | ||
if (IS_ERR(counter)) | ||
esw_warn(esw->dev, | ||
"vport[%d] configure ingress drop rule counter failed\n", | ||
vport->vport); | ||
vport->ingress.legacy.drop_counter = counter; | ||
} | ||
|
||
if (!vport->info.vlan && !vport->info.qos && !vport->info.spoofchk) { | ||
esw_acl_ingress_lgcy_cleanup(esw, vport); | ||
return 0; | ||
} | ||
|
||
if (!vport->ingress.acl) { | ||
vport->ingress.acl = esw_acl_table_create(esw, vport->vport, | ||
MLX5_FLOW_NAMESPACE_ESW_INGRESS, | ||
table_size); | ||
if (IS_ERR_OR_NULL(vport->ingress.acl)) { | ||
err = PTR_ERR(vport->ingress.acl); | ||
vport->ingress.acl = NULL; | ||
return err; | ||
} | ||
|
||
err = esw_acl_ingress_lgcy_groups_create(esw, vport); | ||
if (err) | ||
goto out; | ||
} | ||
|
||
esw_debug(esw->dev, | ||
"vport[%d] configure ingress rules, vlan(%d) qos(%d)\n", | ||
vport->vport, vport->info.vlan, vport->info.qos); | ||
|
||
spec = kvzalloc(sizeof(*spec), GFP_KERNEL); | ||
if (!spec) { | ||
err = -ENOMEM; | ||
goto out; | ||
} | ||
|
||
if (vport->info.vlan || vport->info.qos) | ||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, | ||
outer_headers.cvlan_tag); | ||
|
||
if (vport->info.spoofchk) { | ||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, | ||
outer_headers.smac_47_16); | ||
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, | ||
outer_headers.smac_15_0); | ||
smac_v = MLX5_ADDR_OF(fte_match_param, | ||
spec->match_value, | ||
outer_headers.smac_47_16); | ||
ether_addr_copy(smac_v, vport->info.mac); | ||
} | ||
|
||
/* Create ingress allow rule */ | ||
memset(spec, 0, sizeof(*spec)); | ||
spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; | ||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW; | ||
vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec, | ||
&flow_act, NULL, 0); | ||
if (IS_ERR(vport->ingress.allow_rule)) { | ||
err = PTR_ERR(vport->ingress.allow_rule); | ||
esw_warn(esw->dev, | ||
"vport[%d] configure ingress allow rule, err(%d)\n", | ||
vport->vport, err); | ||
vport->ingress.allow_rule = NULL; | ||
goto out; | ||
} | ||
|
||
memset(&flow_act, 0, sizeof(flow_act)); | ||
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; | ||
/* Attach drop flow counter */ | ||
if (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(counter); | ||
dst = &drop_ctr_dst; | ||
dest_num++; | ||
} | ||
vport->ingress.legacy.drop_rule = | ||
mlx5_add_flow_rules(vport->ingress.acl, NULL, | ||
&flow_act, dst, dest_num); | ||
if (IS_ERR(vport->ingress.legacy.drop_rule)) { | ||
err = PTR_ERR(vport->ingress.legacy.drop_rule); | ||
esw_warn(esw->dev, | ||
"vport[%d] configure ingress drop rule, err(%d)\n", | ||
vport->vport, err); | ||
vport->ingress.legacy.drop_rule = NULL; | ||
goto out; | ||
} | ||
kvfree(spec); | ||
return 0; | ||
|
||
out: | ||
esw_acl_ingress_lgcy_cleanup(esw, vport); | ||
kvfree(spec); | ||
return err; | ||
} | ||
|
||
void esw_acl_ingress_lgcy_cleanup(struct mlx5_eswitch *esw, | ||
struct mlx5_vport *vport) | ||
{ | ||
if (IS_ERR_OR_NULL(vport->ingress.acl)) | ||
goto clean_drop_counter; | ||
|
||
esw_debug(esw->dev, "Destroy vport[%d] E-Switch ingress ACL\n", vport->vport); | ||
|
||
esw_acl_ingress_lgcy_rules_destroy(vport); | ||
esw_acl_ingress_lgcy_groups_destroy(vport); | ||
esw_acl_ingress_table_destroy(vport); | ||
|
||
clean_drop_counter: | ||
if (!IS_ERR_OR_NULL(vport->ingress.legacy.drop_counter)) { | ||
mlx5_fc_destroy(esw->dev, vport->ingress.legacy.drop_counter); | ||
vport->ingress.legacy.drop_counter = NULL; | ||
} | ||
} |
Oops, something went wrong.