Commit 6d2a3ed0 authored by Or Gerlitz's avatar Or Gerlitz Committed by Saeed Mahameed

net/mlx5e: Avoid duplicated code for tc offloads add/del fdb rule

The code for adding/deleting fdb flow is repeated when
user-space does flow add/del and when we add/del from
the neigh update path - unify them to avoid the duplication.
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarPaul Blakey <paulb@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
parent 42f7ad67
...@@ -823,6 +823,43 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -823,6 +823,43 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow, struct mlx5e_tc_flow *flow,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
static struct mlx5_flow_handle *
mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
struct mlx5e_tc_flow *flow,
struct mlx5_flow_spec *spec,
struct mlx5_esw_flow_attr *attr)
{
struct mlx5_flow_handle *rule;
rule = mlx5_eswitch_add_offloaded_rule(esw, spec, attr);
if (IS_ERR(rule))
return rule;
if (attr->mirror_count) {
flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, spec, attr);
if (IS_ERR(flow->rule[1])) {
mlx5_eswitch_del_offloaded_rule(esw, rule, attr);
return flow->rule[1];
}
}
flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
return rule;
}
static void
mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
struct mlx5e_tc_flow *flow,
struct mlx5_esw_flow_attr *attr)
{
flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
if (attr->mirror_count)
mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr);
mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
}
static int static int
mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
struct mlx5e_tc_flow_parse_attr *parse_attr, struct mlx5e_tc_flow_parse_attr *parse_attr,
...@@ -881,25 +918,15 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, ...@@ -881,25 +918,15 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
* (2) there's an encap action and we're on -EAGAIN (no valid neigh) * (2) there's an encap action and we're on -EAGAIN (no valid neigh)
*/ */
if (encap_err != -EAGAIN) { if (encap_err != -EAGAIN) {
flow->rule[0] = mlx5_eswitch_add_offloaded_rule(esw, &parse_attr->spec, attr); flow->rule[0] = mlx5e_tc_offload_fdb_rules(esw, flow, &parse_attr->spec, attr);
if (IS_ERR(flow->rule[0])) { if (IS_ERR(flow->rule[0])) {
err = PTR_ERR(flow->rule[0]); err = PTR_ERR(flow->rule[0]);
goto err_add_rule; goto err_add_rule;
} }
if (attr->mirror_count) {
flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, &parse_attr->spec, attr);
if (IS_ERR(flow->rule[1])) {
err = PTR_ERR(flow->rule[1]);
goto err_fwd_rule;
}
}
} }
return encap_err; return encap_err;
err_fwd_rule:
mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
err_add_rule: err_add_rule:
mlx5_fc_destroy(esw->dev, counter); mlx5_fc_destroy(esw->dev, counter);
err_create_counter: err_create_counter:
...@@ -920,12 +947,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, ...@@ -920,12 +947,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5_esw_flow_attr *attr = flow->esw_attr; struct mlx5_esw_flow_attr *attr = flow->esw_attr;
if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) { if (flow->flags & MLX5E_TC_FLOW_OFFLOADED)
flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED; mlx5e_tc_unoffload_fdb_rules(esw, flow, flow->esw_attr);
if (attr->mirror_count)
mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr);
mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
}
mlx5_eswitch_del_vlan_action(esw, attr); mlx5_eswitch_del_vlan_action(esw, attr);
...@@ -946,6 +969,8 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, ...@@ -946,6 +969,8 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
{ {
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
struct mlx5_esw_flow_attr *esw_attr; struct mlx5_esw_flow_attr *esw_attr;
struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec;
struct mlx5e_tc_flow *flow; struct mlx5e_tc_flow *flow;
int err; int err;
...@@ -964,26 +989,16 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv, ...@@ -964,26 +989,16 @@ void mlx5e_tc_encap_flows_add(struct mlx5e_priv *priv,
list_for_each_entry(flow, &e->flows, encap) { list_for_each_entry(flow, &e->flows, encap) {
esw_attr = flow->esw_attr; esw_attr = flow->esw_attr;
esw_attr->encap_id = e->encap_id; esw_attr->encap_id = e->encap_id;
flow->rule[0] = mlx5_eswitch_add_offloaded_rule(esw, &esw_attr->parse_attr->spec, esw_attr); spec = &esw_attr->parse_attr->spec;
if (IS_ERR(flow->rule[0])) {
err = PTR_ERR(flow->rule[0]); rule = mlx5e_tc_offload_fdb_rules(esw, flow, spec, esw_attr);
if (IS_ERR(rule)) {
err = PTR_ERR(rule);
mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n", mlx5_core_warn(priv->mdev, "Failed to update cached encapsulation flow, %d\n",
err); err);
continue; continue;
} }
flow->rule[0] = rule;
if (esw_attr->mirror_count) {
flow->rule[1] = mlx5_eswitch_add_fwd_rule(esw, &esw_attr->parse_attr->spec, esw_attr);
if (IS_ERR(flow->rule[1])) {
mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], esw_attr);
err = PTR_ERR(flow->rule[1]);
mlx5_core_warn(priv->mdev, "Failed to update cached mirror flow, %d\n",
err);
continue;
}
}
flow->flags |= MLX5E_TC_FLOW_OFFLOADED;
} }
} }
...@@ -994,14 +1009,8 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv, ...@@ -994,14 +1009,8 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow; struct mlx5e_tc_flow *flow;
list_for_each_entry(flow, &e->flows, encap) { list_for_each_entry(flow, &e->flows, encap) {
if (flow->flags & MLX5E_TC_FLOW_OFFLOADED) { if (flow->flags & MLX5E_TC_FLOW_OFFLOADED)
struct mlx5_esw_flow_attr *attr = flow->esw_attr; mlx5e_tc_unoffload_fdb_rules(esw, flow, flow->esw_attr);
flow->flags &= ~MLX5E_TC_FLOW_OFFLOADED;
if (attr->mirror_count)
mlx5_eswitch_del_fwd_rule(esw, flow->rule[1], attr);
mlx5_eswitch_del_offloaded_rule(esw, flow->rule[0], attr);
}
} }
if (e->flags & MLX5_ENCAP_ENTRY_VALID) { if (e->flags & MLX5_ENCAP_ENTRY_VALID) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment