l2tp-ktest is a suite of tools for testing the Linux kernel L2TP dataplane.
The suite is designed to exercise the kernel's APIs for creating and destroying tunnel and session contexts, to validate the data path itself by sending and receiving session data, and to provide some stress tests to attempt to trigger race conditions or oopses in the kernel itself.
Most of the tools are written in C. A shell script, l2tp_ktest, combines most of the tools into a test suite, and this is the easiest way to run them.
Currently l2tp-ktest provides tests for the following kernel features:
- L2TPv2 (RFC2661)
- L2TPv3 (RFC3931)
- AF_INET and AF_INET6 tunnel addresses
- UDP and L2TPIP tunnel encapsulation
- managed and unmanaged/static tunnel instances
- data path validation
- clean session shutdown while passing data
- L2TPv3 cookie validation
The following tests are limited in scope:
- the stress-test applications don't cover a lot of scenarios
- the data path tests don't cover some data path options: UDP checksums, sequence numbers, or L2-Specific Sublayer
The test tools are built using a simple Makefile.
Build requirements are:
- GNU make,
- the GCC C toolchain,
- Linux system headers for L2TP,
- development headers and runtime libraries for libnl, specifically libnl-3 and libnl-genl-3
To build the tools:
$ make
The build outputs are combined in a tarball, l2tp-ktest.tgz, for easy copying to a test machine.
On some older systems the syzbot applications (see below) fail to build: in this situation they can be disabled in the makefile using the variable OPT_NO_SYZBOT_APPS:
$ make OPT_NO_SYZBOT_APPS=1
Once built, the test tools can be run in-place in the build directory, or more usually copied to a test machine or VM for execution there.
The test machine will require:
- the GNU bash shell,
- root permissions to run the test suite,
- runtime libraries for libnl-3 and libnl-genl-3
- a version of iproute2 supporting the l2tp subcommand: most Linux distributions include this by default
- iperf3, jq and numfmt utilities
You can then run the test suite using the l2tp_ktest bash script. The script offers various options to control what it does: you can see documentation for these by passing it the -h command line option.
Alternatively, to simply run the suite of tests, execute the script with no arguments:
$ sudo ./l2tp_ktest
The script will probe the system for its capabilities prior to running the tests, and will exclude any tests which aren't supported by the system. For example, tests using AF_INET6 addresses won't be run on a system that lacks IPv6 support.
The test tools can be run on their own as well as by the test script:
- kcreate can be used to create tunnel and session instances in the kernel, and to explore kernel context lifetimes,
- sess_dataif can be used to create a managed session with it associated netdevice which can be used to test the data path. Two instances are required.
- netns_datapath is a wrapper for sess_dataif which implements a range of tests based on L2TP endpoints running in separate network namespaces
- tunl_delete_race and tunl_query_race are designed to provoke race conditions in the kernel,
- seqnum tests the kernel's data path sequence number handling,
- the syzbot applications are sysbot reproducers for bugs reported to the netdev mailing list for the L2TP subsystem.
All tools except the syzbot reproducers offer interactive usage information via. the -h command line option.
The syzkaller/syzbot project fuzz tests the Linux kernel's system call interface to try to provoke oopses. These are then reported to the netdev mailing list.
l2tp-ktest contains some historical syzbot reproducer applications which have been reported to the mailing list: the src/syzbot directory contains the details of these reports for reference.
Since the syzbot reproducer applications generally run in a never-ending loop, they are not executed by l2tp_ktest.
Instead, run them directly, watching a serial console for any oopses.
Most of the test applications generate some logging, which can be controlled using environmental variables:
- OPT_DEBUG should be defined in order to make logging more verbose
- OPT_QUIET should be defined in order to suppress all non error-related messages
- OPT_SILENT should be defined in order to suppress error messages
We (Katalix Systems Ltd.) created l2tp-ktest as an internal project supporting our work on the Linux L2TP subsystem and our ProL2TP product which makes use of it.
Some of our ProL2TP customers deploy to embedded systems using older kernels, and in such situations l2tp-ktest is useful to validate back-ported patches.
l2tp-ktest is also intended, in part, to act as a reference to the Linux L2TP API, which is only partially covered by existing projects such as iproute2.
Since 2019 the Linux kernel has included built-in L2TP tests in the kernel source tree. These have some overlap with l2tp-ktest, but are distinct tests in their own right.