qemu How to bridge QEMU interface to physical Ethernet?

cracauer@

Developer
I am trying to run a QEMU VM while bridging the virtual network interface to my physical Ethernet. The physical interface is cabled so the usual Wifi problem with spoofing doesn't apply.

Here is what I have and it doesn't work:
Code:
qemu-system-x86_64 \
  -object rng-random,id=rng0,filename=/dev/urandom \
  -device virtio-rng-pci,rng=rng0 \
  -smp 4 \
  -m 4G \
  -nographic \
  -drive if=pflash,format=raw,file=OVMF_CODE_4M.fd \
  -drive file=ipxe.raw,format=raw,index=0,media=disk \
  -device virtio-net,netdev=vmnic,mac=00:a0:98:ea:28:35 \
  -netdev tap,id=vmnic,ifname=tap1,script=no,downscript=no,br=bridge0 \
  -device usb-ehci

There is nothing making it in or out according to tcpdump on the physical Ethernet. Can anybody spot what is wrong?

Specific question:
  • Does the "br=bridge0" option to -netdev automatically add the tap interface to the bridge? It tried manually adding tap1 to the bridge and not doing it, neither seem to work.
 
Do the empty executable files qemu-ifup and qemu-ifdown exist?
I remember this was called by Qemu because the tap device is stateless. Not sure if it's still needed.

ln -fs /usr/bin/true /etc/qemu-ifup
ln -fs /usr/bin/true /etc/qemu-ifdown
 
What does ifconfig bridge0 look like? Does it show your physical NIC and tap1 as members?

Present and accounted for:
Code:
bridge0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0
        options=10<VLAN_HWTAGGING>
        ether 58:9c:fc:10:cc:75
        id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
        maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
        root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
        bridge flags=0<>
        member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                port 7 priority 128 path cost 2000000 vlan protocol 802.1q
        member: tap1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                port 5 priority 128 path cost 55 vlan protocol 802.1q
        member: em0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
                port 3 priority 128 path cost 20000 vlan protocol 802.1q
        groups: bridge
        nd6 options=9<PERFORMNUD,IFDISABLED>
 
Do the empty executable files qemu-ifup and qem-ifdown exist?
I remember this was called by Qemu because the tap device is stateless. Not sure if it's still needed.

ln -fs /usr/bin/true /etc/qemu-ifup
ln -fs /usr/bin/true /etc/qemu-ifdown

I don't have them. Will create.

ETA: did not help
 
I don't have them. Will create.

ETA: did not help
Found an old prepare script that at least worked in FreeBSD 14.x. Maybe it's the sysctl settings...

Code:
#!/usr/local/bin/bash
sysctl net.link.tap.user_open=1
sysctl net.link.tap.up_on_open=1
if [ -z "$(ifconfig | grep tap0)" ]
then
  ifconfig tap0 create
  ifconfig tap0 up
fi
if [ -z "$(ifconfig | grep bridge0)" ]
then
  ifconfig bridge0 create
  ifconfig bridge0 addm re0
  ifconfig bridge0 addm tap0
  ifconfig bridge0 up
fi
ln -fs /usr/bin/true /etc/qemu-ifup
ln -fs /usr/bin/true /etc/qemu-ifdown
chmod u+x /etc/qemu-if*
 
Found an old prepare script that at least worked in FreeBSD 14.x. Maybe it's the sysctl settings...

Code:
#!/usr/local/bin/bash
sysctl net.link.tap.user_open=1
sysctl net.link.tap.up_on_open=1
if [ -z "$(ifconfig | grep tap0)" ]
then
  ifconfig tap0 create
  ifconfig tap0 up
fi
if [ -z "$(ifconfig | grep bridge0)" ]
then
  ifconfig bridge0 create
  ifconfig bridge0 addm re0
  ifconfig bridge0 addm tap0
  ifconfig bridge0 up
fi
ln -fs /usr/bin/true /etc/qemu-ifup
ln -fs /usr/bin/true /etc/qemu-ifdown
chmod u+x /etc/qemu-if*

Hey that worked!

So it was either the sysctl settings or the "tap1 up". Will narrow down later.

On to the next problem: iPXE doesn't like my root-path from the dhcp server...
 
Looks like iPXE has two problems with my FreeBSD PXE boot:

Code:
net0: 172.18.27.127/255.255.0.0 gw 172.18.30.2
net0: fd20:eba7:3816::944/64 gw fe80::a33:edff:fe86:6c72
net0: fe80::2a0:98ff:feea:2835/64
Next server: 172.18.30.2
Filename: pxeboot.nodelay
Root path: 172.18.30.2:/home/diskless/freebsd-current-root1
Ignoring unsupported root path
tftp://172.18.30.2/pxeboot.nodelay... ok
pxeboot.nodelay : 456704 bytes
Could not boot image: Exec format error (https://ipxe.org/2e008081)
No more network devices

BdsDxe: failed to start Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0r

Slightly uphill this whole project.
 
iPXE doesn't seem to like Linux PXE either:
Code:
Configuring (net0 00:a0:98:ea:28:35)...DHCP 0xbd802268 DHCPDISCOVER             
DHCP 0xbd802268 DHCPOFFER from 172.16.30.1:67 for 172.18.27.128                 
.DHCP 0xbd802268 DHCPDISCOVER                                                   
DHCP 0xbd802268 DHCPOFFER from 172.16.30.1:67 for 172.18.27.128                 
..DHCP 0xbd802268 entering request state                                        
DHCP 0xbd802268 DHCPREQUEST to 172.16.30.1:67 for 172.18.27.128                 
DHCP 0xbd802268 DHCPACK from 172.16.30.1:67 for 172.18.27.128                   
 ok
net0: 172.18.27.128/255.255.0.0 gw 172.18.30.2
net0: fd20:eba7:3816::944/64 gw fe80::a33:edff:fe86:6c72
net0: fe80::2a0:98ff:feea:2835/64
Next server: 172.16.30.1
Filename: pxelinux.0.20200418
tftp://172.16.30.1/pxelinux.0.20200418... ok
pxelinux.0.20200418 : 42430 bytes
Could not boot image: Exec format error (https://ipxe.org/2e008081)
No more network devices
 
Hey that worked!

So it was either the sysctl settings or the "tap1 up". Will narrow down later.

On to the next problem: iPXE doesn't like my root-path from the dhcp server...

Actually it is neither.

What needs to happen if a `ifconfig tap1 up` before every qemu start. Then I get the reply packets.
 
And although this trick makes the tap interface in the bridge work for running inside qemu it does not make it work for running inside bhyve. Sigh.
 
Actually it is neither.

What needs to happen if a `ifconfig tap1 up` before every qemu start. Then I get the reply packets.
I had a struggle with this. The ifup/ifdown was probably docoumented somewhere for an earlier qemu version. That script was extreme "make it work first" approach. It has been unreliable for some time. I remember a situation where 2 emulated network nodes had to be pinging eachother on the background to be visible. 😆
 
Back
Top