@@ -9781,6 +9781,97 @@ mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
97819781 return err ;
97829782}
97839783
9784+ struct mlxsw_sp_router_replay_inetaddr_up {
9785+ struct mlxsw_sp * mlxsw_sp ;
9786+ struct netlink_ext_ack * extack ;
9787+ unsigned int done ;
9788+ };
9789+
9790+ static int mlxsw_sp_router_replay_inetaddr_up (struct net_device * dev ,
9791+ struct netdev_nested_priv * priv )
9792+ {
9793+ struct mlxsw_sp_router_replay_inetaddr_up * ctx = priv -> data ;
9794+ struct mlxsw_sp_crif * crif ;
9795+ int err ;
9796+
9797+ if (mlxsw_sp_dev_addr_list_empty (dev ))
9798+ return 0 ;
9799+
9800+ crif = mlxsw_sp_crif_lookup (ctx -> mlxsw_sp -> router , dev );
9801+ if (!crif || crif -> rif )
9802+ return 0 ;
9803+
9804+ if (!mlxsw_sp_rif_should_config (crif -> rif , dev , NETDEV_UP ))
9805+ return 0 ;
9806+
9807+ err = __mlxsw_sp_inetaddr_event (ctx -> mlxsw_sp , dev , NETDEV_UP ,
9808+ false, ctx -> extack );
9809+ if (err )
9810+ return err ;
9811+
9812+ ctx -> done ++ ;
9813+ return 0 ;
9814+ }
9815+
9816+ static int mlxsw_sp_router_unreplay_inetaddr_up (struct net_device * dev ,
9817+ struct netdev_nested_priv * priv )
9818+ {
9819+ struct mlxsw_sp_router_replay_inetaddr_up * ctx = priv -> data ;
9820+ struct mlxsw_sp_crif * crif ;
9821+
9822+ if (!ctx -> done )
9823+ return 0 ;
9824+
9825+ if (mlxsw_sp_dev_addr_list_empty (dev ))
9826+ return 0 ;
9827+
9828+ crif = mlxsw_sp_crif_lookup (ctx -> mlxsw_sp -> router , dev );
9829+ if (!crif || !crif -> rif )
9830+ return 0 ;
9831+
9832+ /* We are rolling back NETDEV_UP, so ask for that. */
9833+ if (!mlxsw_sp_rif_should_config (crif -> rif , dev , NETDEV_UP ))
9834+ return 0 ;
9835+
9836+ __mlxsw_sp_inetaddr_event (ctx -> mlxsw_sp , dev , NETDEV_DOWN , false, NULL );
9837+
9838+ ctx -> done -- ;
9839+ return 0 ;
9840+ }
9841+
9842+ int mlxsw_sp_netdevice_enslavement_replay (struct mlxsw_sp * mlxsw_sp ,
9843+ struct net_device * upper_dev ,
9844+ struct netlink_ext_ack * extack )
9845+ {
9846+ struct mlxsw_sp_router_replay_inetaddr_up ctx = {
9847+ .mlxsw_sp = mlxsw_sp ,
9848+ .extack = extack ,
9849+ };
9850+ struct netdev_nested_priv priv = {
9851+ .data = & ctx ,
9852+ };
9853+ int err ;
9854+
9855+ err = mlxsw_sp_router_replay_inetaddr_up (upper_dev , & priv );
9856+ if (err )
9857+ return err ;
9858+
9859+ err = netdev_walk_all_upper_dev_rcu (upper_dev ,
9860+ mlxsw_sp_router_replay_inetaddr_up ,
9861+ & priv );
9862+ if (err )
9863+ goto err_replay_up ;
9864+
9865+ return 0 ;
9866+
9867+ err_replay_up :
9868+ netdev_walk_all_upper_dev_rcu (upper_dev ,
9869+ mlxsw_sp_router_unreplay_inetaddr_up ,
9870+ & priv );
9871+ mlxsw_sp_router_unreplay_inetaddr_up (upper_dev , & priv );
9872+ return err ;
9873+ }
9874+
97849875static int
97859876mlxsw_sp_port_vid_router_join_existing (struct mlxsw_sp_port * mlxsw_sp_port ,
97869877 u16 vid , struct net_device * dev ,
@@ -9857,6 +9948,26 @@ static int __mlxsw_sp_router_port_join_lag(struct mlxsw_sp_port *mlxsw_sp_port,
98579948 return err ;
98589949}
98599950
9951+ static void
9952+ __mlxsw_sp_router_port_leave_lag (struct mlxsw_sp_port * mlxsw_sp_port ,
9953+ struct net_device * lag_dev )
9954+ {
9955+ u16 default_vid = MLXSW_SP_DEFAULT_VID ;
9956+ struct net_device * upper_dev ;
9957+ struct list_head * iter ;
9958+ u16 vid ;
9959+
9960+ netdev_for_each_upper_dev_rcu (lag_dev , upper_dev , iter ) {
9961+ if (!is_vlan_dev (upper_dev ))
9962+ continue ;
9963+
9964+ vid = vlan_dev_vlan_id (upper_dev );
9965+ mlxsw_sp_port_vid_router_leave (mlxsw_sp_port , vid , upper_dev );
9966+ }
9967+
9968+ mlxsw_sp_port_vid_router_leave (mlxsw_sp_port , default_vid , lag_dev );
9969+ }
9970+
98609971int mlxsw_sp_router_port_join_lag (struct mlxsw_sp_port * mlxsw_sp_port ,
98619972 struct net_device * lag_dev ,
98629973 struct netlink_ext_ack * extack )
@@ -9870,6 +9981,14 @@ int mlxsw_sp_router_port_join_lag(struct mlxsw_sp_port *mlxsw_sp_port,
98709981 return err ;
98719982}
98729983
9984+ void mlxsw_sp_router_port_leave_lag (struct mlxsw_sp_port * mlxsw_sp_port ,
9985+ struct net_device * lag_dev )
9986+ {
9987+ mutex_lock (& mlxsw_sp_port -> mlxsw_sp -> router -> lock );
9988+ __mlxsw_sp_router_port_leave_lag (mlxsw_sp_port , lag_dev );
9989+ mutex_unlock (& mlxsw_sp_port -> mlxsw_sp -> router -> lock );
9990+ }
9991+
98739992static int mlxsw_sp_router_netdevice_event (struct notifier_block * nb ,
98749993 unsigned long event , void * ptr )
98759994{
0 commit comments