From nobody Fri May 10 06:17:19 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; spf=pass (zohomail.com: domain of redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=quarantine dis=quarantine) header.from=virtuozzo.com 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 1646210133061917.5945238663835; Wed, 2 Mar 2022 00:35:33 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-168-Yn6ldcRMMsKOMRxzNmesVQ-1; Wed, 02 Mar 2022 03:35:28 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id B97D61006AA5; Wed, 2 Mar 2022 08:35:23 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3ECB97FCEF; Wed, 2 Mar 2022 08:35:23 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 9506F1809C98; Wed, 2 Mar 2022 08:35:22 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 2228ZK93015361 for ; Wed, 2 Mar 2022 03:35:21 -0500 Received: by smtp.corp.redhat.com (Postfix) id 2B0E51457F05; Wed, 2 Mar 2022 08:35:20 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast04.extmail.prod.ext.rdu2.redhat.com [10.11.55.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 263E01457F04 for ; Wed, 2 Mar 2022 08:35:20 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0D1C8101AA45 for ; Wed, 2 Mar 2022 08:35:20 +0000 (UTC) Received: from relay.sw.ru (130.117.225.111 [130.117.225.111]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-669-d3oQLZO_OgqkYOzIHsOv4w-1; Wed, 02 Mar 2022 03:35:17 -0500 Received: from vz-out.virtuozzo.com ([185.231.240.5] helo=vzdev-s01.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.94.2) (envelope-from ) id 1nPKRc-0009Yz-Hy for libvir-list@redhat.com; Wed, 02 Mar 2022 09:35:07 +0100 X-MC-Unique: Yn6ldcRMMsKOMRxzNmesVQ-1 X-MC-Unique: d3oQLZO_OgqkYOzIHsOv4w-1 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Subject: [RFC patch 1/2] utils: make virFirewallAddRuleFullV public Date: Wed, 2 Mar 2022 11:34:55 +0300 Message-Id: <20220302083456.100451-2-nshirokovskiy@virtuozzo.com> In-Reply-To: <20220302083456.100451-1-nshirokovskiy@virtuozzo.com> References: <20220302083456.100451-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1646210135261100001 Content-Type: text/plain; charset="utf-8" --- src/libvirt_private.syms | 1 + src/util/virfirewall.c | 2 +- src/util/virfirewall.h | 7 +++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6f0d72ca38..c2f43e95ab 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2316,6 +2316,7 @@ virFileCacheSetPriv; =20 # util/virfirewall.h virFirewallAddRuleFull; +virFirewallAddRuleFullV; virFirewallApply; virFirewallFree; virFirewallNew; diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 31a8352d4e..5efa6ffd45 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -186,7 +186,7 @@ void virFirewallFree(virFirewall *firewall) rule->args[rule->argsLen++] =3D g_strdup(str); \ } while (0) =20 -static virFirewallRule * +virFirewallRule * virFirewallAddRuleFullV(virFirewall *firewall, virFirewallLayer layer, bool ignoreErrors, diff --git a/src/util/virfirewall.h b/src/util/virfirewall.h index 7448825dbc..467cc3fb17 100644 --- a/src/util/virfirewall.h +++ b/src/util/virfirewall.h @@ -64,6 +64,13 @@ virFirewallRule *virFirewallAddRuleFull(virFirewall *fir= ewall, ...) G_GNUC_NULL_TERMINATED; =20 +virFirewallRule *virFirewallAddRuleFullV(virFirewall *firewall, + virFirewallLayer layer, + bool ignoreErrors, + virFirewallQueryCallback cb, + void *opaque, + va_list args); + void virFirewallRemoveRule(virFirewall *firewall, virFirewallRule *rule); =20 --=20 2.31.1 From nobody Fri May 10 06:17:19 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=fail(p=quarantine dis=quarantine) header.from=virtuozzo.com Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1646210141459614.2111190306814; Wed, 2 Mar 2022 00:35:41 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-627-Ii9dlakQMticSRlDTSZSsA-1; Wed, 02 Mar 2022 03:35:36 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DA3B11854E2B; Wed, 2 Mar 2022 08:35:29 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id AF9361038ABC; Wed, 2 Mar 2022 08:35:29 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 7C0CB46F98; Wed, 2 Mar 2022 08:35:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 2228ZQER015390 for ; Wed, 2 Mar 2022 03:35:26 -0500 Received: by smtp.corp.redhat.com (Postfix) id 53211407DECA; Wed, 2 Mar 2022 08:35:26 +0000 (UTC) Received: from mimecast-mx02.redhat.com (mimecast08.extmail.prod.ext.rdu2.redhat.com [10.11.55.24]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4EC1E407DEC3 for ; Wed, 2 Mar 2022 08:35:25 +0000 (UTC) Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 463D73802ACA for ; Wed, 2 Mar 2022 08:35:25 +0000 (UTC) Received: from relay.sw.ru (130.117.225.111 [130.117.225.111]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-116-LoHqEoP9MtaGOkAwLsW94g-1; Wed, 02 Mar 2022 03:35:19 -0500 Received: from vz-out.virtuozzo.com ([185.231.240.5] helo=vzdev-s01.qa.sw.ru) by relay.sw.ru with esmtp (Exim 4.94.2) (envelope-from ) id 1nPKRc-0009Yz-P2 for libvir-list@redhat.com; Wed, 02 Mar 2022 09:35:07 +0100 X-MC-Unique: Ii9dlakQMticSRlDTSZSsA-1 X-MC-Unique: LoHqEoP9MtaGOkAwLsW94g-1 From: Nikolay Shirokovskiy To: libvir-list@redhat.com Subject: [RFC patch 2/2] nwfilter: don't query netfilter inside transactions Date: Wed, 2 Mar 2022 11:34:56 +0300 Message-Id: <20220302083456.100451-3-nshirokovskiy@virtuozzo.com> In-Reply-To: <20220302083456.100451-1-nshirokovskiy@virtuozzo.com> References: <20220302083456.100451-1-nshirokovskiy@virtuozzo.com> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition; Similar Internal Domain=false; Similar Monitored External Domain=false; Custom External Domain=false; Mimecast External Domain=false; Newly Observed Domain=false; Internal User Name=false; Custom Display Name List=false; Reply-to Address Mismatch=false; Targeted Threat Dictionary=false; Mimecast Threat Dictionary=false; Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1646210143719100003 Content-Type: text/plain; charset="utf-8" In order to delete or rename tree of chains in netfilter we use generic code that inspect current state of netfilter and traverse the tree accordingly. I found the way traverse is done a bit hard to think about. As an example I'll take ebtable rules generated by ebiptablesTearOldRules for input chains only. Common arguments like '-t nat' and '--concurrent' are also filtered. To illustrate the point libvirt-I-vnet1 has one subchain I-vnet1-mac. Let's look at ebtablesRemoveSubChainsFW[1] work. It make a recursive deletion of chains. I marked below the ebtables calls that it generates in the whole list of commands that generates ebiptablesTearOldRules. One can see that the rules perplex with the ebtablesRenameTmpSubAndRootChainsFW= [2] rules and this looks a bit hard to manage. I'd prefer that the order of ebtables commands will be aligned with code. ebtables -D PREROUTING -i vnet1 -j libvirt-I-vnet1 ebtables -L libvirt-I-vnet1 # listing to detect subchains[1] ebtables -F libvirt-I-vnet1 ebtables -X libvirt-I-vnet1 ebtables -L libvirt-J-vnet1 # [2] ebtables -E libvirt-J-vnet1 libvirt-I-vnet1 # [2] ebtables -L I-vnet1-mac # listing to detect subchains[1] ebtables -F I-vnet1-mac # flushing to unlink subchains[1] ebtables -X I-vnet1-mac # deleting chain itself[1] ebtables -L J-vnet1-mac # [2] ebtables -F I-vnet1-mac # [2] ebtables -X I-vnet1-mac # [2] ebtables -E J-vnet1-mac I-vnet1-mac # [2] Notice also that we need to flush libvirt-I-vnet1 to unlink subchains in order to be able to delete them. And again code look like reversed: ebtablesRemoveSubChainsFW(fw, ifname); ebtablesRemoveRootChainFW(fw, true, ifname); ebtablesRemoveRootChainFW(fw, false, ifname); This is because ebtablesRemoveSubChainsFW only adds listing call and makes actual subchains cleanup in the the process of virFirewallApply. So to make it more manageble/straightforward I propose here to list and add resulted commands inplace. Note that in the process we need: 1. Move ebtablesRemoveTmpRootChainFW rules to the _ebtablesRemoveSubChainsFW to keep correct order - first flush parent and then delete subchains. 2. Avoid using virFirewallStartRollback as otherwise there will be unnesseary listing call done in ebtablesRemoveTmpSubChainsFW. The fact we can't use virFirewallStartRollback in this approach can be seen as a donwside. However it is not a real rollback - you need to code all the steps to rollback on you own so it can be easily replaced by same virFirewallApply. Not only in this place but in all the other places. Now compare the commands order in ebiptablesTearOldRules after patch: ebtables -L libvirt-I-vnet1 # listing to detect subchains [1] ebtables -L I-vnet1-mac # listing to detect subchains [1] ebtables -D PREROUTING -i vnet1 -j libvirt-I-vnet1 ebtables -F libvirt-I-vnet1 # flushing and deleting of chain [1] ebtables -X libvirt-I-vnet1 ebtables -F I-vnet1-mac # flushing and deleting of subchain [1] ebtables -X I-vnet1-mac ebtables -L libvirt-J-vnet1 ebtables -E libvirt-J-vnet1 libvirt-I-vnet1 ebtables -L J-vnet1-mac ebtables -F I-vnet1-mac ebtables -X I-vnet1-mac ebtables -E J-vnet1-mac I-vnet1-mac Notice that listing commands from ebtablesRemoveSubChainsFW pop up to the top of the list. This may seen again as perplexing but it is of a different kind. It only moves nonmodifying listing commands to the top which does not perplexing understanding command flow much. Also if the calls will be optimized we have only one listing command on the top. --- src/nwfilter/nwfilter_ebiptables_driver.c | 154 +++++++++++----------- 1 file changed, 75 insertions(+), 79 deletions(-) diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfil= ter_ebiptables_driver.c index 54065a0f75..6952ebc059 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -148,6 +148,42 @@ static char chainprefixes_host_temp[3] =3D { 0 }; =20 + +static int +ebiptablesQueryCallback(virFirewall *fw G_GNUC_UNUSED, + virFirewallLayer layer G_GNUC_UNUSED, + const char *const *lines, + void *opaque) +{ + GStrv *capture =3D opaque; + + *capture =3D g_strdupv((gchar **)lines); + return 0; +} + + +static GStrv +ebiptablesQuery(virFirewallLayer layer, + ...) +{ + g_autoptr(virFirewall) fw =3D virFirewallNew(); + g_auto(GStrv) capture =3D NULL; + va_list args; + + virFirewallStartTransaction(fw, 0); + + va_start(args, layer); + virFirewallAddRuleFullV(fw, layer, true, + ebiptablesQueryCallback, &capture, args); + va_end(args); + + if (virFirewallApply(fw) < 0) + return NULL; + + return g_steal_pointer(&capture); +} + + static int printVar(virNWFilterVarCombIter *vars, char *buf, int bufsize, @@ -2514,47 +2550,6 @@ ebtablesLinkTmpRootChainFW(virFirewall *fw, } =20 =20 -static void -_ebtablesRemoveRootChainFW(virFirewall *fw, - bool incoming, const char *ifname, - int isTempChain) -{ - char chain[MAX_CHAINNAME_LENGTH]; - char chainPrefix; - if (isTempChain) - chainPrefix =3D incoming ? CHAINPREFIX_HOST_IN_TEMP - : CHAINPREFIX_HOST_OUT_TEMP; - else - chainPrefix =3D incoming ? CHAINPREFIX_HOST_IN - : CHAINPREFIX_HOST_OUT; - - PRINT_ROOT_CHAIN(chain, chainPrefix, ifname); - - virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET, - true, NULL, NULL, - "-t", "nat", "-F", chain, NULL); - virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET, - true, NULL, NULL, - "-t", "nat", "-X", chain, NULL); -} - - -static void -ebtablesRemoveRootChainFW(virFirewall *fw, - bool incoming, const char *ifname) -{ - _ebtablesRemoveRootChainFW(fw, incoming, ifname, false); -} - - -static void -ebtablesRemoveTmpRootChainFW(virFirewall *fw, - bool incoming, const char *ifname) -{ - _ebtablesRemoveRootChainFW(fw, incoming, ifname, 1); -} - - static void _ebtablesUnlinkRootChainFW(virFirewall *fw, bool incoming, const char *ifname, @@ -2649,10 +2644,9 @@ static int ebtablesRemoveSubChainsQuery(virFirewall *fw, virFirewallLayer layer, const char *const *lines, - void *opaque) + const char *chainprefixes) { size_t i, j; - const char *chainprefixes =3D opaque; =20 for (i =3D 0; lines[i] !=3D NULL; i++) { char *tmp =3D strstr(lines[i], "-j "); @@ -2665,17 +2659,21 @@ ebtablesRemoveSubChainsQuery(virFirewall *fw, for (j =3D 0; chainprefixes[j]; j++) { if (tmp[0] =3D=3D chainprefixes[j] && tmp[1] =3D=3D '-') { + g_auto(GStrv) capture =3D NULL; + VIR_DEBUG("Processing chain '%s'", tmp); - virFirewallAddRuleFull(fw, layer, - false, ebtablesRemoveSubChainsQuery, - (void *)chainprefixes, - "-t", "nat", "-L", tmp, NULL); + capture =3D ebiptablesQuery(layer, + "-t", "nat", "-L", tmp, NULL); virFirewallAddRuleFull(fw, layer, true, NULL, NULL, "-t", "nat", "-F", tmp, NULL); virFirewallAddRuleFull(fw, layer, true, NULL, NULL, "-t", "nat", "-X", tmp, NULL); + if (capture) + ebtablesRemoveSubChainsQuery(fw, layer, + (const char *const *)capt= ure, + chainprefixes); } } } @@ -2693,11 +2691,21 @@ _ebtablesRemoveSubChainsFW(virFirewall *fw, size_t i; =20 for (i =3D 0; chainprefixes[i] !=3D 0; i++) { + g_auto(GStrv) capture =3D NULL; PRINT_ROOT_CHAIN(rootchain, chainprefixes[i], ifname); + + capture =3D ebiptablesQuery(VIR_FIREWALL_LAYER_ETHERNET, + "-t", "nat", "-L", rootchain, NULL); virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET, - false, ebtablesRemoveSubChainsQuery, - (void *)chainprefixes, - "-t", "nat", "-L", rootchain, NULL); + true, NULL, NULL, + "-t", "nat", "-F", rootchain, NULL); + virFirewallAddRuleFull(fw, VIR_FIREWALL_LAYER_ETHERNET, + true, NULL, NULL, + "-t", "nat", "-X", rootchain, NULL); + if (capture) + ebtablesRemoveSubChainsQuery(fw, VIR_FIREWALL_LAYER_ETHERNET, + (const char *const *)capture, + chainprefixes); } } =20 @@ -3079,14 +3087,10 @@ ebtablesCleanAll(const char *ifname) ebtablesUnlinkRootChainFW(fw, true, ifname); ebtablesUnlinkRootChainFW(fw, false, ifname); ebtablesRemoveSubChainsFW(fw, ifname); - ebtablesRemoveRootChainFW(fw, true, ifname); - ebtablesRemoveRootChainFW(fw, false, ifname); =20 ebtablesUnlinkTmpRootChainFW(fw, true, ifname); ebtablesUnlinkTmpRootChainFW(fw, false, ifname); ebtablesRemoveTmpSubChainsFW(fw, ifname); - ebtablesRemoveTmpRootChainFW(fw, true, ifname); - ebtablesRemoveTmpRootChainFW(fw, false, ifname); =20 return virFirewallApply(fw); } @@ -3346,8 +3350,6 @@ ebiptablesApplyNewRules(const char *ifname, ebtablesUnlinkTmpRootChainFW(fw, true, ifname); ebtablesUnlinkTmpRootChainFW(fw, false, ifname); ebtablesRemoveTmpSubChainsFW(fw, ifname); - ebtablesRemoveTmpRootChainFW(fw, true, ifname); - ebtablesRemoveTmpRootChainFW(fw, false, ifname); =20 virFirewallStartTransaction(fw, 0); =20 @@ -3499,25 +3501,27 @@ ebiptablesApplyNewRules(const char *ifname, if (virHashSize(chains_out_set) !=3D 0) ebtablesLinkTmpRootChainFW(fw, false, ifname); =20 - virFirewallStartRollback(fw, 0); - ebtablesUnlinkTmpRootChainFW(fw, true, ifname); - ebtablesUnlinkTmpRootChainFW(fw, false, ifname); - if (haveIp6tables) { - iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - } + if (virFirewallApply(fw) < 0) { + g_autoptr(virFirewall) rollback =3D virFirewallNew(); =20 - if (haveIptables) { - iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - } + virFirewallStartTransaction(rollback, VIR_FIREWALL_TRANSACTION_IGN= ORE_ERRORS); =20 - ebtablesRemoveTmpSubChainsFW(fw, ifname); - ebtablesRemoveTmpRootChainFW(fw, true, ifname); - ebtablesRemoveTmpRootChainFW(fw, false, ifname); + if (haveIp6tables) { + iptablesUnlinkTmpRootChainsFW(rollback, VIR_FIREWALL_LAYER_IPV= 6, ifname); + iptablesRemoveTmpRootChainsFW(rollback, VIR_FIREWALL_LAYER_IPV= 6, ifname); + } + + if (haveIptables) { + iptablesUnlinkTmpRootChainsFW(rollback, VIR_FIREWALL_LAYER_IPV= 4, ifname); + iptablesRemoveTmpRootChainsFW(rollback, VIR_FIREWALL_LAYER_IPV= 4, ifname); + } + + ebtablesUnlinkTmpRootChainFW(rollback, true, ifname); + ebtablesUnlinkTmpRootChainFW(rollback, false, ifname); + ebtablesRemoveTmpSubChainsFW(rollback, ifname); =20 - if (virFirewallApply(fw) < 0) goto cleanup; + } =20 ret =3D 0; =20 @@ -3541,8 +3545,6 @@ ebiptablesTearNewRulesFW(virFirewall *fw, const char = *ifname) ebtablesUnlinkTmpRootChainFW(fw, true, ifname); ebtablesUnlinkTmpRootChainFW(fw, false, ifname); ebtablesRemoveTmpSubChainsFW(fw, ifname); - ebtablesRemoveTmpRootChainFW(fw, true, ifname); - ebtablesRemoveTmpRootChainFW(fw, false, ifname); } =20 =20 @@ -3576,8 +3578,6 @@ ebiptablesTearOldRules(const char *ifname) ebtablesUnlinkRootChainFW(fw, true, ifname); ebtablesUnlinkRootChainFW(fw, false, ifname); ebtablesRemoveSubChainsFW(fw, ifname); - ebtablesRemoveRootChainFW(fw, true, ifname); - ebtablesRemoveRootChainFW(fw, false, ifname); ebtablesRenameTmpSubAndRootChainsFW(fw, ifname); =20 return virFirewallApply(fw); @@ -3612,12 +3612,8 @@ ebiptablesAllTeardown(const char *ifname) =20 ebtablesUnlinkRootChainFW(fw, true, ifname); ebtablesUnlinkRootChainFW(fw, false, ifname); - ebtablesRemoveSubChainsFW(fw, ifname); =20 - ebtablesRemoveRootChainFW(fw, true, ifname); - ebtablesRemoveRootChainFW(fw, false, ifname); - return virFirewallApply(fw); } =20 --=20 2.31.1