aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@aristanetworks.com>2009-02-22 03:11:09 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-03 04:14:27 -0500
commit17edde520927070a6bf14a6a75027c0b843443e5 (patch)
treedcd940213c93bc943c670f48aa52ec8571351912
parent2f20d2e667ab1ca44cde5fb361386dff5bb6081d (diff)
netns: Remove net_alive
It turns out that net_alive is unnecessary, and the original problem that led to it being added was simply that the icmp code thought it was a network device and wound up being unable to handle packets while there were still packets in the network namespace. Now that icmp and tcp have been fixed to properly register themselves this problem is no longer present and we have a stronger guarantee that packets will not arrive in a network namespace then that provided by net_alive in netif_receive_skb. So remove net_alive allowing packet reception run a little faster. Additionally document the strong reason why network namespace cleanup is safe so that if something happens again someone else will have a chance of figuring it out. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/net_namespace.h27
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/net_namespace.c3
3 files changed, 17 insertions, 19 deletions
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 6fc13d905c5f..ded434b032a4 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -109,11 +109,6 @@ extern struct list_head net_namespace_list;
109#ifdef CONFIG_NET_NS 109#ifdef CONFIG_NET_NS
110extern void __put_net(struct net *net); 110extern void __put_net(struct net *net);
111 111
112static inline int net_alive(struct net *net)
113{
114 return net && atomic_read(&net->count);
115}
116
117static inline struct net *get_net(struct net *net) 112static inline struct net *get_net(struct net *net)
118{ 113{
119 atomic_inc(&net->count); 114 atomic_inc(&net->count);
@@ -145,11 +140,6 @@ int net_eq(const struct net *net1, const struct net *net2)
145} 140}
146#else 141#else
147 142
148static inline int net_alive(struct net *net)
149{
150 return 1;
151}
152
153static inline struct net *get_net(struct net *net) 143static inline struct net *get_net(struct net *net)
154{ 144{
155 return net; 145 return net;
@@ -234,6 +224,23 @@ struct pernet_operations {
234 void (*exit)(struct net *net); 224 void (*exit)(struct net *net);
235}; 225};
236 226
227/*
228 * Use these carefully. If you implement a network device and it
229 * needs per network namespace operations use device pernet operations,
230 * otherwise use pernet subsys operations.
231 *
232 * This is critically important. Most of the network code cleanup
233 * runs with the assumption that dev_remove_pack has been called so no
234 * new packets will arrive during and after the cleanup functions have
235 * been called. dev_remove_pack is not per namespace so instead the
236 * guarantee of no more packets arriving in a network namespace is
237 * provided by ensuring that all network devices and all sockets have
238 * left the network namespace before the cleanup methods are called.
239 *
240 * For the longest time the ipv4 icmp code was registered as a pernet
241 * device which caused kernel oops, and panics during network
242 * namespace cleanup. So please don't get this wrong.
243 */
237extern int register_pernet_subsys(struct pernet_operations *); 244extern int register_pernet_subsys(struct pernet_operations *);
238extern void unregister_pernet_subsys(struct pernet_operations *); 245extern void unregister_pernet_subsys(struct pernet_operations *);
239extern int register_pernet_gen_subsys(int *id, struct pernet_operations *); 246extern int register_pernet_gen_subsys(int *id, struct pernet_operations *);
diff --git a/net/core/dev.c b/net/core/dev.c
index 72b0d26fd46d..9e4afe650e7a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2267,12 +2267,6 @@ int netif_receive_skb(struct sk_buff *skb)
2267 2267
2268 rcu_read_lock(); 2268 rcu_read_lock();
2269 2269
2270 /* Don't receive packets in an exiting network namespace */
2271 if (!net_alive(dev_net(skb->dev))) {
2272 kfree_skb(skb);
2273 goto out;
2274 }
2275
2276#ifdef CONFIG_NET_CLS_ACT 2270#ifdef CONFIG_NET_CLS_ACT
2277 if (skb->tc_verd & TC_NCLS) { 2271 if (skb->tc_verd & TC_NCLS) {
2278 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); 2272 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 2adb1a7d361f..e3bebd36f053 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -157,9 +157,6 @@ static void cleanup_net(struct work_struct *work)
157 struct pernet_operations *ops; 157 struct pernet_operations *ops;
158 struct net *net; 158 struct net *net;
159 159
160 /* Be very certain incoming network packets will not find us */
161 rcu_barrier();
162
163 net = container_of(work, struct net, work); 160 net = container_of(work, struct net, work);
164 161
165 mutex_lock(&net_mutex); 162 mutex_lock(&net_mutex);