From cf9094a861013cbc5dd436a411505226925cebe4 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sun, 22 Feb 2009 00:11:09 -0800 Subject: [PATCH] --- yaml --- r: 134660 b: refs/heads/master c: ce16c5337ab0d165f95c88aa857207efd7c01139 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/net/net_namespace.h | 27 +++++++++++++++++---------- trunk/net/core/dev.c | 6 ------ trunk/net/core/net_namespace.c | 3 --- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/[refs] b/[refs] index 745ec84cc996..a82a52234483 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6a1b3054d9fd98001a6631501caf1969138ee00d +refs/heads/master: ce16c5337ab0d165f95c88aa857207efd7c01139 diff --git a/trunk/include/net/net_namespace.h b/trunk/include/net/net_namespace.h index 6fc13d905c5f..ded434b032a4 100644 --- a/trunk/include/net/net_namespace.h +++ b/trunk/include/net/net_namespace.h @@ -109,11 +109,6 @@ extern struct list_head net_namespace_list; #ifdef CONFIG_NET_NS extern void __put_net(struct net *net); -static inline int net_alive(struct net *net) -{ - return net && atomic_read(&net->count); -} - static inline struct net *get_net(struct net *net) { atomic_inc(&net->count); @@ -145,11 +140,6 @@ int net_eq(const struct net *net1, const struct net *net2) } #else -static inline int net_alive(struct net *net) -{ - return 1; -} - static inline struct net *get_net(struct net *net) { return net; @@ -234,6 +224,23 @@ struct pernet_operations { void (*exit)(struct net *net); }; +/* + * Use these carefully. If you implement a network device and it + * needs per network namespace operations use device pernet operations, + * otherwise use pernet subsys operations. + * + * This is critically important. Most of the network code cleanup + * runs with the assumption that dev_remove_pack has been called so no + * new packets will arrive during and after the cleanup functions have + * been called. dev_remove_pack is not per namespace so instead the + * guarantee of no more packets arriving in a network namespace is + * provided by ensuring that all network devices and all sockets have + * left the network namespace before the cleanup methods are called. + * + * For the longest time the ipv4 icmp code was registered as a pernet + * device which caused kernel oops, and panics during network + * namespace cleanup. So please don't get this wrong. + */ extern int register_pernet_subsys(struct pernet_operations *); extern void unregister_pernet_subsys(struct pernet_operations *); extern int register_pernet_gen_subsys(int *id, struct pernet_operations *); diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 88dc082b47d1..ac6ab12d3297 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -2254,12 +2254,6 @@ int netif_receive_skb(struct sk_buff *skb) rcu_read_lock(); - /* Don't receive packets in an exiting network namespace */ - if (!net_alive(dev_net(skb->dev))) { - kfree_skb(skb); - goto out; - } - #ifdef CONFIG_NET_CLS_ACT if (skb->tc_verd & TC_NCLS) { skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index 55151faaf90c..516c7b154327 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -140,9 +140,6 @@ static void cleanup_net(struct work_struct *work) struct pernet_operations *ops; struct net *net; - /* Be very certain incoming network packets will not find us */ - rcu_barrier(); - net = container_of(work, struct net, work); mutex_lock(&net_mutex);