The 1.8.0 release of ProL2TP is an exciting one for us as it includes a brand new component in the suite: ProPPP, a scalable PPP server. This post will take a look at this latest addition to the ProL2TP family to see what it brings to the table.
Why a new PPP daemon?
Prior to 1.8.0, ProL2TP supported termination of PPP sessions using the standard Linux pppd daemon. While this worked very well for lower session counts, it limited scalability due to pppd's "one process per PPP session" architecture. Because each new PPP session involved forking a pppd process, bringup time (and CPU load) was increased, while total session count was limited by the system scheduler and memory overhead of all the pppd processes.
In addition to the fundamental scalability limitations, large deployments based around pppd struggled on a number of other fronts. Debugging specific sessions, or getting any information about the state of a session, was difficult since each pppd process logged individually and had no means for the administrator to query state. Getting information about sessions coming up and down was similarly difficult: while pppd provides plenty of script hook points, these don't work well at scale, particularly if multiple instances of a script need to concurrently update some shared resource such as a database.
In order to solve these long-standing issues, we decided to create a new PPP daemon to allow the ProL2TP suite to provide truly scalable PPP support. However, ProPPP isn't completely new. At its core it uses pppd's protocol implementation, which is mature and well-tested across a range of environments. It also retains pppd's commandline argument format for familiarity and ease of use. We believe ProPPP offers the best of both worlds: the stabilility and familiarity of pppd, with improved scalability and features for large-scale deployment.
ProPPP handles multiple PPP sessions within a single process, using a multi-threaded architecture to make use of multiple CPU cores efficiently. This allows ProPPP to bring up PPP sessions more quickly and with less memory overhead than pppd.
Starting up a single PPP session with propppd takes only around 3% of the time it does with pppd. This dramatic time saving is down to the work involved: in the pppd case a new process must be forked, whereas in the propppd case we merely need to send some IPC messages to bring up a new session. When considered as part of a complete transaction, from the first L2TP control message to instantiate a new session through to the final PPP network protocol acknowledge message, a session bringup with propppd takes about 60% of the time of a session bringup with pppd; and the bringup time is now dominated by protocol transactions rather than fork time.
This difference translates into a much snappier start up time for large populations of PPP sessions. As an example, this graph of PPP session instantiation over time shows how pppd compares to ProPPP for a single L2TP tunnel containing 1000 PPP sessions. This is the total time taken from the prol2tpd process starting on the LAC to all the PPP interfaces being up with IP addresses assigned. As the graph shows, ProL2TP is able to establish the 1000 sessions with propppd in roughly half the time taken when using pppd:
ProPPP also saves a great deal of system memory relative to multiple pppd processes. Averaged across the 1000 sessions above, propppd used around 10kB of system memory per session on top of its base use of 5.1MB. By contrast, each pppd process used around 500kB of memory (this is the Unique Set Size: the Resident Set Size is around 3.5MB, which includes pages of memory from shared libraries which can be amortized across all the pppd instances). As such, propppd's incremental memory use per session is around 2% of pppd's.
Accessible status information
ProPPP's management interface adds useful facilities for administrators to query a running system in order to find out what's going on. It is possible to obtain high-level listings of all the running sessions and their state, and to obtain detailed information on a session-by-session basis. The management interface also provides a useful summary page which provides a high-level snapshot of the PPP session population.
Scalable integration points
ProPPP provides an event notification interface which allows scalable integration with external systems (e.g. for logging or billing). Event messages are delivered over an IPC socket, and the ProPPP installation provides shared libraries with APIs for parsing these messages, allowing customers to write C/C++ programs to perform custom actions on PPP session events.
No configuration changes
Support for propppd has been integrated as a plugin for prol2tpd, using exactly the same configuration file syntax as used for pppd integration. So for the majority of users there will be no need to change anything about your prol2tpd configuration, merely load the proppp.so plugin for prol2tpd in place of the ppp_unix.so plugin.
We believe propppd brings a new level of scalable PPP support to the ProL2TP suite. But the journey is only just beginning! With the new foundations in place we have a great basis for new features and further performance improvements.
If you're interested in giving ProPPP a go, please get in contact with us to request a free trial or to discuss your requirements, we'd love to hear from you!