net/mlx5e: Fix allowed tc redirect merged eswitch offload cases
authorMaor Dickman <maord@mellanox.com>
Thu, 23 Apr 2020 12:16:17 +0000 (15:16 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Sat, 23 May 2020 00:28:40 +0000 (17:28 -0700)
After changing the parent_id to be the same for both NICs of same
The cited commit wrongly allow offload of tc redirect flows from
VF to uplink and vice versa when devcies are on different eswitch,
these cases aren't supported by HW.

Disallow the above offloads when devcies are on different eswitch
and VF LAG is not configured.

Fixes: f6dc1264f1c0 ("net/mlx5e: Disallow tc redirect offload cases we don't support")
Signed-off-by: Maor Dickman <maord@mellanox.com>
Reviewed-by: Roi Dayan <roid@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_rep.h
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

index f372e94948fd64f0879b672ab5bfcba51b25ee98..cdecf4280e868d1be72f480260652441644f2dbf 100644 (file)
@@ -1484,13 +1484,9 @@ bool mlx5e_eswitch_uplink_rep(struct net_device *netdev)
        return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep;
 }
 
-bool mlx5e_eswitch_rep(struct net_device *netdev)
+bool mlx5e_eswitch_vf_rep(struct net_device *netdev)
 {
-       if (netdev->netdev_ops == &mlx5e_netdev_ops_rep ||
-           netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep)
-               return true;
-
-       return false;
+       return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
 }
 
 static void mlx5e_build_rep_params(struct net_device *netdev)
index 6a233790042002166088aaf73accf459ee5adaae..612b5cf0673d1bb7939998e2e61b6694482faca6 100644 (file)
@@ -210,8 +210,13 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
 
 void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv);
 
-bool mlx5e_eswitch_rep(struct net_device *netdev);
+bool mlx5e_eswitch_vf_rep(struct net_device *netdev);
 bool mlx5e_eswitch_uplink_rep(struct net_device *netdev);
+static inline bool mlx5e_eswitch_rep(struct net_device *netdev)
+{
+       return mlx5e_eswitch_vf_rep(netdev) ||
+              mlx5e_eswitch_uplink_rep(netdev);
+}
 
 #else /* CONFIG_MLX5_ESWITCH */
 static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; }
index a574c588269a0f0110eb05c745351c9a8c0c761e..5bcf95fcdd59f006b5f7b56079ffabaf1b4ab654 100644 (file)
@@ -3073,6 +3073,11 @@ static bool actions_match_supported(struct mlx5e_priv *priv,
        return true;
 }
 
+static bool same_port_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv)
+{
+       return priv->mdev == peer_priv->mdev;
+}
+
 static bool same_hw_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv)
 {
        struct mlx5_core_dev *fmdev, *pmdev;
@@ -3291,7 +3296,7 @@ static inline int hash_encap_info(struct encap_key *key)
 }
 
 
-static bool is_merged_eswitch_dev(struct mlx5e_priv *priv,
+static bool is_merged_eswitch_vfs(struct mlx5e_priv *priv,
                                  struct net_device *peer_netdev)
 {
        struct mlx5e_priv *peer_priv;
@@ -3299,13 +3304,11 @@ static bool is_merged_eswitch_dev(struct mlx5e_priv *priv,
        peer_priv = netdev_priv(peer_netdev);
 
        return (MLX5_CAP_ESW(priv->mdev, merged_eswitch) &&
-               mlx5e_eswitch_rep(priv->netdev) &&
-               mlx5e_eswitch_rep(peer_netdev) &&
+               mlx5e_eswitch_vf_rep(priv->netdev) &&
+               mlx5e_eswitch_vf_rep(peer_netdev) &&
                same_hw_devs(priv, peer_priv));
 }
 
-
-
 bool mlx5e_encap_take(struct mlx5e_encap_entry *e)
 {
        return refcount_inc_not_zero(&e->refcnt);
@@ -3575,14 +3578,37 @@ static int add_vlan_pop_action(struct mlx5e_priv *priv,
        return err;
 }
 
+static bool same_hw_reps(struct mlx5e_priv *priv,
+                        struct net_device *peer_netdev)
+{
+       struct mlx5e_priv *peer_priv;
+
+       peer_priv = netdev_priv(peer_netdev);
+
+       return mlx5e_eswitch_rep(priv->netdev) &&
+              mlx5e_eswitch_rep(peer_netdev) &&
+              same_hw_devs(priv, peer_priv);
+}
+
+static bool is_lag_dev(struct mlx5e_priv *priv,
+                      struct net_device *peer_netdev)
+{
+       return ((mlx5_lag_is_sriov(priv->mdev) ||
+                mlx5_lag_is_multipath(priv->mdev)) &&
+                same_hw_reps(priv, peer_netdev));
+}
+
 bool mlx5e_is_valid_eswitch_fwd_dev(struct mlx5e_priv *priv,
                                    struct net_device *out_dev)
 {
-       if (is_merged_eswitch_dev(priv, out_dev))
+       if (is_merged_eswitch_vfs(priv, out_dev))
+               return true;
+
+       if (is_lag_dev(priv, out_dev))
                return true;
 
        return mlx5e_eswitch_rep(out_dev) &&
-              same_hw_devs(priv, netdev_priv(out_dev));
+              same_port_devs(priv, netdev_priv(out_dev));
 }
 
 static bool is_duplicated_output_device(struct net_device *dev,