diff options
author | James Chapman <jchapman@katalix.com> | 2007-06-27 18:53:49 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-11 01:16:18 -0400 |
commit | 58e50a904ec78caf4ca938801c031413b0d3f962 (patch) | |
tree | 73a5443d31a5e0dbb3761fab4c20ce61f7545af5 | |
parent | a6d2370b0839c228ae4e680e75263ecf0a73e251 (diff) |
[L2TP]: Add PPPoL2TP in-kernel documentation
Signed-off-by: James Chapman <jchapman@katalix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | Documentation/networking/l2tp.txt | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/Documentation/networking/l2tp.txt b/Documentation/networking/l2tp.txt new file mode 100644 index 000000000000..2451f551c505 --- /dev/null +++ b/Documentation/networking/l2tp.txt | |||
@@ -0,0 +1,169 @@ | |||
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. | ||