summaryrefslogtreecommitdiff
path: root/net/l2tp/l2tp_ip6.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-03-20 12:10:46 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-20 12:10:46 -0400
commite0ebcb80cbf2022db839186b52f8de4591883559 (patch)
tree115d199ee9cd9fb9dbc296d3daad259cd9e0d682 /net/l2tp/l2tp_ip6.c
parentf1e79e208076ffe7bad97158275f1c572c04f5c7 (diff)
parentf6e16b299bacaa71c6604a784f2d088a966f8c23 (diff)
Merge branch 'l2tp'
Tom Parkin says: ==================== This l2tp bugfix patchset addresses a number of issues. The first five patches in the series prevent l2tp sessions pinning an l2tp tunnel open. This occurs because the l2tp tunnel is torn down in the tunnel socket destructor, but each session holds a tunnel socket reference which prevents tunnels with sessions being deleted. The solution I've implemented here involves adding a .destroy hook to udp code, as discussed previously on netdev[1]. The subsequent seven patches address futher bugs exposed by fixing the problem above, or exposed through stress testing the implementation above. Patch 11 (avoid deadlock in l2tp stats update) isn't directly related to tunnel/session lifetimes, but it does prevent deadlocks on i386 kernels running on 64 bit hardware. This patchset has been tested on 32 and 64 bit preempt/non-preempt kernels, using iproute2, openl2tp, and custom-made stress test code. [1] http://comments.gmane.org/gmane.linux.network/259169 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_ip6.c')
-rw-r--r--net/l2tp/l2tp_ip6.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 41f2f8126ebc..c74f5a91ff6a 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -241,10 +241,17 @@ static void l2tp_ip6_close(struct sock *sk, long timeout)
static void l2tp_ip6_destroy_sock(struct sock *sk)
{
+ struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+
lock_sock(sk);
ip6_flush_pending_frames(sk);
release_sock(sk);
+ if (tunnel) {
+ l2tp_tunnel_closeall(tunnel);
+ sock_put(sk);
+ }
+
inet6_destroy_sock(sk);
}