# OpenOnload runs the TCP stack in user space without changing the application

> OpenOnload is a user-level network stack for Linux that intercepts socket calls and accelerates TCP and UDP I/O for unmodified binaries, with an ef_vi fast path for AMD Solarflare adapters and an AF_XDP path for everything else. It is community supported, has no GitHub releases, and its AF_XDP mode is explicitly not at release quality.

**Xilinx-CNS/onload** — OpenOnload high performance user-level network stack

- Repository: https://github.com/Xilinx-CNS/onload
- Stars: 851 · Forks: 149
- Language: C
- License: NOASSERTION
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/xilinx-cns-onload

## The protocol stack moves out of the kernel

OpenOnload is a high performance user-level network stack that accelerates TCP and UDP network I/O for applications using BSD sockets on Linux. The composition is simple to state and hard to implement. A user-level shared library intercepts the network related system calls and implements the protocol stack itself, and a set of supporting kernel modules sits underneath.

The stated features are low application-to-application latency, binary compatibility with existing applications, and open source terms of GPLv2.0 and BSD-2-Clause.

That binary compatibility is the point that separates this from an ordinary kernel tuning exercise. The application is not recompiled, not linked against a different socket library and not aware that anything has changed. You launch it under a wrapper and the interception happens underneath, which is what makes Onload usable for third party binaries, for virtual machines, and for software you do not have the source for.

The interesting engineering is in the parts that user-level networking usually gets wrong. The README calls this out directly, saying the stack is compatible with the full system call API including the aspects that are usually problematic for user-level networking. Those are fork, exec, passing sockets through Unix domain sockets, and advancing the protocol when the application is not scheduled.

The last one deserves attention. If a user-level stack only makes progress while the application runs on a CPU, then a process that blocks in a read for hours has stalled its own network connections. Onload has to keep the protocol moving on the application's behalf, which is a scheduling problem rather than a networking one.

## Two acceleration paths, and only one of them is finished

Onload can accelerate traffic two ways, and the README is honest about the difference between them.

The first path is the native ef_vi hardware interface provided by AMD Solarflare network adapters. In this mode the README says Onload provides the best networking acceleration and additional features compared with using the Linux AF_XDP mechanism, and that kernel and driver support for AF_XDP is not required at all. A version of the sfc net driver for those adapters is included in the tree.

The adapters listed as able to support OpenOnload without AF_XDP are the SFN8522, SFN8542, SFN8042, the X2522, X2522-25G, the X2541 and the X3522. If your hardware is in that list, the ef_vi path is the one to use.

The second path is AF_XDP, which lets Onload accelerate applications on non-Solarflare adapters. The README calls the AF_XDP support a community-supported work in progress that is not currently at release quality. That sentence is the single most important line in the document for anyone planning to deploy this on a standard NIC.

There is a further wrinkle. If a netdriver does not support AF_XDP in native mode, Onload falls back to generic XDP mode when registering an interface, and generic XDP needs a userspace helper to be set up first.

```sh
$ make -C ./src/tools/bpf_link_helper/
$ echo $(realpath ./src/tools/bpf_link_helper/bpf-link-helper) | sudo tee /sys/module/sfc_resource/parameters/bpf_link_helper
```

So the commodity path is two steps worse than the vendor path: an extra helper binary, and a mode the project itself describes as unfinished.

## Getting an application onto the stack

Onload is distributed as source code, and the README points to DEVELOPING.md for the instructions on building, packaging and installing. There is no binary package described there in the pages shown, so a build from the tree is the path.

The build system is a Makefile whose default goal builds the kernel driver. The help text lists the options you are most likely to need: V=1 to print full build command lines, NDEBUG=1 for an optimized build, MMAKE_LIBERAL=1 to turn off -Werror, and the HAVE_SFC, HAVE_EFCT, HAVE_EF10CT and HAVE_SDCI switches to compile out hardware support you do not have. BUILD_PROFILE selects a configuration, with cloud and extra named as examples, and KPATH points at the kernel tree to build against, defaulting to the running kernel's build directory under /lib/modules.

