Skip to content

feat: add support for passt network backend #1721

@alexhaydock

Description

@alexhaydock

I confirm this feature has not been previously requested

  • [ x ] I have searched the issues and this feature has not previously been requested

Is your feature request related to a problem? Please describe.
The passt network backend is a modern update to the -netdev user (aka slirp) network backend.

Benefits of passt:

  • Better performance
  • Proper support for IPv6 (rather than using the deprecated fec0::/10 range that causes userspace applications inside the guest to avoid using v6
  • Gives many of the benefits of using a bridge without needing to maintain a bridge interface (the IPv4 and IPv6 addresses used within the guest are drawn from the DHCPv4 and SLAAC pools used on the host
  • Userspace only (doesn't require admin privs)
  • Seamlessly handles the host being put to sleep, as well as the host switching between Wi-Fi/Ethernet networks

Describe the solution you'd like
Consider the ability to enable support for using passt on systems which support it.

This would require adding the passt dependency, detecting when it is available, and invoking it when able (or, if preferred, by explicit user enablement in the config file).

quickemu should be capable of starting the passt daemon as a process (if not already running), and adding the relevant passt network device config to the .sh file that launches the VM.

Describe alternatives you've considered
N/A

Additional context
A working example that starts passt and enables the relevant -device.

The only change from a current quickemu-generated start script is the two network lines have been replaced with the ones highlighted below, and passt is being started if needed to open the passt socket before starting the VM.

Tested on a Fedora 42 host with the following deps:

sudo dnf install quickemu passt

I'm definitely open to other ways of doing this. If this is agreed to be sensible, I might start working on a PR to add this as optional behaviour to be toggled in the .conf file.

#!/usr/bin/env bash

VMNAME="ubuntu"

test -f /tmp/passt_${VMNAME}.socket >/dev/null 2>/dev/null || nohup /usr/bin/passt -s /tmp/passt_${VMNAME}.socket -f --vhost-user >/dev/null 2>&1 &
nohup /usr/bin/qemu-system-x86_64 \
    -name ${VMNAME},process=${VMNAME} \
    -machine q35,smm=on,vmport=off,accel=kvm \
    -global kvm-pit.lost_tick_policy=discard \
    -cpu host \
    -smp cores=2,threads=2,sockets=1 \
    -m 16G \
    -device virtio-balloon \
    -pidfile ${VMNAME}/${VMNAME}.pid \
    -rtc base=utc,clock=host \
    -vga none \
    -device virtio-vga-gl,xres=1280,yres=800 \
    -display sdl,gl=on \
    -device virtio-rng-pci,rng=rng0 \
    -object rng-random,id=rng0,filename=/dev/urandom \
    -device qemu-xhci,id=spicepass \
    -chardev spicevmc,id=usbredirchardev1,name=usbredir \
    -device usb-redir,chardev=usbredirchardev1,id=usbredirdev1 \
    -chardev spicevmc,id=usbredirchardev2,name=usbredir \
    -device usb-redir,chardev=usbredirchardev2,id=usbredirdev2 \
    -chardev spicevmc,id=usbredirchardev3,name=usbredir \
    -device usb-redir,chardev=usbredirchardev3,id=usbredirdev3 \
    -device pci-ohci,id=smartpass \
    -device usb-ccid \
    -chardev spicevmc,id=ccid,name=smartcard \
    -device ccid-card-passthru,chardev=ccid \
    -device usb-ehci,id=input \
    -device usb-kbd,bus=input.0 \
    -k en-us \
    -device usb-tablet,bus=input.0 \
    -audiodev pipewire,id=audio0 \
    -device intel-hda \
    -device hda-micro,audiodev=audio0 \
    -global driver=cfi.pflash01,property=secure,value=on \
    -drive if=pflash,format=raw,unit=0,file=/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd,readonly=on \
    -drive if=pflash,format=raw,unit=1,file=${VMNAME}/OVMF_VARS.fd \
    -device virtio-blk-pci,drive=SystemDisk \
    -drive id=SystemDisk,if=none,format=qcow2,file=${VMNAME}/disk.qcow2 \
    -fsdev local,id=fsdev0,path=/var/home/user/Public,security_model=mapped-xattr \
    -device virtio-9p-pci,fsdev=fsdev0,mount_tag=Public-user \
    -monitor unix:${VMNAME}/${VMNAME}-monitor.socket,server,nowait \
    -serial unix:${VMNAME}/${VMNAME}-serial.socket,server,nowait \
    -chardev socket,id=chr0,path=/tmp/passt_${VMNAME}.socket \
    -netdev vhost-user,id=netdev0,chardev=chr0 \
    -device virtio-net,netdev=netdev0 \
    -object memory-backend-memfd,id=memfd0,share=on,size=16G \
    -numa node,memdev=memfd0 >/dev/null 2>&1 &

These are the lines from the file above which represent the passt enablement for the QEMU guest. They come directly from the STDOUT of the passt command line when executing it in --vhost-user mode (best performance):

    -chardev socket,id=chr0,path=/tmp/passt_${VMNAME}.socket \
    -netdev vhost-user,id=netdev0,chardev=chr0 \
    -device virtio-net,netdev=netdev0 \
    -object memory-backend-memfd,id=memfd0,share=on,size=16G \
    -numa node,memdev=memfd0 >/dev/null 2>&1 &

Note that the memory-backend-memfd line needs to specify the same size as the guest VM's main RAM.

Issues to solve

  • The passt userspace daemon seems to need to be started once per VM from what I can tell (at least in the mode being used above), so a creative solution might be needed to shut it down as Quickemu typically seems to detach from everything it spawns rather than staying resident. Perhaps there is another solution for this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions