Bridging Qemu Image To Real Network Using Tap Interface

In this tutorial I would like to show how to bridge an Operation System (OS) that is running inside a virtual machine (guest), with OS running on physical hardware (a host). A virtual machine is created and virtualized by  Qemu emulator, installed on the host.

By default, when a Qemu virtual machine is started without specifying NIC options, one single network interface is created on the guest OS.  The interface connects a guest OS with with a host OS using a NAT mode. The NAT ensures that traffic leaving guest OS is passed out of the guest network interface without any restrictions but only established traffic  is allowed to enter a guest network interface. Traffic coming from the host to the guest that is not established, is discarded.  An IP address of the guest network interface is assigned automatically from an internal Qemu DHCP server and it is typically 10.0.2.15/24 with a default gateway IP address 10.0.2.2.

Our goal is to create configuration which allows traffic being initialized from the both directions. This type of connection between is called a bridged connection and the both - guest and host IP addresses  are assigned from the same subnet. To create a bridged connection between the guest and host we have to  create a virtual tap interface on the host and Qemu must be told to bridge a guest interface with a tap interface. Then we can create a bridge virtual interface and bridge an existing host Ethernet interface and tap interface together. The Fedora Linux package bridge-utils can be used for this job.

Host OS Configuration - Fedora Linux

1/ Install bridge-utils package 

The bridge utility creates a virtual bridge interface that forwards traffic between tap and Ethernet interface.

sudo yum install bridge-utils

2/ Install tunctl package

The tunctl utility is used to create and manage virtual TUN/TAP interfaces. It is required that a generic TUN/TAP driver is either built-in to kernel, or available as a module. To check the availability of this module do the following:

ls -la /dev/net/tun

If you get an error message no such file or directory, load a module to a Linux kernel with the modprobe tun command. After that a module should be presented in the output of lsmod command.

sudo yum install tunctl

3/ Create bridge device virbr0

sudo brctl addbr virbr0

4/ Create virtual tap0 interface

Tap interface is persistent and owned by  user brezular

 /usr/sbin/tunctl -t tap0 -u brezular

5/ Add eth0 and tap0 to the bridge and bring the interfaces up

sudo brctl addif virbr0 eth0
sudo brctl addif virbr0 tap0

sudo ifconfig eth0 up
sudo ifconfig tap0 up
sudo ifconfig virbr0 up

Note: Check if  tap0 and eth0 are properly bridged.

 brctl show

Picture 1 - Bridging Ethernet and Virtual TAP Interface

6/ Assign IP address to virbr0 interface and remove IP address eth0 interface

Only the bridge interface virbr0 should have an IP address assigned.

sudo ifconfig virbr0 172.16.1.2/16
sudo ifconfig eth0 0.0.0.0 promisc

Note: If you run DHCP server in your network, issue the following command to assign IP address to the interface virbr0.

sudo dhclient virbr0

Configure a default route if connection to the Internet is required. In the example below, the default gateway IP address is the last usable IP address for the subnet 172.16.0.0/16.

sudo route add default gw 172.16.255.254

7/ Disable L2 traffic filtering - ebtables, bridge-nf, arptables

Change value 1 to 0 for all the files in directory /proc/sys/net/bridge/.

cd /proc/sys/net/bridge; ls

bridge-nf-call-arptables  bridge-nf-call-iptables
bridge-nf-call-ip6tables  bridge-nf-filter-vlan-tagged

sudo su
for f in bridge-nf-*; do echo 0 > $f; done

8/ Start Guest OS - Core Linux

Qemu guest virtual machine have to be started with the parameters that instruct Qemu to bridge a tap0 interface with a guest network interface. Below is deprecated "vlan" command syntax.

/usr/local/bin/qemu-system-x86 -m 128M -enable-kvm -boot c -hda /home/brezular/qemu-tinycore-linux.img -net nic,vlan=0,macaddr=00:aa:00:60:00:01,model=e1000 -net tap,vlan=0,ifname=tap0,script=no

The new Qemu versions use "netdev" syntax.

/usr/local/bin/qemu-system-x86  -m 128M -enable-kvm -boot c -hda /home/brezular/qemu-tinycore-linux.img  -netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device e1000,netdev=net0,mac=00:aa:00:60:00:01

Explanation:
-boot c -> boot from the hard disk
-m 128M -> 128 MB RAM allocated for the image
-enable-kvm ->enable hardware virtualization

Guest OS Configuration - Core Linux

1/ Configure IP address for eth0 interface (it is on the same subnet as virbr0)

sudo su
ifconfig eth0 172.16.1.1/16 up

