From nobody Tue Mar 3 04:52:36 2026 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=1771919865; cv=none; d=zohomail.com; s=zohoarc; b=CfQ61dIEhe4qjCM0bcsY+sJWUllQj47RTArN37hoGfZhWPhL42h+EaM0MvEM+oT76AKj7Fo/ZHUwXzUHGZk9PnUcoI4C5oSx/nX1oROXpsWeY6lRO5KMVzw4ntdeEYEJwbJ6vVBBOGTnn2h5Po6RLV9Fl9urwISgHGe+usWaF/c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1771919865; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=eRmtygk9l4WUQh34qJC1K9dgBKlBF+o4MXNN9UmcjaY=; b=NwRUmt5nGyKd0eiP4uIdQbaxODJOi85FDfFunZJiBKHpy0imBuc13+P0+b4A1o+lWWliq73Gs4GvxfbJfUpduprqrfAi+rFofEIW7iArYbG2/uO8tk/chO3QCqGHSqh+Crict9FVo+cyQmfcHBtP5hDZJ9buqhMWltSkcpo5mTY= 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 1771919865055807.7780472945913; Mon, 23 Feb 2026 23:57:45 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 1B04B41B7B; Tue, 24 Feb 2026 02:57:44 -0500 (EST) Received: from [172.19.199.9] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id EE03C4240F; Tue, 24 Feb 2026 02:52:34 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id A238E41DE8; Tue, 24 Feb 2026 02:52:29 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 3E97841B80 for ; Tue, 24 Feb 2026 02:52:17 -0500 (EST) Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-486-6Qf0SN38Or643jcAhLWNjA-1; Tue, 24 Feb 2026 02:52:14 -0500 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 615DA1828ABF for ; Tue, 24 Feb 2026 07:52:13 +0000 (UTC) Received: from vhost3.router.laine.org (unknown [10.22.64.82]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0A3271800370 for ; Tue, 24 Feb 2026 07:52:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HELO_MISC_IP,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1771919536; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=eRmtygk9l4WUQh34qJC1K9dgBKlBF+o4MXNN9UmcjaY=; b=V4JBLRf5QtDF3C7wZTDMBkDBdIn6kV7MhuG/rhljaaaM4aJE+9OBbrLP//xF5sJSIiOiS/ L8YUxGk5J0MmTDjf3p+hpzXyGwPU8Y4wYg08TLZV0jbcdZeeEfXqXwEjANJYFlJ/e+pTD5 kd6DVyGoZ/x9oJWM3QUUs5cZCk3cUVY= X-MC-Unique: 6Qf0SN38Or643jcAhLWNjA-1 X-Mimecast-MFC-AGG-ID: 6Qf0SN38Or643jcAhLWNjA_1771919533 To: devel@lists.libvirt.org Subject: [PATCH 6/6] qemu: support setting default route for passt interfaces inside the guest Date: Tue, 24 Feb 2026 02:52:08 -0500 Message-ID: <20260224075208.225959-7-laine@redhat.com> In-Reply-To: <20260224075208.225959-1-laine@redhat.com> References: <20260224075208.225959-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Z4bHSjquVtKhflC42B-_yNYqHyzRO9tfgkBfoDyS45U_1771919533 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: DNTD2IMES6H2X4RGY2OQV3U73JYVVFZO X-Message-ID-Hash: DNTD2IMES6H2X4RGY2OQV3U73JYVVFZO X-MailFrom: laine@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Laine Stump via Devel Reply-To: Laine Stump X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1771919865673158500 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Laine Stump libvirt's element has for a long time supported adding sub-elements to specify arbitrary routes to be added to the guest OS networking, but historically this has only worked for LXC guests. If you tried to add to the interface of a QEMU guest, it would be rejected. passt networking doesn't support setting *any arbitrary* route but it does support setting a default route (using the passt commandline "--gateway" parameter). A default route is really just a "route with unspecified destination/prefix", so a default route can be specified in libvirt XML with: Attempts to give a specified destination, prefix, or metric will result in a validation error. Resolves: https://issues.redhat.com/browse/RHEL-46602 Signed-off-by: Laine Stump --- src/qemu/qemu_passt.c | 16 +++++++++++++ src/qemu/qemu_validate.c | 50 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_passt.c b/src/qemu/qemu_passt.c index 56d048d585..125227747d 100644 --- a/src/qemu/qemu_passt.c +++ b/src/qemu/qemu_passt.c @@ -263,6 +263,22 @@ qemuPasstBuildCommand(char **socketName, } } =20 + /* Add default route(s) */ + for (i =3D 0; i < net->guestIP.nroutes; i++) { + const virNetDevIPRoute *route =3D net->guestIP.routes[i]; + g_autofree char *gateway =3D NULL; + + if (!(gateway =3D virSocketAddrFormat(&route->gateway))) + return NULL; + + /* validation has already guaranteed that there is at most 1 + * IPv4 and 1 IPv6 route, and that they are only default + * routes (i.e. destination 0.0.0.0/0) + */ + + virCommandAddArgList(cmd, "--gateway", gateway, NULL); + } + /* Add port forwarding info */ =20 for (i =3D 0; i < net->nPortForwards; i++) { diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 1c6662751b..c194a8a7cd 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -1884,6 +1884,8 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNet= Def *net, { bool hasV4Addr =3D false; bool hasV6Addr =3D false; + bool hasV4Route =3D false; + bool hasV6Route =3D false; size_t i; =20 if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_USER || @@ -1958,10 +1960,50 @@ qemuValidateDomainDeviceDefNetwork(const virDomainN= etDef *net, } } =20 - if (net->guestIP.nroutes) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Invalid attempt to set network interface guest-s= ide IP route, not supported by QEMU")); - return -1; + + for (i =3D 0; i < net->guestIP.nroutes; i++) { + const virNetDevIPRoute *route =3D net->guestIP.routes[i]; + + if (net->backend.type !=3D VIR_DOMAIN_NET_BACKEND_PASST) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Invalid attempt to set network interface gue= st-side IP route, not supported for this interface type/backend")); + return -1; + } + + switch (VIR_SOCKET_ADDR_FAMILY(&route->gateway)) { + case AF_INET: + if (hasV4Route) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only one IPv4 default route can be speci= fied for an interface using the passt backend")); + return -1; + } + hasV4Route =3D true; + break; + case AF_INET6: + if (hasV6Route) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only one IPv6 default route can be speci= fied for an interface using the passt backend")); + return -1; + } + hasV6Route =3D true; + break; + default: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("All elements of an interface using t= he passt backend must be default routes, with an IPv4 or IPv6 gateway speci= fied")); + return -1; + } + + /* the only type of route that can be specified for passt is + * the default route, so none of the parameters except gateway + * are acceptable + */ + if (VIR_SOCKET_ADDR_VALID(&route->address) || + virNetDevIPRouteGetPrefix(route) !=3D 0 || + route->has_metric) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _(" elements of an interface using the p= asst backend must be default routes, with only a gateway specified")); + return -1; + } } =20 if (net->type =3D=3D VIR_DOMAIN_NET_TYPE_VDPA) { --=20 2.52.0