QEMU how to setup Tun/Tap + bridge networking

The default NAT networking as provided by QEMU’s “-net net -net nic” option (which is the default even if you don’t specify it in qemu’s commad line) will only provide NAT networking.

And in this mode you can only connect out of the QEMU guest, but not into it.

To enable it to have its own IP address, through a DHCP outside the host, it is necessary to setup the QEMU in bridge mode.

To do this:

Inside the linux hosts (I am assuming Ubuntu 64-bit 14.04 host here, for other distro some variation may be needed):

sudo apt-get install uml-utilities
sudo apt-get install bridge-utils

Inside the host’s /etc/networking/interfaces file add this:

        auto br0
        iface br0 inet dhcp
        bridge_ports eth0
        bridge_stp off
        bridge_maxwait 0
        bridge_fd 0

Then issue “sudo brctl addbr br0”.   Check using “ifconfig” that “br0” interface is created:

br0       Link encap:Ethernet  HWaddr bc:ee:7b:8c:53:9a
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

And create this file /etc/qemu-ifup (on the host side) which should have contents like below:

#! /bin/sh
# Script to bring a network (tap) device for qemu up.
# The idea is to add the tap device to the same bridge
# as we have default routing to.

# in order to be able to find brctl
PATH=$PATH:/sbin:/usr/sbin
ip=$(which ip)

if [ -n "$ip" ]; then
ip link set "$1" up
else
brctl=$(which brctl)
if [ ! "$ip" -o ! "$brctl" ]; then
echo "W: $0: not doing any bridge processing: neither ip nor brctl utility not found" >&2
exit 0
fi
ifconfig "$1" 0.0.0.0 up
fi

switch=$(ip route ls |
awk '/^default / {
for(i=0;i<NF;i++) { if ($i == "dev") { print $(i+1); next; } }
}'
)

switch=br0

# only add the interface to default-route bridge if we
# have such interface (with default route) and if that
# interface is actually a bridge.
# It is possible to have several default routes too
for br in $switch; do
if [ -d /sys/class/net/$br/bridge/. ]; then
if [ -n "$ip" ]; then
ip link set "$1" master "$br"
else
brctl addif $br "$1"
fi
exit # exit with status of the previous command
fi
done

echo "W: $0: no bridge for guest interface found" >&2

The “switch=br0” is the only line I modified from original.

And then on the host side:

sudo tunctl -d tap0
sudo tunctl -u tteikhua
sudo ifconfig tap0 10.10.1.125 netmask 255.255.255.0

Verify that the command “sudo sh /etc/qemu-ifup tap0” runs without error.   Then doing a “sudo brctl show”:

bridge name    bridge id        STP enabled    interfaces
br0            8000.4ed6f463bc09    no         eth0
                                               tap0

The following diagram (from http://cottidianus.livejournal.com/328031.html) showed the approximate logical traffic flow after the setup.

Inside the QEMU guest, the only thing done is just “dhclient eth0” to initiate the DHCP client seeking a new IP address through the bridge interface, assuming the DHCP server lives outside the host machine.

And if you need to setup another VM guest, just create another tap (eg, “tap1”) interface, and then add the tap to the bridge via “sudo brctl addif br0 tap1” command. And this tap1 and tap0 will appear as independent networking element directly connected to the network.

For a detailed explanation of the above configuration, see:

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: