@@ -208,6 +208,34 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex)
208
208
return & net -> dev_index_head [ifindex & ((1 << NETDEV_HASHBITS ) - 1 )];
209
209
}
210
210
211
+ /* Device list insertion */
212
+ static int list_netdevice (struct net_device * dev )
213
+ {
214
+ struct net * net = dev -> nd_net ;
215
+
216
+ ASSERT_RTNL ();
217
+
218
+ write_lock_bh (& dev_base_lock );
219
+ list_add_tail (& dev -> dev_list , & net -> dev_base_head );
220
+ hlist_add_head (& dev -> name_hlist , dev_name_hash (net , dev -> name ));
221
+ hlist_add_head (& dev -> index_hlist , dev_index_hash (net , dev -> ifindex ));
222
+ write_unlock_bh (& dev_base_lock );
223
+ return 0 ;
224
+ }
225
+
226
+ /* Device list removal */
227
+ static void unlist_netdevice (struct net_device * dev )
228
+ {
229
+ ASSERT_RTNL ();
230
+
231
+ /* Unlink dev from the device chain */
232
+ write_lock_bh (& dev_base_lock );
233
+ list_del (& dev -> dev_list );
234
+ hlist_del (& dev -> name_hlist );
235
+ hlist_del (& dev -> index_hlist );
236
+ write_unlock_bh (& dev_base_lock );
237
+ }
238
+
211
239
/*
212
240
* Our notifier list
213
241
*/
@@ -3571,12 +3599,8 @@ int register_netdevice(struct net_device *dev)
3571
3599
set_bit (__LINK_STATE_PRESENT , & dev -> state );
3572
3600
3573
3601
dev_init_scheduler (dev );
3574
- write_lock_bh (& dev_base_lock );
3575
- list_add_tail (& dev -> dev_list , & net -> dev_base_head );
3576
- hlist_add_head (& dev -> name_hlist , head );
3577
- hlist_add_head (& dev -> index_hlist , dev_index_hash (net , dev -> ifindex ));
3578
3602
dev_hold (dev );
3579
- write_unlock_bh ( & dev_base_lock );
3603
+ list_netdevice ( dev );
3580
3604
3581
3605
/* Notify protocols, that a new device appeared. */
3582
3606
ret = raw_notifier_call_chain (& netdev_chain , NETDEV_REGISTER , dev );
@@ -3883,11 +3907,7 @@ void unregister_netdevice(struct net_device *dev)
3883
3907
dev_close (dev );
3884
3908
3885
3909
/* And unlink it from device chain. */
3886
- write_lock_bh (& dev_base_lock );
3887
- list_del (& dev -> dev_list );
3888
- hlist_del (& dev -> name_hlist );
3889
- hlist_del (& dev -> index_hlist );
3890
- write_unlock_bh (& dev_base_lock );
3910
+ unlist_netdevice (dev );
3891
3911
3892
3912
dev -> reg_state = NETREG_UNREGISTERING ;
3893
3913
@@ -3945,6 +3965,122 @@ void unregister_netdev(struct net_device *dev)
3945
3965
3946
3966
EXPORT_SYMBOL (unregister_netdev );
3947
3967
3968
+ /**
3969
+ * dev_change_net_namespace - move device to different nethost namespace
3970
+ * @dev: device
3971
+ * @net: network namespace
3972
+ * @pat: If not NULL name pattern to try if the current device name
3973
+ * is already taken in the destination network namespace.
3974
+ *
3975
+ * This function shuts down a device interface and moves it
3976
+ * to a new network namespace. On success 0 is returned, on
3977
+ * a failure a netagive errno code is returned.
3978
+ *
3979
+ * Callers must hold the rtnl semaphore.
3980
+ */
3981
+
3982
+ int dev_change_net_namespace (struct net_device * dev , struct net * net , const char * pat )
3983
+ {
3984
+ char buf [IFNAMSIZ ];
3985
+ const char * destname ;
3986
+ int err ;
3987
+
3988
+ ASSERT_RTNL ();
3989
+
3990
+ /* Don't allow namespace local devices to be moved. */
3991
+ err = - EINVAL ;
3992
+ if (dev -> features & NETIF_F_NETNS_LOCAL )
3993
+ goto out ;
3994
+
3995
+ /* Ensure the device has been registrered */
3996
+ err = - EINVAL ;
3997
+ if (dev -> reg_state != NETREG_REGISTERED )
3998
+ goto out ;
3999
+
4000
+ /* Get out if there is nothing todo */
4001
+ err = 0 ;
4002
+ if (dev -> nd_net == net )
4003
+ goto out ;
4004
+
4005
+ /* Pick the destination device name, and ensure
4006
+ * we can use it in the destination network namespace.
4007
+ */
4008
+ err = - EEXIST ;
4009
+ destname = dev -> name ;
4010
+ if (__dev_get_by_name (net , destname )) {
4011
+ /* We get here if we can't use the current device name */
4012
+ if (!pat )
4013
+ goto out ;
4014
+ if (!dev_valid_name (pat ))
4015
+ goto out ;
4016
+ if (strchr (pat , '%' )) {
4017
+ if (__dev_alloc_name (net , pat , buf ) < 0 )
4018
+ goto out ;
4019
+ destname = buf ;
4020
+ } else
4021
+ destname = pat ;
4022
+ if (__dev_get_by_name (net , destname ))
4023
+ goto out ;
4024
+ }
4025
+
4026
+ /*
4027
+ * And now a mini version of register_netdevice unregister_netdevice.
4028
+ */
4029
+
4030
+ /* If device is running close it first. */
4031
+ if (dev -> flags & IFF_UP )
4032
+ dev_close (dev );
4033
+
4034
+ /* And unlink it from device chain */
4035
+ err = - ENODEV ;
4036
+ unlist_netdevice (dev );
4037
+
4038
+ synchronize_net ();
4039
+
4040
+ /* Shutdown queueing discipline. */
4041
+ dev_shutdown (dev );
4042
+
4043
+ /* Notify protocols, that we are about to destroy
4044
+ this device. They should clean all the things.
4045
+ */
4046
+ call_netdevice_notifiers (NETDEV_UNREGISTER , dev );
4047
+
4048
+ /*
4049
+ * Flush the unicast and multicast chains
4050
+ */
4051
+ dev_addr_discard (dev );
4052
+
4053
+ /* Actually switch the network namespace */
4054
+ dev -> nd_net = net ;
4055
+
4056
+ /* Assign the new device name */
4057
+ if (destname != dev -> name )
4058
+ strcpy (dev -> name , destname );
4059
+
4060
+ /* If there is an ifindex conflict assign a new one */
4061
+ if (__dev_get_by_index (net , dev -> ifindex )) {
4062
+ int iflink = (dev -> iflink == dev -> ifindex );
4063
+ dev -> ifindex = dev_new_index (net );
4064
+ if (iflink )
4065
+ dev -> iflink = dev -> ifindex ;
4066
+ }
4067
+
4068
+ /* Fixup sysfs */
4069
+ err = device_rename (& dev -> dev , dev -> name );
4070
+ BUG_ON (err );
4071
+
4072
+ /* Add the device back in the hashes */
4073
+ list_netdevice (dev );
4074
+
4075
+ /* Notify protocols, that a new device appeared. */
4076
+ call_netdevice_notifiers (NETDEV_REGISTER , dev );
4077
+
4078
+ synchronize_net ();
4079
+ err = 0 ;
4080
+ out :
4081
+ return err ;
4082
+ }
4083
+
3948
4084
static int dev_cpu_callback (struct notifier_block * nfb ,
3949
4085
unsigned long action ,
3950
4086
void * ocpu )
@@ -4177,6 +4313,36 @@ static struct pernet_operations netdev_net_ops = {
4177
4313
.exit = netdev_exit ,
4178
4314
};
4179
4315
4316
+ static void default_device_exit (struct net * net )
4317
+ {
4318
+ struct net_device * dev , * next ;
4319
+ /*
4320
+ * Push all migratable of the network devices back to the
4321
+ * initial network namespace
4322
+ */
4323
+ rtnl_lock ();
4324
+ for_each_netdev_safe (net , dev , next ) {
4325
+ int err ;
4326
+
4327
+ /* Ignore unmoveable devices (i.e. loopback) */
4328
+ if (dev -> features & NETIF_F_NETNS_LOCAL )
4329
+ continue ;
4330
+
4331
+ /* Push remaing network devices to init_net */
4332
+ err = dev_change_net_namespace (dev , & init_net , "dev%d" );
4333
+ if (err ) {
4334
+ printk (KERN_WARNING "%s: failed to move %s to init_net: %d\n" ,
4335
+ __func__ , dev -> name , err );
4336
+ unregister_netdevice (dev );
4337
+ }
4338
+ }
4339
+ rtnl_unlock ();
4340
+ }
4341
+
4342
+ static struct pernet_operations default_device_ops = {
4343
+ .exit = default_device_exit ,
4344
+ };
4345
+
4180
4346
/*
4181
4347
* Initialize the DEV module. At boot time this walks the device list and
4182
4348
* unhooks any devices that fail to initialise (normally hardware not
@@ -4207,6 +4373,9 @@ static int __init net_dev_init(void)
4207
4373
if (register_pernet_subsys (& netdev_net_ops ))
4208
4374
goto out ;
4209
4375
4376
+ if (register_pernet_device (& default_device_ops ))
4377
+ goto out ;
4378
+
4210
4379
/*
4211
4380
* Initialise the packet receive queues.
4212
4381
*/
0 commit comments