From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202606 header.b=lAOTWqv6; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 177825A0271 for ; Sun, 19 Jul 2026 06:21:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202606; t=1784434863; bh=wbZ6BPpZ0Y6gb0bm+SC8oNfFlYOYu52cVAqgFDN/VzQ=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=lAOTWqv6nHjS07NTjeQcr2Mn9wNMwUlmeNkvKnjwcjSIxK6dkI4FJDmlNE0dRGVbD H8cjHI9WcSyRy+2TvRvDTfkXeDWFaOFV7s7OKjpuBO3ewx3EEabe2nhoDtCHJVObDT kLeaVsOLFTm1kvMxpEkVFgNCmPVPJfISyQfq1VO03kBhiJpwS31FXEGvw9QpK/u7ai CUFqkxmJG6k6jzOFHryIjtFvhJNh/Rdde/9XeBwjL/wa4gpeY7ltNj0636Li2/9HZg MyDM9heuIIAH56zvvXtcmv0sOgTzSGehYq+vafHBzLkA3jbZwR76Yc5oE5WQ5F9QNX xL5jdBmfo6kDA== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4h2r730HZVz4w8x; Sun, 19 Jul 2026 14:21:03 +1000 (AEST) Date: Sun, 19 Jul 2026 14:03:43 +1000 From: David Gibson To: Stefano Brivio Subject: Re: [PATCH] treewide: Sandbox qrap Message-ID: References: <20260718074225.1331134-1-sbrivio@redhat.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="KUIfFCXcrjZX4IP/" Content-Disposition: inline In-Reply-To: <20260718074225.1331134-1-sbrivio@redhat.com> Message-ID-Hash: LNKCTGOAMA6RXRDGEP6CURWCWYPZW7LZ X-Message-ID-Hash: LNKCTGOAMA6RXRDGEP6CURWCWYPZW7LZ X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: passt-dev@passt.top, Andrea Bolognani X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --KUIfFCXcrjZX4IP/ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Jul 18, 2026 at 09:42:25AM +0200, Stefano Brivio wrote: > No sunsetting or rightsizing for you, qrap: dig, bury, and cover. >=20 > Signed-off-by: Stefano Brivio Hooray! Reviewed-by: David Gibson > --- > .gitignore | 1 - > Makefile | 11 +- > README.md | 4 - > contrib/fedora/passt.spec | 2 - > doc/demo.sh | 12 +- > doc/passt_overview.excalidraw | 29 --- > hooks/pre-push | 2 +- > passt.1 | 235 ++++++++++--------- > qrap.1 | 77 ------ > qrap.c | 429 ---------------------------------- > tap.c | 2 - > test/distro/opensuse | 2 +- > 12 files changed, 127 insertions(+), 679 deletions(-) > delete mode 100644 qrap.1 > delete mode 100644 qrap.c >=20 > diff --git a/.gitignore b/.gitignore > index 3e40d9f..71420b6 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -5,7 +5,6 @@ > /pasta.avx2 > /passt-repair > /pesto > -/qrap > /pasta.1 > /seccomp.h > /seccomp_pesto.h > diff --git a/Makefile b/Makefile > index 5757aef..77474d6 100644 > --- a/Makefile > +++ b/Makefile > @@ -39,13 +39,12 @@ PASST_SRCS =3D arch.c arp.c bitmap.c checksum.c conf.= c dhcp.c dhcpv6.c \ > parse.c passt.c pasta.c pcap.c pif.c repair.c serialise.c tap.c tcp.c \ > tcp_buf.c tcp_splice.c tcp_vu.c udp.c udp_flow.c udp_vu.c util.c \ > vhost_user.c virtio.c vu_common.c > -QRAP_SRCS =3D qrap.c > PASST_REPAIR_SRCS =3D passt-repair.c > PESTO_SRCS =3D pesto.c bitmap.c fwd_rule.c inany.c ip.c lineread.c parse= =2Ec \ > serialise.c > -SRCS =3D $(PASST_SRCS) $(QRAP_SRCS) $(PASST_REPAIR_SRCS) $(PESTO_SRCS) > +SRCS =3D $(PASST_SRCS) $(PASST_REPAIR_SRCS) $(PESTO_SRCS) > =20 > -MANPAGES =3D passt.1 pasta.1 pesto.1 qrap.1 passt-repair.1 > +MANPAGES =3D passt.1 pasta.1 pesto.1 passt-repair.1 > =20 > PASST_HEADERS =3D arch.h arp.h bitmap.h checksum.h conf.h dhcp.h dhcpv6.= h \ > epoll_ctl.h flow.h fwd.h fwd_rule.h flow_table.h icmp.h icmp_flow.h \ > @@ -54,7 +53,6 @@ PASST_HEADERS =3D arch.h arp.h bitmap.h checksum.h conf= =2Eh dhcp.h dhcpv6.h \ > serialise.h siphash.h tap.h tcp.h tcp_buf.h tcp_conn.h tcp_internal.h \ > tcp_splice.h tcp_vu.h udp.h udp_flow.h udp_internal.h udp_vu.h util.h \ > vhost_user.h virtio.h vu_common.h > -QRAP_HEADERS =3D arp.h ip.h passt.h util.h > PASST_REPAIR_HEADERS =3D linux_dep.h > PESTO_HEADERS =3D bitmap.h common.h fwd_rule.h inany.h ip.h log.h parse.= h \ > pesto.h serialise.h > @@ -76,7 +74,7 @@ docdir ?=3D $(datarootdir)/doc/passt > mandir ?=3D $(datarootdir)/man > man1dir ?=3D $(mandir)/man1 > =20 > -BASEBIN :=3D passt qrap passt-repair pesto > +BASEBIN :=3D passt passt-repair pesto > ifeq ($(TARGET_ARCH),x86_64) > BASEBIN +=3D passt.avx2 > endif > @@ -112,9 +110,6 @@ passt.avx2: $(PASST_SRCS) $(PASST_HEADERS) seccomp.h > pasta.avx2 pasta.1 pasta: pasta%: passt% > ln -sf $< $@ > =20 > -qrap: BASE_CPPFLAGS +=3D -DARCH=3D\"$(TARGET_ARCH)\" > -qrap: $(QRAP_SRCS) $(QRAP_HEADERS) > - > passt-repair: $(PASST_REPAIR_SRCS) $(PASST_REPAIR_HEADERS) seccomp_repai= r.h > =20 > pesto: BASE_CPPFLAGS +=3D -DPESTO > diff --git a/README.md b/README.md > index 8fdc0a3..43caf49 100644 > --- a/README.md > +++ b/README.md > @@ -376,10 +376,6 @@ speeding up local connections, and usually requiring= NAT. _pasta_: > _passt_ exchanges packets with _qemu_ via UNIX domain socket, using the = `socket` > back-end in qemu. This is supported since qemu 7.2. > =20 > -For older versions, the [qrap](/passt/tree/qrap.c) wrapper can be used to > -connect to a UNIX domain socket and to start qemu, which can now use the= file > -descriptor that's already opened. > - > This approach, compared to using a _tap_ device, doesn't require any sec= urity > capabilities, as we don't need to create any interface. > =20 > diff --git a/contrib/fedora/passt.spec b/contrib/fedora/passt.spec > index 34838af..6c7530a 100644 > --- a/contrib/fedora/passt.spec > +++ b/contrib/fedora/passt.spec > @@ -118,12 +118,10 @@ fi > %doc %{_docdir}/%{name}/demo.sh > %{_bindir}/passt > %{_bindir}/pasta > -%{_bindir}/qrap > %{_bindir}/passt-repair > %{_bindir}/pesto > %{_mandir}/man1/passt.1* > %{_mandir}/man1/pasta.1* > -%{_mandir}/man1/qrap.1* > %{_mandir}/man1/passt-repair.1* > %{_mandir}/man1/pesto.1* > %ifarch x86_64 > diff --git a/doc/demo.sh b/doc/demo.sh > index 6b0917c..b56669f 100755 > --- a/doc/demo.sh > +++ b/doc/demo.sh > @@ -177,7 +177,7 @@ into_ns() { > next > [ "${KEY}" =3D "s" ] && ${SHELL} > =20 > - cmd passt -P "${DEMO_DIR}/passt.pid" > + cmd passt -P "${DEMO_DIR}/passt.pid" -s "${DEMO_DIR}/passt.socket" > echo > echo "...passt is running." > next > @@ -198,15 +198,12 @@ into_ns() { > echo "can download and use mbuto (https://mbuto.sh/) to build a" > echo "basic initramfs image. Otherwise, press 's' to skip this" > echo "step, and start an existing virtual machine yourself." > - echo "You'll need to use the qrap(1) wrapper, with qemu options" > - echo "as reported above." > =20 > next > else > echo "This script doesn't know, yet, how to run a virtual" > echo "machine on your architecture (${__arch}). Please start an" > - echo "existing virtual machine yourself, using the qrap(1)" > - echo "wrapper, with qemu options as reported above." > + echo "existing virtual machine yourself." > echo > fi > =20 > @@ -225,12 +222,13 @@ into_ns() { > next > =20 > # shellcheck disable=3DSC2086 > - cmd qrap 5 ${__qemu_arch} \ > + cmd ${__qemu_arch} \ > -smp "$(nproc)" -m 1024 \ > -nographic -serial stdio -nodefaults -no-reboot -vga none \ > -initrd "${DEMO_DIR}/demo.img" \ > -kernel "/boot/vmlinuz-$(uname -r)" -append "console=3DttyS0" \ > - -net socket,fd=3D5 -net nic,model=3Dvirtio || : > + -device virtio-net-pci,netdev=3Ds \ > + -netdev stream,id=3Ds,server=3Doff,addr.type=3Dunix,addr.path=3D"${DEM= O_DIR}/passt.socket" || : > } > =20 > STTY_BACKUP=3D"$(stty -g)" > diff --git a/doc/passt_overview.excalidraw b/doc/passt_overview.excalidraw > index 790728e..3217b3f 100644 > --- a/doc/passt_overview.excalidraw > +++ b/doc/passt_overview.excalidraw > @@ -3595,35 +3595,6 @@ > "baseline": 17, > "textAlign": "left", > "verticalAlign": "top" > - }, > - { > - "type": "text", > - "version": 1448, > - "versionNonce": 1345391945, > - "isDeleted": false, > - "id": "c-esZiuHSm3wnTRlmIJZk", > - "fillStyle": "hachure", > - "strokeWidth": 1, > - "strokeStyle": "dotted", > - "roughness": 1, > - "opacity": 100, > - "angle": 4.969352159599495, > - "x": 816.7081559166961, > - "y": 215.74807066759342, > - "strokeColor": "#2b8a3e", > - "backgroundColor": "transparent", > - "width": 211, > - "height": 23, > - "seed": 939668423, > - "groupIds": [], > - "strokeSharpness": "round", > - "boundElementIds": [], > - "fontSize": 20, > - "fontFamily": 1, > - "text": "(currently \"qrap\" wrapper)", > - "baseline": 17, > - "textAlign": "left", > - "verticalAlign": "top" > } > ], > "appState": { > diff --git a/hooks/pre-push b/hooks/pre-push > index 3e2d15f..8eebdbc 100755 > --- a/hooks/pre-push > +++ b/hooks/pre-push > @@ -54,7 +54,7 @@ done > cd .. > =20 > make pkgs > -scp passt passt.avx2 passt.1 qrap qrap.1 "${USER_HOST}:${BIN}" > +scp passt passt.avx2 passt.1 "${USER_HOST}:${BIN}" > scp pasta pasta.avx2 pasta.1 "${USER_HOST}:${BIN}" > scp passt-repair passt-repair.1 "${USER_HOST}:${BIN}" > scp pesto pesto.1 "${USER_HOST}:${BIN}" > diff --git a/passt.1 b/passt.1 > index 995590a..53e072a 100644 > --- a/passt.1 > +++ b/passt.1 > @@ -580,8 +580,7 @@ Default is \fBnone\fR for \fBpasst\fR and \fBauto\fR = for \fBpasta\fR. > =20 > .TP > .BR \-s ", " \-\-socket-path ", " \-\-socket " " \fIpath > -Path for UNIX domain socket used by \fBqemu\fR(1) or \fBqrap\fR(1) to co= nnect to > -\fBpasst\fR. > +Path for UNIX domain socket used by \fBqemu\fR(1) to connect to \fBpasst= \fR. > Default is to probe a free socket, not accepting connections, starting f= rom > \fI/tmp/passt_1.socket\fR to \fI/tmp/passt_64.socket\fR. > =20 > @@ -762,129 +761,132 @@ forwards loopback traffic between namespaces. > .RS > .nf > $ iperf3 -s -D > -$ ./pasta > -Outbound interface: eth0, namespace interface: eth0 > -ARP: > - address: 28:16:ad:39:a9:ea > -DHCP: > - assign: 192.168.1.118 > - mask: 255.255.255.0 > - router: 192.168.1.1 > -NDP/DHCPv6: > - assign: 2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17 > - router: fe80::62e3:27ff:fe33:2b01 > -# > -# dhclient -4 --no-pid > -# dhclient -6 --no-pid > + > +$ pasta --config-net > + > # ip address show > 1: lo: mtu 65536 qdisc noqueue state UNKNOWN grou= p 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=20 > + inet6 ::1/128 scope host proto kernel_lo=20 > valid_lft forever preferred_lft forever > -2: eth0: mtu 65520 qdisc pfifo_fast st= ate UNKNOWN group default qlen 1000 > - link/ether 5e:90:02:eb:b0:2a brd ff:ff:ff:ff:ff:ff > - inet 192.168.1.118/24 brd 192.168.1.255 scope global eth0 > +2: enp9s0: mtu 65520 qdisc fq_codel st= ate UNKNOWN group default qlen 1000 > + link/ether be:16:49:5a:65:dc brd ff:ff:ff:ff:ff:ff > + inet 88.198.0.164/27 brd 88.198.0.191 scope global noprefixroute enp= 9s0 > valid_lft forever preferred_lft forever > - inet6 2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17/128 scope global=20 > + inet6 2a01:4f8:222:904::2/64 scope global nodad=20 > valid_lft forever preferred_lft forever > - inet6 2a02:6d40:3ca5:2001:5c90:2ff:feeb:b02a/64 scope global dynamic= mngtmpaddr=20 > - valid_lft 3591sec preferred_lft 3591sec > - inet6 fe80::5c90:2ff:feeb:b02a/64 scope link=20 > + inet6 fe80::bc16:49ff:fe5a:65dc/64 scope link nodad proto kernel_ll= =20 > valid_lft forever preferred_lft forever > + > # ip route show > -default via 192.168.1.1 dev eth0=20 > -192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.118=20 > +default via 88.198.0.161 dev enp9s0 proto dhcp metric 1002=20 > +88.198.0.160/27 dev enp9s0 proto dhcp scope link metric 1002=20 > + > # ip -6 route show > -2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17 dev eth0 proto kernel metric 256= pref medium > -2a02:6d40:3ca5:2001::/64 dev eth0 proto kernel metric 256 expires 3584se= c pref medium > -fe80::/64 dev eth0 proto kernel metric 256 pref medium > -default via fe80::62e3:27ff:fe33:2b01 dev eth0 proto ra metric 1024 expi= res 3584sec pref medium > +2a01:4f8:222:904::/64 dev enp9s0 proto kernel metric 256 pref medium > +fe80::/64 dev enp9s0 proto kernel metric 256 pref medium > +default via fe80::1 dev enp9s0 metric 1024 onlink pref medium > + > # iperf3 -c 127.0.0.1 -t1 > Connecting to host 127.0.0.1, port 5201 > -[ 5] local 127.0.0.1 port 51938 connected to 127.0.0.1 port 5201 > +[ 5] local 127.0.0.1 port 59112 connected to 127.0.0.1 port 5201 > [ ID] Interval Transfer Bitrate Retr Cwnd > -[ 5] 0.00-1.00 sec 4.46 GBytes 38.3 Gbits/sec 0 3.93 MBytes = =20 > +[ 5] 0.00-1.00 sec 3.89 GBytes 33.4 Gbits/sec 0 2.62 MBytes = =20 > - - - - - - - - - - - - - - - - - - - - - - - - - > [ ID] Interval Transfer Bitrate Retr > -[ 5] 0.00-1.00 sec 4.46 GBytes 38.3 Gbits/sec 0 se= nder > -[ 5] 0.00-1.41 sec 4.45 GBytes 27.1 Gbits/sec re= ceiver > +[ 5] 0.00-1.00 sec 3.89 GBytes 33.4 Gbits/sec 0 se= nder > +[ 5] 0.00-1.00 sec 3.89 GBytes 33.4 Gbits/sec re= ceiver > =20 > iperf Done. > + > # iperf3 -c ::1 -t1 > Connecting to host ::1, port 5201 > -[ 5] local ::1 port 50108 connected to ::1 port 5201 > +[ 5] local ::1 port 49138 connected to ::1 port 5201 > [ ID] Interval Transfer Bitrate Retr Cwnd > -[ 5] 0.00-1.00 sec 4.35 GBytes 37.4 Gbits/sec 0 4.99 MBytes = =20 > +[ 5] 0.00-1.00 sec 4.32 GBytes 37.0 Gbits/sec 0 1.06 MBytes = =20 > - - - - - - - - - - - - - - - - - - - - - - - - - > [ ID] Interval Transfer Bitrate Retr > -[ 5] 0.00-1.00 sec 4.35 GBytes 37.4 Gbits/sec 0 se= nder > -[ 5] 0.00-1.41 sec 4.35 GBytes 26.4 Gbits/sec re= ceiver > +[ 5] 0.00-1.00 sec 4.32 GBytes 37.0 Gbits/sec 0 se= nder > +[ 5] 0.00-1.00 sec 4.32 GBytes 37.0 Gbits/sec re= ceiver > =20 > iperf Done. > -# ping -c1 -4 spaghetti.pizza > -PING spaghetti.pizza (172.67.192.217) 56(84) bytes of data. > -64 bytes from 172.67.192.217: icmp_seq=3D1 ttl=3D255 time=3D37.3 ms > + > +# ping -nc1 -4 spaghetti.pizza > +PING spaghetti.pizza (5.161.47.86) 56(84) bytes of data. > +64 bytes from 5.161.47.86: icmp_seq=3D1 ttl=3D255 time=3D99.4 ms > =20 > --- spaghetti.pizza ping statistics --- > 1 packets transmitted, 1 received, 0% packet loss, time 0ms > -# ping -c1 -6 spaghetti.pizza > -PING spaghetti.pizza(2606:4700:3034::6815:147a (2606:4700:3034::6815:147= a)) 56 data bytes > -64 bytes from 2606:4700:3034::6815:147a: icmp_seq=3D1 ttl=3D255 time=3D3= 5.6 ms > +rtt min/avg/max/mdev =3D 99.433/99.433/99.433/0.000 ms > +# ping -nc1 -6 spaghetti.pizza > +PING spaghetti.pizza (2a01:4f8:1c1e:d6f1::1) 56 data bytes > +64 bytes from 2a01:4f8:1c1e:d6f1::1: icmp_seq=3D1 ttl=3D255 time=3D3.11 = ms > =20 > --- spaghetti.pizza ping statistics --- > 1 packets transmitted, 1 received, 0% packet loss, time 0ms > -rtt min/avg/max/mdev =3D 35.605/35.605/35.605/0.000 ms > -# logout > -$ > - > -.RE > +rtt min/avg/max/mdev =3D 3.110/3.110/3.110/0.000 ms > .fi > +.RE > =20 > .BR "Connect an existing user and network namespace" > .RS > .nf > $ unshare -rUn > -# echo $$ > -2446678 > =20 > +# echo $$ > +1295969 > .fi > -.BR " [From another terminal]" > + > +.BR "[From another terminal]" > .nf > -$ ./pasta 2446678 > -Outbound interface: eth0, namespace interface: eth0 > -ARP: > - address: 28:16:ad:39:a9:ea > +$ pasta --config-net 1295969 > +Template interface: enp9s0 (IPv4), enp9s0 (IPv6) > +Namespace interface: enp9s0 > +MAC: > + host: 9a:55:9a:55:9a:55 > + NAT to host 127.0.0.1: 88.198.0.161 > DHCP: > - assign: 192.168.1.118 > - mask: 255.255.255.0 > - router: 192.168.1.1 > + assign: 88.198.0.164 > + mask: 255.255.255.224 > + router: 88.198.0.161 > +DNS: > + 185.12.64.1 > + 185.12.64.2 > + NAT to host ::1: fe80::1 > NDP/DHCPv6: > - assign: 2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17 > - router: fe80::62e3:27ff:fe33:2b01 > - > + assign: 2a01:4f8:222:904::2 > + router: fe80::1 > + our link-local: fe80::1 > +Inbound forwarding rules (HOST): > + TCP [*]:1-32767 =3D> 1-32767 (best effort) (auto-scan) > + TCP [*]:61000-65535 =3D> 61000-65535 (best effort) (auto-scan) > + UDP [*]:1-32767 =3D> 1-32767 (best effort) (auto-scan) > + UDP [*]:61000-65535 =3D> 61000-65535 (best effort) (auto-scan) > +Outbound forwarding rules (SPLICE): > + TCP [*]%lo:1-32767 =3D> 1-32767 (best effort) (auto-scan) > + TCP [*]%lo:61000-65535 =3D> 61000-65535 (best effort) (auto-scan) > + UDP [*]%lo:1-32767 =3D> 1-32767 (best effort) (auto-scan) > + UDP [*]%lo:61000-65535 =3D> 61000-65535 (best effort) (auto-scan) > .fi > -.BR " [Back to the original terminal]" > + > +.BR "[Back to the original terminal]" > .nf > -# dhclient -4 --no-pid > -# dhclient -6 --no-pid > # ip address show > 1: lo: mtu 65536 qdisc noqueue state UNKNOWN grou= p 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=20 > + inet6 ::1/128 scope host proto kernel_lo=20 > valid_lft forever preferred_lft forever > -2: eth0: mtu 65520 qdisc pfifo_fast st= ate UNKNOWN group default qlen 1000 > - link/ether fa:c1:2a:27:92:a9 brd ff:ff:ff:ff:ff:ff > - inet 192.168.1.118/24 brd 192.168.1.255 scope global eth0 > +2: enp9s0: mtu 65520 qdisc fq_codel st= ate UNKNOWN group default qlen 1000 > + link/ether 9a:44:5e:54:d3:2c brd ff:ff:ff:ff:ff:ff > + inet 88.198.0.164/27 brd 88.198.0.191 scope global noprefixroute enp= 9s0 > valid_lft forever preferred_lft forever > - inet6 2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17/128 scope global=20 > + inet6 2a01:4f8:222:904::2/64 scope global nodad=20 > valid_lft forever preferred_lft forever > - inet6 2a02:6d40:3ca5:2001:f8c1:2aff:fe27:92a9/64 scope global dynami= c mngtmpaddr=20 > - valid_lft 3594sec preferred_lft 3594sec > - inet6 fe80::f8c1:2aff:fe27:92a9/64 scope link=20 > + inet6 fe80::9844:5eff:fe54:d32c/64 scope link nodad proto kernel_ll= =20 > valid_lft forever preferred_lft forever > .fi > .RE > @@ -893,72 +895,69 @@ NDP/DHCPv6: > .BR "Start and connect a guest with basic port forwarding" > .RS > .nf > -$ ./passt -f -t 2222:22 > -Outbound interface: eth0 > -ARP: > - address: 28:16:ad:39:a9:ea > +$ passt -f -t 2222:22 > +UNIX domain socket bound at /tmp/passt_1.socket > +No IPv6 nameserver available for NDP/DHCPv6 > +Template interface: enp9s0 (IPv4), enp9s0 (IPv6) > +MAC: > + host: 9a:55:9a:55:9a:55 > + NAT to host 127.0.0.1: 88.198.0.161 > DHCP: > - assign: 192.168.1.118 > - mask: 255.255.255.0 > - router: 192.168.1.1 > - search: > - redhat.com > + assign: 88.198.0.164 > + mask: 255.255.255.224 > + router: 88.198.0.161 > +DNS: > + 185.12.64.1 > + 185.12.64.2 > + NAT to host ::1: fe80::1 > NDP/DHCPv6: > - assign: 2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17 > - router: fe80::62e3:27ff:fe33:2b01 > - search: > - redhat.com > -UNIX domain socket bound at /tmp/passt_1.socket > - > -You can now start qrap: > - ./qrap 5 qemu-system-x86_64 ... -net socket,fd=3D5 -net nic,model=3D= virtio > -or directly qemu, patched with: > - qemu/0001-net-Allow-also-UNIX-domain-sockets-to-be-used-as-net.patch > -as follows: > - qemu-system-x86_64 ... -net socket,connect=3D/tmp/passt_1.socket -ne= t nic,model=3Dvirtio > - > + assign: 2a01:4f8:222:904::2 > + router: fe80::1 > + our link-local: fe80::1 > +Inbound forwarding rules (HOST): > + TCP [*]:2222 =3D> 22=20 > + > +You can now start qemu (>=3D 7.2, with commit 13c6be96618c): > + kvm ... -device virtio-net-pci,netdev=3Ds -netdev stream,id=3Ds,serv= er=3Doff,addr.type=3Dunix,addr.path=3D/tmp/passt_1.socket > .fi > -.BR " [From another terminal]" > -.nf > -$ ./qrap 5 qemu-system-x86_64 test.qcow2 -m 1024 -display none -nodefaul= ts -nographic -net socket,fd=3D5 -net nic,model=3Dvirtio > -Connected to /tmp/passt_1.socket > =20 > -.fi > -.BR " [Back to the original terminal]" > +.BR "[From another terminal]" > .nf > -passt: DHCP: ack to request > -passt: from 52:54:00:12:34:56 > -passt: NDP: received NS, sending NA > -passt: NDP: received RS, sending RA > -passt: DHCPv6: received SOLICIT, sending ADVERTISE > -passt: NDP: received NS, sending NA > -passt: DHCPv6: received REQUEST/RENEW/CONFIRM, sending REPLY > -passt: NDP: received NS, sending NA > +$ qemu-system-x86_64 -m 128 test.qcow2 -display none -nodefaults -nograp= hic -device virtio-net-pci,netdev=3Ds -netdev stream,id=3Ds,server=3Doff,ad= dr.type=3Dunix,addr.path=3D/tmp/passt_1.socket > +.fi > =20 > +.BR "[Back to the original terminal]" > +.nf > +accepted connection from PID 1301736 > +New guest MAC address observed: 52:54:00:12:34:56 > +DHCP: offer to discover > + from 52:54:00:12:34:56 > +DHCP: ack to request > + from 52:54:00:12:34:56 > +NDP: received RS, sending RA > .fi > -.BR " [From yet another terminal]" > + > +.BR "[From yet another terminal]" > .nf > $ ssh -p 2222 root@localhost > root@localhost's password:=20 > .fi > -.BR " [...]" > +.BR "[...]" > .nf > # ip address show > -1: lo: mtu 65536 qdisc noqueue state UNKNOWN grou= p default qlen 1000 > +1: lo: mtu 65536 qdisc noqueue state UNKNOWN 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=20 > valid_lft forever preferred_lft forever > -2: ens2: mtu 65520 qdisc pfifo_fast st= ate UP group default qlen 1000 > +2: eth0: mtu 1500 qdisc pfifo_fast sta= te UP qlen 1000 > link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff > - inet 192.168.1.118/24 brd 192.168.1.255 scope global noprefixroute e= ns2 > + inet 88.198.0.164/27 scope global eth0 > valid_lft forever preferred_lft forever > - inet6 2a02:6d40:3ca5:2001:b81d:fa4a:8cdd:cf17/128 scope global nopre= fixroute=20 > + inet6 2a01:4f8:222:904:5054:ff:fe12:3456/64 scope global dynamic fla= gs 100=20 > valid_lft forever preferred_lft forever > - inet6 2a02:6d40:3ca5:2001:b019:9ae2:a2fe:e6b4/64 scope global dynami= c noprefixroute=20 > - valid_lft 3588sec preferred_lft 3588sec > - inet6 fe80::1f98:d09f:9309:9e77/64 scope link noprefixroute=20 > + inet6 fe80::5054:ff:fe12:3456/64 scope link=20 > valid_lft forever preferred_lft forever > .fi > .RE > diff --git a/qrap.1 b/qrap.1 > deleted file mode 100644 > index 98cc877..0000000 > --- a/qrap.1 > +++ /dev/null > @@ -1,77 +0,0 @@ > -.\" SPDX-License-Identifier: GPL-2.0-or-later > -.\" Copyright (c) 2020-2021 Red Hat GmbH > -.\" Author: Stefano Brivio > -.TH qrap 1 > - > -.SH NAME > -.B qrap > -\- temporary qemu wrapper connecting UNIX domain socket to file descript= or > - > -.SH SYNOPSIS > -.B qrap > -[\fIFDNUM\fR \fIQEMU_CMD\fR] [\fIQEMU_ARG\fR]... > -.SH DESCRIPTION > -\fBqrap\fR is a wrapper, designed specifically for usage with \fBqemu\fR= (1) and > -\fBpasst\fR(1), connecting a UNIX domain socket to a file descriptor, and > -running \fBqemu\fR(1) with given arguments. > - > -A running instance of \fBpasst\fR(1) is probed checking for UNIX domain = sockets, > -answering a dummy ARP request, with names starting from > -\fI/tmp/passt_1.socket\fR up to \fI/tmp/passt_64.socket\fR. > - > -If first and second arguments are not a socket number and a command, tha= t is, > -respectively, \fIFDNUM\fR and \fIQEMU_CMD\fR, \fBqrap\fR will try to loc= ate a > -qemu executable in \fBPATH\fR and patch the command line to specify a ne= twork > -device and a \fInetdev\fR back-end for usage with \fBpasst\fR(1). > - > -If \fBqrap\fR patches the command line, it will remove any potentially > -conflicting network device, that is, any \fI-netdev\fR or \fI-net\fR opt= ion, or > -any \fI-device\fR option with argument starting with \fIvirtio-net-pci,\= fR, > -\fIvirtio-net-ccw,\fR, \fIe1000,\fR, \fIe1000e,\fR, or \fIrtl8139,\fR. > - > -.SH EXAMPLES > - > -.BR "Start qemu explicitly passing its command name and a socket number" > -.RS > -.nf > -$ ./qrap 5 kvm test.qcow2 -m 1024 -display none -nodefaults -nographic -= net socket,fd=3D5 -net nic,model=3Dvirtio > -.fi > -.RE > - > -.BR "Start qemu without command name and socket number, patching argumen= ts" > -.RS > -.nf > -$ ./qrap test.qcow2 -m 1024 -display none -nodefaults -nographic > -.fi > -.RE > - > -.SH NOTES > - > -This wrapper is temporary: qemu commit 13c6be96618c ("net: stream: add u= nix > -socket") introduces native AF_UNIX socket support, and it should be incl= uded in > -qemu starting from the 7.2 release. It will be around for a little bit l= onger to > -give users enough time to switch. > - > -.SH AUTHOR > - > -Stefano Brivio > - > -.SH REPORTING BUGS > - > -No public bug tracker is available at this time. For the moment being, r= eport > -issues to Stefano Brivio . > - > -.SH COPYRIGHT > - > -Copyright (c) 2020-2021 Red Hat GmbH. > - > -\fBqrap\fR is free software: you can redistribute is and/or modify it un= der the > -terms of the GNU General Public License as published by the Free Software > -Foundation, either version 2 of the License, or (at your option) any lat= er > -version.=20 > - > -.SH SEE ALSO > - > -\fBqemu\fR(1), \fBpasst\fR(1). > - > -High-level documentation is available at https://passt.top/passt/about/. > diff --git a/qrap.c b/qrap.c > deleted file mode 100644 > index d596706..0000000 > --- a/qrap.c > +++ /dev/null > @@ -1,429 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0-or-later > - > -/* PASST - Plug A Simple Socket Transport > - * > - * qrap.c - qemu wrapper connecting UNIX domain socket to file descriptor > - * > - * Copyright (c) 2020-2021 Red Hat GmbH > - * Author: Stefano Brivio > - * > - * TODO: Drop this implementation once qemu commit 13c6be96618c ("net: s= tream: > - * add unix socket") is included in a release (7.2), and once we can rea= sonably > - * assume existing users switched to it. > - */ > - > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > -#include > - > -#include > - > -#include "util.h" > -#include "ip.h" > -#include "passt.h" > -#include "arp.h" > - > -static char *qemu_names[] =3D { > - "kvm", > - "qemu-kvm", > -#ifdef ARCH > - ( "qemu-system-" ARCH ), > -#endif > - "/usr/libexec/qemu-kvm", > - NULL, > -}; > - > -/** > - * struct drop_arg - Drop matching arguments on command line > - * @name: Option name > - * @val: Substring in option value, NULL matches any value > - */ > -static const struct drop_arg { > - char *name; > - char *val; > -} drop_args[] =3D { > - { "-netdev", NULL }, > - { "-net", NULL }, > - { "-device", "virtio-net-pci," }, > - { "-device", "{\"driver\":\"virtio-net-pci\"," }, > - { "-device", "virtio-net-ccw," }, > - { "-device", "{\"driver\":\"virtio-net-ccw\"," }, > - { "-device", "e1000," }, > - { "-device", "{\"driver\":\"e1000\"," }, > - { "-device", "e1000e," }, > - { "-device", "{\"driver\":\"e1000e\"," }, > - { "-device", "rtl8139," }, > - { "-device", "{\"driver\":\"rtl8139\"," }, > - { 0 }, > -}; > - > -/** > - * struct pci_dev - PCI devices to add on command line depending on mach= ine name > - * @mach: Machine name > - * @name: Device ("-device") name to insert > - * @template: Prefix for device specification (first part of address) > - * @template_post: Suffix for device specification (last part of address) > - * @template_json: Device prefix for when JSON is used > - * @template_json_post: Device suffix for when JSON is used > - * @base: Base used for PCI addresses > - * @first: First usable PCI address > - * @last: Last usable PCI address > - */ > -static const struct pci_dev { > - char *mach; > - char *name; > - char *template; > - char *template_post; > - char *template_json; > - char *template_json_post; > - int base; > - int first; > - int last; > -} pci_devs[] =3D { > - { > - "pc-q35", "virtio-net-pci", > - "bus=3Dpci.", ",addr=3D0x0", > - "\"bus\":\"pci.", ",\"addr\":\"0x0\"", > - 10, 3, /* 2: hotplug bus */ 31 > - }, > - { > - "pc-", "virtio-net-pci", > - "bus=3Dpci.0,addr=3D0x", "", > - "\"bus\":\"pci.0\",\"addr\":\"0x", "", > - 16, 2, /* 1: ISA bridge */ 31 > - }, > - { > - "s390-ccw", "virtio-net-ccw", > - "devno=3Dfe.0.", "", > - "\"devno\":\"fe.0.", "", > - 16, 1, 16 > - }, > - { 0 }, > -}; > - > -#define DEFAULT_FD 5 > - > -/** > - * usage() - Print usage and exit > - * @name: Executable name > - */ > -void usage(const char *name) > -{ > - fprintf(stderr, "Usage: %s [FDNUM QEMU_CMD] [QEMU_ARG]...\n", name); > - fprintf(stderr, "\n"); > - fprintf(stderr, "If first and second arguments aren't a socket number\n" > - "and a path, %s will try to locate a qemu binary\n" > - "and directly patch the command line\n", name); > - > - exit(EXIT_FAILURE); > -} > - > -/** > - * main() - Entry point and main loop > - * @argc: Argument count > - * @argv: File descriptor number, then qemu with arguments > - * > - * Return: 0 once interrupted, non-zero on failure > - */ > -int main(int argc, char **argv) > -{ > - int i, s, qemu_argc =3D 0, addr_map =3D 0, has_dev =3D 0, has_json =3D = 0, retry_on_reset, rc; > - struct timeval tv =3D { .tv_sec =3D 0, .tv_usec =3D (long)(500 * 1000) = }; > - char *qemu_argv[ARG_MAX], dev_str[ARG_MAX]; > - struct sockaddr_un addr =3D { > - .sun_family =3D AF_UNIX, > - }; > - const struct pci_dev *dev =3D NULL; > - long fd; > - struct { > - uint32_t vnet_len4; > - struct ethhdr eh4; > - struct arphdr ah; > - struct arpmsg am; > - > - uint32_t vnet_len6; > - struct ethhdr eh6; > - struct ipv6hdr ip6hr; > - struct icmp6hdr ihr; > - struct in6_addr target; > - } __attribute__((__packed__)) probe =3D { > - .vnet_len4 =3D htonl(42), > - { > - .h_dest =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, > - .h_source =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, > - .h_proto =3D htons(ETH_P_ARP), > - }, > - { .ar_hrd =3D htons(ARPHRD_ETHER), > - .ar_pro =3D htons(ETH_P_IP), > - .ar_hln =3D ETH_ALEN, > - .ar_pln =3D 4, > - .ar_op =3D htons(ARPOP_REQUEST), > - }, > - { > - .sha =3D { 0 }, .sip =3D { 0 }, .tha =3D { 0 }, .tip =3D { 0 }, > - }, > - .vnet_len6 =3D htonl(78), > - { > - .h_dest =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, > - .h_source =3D { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, > - .h_proto =3D htons(ETH_P_IPV6), > - }, > - { > - .version =3D 6, > - .payload_len =3D htons(24), > - .nexthdr =3D IPPROTO_ICMPV6, > - .hop_limit =3D 255, > - .saddr =3D IN6ADDR_LOOPBACK_INIT, > - .daddr =3D IN6ADDR_ANY_INIT, > - }, > - { > - .icmp6_type =3D 135, > - .icmp6_code =3D 0, > - }, > - IN6ADDR_ANY_INIT, > - }; > - char probe_r; > - > - if (argc >=3D 3) { > - const char *path =3D getenv("PATH"); > - errno =3D 0; > - fd =3D strtol(argv[1], NULL, 0); > - if (fd >=3D 3 && fd < INT_MAX && !errno && path) { > - char env_path[ARG_MAX + 1], *p, command[ARG_MAX]; > - > - strncpy(env_path, path, ARG_MAX); > - /* cppcheck-suppress strtokCalled */ > - p =3D strtok(env_path, ":"); > - while (p) { > - snprintf(command, ARG_MAX, "%s/%s", p, argv[2]); > - if (!access(command, X_OK)) > - goto valid_args; > - > - /* cppcheck-suppress strtokCalled */ > - p =3D strtok(NULL, ":"); > - } > - } > - } > - > - fd =3D DEFAULT_FD; > - > - for (i =3D 1; i < argc - 1; i++) { > - if (strcmp(argv[i], "-machine")) > - continue; > - > - for (dev =3D pci_devs; dev->mach; dev++) { > - if (strstr(argv[i + 1], dev->mach) =3D=3D argv[i + 1]) > - break; > - } > - } > - > - if (!dev || !dev->mach) > - dev =3D pci_devs; > - > - for (qemu_argc =3D 1, i =3D 1; i < argc; i++) { > - const struct drop_arg *a; > - > - for (a =3D drop_args; a->name; a++) { > - if (!strcmp(argv[i], a->name)) { > - if (!a->val) > - break; > - > - if (i + 1 < argc && > - strstr(argv[i + 1], a->val) =3D=3D argv[i + 1]) > - break; > - } > - } > - if (a->name) { > - i++; > - continue; > - } > - > - if (!strcmp(argv[i], "-device") && i + 1 < argc) { > - const char *template =3D NULL; > - const char *p; > - > - has_dev =3D 1; > - > - if ((p =3D strstr(argv[i + 1], dev->template))) { > - template =3D dev->template; > - } else if ((p =3D strstr(argv[i + 1], dev->template_json))) { > - template =3D dev->template_json; > - has_json =3D 1; > - } > - > - if (template) { > - long n; > - > - n =3D strtol(p + strlen(template), NULL, dev->base); > - if (!errno) > - addr_map |=3D (1 << n); > - } > - } > - > - qemu_argv[qemu_argc++] =3D argv[i]; > - } > - > - for (i =3D dev->first; i < dev->last; i++) { > - if (!(addr_map & (1 << i))) > - break; > - } > - if (i =3D=3D dev->last) { > - fprintf(stderr, "Couldn't find free address for device\n"); > - usage(argv[0]); > - } > - > - if (has_dev) { > - qemu_argv[qemu_argc++] =3D "-device"; > - if (!has_json) { > - if (dev->base =3D=3D 16) { > - snprintf(dev_str, ARG_MAX, > - "%s,%s%x%s,netdev=3Dhostnet0,x-txburst=3D4096", > - dev->name, dev->template, i, dev->template_post); > - } else if (dev->base =3D=3D 10) { > - snprintf(dev_str, ARG_MAX, > - "%s,%s%d%s,netdev=3Dhostnet0,x-txburst=3D4096", > - dev->name, dev->template, i, dev->template_post); > - } > - } else { > - if (dev->base =3D=3D 16) { > - snprintf(dev_str, ARG_MAX, > - "{\"driver\":\"%s\",%s%x\"%s,\"netdev\":\"hostnet0\",\"x-tx= burst\":4096}", > - dev->name, dev->template_json, i, dev->template_json_post); > - } else if (dev->base =3D=3D 10) { > - snprintf(dev_str, ARG_MAX, > - "{\"driver\":\"%s\",%s%d\"%s,\"netdev\":\"hostnet0\",\"x-tx= burst\":4096}", > - dev->name, dev->template_json, i, dev->template_json_post); > - } > - } > - qemu_argv[qemu_argc++] =3D dev_str; > - } > - > - qemu_argv[qemu_argc++] =3D "-netdev"; > - if (!has_json) { > - qemu_argv[qemu_argc++] =3D "socket,fd=3D" STR(DEFAULT_FD) ",id=3Dhostn= et0"; > - } else { > - qemu_argv[qemu_argc++] =3D "{\"type\":\"socket\",\"fd\":\"" STR(DEFAUL= T_FD) "\",\"id\":\"hostnet0\"}"; > - } > - qemu_argv[qemu_argc] =3D NULL; > - > -valid_args: > - for (i =3D 1; i < UNIX_SOCK_MAX; i++) { > - retry_on_reset =3D 50; > - > -retry: > - s =3D socket(AF_UNIX, SOCK_STREAM, 0); > - if (s < 0) { > - perror("socket"); > - exit(EXIT_FAILURE); > - } > - > - if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) > - perror("setsockopt SO_RCVTIMEO"); > - if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv))) > - perror("setsockopt SO_SNDTIMEO"); > - > - snprintf(addr.sun_path, UNIX_PATH_MAX, UNIX_SOCK_PATH, i); > - > - errno =3D 0; > - > - if (connect(s, (const struct sockaddr *)&addr, sizeof(addr))) { > - rc =3D errno; > - perror("connect"); > - } else if (send(s, &probe, sizeof(probe), 0) !=3D sizeof(probe)) { > - rc =3D errno; > - perror("send"); > - } else if (recv(s, &probe_r, 1, MSG_PEEK) <=3D 0) { > - rc =3D errno; > - perror("recv"); > - } else { > - break; > - } > - > - /* FIXME: in a KubeVirt environment, libvirtd invokes qrap three > - * times in a strict sequence when a virtual machine needs to > - * be started, namely, when: > - * - the domain XML is saved > - * - the domain is started (for "probing") > - * - the virtual machine is started for real > - * and it often happens that the qemu process is still running > - * when qrap is invoked again, so passt will refuse the new > - * connection because the previous one is still active. This > - * overlap seems to be anywhere between 0 and 3ms. > - * > - * If we get a connection reset, retry a few times, to allow for > - * the previous qemu instance to terminate and, in turn, for the > - * connection to passt to be closed. > - * > - * This should be fixed in libvirt instead. It probably makes > - * sense to check this behaviour once native libvirt support is > - * there, and this implies native qemu support too, so at that > - * point qrap will have no reason to exist anymore -- that is, > - * this FIXME will probably remain until the tool itself is > - * obsoleted. > - */ > - if (retry_on_reset && rc =3D=3D ECONNRESET) { > - retry_on_reset--; > - /* cppcheck-suppress usleepCalled */ > - usleep(50 * 1000); > - goto retry; > - } > - > - fprintf(stderr, "Probe of %s failed\n", addr.sun_path); > - > - close(s); > - } > - > - if (i =3D=3D UNIX_SOCK_MAX) { > - perror("connect"); > - exit(EXIT_FAILURE); > - } > - > - tv.tv_usec =3D 0; > - if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))) > - perror("setsockopt, SO_RCVTIMEO reset"); > - if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv))) > - perror("setsockopt, SO_SNDTIMEO reset"); > - > - fprintf(stderr, "Connected to %s\n", addr.sun_path); > - > - if (dup2(s, (int)fd) < 0) { > - perror("dup"); > - exit(EXIT_FAILURE); > - } > - > - close(s); > - > - if (qemu_argc) { > - char **name; > - > - for (name =3D qemu_names; *name; name++) { > - qemu_argv[0] =3D *name; > - execvp(*name, qemu_argv); > - if (errno !=3D ENOENT) { > - perror("execvp"); > - usage(argv[0]); > - } > - } > - if (errno =3D=3D ENOENT) > - fprintf(stderr, "Couldn't find qemu command\n"); > - } else { > - execvp(argv[2], argv + 2); > - } > - > - perror("execvp"); > - > - return EXIT_FAILURE; > -} > diff --git a/tap.c b/tap.c > index cf87591..dfa66c7 100644 > --- a/tap.c > +++ b/tap.c > @@ -1377,8 +1377,6 @@ static void tap_backend_show_hints(const struct ctx= *c) > info("\nYou can now start qemu (>=3D 7.2, with commit 13c6be96618c):"); > info(" kvm ... -device virtio-net-pci,netdev=3Ds -netdev stream,id= =3Ds,server=3Doff,addr.type=3Dunix,addr.path=3D%s", > c->sock_path); > - info("or qrap, for earlier qemu versions:"); > - info(" ./qrap 5 kvm ... -net socket,fd=3D5 -net nic,model=3Dvirtio"= ); > break; > case MODE_VU: > info("You can start qemu with:"); > diff --git a/test/distro/opensuse b/test/distro/opensuse > index eab722b..9ceb0bd 100644 > --- a/test/distro/opensuse > +++ b/test/distro/opensuse > @@ -39,7 +39,7 @@ hostb ./passt -s __STATEDIR__/passt.socket -P __PIDFILE= __ & > sleep 1 > host echo > hout DNS6 sed -n 's/^nameserver \([^:]*:\)\([^%]*\).*/\1\2/p' /etc/resol= v.conf | head -1 > -hout GUEST_FILES ls -1 *.c *.h *.sh passt.1 qrap.1 Makefile README.md | = tr '\n' ' '; echo > +hout GUEST_FILES ls -1 *.c *.h *.sh passt.1 Makefile README.md | tr '\n'= ' '; echo > =20 > =20 > test OpenSUSE Leap 15.1 > --=20 > 2.43.0 >=20 --=20 David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson --KUIfFCXcrjZX4IP/ Content-Type: application/pgp-signature; name=signature.asc -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEO+dNsU4E3yXUXRK2zQJF27ox2GcFAmpcTJoACgkQzQJF27ox 2GdPmA/+O2KhHRAOhk3lr784pU0aDLWvR7YXOXk83QuC24ArwC9EtcFWDCNC+mzN 2/xeU/Ples7i+56fqrFcoOjUJq7QxsFHQ+l4AX2axgxUIvwEhvthXuJXrffi5qYQ SLtq0WYMR+aOpMpCsd52tOOJQ1Ea8ibApjrJ2I6/tySqcLmp3AT+gQxcE2onTTdJ oOI1AHwWAMB4ALAb2cIZ2hAeiRgnD1I5+kcjpGSyDlolnZ5tP52yifydv969nsKl LO5QwkbelzVeu8H2aQOYIA1WzZyDxHhDNrhX+ZdYHij6pEH4JZDOvIaNxCMFEgwG nR3pQA6wi+P1y0LrnOmQQE3BjTCuKEkDSo0cjHep9gQjdrduMmShZUQK5QER65F0 nk9w9fwmti+3RrVj4TnPsZWxPzRy9AZqF7OylKJpfKEAujUTlxfQ/QTvenTKXSeX K0Uscy4SFNiWtujtfmkvaDl1secrsIlUPVUxjSyDw1eSJT7MQpOO3nHYA5PqZups K3mB8NN6mMpAYLuL1GVb3681d2cM/kQOaxeMjGFNBTDEDW9UzRFD+WPXlR0hLctA IoiuSXhosnu5KUytC296KoyOv6WVsLvKfz+IeUTeXYvEfB9gc0oXdUG5Afj/bxHr VqCkTSXQBjEtFNdyNpij83OV1h2nifMNxySttqEcjIGZDBrQoiQ= =QB+y -----END PGP SIGNATURE----- --KUIfFCXcrjZX4IP/--