The application side is one word. The README says the application to be Onloaded should be launched by prefixing the command line with onload, and the same name is the wrapper that sets up the environment for the intercepted process.

For interfaces that Onload should accelerate but that are not AMD Solarflare adapters, the interface has to be registered for AF_XDP first, one interface at a time.

```sh
echo ens2f0 > /sys/module/sfc_resource/afxdp/register
```

The path in that command, under the sfc_resource module, is worth noting: registration is a runtime action through sysfs, which means it is per boot unless something in your provisioning makes it persistent.

## Building for AF_XDP only, without the vendor driver

A large share of the interesting build configuration exists so that the stack can be compiled for hardware you do not have.

The README lists the switches for a build without the AMD Solarflare driver: the Makefile takes HAVE_SFC=0, the onload_build and onload_install scripts take a --no-sfc parameter, and onload_tool reload takes --onload-only. There is a similar set for dropping EFCT and AUX support, with HAVE_EFCT=0 for the Makefile and --no-efct for onload_build.

The same pattern repeats for the other hardware paths, with HAVE_EF10CT=0 and HAVE_SDCI=0 in the Makefile help text, so the build matrix is effectively: pick the hardware you have, set the corresponding switch to zero for everything you do not.

The repository layout matches. There is a Makefile at the root with the driver targets, an imports.mk and an mk/ directory for the build fragments, a src/ tree containing the driver subdirectories and the shared libraries, scripts/ for the onload_build, onload_install and onload_tool helpers, a Jenkinsfile for continuous integration, and a versions.env file for version stamping.

The Python packaging is a side detail that still matters for some deployments. The pyproject.toml describes a project called OpenOnload_utilities at version 1.0, licensed GPL-2.0, whose packages are found under scripts/ and whose top level modules are sfcmask and sfcaffinity. Those are the utilities for masking Solarflare interfaces and setting affinity, and they are packaged as a Python distribution separately from the C stack.

## Support comes from two channels, and they are not the same

This repository is community supported, and the README is unusually precise about what that means in practice.

Users are expected to run from the head of the git tree to pick up recent changes, not from official versions of Onload that were typically released before recent breaking kernel changes appeared, because using those older releases is likely to lead to many duplicate issues being raised. The README also says that incompatibilities introduced by recent kernel versions are likely to be fixed rapidly in this repository.

That is a workable arrangement for a project whose compatibility surface is the kernel, and it is also a statement that there is no stable release to depend on here. The repository publishes no GitHub releases at all, so there is no tag to pin.

Supported releases of OpenOnload are available separately, from the AMD Solarflare software download page on xilinx.com, and issues on those supported releases go to support-nic@amd.com rather than to the GitHub tracker. The README also notes that the list of compatible kernels and distributions in the source tree differs from the list of supported operating systems in the released versions, which is a subtle but real trap: what the tree builds against is not necessarily what the supported release supports.

The compatibility list in the tree is Debian 12 and newer, Ubuntu LTS 24.04 and newer, EL 9.0 and 10.0 and newer, and kernel.org Linux kernels from 6.1 to 7.0. Anything outside that range is your own problem.

## Licensing is a dual licence, and it differs per file

The licence picture is unusual and worth reading carefully rather than skimming.

The README describes the project as open source under GPLv2.0 and BSD-2-Clause. The Makefile carries an SPDX header that says GPL-2.0 OR BSD-2-Clause, with a copyright line for Xilinx from 2019 to 2023, which is the standard dual-licence expression meaning you may use it under either term. The pyproject.toml for the Python utilities declares GPL-2.0 and carries an AMD copyright line dated 2026. The README itself says the file is copyright 2020 to 2024 Advanced Micro Devices, Inc.

GitHub's classification of the repository licence is recorded as a custom licence that it cannot categorise, which is a common outcome for a tree where the licence varies by file and by component.

Practically, the dual licence means you can take the parts you want under whichever term suits your distribution model, and the per-file SPDX headers tell you which applies to which file. Read those headers when you vendor a piece rather than assuming one answer for the whole tree. This is not legal advice, and the point to take away is narrower: the terms are stated per file, and a scanner that reports one licence for the repository will be wrong.

## Where Onload is the wrong tool

There are three clear cases where this stack is the wrong answer.

The first is commodity hardware. If your NIC is not one of the listed Solarflare adapters, you are on the AF_XDP path, which the README describes as a community supported work in progress that is not at release quality, with a generic XDP fallback that needs a separate helper binary. If latency is the goal, buying a supported adapter is a smaller risk than running an unfinished path in production.

The second is a software stack you would rather not interpose. Onload intercepts system calls, which means it sits in the path of everything the process does over the network, including calls you did not intend to accelerate, and it has to work correctly across fork, exec and socket handoff. That is a large surface to trust, and for most workloads a modern kernel network stack with tuned queues is the boring answer.

The third is a requirement for a supported, versioned release. The repository has no releases, expects users to run from the head of the tree, and tells you to move to the vendor channel for supported versions. A production platform team will want a version they can reproduce, and that comes from the AMD Solarflare download page rather than from a git checkout.

What Onload does offer that nothing else on this list does is acceleration without touching the application. If your latency problem involves a binary you cannot recompile, that is the deciding factor.

## Conclusion

OpenOnload is the right tool for a latency sensitive service running on AMD Solarflare hardware that cannot be rewritten, since the stack is binary compatible with existing applications and needs no source changes. It is not the right choice on commodity NICs, where the AF_XDP path is a community supported work in progress that the README says is not at release quality, nor for a team that wants a supported release, since the repository publishes no tags and issues are expected against the git head. Before deploying it, read DEVELOPING.md, confirm your kernel and distribution are in the listed range, register any non-Solarflare interface for AF_XDP, and decide whether you can run from the head of the tree rather than a tagged release.

## FAQ

### What is OpenOnload and what does it accelerate?

OpenOnload is a high performance user-level network stack for Linux that accelerates TCP and UDP network I/O for applications using BSD sockets. A user-level shared library intercepts the network system calls and implements the protocol stack, with supporting kernel modules underneath.

### How do I run an application under OpenOnload?

The README says the application to be Onloaded should be launched by prefixing the command line with onload. Before that, any interface that is not an AMD Solarflare adapter has to be registered for AF_XDP through the sysfs register path of the sfc_resource module.

### Which AMD Solarflare adapters support OpenOnload without AF_XDP?

The README lists the SFN8522, SFN8542, SFN8042, X2522, X2522-25G, X2541 and X3522 as able to support OpenOnload without AF_XDP, using the native ef_vi interface. A version of the sfc net driver is included in the tree.

### Can I build OpenOnload without Solarflare hardware?

Yes. The README describes building without the SFC driver using HAVE_SFC=0 for the Makefile, a --no-sfc parameter for onload_build and onload_install, and --onload-only for onload_tool reload. Similar switches exist for EFCT and AUX support.

### Which Linux kernels and distributions does the source tree support?

The README lists Debian 12 and newer, Ubuntu LTS 24.04 and newer, EL 9.0 and 10.0 and newer, and kernel.org Linux kernels from 6.1 to 7.0. That list differs from the supported operating systems of the released versions available from the AMD Solarflare download page.

## Sources

- [Issues](https://github.com/Xilinx-CNS/onload/issues)
- [README](https://github.com/Xilinx-CNS/onload/blob/master/README.md)
- [Xilinx-CNS/onload on GitHub](https://github.com/Xilinx-CNS/onload)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/xilinx-cns-onload
