Skip to content

The network stack

The stack is original code from the Ethernet frame up. It talks to the real internet through QEMU’s user networking, and to a real LAN on Intel e1000e hardware.

Layer What exists
Ethernet frame RX and TX against the e1000e driver
ARP resolution and a cache
IPv4 routing to a default gateway, plus fragment reassembly
ICMP echo request and reply, which is what ping uses
UDP datagram sockets
TCP a state machine with retransmission, delayed ACK and TIME-WAIT, driven by a dedicated tcp-retransmit kernel thread
DHCP client; configures the interface at boot
DNS resolver

DHCP runs as soon as the NIC is up. On a guest boot that is roughly a millisecond after the driver reports ready:

[0.808125] <cpu-2:e1000e:k:6> e1000e: initialized, MAC 52:54:00:12:34:56
[0.808210] <cpu-2:e1000e:k:6> net: dhcp: sending DISCOVER
[0.808449] <cpu-2:e1000e:k:6> net: dhcp: received OFFER 10.0.2.15
[0.808546] <cpu-2:e1000e:k:6> net: dhcp: received ACK, IP 10.0.2.15
/ $ ping 10.0.2.2
PING 10.0.2.2
Reply from 10.0.2.2: seq=0 time=0.12ms
--- ping statistics ---
4 packets sent, 4 received
rtt min/avg/max = 0.08/0.09/0.12 ms
/ $ dns example.com
example.com -> 172.66.147.243
/ $ wget http://example.com
wget: saved to 'index.html' (559 bytes)

ping, dns, dnsprobe, http, wget and tcptest all ship in /bin.

e1000e, verified on real Intel I219, I218 and I217 parts as well as in QEMU. RX and TX are interrupt-driven; the e1000e kernel thread owns the rings, and tcp-retransmit owns the timers.

Terminal window
make run-capture # writes /tmp/edos.pcap

Open the result in Wireshark. This is the fastest way to tell a stack bug from a driver bug.

The stack’s locks are ranked between 240 and 270: the stack itself, then the port table, then a socket, then a connection. They are always taken in that order. See lock order.