Skip to content

Commit ae33bc4

Browse files
ebiedermdavem330
authored andcommitted
net: Guaranetee the proper ordering of the loopback device.
I was recently hunting a bug that occurred in network namespace cleanup. In looking at the code it became apparrent that we have and will continue to have cases where if we have anything going on in a network namespace there will be assumptions that the loopback device is present. Things like sending igmp unsubscribe messages when we bring down network devices invokes the routing code which assumes that at least the loopback driver is present. Therefore to avoid magic initcall ordering hackery that is hard to follow and hard to get right insert a call to register the loopback device directly from net_dev_init(). This guarantes that the loopback device is the first device registered and the last network device to go away. Signed-off-by: Eric W. Biederman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent d0c082c commit ae33bc4

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

drivers/net/loopback.c

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -204,17 +204,8 @@ static __net_exit void loopback_net_exit(struct net *net)
204204
unregister_netdev(dev);
205205
}
206206

207-
static struct pernet_operations __net_initdata loopback_net_ops = {
207+
/* Registered in net/core/dev.c */
208+
struct pernet_operations __net_initdata loopback_net_ops = {
208209
.init = loopback_net_init,
209210
.exit = loopback_net_exit,
210211
};
211-
212-
static int __init loopback_init(void)
213-
{
214-
return register_pernet_device(&loopback_net_ops);
215-
}
216-
217-
/* Loopback is special. It should be initialized before any other network
218-
* device and network subsystem.
219-
*/
220-
fs_initcall(loopback_init);

include/linux/netdevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1766,6 +1766,7 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
17661766
return 0;
17671767
}
17681768

1769+
extern struct pernet_operations __net_initdata loopback_net_ops;
17691770
#endif /* __KERNEL__ */
17701771

17711772
#endif /* _LINUX_DEV_H */

net/core/dev.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4904,6 +4904,18 @@ static int __init net_dev_init(void)
49044904
if (register_pernet_subsys(&netdev_net_ops))
49054905
goto out;
49064906

4907+
/* The loopback device is special if any other network devices
4908+
* is present in a network namespace the loopback device must
4909+
* be present. Since we now dynamically allocate and free the
4910+
* loopback device ensure this invariant is maintained by
4911+
* keeping the loopback device as the first device on the
4912+
* list of network devices. Ensuring the loopback devices
4913+
* is the first device that appears and the last network device
4914+
* that disappears.
4915+
*/
4916+
if (register_pernet_device(&loopback_net_ops))
4917+
goto out;
4918+
49074919
if (register_pernet_device(&default_device_ops))
49084920
goto out;
49094921

0 commit comments

Comments
 (0)