Skip to content

Commit 4560cf4

Browse files
pmachatadavem330
authored andcommitted
mlxsw: spectrum_router: Replay IP NETDEV_UP on device deslavement
When a netdevice is removed from a bridge or a LAG, and it has an IP address, it should join the router and gain a RIF. Do that by replaying address addition event on the netdevice. When handling deslavement of LAG or its upper from a bridge device, the replay should be done after all the lowers of the LAG have left the bridge. Thus these scenarios are handled by passing replay_deslavement of false, and by invoking, after the lowers have been processed, a new helper, mlxsw_sp_netdevice_post_lag_event(), which does the per-LAG / -upper handling, and in particular invokes the replay. Signed-off-by: Petr Machata <petrm@nvidia.com> Reviewed-by: Danielle Ratson <danieller@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 31618b2 commit 4560cf4

3 files changed

Lines changed: 65 additions & 8 deletions

File tree

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4838,15 +4838,20 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
48384838
case NETDEV_CHANGEUPPER:
48394839
upper_dev = info->upper_dev;
48404840
if (netif_is_bridge_master(upper_dev)) {
4841-
if (info->linking)
4841+
if (info->linking) {
48424842
err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
48434843
lower_dev,
48444844
upper_dev,
48454845
extack);
4846-
else
4846+
} else {
48474847
mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
48484848
lower_dev,
48494849
upper_dev);
4850+
if (!replay_deslavement)
4851+
break;
4852+
mlxsw_sp_netdevice_deslavement_replay(mlxsw_sp,
4853+
lower_dev);
4854+
}
48504855
} else if (netif_is_lag_master(upper_dev)) {
48514856
if (info->linking) {
48524857
err = mlxsw_sp_port_lag_join(mlxsw_sp_port,
@@ -4855,6 +4860,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
48554860
mlxsw_sp_port_lag_col_dist_disable(mlxsw_sp_port);
48564861
mlxsw_sp_port_lag_leave(mlxsw_sp_port,
48574862
upper_dev);
4863+
mlxsw_sp_netdevice_deslavement_replay(mlxsw_sp,
4864+
dev);
48584865
}
48594866
} else if (netif_is_ovs_master(upper_dev)) {
48604867
if (info->linking)
@@ -4924,6 +4931,30 @@ static int mlxsw_sp_netdevice_port_event(struct net_device *lower_dev,
49244931
return 0;
49254932
}
49264933

4934+
/* Called for LAG or its upper VLAN after the per-LAG-lower processing was done,
4935+
* to do any per-LAG / per-LAG-upper processing.
4936+
*/
4937+
static int mlxsw_sp_netdevice_post_lag_event(struct net_device *dev,
4938+
unsigned long event,
4939+
void *ptr)
4940+
{
4941+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(dev);
4942+
struct netdev_notifier_changeupper_info *info = ptr;
4943+
4944+
if (!mlxsw_sp)
4945+
return 0;
4946+
4947+
switch (event) {
4948+
case NETDEV_CHANGEUPPER:
4949+
if (info->linking)
4950+
break;
4951+
if (netif_is_bridge_master(info->upper_dev))
4952+
mlxsw_sp_netdevice_deslavement_replay(mlxsw_sp, dev);
4953+
break;
4954+
}
4955+
return 0;
4956+
}
4957+
49274958
static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
49284959
unsigned long event, void *ptr)
49294960
{
@@ -4940,7 +4971,7 @@ static int mlxsw_sp_netdevice_lag_event(struct net_device *lag_dev,
49404971
}
49414972
}
49424973

4943-
return 0;
4974+
return mlxsw_sp_netdevice_post_lag_event(lag_dev, event, ptr);
49444975
}
49454976

49464977
static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
@@ -4984,15 +5015,20 @@ static int mlxsw_sp_netdevice_port_vlan_event(struct net_device *vlan_dev,
49845015
case NETDEV_CHANGEUPPER:
49855016
upper_dev = info->upper_dev;
49865017
if (netif_is_bridge_master(upper_dev)) {
4987-
if (info->linking)
5018+
if (info->linking) {
49885019
err = mlxsw_sp_port_bridge_join(mlxsw_sp_port,
49895020
vlan_dev,
49905021
upper_dev,
49915022
extack);
4992-
else
5023+
} else {
49935024
mlxsw_sp_port_bridge_leave(mlxsw_sp_port,
49945025
vlan_dev,
49955026
upper_dev);
5027+
if (!replay_deslavement)
5028+
break;
5029+
mlxsw_sp_netdevice_deslavement_replay(mlxsw_sp,
5030+
vlan_dev);
5031+
}
49965032
} else if (netif_is_macvlan(upper_dev)) {
49975033
if (!info->linking)
49985034
mlxsw_sp_rif_macvlan_del(mlxsw_sp, upper_dev);
@@ -5022,7 +5058,7 @@ static int mlxsw_sp_netdevice_lag_port_vlan_event(struct net_device *vlan_dev,
50225058
}
50235059
}
50245060

5025-
return 0;
5061+
return mlxsw_sp_netdevice_post_lag_event(vlan_dev, event, ptr);
50265062
}
50275063

