aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_core.c
diff options
context:
space:
mode:
authorJames Chapman <jchapman@katalix.com>2010-04-02 02:19:00 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-03 17:56:04 -0400
commit0d76751fad7739014485ba5bd388d4f1b4fd4143 (patch)
tree25a4525bf6b2ec9f052f22ba98cdfd3ff3a86aa3 /net/l2tp/l2tp_core.c
parente0d4435f93905f517003cfa7328a36ea19788147 (diff)
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 <davem@davemloft.net>
Diffstat (limited to 'net/l2tp/l2tp_core.c')
-rw-r--r--net/l2tp/l2tp_core.c163
1 files changed, 103 insertions, 60 deletions
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 0eee1a65f1b1..1739d04367e4 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -36,8 +36,10 @@
36#include <linux/inetdevice.h> 36#include <linux/inetdevice.h>
37#include <linux/skbuff.h> 37#include <linux/skbuff.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/in.h>
39#include <linux/ip.h> 40#include <linux/ip.h>
40#include <linux/udp.h> 41#include <linux/udp.h>
42#include <linux/l2tp.h>
41#include <linux/hash.h> 43#include <linux/hash.h>
42#include <linux/sort.h> 44#include <linux/sort.h>
43#include <linux/file.h> 45#include <linux/file.h>
@@ -48,6 +50,7 @@
48#include <net/ip.h> 50#include <net/ip.h>
49#include <net/udp.h> 51#include <net/udp.h>
50#include <net/xfrm.h> 52#include <net/xfrm.h>
53#include <net/protocol.h>
51 54
52#include <asm/byteorder.h> 55#include <asm/byteorder.h>
53#include <asm/atomic.h> 56#include <asm/atomic.h>
@@ -849,15 +852,21 @@ static int l2tp_build_l2tpv2_header(struct l2tp_session *session, void *buf)
849 852
850static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) 853static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf)
851{ 854{
855 struct l2tp_tunnel *tunnel = session->tunnel;
852 char *bufp = buf; 856 char *bufp = buf;
853 char *optr = bufp; 857 char *optr = bufp;
854 u16 flags = L2TP_HDR_VER_3;
855 858
856 /* Setup L2TP header. */ 859 /* Setup L2TP header. The header differs slightly for UDP and
857 *((__be16 *) bufp) = htons(flags); 860 * IP encapsulations. For UDP, there is 4 bytes of flags.
858 bufp += 2; 861 */
859 *((__be16 *) bufp) = 0; 862 if (tunnel->encap == L2TP_ENCAPTYPE_UDP) {
860 bufp += 2; 863 u16 flags = L2TP_HDR_VER_3;
864 *((__be16 *) bufp) = htons(flags);
865 bufp += 2;
866 *((__be16 *) bufp) = 0;
867 bufp += 2;
868 }
869
861 *((__be32 *) bufp) = htonl(session->peer_session_id); 870 *((__be32 *) bufp) = htonl(session->peer_session_id);
862 bufp += 4; 871 bufp += 4;
863 if (session->cookie_len) { 872 if (session->cookie_len) {
@@ -902,10 +911,11 @@ int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, size_t dat
902 911
903 if (session->debug & L2TP_MSG_DATA) { 912 if (session->debug & L2TP_MSG_DATA) {
904 int i; 913 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;
906 916
907 printk(KERN_DEBUG "%s: xmit:", session->name); 917 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++) {
909 printk(" %02X", *datap++); 919 printk(" %02X", *datap++);
910 if (i == 31) { 920 if (i == 31) {
911 printk(" ..."); 921 printk(" ...");
@@ -956,21 +966,23 @@ static inline void l2tp_skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
956int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len) 966int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len)
957{ 967{
958 int data_len = skb->len; 968 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;
960 struct udphdr *uh; 971 struct udphdr *uh;
961 unsigned int udp_len;
962 struct inet_sock *inet; 972 struct inet_sock *inet;
963 __wsum csum; 973 __wsum csum;
964 int old_headroom; 974 int old_headroom;
965 int new_headroom; 975 int new_headroom;
966 int headroom; 976 int headroom;
977 int uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
978 int udp_len;
967 979
968 /* Check that there's enough headroom in the skb to insert IP, 980 /* Check that there's enough headroom in the skb to insert IP,
969 * UDP and L2TP headers. If not enough, expand it to 981 * UDP and L2TP headers. If not enough, expand it to
970 * make room. Adjust truesize. 982 * make room. Adjust truesize.
971 */ 983 */
972 headroom = NET_SKB_PAD + sizeof(struct iphdr) + 984 headroom = NET_SKB_PAD + sizeof(struct iphdr) +
973 sizeof(struct udphdr) + hdr_len; 985 uhlen + hdr_len;
974 old_headroom = skb_headroom(skb); 986 old_headroom = skb_headroom(skb);
975 if (skb_cow_head(skb, headroom)) 987 if (skb_cow_head(skb, headroom))
976 goto abort; 988 goto abort;
@@ -981,18 +993,8 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
981 993
982 /* Setup L2TP header */ 994 /* Setup L2TP header */
983 session->build_header(session, __skb_push(skb, hdr_len)); 995 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;
995 996
997 /* Reset skb netfilter state */
996 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 998 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
997 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | 999 IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
998 IPSKB_REROUTED); 1000 IPSKB_REROUTED);
@@ -1001,29 +1003,48 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
1001 /* Get routing info from the tunnel socket */ 1003 /* Get routing info from the tunnel socket */
1002 skb_dst_drop(skb); 1004 skb_dst_drop(skb);
1003 skb_dst_set(skb, dst_clone(__sk_dst_get(sk))); 1005 skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
1004 l2tp_skb_set_owner_w(skb, sk);
1005 1006
1006 /* Calculate UDP checksum if configured to do so */ 1007 switch (tunnel->encap) {
1007 if (sk->sk_no_check == UDP_CSUM_NOXMIT) 1008 case L2TP_ENCAPTYPE_UDP:
1008 skb->ip_summed = CHECKSUM_NONE; 1009 /* Setup UDP header */
1009 else if ((skb_dst(skb) && skb_dst(skb)->dev) && 1010 inet = inet_sk(sk);
1010 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) { 1011 __skb_push(skb, sizeof(*uh));
1011 skb->ip_summed = CHECKSUM_COMPLETE; 1012 skb_reset_transport_header(skb);
1012 csum = skb_checksum(skb, 0, udp_len, 0); 1013 uh = udp_hdr(skb);
1013 uh->check = csum_tcpudp_magic(inet->inet_saddr, 1014 uh->source = inet->inet_sport;
1014 inet->inet_daddr, 1015 uh->dest = inet->inet_dport;
1015 udp_len, IPPROTO_UDP, csum); 1016 udp_len = uhlen + hdr_len + data_len;
1016 if (uh->check == 0) 1017 uh->len = htons(udp_len);
1017 uh->check = CSUM_MANGLED_0; 1018 uh->check = 0;
1018 } else { 1019
1019 skb->ip_summed = CHECKSUM_PARTIAL; 1020 /* Calculate UDP checksum if configured to do so */
1020 skb->csum_start = skb_transport_header(skb) - skb->head; 1021 if (sk->sk_no_check == UDP_CSUM_NOXMIT)
1021 skb->csum_offset = offsetof(struct udphdr, check); 1022 skb->ip_summed = CHECKSUM_NONE;
1022 uh->check = ~csum_tcpudp_magic(inet->inet_saddr, 1023 else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
1023 inet->inet_daddr, 1024 (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
1024 udp_len, IPPROTO_UDP, 0); 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;
1025 } 1044 }
1026 1045
1046 l2tp_skb_set_owner_w(skb, sk);
1047
1027 l2tp_xmit_core(session, skb, data_len); 1048 l2tp_xmit_core(session, skb, data_len);
1028 1049
1029abort: 1050abort:
@@ -1053,9 +1074,15 @@ void l2tp_tunnel_destruct(struct sock *sk)
1053 /* Close all sessions */ 1074 /* Close all sessions */
1054 l2tp_tunnel_closeall(tunnel); 1075 l2tp_tunnel_closeall(tunnel);
1055 1076
1056 /* No longer an encapsulation socket. See net/ipv4/udp.c */ 1077 switch (tunnel->encap) {
1057 (udp_sk(sk))->encap_type = 0; 1078 case L2TP_ENCAPTYPE_UDP:
1058 (udp_sk(sk))->encap_rcv = NULL; 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 }
1059 1086
1060 /* Remove hooks into tunnel socket */ 1087 /* Remove hooks into tunnel socket */
1061 tunnel->sock = NULL; 1088 tunnel->sock = NULL;
@@ -1168,6 +1195,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
1168 struct socket *sock = NULL; 1195 struct socket *sock = NULL;
1169 struct sock *sk = NULL; 1196 struct sock *sk = NULL;
1170 struct l2tp_net *pn; 1197 struct l2tp_net *pn;
1198 enum l2tp_encap_type encap = L2TP_ENCAPTYPE_UDP;
1171 1199
1172 /* Get the tunnel socket from the fd, which was opened by 1200 /* Get the tunnel socket from the fd, which was opened by
1173 * the userspace L2TP daemon. 1201 * the userspace L2TP daemon.
@@ -1182,18 +1210,27 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
1182 1210
1183 sk = sock->sk; 1211 sk = sock->sk;
1184 1212
1213 if (cfg != NULL)
1214 encap = cfg->encap;
1215
1185 /* Quick sanity checks */ 1216 /* Quick sanity checks */
1186 err = -EPROTONOSUPPORT; 1217 switch (encap) {
1187 if (sk->sk_protocol != IPPROTO_UDP) { 1218 case L2TP_ENCAPTYPE_UDP:
1188 printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n", 1219 err = -EPROTONOSUPPORT;
1189 tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP); 1220 if (sk->sk_protocol != IPPROTO_UDP) {
1190 goto err; 1221 printk(KERN_ERR "tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
1191 } 1222 tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
1192 err = -EAFNOSUPPORT; 1223 goto err;
1193 if (sock->ops->family != AF_INET) { 1224 }
1194 printk(KERN_ERR "tunl %hu: fd %d wrong family, got %d, expected %d\n", 1225 break;
1195 tunnel_id, fd, sock->ops->family, AF_INET); 1226 case L2TP_ENCAPTYPE_IP:
1196 goto err; 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;
1197 } 1234 }
1198 1235
1199 /* Check if this socket has already been prepped */ 1236 /* 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
1223 tunnel->l2tp_net = net; 1260 tunnel->l2tp_net = net;
1224 pn = l2tp_pernet(net); 1261 pn = l2tp_pernet(net);
1225 1262
1226 if (cfg) 1263 if (cfg != NULL)
1227 tunnel->debug = cfg->debug; 1264 tunnel->debug = cfg->debug;
1228 1265
1229 /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */ 1266 /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
1230 udp_sk(sk)->encap_type = UDP_ENCAP_L2TPINUDP; 1267 tunnel->encap = encap;
1231 udp_sk(sk)->encap_rcv = l2tp_udp_encap_recv; 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 }
1232 1273
1233 sk->sk_user_data = tunnel; 1274 sk->sk_user_data = tunnel;
1234 1275
@@ -1318,7 +1359,9 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version)
1318 if (session->send_seq) 1359 if (session->send_seq)
1319 session->hdr_len += 4; 1360 session->hdr_len += 4;
1320 } else { 1361 } 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;
1322 } 1365 }
1323 1366
1324} 1367}