@@ -45,17 +45,18 @@ static int wg_open(struct net_device *dev)
45
45
if (dev_v6 )
46
46
dev_v6 -> cnf .addr_gen_mode = IN6_ADDR_GEN_MODE_NONE ;
47
47
48
+ mutex_lock (& wg -> device_update_lock );
48
49
ret = wg_socket_init (wg , wg -> incoming_port );
49
50
if (ret < 0 )
50
- return ret ;
51
- mutex_lock (& wg -> device_update_lock );
51
+ goto out ;
52
52
list_for_each_entry (peer , & wg -> peer_list , peer_list ) {
53
53
wg_packet_send_staged_packets (peer );
54
54
if (peer -> persistent_keepalive_interval )
55
55
wg_packet_send_keepalive (peer );
56
56
}
57
+ out :
57
58
mutex_unlock (& wg -> device_update_lock );
58
- return 0 ;
59
+ return ret ;
59
60
}
60
61
61
62
#ifdef CONFIG_PM_SLEEP
@@ -225,6 +226,7 @@ static void wg_destruct(struct net_device *dev)
225
226
list_del (& wg -> device_list );
226
227
rtnl_unlock ();
227
228
mutex_lock (& wg -> device_update_lock );
229
+ rcu_assign_pointer (wg -> creating_net , NULL );
228
230
wg -> incoming_port = 0 ;
229
231
wg_socket_reinit (wg , NULL , NULL );
230
232
/* The final references are cleared in the below calls to destroy_workqueue. */
@@ -240,13 +242,11 @@ static void wg_destruct(struct net_device *dev)
240
242
skb_queue_purge (& wg -> incoming_handshakes );
241
243
free_percpu (dev -> tstats );
242
244
free_percpu (wg -> incoming_handshakes_worker );
243
- if (wg -> have_creating_net_ref )
244
- put_net (wg -> creating_net );
245
245
kvfree (wg -> index_hashtable );
246
246
kvfree (wg -> peer_hashtable );
247
247
mutex_unlock (& wg -> device_update_lock );
248
248
249
- pr_debug ("%s: Interface deleted \n" , dev -> name );
249
+ pr_debug ("%s: Interface destroyed \n" , dev -> name );
250
250
free_netdev (dev );
251
251
}
252
252
@@ -292,7 +292,7 @@ static int wg_newlink(struct net *src_net, struct net_device *dev,
292
292
struct wg_device * wg = netdev_priv (dev );
293
293
int ret = - ENOMEM ;
294
294
295
- wg -> creating_net = src_net ;
295
+ rcu_assign_pointer ( wg -> creating_net , src_net ) ;
296
296
init_rwsem (& wg -> static_identity .lock );
297
297
mutex_init (& wg -> socket_update_lock );
298
298
mutex_init (& wg -> device_update_lock );
@@ -393,30 +393,26 @@ static struct rtnl_link_ops link_ops __read_mostly = {
393
393
.newlink = wg_newlink ,
394
394
};
395
395
396
- static int wg_netdevice_notification (struct notifier_block * nb ,
397
- unsigned long action , void * data )
396
+ static void wg_netns_pre_exit (struct net * net )
398
397
{
399
- struct net_device * dev = ((struct netdev_notifier_info * )data )-> dev ;
400
- struct wg_device * wg = netdev_priv (dev );
401
-
402
- ASSERT_RTNL ();
403
-
404
- if (action != NETDEV_REGISTER || dev -> netdev_ops != & netdev_ops )
405
- return 0 ;
398
+ struct wg_device * wg ;
406
399
407
- if (dev_net (dev ) == wg -> creating_net && wg -> have_creating_net_ref ) {
408
- put_net (wg -> creating_net );
409
- wg -> have_creating_net_ref = false;
410
- } else if (dev_net (dev ) != wg -> creating_net &&
411
- !wg -> have_creating_net_ref ) {
412
- wg -> have_creating_net_ref = true;
413
- get_net (wg -> creating_net );
400
+ rtnl_lock ();
401
+ list_for_each_entry (wg , & device_list , device_list ) {
402
+ if (rcu_access_pointer (wg -> creating_net ) == net ) {
403
+ pr_debug ("%s: Creating namespace exiting\n" , wg -> dev -> name );
404
+ netif_carrier_off (wg -> dev );
405
+ mutex_lock (& wg -> device_update_lock );
406
+ rcu_assign_pointer (wg -> creating_net , NULL );
407
+ wg_socket_reinit (wg , NULL , NULL );
408
+ mutex_unlock (& wg -> device_update_lock );
409
+ }
414
410
}
415
- return 0 ;
411
+ rtnl_unlock () ;
416
412
}
417
413
418
- static struct notifier_block netdevice_notifier = {
419
- .notifier_call = wg_netdevice_notification
414
+ static struct pernet_operations pernet_ops = {
415
+ .pre_exit = wg_netns_pre_exit
420
416
};
421
417
422
418
int __init wg_device_init (void )
@@ -429,18 +425,18 @@ int __init wg_device_init(void)
429
425
return ret ;
430
426
#endif
431
427
432
- ret = register_netdevice_notifier ( & netdevice_notifier );
428
+ ret = register_pernet_device ( & pernet_ops );
433
429
if (ret )
434
430
goto error_pm ;
435
431
436
432
ret = rtnl_link_register (& link_ops );
437
433
if (ret )
438
- goto error_netdevice ;
434
+ goto error_pernet ;
439
435
440
436
return 0 ;
441
437
442
- error_netdevice :
443
- unregister_netdevice_notifier ( & netdevice_notifier );
438
+ error_pernet :
439
+ unregister_pernet_device ( & pernet_ops );
444
440
error_pm :
445
441
#ifdef CONFIG_PM_SLEEP
446
442
unregister_pm_notifier (& pm_notifier );
@@ -451,7 +447,7 @@ int __init wg_device_init(void)
451
447
void wg_device_uninit (void )
452
448
{
453
449
rtnl_link_unregister (& link_ops );
454
- unregister_netdevice_notifier ( & netdevice_notifier );
450
+ unregister_pernet_device ( & pernet_ops );
455
451
#ifdef CONFIG_PM_SLEEP
456
452
unregister_pm_notifier (& pm_notifier );
457
453
#endif
0 commit comments