mlxsw: spectrum: Sanitize bridge's upper devices
authorIdo Schimmel <idosch@mellanox.com>
Fri, 10 Mar 2017 07:53:34 +0000 (08:53 +0100)
committerDavid S. Miller <davem@davemloft.net>
Fri, 10 Mar 2017 17:36:06 +0000 (09:36 -0800)
We're going to allow bridges stacked on top of port netdevs to be
enslaved to a VRF, but for now, only VLAN uppers of the VLAN-aware
bridge are supported.

Sanitize any other bridge upper. This is consistent with the way we
sanitize port netdevs' uppers.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.c

index ae18067198dd89c1e814c0184dc9ae08496a7b15..c27c8f83f7ace3b2e1cc347c2cba5ec3733601c8 100644 (file)
@@ -4565,33 +4565,40 @@ static int mlxsw_sp_netdevice_bridge_event(struct net_device *br_dev,
        struct netdev_notifier_changeupper_info *info;
        struct net_device *upper_dev;
        struct mlxsw_sp *mlxsw_sp;
-       int err;
+       int err = 0;
 
        mlxsw_sp = mlxsw_sp_lower_get(br_dev);
        if (!mlxsw_sp)
                return 0;
-       if (br_dev != mlxsw_sp->master_bridge.dev)
-               return 0;
 
        info = ptr;
 
        switch (event) {
-       case NETDEV_CHANGEUPPER:
+       case NETDEV_PRECHANGEUPPER:
                upper_dev = info->upper_dev;
                if (!is_vlan_dev(upper_dev))
-                       break;
-               if (info->linking) {
-                       err = mlxsw_sp_master_bridge_vlan_link(mlxsw_sp,
-                                                              upper_dev);
-                       if (err)
-                               return err;
+                       return -EINVAL;
+               if (is_vlan_dev(upper_dev) &&
+                   br_dev != mlxsw_sp->master_bridge.dev)
+                       return -EINVAL;
+               break;
+       case NETDEV_CHANGEUPPER:
+               upper_dev = info->upper_dev;
+               if (is_vlan_dev(upper_dev)) {
+                       if (info->linking)
+                               err = mlxsw_sp_master_bridge_vlan_link(mlxsw_sp,
+                                                                      upper_dev);
+                       else
+                               mlxsw_sp_master_bridge_vlan_unlink(mlxsw_sp,
+                                                                  upper_dev);
                } else {
-                       mlxsw_sp_master_bridge_vlan_unlink(mlxsw_sp, upper_dev);
+                       err = -EINVAL;
+                       WARN_ON(1);
                }
                break;
        }
 
-       return 0;
+       return err;
 }
 
 static u16 mlxsw_sp_avail_vfid_get(const struct mlxsw_sp *mlxsw_sp)