scripts: add --user-network to qemustart

qemustart is a handy script to quickly test OpenWrt firmware using
qemu.  Bringing up networking currently requires a bridge-helper
setup with privileged IP and bridge assignment.  To simplify
testing scenarios like the package manager, which need both shell
access and outbound internet, add a user-mode networking option
backed by SLIRP that requires no privileges.

To stay backward compatible, the defaults don't change.  The new
flag --user-network attaches two NICs (LAN + WAN) and forwards
three host ports to the guest LAN interface (192.168.1.1):
2222 -> 22 (ssh), 8080 -> 80 (http) and 8443 -> 443 (https).  The
host-side ports can be overridden with --ssh-port, --http-port
and --https-port.

Link: https://github.com/openwrt/openwrt/pull/23424
Signed-off-by: Paul Spooren <mail@aparcar.org>
This commit is contained in:
Paul Spooren
2026-05-18 19:55:26 +02:00
parent b8a67fa8d5
commit a7b5926bba
+84 -21
View File
@@ -75,11 +75,36 @@ check_setup_() {
check_setup() { check_setup() {
[ -n "$o_network" ] || return 0 [ -n "$o_network" ] || return 0
[ -z "$o_user" ] || return 0
check_setup_ || { check_setup_ || {
__errmsg "please check the script content to see the environment requirement" __errmsg "please check the script content to see the environment requirement"
return 1 return 1
} }
} }
# Append user-mode networking args to o_qemu_extra. $1 is the qemu NIC device
# (e.g. virtio-net-pci, e1000). The LAN netdev shares OpenWrt's default LAN
# subnet so the guest's static 192.168.1.1 is reachable through SLIRP; the WAN
# netdev uses SLIRP defaults (10.0.2.0/24) to provide internet via the host.
add_user_netdev() {
local nic="$1"
local ssh="${o_ssh_port:-2222}"
local http="${o_http_port:-8080}"
local https="${o_https_port:-8443}"
__errmsg "user-mode networking: ssh on 127.0.0.1:$ssh, http on 127.0.0.1:$http, https on 127.0.0.1:$https"
local lan="user,id=lan,net=192.168.1.0/24,host=192.168.1.2"
lan+=",hostfwd=tcp:127.0.0.1:$ssh-192.168.1.1:22"
lan+=",hostfwd=tcp:127.0.0.1:$http-192.168.1.1:80"
lan+=",hostfwd=tcp:127.0.0.1:$https-192.168.1.1:443"
o_qemu_extra+=(
-netdev "$lan"
-device "$nic,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "user,id=wan"
-device "$nic,id=devwan,netdev=wan,mac=$MAC_WAN"
)
}
#do_setup; check_setup; exit $? #do_setup; check_setup; exit $?
usage() { usage() {
@@ -91,6 +116,7 @@ Usage: $SELF [-h|--help]
[--rootfs <rootfs>] [--rootfs <rootfs>]
[--machine <machine>] [--machine <machine>]
[-n|--network] [-n|--network]
[-u|--user-network [--ssh-port <port>] [--http-port <port>] [--https-port <port>]]
<subtarget> will default to "generic" and must be specified if <subtarget> will default to "generic" and must be specified if
<extra-qemu-options> are present <extra-qemu-options> are present
@@ -100,15 +126,31 @@ e.g. <subtarget> for malta can be le, be, le64, be64, le-glibc, le64-glibc, etc
<kernel>, <rootfs> can be required or optional arguments to qemu depending on <kernel>, <rootfs> can be required or optional arguments to qemu depending on
the actual <target> in use. They will default to files under bin/targets/ the actual <target> in use. They will default to files under bin/targets/
Networking modes:
-n / --network use bridges \$BR_LAN and \$BR_WAN (needs sudo + helper
setup)
-u / --user-network use rootless qemu user-mode networking; the guest LAN
interface (static 192.168.1.1) is reachable from the
host via 127.0.0.1:<ssh-port> (default 2222),
127.0.0.1:<http-port> (default 8080) and
127.0.0.1:<https-port> (default 8443); the guest WAN
gets internet via SLIRP
--ssh-port <p> override host-side ssh forward port (default 2222)
--http-port <p> override host-side http forward port (default 8080)
--https-port <p> override host-side https forward port (default 8443)
Examples Examples
$SELF x86 64 $SELF x86 64
$SELF x86 64 --user-network
$SELF x86 64 --user-network --ssh-port 2200 --http-port 8000 --https-port 8001
$SELF x86 64 --machine q35,accel=kvm -device virtio-balloon-pci $SELF x86 64 --machine q35,accel=kvm -device virtio-balloon-pci
$SELF x86 64 -incoming tcp:0:4444 $SELF x86 64 -incoming tcp:0:4444
$SELF x86 64-glibc $SELF x86 64-glibc
$SELF malta be -m 64 $SELF malta be -m 64
$SELF malta le64 $SELF malta le64
$SELF malta be-glibc $SELF malta be-glibc
$SELF armsr armv8 --user-network
$SELF armsr armv7 \\ $SELF armsr armv7 \\
--machine virt,highmem=off \\ --machine virt,highmem=off \\
--kernel bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-kernel.bin \\ --kernel bin/targets/armsr/armv7/openwrt-armsr-armv7-generic-kernel.bin \\
@@ -122,6 +164,7 @@ rand_mac() {
parse_args() { parse_args() {
o_network= o_network=
o_user=
o_qemu_extra=() o_qemu_extra=()
while [ "$#" -gt 0 ]; do while [ "$#" -gt 0 ]; do
# Cmdline options for the script itself SHOULD try to be # Cmdline options for the script itself SHOULD try to be
@@ -134,6 +177,10 @@ parse_args() {
--rootfs) o_rootfs="$2"; shift 2 ;; --rootfs) o_rootfs="$2"; shift 2 ;;
--machine|-machine|-M) o_mach="$2"; shift 2 ;; --machine|-machine|-M) o_mach="$2"; shift 2 ;;
--network|-n) o_network=1; shift ;; --network|-n) o_network=1; shift ;;
--user-network|-u) o_user=1; o_network=1; shift ;;
--ssh-port) o_ssh_port="$2"; shift 2 ;;
--http-port) o_http_port="$2"; shift 2 ;;
--https-port) o_https_port="$2"; shift 2 ;;
--help|-h) --help|-h)
usage usage
exit 0 exit 0
@@ -196,12 +243,16 @@ start_qemu_armsr() {
} }
[ -z "$o_network" ] || { [ -z "$o_network" ] || {
o_qemu_extra+=( \ if [ -n "$o_user" ]; then
"-netdev" "bridge,id=lan,br=$BR_LAN,helper=$HELPER" \ add_user_netdev virtio-net-pci
"-device" "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN" \ else
"-netdev" "bridge,id=wan,br=$BR_WAN,helper=$HELPER" "-device" \ o_qemu_extra+=( \
"virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN" \ "-netdev" "bridge,id=lan,br=$BR_LAN,helper=$HELPER" \
) "-device" "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN" \
"-netdev" "bridge,id=wan,br=$BR_WAN,helper=$HELPER" "-device" \
"virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN" \
)
fi
} }
"$qemu_exe" -machine "$mach" -cpu "$cpu" -nographic \ "$qemu_exe" -machine "$mach" -cpu "$cpu" -nographic \
@@ -236,14 +287,18 @@ start_qemu_malta() {
) )
} }
# NOTE: order of wan, lan -device arguments matters as it will affect which # NOTE: order of -device arguments matters: the first -device becomes eth0
# one will be actually used as the wan, lan network interface inside the # in the guest, which OpenWrt's 99-default_network assigns as LAN; the
# guest machine # second becomes eth1 / WAN. Keep LAN first to match that mapping.
[ -z "$o_network" ] || { [ -z "$o_network" ] || {
o_qemu_extra+=( if [ -n "$o_user" ]; then
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device pcnet,netdev=lan,mac="$MAC_LAN" add_user_netdev pcnet
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device pcnet,netdev=wan,mac="$MAC_WAN" else
) o_qemu_extra+=(
-netdev bridge,id=lan,br="$BR_LAN,helper=$HELPER" -device pcnet,netdev=lan,mac="$MAC_LAN"
-netdev bridge,id=wan,br="$BR_WAN,helper=$HELPER" -device pcnet,netdev=wan,mac="$MAC_WAN"
)
fi
} }
"$qemu_exe" -machine "$mach" -cpu "$cpu" -nographic \ "$qemu_exe" -machine "$mach" -cpu "$cpu" -nographic \
@@ -287,16 +342,24 @@ start_qemu_x86() {
[ -z "$o_network" ] || { [ -z "$o_network" ] || {
case "${o_subtarget%-*}" in case "${o_subtarget%-*}" in
legacy) legacy)
o_qemu_extra+=( if [ -n "$o_user" ]; then
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "e1000,id=devlan,netdev=lan,mac=$MAC_LAN" add_user_netdev e1000
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "e1000,id=devwan,netdev=wan,mac=$MAC_WAN" else
) o_qemu_extra+=(
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "e1000,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "e1000,id=devwan,netdev=wan,mac=$MAC_WAN"
)
fi
;; ;;
generic|64) generic|64)
o_qemu_extra+=( if [ -n "$o_user" ]; then
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN" add_user_netdev virtio-net-pci
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN" else
) o_qemu_extra+=(
-netdev "bridge,id=lan,br=$BR_LAN,helper=$HELPER" -device "virtio-net-pci,id=devlan,netdev=lan,mac=$MAC_LAN"
-netdev "bridge,id=wan,br=$BR_WAN,helper=$HELPER" -device "virtio-net-pci,id=devwan,netdev=wan,mac=$MAC_WAN"
)
fi
;; ;;
esac esac
} }