QEMU has a number of different ways of connecting the network to a virtualized guest, or vice-versa, connecting a virtualized guest to the network. The mechanism providing the most flexibility involves using a bridge mechanism plus a tap mechanism.
I'll resort to a cattle culling metaphor to explain the basic concept. Each cow represents a packet. The cows
from the field are directed from the fields into a holding pen, which is loosely represented
by the bridge concept. From the holding pen, individual cows are selected and
directed to their destination, which is loosely represented by the tap.
From an implementation point of view, for the purposes of this discussion, will bond together an external physical
interface (such as eth1) with a series of internal interfaces connecting to the virtualized guests (tap0, tap1, ...).
The tap interfaces connect the virtualized guest to the bridge and the bridge works to get those packets
out onto the physical interface, and for externally arriving packets, works to get the packets to the
appropriate tap interface.
On a Linux Debian Wheezy system, things are straight forward to configure. The system, for the purposes
of this example, has two external interfaces: eth0 and eth1. I have eth0 configured with private ip addresses
behind a firewall and is dedicated for physical host management. The other interface, eth1, is connected to the
public interface side of the network. The physical machine has no addresses on this side to help reduce the
risk of compromise of the physical host. For different environments, an ip address could be assigned to the bridge
interface, which would result in the physical machine being reachable on the public side of things.
Even more sophistication can be obtained with VLANs on the external interface. This topic is best left for another
blog entry, and will be covered with a discussion of Open vSwitch.
Before looking at the actual implementation commands, I need to mention two more caveats. The first is that
the following example turns off spanning tree related commands. The configuration is basically a stub off a physical
network. If multiple physical interfaces will belong to the same bridge group, then spanning tree will need to
be enabled. That would be a discussion for one or more separate blog entries.
The second caveat is that the example is based upon QEMU being used with root level privileges. Many other blog
entries use this type of networking in non-root scenarios, and are thus a bit more complicated due to the fact that
sudo is required for bringing up tap connections.
To ensure bridge utilities can be used, the result of the following should be CONFIG_TUN=m or CONFIG_TUN=y:
grep CONFIG_TUN= /boot/config-`uname -r`
Ensure the bridge utilities are installed. The assumption is that qemu/kvm are already installed and operational.
apt-get install bridge-utils
Here is an extract from the /etc/network/interfaces file:
auto eth1
allow-hotplug eth1
iface eth1 inet manual
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down
auto bvi1
iface bvi1 inet manual
pre-up brctl addbr bvi1
pre-up brctl addif bvi1 eth1
pre-up brctl stp bvi1 off
pre-up brctl setfd bvi1 1
pre-up ifconfig $IFACE up
post-down ifconfig $IFACE down
post-down brctl delif bvi1 eth1
post-down brctl delbr bvi1
The eth1 interface is automatically started. For this example, I have used Cisco terminology for the bridge
interface: bvi. BVI is an acronym for Bridged Virtual Interface. For this example, I have numbered the bvi interface as bvi1 to
match that it is attached to eth1.
Under 'iface bvi1 inet manual' stanza, there are a series of pre-up commands. These are commands which are operable
at the command line as well. The command brctl is used to create the bvi1 interface, add eth1 to the bridge group,
turn spanning tree protocol off, and then set a forwarding delay. The interface is then brought up.
When shutting down the interface, eth1 is removed from the bridge group, and then bvi1 is deleted.
Two more files need to be created with execute privileges. The first is /etc/qemu-ifup. This is a file
which qemu executes in order to connect the virtualized guest network interface to the bridge:
/sbin/ifconfig $1 0.0.0.0 promisc up
/sbin/brctl addif bvi1 $1
The other is /etc/qemu-ifdown which qemu uses when the virtualized guest exits:
/sbin/brctl delif bvi1 $1
I add the following parameters to the qemu startup command:
-net nic,vlan=0,model=virtio -net tap,vlan=0,ifname=tap0
'-net nic,vlan=0,model=virtio' sets the type of network card to emulate. 'qemu -net nic,model=?' can be used to obtain
a list of available devices. 'virtio' is a driver used to optimze the speed of communications between the guest and the host.
'tap,vlan=0,ifname=tap0' creates the tap0 interface, and it is with this parameter, that the /etc/qemu-if? commands
are used for joining the tap interface to the bridge.
Ip addresses can then be assigned statically or via dhcp within the guest, and all network operations operate
as though the guest is directly connected to the network.
A few web sites I encountered with additional background material: