diff options
-rw-r--r-- | include/net/net_namespace.h | 27 | ||||
-rw-r--r-- | net/core/dev.c | 6 | ||||
-rw-r--r-- | net/core/net_namespace.c | 3 |
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 |
110 | extern void __put_net(struct net *net); | 110 | extern void __put_net(struct net *net); |
111 | 111 | ||
112 | static inline int net_alive(struct net *net) | ||
113 | { | ||
114 | return net && atomic_read(&net->count); | ||
115 | } | ||
116 | |||
117 | static inline struct net *get_net(struct net *net) | 112 | static 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 | ||
148 | static inline int net_alive(struct net *net) | ||
149 | { | ||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | static inline struct net *get_net(struct net *net) | 143 | static 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 | */ | ||
237 | extern int register_pernet_subsys(struct pernet_operations *); | 244 | extern int register_pernet_subsys(struct pernet_operations *); |
238 | extern void unregister_pernet_subsys(struct pernet_operations *); | 245 | extern void unregister_pernet_subsys(struct pernet_operations *); |
239 | extern int register_pernet_gen_subsys(int *id, struct pernet_operations *); | 246 | extern 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); |