For years, ever since release 2.1.0 in 2013, pfSense software has relied on mpd5 and netgraph to handle PPPoE WAN connections. While this setup served to establish connectivity to PPPoE services, the demands of modern multi-gigabit networks exposed limitations in the underlying architecture. With the offering of PPPoE services up to 8Gbps and even 10Gbps in some markets in Northern Europe, and the continuing use world-wide, including the Middle East, we felt it was important to upgrade the performance of what is, to many homes and businesses, their primary WAN connection. In this post, we dive into the technical details of why Netgraph fell short, how the new if_pppoe driver addresses these issues, and what you can expect from its implementation in pfSense software.
The Multi-link PPP daemon (`mpd5`) leverages Netgraph, a modular FreeBSD kernel framework designed for flexible network function implementation. Netgraph’s strength lies in its versatility—it supports a wide range of operations like bridging, PPP, GIF tunnels, NAT, Netflow, and more, all combinable in arbitrary configurations. This modularity, however, comes at a cost. Netgraph’s design requires extensive validation of module connections, managing reference counters, and handling locks. In the 1990s era of DSL connections with speeds in the tens of megabits and single core CPUs, this overhead was manageable. But as fiber connections pushed throughputs into the multi-gigabit range, and multi-core CPUs became the norm, the inherent inefficiencies of Netgraph became a bottleneck.
Netgraph’s modular architecture, while flexible, sacrifices performance. The constant validation and synchronization required for every packet to support arbitrary graphs of connections between modules introduce latency and limit scalability. In high-throughput environments, this overhead significantly hampers PPPoE performance, making it clear that a new approach was needed.
To address these shortcomings, Netgate has introduced a new if_pppoe driver for pfSense software. This driver is a streamlined implementation focused exclusively on PPPoE. By narrowing its scope, if_pppoe eliminates the overhead and single-threaded nature of Netgraph’s modularity, enabling significant performance gains, particularly in multi-core environments.
Of course, if you set out to improve performance, you’re going to want to test to ensure that you’ve actually improved things. In order to ensure that we were finding the limits of the PPPoE client in pfSense, we used a Sapphire Rapids system running the Linux kernel PPPoE server.
Device Under Test: Netgate 6100, L3 forwarding, pf-disabled, ix0/ix1 link speed: 10Gbps
Traffic Generator: Sapphire Rapids, Linux PPPoE kernel mode server
E810 NIC1, Port0, VF1, Trusted VF, Kernel Namespace (ns1), iperf3 client
E810 NIC2, Port0, VF 1, Trusted VF, Kennel namespace (ns2), iperf3 server
Link Speed: 100Gbps
Test Duration: 60 seconds
The results, in Gbps from the perspective of the client, speak for themselves.
PPPoE Implementation |
Download Min |
Upload Min |
Download Max |
Upload Max |
mpd5 1 Stream |
2.62 |
3.23 |
4.56 |
3.84 |
mpd5 4 Stream |
5.01 |
3.71 |
6.66 |
4.15 |
if_pppoe 1 Stream |
6.18 |
4.59 |
6.38 |
4.94 |
if_pppoe 4 Stream |
8.18 |
7.96 |
9.01 |
8.24 |
tl;dr: On a Netgate 6100, we’ve observed throughput improvements ranging from 25% to 100% in scenarios with multiple simultaneous traffic flows—common in real-world deployments. These gains make if_pppoe a game-changer for users on high-speed PPPoE connections.
As a side note: When we started collecting this data we were using a Netgate 8300 as the DUT, but as it turns out, the Linux kernel PPPoE server wasn't up to the task, even when using the Sapphire Rapids system as the test generation endpoints. We were hitting the test generator limits, roughly 10Gbps sending, and 12Gbps receiving, so we had to go down in DUT sizing to get good data. Because some have PPPoE connections that run at 8Gbps and even 10Gbps, we wanted to use a platform with 10Gbps interfaces so the Netgate 6100 was selected for the Device Under Test.
The if_pppoe driver is available in the pfSense 2.8.0 and 25.03 beta releases, though the initial beta releases of both lack some performance optimizations, bugfixes and features such as traffic-shaping which have all been addressed in the latest beta, released today. Given the diversity of ISPs using PPPoE, we need your help to ensure broad compatibility.
The if_pppoe driver may be enabled from the bottom of the System > Advanced > Networking menu in the pfSense software GUI, by placing a checkmark on the option labeled Use if_pppoe kernel module for PPPoE client. You can submit feedback through the pfSense bug tracker or community forum. Your input will help us polish if_pppoe for a stable release.
The shift from Netgraph to if_pppoe marks a significant gain for pfSense’s PPPoE performance. By prioritizing simplicity and multi-core efficiency, if_pppoe delivers the speed and scalability needed for today’s high-speed networks. We’re excited to see how it performs in the wild and look forward to your feedback to make it even better.
Finally, with our previous work to add netflow via pf, addition of bridge-to in pf and other work, the shift to if_pppoe will eliminate the last use of the Netgraph subsystem and its performance-limiting architecture in pfSense software.
---
Have questions or want to share your testing results? Join the pfSense community discussion on forum.netgate.com.