aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net_namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r--net/core/net_namespace.c54
1 files changed, 22 insertions, 32 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index e3bebd36f053..b7292a2719dc 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -115,41 +115,34 @@ static void net_free(struct net *net)
115 kmem_cache_free(net_cachep, net); 115 kmem_cache_free(net_cachep, net);
116} 116}
117 117
118struct net *copy_net_ns(unsigned long flags, struct net *old_net) 118static struct net *net_create(void)
119{ 119{
120 struct net *new_net = NULL; 120 struct net *net;
121 int err; 121 int rv;
122
123 get_net(old_net);
124
125 if (!(flags & CLONE_NEWNET))
126 return old_net;
127
128 err = -ENOMEM;
129 new_net = net_alloc();
130 if (!new_net)
131 goto out_err;
132 122
123 net = net_alloc();
124 if (!net)
125 return ERR_PTR(-ENOMEM);
133 mutex_lock(&net_mutex); 126 mutex_lock(&net_mutex);
134 err = setup_net(new_net); 127 rv = setup_net(net);
135 if (!err) { 128 if (rv == 0) {
136 rtnl_lock(); 129 rtnl_lock();
137 list_add_tail(&new_net->list, &net_namespace_list); 130 list_add_tail(&net->list, &net_namespace_list);
138 rtnl_unlock(); 131 rtnl_unlock();
139 } 132 }
140 mutex_unlock(&net_mutex); 133 mutex_unlock(&net_mutex);
134 if (rv < 0) {
135 net_free(net);
136 return ERR_PTR(rv);
137 }
138 return net;
139}
141 140
142 if (err) 141struct net *copy_net_ns(unsigned long flags, struct net *old_net)
143 goto out_free; 142{
144out: 143 if (!(flags & CLONE_NEWNET))
145 put_net(old_net); 144 return get_net(old_net);
146 return new_net; 145 return net_create();
147
148out_free:
149 net_free(new_net);
150out_err:
151 new_net = ERR_PTR(err);
152 goto out;
153} 146}
154 147
155static void cleanup_net(struct work_struct *work) 148static void cleanup_net(struct work_struct *work)
@@ -203,9 +196,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
203static int __init net_ns_init(void) 196static int __init net_ns_init(void)
204{ 197{
205 struct net_generic *ng; 198 struct net_generic *ng;
206 int err;
207 199
208 printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
209#ifdef CONFIG_NET_NS 200#ifdef CONFIG_NET_NS
210 net_cachep = kmem_cache_create("net_namespace", sizeof(struct net), 201 net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
211 SMP_CACHE_BYTES, 202 SMP_CACHE_BYTES,
@@ -224,15 +215,14 @@ static int __init net_ns_init(void)
224 rcu_assign_pointer(init_net.gen, ng); 215 rcu_assign_pointer(init_net.gen, ng);
225 216
226 mutex_lock(&net_mutex); 217 mutex_lock(&net_mutex);
227 err = setup_net(&init_net); 218 if (setup_net(&init_net))
219 panic("Could not setup the initial network namespace");
228 220
229 rtnl_lock(); 221 rtnl_lock();
230 list_add_tail(&init_net.list, &net_namespace_list); 222 list_add_tail(&init_net.list, &net_namespace_list);
231 rtnl_unlock(); 223 rtnl_unlock();
232 224
233 mutex_unlock(&net_mutex); 225 mutex_unlock(&net_mutex);
234 if (err)
235 panic("Could not setup the initial network namespace");
236 226
237 return 0; 227 return 0;
238} 228}