diff options
author | James Chapman <jchapman@katalix.com> | 2010-04-02 06:19:00 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-03 14:56:04 -0700 |
commit | 0d76751fad7739014485ba5bd388d4f1b4fd4143 (patch) | |
tree | 25a4525bf6b2ec9f052f22ba98cdfd3ff3a86aa3 /net/l2tp/l2tp_ppp.c | |
parent | e0d4435f93905f517003cfa7328a36ea19788147 (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.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index e5b53126654..63fc62baeeb 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 struct l2tp_session *session; struct l2tp_tunnel *tunnel; struct pppol2tp_session *ps; + int uhlen; error = -ENOTCONN; 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 if (tunnel == NULL) goto error_put_sess; + uhlen = (tunnel->encap == L2TP_ENCAPTYPE_UDP) ? sizeof(struct udphdr) : 0; + /* Allocate a socket buffer */ error = -ENOMEM; skb = sock_wmalloc(sk, NET_SKB_PAD + sizeof(struct iphdr) + - sizeof(struct udphdr) + session->hdr_len + + uhlen + session->hdr_len + sizeof(ppph) + total_len, 0, GFP_KERNEL); if (!skb) @@ -335,7 +338,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh skb_reset_network_header(skb); skb_reserve(skb, sizeof(struct iphdr)); skb_reset_transport_header(skb); - skb_reserve(skb, sizeof(struct udphdr)); + skb_reserve(skb, uhlen); /* Add PPP header */ skb->data[0] = ppph[0]; |