21 thoughts on “Bridging Qemu Image To Real Network Using Tap Interface

  1. Could you show how to do roughly the same thing inside gns3 ?

    dream GNS3: qemuhost-------www_world
    presently GNS3 qemuhost------EthSwitch-------www_world

    does it mean we need somehow to force gns3_qemuwrapper to include net_option:-net tap
    otherwise qemu is "stranger" to hostPC ?.

    thank you

  2. I am wondering what the ip address and subnet of the host PC eth0 interface is in this example? you said it is on the same subnet as the 172.16.0.0/16 I am trying to get this to work and everytime I create the bridge it completely cuts my host OS from the network.

    1. Once you add eth0 interface to the bridge, it really doesn't matter what is eth0 IP address. It can be any IP address because it doesn't have any effect on connection.
      You only need to care about bridge IP address. This IP adress should match your home network subnet.

      You can do a quick test if you want. For example, add eth0 to the bridge and assign any IP adress to eth0 e.g 20.20.20.1/8.
      Then assign such an IP address to bridge interface that matches your home subnet. In my case it is 172.18.0.0/16.

      defualt_gw---------eth0------------virbr0
      172.18.100.1/16 20.20.20.1/8 172.18.100.2/16

      Now try to ping default gateway 172.18.100.1 from your PC. What do you think is result?

  3. Hi
    Please can you tell me how to connect my home network ip address to bridge ?Because now i dont know my fedora internet is not comming up at all :( i dont know what to do to solve it and make it work once again like before...
    Please guide me to let my internet up and also my bride to qemu up too ...

    Thank you and you are really genius :)

    1. 1. bridge eth0 and tap interface and bring eth0, tap0, virbr0 to up state
      2. assign IP address to the bridge
      2. assign null IP address to eth0 interface
      3. use command route and check if route to default gw is tied with virbr0 interface. If not recreate default route with command as root:
      route add default gw IP_address_dfgw

      1. Hi
        Thank You for your replay

        Indeed after the way you showed i configured it and yuppy its working fine but the problem is whenever fedora restarts all my configs all goes away...Is there any way to save them all ?
        Thank You

  4. Currently my Fedora host home network connects to the Internet using a bridge (br0) and if eth0. How should I adapt my current setup using your instructions?

  5. I am running qemu or bochs in android and using dsl4.0 linux but not able to connect to internet every os which was installed on qemu or boschs is not able to find eth0 showing only lo 127.0.0.1
    Is there any way to run net either by config ethernet or via tuntap.
    Can you provide a tut on it if not
    Any help will be great help for me. Config guide is provide on bocjs si5 but any changes in bochsrc leads to no boot same is with qemu.
    Thanks in advance

  6. Hi brezular, I did every thing you said on your post and Im able to ping the bridge form the guest machine and also ping the guest form the host.
    My problem is that Im trying to SSH the guest form the host and I keep getting ssh: connect to host xxx.xxx.xxx.xx port 22: Connection refused

    I installed OpenSHH-shell cleint and server on the host.

    Is there any particular setup that I have to do so I can SSH the guest from the host?

    1. When trying to do this with -M overo or -M beagle, model=e1000 is not emulated for this machines. Insted its model=lan9118.
      Does this setup nned a some special settings before making the VM joing the network? (The first post that I did was based on a x86-64 VM).

      I say this because when I get to the step:
      Guest OS – Microcore Linux
      1/ Configure IP address for eth0 interface (it is on the same subnet as virbr0)
      sudo su
      ifconfig eth0 172.16.1.1/16 up

      The guest VM says that no eth0 device was found.

      Thnx for any help that you can give me.

  7. I used the information to create a bridged interface for a qemu-kvm Windows Vista x86 VM running on openSuSE 12.1 x86_64. Worked great for myself and thanks for posting this useful article. I had been using VMware Player but, something about the dual displays kept locking up my system.

  8. This is fantastic information! You have helped me out immensely! I am in the process of building an ARM-based Debian image for use in a coding class and my problem was getting the network to bridge cleanly without too much effort. Your instructions were nearly spot on (except for the e1000 network interface - the ARM-based Debian image uses an SMC interface (in this case it's a SMC91C11 network card).

    Using the e1000 setting caused the kernel not to load anything (not even the e1000) and I couldn't get the interface up. Just leaving out the model=e1000 and macaddr= arguments brought the image up with a local network interface and IP address and I'm able to finish building the image (need to install developer tools). Thank you very much for this information!

  9. Can you please help and advise, how i can do it in Ubuntu/Kali linux, did not get any joy. Appreciated and looking forward hearing from you!
    Thanks in-advance

  10. If you want to use ip command in place of brctl and tunctl (both will be deprecated) then following conversion table may be helpful.

    brctl addbr virbr0 ---> ip link add br0 type bridge
    /usr/sbin/tunctl -t tap0 -u ab ---> ip tuntap add $1 mode tap user ab
    brctl addif virbr0 enp2s0 ---> ip link set eth0 master br0
    brctl addif virbr0 tap0 ---> ip link set tap0 master br0

    ifconfig tap0 up ---> ip link set dev tap0 up
    ifconfig virbr0 up ---> ip link set dev br0 up

    brctl stp virbr0 on ---> ip link set br0 type bridge stp_state 1

    ifconfig enp2s0 0.0.0.0 promisc ---> ip addr flush dev eth0

  11. I installed foss-cloud single server and created dynamic windows 10 machines. I wants to boot windows 10 vm with pxe directly but dont know how to do settings of dhcp configured with ldap. Dnsmasq.conf itself is not configured but available. Vmbr0 is runing.
    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.