aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2015-12-15 16:03:47 +0100
committerDavid S. Miller <davem@davemloft.net>2015-12-15 11:58:24 -0500
commit272c447017df1bbd68e46efad8178c3e449b03ed (patch)
tree3acfc20a34a0fd5e4d0c021c5c8f5f4a2a090680
parentmlxsw: spectrum: Enable FDB records for VLAN devices on top of LAG (diff)
downloadlinux-dev-272c447017df1bbd68e46efad8178c3e449b03ed.tar.xz
linux-dev-272c447017df1bbd68e46efad8178c3e449b03ed.zip
mlxsw: spectrum: Add support for VLAN devices on top of LAG
When creating a VLAN device on top of LAG, we are basically creating a vPort on top of each of the port netdevs member in the LAG. Therefore, these vPorts should inherit both the LAG status and LAG ID from the underlying port netdevs. In addition, when the VLAN device joins or leaves a bridge each of the underlying vPorts should know about it and act accordingly. This is achieved by propagating the VLAN event down to the lower devices. 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>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index e5f888f4e091..c588c65e91f5 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -626,6 +626,8 @@ mlxsw_sp_port_vport_create(struct mlxsw_sp_port *mlxsw_sp_port,
mlxsw_sp_vport->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
mlxsw_sp_vport->local_port = mlxsw_sp_port->local_port;
mlxsw_sp_vport->stp_state = BR_STATE_FORWARDING;
+ mlxsw_sp_vport->lagged = mlxsw_sp_port->lagged;
+ mlxsw_sp_vport->lag_id = mlxsw_sp_port->lag_id;
mlxsw_sp_vport->vport.vfid = vfid;
mlxsw_sp_vport->vport.vid = vfid->vid;
@@ -2774,16 +2776,40 @@ static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
return NOTIFY_DONE;
}
+static int mlxsw_sp_netdevice_lag_vport_event(struct net_device *lag_dev,
+ unsigned long event, void *ptr,
+ u16 vid)
+{
+ struct net_device *dev;
+ struct list_head *iter;
+ int ret;
+
+ netdev_for_each_lower_dev(lag_dev, dev, iter) {
+ if (mlxsw_sp_port_dev_check(dev)) {
+ ret = mlxsw_sp_netdevice_vport_event(dev, event, ptr,
+ vid);
+ if (ret == NOTIFY_BAD)
+ return ret;
+ }
+ }
+
+ return NOTIFY_DONE;
+}
+
static int mlxsw_sp_netdevice_vlan_event(struct net_device *vlan_dev,
unsigned long event, void *ptr)
{
struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
u16 vid = vlan_dev_vlan_id(vlan_dev);
- if (!mlxsw_sp_port_dev_check(real_dev))
- return NOTIFY_DONE;
+ if (mlxsw_sp_port_dev_check(real_dev))
+ return mlxsw_sp_netdevice_vport_event(real_dev, event, ptr,
+ vid);
+ else if (netif_is_lag_master(real_dev))
+ return mlxsw_sp_netdevice_lag_vport_event(real_dev, event, ptr,
+ vid);
- return mlxsw_sp_netdevice_vport_event(real_dev, event, ptr, vid);
+ return NOTIFY_DONE;
}
static int mlxsw_sp_netdevice_event(struct notifier_block *unused,