From: Ido Schimmel <ido...@nvidia.com>

In case a router interface (RIF) is configured for a LAG, make sure its
configuration is applied on the new LAG member.

Signed-off-by: Ido Schimmel <ido...@nvidia.com>
Reviewed-by: Jiri Pirko <j...@nvidia.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum.c    | 17 ++++++++--
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  4 +++
 .../ethernet/mellanox/mlxsw/spectrum_router.c | 31 ++++++++++++++++---
 3 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 385eb3c3b362..65e8407f4646 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3595,7 +3595,8 @@ static int mlxsw_sp_port_lag_index_get(struct mlxsw_sp 
*mlxsw_sp,
 }
 
 static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port *mlxsw_sp_port,
-                                 struct net_device *lag_dev)
+                                 struct net_device *lag_dev,
+                                 struct netlink_ext_ack *extack)
 {
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
        struct mlxsw_sp_upper *lag;
@@ -3631,8 +3632,20 @@ static int mlxsw_sp_port_lag_join(struct mlxsw_sp_port 
*mlxsw_sp_port,
        if (mlxsw_sp_port->default_vlan->fid)
                mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port->default_vlan);
 
+       /* Join a router interface configured on the LAG, if exists */
+       err = mlxsw_sp_port_vlan_router_join(mlxsw_sp_port->default_vlan,
+                                            lag_dev, extack);
+       if (err)
+               goto err_router_join;
+
        return 0;
 
+err_router_join:
+       lag->ref_count--;
+       mlxsw_sp_port->lagged = 0;
+       mlxsw_core_lag_mapping_clear(mlxsw_sp->core, lag_id,
+                                    mlxsw_sp_port->local_port);
+       mlxsw_sp_lag_col_port_remove(mlxsw_sp_port, lag_id);
 err_col_port_add:
        if (!lag->ref_count)
                mlxsw_sp_lag_destroy(mlxsw_sp, lag_id);
@@ -3997,7 +4010,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct 
net_device *lower_dev,
                } else if (netif_is_lag_master(upper_dev)) {
                        if (info->linking) {
                                err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
-                                                            upper_dev);
+                                                            upper_dev, extack);
                        } else {
                                
mlxsw_sp_port_lag_col_dist_disable(mlxsw_sp_port);
                                mlxsw_sp_port_lag_leave(mlxsw_sp_port,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index ce26cc41831f..6092243a69cb 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -656,6 +656,10 @@ mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
                                 struct net_device *l3_dev,
                                 unsigned long event,
                                 struct netdev_notifier_info *info);
+int
+mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
+                              struct net_device *l3_dev,
+                              struct netlink_ext_ack *extack);
 void
 mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan);
 void mlxsw_sp_rif_destroy_by_dev(struct mlxsw_sp *mlxsw_sp,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index 85223647fdb6..20b141f02145 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -7697,9 +7697,9 @@ static void mlxsw_sp_rif_subport_put(struct mlxsw_sp_rif 
*rif)
 }
 
 static int
-mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
-                              struct net_device *l3_dev,
-                              struct netlink_ext_ack *extack)
+__mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
+                                struct net_device *l3_dev,
+                                struct netlink_ext_ack *extack)
 {
        struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
@@ -7764,6 +7764,27 @@ __mlxsw_sp_port_vlan_router_leave(struct 
mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
        mlxsw_sp_rif_subport_put(rif);
 }
 
+int
+mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
+                              struct net_device *l3_dev,
+                              struct netlink_ext_ack *extack)
+{
+       struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port_vlan->mlxsw_sp_port->mlxsw_sp;
+       struct mlxsw_sp_rif *rif;
+       int err = 0;
+
+       mutex_lock(&mlxsw_sp->router->lock);
+       rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
+       if (!rif)
+               goto out;
+
+       err = __mlxsw_sp_port_vlan_router_join(mlxsw_sp_port_vlan, l3_dev,
+                                              extack);
+out:
+       mutex_unlock(&mlxsw_sp->router->lock);
+       return err;
+}
+
 void
 mlxsw_sp_port_vlan_router_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
 {
@@ -7788,8 +7809,8 @@ static int mlxsw_sp_inetaddr_port_vlan_event(struct 
net_device *l3_dev,
 
        switch (event) {
        case NETDEV_UP:
-               return mlxsw_sp_port_vlan_router_join(mlxsw_sp_port_vlan,
-                                                     l3_dev, extack);
+               return __mlxsw_sp_port_vlan_router_join(mlxsw_sp_port_vlan,
+                                                       l3_dev, extack);
        case NETDEV_DOWN:
                __mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
                break;
-- 
2.28.0

Reply via email to