Commit | Line | Data |
---|---|---|
58e50a90 JC |
1 | This brief document describes how to use the kernel's PPPoL2TP driver |
2 | to provide L2TP functionality. L2TP is a protocol that tunnels one or | |
3 | more PPP sessions over a UDP tunnel. It is commonly used for VPNs | |
4 | (L2TP/IPSec) and by ISPs to tunnel subscriber PPP sessions over an IP | |
5 | network infrastructure. | |
6 | ||
7 | Design | |
8 | ====== | |
9 | ||
10 | The PPPoL2TP driver, drivers/net/pppol2tp.c, provides a mechanism by | |
11 | which PPP frames carried through an L2TP session are passed through | |
12 | the kernel's PPP subsystem. The standard PPP daemon, pppd, handles all | |
13 | PPP interaction with the peer. PPP network interfaces are created for | |
14 | each local PPP endpoint. | |
15 | ||
16 | The L2TP protocol http://www.faqs.org/rfcs/rfc2661.html defines L2TP | |
17 | control and data frames. L2TP control frames carry messages between | |
18 | L2TP clients/servers and are used to setup / teardown tunnels and | |
19 | sessions. An L2TP client or server is implemented in userspace and | |
20 | will use a regular UDP socket per tunnel. L2TP data frames carry PPP | |
21 | frames, which may be PPP control or PPP data. The kernel's PPP | |
22 | subsystem arranges for PPP control frames to be delivered to pppd, | |
23 | while data frames are forwarded as usual. | |
24 | ||
25 | Each tunnel and session within a tunnel is assigned a unique tunnel_id | |
26 | and session_id. These ids are carried in the L2TP header of every | |
27 | control and data packet. The pppol2tp driver uses them to lookup | |
28 | internal tunnel and/or session contexts. Zero tunnel / session ids are | |
29 | treated specially - zero ids are never assigned to tunnels or sessions | |
30 | in the network. In the driver, the tunnel context keeps a pointer to | |
31 | the tunnel UDP socket. The session context keeps a pointer to the | |
32 | PPPoL2TP socket, as well as other data that lets the driver interface | |
33 | to the kernel PPP subsystem. | |
34 | ||
35 | Note that the pppol2tp kernel driver handles only L2TP data frames; | |
36 | L2TP control frames are simply passed up to userspace in the UDP | |
37 | tunnel socket. The kernel handles all datapath aspects of the | |
38 | protocol, including data packet resequencing (if enabled). | |
39 | ||
40 | There are a number of requirements on the userspace L2TP daemon in | |
41 | order to use the pppol2tp driver. | |
42 | ||
43 | 1. Use a UDP socket per tunnel. | |
44 | ||
45 | 2. Create a single PPPoL2TP socket per tunnel bound to a special null | |
46 | session id. This is used only for communicating with the driver but | |
47 | must remain open while the tunnel is active. Opening this tunnel | |
48 | management socket causes the driver to mark the tunnel socket as an | |
49 | L2TP UDP encapsulation socket and flags it for use by the | |
50 | referenced tunnel id. This hooks up the UDP receive path via | |
51 | udp_encap_rcv() in net/ipv4/udp.c. PPP data frames are never passed | |
52 | in this special PPPoX socket. | |
53 | ||
54 | 3. Create a PPPoL2TP socket per L2TP session. This is typically done | |
55 | by starting pppd with the pppol2tp plugin and appropriate | |
56 | arguments. A PPPoL2TP tunnel management socket (Step 2) must be | |
57 | created before the first PPPoL2TP session socket is created. | |
58 | ||
59 | When creating PPPoL2TP sockets, the application provides information | |
60 | to the driver about the socket in a socket connect() call. Source and | |
61 | destination tunnel and session ids are provided, as well as the file | |
62 | descriptor of a UDP socket. See struct pppol2tp_addr in | |
63 | include/linux/if_ppp.h. Note that zero tunnel / session ids are | |
64 | treated specially. When creating the per-tunnel PPPoL2TP management | |
65 | socket in Step 2 above, zero source and destination session ids are | |
66 | specified, which tells the driver to prepare the supplied UDP file | |
67 | descriptor for use as an L2TP tunnel socket. | |
68 | ||
69 | Userspace may control behavior of the tunnel or session using | |
70 | setsockopt and ioctl on the PPPoX socket. The following socket | |
71 | options are supported:- | |
72 | ||
73 | DEBUG - bitmask of debug message categories. See below. | |
74 | SENDSEQ - 0 => don't send packets with sequence numbers | |
75 | 1 => send packets with sequence numbers | |
76 | RECVSEQ - 0 => receive packet sequence numbers are optional | |
77 | 1 => drop receive packets without sequence numbers | |
78 | LNSMODE - 0 => act as LAC. | |
79 | 1 => act as LNS. | |
80 | REORDERTO - reorder timeout (in millisecs). If 0, don't try to reorder. | |
81 | ||
82 | Only the DEBUG option is supported by the special tunnel management | |
83 | PPPoX socket. | |
84 | ||
85 | In addition to the standard PPP ioctls, a PPPIOCGL2TPSTATS is provided | |
86 | to retrieve tunnel and session statistics from the kernel using the | |
87 | PPPoX socket of the appropriate tunnel or session. | |
88 | ||
89 | Debugging | |
90 | ========= | |
91 | ||
92 | The driver supports a flexible debug scheme where kernel trace | |
93 | messages may be optionally enabled per tunnel and per session. Care is | |
94 | needed when debugging a live system since the messages are not | |
95 | rate-limited and a busy system could be swamped. Userspace uses | |
96 | setsockopt on the PPPoX socket to set a debug mask. | |
97 | ||
98 | The following debug mask bits are available: | |
99 | ||
100 | PPPOL2TP_MSG_DEBUG verbose debug (if compiled in) | |
101 | PPPOL2TP_MSG_CONTROL userspace - kernel interface | |
102 | PPPOL2TP_MSG_SEQ sequence numbers handling | |
103 | PPPOL2TP_MSG_DATA data packets | |
104 | ||
105 | Sample Userspace Code | |
106 | ===================== | |
107 | ||
108 | 1. Create tunnel management PPPoX socket | |
109 | ||
110 | kernel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP); | |
111 | if (kernel_fd >= 0) { | |
112 | struct sockaddr_pppol2tp sax; | |
113 | struct sockaddr_in const *peer_addr; | |
114 | ||
115 | peer_addr = l2tp_tunnel_get_peer_addr(tunnel); | |
116 | memset(&sax, 0, sizeof(sax)); | |
117 | sax.sa_family = AF_PPPOX; | |
118 | sax.sa_protocol = PX_PROTO_OL2TP; | |
119 | sax.pppol2tp.fd = udp_fd; /* fd of tunnel UDP socket */ | |
120 | sax.pppol2tp.addr.sin_addr.s_addr = peer_addr->sin_addr.s_addr; | |
121 | sax.pppol2tp.addr.sin_port = peer_addr->sin_port; | |
122 | sax.pppol2tp.addr.sin_family = AF_INET; | |
123 | sax.pppol2tp.s_tunnel = tunnel_id; | |
124 | sax.pppol2tp.s_session = 0; /* special case: mgmt socket */ | |
125 | sax.pppol2tp.d_tunnel = 0; | |
126 | sax.pppol2tp.d_session = 0; /* special case: mgmt socket */ | |
127 | ||
128 | if(connect(kernel_fd, (struct sockaddr *)&sax, sizeof(sax) ) < 0 ) { | |
129 | perror("connect failed"); | |
130 | result = -errno; | |
131 | goto err; | |
132 | } | |
133 | } | |
134 | ||
135 | 2. Create session PPPoX data socket | |
136 | ||
137 | struct sockaddr_pppol2tp sax; | |
138 | int fd; | |
139 | ||
140 | /* Note, the target socket must be bound already, else it will not be ready */ | |
141 | sax.sa_family = AF_PPPOX; | |
142 | sax.sa_protocol = PX_PROTO_OL2TP; | |
143 | sax.pppol2tp.fd = tunnel_fd; | |
144 | sax.pppol2tp.addr.sin_addr.s_addr = addr->sin_addr.s_addr; | |
145 | sax.pppol2tp.addr.sin_port = addr->sin_port; | |
146 | sax.pppol2tp.addr.sin_family = AF_INET; | |
147 | sax.pppol2tp.s_tunnel = tunnel_id; | |
148 | sax.pppol2tp.s_session = session_id; | |
149 | sax.pppol2tp.d_tunnel = peer_tunnel_id; | |
150 | sax.pppol2tp.d_session = peer_session_id; | |
151 | ||
152 | /* session_fd is the fd of the session's PPPoL2TP socket. | |
153 | * tunnel_fd is the fd of the tunnel UDP socket. | |
154 | */ | |
155 | fd = connect(session_fd, (struct sockaddr *)&sax, sizeof(sax)); | |
156 | if (fd < 0 ) { | |
157 | return -errno; | |
158 | } | |
159 | return 0; | |
160 | ||
161 | Miscellanous | |
162 | ============ | |
163 | ||
164 | The PPPoL2TP driver was developed as part of the OpenL2TP project by | |
165 | Katalix Systems Ltd. OpenL2TP is a full-featured L2TP client / server, | |
166 | designed from the ground up to have the L2TP datapath in the | |
167 | kernel. The project also implemented the pppol2tp plugin for pppd | |
168 | which allows pppd to use the kernel driver. Details can be found at | |
169 | http://openl2tp.sourceforge.net. |