aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_core.h
diff options
context:
space:
mode:
authorTom Parkin <tparkin@katalix.com>2013-03-19 06:11:23 +0000
committerDavid S. Miller <davem@davemloft.net>2013-03-20 12:10:39 -0400
commitf6e16b299bacaa71c6604a784f2d088a966f8c23 (patch)
tree115d199ee9cd9fb9dbc296d3daad259cd9e0d682 /net/l2tp/l2tp_core.h
parentl2tp: avoid deadlock in l2tp stats update (diff)
downloadlinux-dev-f6e16b299bacaa71c6604a784f2d088a966f8c23.tar.xz
linux-dev-f6e16b299bacaa71c6604a784f2d088a966f8c23.zip
l2tp: unhash l2tp sessions on delete, not on free
If we postpone unhashing of l2tp sessions until the structure is freed, we risk: 1. further packets arriving and getting queued while the pseudowire is being closed down 2. the recv path hitting "scheduling while atomic" errors in the case that recv drops the last reference to a session and calls l2tp_session_free while in atomic context As such, l2tp sessions should be unhashed from l2tp_core data structures early in the teardown process prior to calling pseudowire close. For pseudowires like l2tp_ppp which have multiple shutdown codepaths, provide an unhash hook. Signed-off-by: Tom Parkin <tparkin@katalix.com> Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_core.h')
-rw-r--r--net/l2tp/l2tp_core.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index 519b013f8b31..485a490fd990 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -242,6 +242,7 @@ extern int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_i
extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
extern int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
extern struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
+extern void __l2tp_session_unhash(struct l2tp_session *session);
extern int l2tp_session_delete(struct l2tp_session *session);
extern void l2tp_session_free(struct l2tp_session *session);
extern void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb));