In our series about the Linux L2TP kernel API we explored using Linux to build L2TP applications using the C programming language.
Being able to build your own application from scratch is one thing, but it's usually preferable to be able to reuse existing components where possible.
Today we're happy to announce a new project providing exactly that. Go-l2tp is a library for building Linux L2TP applications.
The go-l2tp repository hosts the library itself, as well as two applications which demonstrate using the library.
As the project name suggests, go-l2tp is built using the Go programming language. We chose Go for its memory safety and fantastic concurrency support; and because there's no pre-existing Go library supporting L2TP.
go-l2tp currently offers:
- Wrappers for the Linux L2TP subsystem API using netlink. This supports the creation, and destruction of L2TPv2 and L2TPv3 dataplane instances in the kernel. In order to do this, go-l2tp builds on existing Go netlink libraries, adding support for the L2TP-specific netlink commands.
- Support for the L2TPv2 control plane for tunnel and session management in client (LAC) mode. go-l2tp implements L2TP control message parsing, including parsing of the Attribute-Value-Pair (AVP) data contained within the control message.
go-l2tp does not (yet) support:
- Control plane message handling for L2TPv3.
- Server (LNS) mode for the control plane.
- Some more advanced aspects of the L2TP control protocol, such as AVP hiding.
The go-l2tp demo applications
Alongside the go-l2tp library are two applications which make use of the library.
The first, ql2tpd, is a minimal tool for creating static L2TPv3 sessions. Static sessions don't run the control protocol, so the peers at either end of the tunnel must agree all parameters prior to establishing the session.
ql2tpd supports two modes for creating tunnels. In static mode, no control protocol runs. In this mode ql2tpd provides similar functionality to the standard Linux ip l2tp commands (although ql2tpd offers the benefit of a convenient configuration file syntax for defining tunnel and session instances).
In quiescent mode, ql2ptd adds a very minimal control message transport which supports sending and acknowledging L2TPv3 HELLO messages. This allows for the detection of tunnel failure, which will then tear down the sessions running in that tunnel. Quiescent tunnels should only be used if the peer is also running ql2tpd.
The second application included in the repository is kl2tpd, which is a tool for establishing L2TPv2 tunnels and sessions in client (LAC) mode.
kl2tpd is driven by a simple configuration file which defines the tunnel and session instances to create. When sessions establish kl2tpd spawns the standard Linux pppd(8) to run the PPP protocol. Here is an example of kl2tpd configuration for establishing a single session containing a single session:
[tunnel.t1] peer = "18.104.22.168:1701" version = "l2tpv2" encap = "udp" [tunnel.t1.session.s1] pseudowire = "ppp" pppd_args = "/home/bob/pppd.args"
Full details of the configuration file format are available in the repository.
Although kl2tpd is written as a demo application, it is a fully functional L2TPv2 client which could be packaged and used as an alternative to daemons such as xl2tpd. It could also be used in combination with StrongSwan as a L2TP/IPSec VPN client.
go-l2tp in its current form is freely available for use in new Linux L2TP applications.
It hasn't yet been given a semantic version number because it's a young library and its API is not yet set. If you have requests for changes or improvements to the API, we'd love to hear from you -- open an issue on the github project page!
We hope go-l2tp will be a useful community contribution for people wanting to build L2TP applications on Linux systems.