From nobody Sun Feb 8 22:22:51 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=yodel.dev ARC-Seal: i=1; a=rsa-sha256; t=1768258982; cv=none; d=zohomail.com; s=zohoarc; b=ScqRFtThsXfWw4FESi/WuBQ1n13dMTLMIw27Ep49S7rC2KYs1ZtG843tomHvuNGNdHYL4SjQC7iLqElNMXeXkvfxsmlvp91pJeVBiNNy+GL7M9XkuaFKkviN2yRjWRIt6N2fms1qUypOxjc0a01qOGvVvSRjojc9r9NI58xcLcw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768258982; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=lQzMPmtgICG9oe9L/v+xMIkXf+dXY2DUXTpSDA4PHWQ=; b=QgE8027eDBL52Sw74aNQz2MjgNcUOxkoOWRMYMKucKcFDSJlZARgoCCUf52nMsBQ44OgEK+dS/27W7BSagrJlXOJHJ6vdd6HChQTFbZWtJBrTmnLYVrg6SyWrcQRZZA4FMx/b7fkheC+8NGADJtpcIkAtlJIX0J7yolPHgkYVpc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 176825898224394.51096609597528; Mon, 12 Jan 2026 15:03:02 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vfQvU-0003Lt-4q; Mon, 12 Jan 2026 18:02:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vfQvR-0003Ks-Q9 for qemu-devel@nongnu.org; Mon, 12 Jan 2026 18:02:17 -0500 Received: from k62.kb8c70eb.use4.send.mailgun.net ([204.220.184.62]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vfQvO-0006I7-RB for qemu-devel@nongnu.org; Mon, 12 Jan 2026 18:02:17 -0500 Received: from mail.yodel.dev (mail.yodel.dev [35.209.39.246]) by d1e7d384fc715ab1512602a6ac5d2da06fe6a698fc310d411471673906daec7f with SMTP id 69657d6db5a5d57f8524a7ef; Mon, 12 Jan 2026 23:02:05 GMT X-Mailgun-Sid: WyI4ZDFlNiIsInFlbXUtZGV2ZWxAbm9uZ251Lm9yZyIsIjk3NjA3ZSJd X-Mailgun-Sending-Ip: 204.220.184.62 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yodel.dev; s=rsa2048; t=1768258925; bh=lQzMPmtgICG9oe9L/v+xMIkXf+dXY2DUXTpSDA4PHWQ=; h=X-Mailgun-Dkim:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:From:Reply-to: Subject:Date:Message-id:To:Cc:Mime-version:Content-type: Content-transfer-encoding:In-reply-to:References; b=LmKL6NxPQ1yxeRTdieur8DKGvLVZk/K3M4FQLXBsGHWbEOSZgl0FpyQhQTCo7WdQs 0TBVRvlkfOGKbGgLrdFpP8oiZU0lf4r2pWVeXpfr71WCzXaxO/ZdwSbYVIjlOgykbC 10TTwzwrQB2ouNYmTUn07bfPeHxzIFzYX2EfOFhnAb/CBQnnfdvKtaXN38mi1aPsSI slsd/kbGDiuUUAwCXH30wg2cDDOyMcOfHp8zLDbnTnPnwIZTVmC5xh48Xtxqd20rIo fVsRPDBYAdP1RbA3zakO36mEnjvtTRWgLtUei4/UHGT2y3GES4NmLuzL3KF+zs2jkH XrIg1q7o0KDxw== X-Mailgun-Dkim: no X-Mailgun-Dkim: no From: Yodel Eldar To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Stefano Garzarella , Paolo Bonzini , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Thomas Huth , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Yodel Eldar Subject: [RFC PATCH v2 1/3] tests/vhost-user-bridge: Move to contrib/vhost-user-bridge/ Date: Mon, 12 Jan 2026 17:01:25 -0600 Message-ID: <20260112230127.99125-2-yodel.eldar@yodel.dev> In-Reply-To: <20260112230127.99125-1-yodel.eldar@yodel.dev> References: <20260112230127.99125-1-yodel.eldar@yodel.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=204.220.184.62; envelope-from=bounce+0e9322.97607e-qemu-devel=nongnu.org@yodel.dev; helo=k62.kb8c70eb.use4.send.mailgun.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yodel.dev) X-ZM-MESSAGEID: 1768259011606158500 Content-Type: text/plain; charset="utf-8" After the introduction of vhost-user-bridge and libvhost-user, we formed the convention of placing vhost-user daemons in eponymous subdirs of contrib/. Follow this convention. Create a contrib/vhost-user-bridge/ directory and move vhost-user-bridge into it. Extract its build target definition from tests/meson.build into the new directory, and include its subdir in the root-level meson.build. Add a section about it in the "vhost-user daemons in contrib" document. Signed-off-by: Yodel Eldar Reviewed-by: Marc-Andr=C3=A9 Lureau --- contrib/vhost-user-bridge/meson.build | 4 ++ .../vhost-user-bridge}/vhost-user-bridge.c | 0 .../devices/virtio/vhost-user-contrib.rst | 39 +++++++++++++++++++ meson.build | 1 + tests/meson.build | 6 --- 5 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 contrib/vhost-user-bridge/meson.build rename {tests =3D> contrib/vhost-user-bridge}/vhost-user-bridge.c (100%) diff --git a/contrib/vhost-user-bridge/meson.build b/contrib/vhost-user-bri= dge/meson.build new file mode 100644 index 0000000000..aa58c1df20 --- /dev/null +++ b/contrib/vhost-user-bridge/meson.build @@ -0,0 +1,4 @@ +if have_tools and have_vhost_user and host_os =3D=3D 'linux' + executable('vhost-user-bridge', files('vhost-user-bridge.c'), + dependencies: [qemuutil, vhost_user], install: false) +endif diff --git a/tests/vhost-user-bridge.c b/contrib/vhost-user-bridge/vhost-us= er-bridge.c similarity index 100% rename from tests/vhost-user-bridge.c rename to contrib/vhost-user-bridge/vhost-user-bridge.c diff --git a/docs/system/devices/virtio/vhost-user-contrib.rst b/docs/syste= m/devices/virtio/vhost-user-contrib.rst index 48d04d2ade..660d29a700 100644 --- a/docs/system/devices/virtio/vhost-user-contrib.rst +++ b/docs/system/devices/virtio/vhost-user-contrib.rst @@ -85,3 +85,42 @@ vhost-user-scsi - SCSI controller =20 The vhost-user-scsi daemon can proxy iSCSI devices onto a virtualized SCSI controller. + +.. _vhost_user_bridge: + +vhost-user-bridge - Network bridge +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The vhost-user-bridge daemon serves as a development tool for testing real +internet traffic by providing a networking backend, i.e. server, for the +vhost-user protocol. + +Example +------- +For a single QEMU instance that both runs the user-mode net stack (slirp) = and +serves as a vhost-user protocol frontend, i.e. client, simultaneously: + +First, start vhost-user-bridge: + +:: + + $ vhost-user-bridge -u /tmp/vubr.sock \ + -l 127.0.0.1:4444 \ + -r 127.0.0.1:5555 + +Then, invoke QEMU: + +:: + + $ qemu-system-x86_64 \ + -m 4G \ + -object memory-backend-memfd,id=3Dmem0,size=3D4G,share=3Don,preall= oc=3Don \ + -numa node,memdev=3Dmem0 \ + -chardev socket,id=3Dchar0,path=3D/tmp/vubr.sock \ + -netdev vhost-user,id=3Dvhost0,chardev=3Dchar0,vhostforce=3Don \ + -device virtio-net-pci,netdev=3Dvhost0 \ + -netdev socket,id=3Dudp0,udp=3Dlocalhost:4444,localaddr=3Dlocalhos= t:5555 \ + -netdev user,id=3Duser0 \ + -netdev hubport,id=3Dhub0,hubid=3D0,netdev=3Dudp0 \ + -netdev hubport,id=3Dhub1,hubid=3D0,netdev=3Duser0 \ + ... diff --git a/meson.build b/meson.build index db87358d62..a4e8a9b7b5 100644 --- a/meson.build +++ b/meson.build @@ -4546,6 +4546,7 @@ if have_tools subdir('contrib/vhost-user-gpu') subdir('contrib/vhost-user-input') subdir('contrib/vhost-user-scsi') + subdir('contrib/vhost-user-bridge') endif =20 if host_os =3D=3D 'linux' diff --git a/tests/meson.build b/tests/meson.build index cbe7916241..87861b2857 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -70,12 +70,6 @@ test_deps =3D { 'test-qht-par': qht_bench, } =20 -if have_tools and have_vhost_user and host_os =3D=3D 'linux' - executable('vhost-user-bridge', - sources: files('vhost-user-bridge.c'), - dependencies: [qemuutil, vhost_user]) -endif - subdir('decode') =20 if 'CONFIG_TCG' in config_all_accel --=20 2.52.0 From nobody Sun Feb 8 22:22:51 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=yodel.dev ARC-Seal: i=1; a=rsa-sha256; t=1768258991; cv=none; d=zohomail.com; s=zohoarc; b=kUZtpVONHQHviQU5u/dknx1Yo2G362TNe1JHwxRVDQ0X2tfPwDyG8l39Bdpi3aaiP8gFyRq2JHxmSjZG+w0Lz8r7QcHHulksXXm5rCQU5/Kdk90K2SRejEghv43QVANgHXoxQwWGxC44Lk5vy0KKXfYf16cfWu1KCDUP0pbHios= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768258991; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=P5Ok0H0WTtrIdfeLa9f2dS19wnXPPfz5ZOswq0YMenM=; b=LCnMN7hLabdtoiK7QiHexo5AXBF9uttJJU5UN55ePKSS58W8lt20LADEyEQ96ugVDdNIQhaYHZcFaa1QmJcJK30pGikYy12O02bO6/70MKlchjTLZVY/OR+ZCtZk7omg6ywNe11JqSiTmKKdooCRfVSxIP5md9cvkfxMeibXVYA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1768258991485608.0001573669877; Mon, 12 Jan 2026 15:03:11 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vfQvU-0003M2-Pv; Mon, 12 Jan 2026 18:02:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vfQvS-0003L2-0Y for qemu-devel@nongnu.org; Mon, 12 Jan 2026 18:02:18 -0500 Received: from k57.kb8c70eb.use4.send.mailgun.net ([204.220.184.57]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vfQvO-0006II-P8 for qemu-devel@nongnu.org; Mon, 12 Jan 2026 18:02:17 -0500 Received: from mail.yodel.dev (mail.yodel.dev [35.209.39.246]) by abe4e9154eadea1569f0e7b462d2cb4b79ad464017d3fe8ef93a25a7872c7cbc with SMTP id 69657d6e589bbfeeb4db3433; Mon, 12 Jan 2026 23:02:06 GMT X-Mailgun-Sid: WyI4ZDFlNiIsInFlbXUtZGV2ZWxAbm9uZ251Lm9yZyIsIjk3NjA3ZSJd X-Mailgun-Sending-Ip: 204.220.184.57 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yodel.dev; s=rsa2048; t=1768258925; bh=P5Ok0H0WTtrIdfeLa9f2dS19wnXPPfz5ZOswq0YMenM=; h=X-Mailgun-Dkim:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Type:Content-Transfer-Encoding: From:Reply-to:Subject:Date:Message-id:To:Cc:Mime-version: Content-type:Content-transfer-encoding:In-reply-to:References; b=YRDNp+gkAnEwn8ffZZzLnYdsaRFlcRTxiQI5KjAqDppmGNANAT4543d0FVt38Bi1o nBB6tdCn+QQb8sUek53YtyArCS3EdKsg+zpsmVD9V/KOo/2WWc2XvBLiq4xT81DCu9 th3iACiHaZQbPPaHFKPWBlGijs+Xqvx2Xj7zTJ5mYDAo9t7BfH8gFpWpqBqzkUiSy4 +klNulCcdVNTSQcWUq41uJvAtz5NkBDyyqhjiAaWO8v3HgOaajNig6t3JtIv9tsf9V FPs5iPsNLU4dXjpHsMNVEi+unoM+aby8RAQ/v8TLlmbaDS2KHKUngYnsoFCtssBZ5q XpuK/lS/8+eOA== X-Mailgun-Dkim: no X-Mailgun-Dkim: no From: Yodel Eldar To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Stefano Garzarella , Paolo Bonzini , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Thomas Huth , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Yodel Eldar , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Subject: [RFC PATCH v2 2/3] tests/functional/x86_64: Add vhost-user-bridge test Date: Mon, 12 Jan 2026 17:01:26 -0600 Message-ID: <20260112230127.99125-3-yodel.eldar@yodel.dev> In-Reply-To: <20260112230127.99125-1-yodel.eldar@yodel.dev> References: <20260112230127.99125-1-yodel.eldar@yodel.dev> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=204.220.184.57; envelope-from=bounce+0e9322.97607e-qemu-devel=nongnu.org@yodel.dev; helo=k57.kb8c70eb.use4.send.mailgun.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yodel.dev) X-ZM-MESSAGEID: 1768258993223158500 Introduce a functional test of vhost-user-bridge and enter it into MAINTAINERS under the vhost section. The test runs vhost-user-bridge as a subprocess, then launches a guest with four backends: a unix domain socket for vhost-user, a UDP socket, a user-mode net, and a hubport to hub the UDP and user backends; only the vhost-user backend is exposed, the rest are deviceless. This configuration mimics the testing setup described in the initial commit of vhost-user-bridge in 3595e2eb0a23. A file containing a hardcoded UUID is created by the test in a scratch file and exposed to the guest via the tftp parameter of the user netdev. The guest requests the file by invoking tftp, and the test verifies its sha256 hashsum. Similarly, a file containing another hardcoded UUID is created in the guest. A call to check_http_download() serves the file via http to the host and verifies integrity with its hashsum. Suggested-by: C=C3=A9dric Le Goater Suggested-by: Marc-Andr=C3=A9 Lureau Suggested-by: Michael S. Tsirkin Suggested-by: Thomas Huth Signed-off-by: Yodel Eldar Reviewed-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Thomas Huth --- MAINTAINERS | 1 + .../x86_64/test_vhost_user_bridge.py | 147 ++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100755 tests/functional/x86_64/test_vhost_user_bridge.py diff --git a/MAINTAINERS b/MAINTAINERS index 3a46c7fd0b..f41811d482 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2374,32 +2374,33 @@ F: docs/devel/vfio-iommufd.rst vhost M: Michael S. Tsirkin R: Stefano Garzarella S: Supported F: hw/*/*vhost* F: docs/interop/vhost-user* F: docs/system/devices/vhost-user* F: contrib/vhost-user-*/ F: backends/*vhost* F: include/system/vhost-user-backend.h F: include/hw/virtio/vhost* F: include/*/vhost* F: subprojects/libvhost-user/ F: block/export/vhost-user* F: util/vhost-user-server.c F: net/vhost* +F: tests/functional/x86_64/test_vhost_user_bridge.py =20 vhost-shadow-virtqueue R: Eugenio P=C3=A9rez F: hw/virtio/vhost-shadow-virtqueue.* =20 virtio M: Michael S. Tsirkin S: Supported F: hw/*/virtio* F: hw/virtio/Makefile.objs F: hw/virtio/trace-events F: qapi/virtio.json F: net/vhost-user.c F: include/hw/virtio/ F: docs/devel/virtio* F: docs/devel/migration/virtio.rst diff --git a/tests/functional/x86_64/test_vhost_user_bridge.py b/tests/func= tional/x86_64/test_vhost_user_bridge.py new file mode 100755 index 0000000000..bf152dc959 --- /dev/null +++ b/tests/functional/x86_64/test_vhost_user_bridge.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2025 Software Freedom Conservancy, Inc. +# +# Author: Yodel Eldar +# +# SPDX-License-Identifier: GPL-2.0-or-later +""" +Test vhost-user-bridge (vubr) functionality: + + 1) Run vhost-user-bridge on the host. + 2) Launch a guest VM: + a) Instantiate a unix domain socket to the vubr-created path + b) Instantiate a vhost-user backend on top of that socket + c) Map a virtio-net-pci device to the vhost-user backend + d) Instantiate a UDP socket backend + e) Instantiate a user-mode net backend + i) Forward an ephemeral port to port 8080 in-guest with hostfw= d=3D + ii) Expose a generated scratch file to the guest with tftp=3D + f) Hub the UDP and user-mode backends. + 3) Invoke tftp in the guest to download exported scratch file from the= host. + 4) Serve a file to the host via http server in the guest. +""" + +import os +import shutil +import subprocess +from qemu_test import Asset, LinuxKernelTest, which +from qemu_test import exec_command_and_wait_for_pattern +from qemu_test import is_readable_executable_file +from qemu_test import wait_for_console_pattern +from qemu_test.ports import Ports + +class VhostUserBridge(LinuxKernelTest): + + ASSET_KERNEL_INITRAMFS =3D Asset( + "https://github.com/yodel/vhost-user-bridge-test/raw/refs/heads/ma= in/bzImage", + "8860d7aa59434f483542cdf25b42eacae0d4d4aa7ec923af9589d1ad4703d42b") + + HOST_UUID =3D "ba4c2e39-627f-487d-ae3b-93cc5d783eb8" + HOST_UUID_HSUM =3D \ + "d2932e34bf6c17b33e7325140b691e27c191d9ac4dfa550f68c09506facb09b9" + + GUEST_UUID =3D "143d2b21-fdf0-4c5e-a9ef-f35ebbac8945" + GUEST_UUID_HSUM =3D \ + "14b64203f5cf2afe520f8be0fdfe630aafc1e85d1301f55a0d1681e68881f3a2" + + def configure_vm(self, ud_socket_path, lport, rport, hostfwd_port, tft= pdir): + self.require_accelerator("kvm") + self.require_netdev("vhost-user") + self.require_netdev("socket") + self.require_netdev("hubport") + self.require_netdev("user") + self.require_device("virtio-net-pci") + self.set_machine("q35") + self.vm.add_args( + "-cpu", "host", + "-accel", "kvm", + "-append", "printk.time=3D0 console=3DttyS0", + "-smp", "2", + "-m", "128M", + "-object", "memory-backend-memfd,id=3Dmem0," + "size=3D128M,share=3Don,prealloc=3Don", + "-numa", "node,memdev=3Dmem0", + "-chardev", f"socket,id=3Dchar0,path=3D{ud_socket_path}", + "-netdev", "vhost-user,id=3Dvhost0,chardev=3Dchar0,vhostforc= e=3Don", + "-device", "virtio-net-pci,netdev=3Dvhost0", + "-netdev", f"socket,id=3Dudp0,udp=3Dlocalhost:{lport}," + f"localaddr=3Dlocalhost:{rport}", + "-netdev", "hubport,id=3Dhub0,hubid=3D0,netdev=3Dudp0", + "-netdev", "user,id=3Duser0," + f"hostfwd=3Dtcp:127.0.0.1:{hostfwd_port}-:8080," + f"tftp=3D{tftpdir}", + "-netdev", "hubport,id=3Dhub1,hubid=3D0,netdev=3Duser0" + ) + + def assemble_vubr_args(self, vubr_path, ud_socket_path, lport, rport): + vubr_args =3D [] + + if (stdbuf_path :=3D which("stdbuf")) is None: + self.log.info("Could not find stdbuf: vhost-user-bridge " + "log lines may appear out of order") + else: + vubr_args +=3D [stdbuf_path, "-o0", "-e0"] + + vubr_args +=3D [vubr_path, "-u", f"{ud_socket_path}", + "-l", f"127.0.0.1:{lport}", "-r", f"127.0.0.1:{rport= }"] + + return vubr_args + + def test_vhost_user_bridge(self): + prompt =3D "~ # " + host_uuid_filename =3D "vubr-test-uuid.txt" + guest_uuid_path =3D "/tmp/uuid.txt" + kernel_path =3D self.ASSET_KERNEL_INITRAMFS.fetch() + + vubr_path =3D self.build_file("contrib", "vhost-user-bridge", + "vhost-user-bridge") + if is_readable_executable_file(vubr_path) is None: + self.skipTest("Could not find a readable and executable " + "vhost-user-bridge") + + vubr_log_path =3D self.log_file("vhost-user-bridge.log") + self.log.info("For the vhost-user-bridge application log," + f" see: {vubr_log_path}") + + sock_dir =3D self.socket_dir() + ud_socket_path =3D os.path.join(sock_dir.name, "vubr-test.sock") + + tftpdir =3D self.scratch_file("tftp") + shutil.rmtree(tftpdir, ignore_errors=3DTrue) + os.mkdir(tftpdir) + host_uuid_path =3D self.scratch_file("tftp", host_uuid_filename) + with open(host_uuid_path, "w") as host_uuid_file: + host_uuid_file.write(self.HOST_UUID) + + with Ports() as ports: + lport, rport, hostfwd_port =3D ports.find_free_ports(3) + + self.configure_vm(ud_socket_path, lport, rport, hostfwd_port, + tftpdir) + + vubr_args =3D self.assemble_vubr_args(vubr_path, ud_socket_pat= h, + lport, rport) + + with open(vubr_log_path, "w+") as vubr_log, \ + subprocess.Popen(vubr_args, stdin=3Dsubprocess.DEVNULL, + stdout=3Dvubr_log, + stderr=3Dsubprocess.STDOUT) as vubr_proc: + self.launch_kernel(kernel_path, wait_for=3Dprompt) + + exec_command_and_wait_for_pattern(self, + f"tftp -g -r {host_uuid_filename} 10.0.2.2 ; " + f"sha256sum {host_uuid_filename}", self.HOST_UUID_HSUM) + wait_for_console_pattern(self, prompt) + + exec_command_and_wait_for_pattern(self, + f"echo -n '{self.GUEST_UUID}' > {guest_uuid_path}", pr= ompt) + self.check_http_download(guest_uuid_path, self.GUEST_UUID_= HSUM) + wait_for_console_pattern(self, prompt) + + self.vm.shutdown() + vubr_proc.terminate() + vubr_proc.wait() + +if __name__ =3D=3D '__main__': + LinuxKernelTest.main() --=20 2.52.0 From nobody Sun Feb 8 22:22:51 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=yodel.dev ARC-Seal: i=1; a=rsa-sha256; t=1768258997; cv=none; d=zohomail.com; s=zohoarc; b=lbxeZBs8aUfi7/8wrc7X4K+tqHqLnZymai1VeDp5pNhMyvR1G09uNNab4HFqRbt/cP28dobT19k4ZDLov7BckOLnzwhkzuEOfO5t61m5fCnqMO0VPqILFAydiA3puYadOh5ZOm9WHpfWIs5b/lqaifQD/gPMbV6U78kyKYWAcKc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768258997; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=xwtjK7x6BTDlVvAv7/H3jIfDh9ywaqSThR0qDBIpM7Q=; b=LSnhZE5kkw2f7p5Mo2LzCNMRaMsgWDQcv7/lbnCj7XLF+tTRcAHG40KEgUIYPf6NgkFjwJqsfeNszCVJVCt+kf6K9PagTZbZzMyJmV4VALlY0YW2Qy51+susxhKWClyMDLDPgkRrAExQ2bkqtb8lcJcwJfcx3BdemT7PvvPdt/0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1768258997033498.9736672389207; Mon, 12 Jan 2026 15:03:17 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vfQvR-0003Kt-UB; Mon, 12 Jan 2026 18:02:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1vfQvQ-0003KC-AM for qemu-devel@nongnu.org; Mon, 12 Jan 2026 18:02:16 -0500 Received: from k62.kb8c70eb.use4.send.mailgun.net ([204.220.184.62]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1vfQvO-0006IJ-Nq for qemu-devel@nongnu.org; Mon, 12 Jan 2026 18:02:16 -0500 Received: from mail.yodel.dev (mail.yodel.dev [35.209.39.246]) by 9034cdd405f10f7bd058b0d51d498517515ee3791efb5c917effaaa0d63f5937 with SMTP id 69657d6e881ee7b9b8d5a3c3; Mon, 12 Jan 2026 23:02:06 GMT X-Mailgun-Sid: WyI4ZDFlNiIsInFlbXUtZGV2ZWxAbm9uZ251Lm9yZyIsIjk3NjA3ZSJd X-Mailgun-Sending-Ip: 204.220.184.62 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yodel.dev; s=rsa2048; t=1768258926; bh=xwtjK7x6BTDlVvAv7/H3jIfDh9ywaqSThR0qDBIpM7Q=; h=X-Mailgun-Dkim:From:To:Cc:Subject:Date:Message-ID:In-Reply-To: References:MIME-Version:Content-Transfer-Encoding:From:Reply-to: Subject:Date:Message-id:To:Cc:Mime-version:Content-type: Content-transfer-encoding:In-reply-to:References; b=kHEXVRIFhQJpSNClxycx0Gkx4oCrBoOwRRJpI+zMWMo2GRtNPASJVvGiVBzJ9uPy0 voAo+0pOs9M07mk9/l7CzCqifKDNyyY4736Ry9qFJDQ6bfddmTO9y7MUjQUqbKzMcv YECSqf5RIhGsG24HBFH74yfFsLfS3XE1aNPdao7NzgvGxmDaZwC57ztPe1ISX6oMu1 uIDZtja+Fbvk1WOAsBBKLyM+ujtaV7L1EoIGqo5y+pAJ7NPbi8kWzi+O7iWW4ugL+e +WQgQt9m+HW8ZQODphuKIwFXi+o0d9mU6248tILDs6EZ4t5cw0+m08WNuFKOHDXYhp ritXFhYo/GLQg== X-Mailgun-Dkim: no X-Mailgun-Dkim: no From: Yodel Eldar To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Stefano Garzarella , Paolo Bonzini , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Thomas Huth , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , Yodel Eldar Subject: [RFC PATCH v2 3/3] contrib/vhost-user-bridge: Add UDP receive hexdump Date: Mon, 12 Jan 2026 17:01:27 -0600 Message-ID: <20260112230127.99125-4-yodel.eldar@yodel.dev> In-Reply-To: <20260112230127.99125-1-yodel.eldar@yodel.dev> References: <20260112230127.99125-1-yodel.eldar@yodel.dev> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=204.220.184.62; envelope-from=bounce+0e9322.97607e-qemu-devel=nongnu.org@yodel.dev; helo=k62.kb8c70eb.use4.send.mailgun.net X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @yodel.dev) X-ZM-MESSAGEID: 1768258999210158500 Content-Type: text/plain; charset="utf-8" vhost-user-bridge debug prints UDP TX hexdumps in its transmit handler, but does not for receives, even though they are beneficial for testing. Add an RX hexdump in the receive callback. To delineate between transmits and receives, also add a debug print indicating that the program is in the transmit handler. Signed-off-by: Yodel Eldar Reviewed-by: Marc-Andr=C3=A9 Lureau --- contrib/vhost-user-bridge/vhost-user-bridge.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/contrib/vhost-user-bridge/vhost-user-bridge.c b/contrib/vhost-= user-bridge/vhost-user-bridge.c index ce4c3426d3..3f0fd0fa49 100644 --- a/contrib/vhost-user-bridge/vhost-user-bridge.c +++ b/contrib/vhost-user-bridge/vhost-user-bridge.c @@ -179,6 +179,9 @@ vubr_handle_tx(VuDev *dev, int qidx) =20 assert(qidx % 2); =20 + DPRINT("\n\n *** IN UDP TRANSMIT HANDLER ***\n\n"); + DPRINT(" hdrlen =3D %d\n", hdrlen); + for (;;) { ssize_t ret; unsigned int out_num; @@ -333,6 +336,10 @@ vubr_backend_recv_cb(int sock, void *ctx) }; ret =3D RETRY_ON_EINTR(recvmsg(vubr->backend_udp_sock, &msg, 0)); =20 + if (ret > 0 && VHOST_USER_BRIDGE_DEBUG) { + iov_hexdump(sg, num, stderr, "RX:", ret); + } + if (i =3D=3D 0) { iov_restore_front(elem->in_sg, sg, hdrlen); } --=20 2.52.0