From nobody Mon Feb 9 02:15:32 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=1768945870; cv=none; d=zohomail.com; s=zohoarc; b=MwjN+3FGdTSjBzjRXrGRLF2wKk02llIzEKELTmo+ryi/k3erhrRILOg95ldb26CfBlZBc+nBOvVc2x3jCnRFl9bcS+N6d4+iFVu9cPM0cN8otCXlIrtlvWu6xtvVxLBDlOt313plzyhBu6T35pp0zoCO0A5hqf7+AQk6PZQIkQE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768945870; 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=3x6d4caxKpnoY+YeEIVzbKHipAPwF4qHlbP+jL+qgBM=; b=me35N53hAsuk5uzTbSUsmwFn7mbEg17Lv7AOU8a1qj6YD9zhecIZrBlG8oicwmmBWrz8t1K4gb61updrZqgM+mN2dGeb0BOzzpbX2LZB4ipxZ1J+hqLKn6mLuohyogdebIzO2NTTDIj1FIr0uWXM3qZ8PL+7RtdRrWWhLxusLNM= 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 1768945870031917.9316746710156; Tue, 20 Jan 2026 13:51:10 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1viJcW-0007tr-2A; Tue, 20 Jan 2026 16:50:40 -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 1viJcU-0007s0-Rh for qemu-devel@nongnu.org; Tue, 20 Jan 2026 16:50:39 -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 1viJcT-0002fa-0T for qemu-devel@nongnu.org; Tue, 20 Jan 2026 16:50:38 -0500 Received: from mail.yodel.dev (mail.yodel.dev [35.209.39.246]) by a91f9f673cae916c58a140c5093b40313d622028b34b0f2102b0f4160105c686 with SMTP id 696ff8a5b6eaa26798b281c2; Tue, 20 Jan 2026 21:50:29 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=1768945828; bh=3x6d4caxKpnoY+YeEIVzbKHipAPwF4qHlbP+jL+qgBM=; 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=gU/bzFUK1t/STiJx1BnFC7zqzZCeKfgBZJR7/yFonQUPjKG1pTf99/+KnE4I6jfWi mZ329Xs5TQG3XGEWJiih/a+1h7DrmGhZnmbIVatRyEKPuhLkOW+e34k3MOYUEp2hFf Ztz4ZRX4BqItw5JIyDfvusQUIh9gRlrIEAJYVMnHLJ3Z8dQpO32Ig7+ziYsExI37CI zJ9mgH1VBDs1aqIdjf2XpaCm8Hqc2hBsrQeWroIl06jnJrrRko80/tepKDtsAI3fbG YEQuB5oj8TS1LDDwbggLhguqKRB2bW17Rz2KfSiXzmkHL06SAuhh78+s1euLSxtsjp Aaoy8pUDLSJTw== 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: [PATCH v3 1/3] tests/vhost-user-bridge: Move to contrib/vhost-user-bridge/ Date: Tue, 20 Jan 2026 15:50:19 -0600 Message-ID: <20260120215021.30711-2-yodel.eldar@yodel.dev> In-Reply-To: <20260120215021.30711-1-yodel.eldar@yodel.dev> References: <20260120215021.30711-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: 1768945871107154100 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. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Yodel Eldar --- 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 3108f01e88..adfb0a9a89 100644 --- a/meson.build +++ b/meson.build @@ -4491,6 +4491,7 @@ if have_tools =20 if have_vhost_user subdir('contrib/vhost-user-blk') + subdir('contrib/vhost-user-bridge') subdir('contrib/vhost-user-gpu') subdir('contrib/vhost-user-input') subdir('contrib/vhost-user-scsi') 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 Mon Feb 9 02:15:32 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=1768945859; cv=none; d=zohomail.com; s=zohoarc; b=HNOxbl/m9u7zDCi2lQ4FoU2ZdWwtajbfkwf2Ike5wcfakeo270AV2dSZi2zCna8OcTF9JW3WShbl5FKowSDoc81GfRfM00A7VITOsItnobM8wi1hPNf30fRX+s+JdItLDFcfjAyaIvs89CwGQnawf4bgsqDaDvoSiiI0GEedyVw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768945859; 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=N6ZudBQFsu9QLbM2mzNBmI2SHDXA0BLA2na/UUyQBzk=; b=IzBnhx2OLxp5+kyA8XA7jo4eFFEJp93wh5rumJP7+UfwLC7bnB3UlDM+AQK7SuKkCjaUHIZh0j/t7l+zPqErjrNv3gw00fzes5mcRToUIv2b7ZgMO+oQpXKE8T4XtmlwlZ8D7hFaVxXE8nXVtYcyOds5kuMXB7z8Kr7UVUha36M= 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 176894585957081.79690942507602; Tue, 20 Jan 2026 13:50:59 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1viJcY-0007xJ-FZ; Tue, 20 Jan 2026 16:50:42 -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 1viJcW-0007uW-KT for qemu-devel@nongnu.org; Tue, 20 Jan 2026 16:50:40 -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 1viJcU-0002ff-0f for qemu-devel@nongnu.org; Tue, 20 Jan 2026 16:50:40 -0500 Received: from mail.yodel.dev (mail.yodel.dev [35.209.39.246]) by b3db009439be2067bd0b0621d9077bb4f0f2cb3a53ce05603b587bc9405d8b2a with SMTP id 696ff8a55772fc26966b9224; Tue, 20 Jan 2026 21:50:29 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=1768945828; bh=N6ZudBQFsu9QLbM2mzNBmI2SHDXA0BLA2na/UUyQBzk=; 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=YuMvOezIGb58xGgf6qnviwAEH7xzR0+SezQRYq1xX9RwES/badrfMMNY9vzYehw8P HaI6sYqP/+CoOiiamRpGWJvXre0/Y2PjF0Kv2fXuAb3E4jRal92HyEwYDuvdNs0GGh PTaneC0cshLPcVkBo4PniOK+oxwpSnSeq4cYT2c9LrsS8hXB82+R47yQy9+hZQOUhf 2tYlp4NEy2KFm4kT/LcRqfU2bmX9caKUzijE7ATh1mJIUegExKiM1O0MTzibAvr2yd TirwR+XePlSjeed1s92lkiYDewITW7UEeoIWnk4IQL1RXrkkwRd/W170yiilsKHG+n kfqdmr6w7i6bQ== 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: [PATCH v3 2/3] tests/functional/x86_64: Add vhost-user-bridge test Date: Tue, 20 Jan 2026 15:50:20 -0600 Message-ID: <20260120215021.30711-3-yodel.eldar@yodel.dev> In-Reply-To: <20260120215021.30711-1-yodel.eldar@yodel.dev> References: <20260120215021.30711-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.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_MSPIKE_H2=0.001, 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: 1768945861380154100 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. The test creates a scratch file containing a hardcoded UUID on the host and exposes it to the the guest via the tftp parameter of the user netdev. After the guest invokes tftp to request the file, the test verifies the transfer by hashsum. Similarly, the test creates a file with another hardcoded UUID in the guest. A call to check_http_download() serves the file to the host via http, whereupon a check of the file hashsum occurs on the host. Lastly, add the test to the thorough tests suite in meson.build. Suggested-by: C=C3=A9dric Le Goater Suggested-by: Marc-Andr=C3=A9 Lureau Suggested-by: Michael S. Tsirkin Suggested-by: Thomas Huth Reviewed-by: Thomas Huth Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Yodel Eldar --- MAINTAINERS | 1 + tests/functional/x86_64/meson.build | 1 + .../x86_64/test_vhost_user_bridge.py | 147 ++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100755 tests/functional/x86_64/test_vhost_user_bridge.py diff --git a/MAINTAINERS b/MAINTAINERS index c1e586c58f..343493ae21 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2388,6 +2388,7 @@ 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 diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/= meson.build index f78eec5e6c..beab4f304b 100644 --- a/tests/functional/x86_64/meson.build +++ b/tests/functional/x86_64/meson.build @@ -34,6 +34,7 @@ tests_x86_64_system_thorough =3D [ 'reverse_debug', 'tuxrun', 'vfio_user_client', + 'vhost_user_bridge', 'virtio_balloon', 'virtio_gpu', ] 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..ed8c5af298 --- /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", f"user,id=3Duser0,tftp=3D{tftpdir}," + f"hostfwd=3Dtcp:127.0.0.1:{hostfwd_port}-:8080", + "-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", encoding=3D"utf-8") as host_uuid_fi= le: + host_uuid_file.write(self.HOST_UUID) + + with Ports() as ports: + # pylint: disable=3Dunbalanced-tuple-unpacking + 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", encoding=3D"utf-8") 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 Mon Feb 9 02:15:32 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=1768945874; cv=none; d=zohomail.com; s=zohoarc; b=BqVqQDolbQKfES41cgT2wPtFZgOk5wvtbBkzaQsvGOI1dh3oQ+4vJvP8dtd2J321xzye0B6TjpDnFApeZdwFgukH+vA5HcTKQzyCHg0NyUaq+gYHEpOd74BnJXZU/NyZx+7h5kv+MTW39gIvZPNbsweyuOv55AhBDT9D3tmDLPA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1768945874; 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=Ej5O681xYjZWSg5wZN5ay/83YP28Uk0vBVTIItvtfIw=; b=idsXeJ7UCDtOxO6EGOO8ROP5LMLhd5Y2pv7CdgT6npqUR8F+46UG5TC2dDu/1/MWmxes8Hj9DpSISbktF06hjci82n1mDkMXyBQgmu+g6FoDOUa6aHoJtvoeoVLn9LHBAS2d5F4nZoayOwn1mxu5C8yOY6GnnBSCZEEuav8m7Z0= 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 1768945874024334.0577903855084; Tue, 20 Jan 2026 13:51:14 -0800 (PST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1viJcZ-0007yZ-3t; Tue, 20 Jan 2026 16:50:43 -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 1viJcW-0007uA-5S for qemu-devel@nongnu.org; Tue, 20 Jan 2026 16:50:40 -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 1viJcT-0002fe-Vc for qemu-devel@nongnu.org; Tue, 20 Jan 2026 16:50:39 -0500 Received: from mail.yodel.dev (mail.yodel.dev [35.209.39.246]) by 6e55ebd206cd51642717122bceebae796ce0741c995ba3e4915e6cb245ee7f8a with SMTP id 696ff8a52696f198342e2c58; Tue, 20 Jan 2026 21:50:29 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=1768945829; bh=Ej5O681xYjZWSg5wZN5ay/83YP28Uk0vBVTIItvtfIw=; 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=cGPYTk94vmX0s3u0Yte0Er3s056UWE5lT7GYyTlAJt+XwMn/jxScoRCFq7dQ6uawA ZsX9gUJ100b8Hm4RAWVpwggH9d1kTk7aKExss+1tgkUaBOezjxAV+WkKtmnXPI06Cv 5d/M25KHbaX/hXX86BH0BkMmAp5vT+nDOjD8dxmMv+vxLhpxohi2W6qiNzga3G2F28 MWkfZs8xyWgN78BenNSejBvkxQ1MZ7sMwZCO8j81kQceP2KqUP0IS8v0qdTOXYS4pH kB671lYDBgEtPz8K83rQAtor079xhSXwaX+elgN+rKCXIcPql1lqRQyrNhrrbkvAdI m5NziAaUuPbxw== 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: [PATCH v3 3/3] contrib/vhost-user-bridge: Add UDP receive hexdump Date: Tue, 20 Jan 2026 15:50:21 -0600 Message-ID: <20260120215021.30711-4-yodel.eldar@yodel.dev> In-Reply-To: <20260120215021.30711-1-yodel.eldar@yodel.dev> References: <20260120215021.30711-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.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_MSPIKE_H2=0.001, 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: 1768945876104158500 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. Reviewed-by: Marc-Andr=C3=A9 Lureau Signed-off-by: Yodel Eldar --- 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