white wizard

qemu networking done right (qemu bridging with nfsroot)

Well, quick and dirty can't go on forever so here's how to configure the qemu networking.

First of all here's a diagram of my network devices:

When I boot my host the host kernel attaches a driver to my hardware nic and I get enp2s0 (ethernet type, pci bus 2 slot 0) interface looking at router. Later systemd-networkd brings up the br0 bridge, enlaves the enp2s0 to it and gets networkd configuration for br0 via DHCP so the interfaces look like this after successful boot:

Notice the "master br0" at enp2s0 and ipv4 address at br0.

Now the configuration for systemd-networkd looks like this:

Now I need the guest kernel:

Hints for guest kernel configuration:
# CONFIG_MODULES is not set
CONFIG_FHANDLE=y (guest systemd will need it for its getty)

And now I need the rootfs:

And then export it via nfsd:

Ok now I have a bridge interface, kernel and nfsroot. Qemu is going to use the qemu-bridge-helper program to configure the tap interface. So now I'm allowing the qemu-bridge-helper to configure the br0 to enslave the vm's tap interface.

And then allow it to use TUNSETIFF ioctl request on /dev/net/tun to create a tap interface.

All ready, let's start now:

So what happened here is: qemu created a virtual ethernet nic e1000 in guest, tap0 interface in host and connected tap0 to br0 bridge (-netdev bridge,br=br0 is default). Then qemu started the vm, ran the kernel, kernel (and later userspace) used the host's terminal from which I lauchned qemu for i/o. Kernel configured its virtual ethernet nic with settings from router's dhcpd, mounted the rootfs, started systemd and then I logged in, ran a few commands and powered the vm off.

And this is how it's done.