Commit 65ba8fb7 authored by Or Gerlitz's avatar Or Gerlitz Committed by David S. Miller

net/mlx5e: Avoid wrong identification of rules on deletion

When deleting offloaded TC flows, we must correctly identify E-switch
rules. The current check could get us wrong w.r.t to rules set on the
PF. Since it's possible to set NIC rules on the PF, switch to SRIOV
offloads mode and then attempt to delete a NIC rule.

To solve that, we add a flags field to offloaded rules, set it on
creation time and use that over the code where currently needed.

Fixes: 8b32580d ('net/mlx5e: Add TC vlan action for SRIOV offloads')
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Reviewed-by: default avatarRoi Dayan <roid@mellanox.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 33e21c59
...@@ -48,9 +48,14 @@ ...@@ -48,9 +48,14 @@
#include "eswitch.h" #include "eswitch.h"
#include "vxlan.h" #include "vxlan.h"
enum {
MLX5E_TC_FLOW_ESWITCH = BIT(0),
};
struct mlx5e_tc_flow { struct mlx5e_tc_flow {
struct rhash_head node; struct rhash_head node;
u64 cookie; u64 cookie;
u8 flags;
struct mlx5_flow_handle *rule; struct mlx5_flow_handle *rule;
struct list_head encap; /* flows sharing the same encap */ struct list_head encap; /* flows sharing the same encap */
struct mlx5_esw_flow_attr *attr; struct mlx5_esw_flow_attr *attr;
...@@ -177,7 +182,7 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv, ...@@ -177,7 +182,7 @@ static void mlx5e_tc_del_flow(struct mlx5e_priv *priv,
mlx5_fc_destroy(priv->mdev, counter); mlx5_fc_destroy(priv->mdev, counter);
} }
if (esw && esw->mode == SRIOV_OFFLOADS) { if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
mlx5_eswitch_del_vlan_action(esw, flow->attr); mlx5_eswitch_del_vlan_action(esw, flow->attr);
if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP) if (flow->attr->action & MLX5_FLOW_CONTEXT_ACTION_ENCAP)
mlx5e_detach_encap(priv, flow); mlx5e_detach_encap(priv, flow);
...@@ -598,6 +603,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, ...@@ -598,6 +603,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
} }
static int parse_cls_flower(struct mlx5e_priv *priv, static int parse_cls_flower(struct mlx5e_priv *priv,
struct mlx5e_tc_flow *flow,
struct mlx5_flow_spec *spec, struct mlx5_flow_spec *spec,
struct tc_cls_flower_offload *f) struct tc_cls_flower_offload *f)
{ {
...@@ -609,7 +615,7 @@ static int parse_cls_flower(struct mlx5e_priv *priv, ...@@ -609,7 +615,7 @@ static int parse_cls_flower(struct mlx5e_priv *priv,
err = __parse_cls_flower(priv, spec, f, &min_inline); err = __parse_cls_flower(priv, spec, f, &min_inline);
if (!err && esw->mode == SRIOV_OFFLOADS && if (!err && (flow->flags & MLX5E_TC_FLOW_ESWITCH) &&
rep->vport != FDB_UPLINK_VPORT) { rep->vport != FDB_UPLINK_VPORT) {
if (min_inline > esw->offloads.inline_mode) { if (min_inline > esw->offloads.inline_mode) {
netdev_warn(priv->netdev, netdev_warn(priv->netdev,
...@@ -1132,23 +1138,19 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol, ...@@ -1132,23 +1138,19 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
struct tc_cls_flower_offload *f) struct tc_cls_flower_offload *f)
{ {
struct mlx5e_tc_table *tc = &priv->fs.tc; struct mlx5e_tc_table *tc = &priv->fs.tc;
int err = 0; int err, attr_size = 0;
bool fdb_flow = false;
u32 flow_tag, action; u32 flow_tag, action;
struct mlx5e_tc_flow *flow; struct mlx5e_tc_flow *flow;
struct mlx5_flow_spec *spec; struct mlx5_flow_spec *spec;
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
u8 flow_flags = 0;
if (esw && esw->mode == SRIOV_OFFLOADS) if (esw && esw->mode == SRIOV_OFFLOADS) {
fdb_flow = true; flow_flags = MLX5E_TC_FLOW_ESWITCH;
attr_size = sizeof(struct mlx5_esw_flow_attr);
if (fdb_flow) }
flow = kzalloc(sizeof(*flow) +
sizeof(struct mlx5_esw_flow_attr),
GFP_KERNEL);
else
flow = kzalloc(sizeof(*flow), GFP_KERNEL);
flow = kzalloc(sizeof(*flow) + attr_size, GFP_KERNEL);
spec = mlx5_vzalloc(sizeof(*spec)); spec = mlx5_vzalloc(sizeof(*spec));
if (!spec || !flow) { if (!spec || !flow) {
err = -ENOMEM; err = -ENOMEM;
...@@ -1156,12 +1158,13 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol, ...@@ -1156,12 +1158,13 @@ int mlx5e_configure_flower(struct mlx5e_priv *priv, __be16 protocol,
} }
flow->cookie = f->cookie; flow->cookie = f->cookie;
flow->flags = flow_flags;
err = parse_cls_flower(priv, spec, f); err = parse_cls_flower(priv, flow, spec, f);
if (err < 0) if (err < 0)
goto err_free; goto err_free;
if (fdb_flow) { if (flow->flags & MLX5E_TC_FLOW_ESWITCH) {
flow->attr = (struct mlx5_esw_flow_attr *)(flow + 1); flow->attr = (struct mlx5_esw_flow_attr *)(flow + 1);
err = parse_tc_fdb_actions(priv, f->exts, flow); err = parse_tc_fdb_actions(priv, f->exts, flow);
if (err < 0) if (err < 0)
......
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