This repository contains a fully documented, educational Linux kernel virtual Ethernet driver (vnet0).
The project is intentionally built step-by-step, mirroring how real Linux NIC drivers evolve over time.
Each phase introduces a concept that exists in production drivers (e.g., e1000, r8169, mlx5), while keeping the code readable and learning-focused.
Unlike a tutorial dump, the final code is clean, stable, and production‑style, with the phases preserved here for learning context.
| Phase | Description | Status |
|---|---|---|
| 1 | Basic kernel module | ✅ Done |
| 2 | Minimal net_device skeleton |
✅ Done |
| 3 | TX ring buffer | ✅ Done |
| 4 | RX ring + timer-based packet generator | ✅ Done |
| 5 | NAPI-based RX polling | ✅ Done |
| 6 | Statistics + ethtool support | ✅ Done |
| 7 | ARP frame generation + documentation | ✅ Done |
| 8 | Userspace backend (netlink / char dev) | ⏳ Future |
- Clean module load/unload
- Kernel log instrumentation
alloc_etherdev()allocation- Implemented
net_device_ops:ndo_openndo_stopndo_start_xmit
- Deterministic MAC assignment via
eth_hw_addr_set() - Interface appears as:
ip link show vnet0
- Circular TX ring (
VNET_TX_RING_SIZE) - Enqueue/dequeue helpers
- Spinlock-protected access
- Immediate TX completion model (learning-friendly)
- Proper
NETDEV_TX_BUSYhandling
- RX ring buffer (
VNET_RX_RING_SIZE) - Kernel timer simulates RX interrupts
- RX path separated from TX
- Foundation for NAPI polling
- Integrated NAPI via
netif_napi_add() - RX processed inside
vnet_napi_poll() - Timer acts as interrupt source:
- Generates RX skb
- Enqueues to RX ring
- Schedules NAPI
- RX delivered using
netif_rx() - Demonstrates interrupt mitigation and batching
Counters:
tx_packets,tx_bytes,tx_droppedrx_packets,rx_bytes,rx_dropped
Visible via:
ip -s link show vnet0ethtool -i vnet0
ethtool -S vnet0Reports:
- Driver name and version
- Virtual bus info
- Per‑protocol TX/RX counters
- Builds valid Ethernet + ARP request frames
- Broadcast destination MAC
- Correct ARP header and payload layout
- Frames observable via:
tcpdump -i vnet0 -e -n arp
- Extensive Doxygen-style documentation
- Clear ownership and concurrency rules explained inline
vnet-driver/
├── src/
│ ├── vnet_main.c # Complete virtual NIC driver
│ └── Makefile
├── docs/
│ └── architecture.md # Driver architecture (Phase 7)
├── README.md
└── LICENSE
Install prerequisites:
sudo apt install build-essential linux-headers-$(uname -r)Build:
make clean
makeOutput:
src/vnet_main.ko
Load:
sudo insmod src/vnet_main.ko
sudo ip link set vnet0 up
sudo ip addr add 10.0.0.1/24 dev vnet0Observe traffic:
tcpdump -i vnet0 -e -nUnload:
sudo rmmod vnet_mainEnable:
echo 'module vnet_main +p' | sudo tee /sys/kernel/debug/dynamic_debug/controlDisable:
echo 'module vnet_main -p' | sudo tee /sys/kernel/debug/dynamic_debug/controlThis project teaches:
- Linux kernel module fundamentals
net_deviceinternals- TX/RX ring buffer design
- NAPI and softirq RX handling
- Kernel timers as interrupt analogs
- Ethernet + ARP frame construction
- Driver statistics and ethtool
- Concurrency with spinlocks
- Real-world GitHub workflows (branches, PRs, releases)
- Userspace backend (netlink or char device)
- More realistic RX/TX traffic
- Advanced ethtool operations
- Network namespace integration
⭐ If this project helped you learn Linux driver development, consider starring the repo!