aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Parkin <tparkin@katalix.com>2013-03-19 02:11:21 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-20 12:10:39 -0400
commitcf2f5c886a209377daefd5d2ba0bcd49c3887813 (patch)
tree6504ce7eb6d886aad6536706de9ae9080ea4d342
parent4c6e2fd35460208596fa099ee0750a4b0438aa5c (diff)
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: Tom Parkin <tparkin@katalix.com> Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/l2tp/l2tp_ppp.c53
1 files changed, 10 insertions, 43 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 6a53371dba1f..7e3e16aefcb5 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -97,6 +97,7 @@
97#include <net/ip.h> 97#include <net/ip.h>
98#include <net/udp.h> 98#include <net/udp.h>
99#include <net/xfrm.h> 99#include <net/xfrm.h>
100#include <net/inet_common.h>
100 101
101#include <asm/byteorder.h> 102#include <asm/byteorder.h>
102#include <linux/atomic.h> 103#include <linux/atomic.h>
@@ -447,34 +448,16 @@ static void pppol2tp_session_close(struct l2tp_session *session)
447{ 448{
448 struct pppol2tp_session *ps = l2tp_session_priv(session); 449 struct pppol2tp_session *ps = l2tp_session_priv(session);
449 struct sock *sk = ps->sock; 450 struct sock *sk = ps->sock;
450 struct sk_buff *skb; 451 struct socket *sock = sk->sk_socket;
451 452
452 BUG_ON(session->magic != L2TP_SESSION_MAGIC); 453 BUG_ON(session->magic != L2TP_SESSION_MAGIC);
453 454
454 if (session->session_id == 0)
455 goto out;
456
457 if (sk != NULL) {
458 lock_sock(sk);
459
460 if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
461 pppox_unbind_sock(sk);
462 sk->sk_state = PPPOX_DEAD;
463 sk->sk_state_change(sk);
464 }
465
466 /* Purge any queued data */
467 skb_queue_purge(&sk->sk_receive_queue);
468 skb_queue_purge(&sk->sk_write_queue);
469 while ((skb = skb_dequeue(&session->reorder_q))) {
470 kfree_skb(skb);
471 sock_put(sk);
472 }
473 455
474 release_sock(sk); 456 if (sock) {
457 inet_shutdown(sock, 2);
458 /* Don't let the session go away before our socket does */
459 l2tp_session_inc_refcount(session);
475 } 460 }
476
477out:
478 return; 461 return;
479} 462}
480 463
@@ -525,16 +508,12 @@ static int pppol2tp_release(struct socket *sock)
525 session = pppol2tp_sock_to_session(sk); 508 session = pppol2tp_sock_to_session(sk);
526 509
527 /* Purge any queued data */ 510 /* Purge any queued data */
528 skb_queue_purge(&sk->sk_receive_queue);
529 skb_queue_purge(&sk->sk_write_queue);
530 if (session != NULL) { 511 if (session != NULL) {
531 struct sk_buff *skb; 512 l2tp_session_queue_purge(session);
532 while ((skb = skb_dequeue(&session->reorder_q))) {
533 kfree_skb(skb);
534 sock_put(sk);
535 }
536 sock_put(sk); 513 sock_put(sk);
537 } 514 }
515 skb_queue_purge(&sk->sk_receive_queue);
516 skb_queue_purge(&sk->sk_write_queue);
538 517
539 release_sock(sk); 518 release_sock(sk);
540 519
@@ -880,18 +859,6 @@ out:
880 return error; 859 return error;
881} 860}
882 861
883/* Called when deleting sessions via the netlink interface.
884 */
885static int pppol2tp_session_delete(struct l2tp_session *session)
886{
887 struct pppol2tp_session *ps = l2tp_session_priv(session);
888
889 if (ps->sock == NULL)
890 l2tp_session_dec_refcount(session);
891
892 return 0;
893}
894
895#endif /* CONFIG_L2TP_V3 */ 862#endif /* CONFIG_L2TP_V3 */
896 863
897/* getname() support. 864/* getname() support.
@@ -1839,7 +1806,7 @@ static const struct pppox_proto pppol2tp_proto = {
1839 1806
1840static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = { 1807static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
1841 .session_create = pppol2tp_session_create, 1808 .session_create = pppol2tp_session_create,
1842 .session_delete = pppol2tp_session_delete, 1809 .session_delete = l2tp_session_delete,
1843}; 1810};
1844 1811
1845#endif /* CONFIG_L2TP_V3 */ 1812#endif /* CONFIG_L2TP_V3 */