From nobody Mon Sep 8 17:04:31 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=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1752660620663213.14314360193168; Wed, 16 Jul 2025 03:10:20 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 9ABCE110B; Wed, 16 Jul 2025 06:10:19 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id D192A12D7; Wed, 16 Jul 2025 06:09:14 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 2A409E67; Wed, 16 Jul 2025 06:09:11 -0400 (EDT) Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) (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 E0602E5C for ; Wed, 16 Jul 2025 06:09:09 -0400 (EDT) Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-ae35f36da9dso1318398966b.0 for ; Wed, 16 Jul 2025 03:09:09 -0700 (PDT) Received: from thinkiepadje.. ([217.21.255.154]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ae6e7ee48f6sm1182029166b.55.2025.07.16.03.09.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Jul 2025 03:09:07 -0700 (PDT) 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_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, 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=gmail.com; s=20230601; t=1752660549; x=1753265349; darn=lists.libvirt.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qDnysVYR3yjk95bq9RuVx8bPLi+yEmnSZidZqzTRChE=; b=fhM+e2MXEQRiW5gA31+5E+ARGNJ+9EmOapOwXS7vG+lSaW4iZRkT39Vma1p76r9unp XLLHr4DyoDtmlplZW64i9wx/7MbVV4bQoRgbE2vH0PdxJwHgPXuudIAKNKzn0USAEUQE QD3/9+R0fywSt4ipOYKnOku6d3NpPzfMdZpvjrm36be06mkSB33HlPCxuIXtov0oR98s /LZwC7tSJHBK1JiV1MSWHb0+RJsoXCrvvo4/vcf0YTZzh4xVjdxw8ELX7epnUuM2bkeI DO3fAa3vOM9/zydYEiWQNvWAPzDiJwOegHU5wk0nZvcH3eqU3Z/mgjf8QiKWS99QzLYg SzHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752660549; x=1753265349; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qDnysVYR3yjk95bq9RuVx8bPLi+yEmnSZidZqzTRChE=; b=iRgoxzIEbfy6TDA/XTpY6Raefm1n1PUA2jCnDKLUz//N1MZjLenb10DHUIWOCitmYq oVQ5dHg8iZ1NYwILxwVOpHId2HIstgv5M6UWSAsLGtIRvsFqleSkZirgrJDPXDS9LsKE hWc71tKA5PW5NWeU9n1zNWrS2gjA3PmlUNxls4d4Ccd9FEoa3jUc95sH2KwUaiMVkJbP fhEKYvE7xNEfM+dIr4dJhUbT90XROfSWaqiJ10/FgcHD2Fg4S4yG0wn9OqCrbui25DYa cLo7llgrZODno89orJWSGnshTZx3ihprDpfo5Y2B9swEryi/tTK50y/VZe3dXER6nE4Z +WJg== X-Gm-Message-State: AOJu0YxmYzn8y/YDKj1rt4EZl0YuCwwpQlgeD3Pb9ePhRIGCFBZ791tx O3SaTLd6nN7+n96DJsb+9BYb//mXxMiOuOmNTSlvwxt/GZ/spIQFt6Sk/8xPQ/FTIg== X-Gm-Gg: ASbGncuz1+rECqkSHyz4jXes9FUWdadLbvNo/IpDnG2BtvDr3hNy5xF5mhOIouQKXAv ofPlwHqvBkUaiLLkWo4ItIQk0tf0sFXl1UIb1WvFx8Bn9Yo5cQaQ8pbsy21TG1q2ja53CDe9m59 pKUp1lrgfigIB9mMDM0nHB31umEtbYSZ2Vsy/8sfvt3yAf+PMtDxLby5nCZ84CVW23SRrwjYfRm VsgwShy54HPxwxAt5wIKkta2GK224Uu2TB6rWeouWsIsZ1y+i3mrsX51oy17kOQXu12sRMBjdeU Ed1BAMMJIdRJ81znEUuCXay/OwgbWYUe0oQOdXbCxYQp0slDl/obeRDcLycMQLXFkh+sarH4y4k 99kua+ex+8oNjVkaorwlXwZ6E5NbR811z X-Google-Smtp-Source: AGHT+IGLYpcys3mDZDjSfqDN7eo4I3NhVb+NzAOzituTJJJ1g+eiGBhqcCSwUek+KIT7QD9Qi7RcSg== X-Received: by 2002:a17:906:ae8a:b0:ade:cdec:7085 with SMTP id a640c23a62f3a-ae9cde3188dmr159865466b.26.1752660547876; Wed, 16 Jul 2025 03:09:07 -0700 (PDT) From: Dion Bosschieter To: devel@lists.libvirt.org Subject: [PATCH v2 1/1] nwfilter: Check before removing and reinserting iptable base chains Date: Wed, 16 Jul 2025 12:08:58 +0200 Message-ID: <20250716100859.177593-2-dionbosschieter@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250716100859.177593-1-dionbosschieter@gmail.com> References: <20250716100859.177593-1-dionbosschieter@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: UCQKPRWYURKYBDOGSWWHGM4B7THRMZND X-Message-ID-Hash: UCQKPRWYURKYBDOGSWWHGM4B7THRMZND X-MailFrom: dionbosschieter@gmail.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: jean-louis@dupond.be, dionbosschieter@gmail.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: 1752660623120116600 Content-Type: text/plain; charset="utf-8" Upon VM bootstrapping (start,restore,incoming migration) iptablesCreateBaseChainsFW is called and unconditionally deletes and reinserts top-level firewall chain jumps (e.g. INPUT, FORWARD rules). This briefly allows packets to continue, allowing packets through until the base chain iptables -I commands run. This commit ensures that the base chains are only created once per layer (IPV4/IPV6) and checks whether the expected rules already exist using `iptables -L`. If they do, no delete/insert operations are performed. By checking for the existence of rules we can prevent more rules from being created if they already exist. Possibly speeding up nwfilter by reducing the amount of iptable commands it executes. This however is not part of this patch. Solves: https://gitlab.com/libvirt/libvirt/-/issues/784 Signed-off-by: Dion Bosschieter --- src/nwfilter/nwfilter_ebiptables_driver.c | 203 +++++++++++++--------- tests/nwfilterxml2firewalltest.c | 58 +++++-- 2 files changed, 163 insertions(+), 98 deletions(-) diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfil= ter_ebiptables_driver.c index 067df6e612..18cb870fba 100644 --- a/src/nwfilter/nwfilter_ebiptables_driver.c +++ b/src/nwfilter/nwfilter_ebiptables_driver.c @@ -131,6 +131,25 @@ static char chainprefixes_host_temp[3] =3D { 0 }; =20 +typedef struct { + const char *chain; + const char *position; + const char *targetChain; +} iptablesBaseChainFW; + +typedef struct { + const char *ifname; + int nrules; + virNWFilterRuleInst **rules; +} chainCreateCallbackData; + +static iptablesBaseChainFW fw_base_chains[] =3D { + {"FORWARD", "1", VIRT_IN_CHAIN}, + {"FORWARD", "2", VIRT_OUT_CHAIN}, + {"FORWARD", "3", VIRT_IN_POST_CHAIN}, + {"INPUT", "1", HOST_IN_CHAIN}, +}; + static int printVar(virNWFilterVarCombIter *vars, char *buf, int bufsize, @@ -398,46 +417,6 @@ ebtablesHandleEthHdr(virFirewall *fw, =20 /************************ iptables support ************************/ =20 - -static void -iptablesCreateBaseChainsFW(virFirewall *fw, - virFirewallLayer layer) -{ - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-N", VIRT_IN_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-N", VIRT_OUT_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-N", VIRT_IN_POST_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-N", HOST_IN_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-D", "FORWARD", "-j", VIRT_IN_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-D", "FORWARD", "-j", VIRT_OUT_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-D", "FORWARD", "-j", VIRT_IN_POST_CHAIN, NULL); - virFirewallAddCmdFull(fw, layer, - true, NULL, NULL, - "-D", "INPUT", "-j", HOST_IN_CHAIN, NULL); - virFirewallAddCmd(fw, layer, - "-I", "FORWARD", "1", "-j", VIRT_IN_CHAIN, NULL); - virFirewallAddCmd(fw, layer, - "-I", "FORWARD", "2", "-j", VIRT_OUT_CHAIN, NULL); - virFirewallAddCmd(fw, layer, - "-I", "FORWARD", "3", "-j", VIRT_IN_POST_CHAIN, NULL= ); - virFirewallAddCmd(fw, layer, - "-I", "INPUT", "1", "-j", HOST_IN_CHAIN, NULL); -} - - static void iptablesCreateTmpRootChainFW(virFirewall *fw, virFirewallLayer layer, @@ -3148,6 +3127,7 @@ iptablesCheckBridgeNFCallEnabled(bool isIPv6) } } =20 + /* * Given a filtername determine the protocol it is used for evaluating * We do prefix-matching to determine the protocol. @@ -3202,6 +3182,104 @@ iptablesRuleInstCommand(virFirewall *fw, } =20 =20 +static int +iptablesHandleCreateChainAndRules(virFirewall *fw, + virFirewallLayer layer, + const char *const *lines, + void *opaque) +{ + size_t i, j; + static bool baseChainDefined[G_N_ELEMENTS(fw_base_chains)] =3D { false= }; + chainCreateCallbackData *cbdata =3D opaque; + bool isIPv6 =3D layer =3D=3D VIR_FIREWALL_LAYER_IPV6; + + iptablesUnlinkTmpRootChainsFW(fw, layer, cbdata->ifname); + iptablesRemoveTmpRootChainsFW(fw, layer, cbdata->ifname); + + // parse iptables -L output to see if base chains exist + for (i =3D 0; lines[i] !=3D NULL; i++) { + if (!STRPREFIX(lines[i], "Chain ")) { + // line doesn't start with Chain + continue; + }; + + VIR_DEBUG("Considering chain for comparison '%s'", lines[i]); + + for (j =3D 0; j < G_N_ELEMENTS(fw_base_chains); j++) { + // if chain matches basechain + if (STRPREFIX(lines[i]+6, fw_base_chains[j].targetChain)) { + VIR_DEBUG("Found chain '%s'", fw_base_chains[j].targetChai= n); + baseChainDefined[j] =3D true; + } + } + } + + // go through parsing results and add basechain commands if necessary + for (i =3D 0; i < G_N_ELEMENTS(fw_base_chains); i++) { + if (!baseChainDefined[i]) { + VIR_DEBUG("Defining base chain '%s'", fw_base_chains[i].target= Chain); + + virFirewallAddCmdFull(fw, layer, + true, NULL, NULL, + "-N", fw_base_chains[i].targetChain, NUL= L); + virFirewallAddCmdFull(fw, layer, + true, NULL, NULL, + "-D", fw_base_chains[i].chain, "-j", + fw_base_chains[i].targetChain, NULL); + virFirewallAddCmd(fw, layer, + "-I", fw_base_chains[i].chain, fw_base_chain= s[i].position, + "-j", fw_base_chains[i].targetChain, NULL); + } + } + + iptablesCreateTmpRootChainsFW(fw, layer, cbdata->ifname); + iptablesLinkTmpRootChainsFW(fw, layer, cbdata->ifname); + iptablesSetupVirtInPostFW(fw, layer, cbdata->ifname); + + for (i =3D 0; i < cbdata->nrules; i++) { + if (isIPv6 =3D=3D false && + virNWFilterRuleIsProtocolIPv4(cbdata->rules[i]->def)) { + if (iptablesRuleInstCommand(fw, cbdata->ifname, cbdata->rules[= i]) < 0) + goto cleanup; + } else if (isIPv6 && virNWFilterRuleIsProtocolIPv6(cbdata->rules[i= ]->def)) { + if (iptablesRuleInstCommand(fw, cbdata->ifname, cbdata->rules[= i]) < 0) + goto cleanup; + } + } + + iptablesCheckBridgeNFCallEnabled(isIPv6); + + cleanup: + + return 0; +} + + +/** + * iptablesCreateChainsAndRules + * + * @fw: the firewall ruleset instance + * @layer: the firewall layer + * @cbdata: callback data struct which holds variables that + * the call back handler needs in order to create + * the base chain jumps and the dependant rules + * the ICMP rule from being created + * + * Run iptables -L and parse if chains already exist + * skips creation of base chain jumps if possible + * see handler in iptablesHandleCreateChainAndRules + */ +static void iptablesCreateChainsAndRules(virFirewall *fw, + virFirewallLayer layer, + chainCreateCallbackData *cbdata) +{ + virFirewallAddCmdFull(fw, layer, + false, iptablesHandleCreateChainAndRules, + (void *)cbdata, + "-L", NULL, NULL); +} + + static int ebtablesRuleInstCommand(virFirewall *fw, const char *ifname, @@ -3311,6 +3389,7 @@ ebiptablesApplyNewRules(const char *ifname, g_autofree ebtablesSubChainInst **subchains =3D NULL; size_t nsubchains =3D 0; int ret =3D -1; + chainCreateCallbackData chainCallbackData =3D {ifname, nrules, rules}; =20 if (nrules) { g_qsort_with_data(rules, nrules, sizeof(rules[0]), @@ -3429,47 +3508,9 @@ ebiptablesApplyNewRules(const char *ifname, } =20 if (haveIptables) { - iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - - iptablesCreateBaseChainsFW(fw, VIR_FIREWALL_LAYER_IPV4); - iptablesCreateTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - - iptablesLinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - iptablesSetupVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV4, ifname); - - for (i =3D 0; i < nrules; i++) { - if (virNWFilterRuleIsProtocolIPv4(rules[i]->def)) { - if (iptablesRuleInstCommand(fw, - ifname, - rules[i]) < 0) - goto cleanup; - } - } - - iptablesCheckBridgeNFCallEnabled(false); - } - - if (haveIp6tables) { - iptablesUnlinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - iptablesRemoveTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - - iptablesCreateBaseChainsFW(fw, VIR_FIREWALL_LAYER_IPV6); - iptablesCreateTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - - iptablesLinkTmpRootChainsFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - iptablesSetupVirtInPostFW(fw, VIR_FIREWALL_LAYER_IPV6, ifname); - - for (i =3D 0; i < nrules; i++) { - if (virNWFilterRuleIsProtocolIPv6(rules[i]->def)) { - if (iptablesRuleInstCommand(fw, - ifname, - rules[i]) < 0) - goto cleanup; - } - } - - iptablesCheckBridgeNFCallEnabled(true); + iptablesCreateChainsAndRules(fw, VIR_FIREWALL_LAYER_IPV4, &chainCa= llbackData); + } if (haveIp6tables) { + iptablesCreateChainsAndRules(fw, VIR_FIREWALL_LAYER_IPV6, &chainCa= llbackData); } =20 if (virHashSize(chains_in_set) !=3D 0) diff --git a/tests/nwfilterxml2firewalltest.c b/tests/nwfilterxml2firewallt= est.c index b78b1b7947..3da28521b0 100644 --- a/tests/nwfilterxml2firewalltest.c +++ b/tests/nwfilterxml2firewalltest.c @@ -67,6 +67,14 @@ static const char *commonRules[] =3D { "ebtables \\\n--concurrent \\\n-t nat \\\n-N libvirt-J-vnet0\n" "ebtables \\\n--concurrent \\\n-t nat \\\n-N libvirt-P-vnet0\n", =20 + /* Querying existence of rules */ + "iptables \\\n-w \\\n-L\n", + "ip6tables \\\n-w \\\n-L\n", + + /* Inserting ebtables rules */ + "ebtables \\\n--concurrent \\\n-t nat \\\n-A PREROUTING \\\n-i vnet0 \= \\n-j libvirt-J-vnet0\n" + "ebtables \\\n--concurrent \\\n-t nat \\\n-A POSTROUTING \\\n-o vnet0 = \\\n-j libvirt-P-vnet0\n", + /* Dropping iptables rules */ "iptables \\\n-w \\\n-D libvirt-out \\\n-m physdev \\\n--physdev-is-br= idged \\\n--physdev-out vnet0 \\\n-g FP-vnet0\n" "iptables \\\n-w \\\n-D libvirt-out \\\n-m physdev \\\n--physdev-out v= net0 \\\n-g FP-vnet0\n" @@ -81,16 +89,16 @@ static const char *commonRules[] =3D { =20 /* Creating iptables chains */ "iptables \\\n-w \\\n-N libvirt-in\n" - "iptables \\\n-w \\\n-N libvirt-out\n" - "iptables \\\n-w \\\n-N libvirt-in-post\n" - "iptables \\\n-w \\\n-N libvirt-host-in\n" "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in\n" - "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-out\n" - "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in-post\n" - "iptables \\\n-w \\\n-D INPUT \\\n-j libvirt-host-in\n" "iptables \\\n-w \\\n-I FORWARD 1 \\\n-j libvirt-in\n" + "iptables \\\n-w \\\n-N libvirt-out\n" + "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-out\n" "iptables \\\n-w \\\n-I FORWARD 2 \\\n-j libvirt-out\n" + "iptables \\\n-w \\\n-N libvirt-in-post\n" + "iptables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in-post\n" "iptables \\\n-w \\\n-I FORWARD 3 \\\n-j libvirt-in-post\n" + "iptables \\\n-w \\\n-N libvirt-host-in\n" + "iptables \\\n-w \\\n-D INPUT \\\n-j libvirt-host-in\n" "iptables \\\n-w \\\n-I INPUT 1 \\\n-j libvirt-host-in\n" "iptables \\\n-w \\\n-N FP-vnet0\n" "iptables \\\n-w \\\n-N FJ-vnet0\n" @@ -115,16 +123,16 @@ static const char *commonRules[] =3D { =20 /* Creating ip6tables chains */ "ip6tables \\\n-w \\\n-N libvirt-in\n" - "ip6tables \\\n-w \\\n-N libvirt-out\n" - "ip6tables \\\n-w \\\n-N libvirt-in-post\n" - "ip6tables \\\n-w \\\n-N libvirt-host-in\n" "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in\n" - "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-out\n" - "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in-post\n" - "ip6tables \\\n-w \\\n-D INPUT \\\n-j libvirt-host-in\n" "ip6tables \\\n-w \\\n-I FORWARD 1 \\\n-j libvirt-in\n" + "ip6tables \\\n-w \\\n-N libvirt-out\n" + "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-out\n" "ip6tables \\\n-w \\\n-I FORWARD 2 \\\n-j libvirt-out\n" + "ip6tables \\\n-w \\\n-N libvirt-in-post\n" + "ip6tables \\\n-w \\\n-D FORWARD \\\n-j libvirt-in-post\n" "ip6tables \\\n-w \\\n-I FORWARD 3 \\\n-j libvirt-in-post\n" + "ip6tables \\\n-w \\\n-N libvirt-host-in\n" + "ip6tables \\\n-w \\\n-D INPUT \\\n-j libvirt-host-in\n" "ip6tables \\\n-w \\\n-I INPUT 1 \\\n-j libvirt-host-in\n" "ip6tables \\\n-w \\\n-N FP-vnet0\n" "ip6tables \\\n-w \\\n-N FJ-vnet0\n" @@ -134,10 +142,6 @@ static const char *commonRules[] =3D { "ip6tables \\\n-w \\\n-A libvirt-host-in \\\n-m physdev \\\n--physdev-= in vnet0 \\\n-g HJ-vnet0\n" "ip6tables \\\n-w \\\n-D libvirt-in-post \\\n-m physdev \\\n--physdev-= in vnet0 \\\n-j ACCEPT\n" "ip6tables \\\n-w \\\n-A libvirt-in-post \\\n-m physdev \\\n--physdev-= in vnet0 \\\n-j ACCEPT\n", - - /* Inserting ebtables rules */ - "ebtables \\\n--concurrent \\\n-t nat \\\n-A PREROUTING \\\n-i vnet0 \= \\n-j libvirt-J-vnet0\n" - "ebtables \\\n--concurrent \\\n-t nat \\\n-A POSTROUTING \\\n-o vnet0 = \\\n-j libvirt-P-vnet0\n", }; =20 =20 @@ -342,6 +346,26 @@ static int testSetDefaultParameters(GHashTable *vars) return 0; } =20 +static void +testCommandDryRunCallback(const char *const*args, + const char *const*env G_GNUC_UNUSED, + const char *input G_GNUC_UNUSED, + char **output, + char **error G_GNUC_UNUSED, + int *status, + void *opaque G_GNUC_UNUSED) +{ + if (!STREQ(args[0], "iptables") && !STREQ(args[0], "ip6tables")) { + return; + } + + // simulate an empty existing set rules + if (STREQ(args[1], "-w") && STREQ(args[2], "-L")) { + *output =3D g_strdup("Chain nothing\n"); + *status =3D EXIT_SUCCESS; + } +} + static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline) { @@ -352,7 +376,7 @@ static int testCompareXMLToArgvFiles(const char *xml, int ret =3D -1; g_autoptr(virCommandDryRunToken) dryRunToken =3D virCommandDryRunToken= New(); =20 - virCommandSetDryRun(dryRunToken, &buf, true, true, NULL, NULL); + virCommandSetDryRun(dryRunToken, &buf, true, true, testCommandDryRunCa= llback, NULL); =20 if (testSetDefaultParameters(vars) < 0) goto cleanup; --=20 2.43.0