[PATCH] nwfilter: Use numeric output when listing iptables chains

Dimas Moreira Junior posted 1 patch 5 days, 2 hours ago
src/nwfilter/nwfilter_ebiptables_driver.c | 2 +-
tests/nwfilterxml2ebipfirewalltest.c      | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
[PATCH] nwfilter: Use numeric output when listing iptables chains
Posted by Dimas Moreira Junior 5 days, 2 hours ago
iptablesCreateChainsAndRules() runs "iptables -L" and "ip6tables -L"
to find out which base chains already exist. Without -n, iptables
reverse-resolves every address in every rule it lists. The callback
only looks at lines starting with "Chain ", so the resolved names are
never used, but the lookups run anyway and their cost grows with the
number of rules. Where reverse lookups are slow this delays filter
setup in proportion to the rule count. On a Fedora 44 host with
libvirt 12.0.0, a guest whose filter rules contained about 70
addresses took longer than 30 seconds to start. With numeric listing,
creation took under a second.

Pass -n so iptables skips the lookups. The "Chain" header lines the
callback parses are the same in numeric mode.

The "ebtables -t nat -L" listings are left alone: ebtables does not
accept -n and rejects it as an unknown option.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/944
Signed-off-by: Dimas Moreira Junior <dimasmjunior@gmail.com>
---
 src/nwfilter/nwfilter_ebiptables_driver.c | 2 +-
 tests/nwfilterxml2ebipfirewalltest.c      | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/nwfilter/nwfilter_ebiptables_driver.c b/src/nwfilter/nwfilter_ebiptables_driver.c
index 6b6b3cbd69..fbc131ea9d 100644
--- a/src/nwfilter/nwfilter_ebiptables_driver.c
+++ b/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -3015,7 +3015,7 @@ static void iptablesCreateChainsAndRules(virFirewall *fw,
     virFirewallAddCmdFull(fw, layer,
                           false, iptablesHandleCreateChainAndRules,
                           (void *)cbdata,
-                          "-L", NULL, NULL);
+                          "-n", "-L", NULL, NULL);
 }
 
 
diff --git a/tests/nwfilterxml2ebipfirewalltest.c b/tests/nwfilterxml2ebipfirewalltest.c
index b5a89f4fb1..931b987477 100644
--- a/tests/nwfilterxml2ebipfirewalltest.c
+++ b/tests/nwfilterxml2ebipfirewalltest.c
@@ -68,8 +68,8 @@ static const char *commonRules[] = {
     "ebtables \\\n--concurrent \\\n-t nat \\\n-N libvirt-P-vnet0\n",
 
     /* Querying existence of rules */
-    "iptables \\\n-w \\\n-L\n",
-    "ip6tables \\\n-w \\\n-L\n",
+    "iptables \\\n-w \\\n-n \\\n-L\n",
+    "ip6tables \\\n-w \\\n-n \\\n-L\n",
 
     /* Inserting ebtables rules */
     "ebtables \\\n--concurrent \\\n-t nat \\\n-A PREROUTING \\\n-i vnet0 \\\n-j libvirt-J-vnet0\n"
@@ -360,7 +360,7 @@ testCommandDryRunCallback(const char *const*args,
     }
 
     /* simulate an empty existing set rules */
-    if (STREQ(args[1], "-w") && STREQ(args[2], "-L")) {
+    if (STREQ(args[1], "-w") && STREQ(args[2], "-n") && STREQ(args[3], "-L")) {
         *output = g_strdup("Chain nothing\n");
         *status = EXIT_SUCCESS;
     }
-- 
2.56.0