Compare commits

...

1 Commits
c8 ... a8

2 changed files with 93 additions and 1 deletions

View File

@ -0,0 +1,85 @@
From ad48eb571ff4966c3ebfbbf12fe8adf293658e20 Mon Sep 17 00:00:00 2001
From: Andrew Lukoshko <alukoshko@almalinux.org>
Date: Tue, 10 Mar 2026 13:30:54 +0100
Subject: fix(nftables): batch ipset elements in set_restore to avoid O(n^2)
insertion cost
set_restore() currently creates one "add element" nft operation per
ipset entry, then sends them in chunks of 1000 operations. On older
nftables/kernel combinations (e.g. nftables 1.0.4 / kernel 4.18
shipped in RHEL 8) each incremental element insertion into an interval
set has O(n) cost proportional to the current set size, making the
overall complexity O(n^2).
With 12,000 ipset entries this causes firewall-cmd --reload to take
~80 seconds on RHEL 8 with the nftables backend. Even on newer
systems (nftables 1.0.9 / kernel 5.14) batching yields a ~20%
improvement.
This patch accumulates all element fragments and creates batched
"add element" operations - one per chunk of 1000 elements - instead
of one per entry. This lets nftables handle bulk element insertion
natively and reduces nft operations from N to ceil(N/1000).
Benchmark (12k ipset entries, nftables backend):
RHEL 8 (nftables 1.0.4, kernel 4.18): ~79,100ms -> ~2,500ms
RHEL 9 (nftables 1.0.9, kernel 5.14): ~1,560ms -> ~1,240ms
Backport of upstream PR #1544 for firewalld 0.9.11 (RHEL/AlmaLinux 8).
NOTE: erig0's original RHEL-8 backport was missing rules.clear()
between chunks, causing "No buffer space available" on large ipsets.
This version includes the fix.
Fixes #933
---
src/firewall/core/nftables.py | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index XXXXXXX..XXXXXXX 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -1896,14 +1896,19 @@ class nftables(object):
fragment.append(entry_tokens[i])
return [{"concat": fragment}] if len(type_format) > 1 else fragment
- def build_set_add_rules(self, name, entry):
+ def build_set_add_rules(self, name, entries):
rules = []
- element = self._set_entry_fragment(name, entry)
+ elements = []
+ if not isinstance(entries, (list, tuple)):
+ entries = [entries]
+ for element in entries:
+ elements.extend(self._set_entry_fragment(name, element))
+
for family in ["inet", "ip", "ip6"]:
rules.append({"add": {"element": {"family": family,
"table": TABLE_NAME,
"name": name,
- "elem": element}}})
+ "elem": elements}}})
return rules
def set_add(self, name, entry):
@@ -1952,13 +1957,9 @@ class nftables(object):
rules.extend(self.build_set_flush_rules(set_name))
# avoid large memory usage by chunking the entries
- chunk = 0
- for entry in entries:
- rules.extend(self.build_set_add_rules(set_name, entry))
- chunk += 1
- if chunk >= 1000:
- self.set_rules(rules, self._fw.get_log_denied())
- rules.clear()
- chunk = 0
- else:
+ for i in range(0, len(entries), 1000):
+ rules.extend(self.build_set_add_rules(set_name, entries[i : i + 1000]))
+ self.set_rules(rules, self._fw.get_log_denied())
+ rules.clear()
+ else:
self.set_rules(rules, self._fw.get_log_denied())
--
2.43.5

View File

@ -1,7 +1,7 @@
Summary: A firewall daemon with D-Bus interface providing a dynamic firewall
Name: firewalld
Version: 0.9.11
Release: 10%{?dist}
Release: 10%{?dist}.alma.1
URL: http://www.firewalld.org
License: GPLv2+
Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.gz
@ -37,6 +37,9 @@ Patch29: 0029-v2.0.0-feat-direct-avoid-iptables-flush-if-using-nft.patch
Patch30: 0030-v2.0.0-test-direct-avoid-iptables-flush-if-using-nft.patch
Patch31: 0031-v2.2.0-fix-service-update-highest-port-number-for-ce.patch
# AlmaLinux Patch
Patch1000: 1000-fix-nftables-batch-ipset-elements-to-avoid-O-n2-inse.patch
BuildArch: noarch
BuildRequires: autoconf
BuildRequires: automake
@ -237,6 +240,10 @@ desktop-file-install --delete-original \
%{_mandir}/man1/firewall-config*.1*
%changelog
* Wed Mar 11 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 0.9.11-10.alma.1
- fix(nftables): batch ipset elements to avoid O(n^2) insertion cost
- Resolves: almalinux/almalinux-deploy#186
* Tue Feb 04 2025 Eric Garver <egarver@redhat.com> - 0.9.11-10
- fix(service): update highest port number for ceph