mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
[L2TP]: Add PPPoL2TP in-kernel documentation
Signed-off-by: James Chapman <jchapman@katalix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a6d2370b08
commit
58e50a904e
169
Documentation/networking/l2tp.txt
Normal file
169
Documentation/networking/l2tp.txt
Normal file
@ -0,0 +1,169 @@
|
||||
This brief document describes how to use the kernel's PPPoL2TP driver
|
||||
to provide L2TP functionality. L2TP is a protocol that tunnels one or
|
||||
more PPP sessions over a UDP tunnel. It is commonly used for VPNs
|
||||
(L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP
|
||||
network infrastructure.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by
|
||||
which PPP frames carried through an L2TP session are passed through
|
||||
the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all
|
||||
PPP interaction with the peer. PPP network interfaces are created for
|
||||
each local PPP endpoint.
|
||||
|
||||
The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP
|
||||
control and data frames. L2TP control frames carry messages between
|
||||
L2TP clients/servers and are used to setup / teardown tunnels and
|
||||
sessions. An L2TP client or server is implemented in userspace and
|
||||
will use a regular UDP socket per tunnel. L2TP data frames carry PPP
|
||||
frames, which may be PPP control or PPP data. The kernel's PPP
|
||||
subsystem arranges for PPP control frames to be delivered to pppd,
|
||||
while data frames are forwarded as usual.
|
||||
|
||||
Each tunnel and session within a tunnel is assigned a unique tunnel_id
|
||||
and session_id. These ids are carried in the L2TP header of every
|
||||
control and data packet. The pppol2tp driver uses them to lookup
|
||||
internal tunnel and/or session contexts. Zero tunnel / session ids are
|
||||
treated specially - zero ids are never assigned to tunnels or sessions
|
||||
in the network. In the driver, the tunnel context keeps a pointer to
|
||||
the tunnel UDP socket. The session context keeps a pointer to the
|
||||
PPPoL2TP socket, as well as other data that lets the driver interface
|
||||
to the kernel PPP subsystem.
|
||||
|
||||
Note that the pppol2tp kernel driver handles only L2TP data frames;
|
||||
L2TP control frames are simply passed up to userspace in the UDP
|
||||
tunnel socket. The kernel handles all datapath aspects of the
|
||||
protocol, including data packet resequencing (if enabled).
|
||||
|
||||
There are a number of requirements on the userspace L2TP daemon in
|
||||
order to use the pppol2tp driver.
|
||||
|
||||
1. Use a UDP socket per tunnel.
|
||||
|
||||
2. Create a single PPPoL2TP socket per tunnel bound to a special null
|
||||
session id. This is used only for communicating with the driver but
|
||||
must remain open while the tunnel is active. Opening this tunnel
|
||||
management socket causes the driver to mark the tunnel socket as an
|
||||
L2TP UDP encapsulation socket and flags it for use by the
|
||||
referenced tunnel id. This hooks up the UDP receive path via
|
||||
udp_encap_rcv() in net/ipv4/udp.c. PPP data frames are never passed
|
||||
in this special PPPoX socket.
|
||||
|
||||
3. Create a PPPoL2TP socket per L2TP session. This is typically done
|
||||
by starting pppd with the pppol2tp plugin and appropriate
|
||||
arguments. A PPPoL2TP tunnel management socket (Step 2) must be
|
||||
created before the first PPPoL2TP session socket is created.
|
||||
|
||||
When creating PPPoL2TP sockets, the application provides information
|
||||
to the driver about the socket in a socket connect() call. Source and
|
||||
destination tunnel and session ids are provided, as well as the file
|
||||
descriptor of a UDP socket. See struct pppol2tp_addr in
|
||||
include/linux/if_ppp.h. Note that zero tunnel / session ids are
|
||||
treated specially. When creating the per-tunnel PPPoL2TP management
|
||||
socket in Step 2 above, zero source and destination session ids are
|
||||
specified, which tells the driver to prepare the supplied UDP file
|
||||
descriptor for use as an L2TP tunnel socket.
|
||||
|
||||
Userspace may control behavior of the tunnel or session using
|
||||
setsockopt and ioctl on the PPPoX socket. The following socket
|
||||
options are supported:-
|
||||
|
||||
DEBUG - bitmask of debug message categories. See below.
|
||||
SENDSEQ - 0 => don't send packets with sequence numbers
|
||||
1 => send packets with sequence numbers
|
||||
RECVSEQ - 0 => receive packet sequence numbers are optional
|
||||
1 => drop receive packets without sequence numbers
|
||||
LNSMODE - 0 => act as LAC.
|
||||
1 => act as LNS.
|
||||
REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder.
|
||||
|
||||
Only the DEBUG option is supported by the special tunnel management
|
||||
PPPoX socket.
|
||||
|
||||
In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided
|
||||
to retrieve tunnel and session statistics from the kernel using the
|
||||
PPPoX socket of the appropriate tunnel or session.
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
The driver supports a flexible debug scheme where kernel trace
|
||||
messages may be optionally enabled per tunnel and per session. Care is
|
||||
needed when debugging a live system since the messages are not
|
||||
rate-limited and a busy system could be swamped. Userspace uses
|
||||
setsockopt on the PPPoX socket to set a debug mask.
|
||||
|
||||
The following debug mask bits are available:
|
||||
|
||||
PPPOL2TP_MSG_DEBUG verbose debug (if compiled in)
|
||||
PPPOL2TP_MSG_CONTROL userspace - kernel interface
|
||||
PPPOL2TP_MSG_SEQ sequence numbers handling
|
||||
PPPOL2TP_MSG_DATA data packets
|
||||
|
||||
Sample Userspace Code
|
||||
=====================
|
||||
|
||||
1. Create tunnel management PPPoX socket
|
||||
|
||||
kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
|
||||
if (kernel_fd >= 0) {
|
||||
struct sockaddr_pppol2tp sax;
|
||||
struct sockaddr_in const *peer_addr;
|
||||
|
||||
peer_addr = l2tp_tunnel_get_peer_addr(tunnel);
|
||||
memset(&sax, 0, sizeof(sax));
|
||||
sax.sa_family = AF_PPPOX;
|
||||
sax.sa_protocol = PX_PROTO_OL2TP;
|
||||
sax.pppol2tp.fd = udp_fd; /* fd of tunnel UDP socket */
|
||||
sax.pppol2tp.addr.sin_addr.s_addr = peer_addr->sin_addr.s_addr;
|
||||
sax.pppol2tp.addr.sin_port = peer_addr->sin_port;
|
||||
sax.pppol2tp.addr.sin_family = AF_INET;
|
||||
sax.pppol2tp.s_tunnel = tunnel_id;
|
||||
sax.pppol2tp.s_session = 0; /* special case: mgmt socket */
|
||||
sax.pppol2tp.d_tunnel = 0;
|
||||
sax.pppol2tp.d_session = 0; /* special case: mgmt socket */
|
||||
|
||||
if(connect(kernel_fd, (struct sockaddr *)&sax, sizeof(sax) ) < 0 ) {
|
||||
perror("connect failed");
|
||||
result = -errno;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
2. Create session PPPoX data socket
|
||||
|
||||
struct sockaddr_pppol2tp sax;
|
||||
int fd;
|
||||
|
||||
/* Note, the target socket must be bound already, else it will not be ready */
|
||||
sax.sa_family = AF_PPPOX;
|
||||
sax.sa_protocol = PX_PROTO_OL2TP;
|
||||
sax.pppol2tp.fd = tunnel_fd;
|
||||
sax.pppol2tp.addr.sin_addr.s_addr = addr->sin_addr.s_addr;
|
||||
sax.pppol2tp.addr.sin_port = addr->sin_port;
|
||||
sax.pppol2tp.addr.sin_family = AF_INET;
|
||||
sax.pppol2tp.s_tunnel = tunnel_id;
|
||||
sax.pppol2tp.s_session = session_id;
|
||||
sax.pppol2tp.d_tunnel = peer_tunnel_id;
|
||||
sax.pppol2tp.d_session = peer_session_id;
|
||||
|
||||
/* session_fd is the fd of the session's PPPoL2TP socket.
|
||||
* tunnel_fd is the fd of the tunnel UDP socket.
|
||||
*/
|
||||
fd = connect(session_fd, (struct sockaddr *)&sax, sizeof(sax));
|
||||
if (fd < 0 ) {
|
||||
return -errno;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Miscellanous
|
||||
============
|
||||
|
||||
The PPPoL2TP driver was developed as part of the OpenL2TP project by
|
||||
Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server,
|
||||
designed from the ground up to have the L2TP datapath in the
|
||||
kernel. The project also implemented the pppol2tp plugin for pppd
|
||||
which allows pppd to use the kernel driver. Details can be found at
|
||||
http://openl2tp.sourceforge.net.
|
Loading…
Reference in New Issue
Block a user