From nobody Fri Oct 18 09:19:37 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) client-ip=170.10.133.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1682911235; cv=none; d=zohomail.com; s=zohoarc; b=e1YJ0wctGa3D7ylMtUiCY5RHRtddfD3+1jcvS+d6dQuYbno9dmPhrpo/Eq54FTztuiKM3+Pl8th/nv4/A2FFPojmTY6ZIfpN611j4NkaI7iqpyyvDTbj1LOEqBTgKulwXQXVqUGiOCK+sRVNEN1HglpYwKiFUcQR2huLiCiQ90s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1682911235; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=U2drYcc/BdliiABG1x5nLMbySJ6FXGxxaf3nvHSRbY0=; b=g7B7fYPkDzNsupXJHZ01pNJ8givoJIZ5LUOgHPaYSz7FGxQvnA2QXmZ1pZ+PAztaq3O86rQ4A7Teq+vjHKkLkLjQW+O1nc9VbEzhYVwi6poVclOIU6f9/hRbt5WMkfA1gsca0W3O+syohrXO+1fQlkyWpyQuRhd076E7ntSE84E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.zohomail.com with SMTPS id 1682911235091692.584533148; Sun, 30 Apr 2023 20:20:35 -0700 (PDT) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-470-thmAepWsNpGf4QT2X4BPwQ-1; Sun, 30 Apr 2023 23:20:32 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9187488B7AF; Mon, 1 May 2023 03:20:24 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 67FC4C164EE; Mon, 1 May 2023 03:20:24 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id B61F41940375; Mon, 1 May 2023 03:20:14 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id CD37B1946A42 for ; Mon, 1 May 2023 03:20:05 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id 1B58240F169; Mon, 1 May 2023 03:19:46 +0000 (UTC) Received: from vhost3.router.laine.org (unknown [10.22.8.105]) by smtp.corp.redhat.com (Postfix) with ESMTP id 022AA475072 for ; Mon, 1 May 2023 03:19:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1682911234; h=from:from:sender:sender: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:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=U2drYcc/BdliiABG1x5nLMbySJ6FXGxxaf3nvHSRbY0=; b=DG1ehN0dCcUGEvOYze3m3FChhMF1IQoBtUUv0NZ6jSdDeuDAxzLal6+KIyONEzFPJcT9sF FvthX0MrfGOZmSKikxLrR0p+J6pYyAyMPmpg08r36SF7PCOVkBoUWKDQpw/x5yllftktJX 9VTj6xEWGyQeqQ7XM+D1Fxyn6yMEbik= X-MC-Unique: thmAepWsNpGf4QT2X4BPwQ-1 X-Original-To: libvir-list@listman.corp.redhat.com From: Laine Stump To: libvir-list@redhat.com Subject: [libvirt PATCH 13/28] network: call backend agnostic function to init private filter chains Date: Sun, 30 Apr 2023 23:19:28 -0400 Message-Id: <20230501031943.288145-14-laine@redhat.com> In-Reply-To: <20230501031943.288145-1-laine@redhat.com> References: <20230501031943.288145-1-laine@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1682911236762100001 Content-Type: text/plain; charset="utf-8"; x-default="true" Instead of calling iptableSetupPrivateChains(), the network driver now calls virNetfilterSetupPrivateChains() (which right now always calls the iptables version of the function, but in the future might instead call the nftables version). virNetFilterSetupPrivateChains() needs an argument to know which backend to call, and that means that networkSetupPrivateChains() has to take an argument (we can't rely on getting the setting from the driver config, because the unit tests don't initialize the network driver). But networkSetupPrivateChains() was being called with virOnce(), and virOnce() doesn't support calling functions that require an argument (it's based on pthread_once(), which accepts no arguments, so it's not something we can easily fix in our implementation of virOnce()). So instead this patch changes things to handle the "do it once" functionality by adding a static lock, and putting all of networkSetupPrivateChains() (including the setting of "chainInitDone") inside a lock guard - now the places that used to call it via virOnce(), just call it directly instead. (If it turns out to be significant, we could optimize this by checking for chainInitDone outside the lock guard, returning immediately if it's already set, and then moving the setting of chainInitDone up to the top of the guarded section.) Signed-off-by: Laine Stump --- src/libvirt_private.syms | 1 + src/network/bridge_driver_linux.c | 30 +++++++++++++++--------------- src/util/viriptables.h | 7 ++++--- src/util/virnetfilter.c | 16 ++++++++++++++++ src/util/virnetfilter.h | 3 +++ 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a09e5ae871..a93143638f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2966,6 +2966,7 @@ virNetfilterRemoveTcpInput; virNetfilterRemoveTcpOutput; virNetfilterRemoveUdpInput; virNetfilterRemoveUdpOutput; +virNetfilterSetupPrivateChains; =20 =20 # util/virnetlink.h diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_= linux.c index 3efb669789..058cfa1d80 100644 --- a/src/network/bridge_driver_linux.c +++ b/src/network/bridge_driver_linux.c @@ -35,25 +35,26 @@ VIR_LOG_INIT("network.bridge_driver_linux"); =20 #define PROC_NET_ROUTE "/proc/net/route" =20 -static virOnceControl createdOnce; +static virMutex chainInitLock =3D VIR_MUTEX_INITIALIZER; static bool chainInitDone; /* true iff networkSetupPrivateChains was ever = called */ =20 static virErrorPtr errInitV4; static virErrorPtr errInitV6; =20 -/* Usually only called via virOnce, but can also be called directly in - * response to firewalld reload (if chainInitDone =3D=3D true) - */ -static void networkSetupPrivateChains(void) +static void networkSetupPrivateChains(virFirewallBackend backend, bool for= ce) { + VIR_LOCK_GUARD lock =3D virLockGuardLock(&chainInitLock); int rc; =20 + if (chainInitDone && !force) + return; + VIR_DEBUG("Setting up global firewall chains"); =20 g_clear_pointer(&errInitV4, virFreeError); g_clear_pointer(&errInitV6, virFreeError); =20 - rc =3D iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV4); + rc =3D virNetfilterSetupPrivateChains(backend, VIR_FIREWALL_LAYER_IPV4= ); if (rc < 0) { VIR_DEBUG("Failed to create global IPv4 chains: %s", virGetLastErrorMessage()); @@ -66,7 +67,7 @@ static void networkSetupPrivateChains(void) VIR_DEBUG("Global IPv4 chains already exist"); } =20 - rc =3D iptablesSetupPrivateChains(VIR_FIREWALL_LAYER_IPV6); + rc =3D virNetfilterSetupPrivateChains(backend, VIR_FIREWALL_LAYER_IPV6= ); if (rc < 0) { VIR_DEBUG("Failed to create global IPv6 chains: %s", virGetLastErrorMessage()); @@ -139,6 +140,7 @@ networkPreReloadFirewallRules(virNetworkDriverState *dr= iver, bool startup G_GNUC_UNUSED, bool force) { + g_autoptr(virNetworkDriverConfig) cfg =3D virNetworkDriverGetConfig(dr= iver); /* * If there are any running networks, we need to * create the global rules upfront. This allows us @@ -158,14 +160,13 @@ networkPreReloadFirewallRules(virNetworkDriverState *= driver, */ if (chainInitDone && force) { /* The Private chains have already been initialized once - * during this run of libvirtd, so 1) we can't do it again via - * virOnce(), and 2) we need to re-add the private chains even + * during this run of libvirtd (known because chainInitDone =3D=3D= true) + * so we need to re-add the private chains even * if there are currently no running networks, because the * next time a network is started, libvirt will expect that - * the chains have already been added. So we call directly - * instead of via virOnce(). + * the chains have already been added. So we force the init. */ - networkSetupPrivateChains(); + networkSetupPrivateChains(cfg->firewallBackend, true); =20 } else { if (!networkHasRunningNetworksWithFW(driver)) { @@ -173,7 +174,7 @@ networkPreReloadFirewallRules(virNetworkDriverState *dr= iver, return; } =20 - ignore_value(virOnce(&createdOnce, networkSetupPrivateChains)); + networkSetupPrivateChains(cfg->firewallBackend, false); } } =20 @@ -823,8 +824,7 @@ networkAddFirewallRules(virNetworkDef *def, virNetworkIPDef *ipdef; g_autoptr(virFirewall) fw =3D virFirewallNew(firewallBackend); =20 - if (virOnce(&createdOnce, networkSetupPrivateChains) < 0) - return -1; + networkSetupPrivateChains(firewallBackend, false); =20 if (errInitV4 && (virNetworkDefGetIPByIndex(def, AF_INET, 0) || diff --git a/src/util/viriptables.h b/src/util/viriptables.h index 990cb2e25d..496c6eaf51 100644 --- a/src/util/viriptables.h +++ b/src/util/viriptables.h @@ -37,8 +37,6 @@ virIptablesApplyFirewallRule(virFirewall *firewall, * requires untangling all the special cases for setting up private * chains that are necessitated by firewalld reloads). */ -int iptablesSetupPrivateChains (virFirewallLayer layer); - void iptablesAddOutputFixUdpChecksum (virFirewall *fw, const char *iface, int port); @@ -46,12 +44,15 @@ void iptablesRemoveOutputFixUdpChecksum (vi= rFirewall *fw, const char *iface, int port); =20 -/* These functions are only called from virnetfilter.c. Each can be +/* These functions are only called from virnetfilter.c. Most can be * called with an action of VIR_NETFILTER_INSERT or * VIR_NETFILTER_DELETE, to add or remove the described rule(s) in the * appropriate chain. */ =20 +int +iptablesSetupPrivateChains(virFirewallLayer layer); + void iptablesInput(virFirewall *fw, virFirewallLayer layer, diff --git a/src/util/virnetfilter.c b/src/util/virnetfilter.c index ba0f292ea9..f0fa0d5cd2 100644 --- a/src/util/virnetfilter.c +++ b/src/util/virnetfilter.c @@ -63,6 +63,22 @@ virNetfilterApplyFirewallRule(virFirewall *fw, } =20 =20 +/** + * virNetFilterSetupPrivateChains: + * @layer: VIR_NETFILTER_LAYER_IPV(4|6) + * + * Check if the private tables/chains needed for libvirt virtual + * networks exist in the systems filters, and add them if they're not + * already there. + * + */ +int +virNetfilterSetupPrivateChains(virFirewallBackend backend G_GNUC_UNUSED, + virFirewallLayer layer) +{ + return iptablesSetupPrivateChains(layer); +} + /** * virNetfilterAddTcpInput: * @ctx: pointer to the IP table context diff --git a/src/util/virnetfilter.h b/src/util/virnetfilter.h index eff047cde0..70dede3c3f 100644 --- a/src/util/virnetfilter.h +++ b/src/util/virnetfilter.h @@ -33,6 +33,9 @@ int virNetfilterApplyFirewallRule (virFirewall *fw, virFirewallRule *rule, char **output); + +int virNetfilterSetupPrivateChains (virFirewallBackend backe= nd, + virFirewallLayer layer); void virNetfilterAddTcpInput (virFirewall *fw, virFirewallLayer layer, const char *iface, --=20 2.39.2