Skip to content

Commit 0d76751

Browse files
j-c-hdavem330
authored andcommitted
l2tp: Add L2TPv3 IP encapsulation (no UDP) support
This patch adds a new L2TPIP socket family and modifies the core to handle the case where there is no UDP header in the L2TP packet. L2TP/IP uses IP protocol 115. Since L2TP/UDP and L2TP/IP packets differ in layout, the datapath packet handling code needs changes too. Userspace uses an L2TPIP socket instead of a UDP socket when IP encapsulation is required. We can't use raw sockets for this because the semantics of raw sockets don't lend themselves to the socket-per-tunnel model - we need to Signed-off-by: David S. Miller <[email protected]>
1 parent e0d4435 commit 0d76751

File tree

7 files changed

+850
-62
lines changed

7 files changed

+850
-62
lines changed

include/linux/l2tp.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* L2TP-over-IP socket for L2TPv3.
3+
*
4+
* Author: James Chapman <[email protected]>
5+
*/
6+
7+
#ifndef _LINUX_L2TP_H_
8+
#define _LINUX_L2TP_H_
9+
10+
#include <linux/types.h>
11+
#ifdef __KERNEL__
12+
#include <linux/socket.h>
13+
#include <linux/in.h>
14+
#endif
15+
16+
#define IPPROTO_L2TP 115
17+
18+
/**
19+
* struct sockaddr_l2tpip - the sockaddr structure for L2TP-over-IP sockets
20+
* @l2tp_family: address family number AF_L2TPIP.
21+
* @l2tp_addr: protocol specific address information
22+
* @l2tp_conn_id: connection id of tunnel
23+
*/
24+
struct sockaddr_l2tpip {
25+
/* The first fields must match struct sockaddr_in */
26+
sa_family_t l2tp_family; /* AF_INET */
27+
__be16 l2tp_unused; /* INET port number (unused) */
28+
struct in_addr l2tp_addr; /* Internet address */
29+
30+
__u32 l2tp_conn_id; /* Connection ID of tunnel */
31+
32+
/* Pad to size of `struct sockaddr'. */
33+
unsigned char __pad[sizeof(struct sockaddr) - sizeof(sa_family_t) -
34+
sizeof(__be16) - sizeof(struct in_addr) -
35+
sizeof(__u32)];
36+
};
37+
38+
#endif

net/l2tp/Kconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,20 @@ config L2TP_V3
5151
If you are connecting to L2TPv3 equipment, or you want to
5252
tunnel raw ethernet frames using L2TP, say Y here. If
5353
unsure, say N.
54+
55+
config L2TP_IP
56+
tristate "L2TP IP encapsulation for L2TPv3"
57+
depends on L2TP_V3
58+
help
59+
Support for L2TP-over-IP socket family.
60+
61+
The L2TPv3 protocol defines two possible encapsulations for
62+
L2TP frames, namely UDP and plain IP (without UDP). This
63+
driver provides a new L2TPIP socket family with which
64+
userspace L2TPv3 daemons may create L2TP/IP tunnel sockets
65+
when UDP encapsulation is not required. When L2TP is carried
66+
in IP packets, it used IP protocol number 115, so this port
67+
must be enabled in firewalls.
68+
69+
To compile this driver as a module, choose M here. The module
70+
will be called l2tp_ip.

net/l2tp/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ obj-$(CONFIG_L2TP) += l2tp_core.o
66

77
# Build l2tp as modules if L2TP is M
88
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_PPPOL2TP)) += l2tp_ppp.o
9+
obj-$(subst y,$(CONFIG_L2TP),$(CONFIG_L2TP_IP)) += l2tp_ip.o

net/l2tp/l2tp_core.c

Lines changed: 103 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
#include <linux/inetdevice.h>
3737
#include <linux/skbuff.h>
3838
#include <linux/init.h>
39+
#include <linux/in.h>
3940
#include <linux/ip.h>
4041
#include <linux/udp.h>
42+
#include <linux/l2tp.h>
4143
#include <linux/hash.h>
4244
#include <linux/sort.h>
4345
#include <linux/file.h>
@@ -48,6 +50,7 @@
4850
#include <net/ip.h>
4951
#include <net/udp.h>
5052
#include <net/xfrm.h>
53+
#include <net/protocol.h>
5154

