@@ -291,17 +291,6 @@ static void pppol2tp_session_sock_put(struct l2tp_session *session)
291
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
- */
297
- static 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
294
/* This is the sendmsg for the PPPoL2TP pppol2tp_session socket. We come here
306
295
* when a user application does a sendmsg() on the session socket. L2TP and
307
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
383
static const u8 ppph [2 ] = { 0xff , 0x03 };
395
384
struct sock * sk = (struct sock * ) chan -> private ;
396
385
struct sock * sk_tun ;
397
- int hdr_len ;
398
386
struct l2tp_session * session ;
399
387
struct l2tp_tunnel * tunnel ;
400
388
struct pppol2tp_session * ps ;
@@ -417,9 +405,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
417
405
if (tunnel == NULL )
418
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
408
old_headroom = skb_headroom (skb );
424
409
if (skb_cow_head (skb , sizeof (ppph )))
425
410
goto abort_put_sess_tun ;
@@ -432,7 +417,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
432
417
skb -> data [0 ] = ppph [0 ];
433
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
422
sock_put (sk_tun );
438
423
sock_put (sk );
@@ -615,13 +600,18 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
615
600
{
616
601
struct sock * sk = sock -> sk ;
617
602
struct sockaddr_pppol2tp * sp = (struct sockaddr_pppol2tp * ) uservaddr ;
603
+ struct sockaddr_pppol2tpv3 * sp3 = (struct sockaddr_pppol2tpv3 * ) uservaddr ;
618
604
struct pppox_sock * po = pppox_sk (sk );
619
605
struct l2tp_session * session = NULL ;
620
606
struct l2tp_tunnel * tunnel ;
621
607
struct pppol2tp_session * ps ;
622
608
struct dst_entry * dst ;
623
609
struct l2tp_session_cfg cfg = { 0 , };
624
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
616
lock_sock (sk );
627
617
@@ -639,21 +629,40 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
639
629
if (sk -> sk_user_data )
640
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
652
error = - EINVAL ;
644
- if (sp -> pppol2tp . s_tunnel == 0 )
653
+ if (tunnel_id == 0 )
645
654
goto end ;
646
655
647
- /* Special case: create tunnel context if s_session and
648
- * d_session is 0. Otherwise look up tunnel using supplied
656
+ /* Special case: create tunnel context if session_id and
657
+ * peer_session_id is 0. Otherwise look up tunnel using supplied
649
658
* tunnel id.
650
659
*/
651
- if ((sp -> pppol2tp . s_session == 0 ) && (sp -> pppol2tp . d_session == 0 )) {
652
- error = l2tp_tunnel_create (sock_net (sk ), sp -> pppol2tp . fd , 2 , sp -> pppol2tp . s_tunnel , sp -> pppol2tp . d_tunnel , NULL , & tunnel );
660
+ if ((session_id == 0 ) && (peer_session_id == 0 )) {
661
+ error = l2tp_tunnel_create (sock_net (sk ), fd , ver , tunnel_id , peer_tunnel_id , NULL , & tunnel );
653
662
if (error < 0 )
654
663
goto end ;
655
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
667
/* Error if we can't find the tunnel */
659
668
error = - ENOENT ;
@@ -670,20 +679,21 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
670
679
671
680
/* Check that this session doesn't already exist */
672
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
683
if (session != NULL )
675
684
goto end ;
676
685
677
- /* Default MTU must allow space for UDP/L2TP/PPP
678
- * headers.
679
- */
680
- cfg .mtu = cfg .mru = 1500 - PPPOL2TP_HEADER_OVERHEAD ;
686
+ /* Default MTU values. */
687
+ if (cfg .mtu == 0 )
688
+ cfg .mtu = 1500 - PPPOL2TP_HEADER_OVERHEAD ;
689
+ if (cfg .mru == 0 )
690
+ cfg .mru = cfg .mtu ;
681
691
cfg .debug = tunnel -> debug ;
682
692
683
693
/* Allocate and initialize a new session context. */
684
694
session = l2tp_session_create (sizeof (struct pppol2tp_session ),
685
- tunnel , sp -> pppol2tp . s_session ,
686
- sp -> pppol2tp . d_session , & cfg );
695
+ tunnel , session_id ,
696
+ peer_session_id , & cfg );
687
697
if (session == NULL ) {
688
698
error = - ENOMEM ;
689
699
goto end ;
@@ -756,8 +766,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
756
766
static int pppol2tp_getname (struct socket * sock , struct sockaddr * uaddr ,
757
767
int * usockaddr_len , int peer )
758
768
{
759
- int len = sizeof (struct sockaddr_pppol2tp );
760
- struct sockaddr_pppol2tp sp ;
769
+ int len = 0 ;
761
770
int error = 0 ;
762
771
struct l2tp_session * session ;
763
772
struct l2tp_tunnel * tunnel ;
@@ -783,21 +792,40 @@ static int pppol2tp_getname(struct socket *sock, struct sockaddr *uaddr,
783
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
795
inet = inet_sk (sk );
796
- sp .pppol2tp .addr .sin_family = AF_INET ;
797
- sp .pppol2tp .addr .sin_port = inet -> inet_dport ;
798
- sp .pppol2tp .addr .sin_addr .s_addr = inet -> inet_daddr ;
799
-
800
- memcpy (uaddr , & sp , len );
796
+ if (tunnel -> version == 2 ) {
797
+ struct sockaddr_pppol2tp sp ;
798
+ len = sizeof (sp );
799
+ memset (& sp , 0 , 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
830
* usockaddr_len = len ;
803
831
0 commit comments