123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677 |
- .. SPDX-License-Identifier: GPL-2.0
- ====
- L2TP
- ====
- Layer 2 Tunneling Protocol (L2TP) allows L2 frames to be tunneled over
- an IP network.
- This document covers the kernel's L2TP subsystem. It documents kernel
- APIs for application developers who want to use the L2TP subsystem and
- it provides some technical details about the internal implementation
- which may be useful to kernel developers and maintainers.
- Overview
- ========
- The kernel's L2TP subsystem implements the datapath for L2TPv2 and
- L2TPv3. L2TPv2 is carried over UDP. L2TPv3 is carried over UDP or
- directly over IP (protocol 115).
- The L2TP RFCs define two basic kinds of L2TP packets: control packets
- (the "control plane"), and data packets (the "data plane"). The kernel
- deals only with data packets. The more complex control packets are
- handled by user space.
- An L2TP tunnel carries one or more L2TP sessions. Each tunnel is
- associated with a socket. Each session is associated with a virtual
- netdevice, e.g. ``pppN``, ``l2tpethN``, through which data frames pass
- to/from L2TP. Fields in the L2TP header identify the tunnel or session
- and whether it is a control or data packet. When tunnels and sessions
- are set up using the Linux kernel API, we're just setting up the L2TP
- data path. All aspects of the control protocol are to be handled by
- user space.
- This split in responsibilities leads to a natural sequence of
- operations when establishing tunnels and sessions. The procedure looks
- like this:
- 1) Create a tunnel socket. Exchange L2TP control protocol messages
- with the peer over that socket in order to establish a tunnel.
- 2) Create a tunnel context in the kernel, using information
- obtained from the peer using the control protocol messages.
- 3) Exchange L2TP control protocol messages with the peer over the
- tunnel socket in order to establish a session.
- 4) Create a session context in the kernel using information
- obtained from the peer using the control protocol messages.
- L2TP APIs
- =========
- This section documents each userspace API of the L2TP subsystem.
- Tunnel Sockets
- --------------
- L2TPv2 always uses UDP. L2TPv3 may use UDP or IP encapsulation.
- To create a tunnel socket for use by L2TP, the standard POSIX
- socket API is used.
- For example, for a tunnel using IPv4 addresses and UDP encapsulation::
- int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- Or for a tunnel using IPv6 addresses and IP encapsulation::
- int sockfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_L2TP);
- UDP socket programming doesn't need to be covered here.
- IPPROTO_L2TP is an IP protocol type implemented by the kernel's L2TP
- subsystem. The L2TPIP socket address is defined in struct
- sockaddr_l2tpip and struct sockaddr_l2tpip6 at
- `include/uapi/linux/l2tp.h`_. The address includes the L2TP tunnel
- (connection) id. To use L2TP IP encapsulation, an L2TPv3 application
- should bind the L2TPIP socket using the locally assigned
- tunnel id. When the peer's tunnel id and IP address is known, a
- connect must be done.
- If the L2TP application needs to handle L2TPv3 tunnel setup requests
- from peers using L2TPIP, it must open a dedicated L2TPIP
- socket to listen for those requests and bind the socket using tunnel
- id 0 since tunnel setup requests are addressed to tunnel id 0.
- An L2TP tunnel and all of its sessions are automatically closed when
- its tunnel socket is closed.
- Netlink API
- -----------
- L2TP applications use netlink to manage L2TP tunnel and session
- instances in the kernel. The L2TP netlink API is defined in
- `include/uapi/linux/l2tp.h`_.
- L2TP uses `Generic Netlink`_ (GENL). Several commands are defined:
- Create, Delete, Modify and Get for tunnel and session
- instances, e.g. ``L2TP_CMD_TUNNEL_CREATE``. The API header lists the
- netlink attribute types that can be used with each command.
- Tunnel and session instances are identified by a locally unique
- 32-bit id. L2TP tunnel ids are given by ``L2TP_ATTR_CONN_ID`` and
- ``L2TP_ATTR_PEER_CONN_ID`` attributes and L2TP session ids are given
- by ``L2TP_ATTR_SESSION_ID`` and ``L2TP_ATTR_PEER_SESSION_ID``
- attributes. If netlink is used to manage L2TPv2 tunnel and session
- instances, the L2TPv2 16-bit tunnel/session id is cast to a 32-bit
- value in these attributes.
- In the ``L2TP_CMD_TUNNEL_CREATE`` command, ``L2TP_ATTR_FD`` tells the
- kernel the tunnel socket fd being used. If not specified, the kernel
- creates a kernel socket for the tunnel, using IP parameters set in
- ``L2TP_ATTR_IP[6]_SADDR``, ``L2TP_ATTR_IP[6]_DADDR``,
- ``L2TP_ATTR_UDP_SPORT``, ``L2TP_ATTR_UDP_DPORT`` attributes. Kernel
- sockets are used to implement unmanaged L2TPv3 tunnels (iproute2's "ip
- l2tp" commands). If ``L2TP_ATTR_FD`` is given, it must be a socket fd
- that is already bound and connected. There is more information about
- unmanaged tunnels later in this document.
- ``L2TP_CMD_TUNNEL_CREATE`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID Y Sets the tunnel (connection) id.
- PEER_CONN_ID Y Sets the peer tunnel (connection) id.
- PROTO_VERSION Y Protocol version. 2 or 3.
- ENCAP_TYPE Y Encapsulation type: UDP or IP.
- FD N Tunnel socket file descriptor.
- UDP_CSUM N Enable IPv4 UDP checksums. Used only if FD is
- not set.
- UDP_ZERO_CSUM6_TX N Zero IPv6 UDP checksum on transmit. Used only
- if FD is not set.
- UDP_ZERO_CSUM6_RX N Zero IPv6 UDP checksum on receive. Used only if
- FD is not set.
- IP_SADDR N IPv4 source address. Used only if FD is not
- set.
- IP_DADDR N IPv4 destination address. Used only if FD is
- not set.
- UDP_SPORT N UDP source port. Used only if FD is not set.
- UDP_DPORT N UDP destination port. Used only if FD is not
- set.
- IP6_SADDR N IPv6 source address. Used only if FD is not
- set.
- IP6_DADDR N IPv6 destination address. Used only if FD is
- not set.
- DEBUG N Debug flags.
- ================== ======== ===
- ``L2TP_CMD_TUNNEL_DESTROY`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID Y Identifies the tunnel id to be destroyed.
- ================== ======== ===
- ``L2TP_CMD_TUNNEL_MODIFY`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID Y Identifies the tunnel id to be modified.
- DEBUG N Debug flags.
- ================== ======== ===
- ``L2TP_CMD_TUNNEL_GET`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID N Identifies the tunnel id to be queried.
- Ignored in DUMP requests.
- ================== ======== ===
- ``L2TP_CMD_SESSION_CREATE`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID Y The parent tunnel id.
- SESSION_ID Y Sets the session id.
- PEER_SESSION_ID Y Sets the parent session id.
- PW_TYPE Y Sets the pseudowire type.
- DEBUG N Debug flags.
- RECV_SEQ N Enable rx data sequence numbers.
- SEND_SEQ N Enable tx data sequence numbers.
- LNS_MODE N Enable LNS mode (auto-enable data sequence
- numbers).
- RECV_TIMEOUT N Timeout to wait when reordering received
- packets.
- L2SPEC_TYPE N Sets layer2-specific-sublayer type (L2TPv3
- only).
- COOKIE N Sets optional cookie (L2TPv3 only).
- PEER_COOKIE N Sets optional peer cookie (L2TPv3 only).
- IFNAME N Sets interface name (L2TPv3 only).
- ================== ======== ===
- For Ethernet session types, this will create an l2tpeth virtual
- interface which can then be configured as required. For PPP session
- types, a PPPoL2TP socket must also be opened and connected, mapping it
- onto the new session. This is covered in "PPPoL2TP Sockets" later.
- ``L2TP_CMD_SESSION_DESTROY`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID Y Identifies the parent tunnel id of the session
- to be destroyed.
- SESSION_ID Y Identifies the session id to be destroyed.
- IFNAME N Identifies the session by interface name. If
- set, this overrides any CONN_ID and SESSION_ID
- attributes. Currently supported for L2TPv3
- Ethernet sessions only.
- ================== ======== ===
- ``L2TP_CMD_SESSION_MODIFY`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID Y Identifies the parent tunnel id of the session
- to be modified.
- SESSION_ID Y Identifies the session id to be modified.
- IFNAME N Identifies the session by interface name. If
- set, this overrides any CONN_ID and SESSION_ID
- attributes. Currently supported for L2TPv3
- Ethernet sessions only.
- DEBUG N Debug flags.
- RECV_SEQ N Enable rx data sequence numbers.
- SEND_SEQ N Enable tx data sequence numbers.
- LNS_MODE N Enable LNS mode (auto-enable data sequence
- numbers).
- RECV_TIMEOUT N Timeout to wait when reordering received
- packets.
- ================== ======== ===
- ``L2TP_CMD_SESSION_GET`` attributes:-
- ================== ======== ===
- Attribute Required Use
- ================== ======== ===
- CONN_ID N Identifies the tunnel id to be queried.
- Ignored for DUMP requests.
- SESSION_ID N Identifies the session id to be queried.
- Ignored for DUMP requests.
- IFNAME N Identifies the session by interface name.
- If set, this overrides any CONN_ID and
- SESSION_ID attributes. Ignored for DUMP
- requests. Currently supported for L2TPv3
- Ethernet sessions only.
- ================== ======== ===
- Application developers should refer to `include/uapi/linux/l2tp.h`_ for
- netlink command and attribute definitions.
- Sample userspace code using libmnl_:
- - Open L2TP netlink socket::
- struct nl_sock *nl_sock;
- int l2tp_nl_family_id;
- nl_sock = nl_socket_alloc();
- genl_connect(nl_sock);
- genl_id = genl_ctrl_resolve(nl_sock, L2TP_GENL_NAME);
- - Create a tunnel::
- struct nlmsghdr *nlh;
- struct genlmsghdr *gnlh;
- nlh = mnl_nlmsg_put_header(buf);
- nlh->nlmsg_type = genl_id; /* assigned to genl socket */
- nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- nlh->nlmsg_seq = seq;
- gnlh = mnl_nlmsg_put_extra_header(nlh, sizeof(*gnlh));
- gnlh->cmd = L2TP_CMD_TUNNEL_CREATE;
- gnlh->version = L2TP_GENL_VERSION;
- gnlh->reserved = 0;
- mnl_attr_put_u32(nlh, L2TP_ATTR_FD, tunl_sock_fd);
- mnl_attr_put_u32(nlh, L2TP_ATTR_CONN_ID, tid);
- mnl_attr_put_u32(nlh, L2TP_ATTR_PEER_CONN_ID, peer_tid);
- mnl_attr_put_u8(nlh, L2TP_ATTR_PROTO_VERSION, protocol_version);
- mnl_attr_put_u16(nlh, L2TP_ATTR_ENCAP_TYPE, encap);
- - Create a session::
- struct nlmsghdr *nlh;
- struct genlmsghdr *gnlh;
- nlh = mnl_nlmsg_put_header(buf);
- nlh->nlmsg_type = genl_id; /* assigned to genl socket */
- nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- nlh->nlmsg_seq = seq;
- gnlh = mnl_nlmsg_put_extra_header(nlh, sizeof(*gnlh));
- gnlh->cmd = L2TP_CMD_SESSION_CREATE;
- gnlh->version = L2TP_GENL_VERSION;
- gnlh->reserved = 0;
- mnl_attr_put_u32(nlh, L2TP_ATTR_CONN_ID, tid);
- mnl_attr_put_u32(nlh, L2TP_ATTR_PEER_CONN_ID, peer_tid);
- mnl_attr_put_u32(nlh, L2TP_ATTR_SESSION_ID, sid);
- mnl_attr_put_u32(nlh, L2TP_ATTR_PEER_SESSION_ID, peer_sid);
- mnl_attr_put_u16(nlh, L2TP_ATTR_PW_TYPE, pwtype);
- /* there are other session options which can be set using netlink
- * attributes during session creation -- see l2tp.h
- */
- - Delete a session::
- struct nlmsghdr *nlh;
- struct genlmsghdr *gnlh;
- nlh = mnl_nlmsg_put_header(buf);
- nlh->nlmsg_type = genl_id; /* assigned to genl socket */
- nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- nlh->nlmsg_seq = seq;
- gnlh = mnl_nlmsg_put_extra_header(nlh, sizeof(*gnlh));
- gnlh->cmd = L2TP_CMD_SESSION_DELETE;
- gnlh->version = L2TP_GENL_VERSION;
- gnlh->reserved = 0;
- mnl_attr_put_u32(nlh, L2TP_ATTR_CONN_ID, tid);
- mnl_attr_put_u32(nlh, L2TP_ATTR_SESSION_ID, sid);
- - Delete a tunnel and all of its sessions (if any)::
- struct nlmsghdr *nlh;
- struct genlmsghdr *gnlh;
- nlh = mnl_nlmsg_put_header(buf);
- nlh->nlmsg_type = genl_id; /* assigned to genl socket */
- nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- nlh->nlmsg_seq = seq;
- gnlh = mnl_nlmsg_put_extra_header(nlh, sizeof(*gnlh));
- gnlh->cmd = L2TP_CMD_TUNNEL_DELETE;
- gnlh->version = L2TP_GENL_VERSION;
- gnlh->reserved = 0;
- mnl_attr_put_u32(nlh, L2TP_ATTR_CONN_ID, tid);
- PPPoL2TP Session Socket API
- ---------------------------
- For PPP session types, a PPPoL2TP socket must be opened and connected
- to the L2TP session.
- When creating PPPoL2TP sockets, the application provides information
- to the kernel about the tunnel and session in a socket connect()
- call. Source and destination tunnel and session ids are provided, as
- well as the file descriptor of a UDP or L2TPIP socket. See struct
- pppol2tp_addr in `include/linux/if_pppol2tp.h`_. For historical reasons,
- there are unfortunately slightly different address structures for
- L2TPv2/L2TPv3 IPv4/IPv6 tunnels and userspace must use the appropriate
- structure that matches the tunnel socket type.
- 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.
- ========= ===========================================================
- 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.
- Sample userspace code:
- - Create session PPPoX data socket::
- struct sockaddr_pppol2tp sax;
- int fd;
- /* Note, the tunnel 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 / L2TPIP socket.
- */
- fd = connect(session_fd, (struct sockaddr *)&sax, sizeof(sax));
- if (fd < 0 ) {
- return -errno;
- }
- return 0;
- Old L2TPv2-only API
- -------------------
- When L2TP was first added to the Linux kernel in 2.6.23, it
- implemented only L2TPv2 and did not include a netlink API. Instead,
- tunnel and session instances in the kernel were managed directly using
- only PPPoL2TP sockets. The PPPoL2TP socket is used as described in
- section "PPPoL2TP Session Socket API" but tunnel and session instances
- are automatically created on a connect() of the socket instead of
- being created by a separate netlink request:
- - Tunnels are managed using a tunnel management socket which is a
- dedicated PPPoL2TP socket, connected to (invalid) session
- id 0. The L2TP tunnel instance is created when the PPPoL2TP
- tunnel management socket is connected and is destroyed when the
- socket is closed.
- - Session instances are created in the kernel when a PPPoL2TP
- socket is connected to a non-zero session id. Session parameters
- are set using setsockopt. The L2TP session instance is destroyed
- when the socket is closed.
- This API is still supported but its use is discouraged. Instead, new
- L2TPv2 applications should use netlink to first create the tunnel and
- session, then create a PPPoL2TP socket for the session.
- Unmanaged L2TPv3 tunnels
- ------------------------
- The kernel L2TP subsystem also supports static (unmanaged) L2TPv3
- tunnels. Unmanaged tunnels have no userspace tunnel socket, and
- exchange no control messages with the peer to set up the tunnel; the
- tunnel is configured manually at each end of the tunnel. All
- configuration is done using netlink. There is no need for an L2TP
- userspace application in this case -- the tunnel socket is created by
- the kernel and configured using parameters sent in the
- ``L2TP_CMD_TUNNEL_CREATE`` netlink request. The ``ip`` utility of
- ``iproute2`` has commands for managing static L2TPv3 tunnels; do ``ip
- l2tp help`` for more information.
- Debugging
- ---------
- The L2TP subsystem offers a range of debugging interfaces through the
- debugfs filesystem.
- To access these interfaces, the debugfs filesystem must first be mounted::
- # mount -t debugfs debugfs /debug
- Files under the l2tp directory can then be accessed, providing a summary
- of the current population of tunnel and session contexts existing in the
- kernel::
- # cat /debug/l2tp/tunnels
- The debugfs files should not be used by applications to obtain L2TP
- state information because the file format is subject to change. It is
- implemented to provide extra debug information to help diagnose
- problems. Applications should instead use the netlink API.
- In addition the L2TP subsystem implements tracepoints using the standard
- kernel event tracing API. The available L2TP events can be reviewed as
- follows::
- # find /debug/tracing/events/l2tp
- Finally, /proc/net/pppol2tp is also provided for backwards compatibility
- with the original pppol2tp code. It lists information about L2TPv2
- tunnels and sessions only. Its use is discouraged.
- Internal Implementation
- =======================
- This section is for kernel developers and maintainers.
- Sockets
- -------
- UDP sockets are implemented by the networking core. When an L2TP
- tunnel is created using a UDP socket, the socket is set up as an
- encapsulated UDP socket by setting encap_rcv and encap_destroy
- callbacks on the UDP socket. l2tp_udp_encap_recv is called when
- packets are received on the socket. l2tp_udp_encap_destroy is called
- when userspace closes the socket.
- L2TPIP sockets are implemented in `net/l2tp/l2tp_ip.c`_ and
- `net/l2tp/l2tp_ip6.c`_.
- Tunnels
- -------
- The kernel keeps a struct l2tp_tunnel context per L2TP tunnel. The
- l2tp_tunnel is always associated with a UDP or L2TP/IP socket and
- keeps a list of sessions in the tunnel. When a tunnel is first
- registered with L2TP core, the reference count on the socket is
- increased. This ensures that the socket cannot be removed while L2TP's
- data structures reference it.
- Tunnels are identified by a unique tunnel id. The id is 16-bit for
- L2TPv2 and 32-bit for L2TPv3. Internally, the id is stored as a 32-bit
- value.
- Tunnels are kept in a per-net list, indexed by tunnel id. The tunnel
- id namespace is shared by L2TPv2 and L2TPv3. The tunnel context can be
- derived from the socket's sk_user_data.
- Handling tunnel socket close is perhaps the most tricky part of the
- L2TP implementation. If userspace closes a tunnel socket, the L2TP
- tunnel and all of its sessions must be closed and destroyed. Since the
- tunnel context holds a ref on the tunnel socket, the socket's
- sk_destruct won't be called until the tunnel sock_put's its
- socket. For UDP sockets, when userspace closes the tunnel socket, the
- socket's encap_destroy handler is invoked, which L2TP uses to initiate
- its tunnel close actions. For L2TPIP sockets, the socket's close
- handler initiates the same tunnel close actions. All sessions are
- first closed. Each session drops its tunnel ref. When the tunnel ref
- reaches zero, the tunnel puts its socket ref. When the socket is
- eventually destroyed, it's sk_destruct finally frees the L2TP tunnel
- context.
- Sessions
- --------
- The kernel keeps a struct l2tp_session context for each session. Each
- session has private data which is used for data specific to the
- session type. With L2TPv2, the session always carries PPP
- traffic. With L2TPv3, the session can carry Ethernet frames (Ethernet
- pseudowire) or other data types such as PPP, ATM, HDLC or Frame
- Relay. Linux currently implements only Ethernet and PPP session types.
- Some L2TP session types also have a socket (PPP pseudowires) while
- others do not (Ethernet pseudowires). We can't therefore use the
- socket reference count as the reference count for session
- contexts. The L2TP implementation therefore has its own internal
- reference counts on the session contexts.
- Like tunnels, L2TP sessions are identified by a unique
- session id. Just as with tunnel ids, the session id is 16-bit for
- L2TPv2 and 32-bit for L2TPv3. Internally, the id is stored as a 32-bit
- value.
- Sessions hold a ref on their parent tunnel to ensure that the tunnel
- stays extant while one or more sessions references it.
- Sessions are kept in a per-tunnel list, indexed by session id. L2TPv3
- sessions are also kept in a per-net list indexed by session id,
- because L2TPv3 session ids are unique across all tunnels and L2TPv3
- data packets do not contain a tunnel id in the header. This list is
- therefore needed to find the session context associated with a
- received data packet when the tunnel context cannot be derived from
- the tunnel socket.
- Although the L2TPv3 RFC specifies that L2TPv3 session ids are not
- scoped by the tunnel, the kernel does not police this for L2TPv3 UDP
- tunnels and does not add sessions of L2TPv3 UDP tunnels into the
- per-net session list. In the UDP receive code, we must trust that the
- tunnel can be identified using the tunnel socket's sk_user_data and
- lookup the session in the tunnel's session list instead of the per-net
- session list.
- PPP
- ---
- `net/l2tp/l2tp_ppp.c`_ implements the PPPoL2TP socket family. Each PPP
- session has a PPPoL2TP socket.
- The PPPoL2TP socket's sk_user_data references the l2tp_session.
- Userspace sends and receives PPP packets over L2TP using a PPPoL2TP
- socket. Only PPP control frames pass over this socket: PPP data
- packets are handled entirely by the kernel, passing between the L2TP
- session and its associated ``pppN`` netdev through the PPP channel
- interface of the kernel PPP subsystem.
- The L2TP PPP implementation handles the closing of a PPPoL2TP socket
- by closing its corresponding L2TP session. This is complicated because
- it must consider racing with netlink session create/destroy requests
- and pppol2tp_connect trying to reconnect with a session that is in the
- process of being closed. Unlike tunnels, PPP sessions do not hold a
- ref on their associated socket, so code must be careful to sock_hold
- the socket where necessary. For all the details, see commit
- 3d609342cc04129ff7568e19316ce3d7451a27e8.
- Ethernet
- --------
- `net/l2tp/l2tp_eth.c`_ implements L2TPv3 Ethernet pseudowires. It
- manages a netdev for each session.
- L2TP Ethernet sessions are created and destroyed by netlink request,
- or are destroyed when the tunnel is destroyed. Unlike PPP sessions,
- Ethernet sessions do not have an associated socket.
- Miscellaneous
- =============
- RFCs
- ----
- The kernel code implements the datapath features specified in the
- following RFCs:
- ======= =============== ===================================
- RFC2661 L2TPv2 https://tools.ietf.org/html/rfc2661
- RFC3931 L2TPv3 https://tools.ietf.org/html/rfc3931
- RFC4719 L2TPv3 Ethernet https://tools.ietf.org/html/rfc4719
- ======= =============== ===================================
- Implementations
- ---------------
- A number of open source applications use the L2TP kernel subsystem:
- ============ ==============================================
- iproute2 https://github.com/shemminger/iproute2
- go-l2tp https://github.com/katalix/go-l2tp
- tunneldigger https://github.com/wlanslovenija/tunneldigger
- xl2tpd https://github.com/xelerance/xl2tpd
- ============ ==============================================
- Limitations
- -----------
- The current implementation has a number of limitations:
- 1) Multiple UDP sockets with the same 5-tuple address cannot be
- used. The kernel's tunnel context is identified using private
- data associated with the socket so it is important that each
- socket is uniquely identified by its address.
- 2) Interfacing with openvswitch is not yet implemented. It may be
- useful to map OVS Ethernet and VLAN ports into L2TPv3 tunnels.
- 3) VLAN pseudowires are implemented using an ``l2tpethN`` interface
- configured with a VLAN sub-interface. Since L2TPv3 VLAN
- pseudowires carry one and only one VLAN, it may be better to use
- a single netdevice rather than an ``l2tpethN`` and ``l2tpethN``:M
- pair per VLAN session. The netlink attribute
- ``L2TP_ATTR_VLAN_ID`` was added for this, but it was never
- implemented.
- Testing
- -------
- Unmanaged L2TPv3 Ethernet features are tested by the kernel's built-in
- selftests. See `tools/testing/selftests/net/l2tp.sh`_.
- Another test suite, l2tp-ktest_, covers all
- of the L2TP APIs and tunnel/session types. This may be integrated into
- the kernel's built-in L2TP selftests in the future.
- .. Links
- .. _Generic Netlink: generic_netlink.html
- .. _libmnl: https://www.netfilter.org/projects/libmnl
- .. _include/uapi/linux/l2tp.h: ../../../include/uapi/linux/l2tp.h
- .. _include/linux/if_pppol2tp.h: ../../../include/linux/if_pppol2tp.h
- .. _net/l2tp/l2tp_ip.c: ../../../net/l2tp/l2tp_ip.c
- .. _net/l2tp/l2tp_ip6.c: ../../../net/l2tp/l2tp_ip6.c
- .. _net/l2tp/l2tp_ppp.c: ../../../net/l2tp/l2tp_ppp.c
- .. _net/l2tp/l2tp_eth.c: ../../../net/l2tp/l2tp_eth.c
- .. _tools/testing/selftests/net/l2tp.sh: ../../../tools/testing/selftests/net/l2tp.sh
- .. _l2tp-ktest: https://github.com/katalix/l2tp-ktest
|