net/mlx5e: Fail attempt to offload e-switch TC flows with egress upper devices
authorEli Britstein <elibr@mellanox.com>
Wed, 19 Dec 2018 07:24:58 +0000 (09:24 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Thu, 20 Dec 2018 13:06:01 +0000 (05:06 -0800)
We use the switchdev parent HW id helper to identify if the mirred device
shares the same ASIC/port with the ingress device. This can get us wrong
in the presence of upper devices such as vlan or bridge set over the HW
devices (VF or uplink representors), b/c the switchdev ID is retrieved
recursively.

To fail offload attempts in such cases, we condition the check on the
egress device to have not only the same switchdev ID but also the relevant
mlx5 netdev ops.

Fixes: 03a9d11e6eeb ('net/mlx5e: Add TC drop and mirred/redirect action parsing for SRIOV offloads')
Signed-off-by: Eli Britstein <elibr@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Acked-by: Or Gerlitz <ogerlitz@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 91c3eb85f32eb74b6fbed742f687a76c032ce02e..f414f19c1159c2ecd073782300548fe8201d84de 100644 (file)
@@ -1316,6 +1316,15 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
        .ndo_get_vf_stats        = mlx5e_get_vf_stats,
 };
 
+bool mlx5e_eswitch_rep(struct net_device *netdev)
+{
+       if (netdev->netdev_ops == &mlx5e_netdev_ops_vf_rep ||
+           netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep)
+               return true;
+
+       return false;
+}
+
 static void mlx5e_build_rep_params(struct net_device *netdev)
 {
        struct mlx5e_priv *priv = netdev_priv(netdev);
index 5645d3cef1bb8c48b2c506662b8de7135c7012b5..edd722824697f42c45a7bf57c9c6c510d202bfea 100644 (file)
@@ -176,6 +176,9 @@ void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
                                  struct mlx5e_encap_entry *e);
 
 void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv);
+
+bool mlx5e_eswitch_rep(struct net_device *netdev);
+
 #else /* CONFIG_MLX5_ESWITCH */
 static inline bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv) { return false; }
 static inline int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv) { return 0; }
index c1a9120412b8cc3a943a2fb1b315a1409062c231..9ba8ade3be472345874b6f112a34446da001355e 100644 (file)
@@ -2583,6 +2583,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, struct tcf_exts *exts,
                                    uplink_upper == out_dev)
                                        out_dev = uplink_dev;
 
+                               if (!mlx5e_eswitch_rep(out_dev))
+                                       return -EOPNOTSUPP;
+
                                out_priv = netdev_priv(out_dev);
                                rpriv = out_priv->ppriv;
                                attr->dests[attr->out_count].rep = rpriv->rep;