diff options
-rw-r--r-- | include/net/net_namespace.h | 11 | ||||
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/core/net_namespace.c | 3 |
3 files changed, 18 insertions, 0 deletions
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index aa540e6be502..d9dd0f707296 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -95,6 +95,11 @@ extern struct list_head net_namespace_list; | |||
95 | #ifdef CONFIG_NET_NS | 95 | #ifdef CONFIG_NET_NS |
96 | extern void __put_net(struct net *net); | 96 | extern void __put_net(struct net *net); |
97 | 97 | ||
98 | static inline int net_alive(struct net *net) | ||
99 | { | ||
100 | return net && atomic_read(&net->count); | ||
101 | } | ||
102 | |||
98 | static inline struct net *get_net(struct net *net) | 103 | static inline struct net *get_net(struct net *net) |
99 | { | 104 | { |
100 | atomic_inc(&net->count); | 105 | atomic_inc(&net->count); |
@@ -125,6 +130,12 @@ int net_eq(const struct net *net1, const struct net *net2) | |||
125 | return net1 == net2; | 130 | return net1 == net2; |
126 | } | 131 | } |
127 | #else | 132 | #else |
133 | |||
134 | static inline int net_alive(struct net *net) | ||
135 | { | ||
136 | return 1; | ||
137 | } | ||
138 | |||
128 | static inline struct net *get_net(struct net *net) | 139 | static inline struct net *get_net(struct net *net) |
129 | { | 140 | { |
130 | return net; | 141 | return net; |
diff --git a/net/core/dev.c b/net/core/dev.c index 68d8df0992ab..c421a1f8f0b9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2077,6 +2077,10 @@ int netif_receive_skb(struct sk_buff *skb) | |||
2077 | 2077 | ||
2078 | rcu_read_lock(); | 2078 | rcu_read_lock(); |
2079 | 2079 | ||
2080 | /* Don't receive packets in an exiting network namespace */ | ||
2081 | if (!net_alive(dev_net(skb->dev))) | ||
2082 | goto out; | ||
2083 | |||
2080 | #ifdef CONFIG_NET_CLS_ACT | 2084 | #ifdef CONFIG_NET_CLS_ACT |
2081 | if (skb->tc_verd & TC_NCLS) { | 2085 | if (skb->tc_verd & TC_NCLS) { |
2082 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); | 2086 | skb->tc_verd = CLR_TC_NCLS(skb->tc_verd); |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 72b4c184dd84..7c52fe277b62 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -140,6 +140,9 @@ static void cleanup_net(struct work_struct *work) | |||
140 | struct pernet_operations *ops; | 140 | struct pernet_operations *ops; |
141 | struct net *net; | 141 | struct net *net; |
142 | 142 | ||
143 | /* Be very certain incoming network packets will not find us */ | ||
144 | rcu_barrier(); | ||
145 | |||
143 | net = container_of(work, struct net, work); | 146 | net = container_of(work, struct net, work); |
144 | 147 | ||
145 | mutex_lock(&net_mutex); | 148 | mutex_lock(&net_mutex); |