the brief
VyOS users had been asking for OpenVPN data channel offload for some time, and the kernel VyOS ships, 6.18, already contained ovpn, the module we wrote and maintain upstream. What was missing was everything around it: an OpenVPN build that uses the module, and a configuration system that knows how to drive it.
We did that integration ourselves, as unpaid open-source work. The three pull requests were merged in September 2026, about two and a half weeks after we posted them, and OpenVPN 2.7 with DCO is now available in VyOS Rolling.
not a version bump
OpenVPN 2.7 talks exclusively to ovpn, and the older ovpn-dco-v2 module that earlier releases relied on is no longer supported. On a router operating system this means the userspace package, the kernel module and the configuration system all have to move together, because if any one of them is left behind, tunnels simply fail to come up.
old configs keep working
On a router, the configuration is what users actually depend on, and an upgrade that quietly changes how a production tunnel behaves can do more damage than skipping the upgrade altogether. Migration was therefore the most delicate part of the work: existing OpenVPN configurations move to 2.7 and continue to work as they did before.
We also made the configuration system aware of what DCO can and cannot handle, so that when a setup relies on a cipher, option or topology outside DCO’s scope, VyOS reports it when the configuration is committed rather than letting it fail later at runtime.
interfaces that already exist
VyOS doesn’t leave the tunnel interface to OpenVPN. It creates the interface itself, applies its VRF, addresses, MTU and the rest of its settings, and keeps it in place across daemon restarts, removing it only when the tunnel is deleted, disabled or reconfigured into an incompatible mode. This way the interface exists and carries its configuration whether or not the tunnel is up, which matters in client mode in particular, where OpenVPN would otherwise create the interface only once the server answers. With data channel offload that interface is an ovpn kernel device, so OpenVPN regularly starts on one that VyOS has already created and configured, and OpenVPN 2.7 couldn’t handle that.
Ralf Lici, one of our engineers, wrote the fix: OpenVPN now recognises an existing interface, checks that it is an ovpn device in the expected mode, takes it over, and leaves it in place on shutdown instead of deleting it, so the configuration VyOS applied to it survives a restart of the tunnel.
The patch is still going through OpenVPN’s review process, so we have shipped it in VyOS ahead of the merge. VyOS users get the fix today, and the package will move to the upstream version once it lands.
what shipped
- vyos-build #1281 builds OpenVPN 2.7 against the in-tree ovpn module.
- vyos-1x #5435 adds OpenVPN 2.7 support to the configuration system.
- vyos-1x #5441 handles the DCO lifecycle, covering interface provisioning, compatibility checks and runtime mode changes, and extends the smoke tests accordingly.
backports, when needed
VyOS didn’t need ovpn-backports, since its kernel already carries the module. Once the in-kernel version starts to fall behind, backports can bring newer ovpn code to the same kernel without requiring a kernel upgrade, which is the route OpenWrt already takes today.
what it took
Having written ovpn, connecting it to VyOS was the straightforward part. Most of the effort went into making a production router OS adopt it smoothly, with a safe migration path, clear validation and correct handling of the edge cases that only show up on real systems.
That is the kind of work we do for networking products. How ovpn got into the kernel >
if this sounds familiar
If you ship a router, firewall or gateway and want OpenVPN DCO in it, whether on a current kernel or on an LTS branch, we can bring it there while keeping your users’ existing setups intact.
Just book a call and let’s discuss.
More about our networking and kernel work · Our open-source contributions