Running qemu / kvm with tap interfaces and a bridge

A convenient way to give a kvm guest image connectivity to the host, without editing global configuration files or anything else.

When you want to give a kvm guest image connectivity to the host, you can configure a bridge and launch directly kvm with it after setting it up. There are ways to do this using global qemu ifup scripts, or virtio drivers, but I find this one more convenient and less cumbersome to maintain, as there is no need to write anything to system files.

This is something cassilda does (along with creating the whole image) but i leave this as quick reference when booting foreign systems, such as windows

Setting up a tap device inserted into a virtual switch (bridge)

 /sbin/sysctl -w net.ipv4.ip_forward=1
 /sbin/iptables -t nat -A POSTROUTING -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j MASQUERADE
 /usr/sbin/brctl addbr br0
 /sbin/ifconfig br0 192.168.0.1
 /usr/sbin/tunctl -t tap0
 /usr/sbin/brctl addif br0 tap0
 /sbin/ifconfig tap0 up

Launching kvm with the right options

 kvm -m 1G -hda winxp-x64.img -net nic,macaddr=01:02:03:04:05:06 -net tap,ifname=tap0,script=/bin/true

The kvm command can be named qemu-kvm, or if you are using only software emulation (for example emulating an arm or mips system) you can launch it as 'qemu'. The options are the same regardless on how the command is named.

Setup the network in the image to have a static ip address, namely 192.168.0.2/24. Inside it, connect to the host through http/scp/ssh using 192.168.0.1 as address. Use also 192.168.0.1 as broadcast address.

Tearing down everything after running

 /sbin/ifconfig tap0 down
 /usr/sbin/brctl delif br0 tap0
 /usr/sbin/tunctl -d tap0
 /sbin/ifconfig br0 down
 /usr/sbin/brctl delbr br0
 /sbin/iptables -t nat -D POSTROUTING -s 192.168.0.0/24 ! -d 192.168.0.0/24 -j MASQUERADE
 /sbin/sysctl -w net.ipv4.ip_forward=0

Quick explanation on the commands

The sysctl call allows the linux host to act as a router. The iptables invocation tells the kernel firewall to allow forwarding to and from the network 192.168.0.0/24, and do masquerading (NATting) of the packages.

The 'brctl addbr' call adds a bridge, think of it as a virtual switch, into the kernel network subsystem. It is then given an address.

The 'tunctl -t' creates a new TUN/TAP device, called tap0 that is 'our end' for the virtual interface inside the virtual machine. Think of it as the other end of an ethernet cable that we are plugging into our switch. It does not have address, but must be plugged into the bridge (brctl addif) and up ('ifconfig tap0 up').