aboutsummaryrefslogtreecommitdiffstats
path: root/net/l2tp/l2tp_ppp.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_ppp.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_ppp.c')
-rw-r--r--net/l2tp/l2tp_ppp.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index e5b531266541..63fc62baeeb9 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -305,6 +305,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
305 struct l2tp_session *session; 305 struct l2tp_session *session;
306 struct l2tp_tunnel *tunnel; 306 struct l2tp_tunnel *tunnel;
307 struct pppol2tp_session *ps; 307 struct pppol2tp_session *ps;
308 int uhlen;
308 309
309 error = -ENOTCONN; 310 error = -ENOTCONN;
310 if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED)) 311 if (sock_flag(sk, SOCK_DEAD) || !(sk->sk_state & PPPOX_CONNECTED))
@@ -321,10 +322,12 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
321 if (tunnel == NULL) 322 if (tunnel == NULL)
322 goto error_put_sess; 323 goto error_put_sess;
323 324
325 uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0;
326
324 /* Allocate a socket buffer */ 327 /* Allocate a socket buffer */
325 error = -ENOMEM; 328 error = -ENOMEM;
326 skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) + 329 skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) +
327 sizeof(struct udphdr) + session->hdr_len + 330 uhlen + session->hdr_len +
328 sizeof(ppph) + total_len, 331 sizeof(ppph) + total_len,
329 0, GFP_KERNEL); 332 0, GFP_KERNEL);
330 if (!skb) 333 if (!skb)
@@ -335,7 +338,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
335 skb_reset_network_header(skb); 338 skb_reset_network_header(skb);
336 skb_reserve(skb, sizeof(struct iphdr)); 339 skb_reserve(skb, sizeof(struct iphdr));
337 skb_reset_transport_header(skb); 340 skb_reset_transport_header(skb);
338 skb_reserve(skb, sizeof(struct udphdr)); 341 skb_reserve(skb, uhlen);
339 342
340 /* Add PPP header */ 343 /* Add PPP header */
341 skb->data[0] = ppph[0]; 344 skb->data[0] = ppph[0];