50285064
static int mlxsw_sp_netdevice_bridge_vlan_event(struct mlxsw_sp *mlxsw_sp,

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9785,12 +9785,14 @@ struct mlxsw_sp_router_replay_inetaddr_up {
97859785
struct mlxsw_sp *mlxsw_sp;
97869786
struct netlink_ext_ack *extack;
97879787
unsigned int done;
9788+
bool deslavement;
97889789
};
97899790

97909791
static int mlxsw_sp_router_replay_inetaddr_up(struct net_device *dev,
97919792
struct netdev_nested_priv *priv)
97929793
{
97939794
struct mlxsw_sp_router_replay_inetaddr_up *ctx = priv->data;
9795+
bool nomaster = ctx->deslavement;
97949796
struct mlxsw_sp_crif *crif;
97959797
int err;
97969798

@@ -9805,7 +9807,7 @@ static int mlxsw_sp_router_replay_inetaddr_up(struct net_device *dev,
98059807
return 0;
98069808

98079809
err = __mlxsw_sp_inetaddr_event(ctx->mlxsw_sp, dev, NETDEV_UP,
9808-
false, ctx->extack);
9810+
nomaster, ctx->extack);
98099811
if (err)
98109812
return err;
98119813

@@ -9817,6 +9819,7 @@ static int mlxsw_sp_router_unreplay_inetaddr_up(struct net_device *dev,
98179819
struct netdev_nested_priv *priv)
98189820
{
98199821
struct mlxsw_sp_router_replay_inetaddr_up *ctx = priv->data;
9822+
bool nomaster = ctx->deslavement;
98209823
struct mlxsw_sp_crif *crif;
98219824

98229825
if (!ctx->done)
@@ -9833,7 +9836,8 @@ static int mlxsw_sp_router_unreplay_inetaddr_up(struct net_device *dev,
98339836
if (!mlxsw_sp_rif_should_config(crif->rif, dev, NETDEV_UP))
98349837
return 0;
98359838

9836-
__mlxsw_sp_inetaddr_event(ctx->mlxsw_sp, dev, NETDEV_DOWN, false, NULL);
9839+
__mlxsw_sp_inetaddr_event(ctx->mlxsw_sp, dev, NETDEV_DOWN, nomaster,
9840+
NULL);
98379841

98389842
ctx->done--;
98399843
return 0;
@@ -9846,6 +9850,7 @@ int mlxsw_sp_netdevice_enslavement_replay(struct mlxsw_sp *mlxsw_sp,
98469850
struct mlxsw_sp_router_replay_inetaddr_up ctx = {
98479851
.mlxsw_sp = mlxsw_sp,
98489852
.extack = extack,
9853+
.deslavement = false,
98499854
};
98509855
struct netdev_nested_priv priv = {
98519856
.data = &ctx,
@@ -9872,6 +9877,20 @@ int mlxsw_sp_netdevice_enslavement_replay(struct mlxsw_sp *mlxsw_sp,
98729877
return err;
98739878
}
98749879

9880+
void mlxsw_sp_netdevice_deslavement_replay(struct mlxsw_sp *mlxsw_sp,
9881+
struct net_device *dev)
9882+
{
9883+
struct mlxsw_sp_router_replay_inetaddr_up ctx = {
9884+
.mlxsw_sp = mlxsw_sp,
9885+
.deslavement = true,
9886+
};
9887+
struct netdev_nested_priv priv = {
9888+
.data = &ctx,
9889+
};
9890+
9891+
mlxsw_sp_router_replay_inetaddr_up(dev, &priv);
9892+
}
9893+
98759894
static int
98769895
mlxsw_sp_port_vid_router_join_existing(struct mlxsw_sp_port *mlxsw_sp_port,
98779896
u16 vid, struct net_device *dev,

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,7 @@ void mlxsw_sp_router_port_leave_lag(struct mlxsw_sp_port *mlxsw_sp_port,
183183
int mlxsw_sp_netdevice_enslavement_replay(struct mlxsw_sp *mlxsw_sp,
184184
struct net_device *upper_dev,
185185
struct netlink_ext_ack *extack);
186+
void mlxsw_sp_netdevice_deslavement_replay(struct mlxsw_sp *mlxsw_sp,
187+
struct net_device *dev);
186188

187189
#endif /* _MLXSW_ROUTER_H_*/

0 commit comments

Comments
 (0)