I used eBPF to capture packets on a WLAN interface for network analysis. This project connects my interest in embedded systems with Linux networking: observing traffic, deciding where packet processing should happen, and using the captured data to understand activity on the network.
From Netlink and epoll to eBPF
An earlier version of the project used the Netlink API to move information from the kernel to a user-space application. The application used epoll to wait for events and process the incoming data. That design worked, but it also placed more of the capture path in user space: the process had to wake up, receive messages, and parse the data before deciding what was relevant.
I reworked the capture path with eBPF so that the first stage of packet inspection could happen inside the kernel. The design goal was to filter or summarize traffic earlier and send only the useful results to user space, reducing unnecessary transfers and wakeups while keeping the analysis application event driven.
The performance boundary
I cannot claim a measured CPU reduction because I did not benchmark the Netlink/epoll and eBPF versions under the same traffic workload. The attachment mode also matters. Native XDP runs in the network driver before the kernel allocates a socket buffer, but the WLAN interface in this setup used generic XDP, also called SKB mode. In that mode the socket buffer already exists, so it does not have the same fast-path advantage as native XDP.
The eBPF version still let me move selected logic into the kernel and control what reached the analysis process. Its actual CPU cost depends on the packet rate, the work performed by the eBPF program, and how much data is passed to user space. A controlled comparison of CPU time, wakeups, and packet loss would be the next step before presenting it as a performance improvement (but this project ended in my university lol). The Linux kernel AF_XDP documentation describes the distinction between native driver mode and the generic SKB fallback.
What I explored
Beyond packet capture itself, this project gave me practical experience with the boundary between the Linux kernel and user space. It involved event-driven I/O, wireless traffic analysis, and the tradeoff between doing more work early in the packet path and retaining enough information for later analysis. And later on, thanks to Liz Rice with her books about eBPF and containers, I know about the cloud world.