Commit cf2f5c88 authored by Tom Parkin's avatar Tom Parkin Committed by David S. Miller

l2tp: push all ppp pseudowire shutdown through .release handler

If userspace deletes a ppp pseudowire using the netlink API, either by
directly deleting the session or by deleting the tunnel that contains the
session, we need to tear down the corresponding pppox channel.

Rather than trying to manage two pppox unbind codepaths, switch the netlink
and l2tp_core session_close handlers to close via. the l2tp_ppp socket
.release handler.
Signed-off-by: default avatarTom Parkin <tparkin@katalix.com>
Signed-off-by: default avatarJames Chapman <jchapman@katalix.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4c6e2fd3
...@@ -97,6 +97,7 @@ ...@@ -97,6 +97,7 @@
#include <net/ip.h> #include <net/ip.h>
#include <net/udp.h> #include <net/udp.h>
#include <net/xfrm.h> #include <net/xfrm.h>
#include <net/inet_common.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <linux/atomic.h> #include <linux/atomic.h>
...@@ -447,34 +448,16 @@ static void pppol2tp_session_close(struct l2tp_session *session) ...@@ -447,34 +448,16 @@ static void pppol2tp_session_close(struct l2tp_session *session)
{ {
struct pppol2tp_session *ps = l2tp_session_priv(session); struct pppol2tp_session *ps = l2tp_session_priv(session);
struct sock *sk = ps->sock; struct sock *sk = ps->sock;
struct sk_buff *skb; struct socket *sock = sk->sk_socket;
BUG_ON(session->magic != L2TP_SESSION_MAGIC); BUG_ON(session->magic != L2TP_SESSION_MAGIC);
if (session->session_id == 0)
goto out;
if (sk != NULL) {
lock_sock(sk);
if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
pppox_unbind_sock(sk);
sk->sk_state = PPPOX_DEAD;
sk->sk_state_change(sk);
}
/* Purge any queued data */
skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_write_queue);
while ((skb = skb_dequeue(&session->reorder_q))) {
kfree_skb(skb);
sock_put(sk);
}
release_sock(sk); if (sock) {
inet_shutdown(sock, 2);
/* Don't let the session go away before our socket does */
l2tp_session_inc_refcount(session);
} }
out:
return; return;
} }
...@@ -525,16 +508,12 @@ static int pppol2tp_release(struct socket *sock) ...@@ -525,16 +508,12 @@ static int pppol2tp_release(struct socket *sock)
session = pppol2tp_sock_to_session(sk); session = pppol2tp_sock_to_session(sk);
/* Purge any queued data */ /* Purge any queued data */
skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_write_queue);
if (session != NULL) { if (session != NULL) {
struct sk_buff *skb; l2tp_session_queue_purge(session);
while ((skb = skb_dequeue(&session->reorder_q))) {
kfree_skb(skb);
sock_put(sk);
}
sock_put(sk); sock_put(sk);
} }
skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_write_queue);
release_sock(sk); release_sock(sk);
...@@ -880,18 +859,6 @@ static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_i ...@@ -880,18 +859,6 @@ static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_i
return error; return error;
} }
/* Called when deleting sessions via the netlink interface.
*/
static int pppol2tp_session_delete(struct l2tp_session *session)
{
struct pppol2tp_session *ps = l2tp_session_priv(session);
if (ps->sock == NULL)
l2tp_session_dec_refcount(session);
return 0;
}
#endif /* CONFIG_L2TP_V3 */ #endif /* CONFIG_L2TP_V3 */
/* getname() support. /* getname() support.
...@@ -1839,7 +1806,7 @@ static const struct pppox_proto pppol2tp_proto = { ...@@ -1839,7 +1806,7 @@ static const struct pppox_proto pppol2tp_proto = {
static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = { static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
.session_create = pppol2tp_session_create, .session_create = pppol2tp_session_create,
.session_delete = pppol2tp_session_delete, .session_delete = l2tp_session_delete,
}; };
#endif /* CONFIG_L2TP_V3 */ #endif /* CONFIG_L2TP_V3 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment