aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/net_namespace.h11
-rw-r--r--net/core/dev.c4
-rw-r--r--net/core/net_namespace.c3
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
96extern void __put_net(struct net *net); 96extern void __put_net(struct net *net);
97 97
98static inline int net_alive(struct net *net)
99{
100 return net && atomic_read(&net->count);
101}
102
98static inline struct net *get_net(struct net *net) 103static 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
134static inline int net_alive(struct net *net)
135{
136 return 1;
137}
138
128static inline struct net *get_net(struct net *net) 139static 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);