Can a userland process run an existing kernel NIC driver?

149 views Asked by At

I'm not experienced with the Linux kernel (more application-side C/C++) but I would like to process packets from the network card within userland.

However, I wish to avoid frameworks such as DPDK, Openonload etc. I find they have a high setup/maintenance overhead (and I know I'll enjoy writing one).

If I know what my network card will be:

Is it possible for a userland process to load an existing NIC driver, set itself as a callback and receive the packet bytes?

My expectation/hunch is the NIC code is tightly-coupled to the kernel and would require a re-write? If I chose to do this, perhaps I could use the DPDK code for inspiration.

1

There are 1 answers

2
user22289217 On

For the main question, the answer is no. A userland process cannot run a kernel NIC driver. As for DPDK, its NIC drivers (PMDs) are decoupled from the kernel code. They've been tailored specifically for that framework, they follow DPDK in-house code style, and so on. That being said, DPDK PMDs may share certain portions of code with the same-vendor kernel drivers (so-called "base" code).

On the other hand, trying to delve further into the question, it should be possible to leverage the existing kernel means, PACKET_MMAP, to write an application that would be very DPDK-like (receiving packets at the earliest stage possible). The gist of it is as follows. The application can set up a memory buffer shared between the kernel- and userspace and then read out incoming packets from it, ideally in batches, thus avoiding costly kernel-to userspace copies and context switches. Furthermore, the application can request that packets be load-balanced across multiple threads, very RSS-like (AF_PACKET fanout mode).

A good example of PACKET_MMAP usage might be libpcap-based applications. They use the base PACKET_MMAP mechanism extensively, as well as its optimisations (fanout mode and the likes). All of that allows for efficient packet capture, very close to DPDK and much faster than regular (kernel-to-userspace copy) sockets.