Sunday, January 11, 2009

QEMU TAP network setup

This is one of the toughest task I have ever achieved, Its really complex, even though there are many post explaining how to setup the Virtual network, I feel most of them lack the complete information, and you end up getting frustrated. So after I achieved tun/tap networking up on PC, I thought of sharing the same.

When you run qemu normally without network options specified, automatically user mode network is setup between host OS and guest OS. In user mode networking, QEmu manages network interface internally in the user mode emulator application. QEmu provides DHCP host which assigns a dynamic IP for the guest OS. TCP and UDP ports can be redirected from the host OS to the guest OS using QEmu command line parameters. Easy to set up but, Only TCP and UDP connections are available by default. Ping command, for example, doesn't work inside the guest OS

In TAP networking, QEmu connects the guest OS ethernet to the host OS using TAP network bridge. Linux creates a virtual network interface (tap0) which appears in ifconfig listing as other network interfaces.

First off all you need to configure a network bridge. Which requires the bridge-utils package. For the TUN/TAP you need to check your kernel config file for CONFIG_TUN=m or CONFIG_TUN=y.

$ grep CONFIG_TUN= /boot/config-`uname -r`

Also you need to make sure /dev/net/tun exists. To make it:

$ mknod /dev/net/tun c 10 200


You need to have bridge utils installed. But then its safe to install these two packages, and I have installed these two and my network is working fine.

$ sudo apt-get install uml_utilities
$ sudo apt-get install bridge-utils


Once this is done, We can start setting up the network. I assume that Windows XP is installed on QEMU and KQEMU accelerator is being already used for the speed up purpose. Please refer to my other post for doing this.

For setting up the network qemu calls /etc/qemu-ifup script when -net nic -net tap option is given, It expects you to write the qemu-ifup script to setup bridge network. So first lets do that.

$ sudo vim /etc/qemu-ifup

#!/bin/sh
#
# script to bring up the tun device in QEMU in bridged mode
# first parameter is name of tap device (e.g. tap0)
#
# Prasad Shetty
# http://shettyprasad.blogspot.com
#
ETH0IP=192.168.0.3
GATEWAY=192.168.0.1
BROADCAST=192.168.0.255

# First take eth0 down, Add bridge, then bring it up with IP 0.0.0.0
ifconfig eth0 down
brctl addbr br0
ifconfig eth0 0.0.0.0 up

# Configure the bridge, create bridge between eth0 and br0
# and add the default route
ifconfig br0 $ETH0IP netmask 255.255.255.0 broadcast $BROADCAST
brctl addif br0 eth0
route add default gw $GATEWAY

# Bring the TAP bridge network up, and intereface with br0
ifconfig $1 up
brctl addif br0 $1

when qemu shuts down, it will call /etc/qemu-ifdown script, in which we can add functionality to bring down the bridge, and bring up the ethernet in normal mode.

$ sudo vim /etc/qemu-ifdown

#!/bin/sh
#
# Script to bring down and delete bridge br0 when QEMU exits
#
# Prasad Shetty
# http://shettyprasad.blogspot.com
#
# Bring down eth0 and br0
ifconfig eth0 down
ifconfig br0 down

# Delete the bridge
brctl delbr br0

# bring up eth0 in "normal" mode
ifconfig eth0 0.0.0.0 -promisc up

Once all this is done, we just need to specify which tap device to use for bridge to qemu, we can use tunctl to setup a TUN TAP device and then pass the retun value to qemu to use it with qemu-ifup and qemu-ifdown script.

I add some more functionality to this script to take care of setting up basic things before calling the qemu to run windows with network options. The comments itself explain the details of it. This is called wrapper script. All these things work with root and setting up the same for user is possible but it has lot of complexities and most possibly may not work properly.

$ sudo vim winxp.sh

#!/bin/sh
# insert the tuntap module
sudo modprobe tun
#
# insert the bridge module
sudo modprobe bridge
#
# insert the kqemu module
sudo modprobe kqemu major=0
#
iface=`sudo tunctl -b`
sudo qemu -m 256 -boot c -hda xp.img -snapshot -kernel-kqemu -localtime
-net nic -net tap,ifname=$iface
sudo tunctl -d $iface &>/dev/null

Now you can run this wrapper script and your QEMU comes up with windows xp with network up. Enjoy browsing under windows running on QEMU.

I sometimes get bus error, which I dont think is because of any errors in the network setup, If I fix it I will update here.

2 comments:

  1. I used your advice but could not get an address to the VM ( running Ubuntu 8.10 dsktop)

    my qemu script :

    IFACE=`sudo tunctl -b`
    echo $IFACE
    sudo /usr/bin/qemu-system-x86_64 -m 1000
    -smp 8 -boot c -hda /home/dubi/shared/ubuntu-intel.img -snapshot
    -net nic,macaddr=52:54:00:48:5a:4a,model=e1000 -net tap,ifname=$IFACE

    sudo tunctl -d $iface &>/dev/null

    Note that I have the bridge and tun drivers and brctl and tunctl installed as you instruct

    with the standard /etc/qemu-ifup that comes with the distro I am able to start the VM but I do not get an IP address to the VM

    the standard /etc/qemu-ifup is :

    #!/bin/sh
    sudo -p "Password for $0:" /sbin/ifconfig $1 172.20.0.1


    my Ubuntu host was already configured to have bridge (according to web instructions) as below and it does give an IP to the VM if I launch the VM using libvirt XML file but I need do it without an XML file , just directly with qemu

    here is my /etc/network/interfaces file:

    auto lo eth0
    iface lo inet loopback
    iface eth0 inet manual
    auto b0
    iface b0 inet static
    address 9.148.4.71
    netmask 255.255.255.0
    gateway 9.148.4.4
    bridge_ports eth0
    bridge_fd 9
    bridge_hello 2
    bridge_maxage 12
    bridge_stp off




    still got the following error :
    tap0
    /etc/qemu-ifup: could not launch network script
    Could not initialize device 'tap'

    ReplyDelete
  2. Thanks for sharing useful information. I always make sure to bookmark pages like this because you know it will be useful in the future too. thanks again. Home Network Setup

    ReplyDelete