mlxsw: spectrum: Remove RIF from PVID vPort when joining / leaving LAG
authorIdo Schimmel <idosch@mellanox.com>
Sat, 2 Jul 2016 09:00:12 +0000 (11:00 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 2 Jul 2016 19:21:17 +0000 (15:21 -0400)
We are going to assign router interfaces (RIFs) to netdevs if an IPv4
address was assigned to them. If one was assigned to a port netdev, this
will translate to the PVID vPort being member in a RIF.

While it's possible for a LAG slave to have an IP address, we can't have
a vPort being member in two FIDs (assuming the LAG device will be
put in bridge / assigned an IP address).

Solve that by making the PVID vPort leave any FID it might be a member
in when joining / leaving LAG.

Note that the PVID vPort is the only vPort that can be present on the
port when it's put under LAG.

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 f276c453885f2116228d427008885ac3f905b585..30fe0d2e31a6eb33d7541db4b81c8a620e4206b9 100644 (file)
@@ -2800,11 +2800,19 @@ mlxsw_sp_port_pvid_vport_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
                                  u16 lag_id)
 {
        struct mlxsw_sp_port *mlxsw_sp_vport;
+       struct mlxsw_sp_fid *f;
 
        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, 1);
        if (WARN_ON(!mlxsw_sp_vport))
                return;
 
+       /* If vPort is assigned a RIF, then leave it since it's no
+        * longer valid.
+        */
+       f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
+       if (f)
+               f->leave(mlxsw_sp_vport);
+
        mlxsw_sp_vport->lag_id = lag_id;
        mlxsw_sp_vport->lagged = 1;
 }
@@ -2813,11 +2821,16 @@ static void
 mlxsw_sp_port_pvid_vport_lag_leave(struct mlxsw_sp_port *mlxsw_sp_port)
 {
        struct mlxsw_sp_port *mlxsw_sp_vport;
+       struct mlxsw_sp_fid *f;
 
        mlxsw_sp_vport = mlxsw_sp_port_vport_find(mlxsw_sp_port, 1);
        if (WARN_ON(!mlxsw_sp_vport))
                return;
 
+       f = mlxsw_sp_vport_fid_get(mlxsw_sp_vport);
+       if (f)
+               f->leave(mlxsw_sp_vport);
+
        mlxsw_sp_vport->lagged = 0;
 }