aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_ppp.c
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2012-04-29 17:48:50 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-01 09:30:55 -0400
commitb79585f537ba9631c9b6aafb54a8040c8d515fee (patch)
treea0de8558ab9af6339573408bb2d5a1b4a3f51a20 /net/l2tp/l2tp_ppp.c
parent9d4ec1aeda4a2754681a93029adf89f8f41b9a4d (diff)
l2tp: pppol2tp_connect() handles ipv6 sockaddr variants
Userspace uses connect() to associate a pppol2tp socket with a tunnel socket. This needs to allow the caller to supply the new IPv6 sockaddr_pppol2tp structures if IPv6 is used. Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_ppp.c')
-rw-r--r--net/l2tp/l2tp_ppp.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 27b9dec9d254..9f2c421aa307 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -628,7 +628,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
628{ 628{
629 struct sock *sk = sock->sk; 629 struct sock *sk = sock->sk;
630 struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr; 630 struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr;
631 struct sockaddr_pppol2tpv3 *sp3 = (struct sockaddr_pppol2tpv3 *) uservaddr;
632 struct pppox_sock *po = pppox_sk(sk); 631 struct pppox_sock *po = pppox_sk(sk);
633 struct l2tp_session *session = NULL; 632 struct l2tp_session *session = NULL;
634 struct l2tp_tunnel *tunnel; 633 struct l2tp_tunnel *tunnel;
@@ -657,7 +656,13 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
657 if (sk->sk_user_data) 656 if (sk->sk_user_data)
658 goto end; /* socket is already attached */ 657 goto end; /* socket is already attached */
659 658
660 /* Get params from socket address. Handle L2TPv2 and L2TPv3 */ 659 /* Get params from socket address. Handle L2TPv2 and L2TPv3.
660 * This is nasty because there are different sockaddr_pppol2tp
661 * structs for L2TPv2, L2TPv3, over IPv4 and IPv6. We use
662 * the sockaddr size to determine which structure the caller
663 * is using.
664 */
665 peer_tunnel_id = 0;
661 if (sockaddr_len == sizeof(struct sockaddr_pppol2tp)) { 666 if (sockaddr_len == sizeof(struct sockaddr_pppol2tp)) {
662 fd = sp->pppol2tp.fd; 667 fd = sp->pppol2tp.fd;
663 tunnel_id = sp->pppol2tp.s_tunnel; 668 tunnel_id = sp->pppol2tp.s_tunnel;
@@ -665,12 +670,31 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
665 session_id = sp->pppol2tp.s_session; 670 session_id = sp->pppol2tp.s_session;
666 peer_session_id = sp->pppol2tp.d_session; 671 peer_session_id = sp->pppol2tp.d_session;
667 } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3)) { 672 } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3)) {
673 struct sockaddr_pppol2tpv3 *sp3 =
674 (struct sockaddr_pppol2tpv3 *) sp;
668 ver = 3; 675 ver = 3;
669 fd = sp3->pppol2tp.fd; 676 fd = sp3->pppol2tp.fd;
670 tunnel_id = sp3->pppol2tp.s_tunnel; 677 tunnel_id = sp3->pppol2tp.s_tunnel;
671 peer_tunnel_id = sp3->pppol2tp.d_tunnel; 678 peer_tunnel_id = sp3->pppol2tp.d_tunnel;
672 session_id = sp3->pppol2tp.s_session; 679 session_id = sp3->pppol2tp.s_session;
673 peer_session_id = sp3->pppol2tp.d_session; 680 peer_session_id = sp3->pppol2tp.d_session;
681 } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpin6)) {
682 struct sockaddr_pppol2tpin6 *sp6 =
683 (struct sockaddr_pppol2tpin6 *) sp;
684 fd = sp6->pppol2tp.fd;
685 tunnel_id = sp6->pppol2tp.s_tunnel;
686 peer_tunnel_id = sp6->pppol2tp.d_tunnel;
687 session_id = sp6->pppol2tp.s_session;
688 peer_session_id = sp6->pppol2tp.d_session;
689 } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3in6)) {
690 struct sockaddr_pppol2tpv3in6 *sp6 =
691 (struct sockaddr_pppol2tpv3in6 *) sp;
692 ver = 3;
693 fd = sp6->pppol2tp.fd;
694 tunnel_id = sp6->pppol2tp.s_tunnel;
695 peer_tunnel_id = sp6->pppol2tp.d_tunnel;
696 session_id = sp6->pppol2tp.s_session;
697 peer_session_id = sp6->pppol2tp.d_session;
674 } else { 698 } else {
675 error = -EINVAL; 699 error = -EINVAL;
676 goto end; /* bad socket address */ 700 goto end; /* bad socket address */
@@ -711,12 +735,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
711 if (tunnel->recv_payload_hook == NULL) 735 if (tunnel->recv_payload_hook == NULL)
712 tunnel->recv_payload_hook = pppol2tp_recv_payload_hook; 736 tunnel->recv_payload_hook = pppol2tp_recv_payload_hook;
713 737
714 if (tunnel->peer_tunnel_id == 0) { 738 if (tunnel->peer_tunnel_id == 0)
715 if (ver == 2) 739 tunnel->peer_tunnel_id = peer_tunnel_id;
716 tunnel->peer_tunnel_id = sp->pppol2tp.d_tunnel;
717 else
718 tunnel->peer_tunnel_id = sp3->pppol2tp.d_tunnel;
719 }
720 740
721 /* Create session if it doesn't already exist. We handle the 741 /* Create session if it doesn't already exist. We handle the
722 * case where a session was previously created by the netlink 742 * case where a session was previously created by the netlink