Skip to content

Instantly share code, notes, and snippets.

@mcastelino
Last active December 16, 2024 19:18
Show Gist options
  • Save mcastelino/88195a7d99811a177f5e643d1465e19e to your computer and use it in GitHub Desktop.
Save mcastelino/88195a7d99811a177f5e643d1465e19e to your computer and use it in GitHub Desktop.
QEMU usermode virtual vlan using -netdev socket

Goal

How to launch multiple QEMU based VM's that can communicate with the outside world and between each other other without any setup on the host.

This uses two features available in qemu

  • User Mode Networking stack - SLIRP
  • Socket networking backend allows you to create a network of guests that can see each other

This allows us to have

  • SLIRP to communicate to the outside world
  • multicast to communicate between the VMs
  • And it uses the multicast to allow the host to communicate with the guests

Virtual Machine launch

VMN=1
qemu-system-x86_64 \
    -machine pc,accel=kvm,kernel_irqchip \
    -enable-kvm \
    -bios OVMF.fd \
    -smp sockets=1,cpus=4,cores=2 -cpu host \
    -m 1024 \
    -vga none -nographic \
    -drive file="$IMAGE",if=virtio,aio=threads,format=raw \
    -netdev user,id=mynet0,hostfwd=tcp::${VMN}0022-:22,hostfwd=tcp::${VMN}2375-:2375 \
    -device virtio-net-pci,netdev=mynet0 \
    -netdev socket,id=vlan,mcast=230.0.0.1:1234 \
    -device virtio-net-pci,netdev=vlan \

You can add any number of VM's to this socket network, choosing a different value for VMN

Connecting to this network from the host

You can use socat to create a tap interface on the host with an IP in the same subnet as you want to VLAN to be on and

sudo socat UDP4-DATAGRAM:230.0.0.1:1234,sourceport=1234,reuseaddr,ip-add-membership=230.0.0.1:127.0.0.1 TUN:10.0.3.1/24,tun-type=tap,iff-no-pi,iff-up,tun-name=vmvlan0

This will create a tap interface vmvlan0 on the host with IP: 10.0.3.1

We can run a DHCP server on this tap interface to allow for seamless configuration of the VLAN driven by the host

DHCP based VLAN configuration

To assign IP addresss to these VM's from the host you can use dnsmasq serving DHCP on the vmvlan0 interface.

sudo -E dnsmasq --conf-file=dnsmasq.conf --leasefile-ro

dnsmasq.conf

strict-order
pid-file=default.pid
except-interface=lo
bind-dynamic
interface=vmvlan0
dhcp-range=10.0.3.100,10.0.3.200
dhcp-no-override
dhcp-authoritative
dhcp-lease-max=253
@narcisgarcia
Copy link

In a Debian 12 host (Qemu 7.2.13), not using superuser privileges,
I launch VM1:

$ qemu-system-x86_64 -name "Windows XP" (...)
    -device rtl8139,netdev=net0
    -netdev user,id=net0
    -netdev socket,id=vlan-winxp,mcast=230.0.0.1:1234
    -device rtl8139,netdev=vlan-winxp

and VM2:

$ qemu-system-x86_64 -name debian10 (...)
    -device rtl8139,netdev=net0
    -netdev user,id=net0,smb=/home/_all/public
    -netdev socket,id=vlan-winxp,mcast=230.0.0.1:1234
    -device virtio-net-pci,netdev=vlan-winxp

Then in guest VM1 first (default) NIC acquires address 10.0.2.15/24 and I configure manually second NIC to have address 192.168.139.1/24
In guest VM2 first (default) NIC also acquires address 10.0.2.15/24 and I configure manually second NIC to have address 192.168.139.139/24

From VM1 I ping to 192.168.139.139 with result "Timeout"
From VM2 I ping to 192.168.139.1 with result "Destination Host Unreachable"

@kristianlm
Copy link

Hi @mcastelino , thanks for this writeup! I helped me set up my own multicast-based QEMU VLAN. I did a quick description of that I did here.

@mcastelino
Copy link
Author

Hi @mcastelino , thanks for this writeup! I helped me set up my own multicast-based QEMU VLAN. I did a quick description of that I did here.

Nice. You took it a long way :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment