123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- 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.
|