TransWikia.com

QEMU - network bridge

Unix & Linux Asked by Matthew Lugg on January 6, 2022

I’m setting up a VM on Debian 9 using QEMU (and KVM). I’m currently trying to make it work through a bridged network, which I have set up using ip link, ip tuntap etc; here is the output of brctl show:

bridge name     bridge id               STP enabled     interfaces
br0             8000.107b444f55d6       no              enp4s0
                                                        tap0
docker0         8000.0242d4c18983       no

And here is the output of ip a:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
    link/ether 10:7b:44:4f:55:d6 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 02:42:d4:c1:89:83 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
4: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN group default qlen 1000
    link/ether f6:54:bb:db:d7:c6 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::f454:bbff:fedb:d7c6/64 scope link
       valid_lft forever preferred_lft forever
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 10:7b:44:4f:55:d6 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.26/24 brd 192.168.0.255 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::127b:44ff:fe4f:55d6/64 scope link
       valid_lft forever preferred_lft forever

The docker0 interface is unrelated.

As far as I can tell, this should be working. However, my Windows 8.1 guest within QEMU has no internet access, and is unable to acquire an IP over DHCP (I’m simply getting auto-generated 169.xx.xx.xx IPs).

I’m unsure as to why this is. My QEMU arguments are:

-net nic -net tap,ifname=tap0

and I’ve also tried:

-device e1000,netdev=net0,mac=52:55:00:d1:55:01 -netdev tap,id=net0

which both yield the same result of no network access. I can’t figure this out.

Am I doing something stupid?

2 Answers

I am currently struggling with this problem as well. I've come a bit closer to the solution than you.

I am on Debian 10 and I decidd to only use the a package iproute2 (ip link, ip addr, bridge link...) which is part of a kernel and will be available on any Linux. and package qemu-kvm. This is everything you need.




STEP 1

Open 1st terminal and write this down, so that you will be able to see your progres:

while true; do ip addr; sleep 1; clear; done



STEP 2

Open 2nd terminal and execute these commmands while you look at the progress in the 1st terminal:

sudo ip link add virtual_bridge type bridge
sudo ip link set virtual_bridge up

And you have a bridge which is up.




JUST AN EXPERIMENT BEFORE YOU CONTINUE

Your virtual_bridge is now up but your ethernet card might be up or down. Now read these two scenarios I figured out by trial and error. It is very important (!) so that you will understand how your ethernet card reacts. You might try this or not, but I advise you to do it exactly like described below while watching the 1st terminal for changes.

Scenario A:

If your ethernet card is down try to assign a master to it with a command below. It will work:

sudo ip link set enx24f5a2f17b27 master virtual_bridge

and now turn it on:

sudo ip link set enx24f5a2f17b27 up

you will be surprised that card won't connect you to the internet. It won't make it even if you restart it:

sudo ip link set enx24f5a2f17b27 down
sudo ip link set enx24f5a2f17b27 up

and not even if you restart the bridge that is card's master who should control it:

sudo ip link set virtual_bridge down
sudo ip link set virtual_bridge up

