From nobody Mon Feb 9 21:02:59 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=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1732591599556776.1582835262561; Mon, 25 Nov 2024 19:26:39 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 996) id D41F71B5F; Mon, 25 Nov 2024 22:26:38 -0500 (EST) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 96A1219D6; Mon, 25 Nov 2024 22:25:03 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 996) id 6BC1217E7; Mon, 25 Nov 2024 22:24:57 -0500 (EST) 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 C565117E1 for ; Mon, 25 Nov 2024 22:24:56 -0500 (EST) Received: from mx-prod-mc-04.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-396-6TreGjNbNPewswF5otD14g-1; Mon, 25 Nov 2024 22:24:55 -0500 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (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-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 43B9219560BE for ; Tue, 26 Nov 2024 03:24:54 +0000 (UTC) Received: from vhost3.router.laine.org (unknown [10.22.88.88]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 233BB195DF81; Tue, 26 Nov 2024 03:24:52 +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, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3,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=1732591496; 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: in-reply-to:in-reply-to:references:references; bh=zgI36OhW/sEpc65/ffsq8ZK0hIASTbxeeLtMHn9BKDA=; b=FNDyqYOFmt/IuMHdupOrcozZlxP3mJVLh7JWviuj3Vc5s3RosR7Uz31cdJhf6yrnscT1a/ YATrjz0iJ8vqrvfGRbjqfWbmYaf1Ncy9vEhEYyIUidlvPSY48lZsj4JZ73YJgJgEbgiv7U RzA1jEihG0c7pFOL3yrrxkn+Dpvuj6E= X-MC-Unique: 6TreGjNbNPewswF5otD14g-1 X-Mimecast-MFC-AGG-ID: 6TreGjNbNPewswF5otD14g From: Laine Stump To: devel@lists.libvirt.org Subject: [PATCH v2 2/6] util: make it optional to clear existing tc qdiscs/filters in virNetDevBandwidthSet() Date: Mon, 25 Nov 2024 22:24:45 -0500 Message-ID: <20241126032449.912167-3-laine@redhat.com> In-Reply-To: <20241126032449.912167-1-laine@redhat.com> References: <20241126032449.912167-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: sWSCFWlqReN8PMP9aOcdSaf3xOdb6dR2Ip1gE-kar2k_1732591494 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: YTG2CBAWLQAZIXWJ4CC4BMCVUP2IUWG3 X-Message-ID-Hash: YTG2CBAWLQAZIXWJ4CC4BMCVUP2IUWG3 X-MailFrom: laine@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: egarver@redhat.com, mprivozn@redhat.com, psutter@redhat.com, abologna@redhat.com 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: X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1732591604912019100 Content-Type: text/plain; charset="utf-8"; x-default="true" virNetDevBandwidthSet() always clears all existing qdiscs and their subordinate filters before adding all the new qdiscs/filters. This is normally exactly what we want, but there is one case (the network driver) where the Qdisc added by virNetDevBandwidthSet() may already be in use by the nftables backend (which will add a rule to fix the checksum of dhcp packets); in that case, we *don't* want virNetDevBandwidthSet() to clear out the qdisc that was already added for nftables, and none of the bandwidth filters have been added yet, so there already aren't any "old" filters that need to be removed either - it is safe to just skip virNetDevBandwidthClear() in this case. To allow the network driver to set bandwidth without first clearing it, this patch adds the flag VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL to the virNetDevBandwidthSetFlags enum, and recognizes it in virNetDevBandwidthSet() - if the flag is set, then virNetDevBandwidth() will call virNetDevBandwidthClear() just as it always has. But if the flag isn't set it *won't* call virNetDevBandwidthClear(). As suggested above, VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL is set for all calls to virNetdevBandwidthSet() except for two places in the network driver. Signed-off-by: Laine Stump --- src/lxc/lxc_driver.c | 2 +- src/lxc/lxc_process.c | 2 +- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_driver.c | 2 +- src/qemu/qemu_hotplug.c | 4 ++-- src/util/virnetdevbandwidth.c | 21 ++++++++++++++++++++- src/util/virnetdevbandwidth.h | 1 + tests/virnetdevbandwidthtest.c | 3 ++- 8 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index a64cfef1a0..d682e7168a 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3570,7 +3570,7 @@ lxcDomainAttachDeviceNetLive(virLXCDriver *driver, actualBandwidth =3D virDomainNetGetActualBandwidth(net); if (actualBandwidth) { if (virNetDevSupportsBandwidth(actualType)) { - unsigned int flags =3D 0; + unsigned int flags =3D VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL; =20 if (!virDomainNetTypeSharesHostView(net)) flags |=3D VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 7eba7a2c46..cd8bcfc282 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -609,7 +609,7 @@ virLXCProcessSetupInterfaces(virLXCDriver *driver, actualBandwidth =3D virDomainNetGetActualBandwidth(net); if (actualBandwidth) { if (virNetDevSupportsBandwidth(type)) { - unsigned int flags =3D 0; + unsigned int flags =3D VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL; =20 if (!virDomainNetTypeSharesHostView(net)) flags |=3D VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3d0a5dd460..47fe0a819c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -8695,7 +8695,7 @@ qemuBuildInterfaceCommandLine(virQEMUDriver *driver, !virDomainNetTypeS= haresHostView(net)) < 0) goto cleanup; } else { - unsigned int flags =3D 0; + unsigned int flags =3D VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL; =20 if (!virDomainNetTypeSharesHostView(net)) flags |=3D VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 425d583e99..d1b32de56a 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -9939,7 +9939,7 @@ qemuDomainSetInterfaceParameters(virDomainPtr dom, goto endjob; } } else { - unsigned int bwflags =3D 0; + unsigned int bwflags =3D VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL; =20 if (!virDomainNetTypeSharesHostView(net)) bwflags |=3D VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index b06ae61a44..3c18af6b0c 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1332,7 +1332,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, !virDomainNetTypeS= haresHostView(net)) < 0) goto cleanup; } else { - int flags =3D 0; + int flags =3D VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL; =20 if (!virDomainNetTypeSharesHostView(net)) flags |=3D VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; @@ -4187,7 +4187,7 @@ qemuDomainChangeNet(virQEMUDriver *driver, !virDomainNetTypeS= haresHostView(newdev)) < 0) goto cleanup; } else { - int flags =3D 0; + int flags =3D VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL; =20 if (!virDomainNetTypeSharesHostView(newdev)) flags |=3D VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED; diff --git a/src/util/virnetdevbandwidth.c b/src/util/virnetdevbandwidth.c index 1baad849c6..9c48844c5d 100644 --- a/src/util/virnetdevbandwidth.c +++ b/src/util/virnetdevbandwidth.c @@ -196,6 +196,21 @@ virNetDevBandwidthManipulateFilter(const char *ifname, * interface (so domain's RX/TX is host's RX/TX), and for some * it's swapped (domain's RX/TX is hosts's TX/RX). * + * VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL + * If VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL is set, then the root + * qdisc is deleted before adding any new qdisc/class/filter, + * which causes any pre-existing filters to also be deleted. If + * not set, then it's assumed that there are no existing rules (or + * that those already there need to be kept). The caller should + * set this flag for an existing interface that is having its + * bandwidth settings modified, but can leave it unset if the + * interface was newly created and this is the first time + * bandwidth has been set, but someone else might have already + * added the qdisc (e.g. this is the case when the network driver + * is setting bandwidth for a virtual network bridge device - the + * nftables backend may have already added qdisc handle 1:0 and a + * filter, and we don't want to delete them) + * * Return 0 on success, -1 otherwise. */ int @@ -238,7 +253,11 @@ virNetDevBandwidthSet(const char *ifname, tx =3D bandwidth->out; } =20 - virNetDevBandwidthClear(ifname); + /* Only if the caller requests, clear everything including root + * qdisc and all filters before adding everything. + */ + if (flags & VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL) + virNetDevBandwidthClear(ifname); =20 if (tx && tx->average) { average =3D g_strdup_printf("%llukbps", tx->average); diff --git a/src/util/virnetdevbandwidth.h b/src/util/virnetdevbandwidth.h index 414d6c97eb..69c204389c 100644 --- a/src/util/virnetdevbandwidth.h +++ b/src/util/virnetdevbandwidth.h @@ -42,6 +42,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetDevBandwidth, virNetD= evBandwidthFree); typedef enum { VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS =3D (1 << 0), VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED =3D (1 << 1), + VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL =3D (1 << 2), } virNetDevBandwidthSetFlags; =20 int virNetDevBandwidthSet(const char *ifname, diff --git a/tests/virnetdevbandwidthtest.c b/tests/virnetdevbandwidthtest.c index 3a87d876c8..c34fbd5073 100644 --- a/tests/virnetdevbandwidthtest.c +++ b/tests/virnetdevbandwidthtest.c @@ -82,7 +82,8 @@ testVirNetDevBandwidthSet(const void *data) if (virNetDevOpenvswitchInterfaceSetQos(iface, band, info->uuid, t= rue) < 0) return -1; } else { - int flags =3D (VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED); + int flags =3D (VIR_NETDEV_BANDWIDTH_SET_DIR_SWAPPED + | VIR_NETDEV_BANDWIDTH_SET_CLEAR_ALL); =20 if (info->hierarchical_class) flags |=3D VIR_NETDEV_BANDWIDTH_SET_HIERARCHICAL_CLASS; --=20 2.47.0