aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/if_pppol2tp.h14
-rw-r--r--include/linux/if_pppox.h9
-rw-r--r--net/l2tp/l2tp_ppp.c120
3 files changed, 97 insertions, 46 deletions
diff --git a/include/linux/if_pppol2tp.h b/include/linux/if_pppol2tp.h
index 1a1fb6e5d93..184bc556620 100644
--- a/include/linux/if_pppol2tp.h
+++ b/include/linux/if_pppol2tp.h
@@ -35,6 +35,20 @@ struct pppol2tp_addr {
35 __u16 d_tunnel, d_session; /* For sending outgoing packets */ 35 __u16 d_tunnel, d_session; /* For sending outgoing packets */
36}; 36};
37 37
38/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
39 * bits. So we need a different sockaddr structure.
40 */
41struct pppol2tpv3_addr {
42 pid_t pid; /* pid that owns the fd.
43 * 0 => current */
44 int fd; /* FD of UDP or IP socket to use */
45
46 struct sockaddr_in addr; /* IP address and port to send to */
47
48 __u32 s_tunnel, s_session; /* For matching incoming packets */
49 __u32 d_tunnel, d_session; /* For sending outgoing packets */
50};
51
38/* Socket options: 52/* Socket options:
39 * DEBUG - bitmask of debug message categories 53 * DEBUG - bitmask of debug message categories
40 * SENDSEQ - 0 => don't send packets with sequence numbers 54 * SENDSEQ - 0 => don't send packets with sequence numbers
diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
index 90b5fae5d71..a6577af0c4e 100644
--- a/include/linux/if_pppox.h
+++ b/include/linux/if_pppox.h
@@ -72,6 +72,15 @@ struct sockaddr_pppol2tp {
72 struct pppol2tp_addr pppol2tp; 72 struct pppol2tp_addr pppol2tp;
73}__attribute__ ((packed)); 73}__attribute__ ((packed));
74 74
75/* The L2TPv3 protocol changes tunnel and session ids from 16 to 32
76 * bits. So we need a different sockaddr structure.
77 */
78struct sockaddr_pppol2tpv3 {
79 sa_family_t sa_family; /* address family, AF_PPPOX */
80 unsigned int sa_protocol; /* protocol identifier */
81 struct pppol2tpv3_addr pppol2tp;
82} __attribute__ ((packed));
83
75/********************************************************************* 84/*********************************************************************
76 * 85 *
77 * ioctl interface for defining forwarding of connections 86 * ioctl interface for defining forwarding of connections
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index bee5b1413ec..e5b53126654 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -291,17 +291,6 @@ static void pppol2tp_session_sock_put(struct l2tp_session *session)
291 * Transmit handling 291 * Transmit handling
292 ***********************************************************************/ 292 ***********************************************************************/
293 293
294/* Tell how big L2TP headers are for a particular session. This
295 * depends on whether sequence numbers are being used.
296 */
297static inline int pppol2tp_l2tp_header_len(struct l2tp_session *session)
298{
299 if (session->send_seq)
300 return PPPOL2TP_L2TP_HDR_SIZE_SEQ;
301
302 return PPPOL2TP_L2TP_HDR_SIZE_NOSEQ;
303}
304
305/* This is the sendmsg for the PPPoL2TP pppol2tp_session socket. We come here 294/* This is the sendmsg for the PPPoL2TP pppol2tp_session socket. We come here
306 * when a user application does a sendmsg() on the session socket. L2TP and 295 * when a user application does a sendmsg() on the session socket. L2TP and
307 * PPP headers must be inserted into the user's data. 296 * PPP headers must be inserted into the user's data.
@@ -394,7 +383,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
394 static const u8 ppph[2] = { 0xff, 0x03 }; 383 static const u8 ppph[2] = { 0xff, 0x03 };
395 struct sock *sk = (struct sock *) chan->private; 384 struct sock *sk = (struct sock *) chan->private;
396 struct sock *sk_tun; 385 struct sock *sk_tun;
397 int hdr_len;
398 struct l2tp_session *session; 386 struct l2tp_session *session;
399 struct l2tp_tunnel *tunnel; 387 struct l2tp_tunnel *tunnel;
400 struct pppol2tp_session *ps; 388 struct pppol2tp_session *ps;
@@ -417,9 +405,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
417 if (tunnel == NULL) 405 if (tunnel == NULL)
418 goto abort_put_sess; 406 goto abort_put_sess;
419 407
420 /* What header length is configured for this session? */
421 hdr_len = pppol2tp_l2tp_header_len(session);
422
423 old_headroom = skb_headroom(skb); 408 old_headroom = skb_headroom(skb);
424 if (skb_cow_head(skb, sizeof(ppph))) 409 if (skb_cow_head(skb, sizeof(ppph)))
425 goto abort_put_sess_tun; 410 goto abort_put_sess_tun;
@@ -432,7 +417,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
432 skb->data[0] = ppph[0]; 417 skb->data[0] = ppph[0];
433 skb->data[1] = ppph[1]; 418 skb->data[1] = ppph[1];
434 419
435 l2tp_xmit_skb(session, skb, hdr_len); 420 l2tp_xmit_skb(session, skb, session->hdr_len);
436 421
437 sock_put(sk_tun); 422 sock_put(sk_tun);
438 sock_put(sk); 423 sock_put(sk);
@@ -615,6 +600,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
615{ 600{
616 struct sock *sk = sock->sk; 601 struct sock *sk = sock->sk;
617 struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr; 602 struct sockaddr_pppol2tp *sp = (struct sockaddr_pppol2tp *) uservaddr;
603 struct sockaddr_pppol2tpv3 *sp3 = (struct sockaddr_pppol2tpv3 *) uservaddr;
618 struct pppox_sock *po = pppox_sk(sk); 604 struct pppox_sock *po = pppox_sk(sk);
619 struct l2tp_session *session = NULL; 605 struct l2tp_session *session = NULL;
620 struct l2tp_tunnel *tunnel; 606 struct l2tp_tunnel *tunnel;
@@ -622,6 +608,10 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
622 struct dst_entry *dst; 608 struct dst_entry *dst;
623 struct l2tp_session_cfg cfg = { 0, }; 609 struct l2tp_session_cfg cfg = { 0, };
624 int error = 0; 610 int error = 0;
611 u32 tunnel_id, peer_tunnel_id;
612 u32 session_id, peer_session_id;
613 int ver = 2;
614 int fd;
625 615
626 lock_sock(sk); 616 lock_sock(sk);
627 617
@@ -639,21 +629,40 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
639 if (sk->sk_user_data) 629 if (sk->sk_user_data)
640 goto end; /* socket is already attached */ 630 goto end; /* socket is already attached */
641 631
642 /* Don't bind if s_tunnel is 0 */ 632 /* Get params from socket address. Handle L2TPv2 and L2TPv3 */
633 if (sockaddr_len == sizeof(struct sockaddr_pppol2tp)) {
634 fd = sp->pppol2tp.fd;
635 tunnel_id = sp->pppol2tp.s_tunnel;
636 peer_tunnel_id = sp->pppol2tp.d_tunnel;
637 session_id = sp->pppol2tp.s_session;
638 peer_session_id = sp->pppol2tp.d_session;
639 } else if (sockaddr_len == sizeof(struct sockaddr_pppol2tpv3)) {
640 ver = 3;
641 fd = sp3->pppol2tp.fd;
642 tunnel_id = sp3->pppol2tp.s_tunnel;
643 peer_tunnel_id = sp3->pppol2tp.d_tunnel;
644 session_id = sp3->pppol2tp.s_session;
645 peer_session_id = sp3->pppol2tp.d_session;
646 } else {
647 error = -EINVAL;
648 goto end; /* bad socket address */
649 }
650
651 /* Don't bind if tunnel_id is 0 */
643 error = -EINVAL; 652 error = -EINVAL;
644 if (sp->pppol2tp.s_tunnel == 0) 653 if (tunnel_id == 0)
645 goto end; 654 goto end;
646 655
647 /* Special case: create tunnel context if s_session and 656 /* Special case: create tunnel context if session_id and
648 * d_session is 0. Otherwise look up tunnel using supplied 657 * peer_session_id is 0. Otherwise look up tunnel using supplied
649 * tunnel id. 658 * tunnel id.
650 */ 659 */
651 if ((sp->pppol2tp.s_session == 0) && (sp->pppol2tp.d_session == 0)) { 660 if ((session_id == 0) && (peer_session_id == 0)) {
652 error = l2tp_tunnel_create(sock_net(sk), sp->pppol2tp.fd, 2, sp->pppol2tp.s_tunnel, sp->pppol2tp.d_tunnel, NULL, &tunnel); 661 error = l2tp_tunnel_create(sock_net(sk), fd, ver, tunnel_id, peer_tunnel_id, NULL, &tunnel);
653 if (error < 0) 662 if (error < 0)
654 goto end; 663 goto end;
655 } else { 664 } else {
656 tunnel = l2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel); 665 tunnel = l2tp_tunnel_find(sock_net(sk), tunnel_id);
657 666
658 /* Error if we can't find the tunnel */ 667 /* Error if we can't find the tunnel */
659 error = -ENOENT; 668 error = -ENOENT;
@@ -670,20 +679,21 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
670 679
671 /* Check that this session doesn't already exist */ 680 /* Check that this session doesn't already exist */
672 error = -EEXIST; 681 error = -EEXIST;
673 session = l2tp_session_find(sock_net(sk), tunnel, sp->pppol2tp.s_session); 682 session = l2tp_session_find(sock_net(sk), tunnel, session_id);
674 if (session != NULL) 683 if (session != NULL)
675 goto end; 684 goto end;
676 685
677 /* Default MTU must allow space for UDP/L2TP/PPP 686 /* Default MTU values. */
678 * headers. 687 if (cfg.mtu == 0)
679 */ 688 cfg.mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD;
680 cfg.mtu = cfg.mru = 1500 - PPPOL2TP_HEADER_OVERHEAD; 689 if (cfg.mru == 0)
690 cfg.mru = cfg.mtu;
681 cfg.debug = tunnel->debug; 691 cfg.debug = tunnel->debug;
682 692
683 /* Allocate and initialize a new session context. */ 693 /* Allocate and initialize a new session context. */
684 session = l2tp_session_create(sizeof(struct pppol2tp_session), 694 session = l2tp_session_create(sizeof(struct pppol2tp_session),
685 tunnel, sp->pppol2tp.s_session, 695 tunnel, session_id,
686 sp->pppol2tp.d_session, &cfg); 696 peer_session_id, &cfg);
687 if (session == NULL) { 697 if (session == NULL) {
688 error = -ENOMEM; 698 error = -ENOMEM;
689 goto end; 699 goto end;
@@ -756,8 +766,7 @@ end:
756static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr, 766static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
757 int *usockaddr_len, int peer) 767 int *usockaddr_len, int peer)
758{ 768{
759 int len = sizeof(struct sockaddr_pppol2tp); 769 int len = 0;
760 struct sockaddr_pppol2tp sp;
761 int error = 0; 770 int error = 0;
762 struct l2tp_session *session; 771 struct l2tp_session *session;
763 struct l2tp_tunnel *tunnel; 772 struct l2tp_tunnel *tunnel;
@@ -783,21 +792,40 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
783 goto end_put_sess; 792 goto end_put_sess;
784 } 793 }
785 794
786 memset(&sp, 0, len);
787 sp.sa_family = AF_PPPOX;
788 sp.sa_protocol = PX_PROTO_OL2TP;
789 sp.pppol2tp.fd = tunnel->fd;
790 sp.pppol2tp.pid = pls->owner;
791 sp.pppol2tp.s_tunnel = tunnel->tunnel_id;
792 sp.pppol2tp.d_tunnel = tunnel->peer_tunnel_id;
793 sp.pppol2tp.s_session = session->session_id;
794 sp.pppol2tp.d_session = session->peer_session_id;
795 inet = inet_sk(sk); 795 inet = inet_sk(sk);
796 sp.pppol2tp.addr.sin_family = AF_INET; 796 if (tunnel->version == 2) {
797 sp.pppol2tp.addr.sin_port = inet->inet_dport; 797 struct sockaddr_pppol2tp sp;
798 sp.pppol2tp.addr.sin_addr.s_addr = inet->inet_daddr; 798 len = sizeof(sp);
799 799 memset(&sp, 0, len);
800 memcpy(uaddr, &sp, len); 800 sp.sa_family = AF_PPPOX;
801 sp.sa_protocol = PX_PROTO_OL2TP;
802 sp.pppol2tp.fd = tunnel->fd;
803 sp.pppol2tp.pid = pls->owner;
804 sp.pppol2tp.s_tunnel = tunnel->tunnel_id;
805 sp.pppol2tp.d_tunnel = tunnel->peer_tunnel_id;
806 sp.pppol2tp.s_session = session->session_id;
807 sp.pppol2tp.d_session = session->peer_session_id;
808 sp.pppol2tp.addr.sin_family = AF_INET;
809 sp.pppol2tp.addr.sin_port = inet->inet_dport;
810 sp.pppol2tp.addr.sin_addr.s_addr = inet->inet_daddr;
811 memcpy(uaddr, &sp, len);
812 } else if (tunnel->version == 3) {
813 struct sockaddr_pppol2tpv3 sp;
814 len = sizeof(sp);
815 memset(&sp, 0, len);
816 sp.sa_family = AF_PPPOX;
817 sp.sa_protocol = PX_PROTO_OL2TP;
818 sp.pppol2tp.fd = tunnel->fd;
819 sp.pppol2tp.pid = pls->owner;
820 sp.pppol2tp.s_tunnel = tunnel->tunnel_id;
821 sp.pppol2tp.d_tunnel = tunnel->peer_tunnel_id;
822 sp.pppol2tp.s_session = session->session_id;
823 sp.pppol2tp.d_session = session->peer_session_id;
824 sp.pppol2tp.addr.sin_family = AF_INET;
825 sp.pppol2tp.addr.sin_port = inet->inet_dport;
826 sp.pppol2tp.addr.sin_addr.s_addr = inet->inet_daddr;
827 memcpy(uaddr, &sp, len);
828 }
801 829
802 *usockaddr_len = len; 830 *usockaddr_len = len;
803 831