the only way I managed to make it connect to the internet was to restart the card, remove the master, flush it to remove all IP (maybe this isn't needed), manualy assign a known & working IP and then assign the master:

sudo ip link set enx24f5a2f17b27 down
sudo ip link set enx24f5a2f17b27 up
sudo ip addr flush enx24f5a2f17b27
sudo ip addr add 192.168.64.100/24 dev enx24f5a2f17b27
sudo ip link set enx24f5a2f17b27 master virtual_bridge

At this point internet should start working.

Scenario B:

If your ethernet card is up it probably has an IP and your internet must be working. So now try to assign it a master with a command below. It will work!

sudo ip link set enx24f5a2f17b27 master virtual_bridge

Now reset the bridge multiple times and pay attention what happens to a card:

sudo ip link set virtual_bridge down
sudo ip link set virtual_bridge up
sudo ip link set virtual_bridge down
sudo ip link set virtual_bridge up

You will see that whenever you enable the bridge ethernet card will also be enabled, it will get IP and connect to the internet. But once you turn off the card:

sudo ip link set enx24f5a2f17b27 down

it won't be able to reconect to the internet no mater how many times you reset the bridge.

So this is why it is most important that you first turn on the ethernet card and second asign it a master and not the other way around! In other words card should be enabled when you are assigning a master.




STEP 3

As we learned from the example above, we first (!) turn on the ethernet card which will get an IP:

sudo ip link set enx24f5a2f17b27 up

and then we assign it a master:

sudo ip link set enx24f5a2f17b27 master virtual_bridge

we create a TAP device which is like a virtual ethernet card for the virtual machine. It is important (!) that you assign a user and a group to it, because it might not have proper privileges otherwise:

sudo ip tuntap add virtual_tap mode tap user ziga group ziga

Now that you created it, you can try to enable it, but you won't suceed, because only virtual machine can do that:

sudo ip link set virtual_tap up

so it will remain in the down state. Just apply the master to it as well:

sudo ip link set virtual_tap master virtual_bridge

and you are done with setting up the network. Pay attention that at this point your TAP device won't have IP. It will be assigned to it when you start the virtual machine and wait for virtual machine to set itself up.




STEP 4

Now it is time to properly start the virtual machine. I do it using the newest -nic command which is shorter and more capable (!) than old commands (read). Well anyway... I use this command:

qemu-system-x86_64 -enable-kvm -cpu host -smp cores=3,threads=1 -m 4096 -nic tap,ifname=virtual_tap,script=no,downscript=no -boot order=c -cdrom ~/Dropbox/workspace/racunalnistvo/programi/kvm/iso/centos-8.1.1911-x86_64-dvd1.iso -drive file=~/Dropbox/workspace/racunalnistvo/programi/kvm/vm/windows.qcow2,format=qcow2

If you ommit options script=no and downscript=no the above comand will return a harmless warning:

RTNETLINK answers: Operation not permitted
W: /etc/qemu-ifup: no bridge for guest interface found

which happens because prior to emulation Qemu tryies to auto set up it's own bridge & TAP with a script /etc/qemu-ifup. It will also try to remove the bridge & TAP after it is finished with a script /etc/qemu-ifdown. If you look into these scripts you will see that they use command brctl which is part of a package bridge-utils that I don't have installed and scripts fail!

We created the bridge & TAP devices manually anyway so we don't need those scripts and we prevent Qemu to call them with script=no and downscript=no.

It would be interesting to rewrite these scripts to use iproute2 instead of bridge-utils but you would need root privileges to run them and experts disadvise us running virtual machines as root.

Virtual machine will start, connect to the internet, but it won't be able to ping host! Also the host will be able to connect to the internet and will be able to ping the same gateway. But it won't be able to ping a virtual machine!

Also pay attention to the 1st terminal where you will see that TAP device is now enabled and it got an IP, but this IP here is different than the one you see from inside the virtual machine! Can anyone explain this?




TODO

This is how much I was able to figure out and I hope it helps someone. I stil don't know why host and virtual machine can't ping eachother as TAP device should enable TCP, UDP & ICMP... I suspect that it is because I have to somehow assign IP to the bridge (read, read) but I don't know how to choose the right one. Can anyone help in the comments?

Answered by 71GA on January 6, 2022

I've just had a very similar problem with a QEMU Linux guest and it has turned out that iptables was blocking the traffic. If I set up a static IP address for the guest then the host and the guest could ping each other but that was it. The internet and the rest of my network couldn't be reached from the guest machine.

I highly recommend you to use something like Wireshark or tcpdump to investigate the problem.

I've captured the bridge interface from the host using Wireshark and it seemed like requests were coming out from the virtual machine but no response was received.

enter image description here

TL;DR: This clue led me to the magic iptable commands (it was magical for me because I'm not experienced enough with iptables :)) in the following answer:

https://serverfault.com/a/165786

It worked and even if I don't fully understand it at this very moment I thought I would leave my two cents here.

Good luck!

Answered by Kuklin István on January 6, 2022

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP