import UBI firewalld-1.3.4-18.el9_7

This commit is contained in:
AlmaLinux RelEng Bot 2026-03-10 18:26:30 -04:00
parent ea412f88be
commit 785c2e7cc1
15 changed files with 1249 additions and 1 deletions

View File

@ -0,0 +1,71 @@
From 0829f9ec9d171894bda6695a87c15aba49f3e6a2 Mon Sep 17 00:00:00 2001
From: cyqsimon <28627918+cyqsimon@users.noreply.github.com>
Date: Tue, 30 Jan 2024 17:08:30 +0800
Subject: [PATCH 35/48] v2.2.0: feat: add iperf{2,3} services
(cherry picked from commit a21b401f6d8dd6eb65adba1878a29d63086b15e7)
---
config/Makefile.am | 2 ++
config/services/iperf2.xml | 7 +++++++
config/services/iperf3.xml | 8 ++++++++
po/POTFILES.in | 2 ++
4 files changed, 19 insertions(+)
create mode 100644 config/services/iperf2.xml
create mode 100644 config/services/iperf3.xml
diff --git a/config/Makefile.am b/config/Makefile.am
index 711f05afb799..a7a6dc039594 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -188,6 +188,8 @@ CONFIG_FILES = \
services/ident.xml \
services/imaps.xml \
services/imap.xml \
+ services/iperf2.xml \
+ services/iperf3.xml \
services/ipfs.xml \
services/ipp-client.xml \
services/ipp.xml \
diff --git a/config/services/iperf2.xml b/config/services/iperf2.xml
new file mode 100644
index 000000000000..4475c4e58212
--- /dev/null
+++ b/config/services/iperf2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+ <short>iperf2</short>
+ <description>iperf2 is a TCP and UDP network bandwidth measurement tool. Enable this option if you want to run an iperf2 server on its default port.</description>
+ <port protocol="tcp" port="5001"/>
+ <port protocol="udp" port="5001"/>
+</service>
diff --git a/config/services/iperf3.xml b/config/services/iperf3.xml
new file mode 100644
index 000000000000..4a481b0ecdfb
--- /dev/null
+++ b/config/services/iperf3.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<service>
+ <short>iperf3</short>
+ <description>iperf3 is a TCP, UDP, and SCTP network bandwidth measurement tool. Enable this option if you want to run an iperf3 server on its default port.</description>
+ <port protocol="tcp" port="5201"/>
+ <port protocol="udp" port="5201"/>
+ <port protocol="sctp" port="5201"/>
+</service>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a03ff0ce1df3..bdd0d3fc939e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -120,6 +120,8 @@ config/services/http.xml
config/services/ident.xml
config/services/imaps.xml
config/services/imap.xml
+config/services/iperf2.xml
+config/services/iperf3.xml
config/services/ipfs.xml
config/services/ipp-client.xml
config/services/ipp.xml
--
2.47.3

View File

@ -0,0 +1,36 @@
From 1f72a1c3bdf0dd727d76f205b87223dd29ef0c7c Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Mon, 6 Oct 2025 16:32:59 -0400
Subject: [PATCH 36/48] v2.4.0: test(functions): add macro WAIT_UNTIL
(cherry picked from commit 50890c62b00db91f15ba5802055afc293a3fe77a)
---
src/tests/functions.at | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/tests/functions.at b/src/tests/functions.at
index 8b07908c667c..df3fff6ad4b9 100644
--- a/src/tests/functions.at
+++ b/src/tests/functions.at
@@ -763,3 +763,18 @@ m4_define([CHECK_NFTABLES_FIB_IN_FORWARD], [
NS_CHECK([nft delete table inet firewalld_check])
])
])
+
+dnl $1 = command to run until zero exit code
+m4_define([WAIT_UNTIL], [
+ _fail=1
+ _timeout=120
+ for I in $(seq ${_timeout}); do
+ { $1 ; } && { _fail=0; break; }
+ sleep 1
+ done
+ if test ${_fail} -gt 0; then
+ printf "FAIL: Command failed succeed in ${_timeout} seconds:\n"
+ printf " $1\n"
+ AT_FAIL_IF([:])
+ fi
+])
--
2.47.3

View File

@ -0,0 +1,81 @@
From 3a91e1c6a575572cabbc06460ad94f65234a7d98 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 14 Oct 2025 16:41:49 -0400
Subject: [PATCH 37/48] v2.4.0: fix(server): load firewall rules before
claiming dbus
This guarantees that the firewall is loaded and ready before the daemon
registers with dbus.
(cherry picked from commit 63d2238d055ee193f18acb51f6362b64d11e0886)
---
src/firewall/server/firewalld.py | 15 +++++++++++----
src/firewall/server/server.py | 10 +---------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py
index 8b9593a22fd8..fc85d3e0c359 100644
--- a/src/firewall/server/firewalld.py
+++ b/src/firewall/server/firewalld.py
@@ -25,6 +25,7 @@ from gi.repository import GLib
import copy
import dbus
import dbus.service
+import dbus.mainloop.glib
from firewall import config
from firewall.core.fw import Firewall
@@ -69,12 +70,18 @@ class FirewallD(DbusServiceObject):
""" Use config.dbus.PK_ACTION_CONFIG as a default """
@handle_exceptions
- def __init__(self, *args, **kwargs):
- super(FirewallD, self).__init__(*args, **kwargs)
+ def __init__(self):
self.fw = Firewall()
- self.busname = args[0]
- self.path = args[1]
self.start()
+
+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+ bus = dbus.SystemBus()
+ name = dbus.service.BusName(config.dbus.DBUS_INTERFACE, bus=bus)
+ super(FirewallD, self).__init__(name, config.dbus.DBUS_PATH)
+
+ self.busname = name
+ self.path = config.dbus.DBUS_PATH
+
dbus_introspection_prepare_properties(self, config.dbus.DBUS_INTERFACE)
self.config = FirewallDConfig(self.fw.config, self.busname,
config.dbus.DBUS_PATH_CONFIG)
diff --git a/src/firewall/server/server.py b/src/firewall/server/server.py
index 2921ae9104f1..7f3404793f12 100644
--- a/src/firewall/server/server.py
+++ b/src/firewall/server/server.py
@@ -31,11 +31,6 @@ import signal
from gi.repository import GLib
-import dbus
-import dbus.service
-import dbus.mainloop.glib
-
-from firewall import config
from firewall.core.logger import log
from firewall.server.firewalld import FirewallD
@@ -83,10 +78,7 @@ def run_server(debug_gc=False):
GLib.timeout_add_seconds(gc_timeout, gc_collect)
try:
- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- bus = dbus.SystemBus()
- name = dbus.service.BusName(config.dbus.DBUS_INTERFACE, bus=bus)
- service = FirewallD(name, config.dbus.DBUS_PATH)
+ service = FirewallD()
mainloop = GLib.MainLoop()
if debug_gc:
--
2.47.3

View File

@ -0,0 +1,29 @@
From bbfef80c94f368130e4440d1624d2a2bc1daf28d Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 14 Oct 2025 16:05:41 -0400
Subject: [PATCH 38/48] v2.4.0: Revert "fix(systemd): allow start code 251
(RUNNING_BUT_FAILED)"
This reverts commit d52815e198f05378a3f34633adfedd29165cc64e.
(cherry picked from commit d2af4c8de086b658b0f1a24be9d3bf55b514b3c3)
---
config/firewalld.service.in | 2 --
1 file changed, 2 deletions(-)
diff --git a/config/firewalld.service.in b/config/firewalld.service.in
index bd8690fd87a6..cd7f772b8581 100644
--- a/config/firewalld.service.in
+++ b/config/firewalld.service.in
@@ -11,8 +11,6 @@ Documentation=man:firewalld(1)
EnvironmentFile=-/etc/sysconfig/firewalld
ExecStart=@sbindir@/firewalld --nofork --nopid $FIREWALLD_ARGS
ExecStartPost=@bindir@/firewall-cmd --state
-# don't fail ExecStartPost on RUNNING_BUT_FAILED
-SuccessExitStatus=251
ExecReload=/bin/kill -HUP $MAINPID
StandardOutput=null
StandardError=null
--
2.47.3

View File

@ -0,0 +1,29 @@
From 82a7c51975297fa185410ce37ae0c73b70d1924d Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 14 Oct 2025 16:05:54 -0400
Subject: [PATCH 39/48] v2.4.0: Revert "fix(systemd): verify firewalld is
responsive to dbus"
This reverts commit 4ddfe5672e3a51e1c081b410144155553f256e91.
Fixes: #1492
(cherry picked from commit 3e61bcccdb3efc12474eb99538bd52fc4f63f4dd)
---
config/firewalld.service.in | 1 -
1 file changed, 1 deletion(-)
diff --git a/config/firewalld.service.in b/config/firewalld.service.in
index cd7f772b8581..08c9f74dd924 100644
--- a/config/firewalld.service.in
+++ b/config/firewalld.service.in
@@ -10,7 +10,6 @@ Documentation=man:firewalld(1)
[Service]
EnvironmentFile=-/etc/sysconfig/firewalld
ExecStart=@sbindir@/firewalld --nofork --nopid $FIREWALLD_ARGS
-ExecStartPost=@bindir@/firewall-cmd --state
ExecReload=/bin/kill -HUP $MAINPID
StandardOutput=null
StandardError=null
--
2.47.3

View File

@ -0,0 +1,66 @@
From 85d9dfb83d49499b21fb3c97e4486bc944a2651e Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 14 Oct 2025 15:59:05 -0400
Subject: [PATCH 40/48] v2.4.0: fix(nftables): ipset: add entries from GLib
loop when idle
Sets with a large amount of entries can take a significant time to
apply. Use the GLib mainloop to add them in chunks when the loop is
idle. This allows dbus calls in between the chunks as the dbus
events/calls have higher priority.
Fixes: #1277
(cherry picked from commit 3874bafc427139e647829d7662577567343aceb6)
---
src/firewall/core/nftables.py | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index 8115bcb9d7f4..254fe7cfbebe 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -18,6 +18,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+
+from gi.repository import GLib
+
import copy
import json
import ipaddress
@@ -1958,15 +1961,27 @@ class nftables(object):
rules = []
rules.extend(self.build_set_create_rules(set_name, type_name, create_options))
rules.extend(self.build_set_flush_rules(set_name))
+ self.set_rules(rules, self._fw.get_log_denied())
+
+ def _idle_set_add_entries(rules):
+ try:
+ self.set_rules(rules, self._fw.get_log_denied())
+ except Exception as e:
+ log.error("While restoring ipset entries the following Error occurred:")
+ log.error(e)
- # avoid large memory usage by chunking the entries
+ # Avoid large memory usage by chunking the entries. Additionally, add
+ # the entries from the GLib main loop when it's idle. This avoids
+ # blocking the main loop for too long.
+ #
chunk = 0
+ rules = []
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()
+ GLib.idle_add(lambda x: _idle_set_add_entries(x), rules)
+ rules = []
chunk = 0
else:
- self.set_rules(rules, self._fw.get_log_denied())
+ GLib.idle_add(lambda x: _idle_set_add_entries(x), rules)
--
2.47.3

View File

