From nobody Mon Dec 15 21:29:04 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1750837291; cv=none; d=zohomail.com; s=zohoarc; b=M25y5yUN+vDWnJaPj8d+BizexibaSgMCEK1T17Nq7TRCNKy+JYwjDEifXjWbMFILUP3d91LGgGl7fGkfpMPxtC6reGsnLq0Wtws6hVOBbMHooOyYE2Ps1uAmOnFNoY679qQV+gzOOxLweUsFhCONnTe9gM2Pl39KBicHbE+C/mI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750837291; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:Subject:Subject:To:To:Message-Id; bh=GWJ6IaZ57O74Muxo5PAL4pyLB3RKPTFbxURuoEDTkHo=; b=IejUa6nNboY/rWWdiPQh8m4mBsIN6wMZswtia2Wnb0J2o0rETCMmsW4n5VDElFtub9b/lV6ZnXjwxoZDV+gBKI+Lmfi2i5nrUcwbsWNfJnN+7eNi500Av5FfYyKmUmsBCflMwC7UwxQOy3suL2B0EXwVKTBPon8sxnh+yrJz1IA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1750837291181310.4143315675142; Wed, 25 Jun 2025 00:41:31 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id EBDA013CD; Wed, 25 Jun 2025 03:41:29 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 638E41394; Wed, 25 Jun 2025 03:40:34 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 21916135A; Wed, 25 Jun 2025 03:40:31 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id EE959134E for ; Wed, 25 Jun 2025 03:40:29 -0400 (EDT) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-494-gyajKjXuNjWT9RM-v6XrtA-1; Wed, 25 Jun 2025 03:40:28 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 52CA719560A2 for ; Wed, 25 Jun 2025 07:40:27 +0000 (UTC) Received: from fedora.redhat.com (unknown [10.45.224.35]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 343A13000221; Wed, 25 Jun 2025 07:40:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750837229; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=zMtHvkUYUn2mHDzezbu0yHRV8w6B8z0csi6UKanvJf4=; b=PAHkpzxwdFAzz/sWDGR51d3pWJEsVBxC0xcCATHRcZtijAV8t85o3k1oq51t/8t2TfZ9xq eQRn6HunUiqMvy5VIvSQaG0QEm6zwzaBo/za4a+dlJWnatU1tgWwcP45r4LEQMSPet9083 npPLRKJF/gsRNBYWCc9aTPC7mWWhBHg= X-MC-Unique: gyajKjXuNjWT9RM-v6XrtA-1 X-Mimecast-MFC-AGG-ID: gyajKjXuNjWT9RM-v6XrtA_1750837227 To: devel@lists.libvirt.org Subject: [PATCH RFE] conf: Add extraArgs option to passt backend Date: Wed, 25 Jun 2025 09:40:16 +0200 Message-ID: <20250625074016.294856-1-ellorent@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 3c-J3xptTMIKrnxs7DGcBxBQZXHpRpo6aJcIimAQO4g_1750837227 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: JWTHTPZXLBDJYRH3VCEUXJAB4HL4IFUG X-Message-ID-Hash: JWTHTPZXLBDJYRH3VCEUXJAB4HL4IFUG X-MailFrom: ellorent@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Enrique Llorente X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: From: Enrique Llorente via Devel Reply-To: Enrique Llorente X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1750837291988116600 Content-Type: text/plain; charset="utf-8"; x-default="true" Add support for passing extra arguments to the passt binary through the domain XML configuration. This allows users to specify additional command-line arguments for passt that are not covered by existing structured fields. The new extraArgs attribute is added to the backend element: The extraArgs string is parsed using g_shell_parse_argv() to split it into individual arguments before passing them to the passt command. This change includes: - New field in virDomainNetBackend structure - XML schema update to allow extraArgs attribute - Parsing and formatting support in domain_conf.c - Backend comparison function update - Memory cleanup for the new field - QEMU passt integration to use the extra arguments - Comprehensive tests for both user and vhostuser interfaces This is an RFE to gather feedback on the approach. I have a few questions for the community: 1. Is this general approach of adding extraArgs reasonable, or should we instead focus on adding specific structured fields for each passt option? 2. Should extraArgs be marked as unsupported/unstable in the documentation, with a clear indication that it's primarily intended for development and testing purposes? 3. Are there any security concerns with allowing arbitrary arguments to be passed to the passt binary via XML configuration? 4. Would it be better to validate the arguments against a known allowlist rather than allowing any argument string? The current implementation uses g_shell_parse_argv() to safely parse the argument string, but I'm open to feedback on whether additional validation or restrictions should be applied. Signed-off-by: Enrique Llorente --- src/conf/domain_conf.c | 6 ++- src/conf/domain_conf.h | 1 + src/conf/schemas/domaincommon.rng | 3 ++ src/qemu/qemu_passt.c | 16 +++++++ ...t-user-passt-extra-args.x86_64-latest.args | 35 ++++++++++++++ ...et-user-passt-extra-args.x86_64-latest.xml | 44 +++++++++++++++++ .../net-user-passt-extra-args.xml | 41 ++++++++++++++++ ...stuser-passt-extra-args.x86_64-latest.args | 36 ++++++++++++++ ...ostuser-passt-extra-args.x86_64-latest.xml | 47 +++++++++++++++++++ .../net-vhostuser-passt-extra-args.xml | 44 +++++++++++++++++ tests/qemuxmlconftest.c | 2 + 11 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-= latest.args create mode 100644 tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-= latest.xml create mode 100644 tests/qemuxmlconfdata/net-user-passt-extra-args.xml create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt-extra-args.x8= 6_64-latest.args create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt-extra-args.x8= 6_64-latest.xml create mode 100644 tests/qemuxmlconfdata/net-vhostuser-passt-extra-args.xml diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 1e24e41a48..a83b9002d0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2918,6 +2918,7 @@ virDomainNetDefFree(virDomainNetDef *def) g_free(def->backend.tap); g_free(def->backend.vhost); g_free(def->backend.logFile); + g_free(def->backend.extraArgs); virDomainNetTeamingInfoFree(def->teaming); g_free(def->virtPortProfile); g_free(def->script); @@ -9798,6 +9799,7 @@ virDomainNetBackendParseXML(xmlNodePtr node, } =20 def->backend.logFile =3D virXMLPropString(node, "logFile"); + def->backend.extraArgs =3D virXMLPropString(node, "extraArgs"); =20 if (tap) def->backend.tap =3D virFileSanitizePath(tap); @@ -20799,7 +20801,8 @@ virDomainNetBackendIsEqual(virDomainNetBackend *src, if (src->type !=3D dst->type || STRNEQ_NULLABLE(src->tap, dst->tap) || STRNEQ_NULLABLE(src->vhost, dst->vhost) || - STRNEQ_NULLABLE(src->logFile, dst->logFile)) { + STRNEQ_NULLABLE(src->logFile, dst->logFile) || + STRNEQ_NULLABLE(src->extraArgs, dst->extraArgs)) { return false; } return true; @@ -24934,6 +24937,7 @@ virDomainNetBackendFormat(virBuffer *buf, virBufferEscapeString(&attrBuf, " tap=3D'%s'", backend->tap); virBufferEscapeString(&attrBuf, " vhost=3D'%s'", backend->vhost); virBufferEscapeString(&attrBuf, " logFile=3D'%s'", backend->logFile); + virBufferEscapeString(&attrBuf, " extraArgs=3D'%s'", backend->extraArg= s); virXMLFormatElement(buf, "backend", &attrBuf, NULL); } =20 diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 6997cf7c09..d85e6e5c8e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1076,6 +1076,7 @@ struct _virDomainNetBackend { char *vhost; /* The following are currently only valid/used when backend type=3D'pa= sst' */ char *logFile; /* path to logfile used by passt process */ + char *extraArgs; /* extra arguments to pass to passt process */ }; =20 struct _virDomainNetPortForwardRange { diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincom= mon.rng index 183dd5db5e..58946b6873 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -3931,6 +3931,9 @@ + + + diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c index fcc34de384..47efbc4c80 100644 --- a/src/qemu/qemu_passt.c +++ b/src/qemu/qemu_passt.c @@ -229,6 +229,22 @@ qemuPasstStart(virDomainObj *vm, if (net->backend.logFile) virCommandAddArgList(cmd, "--log-file", net->backend.logFile, NULL= ); =20 + /* Add extra arguments */ + if (net->backend.extraArgs) { + g_auto(GStrv) extraArgv =3D NULL; + gint argc =3D 0; + =20 + if (!g_shell_parse_argv(net->backend.extraArgs, &argc, &extraArgv,= NULL)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Failed to parse extraArgs: %1$s"), net->back= end.extraArgs); + return -1; + } + + for (gint j =3D 0; j < argc; j++) { + virCommandAddArg(cmd, extraArgv[j]); + } + } + /* Add IP address info */ for (i =3D 0; i < net->guestIP.nips; i++) { const virNetDevIPAddr *ip =3D net->guestIP.ips[i]; diff --git a/tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-latest.= args b/tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-latest.args new file mode 100644 index 0000000000..48d2596594 --- /dev/null +++ b/tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-latest.args @@ -0,0 +1,35 @@ +LC_ALL=3DC \ +PATH=3D/bin \ +HOME=3D/var/lib/libvirt/qemu/domain--1-QEMUGuest1 \ +USER=3Dtest \ +LOGNAME=3Dtest \ +XDG_DATA_HOME=3D/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=3D/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=3D/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=3DQEMUGuest1,debug-threads=3Don \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/va= r/lib/libvirt/qemu/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc,usb=3Doff,dump-guest-core=3Doff,memory-backend=3Dpc.ram,acpi= =3Doff \ +-accel tcg \ +-cpu qemu64 \ +-m size=3D219136k \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":224395264}'= \ +-overcommit mem-lock=3Doff \ +-smp 1,sockets=3D1,cores=3D1,threads=3D1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=3Dcharmonitor,fd=3D1729,server=3Don,wait=3Doff \ +-mon chardev=3Dcharmonitor,id=3Dmonitor,mode=3Dcontrol \ +-rtc base=3Dutc \ +-no-shutdown \ +-boot strict=3Don \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1","no= de-name":"libvirt-1-storage","read-only":false}' \ +-device '{"driver":"ide-hd","bus":"ide.0","unit":0,"drive":"libvirt-1-stor= age","id":"ide0-0-0","bootindex":1}' \ +-netdev '{"type":"stream","addr":{"type":"unix","path":"/var/run/libvirt/q= emu/passt/-1-QEMUGuest1-net0.socket"},"server":false,"reconnect-ms":5000,"i= d":"hostnet0"}' \ +-device '{"driver":"rtl8139","netdev":"hostnet0","id":"net0","mac":"00:11:= 22:33:44:55","bus":"pci.0","addr":"0x2"}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-sandbox on,obsolete=3Ddeny,elevateprivileges=3Ddeny,spawn=3Ddeny,resource= control=3Ddeny \ +-msg timestamp=3Don diff --git a/tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-latest.= xml b/tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-latest.xml new file mode 100644 index 0000000000..e01dc55894 --- /dev/null +++ b/tests/qemuxmlconfdata/net-user-passt-extra-args.x86_64-latest.xml @@ -0,0 +1,44 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + qemu64 + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + +
+ + + +
+ + + + + + + + +
+ + + +