|
@@ -628,7 +628,6 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|
{
|
|
{
|
|
struct sock *sk = sock->sk;
|
|
struct sock *sk = sock->sk;
|
|
struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr;
|
|
struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr;
|
|
- struct sockaddr_pppol2tpv3 *sp3 = (struct sockaddr_pppol2tpv3 *) uservaddr;
|
|
|
|
struct pppox_sock *po = pppox_sk(sk);
|
|
struct pppox_sock *po = pppox_sk(sk);
|
|
struct l2tp_session *session = NULL;
|
|
struct l2tp_session *session = NULL;
|
|
struct l2tp_tunnel *tunnel;
|
|
struct l2tp_tunnel *tunnel;
|
|
@@ -657,7 +656,13 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|
if (sk->sk_user_data)
|
|
if (sk->sk_user_data)
|
|
goto end; /* socket is already attached */
|
|
goto end; /* socket is already attached */
|
|
|
|
|
|
- /* Get params from socket address. Handle L2TPv2 and L2TPv3 */
|
|
|
|
|
|
+ /* Get params from socket address. Handle L2TPv2 and L2TPv3.
|
|
|
|
+ * This is nasty because there are different sockaddr_pppol2tp
|
|
|
|
+ * structs for L2TPv2, L2TPv3, over IPv4 and IPv6. We use
|
|
|
|
+ * the sockaddr size to determine which structure the caller
|
|
|
|
+ * is using.
|
|
|
|
+ */
|
|
|
|
+ peer_tunnel_id = 0;
|
|
if (sockaddr_len == sizeof(struct sockaddr_pppol2tp)) {
|
|
if (sockaddr_len == sizeof(struct sockaddr_pppol2tp)) {
|
|
fd = sp->pppol2tp.fd;
|
|
fd = sp->pppol2tp.fd;
|
|
tunnel_id = sp->pppol2tp.s_tunnel;
|
|
tunnel_id = sp->pppol2tp.s_tunnel;
|
|
@@ -665,12 +670,31 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|
session_id = sp->pppol2tp.s_session;
|
|
session_id = sp->pppol2tp.s_session;
|
|
peer_session_id = sp->pppol2tp.d_session;
|
|
peer_session_id = sp->pppol2tp.d_session;
|
|
} else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3)) {
|
|
} else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3)) {
|
|
|
|
+ struct sockaddr_pppol2tpv3 *sp3 =
|
|
|
|
+ (struct sockaddr_pppol2tpv3 *) sp;
|
|
ver = 3;
|
|
ver = 3;
|
|
fd = sp3->pppol2tp.fd;
|
|
fd = sp3->pppol2tp.fd;
|
|
tunnel_id = sp3->pppol2tp.s_tunnel;
|
|
tunnel_id = sp3->pppol2tp.s_tunnel;
|
|
peer_tunnel_id = sp3->pppol2tp.d_tunnel;
|
|
peer_tunnel_id = sp3->pppol2tp.d_tunnel;
|
|
session_id = sp3->pppol2tp.s_session;
|
|
session_id = sp3->pppol2tp.s_session;
|
|
peer_session_id = sp3->pppol2tp.d_session;
|
|
peer_session_id = sp3->pppol2tp.d_session;
|
|
|
|
+ } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpin6)) {
|
|
|
|
+ struct sockaddr_pppol2tpin6 *sp6 =
|
|
|
|
+ (struct sockaddr_pppol2tpin6 *) sp;
|
|
|
|
+ fd = sp6->pppol2tp.fd;
|
|
|
|
+ tunnel_id = sp6->pppol2tp.s_tunnel;
|
|
|
|
+ peer_tunnel_id = sp6->pppol2tp.d_tunnel;
|
|
|
|
+ session_id = sp6->pppol2tp.s_session;
|
|
|
|
+ peer_session_id = sp6->pppol2tp.d_session;
|
|
|
|
+ } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3in6)) {
|
|
|
|
+ struct sockaddr_pppol2tpv3in6 *sp6 =
|
|
|
|
+ (struct sockaddr_pppol2tpv3in6 *) sp;
|
|
|
|
+ ver = 3;
|
|
|
|
+ fd = sp6->pppol2tp.fd;
|
|
|
|
+ tunnel_id = sp6->pppol2tp.s_tunnel;
|
|
|
|
+ peer_tunnel_id = sp6->pppol2tp.d_tunnel;
|
|
|
|
+ session_id = sp6->pppol2tp.s_session;
|
|
|
|
+ peer_session_id = sp6->pppol2tp.d_session;
|
|
} else {
|
|
} else {
|
|
error = -EINVAL;
|
|
error = -EINVAL;
|
|
goto end; /* bad socket address */
|
|
goto end; /* bad socket address */
|
|
@@ -711,12 +735,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
|
|
if (tunnel->recv_payload_hook == NULL)
|
|
if (tunnel->recv_payload_hook == NULL)
|
|
tunnel->recv_payload_hook = pppol2tp_recv_payload_hook;
|
|
tunnel->recv_payload_hook = pppol2tp_recv_payload_hook;
|
|
|
|
|
|
- if (tunnel->peer_tunnel_id == 0) {
|
|
|
|
- if (ver == 2)
|
|
|
|
- tunnel->peer_tunnel_id = sp->pppol2tp.d_tunnel;
|
|
|
|
- else
|
|
|
|
- tunnel->peer_tunnel_id = sp3->pppol2tp.d_tunnel;
|
|
|
|
- }
|
|
|
|
|
|
+ if (tunnel->peer_tunnel_id == 0)
|
|
|
|
+ tunnel->peer_tunnel_id = peer_tunnel_id;
|
|
|
|
|
|
/* Create session if it doesn't already exist. We handle the
|
|
/* Create session if it doesn't already exist. We handle the
|
|
* case where a session was previously created by the netlink
|
|
* case where a session was previously created by the netlink
|