@ -0,0 +1,39 @@
From c2f4ff8d26d2d7510e32f8ec6bcaa222af95ed9a Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 14 Oct 2025 17:50:22 -0400
Subject: [PATCH 41/48] v2.4.0: test(ipset): scale: verify all the entries were
added
(cherry picked from commit ab35fc7a99536efc7dde2242507fad6bed577d68)
---
src/tests/regression/ipset_scale.at | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/tests/regression/ipset_scale.at b/src/tests/regression/ipset_scale.at
index 0aef986434f0..d754e035f187 100644
--- a/src/tests/regression/ipset_scale.at
+++ b/src/tests/regression/ipset_scale.at
@@ -1,6 +1,8 @@
FWD_START_TEST([ipset scale])
AT_KEYWORDS(ipset gh738 scale)
+AT_SKIP_IF([! NS_CMD([which wc >/dev/null 2>&1])])
+
dnl Create a huge ipset
AT_CHECK([touch ./entries], 0, [ignore])
AT_CHECK([sh -c '
@@ -22,4 +24,11 @@ ulimit -d $(expr 1024 \* 300)
FWD_RESTART() dnl required because we changed ulimit
FWD_RELOAD()
+dnl Verify all the entries are added.
+m4_if(nftables, FIREWALL_BACKEND, [
+ WAIT_UNTIL([test "$(NS_CMD([nft $NFT_NUMERIC_ARGS list set inet firewalld foobar |wc -l]))" -eq 31256])
+], [
+ WAIT_UNTIL([test "$(NS_CMD([$IPSET list foobar |wc -l]))" -eq 62508])
+])
+
FWD_END_TEST()
--
2.47.3

View File

@ -0,0 +1,28 @@
From f7c7f94908834824bc777334c5b61e7af4d629b5 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Mon, 13 Oct 2025 15:44:17 -0400
Subject: [PATCH 42/48] v2.4.0: fix(systemd): Requires dbus
Use Requires so when dbus is restarted firewalld is also restarted.
Fixes: RHEL-94927
(cherry picked from commit b9595ea06e6159735300bb4668a3e7e84966219c)
---
config/firewalld.service.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/config/firewalld.service.in b/config/firewalld.service.in
index 08c9f74dd924..7ace390c29d6 100644
--- a/config/firewalld.service.in
+++ b/config/firewalld.service.in
@@ -2,6 +2,7 @@
Description=firewalld - dynamic firewall daemon
Before=network-pre.target
Wants=network-pre.target
+Requires=dbus.service
After=dbus.service
After=polkit.service
Conflicts=iptables.service ip6tables.service ebtables.service ipset.service
--
2.47.3

View File

@ -0,0 +1,96 @@
From 496cadf080a047286dbbb0fef4a06a8d17261587 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 28 Oct 2025 15:59:26 -0400
Subject: [PATCH 43/48] v2.4.0: chore(icmp): add all icmptypes to ICMP_TYPES
dict
We can then use this as a source of truth for types/codes.
(cherry picked from commit b121faab666faddf7181d21691ee6e8a13b30dbe)
---
src/firewall/core/icmp.py | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/src/firewall/core/icmp.py b/src/firewall/core/icmp.py
index c293098da20f..2928052194ea 100644
--- a/src/firewall/core/icmp.py
+++ b/src/firewall/core/icmp.py
@@ -25,32 +25,42 @@ __all__ = [ "ICMP_TYPES", "ICMPV6_TYPES",
ICMP_TYPES = {
"echo-reply": "0/0",
"pong": "0/0",
+ "destination-unreachable": "3/0",
"network-unreachable": "3/0",
+ "tos-network-unreachable": "3/0",
"host-unreachable": "3/1",
+ "tos-host-unreachable": "3/1",
"protocol-unreachable": "3/2",
"port-unreachable": "3/3",
"fragmentation-needed": "3/4",
"source-route-failed": "3/5",
+ # RFC-1112 Section 3.2.2.1 defines type 3, code 6-12
"network-unknown": "3/6",
"host-unknown": "3/7",
"network-prohibited": "3/9",
"host-prohibited": "3/10",
"TOS-network-unreachable": "3/11",
"TOS-host-unreachable": "3/12",
+ # RFC-1812 Section 5.2.7.1 defines type 3, code 13-15
"communication-prohibited": "3/13",
"host-precedence-violation": "3/14",
"precedence-cutoff": "3/15",
"source-quench": "4/0",
"network-redirect": "5/0",
+ "redirect": "5/0",
"host-redirect": "5/1",
+ "tos-host-redirect": "5/1",
"TOS-network-redirect": "5/2",
+ "tos-network-redirect": "5/2",
"TOS-host-redirect": "5/3",
"echo-request": "8/0",
"ping": "8/0",
"router-advertisement": "9/0",
"router-solicitation": "10/0",
+ "time-exceeded": "11/0",
"ttl-zero-during-transit": "11/0",
"ttl-zero-during-reassembly": "11/1",
+ "parameter-problem": "12/0",
"ip-header-bad": "12/0",
"required-option-missing": "12/1",
"timestamp-request": "13/0",
@@ -60,13 +70,19 @@ ICMP_TYPES = {
}
ICMPV6_TYPES = {
+ "destination-unreachable": "1/0",
"no-route": "1/0",
"communication-prohibited": "1/1",
+ "beyond-scope": "1/2",
"address-unreachable": "1/3",
"port-unreachable": "1/4",
+ "failed-policy": "1/5",
+ "reject-route": "1/6",
"packet-too-big": "2/0",
+ "time-exceeded": "3/0",
"ttl-zero-during-transit": "3/0",
"ttl-zero-during-reassembly": "3/1",
+ "parameter-problem": "4/0",
"bad-header": "4/0",
"unknown-header-type": "4/1",
"unknown-option": "4/2",
@@ -81,6 +97,12 @@ ICMPV6_TYPES = {
"neighbour-advertisement": "136/0",
"neigbour-advertisement": "136/0",
"redirect": "137/0",
+ # MLD is RFC-2710
+ "mld-listener-query": "130/0",
+ "mld-listener-report": "131/0",
+ "mld-listener-done": "132/0",
+ # MLDv2 is RFC-9777
+ "mld2-listener-report": "143/0",
}
def check_icmp_name(_name):
--
2.47.3

View File

@ -0,0 +1,261 @@
From 8c01d2e4f45c83c2f75e2c5038571f99a650b862 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Wed, 29 Oct 2025 11:32:35 -0400
Subject: [PATCH 44/48] v2.4.0: chore(icmp): convert type/code map to tuple
This will make it easier to use/query.
(cherry picked from commit 6c33bbcdb60e257ec1102baaff128f5b345c67f8)
---
src/firewall/core/icmp.py | 156 +++++++++++++++++-----------------
src/firewall/core/io/ipset.py | 26 ++++--
2 files changed, 99 insertions(+), 83 deletions(-)
diff --git a/src/firewall/core/icmp.py b/src/firewall/core/icmp.py
index 2928052194ea..fc828ae59e51 100644
--- a/src/firewall/core/icmp.py
+++ b/src/firewall/core/icmp.py
@@ -23,86 +23,88 @@ __all__ = [ "ICMP_TYPES", "ICMPV6_TYPES",
"check_icmp_type", "check_icmpv6_type" ]
ICMP_TYPES = {
- "echo-reply": "0/0",
- "pong": "0/0",
- "destination-unreachable": "3/0",
- "network-unreachable": "3/0",
- "tos-network-unreachable": "3/0",
- "host-unreachable": "3/1",
- "tos-host-unreachable": "3/1",
- "protocol-unreachable": "3/2",
- "port-unreachable": "3/3",
- "fragmentation-needed": "3/4",
- "source-route-failed": "3/5",
+ # "type": (type, code, backend omit code)
+ "echo-reply": (0, 0, True),
+ "pong": (0, 0, True),
+ "destination-unreachable": (3, 0, True),
+ "network-unreachable": (3, 0, False),
+ "tos-network-unreachable": (3, 0, False),
+ "host-unreachable": (3, 1, False),
+ "tos-host-unreachable": (3, 1, False),
+ "protocol-unreachable": (3, 2, False),
+ "port-unreachable": (3, 3, False),
+ "fragmentation-needed": (3, 4, False),
+ "source-route-failed": (3, 5, False),
# RFC-1112 Section 3.2.2.1 defines type 3, code 6-12
- "network-unknown": "3/6",
- "host-unknown": "3/7",
- "network-prohibited": "3/9",
- "host-prohibited": "3/10",
- "TOS-network-unreachable": "3/11",
- "TOS-host-unreachable": "3/12",
+ "network-unknown": (3, 6, False),
+ "host-unknown": (3, 7, False),
+ "network-prohibited": (3, 9, False),
+ "host-prohibited": (3, 10, False),
+ "TOS-network-unreachable": (3, 11, False),
+ "TOS-host-unreachable": (3, 12, False),
# RFC-1812 Section 5.2.7.1 defines type 3, code 13-15
- "communication-prohibited": "3/13",
- "host-precedence-violation": "3/14",
- "precedence-cutoff": "3/15",
- "source-quench": "4/0",
- "network-redirect": "5/0",
- "redirect": "5/0",
- "host-redirect": "5/1",
- "tos-host-redirect": "5/1",
- "TOS-network-redirect": "5/2",
- "tos-network-redirect": "5/2",
- "TOS-host-redirect": "5/3",
- "echo-request": "8/0",
- "ping": "8/0",
- "router-advertisement": "9/0",
- "router-solicitation": "10/0",
- "time-exceeded": "11/0",
- "ttl-zero-during-transit": "11/0",
- "ttl-zero-during-reassembly": "11/1",
- "parameter-problem": "12/0",
- "ip-header-bad": "12/0",
- "required-option-missing": "12/1",
- "timestamp-request": "13/0",
- "timestamp-reply": "14/0",
- "address-mask-request": "17/0",
- "address-mask-reply": "18/0",
+ "communication-prohibited": (3, 13, False),
+ "host-precedence-violation": (3, 14, False),
+ "precedence-cutoff": (3, 15, False),
+ "source-quench": (4, 0, True),
+ "network-redirect": (5, 0, False),
+ "redirect": (5, 0, True),
+ "host-redirect": (5, 1, False),
+ "tos-host-redirect": (5, 1, False),
+ "TOS-network-redirect": (5, 2, False),
+ "tos-network-redirect": (5, 2, False),
+ "TOS-host-redirect": (5, 3, False),
+ "echo-request": (8, 0, True),
+ "ping": (8, 0, True),
+ "router-advertisement": (9, 0, True),
+ "router-solicitation": (10, 0, True),
+ "time-exceeded": (11, 0, True),
+ "ttl-zero-during-transit": (11, 0, False),
+ "ttl-zero-during-reassembly": (11, 1, False),
+ "parameter-problem": (12, 0, True),
+ "ip-header-bad": (12, 0, False),
+ "required-option-missing": (12, 1, False),
+ "timestamp-request": (13, 0, True),
+ "timestamp-reply": (14, 0, True),
+ "address-mask-request": (17, 0, False),
+ "address-mask-reply": (18, 0, False),
}
ICMPV6_TYPES = {
- "destination-unreachable": "1/0",
- "no-route": "1/0",
- "communication-prohibited": "1/1",
- "beyond-scope": "1/2",
- "address-unreachable": "1/3",
- "port-unreachable": "1/4",
- "failed-policy": "1/5",
- "reject-route": "1/6",
- "packet-too-big": "2/0",
- "time-exceeded": "3/0",
- "ttl-zero-during-transit": "3/0",
- "ttl-zero-during-reassembly": "3/1",
- "parameter-problem": "4/0",
- "bad-header": "4/0",
- "unknown-header-type": "4/1",
- "unknown-option": "4/2",
- "echo-request": "128/0",
- "ping": "128/0",
- "echo-reply": "129/0",
- "pong": "129/0",
- "router-solicitation": "133/0",
- "router-advertisement": "134/0",
- "neighbour-solicitation": "135/0",
- "neigbour-solicitation": "135/0",
- "neighbour-advertisement": "136/0",
- "neigbour-advertisement": "136/0",
- "redirect": "137/0",
+ # "type": (type, code, backend omit code)
+ "destination-unreachable": (1, 0, True),
+ "no-route": (1, 0, False),
+ "communication-prohibited": (1, 1, False),
+ "beyond-scope": (1, 2, False),
+ "address-unreachable": (1, 3, False),
+ "port-unreachable": (1, 4, False),
+ "failed-policy": (1, 5, False),
+ "reject-route": (1, 6, False),
+ "packet-too-big": (2, 0, True),
+ "time-exceeded": (3, 0, True),
+ "ttl-zero-during-transit": (3, 0, False),
+ "ttl-zero-during-reassembly": (3, 1, False),
+ "parameter-problem": (4, 0, True),
+ "bad-header": (4, 0, False),
+ "unknown-header-type": (4, 1, False),
+ "unknown-option": (4, 2, False),
+ "echo-request": (128, 0, True),
+ "ping": (128, 0, True),
+ "echo-reply": (129, 0, True),
+ "pong": (129, 0, True),
+ "router-solicitation": (133, 0, True),
+ "router-advertisement": (134, 0, True),
+ "neighbour-solicitation": (135, 0, True),
+ "neigbour-solicitation": (135, 0, True),
+ "neighbour-advertisement": (136, 0, True),
+ "neigbour-advertisement": (136, 0, True),
+ "redirect": (137, 0, True),
# MLD is RFC-2710
- "mld-listener-query": "130/0",
- "mld-listener-report": "131/0",
- "mld-listener-done": "132/0",
+ "mld-listener-query": (130, 0, True),
+ "mld-listener-report": (131, 0, True),
+ "mld-listener-done": (132, 0, True),
# MLDv2 is RFC-9777
- "mld2-listener-report": "143/0",
+ "mld2-listener-report": (143, 0, True),
}
def check_icmp_name(_name):
@@ -110,8 +112,8 @@ def check_icmp_name(_name):
return True
return False
-def check_icmp_type(_type):
- if _type in ICMP_TYPES.values():
+def check_icmp_type_code(_type, _code):
+ if (_type, _code) in ICMP_TYPES.values():
return True
return False
@@ -120,7 +122,7 @@ def check_icmpv6_name(_name):
return True
return False
-def check_icmpv6_type(_type):
- if _type in ICMPV6_TYPES.values():
+def check_icmpv6_type_code(_type, _code):
+ if (_type, _code) in ICMPV6_TYPES.values():
return True
return False
diff --git a/src/firewall/core/io/ipset.py b/src/firewall/core/io/ipset.py
index a2fe16725875..6a612c8380f4 100644
--- a/src/firewall/core/io/ipset.py
+++ b/src/firewall/core/io/ipset.py
@@ -35,8 +35,8 @@ from firewall.functions import checkIP, checkIP6, checkIPnMask, \
from firewall.core.io.io_object import IO_Object, \
IO_Object_ContentHandler, IO_Object_XMLGenerator
from firewall.core.ipset import IPSET_TYPES, IPSET_CREATE_OPTIONS
-from firewall.core.icmp import check_icmp_name, check_icmp_type, \
- check_icmpv6_name, check_icmpv6_type
+from firewall.core.icmp import check_icmp_name, check_icmp_type_code, \
+ check_icmpv6_name, check_icmpv6_type_code
from firewall.core.logger import log
from firewall import errors
from firewall.errors import FirewallError
@@ -203,24 +203,38 @@ class IPSet(IO_Object):
errors.INVALID_ENTRY,
"invalid protocol for family '%s' in '%s'" % \
(family, entry))
- if not check_icmp_name(splits[1]) and not \
- check_icmp_type(splits[1]):
+ if not check_icmp_name(splits[1]) and "/" not in splits[1]:
raise FirewallError(
errors.INVALID_ENTRY,
"invalid icmp type '%s' in '%s'" % \
(splits[1], entry))
+ else:
+ (_type, _code) = splits[1].split("/")
+ if not check_icmp_type_code(_type, _code):
+ raise FirewallError(
+ errors.INVALID_ENTRY,
+ "invalid icmp type '%s' in '%s'"
+ % (splits[1], entry),
+ )
elif splits[0] in [ "icmpv6", "ipv6-icmp" ]:
if family != "ipv6":
raise FirewallError(
errors.INVALID_ENTRY,
"invalid protocol for family '%s' in '%s'" % \
(family, entry))
- if not check_icmpv6_name(splits[1]) and not \
- check_icmpv6_type(splits[1]):
+ if not check_icmpv6_name(splits[1]) and "/" not in splits[1]:
raise FirewallError(
errors.INVALID_ENTRY,
"invalid icmpv6 type '%s' in '%s'" % \
(splits[1], entry))
+ else:
+ (_type, _code) = splits[1].split("/")
+ if not check_icmpv6_type_code(_type, _code):
+ raise FirewallError(
+ errors.INVALID_ENTRY,
+ "invalid icmpv6 type '%s' in '%s'"
+ % (splits[1], entry),
+ )
elif splits[0] not in [ "tcp", "sctp", "udp", "udplite" ] \
and not checkProtocol(splits[0]):
raise FirewallError(
--
2.47.3

View File

@ -0,0 +1,139 @@
From 92d92e4f9d58d354b214a678f85a4fe64d510699 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Wed, 29 Oct 2025 11:49:12 -0400
Subject: [PATCH 45/48] v2.4.0: chore(nftables): simplify icmp match fragments
We can use ICMP_TYPES/ICMPV6_TYPES to get the codes and make generating
the match code generic. This eliminates ICMP_TYPES_FRAGMENTS.
(cherry picked from commit d9c36de285fc3df1f1226972f8f9826d07e30921)
---
src/firewall/core/nftables.py | 89 +++++------------------------------
1 file changed, 11 insertions(+), 78 deletions(-)
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index 254fe7cfbebe..2a48ff6ed7f5 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -35,6 +35,7 @@ from firewall.core.rich import Rich_Accept, Rich_Reject, Rich_Drop, Rich_Mark, \
Rich_Masquerade, Rich_ForwardPort, Rich_IcmpBlock, \
Rich_Tcp_Mss_Clamp, Rich_NFLog
from firewall.core.base import DEFAULT_ZONE_TARGET
+from firewall.core.icmp import ICMP_TYPES, ICMPV6_TYPES
from nftables.nftables import Nftables
TABLE_NAME = "firewalld"
@@ -94,78 +95,6 @@ def _icmp_types_fragments(protocol, type, code=None):
"right": code}})
return fragments
-# Most ICMP types are provided by nft, but for the codes we have to use numeric
-# values.
-#
-ICMP_TYPES_FRAGMENTS = {
- "ipv4": {
- "communication-prohibited": _icmp_types_fragments("icmp", "destination-unreachable", 13),
- "destination-unreachable": _icmp_types_fragments("icmp", "destination-unreachable"),
- "echo-reply": _icmp_types_fragments("icmp", "echo-reply"),
- "echo-request": _icmp_types_fragments("icmp", "echo-request"),
- "fragmentation-needed": _icmp_types_fragments("icmp", "destination-unreachable", 4),
- "host-precedence-violation": _icmp_types_fragments("icmp", "destination-unreachable", 14),
- "host-prohibited": _icmp_types_fragments("icmp", "destination-unreachable", 10),
- "host-redirect": _icmp_types_fragments("icmp", "redirect", 1),
- "host-unknown": _icmp_types_fragments("icmp", "destination-unreachable", 7),
- "host-unreachable": _icmp_types_fragments("icmp", "destination-unreachable", 1),
- "ip-header-bad": _icmp_types_fragments("icmp", "parameter-problem", 1),
- "network-prohibited": _icmp_types_fragments("icmp", "destination-unreachable", 8),
- "network-redirect": _icmp_types_fragments("icmp", "redirect", 0),
- "network-unknown": _icmp_types_fragments("icmp", "destination-unreachable", 6),
- "network-unreachable": _icmp_types_fragments("icmp", "destination-unreachable", 0),
- "parameter-problem": _icmp_types_fragments("icmp", "parameter-problem"),
- "port-unreachable": _icmp_types_fragments("icmp", "destination-unreachable", 3),
- "precedence-cutoff": _icmp_types_fragments("icmp", "destination-unreachable", 15),
- "protocol-unreachable": _icmp_types_fragments("icmp", "destination-unreachable", 2),
- "redirect": _icmp_types_fragments("icmp", "redirect"),
- "required-option-missing": _icmp_types_fragments("icmp", "parameter-problem", 1),
- "router-advertisement": _icmp_types_fragments("icmp", "router-advertisement"),
- "router-solicitation": _icmp_types_fragments("icmp", "router-solicitation"),
- "source-quench": _icmp_types_fragments("icmp", "source-quench"),
- "source-route-failed": _icmp_types_fragments("icmp", "destination-unreachable", 5),
- "time-exceeded": _icmp_types_fragments("icmp", "time-exceeded"),
- "timestamp-reply": _icmp_types_fragments("icmp", "timestamp-reply"),
- "timestamp-request": _icmp_types_fragments("icmp", "timestamp-request"),
- "tos-host-redirect": _icmp_types_fragments("icmp", "redirect", 3),
- "tos-host-unreachable": _icmp_types_fragments("icmp", "destination-unreachable", 12),
- "tos-network-redirect": _icmp_types_fragments("icmp", "redirect", 2),
- "tos-network-unreachable": _icmp_types_fragments("icmp", "destination-unreachable", 11),
- "ttl-zero-during-reassembly": _icmp_types_fragments("icmp", "time-exceeded", 1),
- "ttl-zero-during-transit": _icmp_types_fragments("icmp", "time-exceeded", 0),
- },
-
- "ipv6": {
- "address-unreachable": _icmp_types_fragments("icmpv6", "destination-unreachable", 3),
- "bad-header": _icmp_types_fragments("icmpv6", "parameter-problem", 0),
- "beyond-scope": _icmp_types_fragments("icmpv6", "destination-unreachable", 2),
- "communication-prohibited": _icmp_types_fragments("icmpv6", "destination-unreachable", 1),
- "destination-unreachable": _icmp_types_fragments("icmpv6", "destination-unreachable"),
- "echo-reply": _icmp_types_fragments("icmpv6", "echo-reply"),
- "echo-request": _icmp_types_fragments("icmpv6", "echo-request"),
- "failed-policy": _icmp_types_fragments("icmpv6", "destination-unreachable", 5),
- "mld-listener-done": _icmp_types_fragments("icmpv6", "mld-listener-done"),
- "mld-listener-query": _icmp_types_fragments("icmpv6", "mld-listener-query"),
- "mld-listener-report": _icmp_types_fragments("icmpv6", "mld-listener-report"),
- "mld2-listener-report": _icmp_types_fragments("icmpv6", "mld2-listener-report"),
- "neighbour-advertisement": _icmp_types_fragments("icmpv6", "nd-neighbor-advert"),
- "neighbour-solicitation": _icmp_types_fragments("icmpv6", "nd-neighbor-solicit"),
- "no-route": _icmp_types_fragments("icmpv6", "destination-unreachable", 0),
- "packet-too-big": _icmp_types_fragments("icmpv6", "packet-too-big"),
- "parameter-problem": _icmp_types_fragments("icmpv6", "parameter-problem"),
- "port-unreachable": _icmp_types_fragments("icmpv6", "destination-unreachable", 4),
- "redirect": _icmp_types_fragments("icmpv6", "nd-redirect"),
- "reject-route": _icmp_types_fragments("icmpv6", "destination-unreachable", 6),
- "router-advertisement": _icmp_types_fragments("icmpv6", "nd-router-advert"),
- "router-solicitation": _icmp_types_fragments("icmpv6", "nd-router-solicit"),
- "time-exceeded": _icmp_types_fragments("icmpv6", "time-exceeded"),
- "ttl-zero-during-reassembly": _icmp_types_fragments("icmpv6", "time-exceeded", 1),
- "ttl-zero-during-transit": _icmp_types_fragments("icmpv6", "time-exceeded", 0),
- "unknown-header-type": _icmp_types_fragments("icmpv6", "parameter-problem", 1),
- "unknown-option": _icmp_types_fragments("icmpv6", "parameter-problem", 2),
- }
-}
-
class nftables(object):
name = "nftables"
policies_supported = True
@@ -566,12 +495,12 @@ class nftables(object):
return rules
def supported_icmp_types(self, ipv=None):
- # nftables supports any icmp_type via arbitrary type/code matching.
- # We just need a translation for it in ICMP_TYPES_FRAGMENTS.
supported = set()
- for _ipv in [ipv] if ipv else ICMP_TYPES_FRAGMENTS.keys():
- supported.update(ICMP_TYPES_FRAGMENTS[_ipv].keys())
+ if ipv is None or ipv == "ipv4":
+ supported.update(ICMP_TYPES.keys())
+ if ipv is None or ipv == "ipv6":
+ supported.update(ICMPV6_TYPES.keys())
return list(supported)
@@ -1577,8 +1506,12 @@ class nftables(object):
return [{add_del: {"rule": rule}}]
def _icmp_types_to_nft_fragments(self, ipv, icmp_type):
- if icmp_type in ICMP_TYPES_FRAGMENTS[ipv]:
- return ICMP_TYPES_FRAGMENTS[ipv][icmp_type]
+ if ipv == "ipv4" and icmp_type in ICMP_TYPES:
+ _type, _code, _omit_code = ICMP_TYPES[icmp_type]
+ return _icmp_types_fragments("icmp", _type, None if _omit_code else _code)
+ elif ipv == "ipv6" and icmp_type in ICMPV6_TYPES:
+ _type, _code, _omit_code = ICMPV6_TYPES[icmp_type]
+ return _icmp_types_fragments("icmpv6", _type, None if _omit_code else _code)
else:
raise FirewallError(INVALID_ICMPTYPE,
"ICMP type '%s' not supported by %s for %s" % (icmp_type, self.name, ipv))
--
2.47.3

View File

@ -0,0 +1,68 @@
From 47d8ef737fc2f7b5990e39a86efb9358dc761076 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Wed, 29 Oct 2025 11:51:18 -0400
Subject: [PATCH 46/48] v2.4.0: chore(nftables): move _icmp_types_fragments()
inside the class
It was the only function outside of the class and is not useful to any
other code. Put it inside the class with everything else.
(cherry picked from commit 69ad16a4435a0b49b4196aa1a99ee963b72c4b69)
---
src/firewall/core/nftables.py | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index 2a48ff6ed7f5..0d3e31299d15 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -85,16 +85,6 @@ IPTABLES_TO_NFT_HOOK = {
},
}
-def _icmp_types_fragments(protocol, type, code=None):
- fragments = [{"match": {"left": {"payload": {"protocol": protocol, "field": "type"}},
- "op": "==",
- "right": type}}]
- if code is not None:
- fragments.append({"match": {"left": {"payload": {"protocol": protocol, "field": "code"}},
- "op": "==",
- "right": code}})
- return fragments
-
class nftables(object):
name = "nftables"
policies_supported = True
@@ -1505,13 +1495,27 @@ class nftables(object):
rule.update(self._rich_rule_priority_fragment(rich_rule))
return [{add_del: {"rule": rule}}]
+ def _icmp_types_fragments(self, protocol, type, code=None):
+ fragments = [{"match": {"left": {"payload": {"protocol": protocol, "field": "type"}},
+ "op": "==",
+ "right": type}}]
+ if code is not None:
+ fragments.append({"match": {"left": {"payload": {"protocol": protocol, "field": "code"}},
+ "op": "==",
+ "right": code}})
+ return fragments
+
def _icmp_types_to_nft_fragments(self, ipv, icmp_type):
if ipv == "ipv4" and icmp_type in ICMP_TYPES:
_type, _code, _omit_code = ICMP_TYPES[icmp_type]
- return _icmp_types_fragments("icmp", _type, None if _omit_code else _code)
+ return self._icmp_types_fragments(
+ "icmp", _type, None if _omit_code else _code
+ )
elif ipv == "ipv6" and icmp_type in ICMPV6_TYPES:
_type, _code, _omit_code = ICMPV6_TYPES[icmp_type]
- return _icmp_types_fragments("icmpv6", _type, None if _omit_code else _code)
+ return self._icmp_types_fragments(
+ "icmpv6", _type, None if _omit_code else _code
+ )
else:
raise FirewallError(INVALID_ICMPTYPE,
"ICMP type '%s' not supported by %s for %s" % (icmp_type, self.name, ipv))
--
2.47.3

View File

@ -0,0 +1,115 @@
From ea62b989b3ccb4bdf99cd42cfc17f08723c63407 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Wed, 29 Oct 2025 16:33:17 -0400
Subject: [PATCH 47/48] v2.4.0: chore(ipXtables): simplify icmp match fragments
We can use ICMP_TYPES/ICMPV6_TYPES to get the codes and make rule
generation generic while also supporting more types that don't have name
support in iptables, e.g. mld.
(cherry picked from commit 1562687ae6ca3cbcf6ece25126af9116adfb897b)
---
src/firewall/core/ipXtables.py | 61 +++++++++++++++-------------------
1 file changed, 27 insertions(+), 34 deletions(-)
diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py
index 339840c37ba4..efe292b3f638 100644
--- a/src/firewall/core/ipXtables.py
+++ b/src/firewall/core/ipXtables.py
@@ -27,10 +27,12 @@ from firewall.core.logger import log
from firewall.functions import tempFile, readfile, splitArgs, check_mac, portStr, \
check_single_address, check_address, normalizeIP6
from firewall import config
-from firewall.errors import FirewallError, INVALID_PASSTHROUGH, INVALID_RULE, UNKNOWN_ERROR, INVALID_ADDR
+from firewall.errors import FirewallError, INVALID_PASSTHROUGH, INVALID_RULE, UNKNOWN_ERROR, INVALID_ADDR, \
+ INVALID_ICMPTYPE
from firewall.core.rich import Rich_Accept, Rich_Reject, Rich_Drop, Rich_Mark, Rich_NFLog, \
Rich_Masquerade, Rich_ForwardPort, Rich_IcmpBlock, Rich_Tcp_Mss_Clamp
from firewall.core.base import DEFAULT_ZONE_TARGET
+from firewall.core.icmp import ICMP_TYPES, ICMPV6_TYPES
import string
POLICY_CHAIN_PREFIX = ""
@@ -598,37 +600,14 @@ class ip4tables(object):
return rules
def supported_icmp_types(self, ipv=None):
- """Return ICMP types that are supported by the iptables/ip6tables command and kernel"""
- ret = [ ]
- output = ""
- try:
- output = self.__run(["-p",
- "icmp" if self.ipv == "ipv4" else "ipv6-icmp",
- "--help"])
- except ValueError as ex:
- if self.ipv == "ipv4":
- log.debug1("iptables error: %s" % ex)
- else:
- log.debug1("ip6tables error: %s" % ex)
- lines = output.splitlines()
-
- in_types = False
- for line in lines:
- #print(line)
- if in_types:
- line = line.strip().lower()
- splits = line.split()
- for split in splits:
- if split.startswith("(") and split.endswith(")"):
- x = split[1:-1]
- else:
- x = split
- if x not in ret:
- ret.append(x)
- if self.ipv == "ipv4" and line.startswith("Valid ICMP Types:") or \
- self.ipv == "ipv6" and line.startswith("Valid ICMPv6 Types:"):
- in_types = True
- return ret
+ supported = set()
+
+ if ipv is None or self.ipv == "ipv4":
+ supported.update(ICMP_TYPES.keys())
+ if ipv is None or self.ipv == "ipv6":
+ supported.update(ICMPV6_TYPES.keys())
+
+ return list(supported)
def build_default_tables(self):
# nothing to do, they always exist
@@ -1350,6 +1329,20 @@ class ip4tables(object):
return rules
+ def _icmp_types_fragment(self, icmp_type):
+ if self.ipv == "ipv4" and icmp_type in ICMP_TYPES:
+ _type, _code, _omit_code = ICMP_TYPES[icmp_type]
+ _type_str = str(_type) if _omit_code else str(_type) + "/" + str(_code)
+ return ["-m", "icmp", "--icmp-type", _type_str]
+ elif self.ipv == "ipv6" and icmp_type in ICMPV6_TYPES:
+ _type, _code, _omit_code = ICMPV6_TYPES[icmp_type]
+ _type_str = str(_type) if _omit_code else str(_type) + "/" + str(_code)
+ return ["-m", "icmp6", "--icmpv6-type", _type_str]
+ else:
+ raise FirewallError(
+ INVALID_ICMPTYPE, f"ICMP type {icmp_type} not supported by {self.name}"
+ )
+
def build_policy_icmp_block_rules(self, enable, policy, ict, rich_rule=None):
table = "filter"
_policy = self._fw.policy.policy_base_chain_name(policy, table, POLICY_CHAIN_PREFIX)
@@ -1357,10 +1350,10 @@ class ip4tables(object):
if self.ipv == "ipv4":
proto = [ "-p", "icmp" ]
- match = [ "-m", "icmp", "--icmp-type", ict.name ]
+ match = self._icmp_types_fragment(ict.name)
else:
proto = [ "-p", "ipv6-icmp" ]
- match = [ "-m", "icmp6", "--icmpv6-type", ict.name ]
+ match = self._icmp_types_fragment(ict.name)
rules = []
if self._fw.policy.query_icmp_block_inversion(policy):
--
2.47.3

View File

@ -0,0 +1,165 @@
From bf8461cacb5a87bea1206dbc4a33f05d1007de46 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Mon, 27 Oct 2025 16:37:35 -0400
Subject: [PATCH 48/48] v2.4.0: fix(policy): allow-host-ipv6: allow MLD packets
RFC 4890 Section 4.4.1 makes it very clear that MLD packets must be
allowed by default.
Fixes: RHEL-54411
Fixes: RHEL-123703
(cherry picked from commit 3c42d02b770391686e6f7b202556ea4eee0722f5)
---
config/policies/allow-host-ipv6.xml | 16 +++++++++++++
src/tests/dbus/policy_permanent_functional.at | 4 ++--
src/tests/dbus/policy_runtime_functional.at | 2 +-
src/tests/features/policy.at | 24 +++++++++++++++++++
src/tests/regression/rhbz2222044.at | 2 +-
5 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/config/policies/allow-host-ipv6.xml b/config/policies/allow-host-ipv6.xml
index 0de7629c3809..33b5d13206a6 100644
--- a/config/policies/allow-host-ipv6.xml
+++ b/config/policies/allow-host-ipv6.xml
@@ -20,4 +20,20 @@
<icmp-type name="redirect" />
<accept />
</rule>
+ <rule family="ipv6">
+ <icmp-type name="mld-listener-done" />
+ <accept />
+ </rule>
+ <rule family="ipv6">
+ <icmp-type name="mld-listener-query" />
+ <accept />
+ </rule>
+ <rule family="ipv6">
+ <icmp-type name="mld-listener-report" />
+ <accept />
+ </rule>
+ <rule family="ipv6">
+ <icmp-type name="mld2-listener-report" />
+ <accept />
+ </rule>
</policy>
diff --git a/src/tests/dbus/policy_permanent_functional.at b/src/tests/dbus/policy_permanent_functional.at
index a5e1af90cc1c..44b8ebeea18e 100644
--- a/src/tests/dbus/policy_permanent_functional.at
+++ b/src/tests/dbus/policy_permanent_functional.at
@@ -155,7 +155,7 @@ DBUS_CHECK([config/policy/${DBUS_BUILTIN_POLICY_OBJ}], [config.policy.getSetting
'ingress_zones': m4_escape([<['ANY']>])
'masquerade': <false>
'priority': <-15000>
- 'rich_rules': m4_escape([<['rule family="ipv6" icmp-type name="neighbour-advertisement" accept', 'rule family="ipv6" icmp-type name="neighbour-solicitation" accept', 'rule family="ipv6" icmp-type name="router-advertisement" accept', 'rule family="ipv6" icmp-type name="redirect" accept']>])
+ 'rich_rules': m4_escape([<['rule family="ipv6" icmp-type name="neighbour-advertisement" accept', 'rule family="ipv6" icmp-type name="neighbour-solicitation" accept', 'rule family="ipv6" icmp-type name="router-advertisement" accept', 'rule family="ipv6" icmp-type name="redirect" accept', 'rule family="ipv6" icmp-type name="mld-listener-done" accept', 'rule family="ipv6" icmp-type name="mld-listener-query" accept', 'rule family="ipv6" icmp-type name="mld-listener-report" accept', 'rule family="ipv6" icmp-type name="mld2-listener-report" accept']>])
'short': <'Allow host IPv6'>
'target': <'DROP'>
'version': <'1.2'>
@@ -168,7 +168,7 @@ DBUS_CHECK([config/policy/${DBUS_BUILTIN_POLICY_OBJ}], [config.policy.getSetting
'ingress_zones': m4_escape([<['ANY']>])
'masquerade': <false>
'priority': <-15000>
- 'rich_rules': m4_escape([<['rule family="ipv6" icmp-type name="neighbour-advertisement" accept', 'rule family="ipv6" icmp-type name="neighbour-solicitation" accept', 'rule family="ipv6" icmp-type name="router-advertisement" accept', 'rule family="ipv6" icmp-type name="redirect" accept']>])
+ 'rich_rules': m4_escape([<['rule family="ipv6" icmp-type name="neighbour-advertisement" accept', 'rule family="ipv6" icmp-type name="neighbour-solicitation" accept', 'rule family="ipv6" icmp-type name="router-advertisement" accept', 'rule family="ipv6" icmp-type name="redirect" accept', 'rule family="ipv6" icmp-type name="mld-listener-done" accept', 'rule family="ipv6" icmp-type name="mld-listener-query" accept', 'rule family="ipv6" icmp-type name="mld-listener-report" accept', 'rule family="ipv6" icmp-type name="mld2-listener-report" accept']>])
'short': <'Allow host IPv6'>
'target': <'CONTINUE'>
])
diff --git a/src/tests/dbus/policy_runtime_functional.at b/src/tests/dbus/policy_runtime_functional.at
index ab9a43dda8f3..08cb3b1051ff 100644
--- a/src/tests/dbus/policy_runtime_functional.at
+++ b/src/tests/dbus/policy_runtime_functional.at
@@ -11,7 +11,7 @@ DBUS_CHECK([], [policy.getPolicySettings], ["allow-host-ipv6"], 0, [dnl
'ingress_zones': m4_escape([<['ANY']>])
'masquerade': <false>
'priority': <-15000>
- 'rich_rules': m4_escape([<['rule family="ipv6" icmp-type name="neighbour-advertisement" accept', 'rule family="ipv6" icmp-type name="neighbour-solicitation" accept', 'rule family="ipv6" icmp-type name="router-advertisement" accept', 'rule family="ipv6" icmp-type name="redirect" accept']>])
+ 'rich_rules': m4_escape([<['rule family="ipv6" icmp-type name="neighbour-advertisement" accept', 'rule family="ipv6" icmp-type name="neighbour-solicitation" accept', 'rule family="ipv6" icmp-type name="router-advertisement" accept', 'rule family="ipv6" icmp-type name="redirect" accept', 'rule family="ipv6" icmp-type name="mld-listener-done" accept', 'rule family="ipv6" icmp-type name="mld-listener-query" accept', 'rule family="ipv6" icmp-type name="mld-listener-report" accept', 'rule family="ipv6" icmp-type name="mld2-listener-report" accept']>])
'short': <'Allow host IPv6'>
'target': <'CONTINUE'>
])
diff --git a/src/tests/features/policy.at b/src/tests/features/policy.at
index 7136c0cf5ab9..e237c333651a 100644
--- a/src/tests/features/policy.at
+++ b/src/tests/features/policy.at
@@ -127,6 +127,10 @@ allow-host-ipv6 (active)
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
rule family="ipv6" icmp-type name="redirect" accept
+ rule family="ipv6" icmp-type name="mld-listener-done" accept
+ rule family="ipv6" icmp-type name="mld-listener-query" accept
+ rule family="ipv6" icmp-type name="mld-listener-report" accept
+ rule family="ipv6" icmp-type name="mld2-listener-report" accept
])])
FWD_CHECK([--permanent --info-policy allow-host-ipv6 | TRIM_WHITESPACE], 0, [m4_strip([dnl
allow-host-ipv6 (active)
@@ -146,6 +150,10 @@ allow-host-ipv6 (active)
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
rule family="ipv6" icmp-type name="redirect" accept
+ rule family="ipv6" icmp-type name="mld-listener-done" accept
+ rule family="ipv6" icmp-type name="mld-listener-query" accept
+ rule family="ipv6" icmp-type name="mld-listener-report" accept
+ rule family="ipv6" icmp-type name="mld2-listener-report" accept
])])
FWD_CHECK([--list-all-policies | TRIM_WHITESPACE], 0, [m4_strip([dnl
@@ -166,6 +174,10 @@ allow-host-ipv6 (active)
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
rule family="ipv6" icmp-type name="redirect" accept
+ rule family="ipv6" icmp-type name="mld-listener-done" accept
+ rule family="ipv6" icmp-type name="mld-listener-query" accept
+ rule family="ipv6" icmp-type name="mld-listener-report" accept
+ rule family="ipv6" icmp-type name="mld2-listener-report" accept
])])
FWD_CHECK([--permanent --list-all-policies | TRIM_WHITESPACE], 0, [m4_strip([dnl
allow-host-ipv6 (active)
@@ -185,6 +197,10 @@ allow-host-ipv6 (active)
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
rule family="ipv6" icmp-type name="redirect" accept
+ rule family="ipv6" icmp-type name="mld-listener-done" accept
+ rule family="ipv6" icmp-type name="mld-listener-query" accept
+ rule family="ipv6" icmp-type name="mld-listener-report" accept
+ rule family="ipv6" icmp-type name="mld2-listener-report" accept
])])
FWD_CHECK([--policy allow-host-ipv6 --list-all | TRIM_WHITESPACE], 0, [m4_strip([dnl
@@ -205,6 +221,10 @@ allow-host-ipv6 (active)
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
rule family="ipv6" icmp-type name="redirect" accept
+ rule family="ipv6" icmp-type name="mld-listener-done" accept
+ rule family="ipv6" icmp-type name="mld-listener-query" accept
+ rule family="ipv6" icmp-type name="mld-listener-report" accept
+ rule family="ipv6" icmp-type name="mld2-listener-report" accept
])])
FWD_CHECK([--permanent --policy allow-host-ipv6 --list-all | TRIM_WHITESPACE], 0, [m4_strip([dnl
allow-host-ipv6 (active)
@@ -224,6 +244,10 @@ allow-host-ipv6 (active)
rule family="ipv6" icmp-type name="neighbour-solicitation" accept
rule family="ipv6" icmp-type name="router-advertisement" accept
rule family="ipv6" icmp-type name="redirect" accept
+ rule family="ipv6" icmp-type name="mld-listener-done" accept
+ rule family="ipv6" icmp-type name="mld-listener-query" accept
+ rule family="ipv6" icmp-type name="mld-listener-report" accept
+ rule family="ipv6" icmp-type name="mld2-listener-report" accept
])])
FWD_END_TEST
diff --git a/src/tests/regression/rhbz2222044.at b/src/tests/regression/rhbz2222044.at
index 2d0333865076..cfa8b32d6c86 100644
--- a/src/tests/regression/rhbz2222044.at
+++ b/src/tests/regression/rhbz2222044.at
@@ -11,7 +11,7 @@ dnl rules have not changed so rule count should not change
m4_define([check_rule_count], [
m4_if(nftables, FIREWALL_BACKEND, [
NS_CHECK([nft list table inet firewalld | wc -l], 0, [dnl
-326
+330
])
], [ dnl iptables
NS_CHECK([iptables-save | wc -l], 0, [dnl
--
2.47.3

View File

@ -1,7 +1,7 @@
Summary: A firewall daemon with D-Bus interface providing a dynamic firewall
Name: firewalld
Version: 1.3.4
Release: 15%{?dist}
Release: 18%{?dist}
URL: http://www.firewalld.org
License: GPLv2+
Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.bz2
@ -39,6 +39,20 @@ Patch31: 0031-v2.4.0-fix-fw-start-remove-ipset-probe.patch
Patch32: 0032-v2.4.0-fix-systemd-allow-start-code-251-RUNNING_BUT_FAILED.patch
Patch33: 0033-v2.4.0-fix-policy-rich-verify-ipset-exists.patch
Patch34: 0034-v2.4.0-test-rich-rule-reference-invalid-ipset.patch
Patch35: 0035-v2.2.0-feat-add-iperf-2-3-services.patch
Patch36: 0036-v2.4.0-test-functions-add-macro-WAIT_UNTIL.patch
Patch37: 0037-v2.4.0-fix-server-load-firewall-rules-before-claimin.patch
Patch38: 0038-v2.4.0-Revert-fix-systemd-allow-start-code-251-RUNNI.patch
Patch39: 0039-v2.4.0-Revert-fix-systemd-verify-firewalld-is-respon.patch
Patch40: 0040-v2.4.0-fix-nftables-ipset-add-entries-from-GLib-loop.patch
Patch41: 0041-v2.4.0-test-ipset-scale-verify-all-the-entries-were-.patch
Patch42: 0042-v2.4.0-fix-systemd-Requires-dbus.patch
Patch43: 0043-v2.4.0-chore-icmp-add-all-icmptypes-to-ICMP_TYPES-di.patch
Patch44: 0044-v2.4.0-chore-icmp-convert-type-code-map-to-tuple.patch
Patch45: 0045-v2.4.0-chore-nftables-simplify-icmp-match-fragments.patch
Patch46: 0046-v2.4.0-chore-nftables-move-_icmp_types_fragments-ins.patch
Patch47: 0047-v2.4.0-chore-ipXtables-simplify-icmp-match-fragments.patch
Patch48: 0048-v2.4.0-fix-policy-allow-host-ipv6-allow-MLD-packets.patch
BuildArch: noarch
BuildRequires: autoconf
BuildRequires: automake
@ -262,6 +276,17 @@ rm -rf %{buildroot}%{_datadir}/firewalld/testsuite
%{_mandir}/man1/firewall-config*.1*
%changelog
* Tue Dec 02 2025 Eric Garver <egarver@redhat.com> - 1.3.4-18
- fix(policy): allow-host-ipv6: allow MLD packets
* Tue Dec 02 2025 Eric Garver <egarver@redhat.com> - 1.3.4-17
- fix(server): load firewall rules before claiming dbus
- fix(nftables): ipset: add entries from GLib loop when idle
- fix(systemd): Requires dbus
* Tue Dec 02 2025 Eric Garver <egarver@redhat.com> - 1.3.4-16
- feat: add iperf{2,3} services
* Tue Jun 17 2025 Eric Garver <egarver@redhat.com> - 1.3.4-15
- fix(policy): rich: verify ipset exists