OSDN Git Service

net/mlx5e: Avoid encap flows deletion attempt the 1st time a neigh is resolved
authorOr Gerlitz <ogerlitz@mellanox.com>
Mon, 10 Dec 2018 15:05:59 +0000 (17:05 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Thu, 13 Dec 2018 09:24:44 +0000 (01:24 -0800)
Currently, we are deleting offloaded encap flows in case the relevant neigh
becomes unconnected while the encap is valid (a sign that it used to be
connected), or if the curr neigh mac is different from the cached mac
(a sign that the remote side changed their mac).

The 2nd check also applies when the neigh becomes connected on the 1st
time (we start with zero mac). Before the offending commit, the deleting
handler was practically no op, as no flows were offloaded. But since
that commit, we offload neigh-less encap flows to slow path.

Under mirroring scheme, we go into the delete handler, attempt to unoffload a
mirror rule which was never set (as we were offloading to slow path) and crash.

Fix that by calling the delete handler only when the encap is valid,
which covers both cases mentioned above.

Fixes: 5dbe906ff1d5 ('net/mlx5e: Use a slow path rule instead if vxlan neighbour isn't available')
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Eli Britstein <elibr@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

index 6a4d782..820fe85 100644 (file)
@@ -467,8 +467,8 @@ static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
 
        ASSERT_RTNL();
 
-       if ((!neigh_connected && (e->flags & MLX5_ENCAP_ENTRY_VALID)) ||
-           !ether_addr_equal(e->h_dest, ha))
+       if ((e->flags & MLX5_ENCAP_ENTRY_VALID) &&
+           (!neigh_connected || !ether_addr_equal(e->h_dest, ha)))
                mlx5e_tc_encap_flows_del(priv, e);
 
        if (neigh_connected && !(e->flags & MLX5_ENCAP_ENTRY_VALID)) {
index 3b732c0..9dabe9d 100644 (file)
@@ -1096,10 +1096,9 @@ void mlx5e_tc_encap_flows_del(struct mlx5e_priv *priv,
                flow->rule[0] = rule;
        }
 
-       if (e->flags & MLX5_ENCAP_ENTRY_VALID) {
-               e->flags &= ~MLX5_ENCAP_ENTRY_VALID;
-               mlx5_packet_reformat_dealloc(priv->mdev, e->encap_id);
-       }
+       /* we know that the encap is valid */
+       e->flags &= ~MLX5_ENCAP_ENTRY_VALID;
+       mlx5_packet_reformat_dealloc(priv->mdev, e->encap_id);
 }
 
 static struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow)