From 02581e536c3e62cedb465fd101b61b9142e87adb Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 20 Jun 2008 22:16:51 -0700 Subject: [PATCH] --- yaml --- r: 98367 b: refs/heads/master c: b9f75f45a6b46a0ab4eb0857d437a0845871f314 h: refs/heads/master i: 98365: f79468a952b98e3300bf2a8ec25b9dd978a6df64 98363: 9c5454a4717116db9bd17f34b78726bde6fb4b15 98359: 141e1489b26cbf9a0e7879c00bcf72ecffd5688e 98351: a1cfff810ed2c485fd8285e942aea1d3cd13b01a 98335: 741e0d1f6a9015bd2db21426a27b634767960f18 98303: 8d3fd52306c01a77327e5a8547cc363fa60bb45f v: v3 --- [refs] | 2 +- trunk/include/net/net_namespace.h | 11 +++++++++++ trunk/net/core/dev.c | 4 ++++ trunk/net/core/net_namespace.c | 3 +++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 545e2a01e0be..fac6026a7c77 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 735ce972fbc8a65fb17788debd7bbe7b4383cc62 +refs/heads/master: b9f75f45a6b46a0ab4eb0857d437a0845871f314 diff --git a/trunk/include/net/net_namespace.h b/trunk/include/net/net_namespace.h index aa540e6be502..d9dd0f707296 100644 --- a/trunk/include/net/net_namespace.h +++ b/trunk/include/net/net_namespace.h @@ -95,6 +95,11 @@ 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); @@ -125,6 +130,12 @@ int net_eq(const struct net *net1, const struct net *net2) return net1 == net2; } #else + +static inline int net_alive(struct net *net) +{ + return 1; +} + static inline struct net *get_net(struct net *net) { return net; diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 68d8df0992ab..c421a1f8f0b9 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -2077,6 +2077,10 @@ 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))) + 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 72b4c184dd84..7c52fe277b62 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -140,6 +140,9 @@ 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);