5255
#include <asm/byteorder.h>
5356
#include <asm/atomic.h>
@@ -849,15 +852,21 @@ static int l2tp_build_l2tpv2_header(struct l2tp_session *session, void *buf)
849852

850853
static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
851854
{
855+
struct l2tp_tunnel *tunnel = session->tunnel;
852856
char *bufp = buf;
853857
char *optr = bufp;
854-
u16 flags = L2TP_HDR_VER_3;
855858

856-
/* Setup L2TP header. */
857-
*((__be16 *) bufp) = htons(flags);
858-
bufp += 2;
859-
*((__be16 *) bufp) = 0;
860-
bufp += 2;
859+
/* Setup L2TP header. The header differs slightly for UDP and
860+
* IP encapsulations. For UDP, there is 4 bytes of flags.
861+
*/
862+
if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
863+
u16 flags = L2TP_HDR_VER_3;
864+
*((__be16 *) bufp) = htons(flags);
865+
bufp += 2;
866+
*((__be16 *) bufp) = 0;
867+
bufp += 2;
868+
}
869+
861870
*((__be32 *) bufp) = htonl(session->peer_session_id);
862871
bufp += 4;
863872
if (session->cookie_len) {
@@ -902,10 +911,11 @@ int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, size_t dat
902911

903912
if (session->debug & L2TP_MSG_DATA) {
904913
int i;
905-
unsigned char *datap = skb->data + sizeof(struct udphdr);
914+
int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
915+
unsigned char *datap = skb->data + uhlen;
906916

907917
printk(KERN_DEBUG "%s: xmit:", session->name);
908-
for (i = 0; i < (len - sizeof(struct udphdr)); i++) {
918+
for (i = 0; i < (len - uhlen); i++) {
909919
printk(" %02X", *datap++);
910920
if (i == 31) {
911921
printk(" ...");
@@ -956,21 +966,23 @@ static inline void l2tp_skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
956966
int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len)
957967
{
958968
int data_len = skb->len;
959-
struct sock *sk = session->tunnel->sock;
969+
struct l2tp_tunnel *tunnel = session->tunnel;
970+
struct sock *sk = tunnel->sock;
960971
struct udphdr *uh;
961-
unsigned int udp_len;
962972
struct inet_sock *inet;
963973
__wsum csum;
964974
int old_headroom;
965975
int new_headroom;
966976
int headroom;
977+
int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
978+
int udp_len;
967979

968980
/* Check that there's enough headroom in the skb to insert IP,
969981
* UDP and L2TP headers. If not enough, expand it to
970982
* make room. Adjust truesize.
971983
*/
972984
headroom = NET_SKB_PAD + sizeof(struct iphdr) +
973-
sizeof(struct udphdr) + hdr_len;
985+
uhlen + hdr_len;
974986
old_headroom = skb_headroom(skb);
975987
if (skb_cow_head(skb, headroom))
976988
goto abort;
@@ -981,18 +993,8 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
981993

982994
/* Setup L2TP header */
983995
session->build_header(session, __skb_push(skb, hdr_len));
984-
udp_len = sizeof(struct udphdr) + hdr_len + data_len;
985-
986-
/* Setup UDP header */
987-
inet = inet_sk(sk);
988-
__skb_push(skb, sizeof(*uh));
989-
skb_reset_transport_header(skb);
990-
uh = udp_hdr(skb);
991-
uh->source = inet->inet_sport;
992-
uh->dest = inet->inet_dport;
993-
uh->len = htons(udp_len);
994-
uh->check = 0;
995996

997+
/* Reset skb netfilter state */
996998
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
997999
IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
9981000
IPSKB_REROUTED);
@@ -1001,29 +1003,48 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
10011003
/* Get routing info from the tunnel socket */
10021004
skb_dst_drop(skb);
10031005
skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
1004-
l2tp_skb_set_owner_w(skb, sk);
10051006

1006-
/* Calculate UDP checksum if configured to do so */
1007-
if (sk->sk_no_check == UDP_CSUM_NOXMIT)
1008-
skb->ip_summed = CHECKSUM_NONE;
1009-
else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
1010-
(!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
1011-
skb->ip_summed = CHECKSUM_COMPLETE;
1012-
csum = skb_checksum(skb, 0, udp_len, 0);
1013-
uh->check = csum_tcpudp_magic(inet->inet_saddr,
1014-
inet->inet_daddr,
1015-
udp_len, IPPROTO_UDP, csum);
1016-
if (uh->check == 0)
1017-
uh->check = CSUM_MANGLED_0;
1018-
} else {
1019-
skb->ip_summed = CHECKSUM_PARTIAL;
1020-
skb->csum_start = skb_transport_header(skb) - skb->head;
1021-
skb->csum_offset = offsetof(struct udphdr, check);
1022-
uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
1023-
inet->inet_daddr,
1024-
udp_len, IPPROTO_UDP, 0);
1007+
switch (tunnel->encap) {
1008+
case L2TP_ENCAPTYPE_UDP:
1009+
/* Setup UDP header */
1010+
inet = inet_sk(sk);
1011+
__skb_push(skb, sizeof(*uh));
1012+
skb_reset_transport_header(skb);
1013+
uh = udp_hdr(skb);
1014+
uh->source = inet->inet_sport;
1015+
uh->dest = inet->inet_dport;
1016+
udp_len = uhlen + hdr_len + data_len;
1017+
uh->len = htons(udp_len);
1018+
uh->check = 0;
1019+
1020+
/* Calculate UDP checksum if configured to do so */
1021+
if (sk->sk_no_check == UDP_CSUM_NOXMIT)
1022+
skb->ip_summed = CHECKSUM_NONE;
1023+
else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
1024+
(!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
1025+
skb->ip_summed = CHECKSUM_COMPLETE;
1026+
csum = skb_checksum(skb, 0, udp_len, 0);
1027+
uh->check = csum_tcpudp_magic(inet->inet_saddr,
1028+
inet->inet_daddr,
1029+
udp_len, IPPROTO_UDP, csum);
1030+
if (uh->check == 0)
1031+
uh->check = CSUM_MANGLED_0;
1032+
} else {
1033+
skb->ip_summed = CHECKSUM_PARTIAL;
1034+
skb->csum_start = skb_transport_header(skb) - skb->head;
1035+
skb->csum_offset = offsetof(struct udphdr, check);
1036+
uh->check = ~csum_tcpudp_magic(inet->inet_saddr,
1037+
inet->inet_daddr,
1038+
udp_len, IPPROTO_UDP, 0);
1039+
}
1040+
break;
1041+
1042+
case L2TP_ENCAPTYPE_IP:
1043+
break;
10251044
}
10261045

1046+
l2tp_skb_set_owner_w(skb, sk);
1047+
10271048
l2tp_xmit_core(session, skb, data_len);
10281049

10291050
abort:
@@ -1053,9 +1074,15 @@ void l2tp_tunnel_destruct(struct sock *sk)
10531074
/* Close all sessions */
10541075
l2tp_tunnel_closeall(tunnel);
10551076

1056-
/* No longer an encapsulation socket. See net/ipv4/udp.c */
1057-
(udp_sk(sk))->encap_type = 0;
1058-
(udp_sk(sk))->encap_rcv = NULL;
1077+
switch (tunnel->encap) {
1078+
case L2TP_ENCAPTYPE_UDP:
1079+
/* No longer an encapsulation socket. See net/ipv4/udp.c */
1080+
(udp_sk(sk))->encap_type = 0;
1081+
(udp_sk(sk))->encap_rcv = NULL;
1082+
break;
1083+
case L2TP_ENCAPTYPE_IP:
1084+
break;
1085+
}
10591086

10601087
/* Remove hooks into tunnel socket */
10611088
tunnel->sock = NULL;
@@ -1168,6 +1195,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
11681195
struct socket *sock = NULL;
11691196
struct sock *sk = NULL;
11701197
struct l2tp_net *pn;
1198+
enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP;
11711199

11721200
/* Get the tunnel socket from the fd, which was opened by
11731201
* the userspace L2TP daemon.
@@ -1182,18 +1210,27 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
11821210

11831211
sk = sock->sk;
11841212

1213+
if (cfg != NULL)
1214+
encap = cfg->encap;
1215+
11851216
/* Quick sanity checks */
1186-
err = -EPROTONOSUPPORT;
1187-
if (sk->sk_protocol != IPPROTO_UDP) {
1188-
printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
1189-
tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
1190-
goto err;
1191-
}
1192-
err = -EAFNOSUPPORT;
1193-
if (sock->ops->family != AF_INET) {
1194-
printk(KERN_ERR "tunl %hu: fd %d wrong family, got %d, expected %d\n",
1195-
tunnel_id, fd, sock->ops->family, AF_INET);
1196-
goto err;
1217+
switch (encap) {
1218+
case L2TP_ENCAPTYPE_UDP:
1219+
err = -EPROTONOSUPPORT;
1220+
if (sk->sk_protocol != IPPROTO_UDP) {
1221+
printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
1222+
tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
1223+
goto err;
1224+
}
1225+
break;
1226+
case L2TP_ENCAPTYPE_IP:
1227+
err = -EPROTONOSUPPORT;
1228+
if (sk->sk_protocol != IPPROTO_L2TP) {
1229+
printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
1230+
tunnel_id, fd, sk->sk_protocol, IPPROTO_L2TP);
1231+
goto err;
1232+
}
1233+
break;
11971234
}
11981235

11991236
/* Check if this socket has already been prepped */
@@ -1223,12 +1260,16 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
12231260
tunnel->l2tp_net = net;
12241261
pn = l2tp_pernet(net);
12251262

1226-
if (cfg)
1263+
if (cfg != NULL)
12271264
tunnel->debug = cfg->debug;
12281265

12291266
/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
1230-
udp_sk(sk)->encap_type = UDP_ENCAP_L2TPINUDP;
1231-
udp_sk(sk)->encap_rcv = l2tp_udp_encap_recv;
1267+
tunnel->encap = encap;
1268+
if (encap == L2TP_ENCAPTYPE_UDP) {
1269+
/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
1270+
udp_sk(sk)->encap_type = UDP_ENCAP_L2TPINUDP;
1271+
udp_sk(sk)->encap_rcv = l2tp_udp_encap_recv;
1272+
}
12321273

12331274
sk->sk_user_data = tunnel;
12341275

@@ -1318,7 +1359,9 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)
13181359
if (session->send_seq)
13191360
session->hdr_len += 4;
13201361
} else {
1321-
session->hdr_len = 8 + session->cookie_len + session->l2specific_len + session->offset;
1362+
session->hdr_len = 4 + session->cookie_len + session->l2specific_len + session->offset;
1363+
if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP)
1364+
session->hdr_len += 4;
13221365
}
13231366

13241367
}

net/l2tp/l2tp_core.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ enum l2tp_l2spec_type {
4848
L2TP_L2SPECTYPE_DEFAULT,
4949
};
5050

51+
enum l2tp_encap_type {
52+
L2TP_ENCAPTYPE_UDP,
53+
L2TP_ENCAPTYPE_IP,
54+
};
55+
5156
struct sk_buff;
5257

5358
struct l2tp_stats {
@@ -155,6 +160,7 @@ struct l2tp_session {
155160
struct l2tp_tunnel_cfg {
156161
int debug; /* bitmask of debug message
157162
* categories */
163+
enum l2tp_encap_type encap;
158164
};
159165

160166
struct l2tp_tunnel {
@@ -170,6 +176,7 @@ struct l2tp_tunnel {
170176
char name[20]; /* for logging */
171177
int debug; /* bitmask of debug message
172178
* categories */
179+
enum l2tp_encap_type encap;
173180
struct l2tp_stats stats;
174181

175182
struct list_head list; /* Keep a list of all tunnels */

0 commit comments

Comments
 (0)