aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/net_namespace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-06 18:19:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-06 18:19:59 -0400
commit442bb4bad90134e1c49ffb3ccdefca391ce05600 (patch)
tree2e8796f8193001595e050909b482ac29cba0f1b0 /net/core/net_namespace.c
parent9e441639d1ed78245600191f0fa45e106935a9dc (diff)
parentfde913e25496761a4e2a4c81230c913aba6289a2 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) In TCP, don't register an FRTO for cumulatively ACK'd data that was previously SACK'd, from Neal Cardwell. 2) Need to hold RNL mutex in ipv4 multicast code namespace cleanup, from Cong WANG. 3) Similarly we have to hold RNL mutex for fib_rules_unregister(), also from Cong WANG. 4) Revert and rework netns nsid allocation fix, from Nicolas Dichtel. 5) When we encapsulate for a tunnel device, skb->sk still points to the user socket. So this leads to cases where we retraverse the ipv4/ipv6 output path with skb->sk being of some other address family (f.e. AF_PACKET). This can cause things to crash since the ipv4 output path is dereferencing an AF_PACKET socket as if it were an ipv4 one. The short term fix for 'net' and -stable is to elide these socket checks once we've entered an encapsulation sequence by testing xmit_recursion. Longer term we have a better solution wherein we pass the tunnel's socket down through the output paths, but that is way too invasive for 'net' and -stable. From Hannes Frederic Sowa. 6) l2tp_init() failure path forgets to unregister per-net ops, from Cong WANG. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: net/mlx4_core: Fix error message deprecation for ConnectX-2 cards net: dsa: fix filling routing table from OF description l2tp: unregister l2tp_net_ops on failure path mvneta: dont call mvneta_adjust_link() manually ipv6: protect skb->sk accesses from recursive dereference inside the stack netns: don't allocate an id for dead netns Revert "netns: don't clear nsid too early on removal" ip6mr: call del_timer_sync() in ip6mr_free_table() net: move fib_rules_unregister() under rtnl lock ipv4: take rtnl_lock and mark mrt table as freed on namespace cleanup tcp: fix FRTO undo on cumulative ACK of SACKed range xen-netfront: transmit fully GSO-sized packets
Diffstat (limited to 'net/core/net_namespace.c')
-rw-r--r--net/core/net_namespace.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 5221f975a4cc..70d3450588b2 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -198,8 +198,10 @@ static int __peernet2id(struct net *net, struct net *peer, bool alloc)
198 */ 198 */
199int peernet2id(struct net *net, struct net *peer) 199int peernet2id(struct net *net, struct net *peer)
200{ 200{
201 int id = __peernet2id(net, peer, true); 201 bool alloc = atomic_read(&peer->count) == 0 ? false : true;
202 int id;
202 203
204 id = __peernet2id(net, peer, alloc);
203 return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED; 205 return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED;
204} 206}
205EXPORT_SYMBOL(peernet2id); 207EXPORT_SYMBOL(peernet2id);
@@ -349,7 +351,7 @@ static LIST_HEAD(cleanup_list); /* Must hold cleanup_list_lock to touch */
349static void cleanup_net(struct work_struct *work) 351static void cleanup_net(struct work_struct *work)
350{ 352{
351 const struct pernet_operations *ops; 353 const struct pernet_operations *ops;
352 struct net *net, *tmp, *peer; 354 struct net *net, *tmp;
353 struct list_head net_kill_list; 355 struct list_head net_kill_list;
354 LIST_HEAD(net_exit_list); 356 LIST_HEAD(net_exit_list);
355 357
@@ -365,6 +367,14 @@ static void cleanup_net(struct work_struct *work)
365 list_for_each_entry(net, &net_kill_list, cleanup_list) { 367 list_for_each_entry(net, &net_kill_list, cleanup_list) {
366 list_del_rcu(&net->list); 368 list_del_rcu(&net->list);
367 list_add_tail(&net->exit_list, &net_exit_list); 369 list_add_tail(&net->exit_list, &net_exit_list);
370 for_each_net(tmp) {
371 int id = __peernet2id(tmp, net, false);
372
373 if (id >= 0)
374 idr_remove(&tmp->netns_ids, id);
375 }
376 idr_destroy(&net->netns_ids);
377
368 } 378 }
369 rtnl_unlock(); 379 rtnl_unlock();
370 380
@@ -390,26 +400,12 @@ static void cleanup_net(struct work_struct *work)
390 */ 400 */
391 rcu_barrier(); 401 rcu_barrier();
392 402
393 rtnl_lock();
394 /* Finally it is safe to free my network namespace structure */ 403 /* Finally it is safe to free my network namespace structure */
395 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) { 404 list_for_each_entry_safe(net, tmp, &net_exit_list, exit_list) {
396 /* Unreference net from all peers (no need to loop over
397 * net_exit_list because idr_destroy() will be called for each
398 * element of this list.
399 */
400 for_each_net(peer) {
401 int id = __peernet2id(peer, net, false);
402
403 if (id >= 0)
404 idr_remove(&peer->netns_ids, id);
405 }
406 idr_destroy(&net->netns_ids);
407
408 list_del_init(&net->exit_list); 405 list_del_init(&net->exit_list);
409 put_user_ns(net->user_ns); 406 put_user_ns(net->user_ns);
410 net_drop_ns(net); 407 net_drop_ns(net);
411 } 408 }
412 rtnl_unlock();
413} 409}
414static DECLARE_WORK(net_cleanup_work, cleanup_net); 410static DECLARE_WORK(net_cleanup_work, cleanup_net);
415 411