@@ -2748,13 +2748,12 @@ static void mlxsw_sp_router_update_priority_work(struct work_struct *work)
27482748}
27492749
27502750static int mlxsw_sp_router_schedule_work (struct net * net ,
2751- struct notifier_block * nb ,
2751+ struct mlxsw_sp_router * router ,
2752+ struct neighbour * n ,
27522753 void (* cb )(struct work_struct * ))
27532754{
27542755 struct mlxsw_sp_netevent_work * net_work ;
2755- struct mlxsw_sp_router * router ;
27562756
2757- router = container_of (nb , struct mlxsw_sp_router , netevent_nb );
27582757 if (!net_eq (net , mlxsw_sp_net (router -> mlxsw_sp )))
27592758 return NOTIFY_DONE ;
27602759
@@ -2764,19 +2763,31 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
27642763
27652764 INIT_WORK (& net_work -> work , cb );
27662765 net_work -> mlxsw_sp = router -> mlxsw_sp ;
2766+ net_work -> n = n ;
27672767 mlxsw_core_schedule_work (& net_work -> work );
27682768 return NOTIFY_DONE ;
27692769}
27702770
2771+ static bool mlxsw_sp_dev_lower_is_port (struct net_device * dev )
2772+ {
2773+ struct mlxsw_sp_port * mlxsw_sp_port ;
2774+
2775+ rcu_read_lock ();
2776+ mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu (dev );
2777+ rcu_read_unlock ();
2778+ return !!mlxsw_sp_port ;
2779+ }
2780+
27712781static int mlxsw_sp_router_netevent_event (struct notifier_block * nb ,
27722782 unsigned long event , void * ptr )
27732783{
2774- struct mlxsw_sp_netevent_work * net_work ;
2775- struct mlxsw_sp_port * mlxsw_sp_port ;
2776- struct mlxsw_sp * mlxsw_sp ;
2784+ struct mlxsw_sp_router * router ;
27772785 unsigned long interval ;
27782786 struct neigh_parms * p ;
27792787 struct neighbour * n ;
2788+ struct net * net ;
2789+
2790+ router = container_of (nb , struct mlxsw_sp_router , netevent_nb );
27802791
27812792 switch (event ) {
27822793 case NETEVENT_DELAY_PROBE_TIME_UPDATE :
@@ -2790,51 +2801,37 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
27902801 /* We are in atomic context and can't take RTNL mutex,
27912802 * so use RCU variant to walk the device chain.
27922803 */
2793- mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold (p -> dev );
2794- if (!mlxsw_sp_port )
2804+ if (!mlxsw_sp_dev_lower_is_port (p -> dev ))
27952805 return NOTIFY_DONE ;
27962806
2797- mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
27982807 interval = jiffies_to_msecs (NEIGH_VAR (p , DELAY_PROBE_TIME ));
2799- mlxsw_sp -> router -> neighs_update .interval = interval ;
2800-
2801- mlxsw_sp_port_dev_put (mlxsw_sp_port );
2808+ router -> neighs_update .interval = interval ;
28022809 break ;
28032810 case NETEVENT_NEIGH_UPDATE :
28042811 n = ptr ;
2812+ net = neigh_parms_net (n -> parms );
28052813
28062814 if (n -> tbl -> family != AF_INET && n -> tbl -> family != AF_INET6 )
28072815 return NOTIFY_DONE ;
28082816
2809- mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold (n -> dev );
2810- if (!mlxsw_sp_port )
2817+ if (!mlxsw_sp_dev_lower_is_port (n -> dev ))
28112818 return NOTIFY_DONE ;
28122819
2813- net_work = kzalloc (sizeof (* net_work ), GFP_ATOMIC );
2814- if (!net_work ) {
2815- mlxsw_sp_port_dev_put (mlxsw_sp_port );
2816- return NOTIFY_BAD ;
2817- }
2818-
2819- INIT_WORK (& net_work -> work , mlxsw_sp_router_neigh_event_work );
2820- net_work -> mlxsw_sp = mlxsw_sp_port -> mlxsw_sp ;
2821- net_work -> n = n ;
2822-
28232820 /* Take a reference to ensure the neighbour won't be
28242821 * destructed until we drop the reference in delayed
28252822 * work.
28262823 */
28272824 neigh_clone (n );
2828- mlxsw_core_schedule_work ( & net_work -> work );
2829- mlxsw_sp_port_dev_put ( mlxsw_sp_port );
2830- break ;
2825+ return mlxsw_sp_router_schedule_work ( net , router , n ,
2826+ mlxsw_sp_router_neigh_event_work );
2827+
28312828 case NETEVENT_IPV4_MPATH_HASH_UPDATE :
28322829 case NETEVENT_IPV6_MPATH_HASH_UPDATE :
2833- return mlxsw_sp_router_schedule_work (ptr , nb ,
2830+ return mlxsw_sp_router_schedule_work (ptr , router , NULL ,
28342831 mlxsw_sp_router_mp_hash_event_work );
28352832
28362833 case NETEVENT_IPV4_FWD_UPDATE_PRIORITY_UPDATE :
2837- return mlxsw_sp_router_schedule_work (ptr , nb ,
2834+ return mlxsw_sp_router_schedule_work (ptr , router , NULL ,
28382835 mlxsw_sp_router_update_priority_work );
28392836 }
28402837
@@ -7708,7 +7705,7 @@ mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
77087705
77097706 for (i = 0 ; i < max_rifs ; i ++ )
77107707 if (mlxsw_sp -> router -> rifs [i ] &&
7711- mlxsw_sp -> router -> rifs [i ]-> dev == dev )
7708+ mlxsw_sp_rif_dev_is ( mlxsw_sp -> router -> rifs [i ], dev ) )
77127709 return mlxsw_sp -> router -> rifs [i ];
77137710
77147711 return NULL ;
@@ -8078,11 +8075,22 @@ int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif)
80788075 return rif -> dev -> ifindex ;
80798076}
80808077
8081- const struct net_device * mlxsw_sp_rif_dev (const struct mlxsw_sp_rif * rif )
8078+ static const struct net_device * mlxsw_sp_rif_dev (const struct mlxsw_sp_rif * rif )
80828079{
80838080 return rif -> dev ;
80848081}
80858082
8083+ bool mlxsw_sp_rif_has_dev (const struct mlxsw_sp_rif * rif )
8084+ {
8085+ return !!mlxsw_sp_rif_dev (rif );
8086+ }
8087+
8088+ bool mlxsw_sp_rif_dev_is (const struct mlxsw_sp_rif * rif ,
8089+ const struct net_device * dev )
8090+ {
8091+ return mlxsw_sp_rif_dev (rif ) == dev ;
8092+ }
8093+
80868094static void mlxsw_sp_rif_push_l3_stats (struct mlxsw_sp_rif * rif )
80878095{
80888096 struct rtnl_hw_stats64 stats = {};
@@ -8879,8 +8887,8 @@ static int mlxsw_sp_inetaddr_event(struct notifier_block *nb,
88798887 return notifier_from_errno (err );
88808888}
88818889
8882- int mlxsw_sp_inetaddr_valid_event (struct notifier_block * unused ,
8883- unsigned long event , void * ptr )
8890+ static int mlxsw_sp_inetaddr_valid_event (struct notifier_block * unused ,
8891+ unsigned long event , void * ptr )
88848892{
88858893 struct in_validator_info * ivi = (struct in_validator_info * ) ptr ;
88868894 struct net_device * dev = ivi -> ivi_dev -> dev ;
@@ -8962,8 +8970,8 @@ static int mlxsw_sp_inet6addr_event(struct notifier_block *nb,
89628970 return NOTIFY_DONE ;
89638971}
89648972
8965- int mlxsw_sp_inet6addr_valid_event (struct notifier_block * unused ,
8966- unsigned long event , void * ptr )
8973+ static int mlxsw_sp_inet6addr_valid_event (struct notifier_block * unused ,
8974+ unsigned long event , void * ptr )
89678975{
89688976 struct in6_validator_info * i6vi = (struct in6_validator_info * ) ptr ;
89698977 struct net_device * dev = i6vi -> i6vi_dev -> dev ;
@@ -10510,6 +10518,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
1051010518 struct netlink_ext_ack * extack )
1051110519{
1051210520 struct mlxsw_sp_router * router ;
10521+ struct notifier_block * nb ;
1051310522 int err ;
1051410523
1051510524 router = kzalloc (sizeof (* mlxsw_sp -> router ), GFP_KERNEL );
@@ -10588,6 +10597,17 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
1058810597 if (err )
1058910598 goto err_register_inet6addr_notifier ;
1059010599
10600+ router -> inetaddr_valid_nb .notifier_call = mlxsw_sp_inetaddr_valid_event ;
10601+ err = register_inetaddr_validator_notifier (& router -> inetaddr_valid_nb );
10602+ if (err )
10603+ goto err_register_inetaddr_valid_notifier ;
10604+
10605+ nb = & router -> inet6addr_valid_nb ;
10606+ nb -> notifier_call = mlxsw_sp_inet6addr_valid_event ;
10607+ err = register_inet6addr_validator_notifier (nb );
10608+ if (err )
10609+ goto err_register_inet6addr_valid_notifier ;
10610+
1059110611 mlxsw_sp -> router -> netevent_nb .notifier_call =
1059210612 mlxsw_sp_router_netevent_event ;
1059310613 err = register_netevent_notifier (& mlxsw_sp -> router -> netevent_nb );
@@ -10627,6 +10647,10 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
1062710647err_register_nexthop_notifier :
1062810648 unregister_netevent_notifier (& mlxsw_sp -> router -> netevent_nb );
1062910649err_register_netevent_notifier :
10650+ unregister_inet6addr_validator_notifier (& router -> inet6addr_valid_nb );
10651+ err_register_inet6addr_valid_notifier :
10652+ unregister_inetaddr_validator_notifier (& router -> inetaddr_valid_nb );
10653+ err_register_inetaddr_valid_notifier :
1063010654 unregister_inet6addr_notifier (& router -> inet6addr_nb );
1063110655err_register_inet6addr_notifier :
1063210656 unregister_inetaddr_notifier (& router -> inetaddr_nb );
@@ -10664,28 +10688,31 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
1066410688
1066510689void mlxsw_sp_router_fini (struct mlxsw_sp * mlxsw_sp )
1066610690{
10691+ struct mlxsw_sp_router * router = mlxsw_sp -> router ;
10692+
1066710693 unregister_netdevice_notifier_net (mlxsw_sp_net (mlxsw_sp ),
10668- & mlxsw_sp -> router -> netdevice_nb );
10669- unregister_fib_notifier (mlxsw_sp_net (mlxsw_sp ),
10670- & mlxsw_sp -> router -> fib_nb );
10694+ & router -> netdevice_nb );
10695+ unregister_fib_notifier (mlxsw_sp_net (mlxsw_sp ), & router -> fib_nb );
1067110696 unregister_nexthop_notifier (mlxsw_sp_net (mlxsw_sp ),
10672- & mlxsw_sp -> router -> nexthop_nb );
10673- unregister_netevent_notifier (& mlxsw_sp -> router -> netevent_nb );
10674- unregister_inet6addr_notifier (& mlxsw_sp -> router -> inet6addr_nb );
10675- unregister_inetaddr_notifier (& mlxsw_sp -> router -> inetaddr_nb );
10697+ & router -> nexthop_nb );
10698+ unregister_netevent_notifier (& router -> netevent_nb );
10699+ unregister_inet6addr_validator_notifier (& router -> inet6addr_valid_nb );
10700+ unregister_inetaddr_validator_notifier (& router -> inetaddr_valid_nb );
10701+ unregister_inet6addr_notifier (& router -> inet6addr_nb );
10702+ unregister_inetaddr_notifier (& router -> inetaddr_nb );
1067610703 mlxsw_core_flush_owq ();
1067710704 mlxsw_sp_mp_hash_fini (mlxsw_sp );
1067810705 mlxsw_sp_neigh_fini (mlxsw_sp );
1067910706 mlxsw_sp_lb_rif_fini (mlxsw_sp );
1068010707 mlxsw_sp_vrs_fini (mlxsw_sp );
1068110708 mlxsw_sp_mr_fini (mlxsw_sp );
1068210709 mlxsw_sp_lpm_fini (mlxsw_sp );
10683- rhashtable_destroy (& mlxsw_sp -> router -> nexthop_group_ht );
10684- rhashtable_destroy (& mlxsw_sp -> router -> nexthop_ht );
10710+ rhashtable_destroy (& router -> nexthop_group_ht );
10711+ rhashtable_destroy (& router -> nexthop_ht );
1068510712 mlxsw_sp_ipips_fini (mlxsw_sp );
1068610713 mlxsw_sp_rifs_fini (mlxsw_sp );
1068710714 __mlxsw_sp_router_fini (mlxsw_sp );
10688- cancel_delayed_work_sync (& mlxsw_sp -> router -> nh_grp_activity_dw );
10689- mutex_destroy (& mlxsw_sp -> router -> lock );
10690- kfree (mlxsw_sp -> router );
10715+ cancel_delayed_work_sync (& router -> nh_grp_activity_dw );
10716+ mutex_destroy (& router -> lock );
10717+ kfree (router );
1069110718}
0 commit comments