From eb5673aa04540ed398c21af4289e6d5dff383377 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Tue, 4 Aug 2026 16:10:19 -0400 Subject: [PATCH] import CS git firewalld-1.3.4-19.el9_8 --- ...licy-timeout-argument-for-rich-rules.patch | 42 ++ ...ctions-fix-macro-CHECK_NFT_CT_HELPER.patch | 30 ++ ...policy-add-utility-functions-to-supp.patch | 60 +++ ...zone-service-move-timeouts-to-policy.patch | 77 ++++ ...re-zone-port-move-timeouts-to-policy.patch | 78 ++++ ...e-source_port-move-timeouts-to-polic.patch | 81 ++++ ...e-forward_port-move-timeouts-to-poli.patch | 91 ++++ ...e-icmp_block-move-timeouts-to-policy.patch | 78 ++++ ...e-masquerade-move-timeouts-to-policy.patch | 75 ++++ ...one-protocol-move-timeouts-to-policy.patch | 77 ++++ ...re-zone-rule-move-timeouts-to-policy.patch | 76 ++++ ...one-remove-daemon-level-timeout-code.patch | 49 ++ ...zone-add-utility-functions-to-suppor.patch | 51 +++ ...w_zone-support-timeouts-via-dict-API.patch | 78 ++++ ...5.0-fix-zone-forward-support-timeout.patch | 76 ++++ ...t-zone-forward-move-test-to-features.patch | 418 ++++++++++++++++++ ...2.5.0-test-zone-verify-timeout-works.patch | 214 +++++++++ ...5.0-chore-fw_policy-support-timeouts.patch | 74 ++++ ...7-v2.5.0-fix-policy-support-timeouts.patch | 97 ++++ ...olicy-allow-timeout-with-ingress-zon.patch | 26 ++ ...5.0-test-policy-verify-timeout-works.patch | 237 ++++++++++ SPECS/firewalld.spec | 27 +- 22 files changed, 2111 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0049-v2.3.0-fix-policy-timeout-argument-for-rich-rules.patch create mode 100644 SOURCES/0050-v2.5.0-test-functions-fix-macro-CHECK_NFT_CT_HELPER.patch create mode 100644 SOURCES/0051-v2.5.0-chore-fw_policy-add-utility-functions-to-supp.patch create mode 100644 SOURCES/0052-v2.5.0-chore-zone-service-move-timeouts-to-policy.patch create mode 100644 SOURCES/0053-v2.5.0-chore-zone-port-move-timeouts-to-policy.patch create mode 100644 SOURCES/0054-v2.5.0-chore-zone-source_port-move-timeouts-to-polic.patch create mode 100644 SOURCES/0055-v2.5.0-chore-zone-forward_port-move-timeouts-to-poli.patch create mode 100644 SOURCES/0056-v2.5.0-chore-zone-icmp_block-move-timeouts-to-policy.patch create mode 100644 SOURCES/0057-v2.5.0-chore-zone-masquerade-move-timeouts-to-policy.patch create mode 100644 SOURCES/0058-v2.5.0-chore-zone-protocol-move-timeouts-to-policy.patch create mode 100644 SOURCES/0059-v2.5.0-chore-zone-rule-move-timeouts-to-policy.patch create mode 100644 SOURCES/0060-v2.5.0-chore-zone-remove-daemon-level-timeout-code.patch create mode 100644 SOURCES/0061-v2.5.0-chore-fw_zone-add-utility-functions-to-suppor.patch create mode 100644 SOURCES/0062-v2.5.0-chore-fw_zone-support-timeouts-via-dict-API.patch create mode 100644 SOURCES/0063-v2.5.0-fix-zone-forward-support-timeout.patch create mode 100644 SOURCES/0064-v2.5.0-test-zone-forward-move-test-to-features.patch create mode 100644 SOURCES/0065-v2.5.0-test-zone-verify-timeout-works.patch create mode 100644 SOURCES/0066-v2.5.0-chore-fw_policy-support-timeouts.patch create mode 100644 SOURCES/0067-v2.5.0-fix-policy-support-timeouts.patch create mode 100644 SOURCES/0068-v2.5.0-fix-cli-policy-allow-timeout-with-ingress-zon.patch create mode 100644 SOURCES/0069-v2.5.0-test-policy-verify-timeout-works.patch diff --git a/SOURCES/0049-v2.3.0-fix-policy-timeout-argument-for-rich-rules.patch b/SOURCES/0049-v2.3.0-fix-policy-timeout-argument-for-rich-rules.patch new file mode 100644 index 0000000..0f86f48 --- /dev/null +++ b/SOURCES/0049-v2.3.0-fix-policy-timeout-argument-for-rich-rules.patch @@ -0,0 +1,42 @@ +From 21c9e9ad3811a9679e494a1fe32834edf96393af Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 13 Sep 2024 13:38:07 -0400 +Subject: [PATCH 49/70] v2.3.0: fix(policy): timeout argument for rich rules + +This is inconsequential, but noticed which looking at other changes. + +(cherry picked from commit 24f0e4ffc9dead83f178d4fdced6cd08852c6d9e) +--- + src/firewall/core/fw_policy.py | 2 +- + src/firewall/core/fw_zone.py | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index ff6ac07a2dc1..0a3c37224882 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -170,7 +170,7 @@ class FirewallPolicy(object): + # stupid wrappers to convert rich rule string to rich rule object + from firewall.core.rich import Rich_Rule + def add_rule_wrapper(policy, rule_str, timeout=0, sender=None): +- self.add_rule(policy, Rich_Rule(rule_str=rule_str), timeout=0, sender=sender) ++ self.add_rule(policy, Rich_Rule(rule_str=rule_str), timeout=timeout, sender=sender) + def remove_rule_wrapper(policy, rule_str): + self.remove_rule(policy, Rich_Rule(rule_str=rule_str)) + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index cdf080895e50..6c659047b97d 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -343,7 +343,7 @@ class FirewallZone(object): + def set_config_with_settings_dict(self, zone, settings, sender): + # stupid wrappers to convert rich rule string to rich rule object + def add_rule_wrapper(zone, rule_str, timeout=0, sender=None): +- self.add_rule(zone, Rich_Rule(rule_str=rule_str), timeout=0, sender=sender) ++ self.add_rule(zone, Rich_Rule(rule_str=rule_str), timeout=timeout, sender=sender) + def remove_rule_wrapper(zone, rule_str): + self.remove_rule(zone, Rich_Rule(rule_str=rule_str)) + +-- +2.52.0 + diff --git a/SOURCES/0050-v2.5.0-test-functions-fix-macro-CHECK_NFT_CT_HELPER.patch b/SOURCES/0050-v2.5.0-test-functions-fix-macro-CHECK_NFT_CT_HELPER.patch new file mode 100644 index 0000000..ecfb181 --- /dev/null +++ b/SOURCES/0050-v2.5.0-test-functions-fix-macro-CHECK_NFT_CT_HELPER.patch @@ -0,0 +1,30 @@ +From 697ab1154b57fc875aa87d9407a3d123b324731d Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 6 Jan 2026 13:13:44 -0500 +Subject: [PATCH 50/70] v2.5.0: test(functions): fix macro + CHECK_NFT_CT_HELPER() + +It never worked! + +Fixes: 32c2497f6ec0 ("test: add macro CHECK_NFT_CT_HELPER()") +(cherry picked from commit eca5890a1ac596dd3ff08f6446de0b68427dffc9) +--- + src/tests/functions.at | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tests/functions.at b/src/tests/functions.at +index df3fff6ad4b9..fa0c961fb574 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -647,7 +647,7 @@ m4_define([CHECK_LOG_AUDIT], [ + m4_define([CHECK_NFT_CT_HELPER], [ + m4_if(nftables, FIREWALL_BACKEND, [ + NS_CHECK([nft add table inet firewalld_check_ct_helper]) +- AT_SKIP_IF([! NS_CMD([nft add ct helper inet firewalld helper-ftp-tcp { type \"ftp\" protocol tcp \; } >/dev/null 2>&1])]) ++ AT_SKIP_IF([! NS_CMD([nft add ct helper inet firewalld_check_ct_helper helper-ftp-tcp { type \"ftp\" protocol tcp \; } >/dev/null 2>&1])]) + NS_CHECK([nft delete table inet firewalld_check_ct_helper]) + ]) + ]) +-- +2.52.0 + diff --git a/SOURCES/0051-v2.5.0-chore-fw_policy-add-utility-functions-to-supp.patch b/SOURCES/0051-v2.5.0-chore-fw_policy-add-utility-functions-to-supp.patch new file mode 100644 index 0000000..4f3a16c --- /dev/null +++ b/SOURCES/0051-v2.5.0-chore-fw_policy-add-utility-functions-to-supp.patch @@ -0,0 +1,60 @@ +From a21b62942819c4fd5d83fad49e45d0033954aa24 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:18:42 -0500 +Subject: [PATCH 51/70] v2.5.0: chore(fw_policy): add utility functions to + support timeouts + +(cherry picked from commit 2a14e41b153c397cce3379be4e7ee2651c8d2a79) +--- + src/firewall/core/fw_policy.py | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 0a3c37224882..444d84fe9023 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -2,6 +2,8 @@ + # + # SPDX-License-Identifier: GPL-2.0-or-later + ++from gi.repository import GLib ++ + import copy + + from firewall.core.logger import log +@@ -23,6 +25,7 @@ class FirewallPolicy(object): + self._fw = fw + self._chains = { } + self._policies = { } ++ self._timeouts = {} + + def __repr__(self): + return '%s(%r, %r)' % (self.__class__, self._chains, self._policies) +@@ -30,6 +33,8 @@ class FirewallPolicy(object): + def cleanup(self): + self._chains.clear() + self._policies.clear() ++ for _id in self._timeouts: ++ self.removeTimeout(_id) + + # transaction + +@@ -217,6 +222,15 @@ class FirewallPolicy(object): + else: # bool + setting_to_fn[key][0](policy, timeout=0, sender=sender) + ++ def addTimeout(self, tag, _id): ++ if _id not in self._timeouts: ++ self._timeouts[_id] = tag ++ ++ def removeTimeout(self, _id): ++ if _id in self._timeouts: ++ GLib.source_remove(self._timeouts[_id]) ++ del self._timeouts[_id] ++ + # ingress zones + + def check_ingress_zone(self, zone): +-- +2.52.0 + diff --git a/SOURCES/0052-v2.5.0-chore-zone-service-move-timeouts-to-policy.patch b/SOURCES/0052-v2.5.0-chore-zone-service-move-timeouts-to-policy.patch new file mode 100644 index 0000000..62c83d1 --- /dev/null +++ b/SOURCES/0052-v2.5.0-chore-zone-service-move-timeouts-to-policy.patch @@ -0,0 +1,77 @@ +From 1f650ad8b02f761732305c5ffc9ae84d774bb48a Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:19:23 -0500 +Subject: [PATCH 52/70] v2.5.0: chore(zone): service: move timeouts to policy + +(cherry picked from commit 248d69433f236dd67f9104ace8baf61298b044eb) +--- + src/firewall/core/fw_policy.py | 8 ++++++++ + src/firewall/server/firewalld.py | 12 +----------- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 444d84fe9023..8087f4bf9509 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -556,6 +556,12 @@ class FirewallPolicy(object): + if _obj.applied: + self._service(True, _policy, service, transaction) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_service, _policy, service ++ ) ++ self.addTimeout(tag, ("service", _policy, service)) ++ + self.__register_service(_obj, service_id, timeout, sender) + transaction.add_fail(self.__unregister_service, _obj, service_id) + +@@ -587,6 +593,8 @@ class FirewallPolicy(object): + if _obj.applied: + self._service(False, _policy, service, transaction) + ++ self.removeTimeout(("service", _policy, service)) ++ + transaction.add_post(self.__unregister_service, _obj, service_id) + + if use_transaction is None: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index fc85d3e0c359..58c773732953 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1553,13 +1553,6 @@ class FirewallD(DbusServiceObject): + + # SERVICES + +- @dbus_handle_exceptions +- def disableTimedService(self, zone, service): +- log.debug1("zone.disableTimedService('%s', '%s')" % (zone, service)) +- del self._timeouts[zone][service] +- self.fw.zone.remove_service(zone, service) +- self.ServiceRemoved(zone, service) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi', + out_signature='s') +@@ -1575,9 +1568,7 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.add_service(zone, service, timeout, sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedService, +- _zone, service) +- self.addTimeout(_zone, service, tag) ++ GLib.timeout_add_seconds(timeout, self.ServiceRemoved, _zone, service) + + self.ServiceAdded(_zone, service, timeout) + return _zone +@@ -1595,7 +1586,6 @@ class FirewallD(DbusServiceObject): + + _zone = self.fw.zone.remove_service(zone, service) + +- self.removeTimeout(_zone, service) + self.ServiceRemoved(_zone, service) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0053-v2.5.0-chore-zone-port-move-timeouts-to-policy.patch b/SOURCES/0053-v2.5.0-chore-zone-port-move-timeouts-to-policy.patch new file mode 100644 index 0000000..0c9bd53 --- /dev/null +++ b/SOURCES/0053-v2.5.0-chore-zone-port-move-timeouts-to-policy.patch @@ -0,0 +1,78 @@ +From 53686874a4dfb7cf2ec5a7a31969e8c19e64d1c4 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:24:36 -0500 +Subject: [PATCH 53/70] v2.5.0: chore(zone): port: move timeouts to policy + +(cherry picked from commit 5db0925a9478ce5f6dd719f34a0da3c7185d4647) +--- + src/firewall/core/fw_policy.py | 8 ++++++++ + src/firewall/server/firewalld.py | 13 +------------ + 2 files changed, 9 insertions(+), 12 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 8087f4bf9509..733758d7d3f7 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -690,6 +690,12 @@ class FirewallPolicy(object): + port_id = self.__port_id(range, protocol) + transaction.add_post(self.__unregister_port, _obj, port_id) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_port, _policy, port, protocol ++ ) ++ self.addTimeout(tag, ("port", _policy, port, protocol)) ++ + if use_transaction is None: + transaction.execute(True) + +@@ -734,6 +740,8 @@ class FirewallPolicy(object): + port_id = self.__port_id(range, protocol) + transaction.add_post(self.__unregister_port, _obj, port_id) + ++ self.removeTimeout(("port", _policy, port, protocol)) ++ + if use_transaction is None: + transaction.execute(True) + +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 58c773732953..939fb687a7af 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1627,14 +1627,6 @@ class FirewallD(DbusServiceObject): + + # PORTS + +- @dbus_handle_exceptions +- def disableTimedPort(self, zone, port, protocol): +- log.debug1("zone.disableTimedPort('%s', '%s', '%s')" % \ +- (zone, port, protocol)) +- del self._timeouts[zone][(port, protocol)] +- self.fw.zone.remove_port(zone, port, protocol) +- self.PortRemoved(zone, port, protocol) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssi', + out_signature='s') +@@ -1651,9 +1643,7 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.add_port(zone, port, protocol, timeout, sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedPort, +- _zone, port, protocol) +- self.addTimeout(_zone, (port, protocol), tag) ++ GLib.timeout_add_seconds(timeout, self.PortRemoved, _zone, port, protocol) + + self.PortAdded(_zone, port, protocol, timeout) + return _zone +@@ -1672,7 +1662,6 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + _zone= self.fw.zone.remove_port(zone, port, protocol) + +- self.removeTimeout(_zone, (port, protocol)) + self.PortRemoved(_zone, port, protocol) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0054-v2.5.0-chore-zone-source_port-move-timeouts-to-polic.patch b/SOURCES/0054-v2.5.0-chore-zone-source_port-move-timeouts-to-polic.patch new file mode 100644 index 0000000..e3a7784 --- /dev/null +++ b/SOURCES/0054-v2.5.0-chore-zone-source_port-move-timeouts-to-polic.patch @@ -0,0 +1,81 @@ +From cbdfc33f078818127e4be2e510b665ca1f0f6bda Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 15:06:56 -0500 +Subject: [PATCH 54/70] v2.5.0: chore(zone): source_port: move timeouts to + policy + +(cherry picked from commit 41a2573afefb4d20801b27e3862293c0e06a344d) +--- + src/firewall/core/fw_policy.py | 8 ++++++++ + src/firewall/server/firewalld.py | 15 +++------------ + 2 files changed, 11 insertions(+), 12 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 733758d7d3f7..ee652d892d4a 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -886,6 +886,12 @@ class FirewallPolicy(object): + port_id = self.__source_port_id(range, protocol) + transaction.add_post(self.__unregister_source_port, _obj, port_id) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_source_port, _policy, port, protocol ++ ) ++ self.addTimeout(tag, ("source_port", _policy, port, protocol)) ++ + if use_transaction is None: + transaction.execute(True) + +@@ -930,6 +936,8 @@ class FirewallPolicy(object): + port_id = self.__source_port_id(range, protocol) + transaction.add_post(self.__unregister_source_port, _obj, port_id) + ++ self.removeTimeout(("source_port", _policy, port, protocol)) ++ + if use_transaction is None: + transaction.execute(True) + +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 939fb687a7af..75fa486f0f92 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1787,14 +1787,6 @@ class FirewallD(DbusServiceObject): + + # SOURCE PORTS + +- @dbus_handle_exceptions +- def disableTimedSourcePort(self, zone, port, protocol): +- log.debug1("zone.disableTimedSourcePort('%s', '%s', '%s')" % \ +- (zone, port, protocol)) +- del self._timeouts[zone][("sport", port, protocol)] +- self.fw.zone.remove_source_port(zone, port, protocol) +- self.SourcePortRemoved(zone, port, protocol) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssi', + out_signature='s') +@@ -1812,9 +1804,9 @@ class FirewallD(DbusServiceObject): + sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedSourcePort, +- _zone, port, protocol) +- self.addTimeout(_zone, ("sport", port, protocol), tag) ++ GLib.timeout_add_seconds( ++ timeout, self.SourcePortRemoved, _zone, port, protocol ++ ) + + self.SourcePortAdded(_zone, port, protocol, timeout) + return _zone +@@ -1833,7 +1825,6 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + _zone= self.fw.zone.remove_source_port(zone, port, protocol) + +- self.removeTimeout(_zone, ("sport", port, protocol)) + self.SourcePortRemoved(_zone, port, protocol) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0055-v2.5.0-chore-zone-forward_port-move-timeouts-to-poli.patch b/SOURCES/0055-v2.5.0-chore-zone-forward_port-move-timeouts-to-poli.patch new file mode 100644 index 0000000..c3fe6af --- /dev/null +++ b/SOURCES/0055-v2.5.0-chore-zone-forward_port-move-timeouts-to-poli.patch @@ -0,0 +1,91 @@ +From c53903f8b42673451a22992a4b1199ad5e554533 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 15:03:21 -0500 +Subject: [PATCH 55/70] v2.5.0: chore(zone): forward_port: move timeouts to + policy + +(cherry picked from commit b7f543d71b25218eb6cdabf78fdb678507201400) +--- + src/firewall/core/fw_policy.py | 18 ++++++++++++++++++ + src/firewall/server/firewalld.py | 15 +++------------ + 2 files changed, 21 insertions(+), 12 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index ee652d892d4a..70ca2ecf20d3 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -1068,6 +1068,20 @@ class FirewallPolicy(object): + self._forward_port(True, _policy, transaction, port, protocol, + toport, toaddr) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, ++ self.remove_forward_port, ++ _policy, ++ port, ++ protocol, ++ toport, ++ toaddr, ++ ) ++ self.addTimeout( ++ tag, ("forward_port", _policy, port, protocol, toport, toaddr) ++ ) ++ + self.__register_forward_port(_obj, forward_id, timeout, sender) + transaction.add_fail(self.__unregister_forward_port, _obj, forward_id) + +@@ -1101,6 +1115,10 @@ class FirewallPolicy(object): + self._forward_port(False, _policy, transaction, port, protocol, + toport, toaddr) + ++ self.removeTimeout( ++ ("forward_port", _policy, port, protocol, toport, toaddr) ++ ) ++ + transaction.add_post(self.__unregister_forward_port, _obj, forward_id) + + if use_transaction is None: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 75fa486f0f92..66321939237f 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1934,12 +1934,6 @@ class FirewallD(DbusServiceObject): + + # FORWARD PORT + +- @dbus_handle_exceptions +- def disable_forward_port(self, zone, port, protocol, toport, toaddr): # pylint: disable=R0913 +- del self._timeouts[zone][(port, protocol, toport, toaddr)] +- self.fw.zone.remove_forward_port(zone, port, protocol, toport, toaddr) +- self.ForwardPortRemoved(zone, port, protocol, toport, toaddr) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='sssssi', + out_signature='s') +@@ -1960,11 +1954,9 @@ class FirewallD(DbusServiceObject): + toaddr, timeout, sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, +- self.disable_forward_port, +- _zone, port, protocol, toport, +- toaddr) +- self.addTimeout(_zone, (port, protocol, toport, toaddr), tag) ++ GLib.timeout_add_seconds( ++ timeout, self.ForwardPortRemoved, _zone, port, protocol, toport, toaddr ++ ) + + self.ForwardPortAdded(_zone, port, protocol, toport, toaddr, timeout) + return _zone +@@ -1987,7 +1979,6 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.remove_forward_port(zone, port, protocol, toport, + toaddr) + +- self.removeTimeout(_zone, (port, protocol, toport, toaddr)) + self.ForwardPortRemoved(_zone, port, protocol, toport, toaddr) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0056-v2.5.0-chore-zone-icmp_block-move-timeouts-to-policy.patch b/SOURCES/0056-v2.5.0-chore-zone-icmp_block-move-timeouts-to-policy.patch new file mode 100644 index 0000000..198aa43 --- /dev/null +++ b/SOURCES/0056-v2.5.0-chore-zone-icmp_block-move-timeouts-to-policy.patch @@ -0,0 +1,78 @@ +From 45175cdb284572a7a888ee285aa8a645e41dd448 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:27:17 -0500 +Subject: [PATCH 56/70] v2.5.0: chore(zone): icmp_block: move timeouts to + policy + +(cherry picked from commit 426ba555b74958a3e43a62c2f0da4013b408fb05) +--- + src/firewall/core/fw_policy.py | 8 ++++++++ + src/firewall/server/firewalld.py | 12 +----------- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 70ca2ecf20d3..5382c9c51ef5 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -1168,6 +1168,12 @@ class FirewallPolicy(object): + if _obj.applied: + self._icmp_block(True, _policy, icmp, transaction) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_icmp_block, _policy, icmp ++ ) ++ self.addTimeout(tag, ("icmp_block", _policy, icmp)) ++ + self.__register_icmp_block(_obj, icmp_id, timeout, sender) + transaction.add_fail(self.__unregister_icmp_block, _obj, icmp_id) + +@@ -1198,6 +1204,8 @@ class FirewallPolicy(object): + if _obj.applied: + self._icmp_block(False, _policy, icmp, transaction) + ++ self.removeTimeout(("icmp_block", _policy, icmp)) ++ + transaction.add_post(self.__unregister_icmp_block, _obj, icmp_id) + + if use_transaction is None: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 66321939237f..913c9a8e173a 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -2028,13 +2028,6 @@ class FirewallD(DbusServiceObject): + + # ICMP BLOCK + +- @dbus_handle_exceptions +- def disableTimedIcmpBlock(self, zone, icmp, sender): # pylint: disable=W0613 +- log.debug1("zone.disableTimedIcmpBlock('%s', '%s')" % (zone, icmp)) +- del self._timeouts[zone][icmp] +- self.fw.zone.remove_icmp_block(zone, icmp) +- self.IcmpBlockRemoved(zone, icmp) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi', + out_signature='s') +@@ -2049,9 +2042,7 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.add_icmp_block(zone, icmp, timeout, sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedIcmpBlock, +- _zone, icmp, sender) +- self.addTimeout(_zone, icmp, tag) ++ GLib.timeout_add_seconds(timeout, self.IcmpBlockRemoved, _zone, icmp) + + self.IcmpBlockAdded(_zone, icmp, timeout) + return _zone +@@ -2068,7 +2059,6 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + _zone = self.fw.zone.remove_icmp_block(zone, icmp) + +- self.removeTimeout(_zone, icmp) + self.IcmpBlockRemoved(_zone, icmp) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0057-v2.5.0-chore-zone-masquerade-move-timeouts-to-policy.patch b/SOURCES/0057-v2.5.0-chore-zone-masquerade-move-timeouts-to-policy.patch new file mode 100644 index 0000000..1ccb0ac --- /dev/null +++ b/SOURCES/0057-v2.5.0-chore-zone-masquerade-move-timeouts-to-policy.patch @@ -0,0 +1,75 @@ +From b6cbb249a6342749c52c24978ff1fb6411bef729 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:35:02 -0500 +Subject: [PATCH 57/70] v2.5.0: chore(zone): masquerade: move timeouts to + policy + +(cherry picked from commit ef995448e43cdd307b6ff74f081e7db100add6c7) +--- + src/firewall/core/fw_policy.py | 6 ++++++ + src/firewall/server/firewalld.py | 11 +---------- + 2 files changed, 7 insertions(+), 10 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 5382c9c51ef5..ebb052e9caa2 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -979,6 +979,10 @@ class FirewallPolicy(object): + if _obj.applied: + self._masquerade(True, _policy, transaction) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds(timeout, self.remove_masquerade, _policy) ++ self.addTimeout(tag, ("masquerade", _policy)) ++ + self.__register_masquerade(_obj, timeout, sender) + transaction.add_fail(self.__unregister_masquerade, _obj) + +@@ -1008,6 +1012,8 @@ class FirewallPolicy(object): + if _obj.applied: + self._masquerade(False, _policy, transaction) + ++ self.removeTimeout(("masquerade", _policy)) ++ + transaction.add_post(self.__unregister_masquerade, _obj) + + if use_transaction is None: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 913c9a8e173a..b7ced6143734 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1869,12 +1869,6 @@ class FirewallD(DbusServiceObject): + + # MASQUERADE + +- @dbus_handle_exceptions +- def disableTimedMasquerade(self, zone): +- del self._timeouts[zone]["masquerade"] +- self.fw.zone.remove_masquerade(zone) +- self.MasqueradeRemoved(zone) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='si', + out_signature='s') +@@ -1888,9 +1882,7 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.add_masquerade(zone, timeout, sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedMasquerade, +- _zone) +- self.addTimeout(_zone, "masquerade", tag) ++ GLib.timeout_add_seconds(timeout, self.MasqueradeRemoved, _zone) + + self.MasqueradeAdded(_zone, timeout) + return _zone +@@ -1906,7 +1898,6 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + _zone = self.fw.zone.remove_masquerade(zone) + +- self.removeTimeout(_zone, "masquerade") + self.MasqueradeRemoved(_zone) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0058-v2.5.0-chore-zone-protocol-move-timeouts-to-policy.patch b/SOURCES/0058-v2.5.0-chore-zone-protocol-move-timeouts-to-policy.patch new file mode 100644 index 0000000..6909a79 --- /dev/null +++ b/SOURCES/0058-v2.5.0-chore-zone-protocol-move-timeouts-to-policy.patch @@ -0,0 +1,77 @@ +From 331c2e576dac97695fe51d9dce3b24093adfdfb5 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:59:53 -0500 +Subject: [PATCH 58/70] v2.5.0: chore(zone): protocol: move timeouts to policy + +(cherry picked from commit 7ff66d7690f629947c96863b3980efc22b439406) +--- + src/firewall/core/fw_policy.py | 8 ++++++++ + src/firewall/server/firewalld.py | 12 +----------- + 2 files changed, 9 insertions(+), 11 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index ebb052e9caa2..b477f62f640c 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -796,6 +796,12 @@ class FirewallPolicy(object): + if _obj.applied: + self._protocol(True, _policy, protocol, transaction) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_protocol, _policy, protocol ++ ) ++ self.addTimeout(tag, ("protocol", _policy, protocol)) ++ + self.__register_protocol(_obj, protocol_id, timeout, sender) + transaction.add_fail(self.__unregister_protocol, _obj, protocol_id) + +@@ -827,6 +833,8 @@ class FirewallPolicy(object): + if _obj.applied: + self._protocol(False, _policy, protocol, transaction) + ++ self.removeTimeout(("protocol", _policy, protocol)) ++ + transaction.add_post(self.__unregister_protocol, _obj, + protocol_id) + +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index b7ced6143734..ab3078b2e8b9 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1705,13 +1705,6 @@ class FirewallD(DbusServiceObject): + + # PROTOCOLS + +- @dbus_handle_exceptions +- def disableTimedProtocol(self, zone, protocol): +- log.debug1("zone.disableTimedProtocol('%s', '%s')" % (zone, protocol)) +- del self._timeouts[zone][(protocol)] +- self.fw.zone.remove_protocol(zone, protocol) +- self.ProtocolRemoved(zone, protocol) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi', + out_signature='s') +@@ -1726,9 +1719,7 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.add_protocol(zone, protocol, timeout, sender) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedProtocol, +- _zone, protocol) +- self.addTimeout(_zone, protocol, tag) ++ GLib.timeout_add_seconds(timeout, self.ProtocolRemoved, _zone, protocol) + + self.ProtocolAdded(_zone, protocol, timeout) + return _zone +@@ -1745,7 +1736,6 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + _zone= self.fw.zone.remove_protocol(zone, protocol) + +- self.removeTimeout(_zone, protocol) + self.ProtocolRemoved(_zone, protocol) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0059-v2.5.0-chore-zone-rule-move-timeouts-to-policy.patch b/SOURCES/0059-v2.5.0-chore-zone-rule-move-timeouts-to-policy.patch new file mode 100644 index 0000000..afce975 --- /dev/null +++ b/SOURCES/0059-v2.5.0-chore-zone-rule-move-timeouts-to-policy.patch @@ -0,0 +1,76 @@ +From 0037599863132394bddfe2e609e4c8c3786627a1 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 16:29:05 -0500 +Subject: [PATCH 59/70] v2.5.0: chore(zone): rule: move timeouts to policy + +(cherry picked from commit cd928486a31b8fbe98a25f1a682cac2c5f9226d3) +--- + src/firewall/core/fw_policy.py | 6 ++++++ + src/firewall/server/firewalld.py | 13 +------------ + 2 files changed, 7 insertions(+), 12 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index b477f62f640c..6203824166c3 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -478,6 +478,10 @@ class FirewallPolicy(object): + if _obj.applied: + self.__rule(True, _policy, rule, transaction) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds(timeout, self.remove_rule, _policy, rule) ++ self.addTimeout(tag, ("rule", _policy, rule)) ++ + self.__register_rule(_obj, rule_id, timeout, sender) + transaction.add_fail(self.__unregister_rule, _obj, rule_id) + +@@ -509,6 +513,8 @@ class FirewallPolicy(object): + if _obj.applied: + self.__rule(False, _policy, rule, transaction) + ++ self.removeTimeout(("rule", _policy, rule)) ++ + transaction.add_post(self.__unregister_rule, _obj, rule_id) + + if use_transaction is None: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index ab3078b2e8b9..48429bc8061a 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -1474,14 +1474,6 @@ class FirewallD(DbusServiceObject): + + # RICH RULES + +- @dbus_handle_exceptions +- def disableTimedRichRule(self, zone, rule): +- log.debug1("zone.disableTimedRichRule('%s', '%s')" % (zone, rule)) +- del self._timeouts[zone][rule] +- obj = Rich_Rule(rule_str=rule) +- self.fw.zone.remove_rule(zone, obj) +- self.RichRuleRemoved(zone, rule) +- + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG) + @dbus_service_method(config.dbus.DBUS_INTERFACE_ZONE, in_signature='ssi', + out_signature='s') +@@ -1495,9 +1487,7 @@ class FirewallD(DbusServiceObject): + _zone = self.fw.zone.add_rule(zone, obj, timeout) + + if timeout > 0: +- tag = GLib.timeout_add_seconds(timeout, self.disableTimedRichRule, +- _zone, rule) +- self.addTimeout(_zone, rule, tag) ++ GLib.timeout_add_seconds(timeout, self.RichRuleRemoved, _zone, rule) + + self.RichRuleAdded(_zone, rule, timeout) + return _zone +@@ -1512,7 +1502,6 @@ class FirewallD(DbusServiceObject): + log.debug1("zone.removeRichRule('%s', '%s')" % (zone, rule)) + obj = Rich_Rule(rule_str=rule) + _zone = self.fw.zone.remove_rule(zone, obj) +- self.removeTimeout(_zone, rule) + self.RichRuleRemoved(_zone, rule) + return _zone + +-- +2.52.0 + diff --git a/SOURCES/0060-v2.5.0-chore-zone-remove-daemon-level-timeout-code.patch b/SOURCES/0060-v2.5.0-chore-zone-remove-daemon-level-timeout-code.patch new file mode 100644 index 0000000..61eb8a4 --- /dev/null +++ b/SOURCES/0060-v2.5.0-chore-zone-remove-daemon-level-timeout-code.patch @@ -0,0 +1,49 @@ +From 475eb2107544a4c8ef113db4a81bf1363247180c Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 16:29:50 -0500 +Subject: [PATCH 60/70] v2.5.0: chore(zone): remove daemon level timeout code + +As its no longer used. + +(cherry picked from commit 537af3fcb09bec296869d9ee23c4d4b9b2b72141) +--- + src/firewall/server/firewalld.py | 23 ----------------------- + 1 file changed, 23 deletions(-) + +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index 48429bc8061a..cb786b63f93f 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -127,29 +127,6 @@ class FirewallD(DbusServiceObject): + return + raise FirewallError(errors.ACCESS_DENIED, "lockdown is enabled") + +- # timeout functions +- +- @dbus_handle_exceptions +- def addTimeout(self, zone, x, tag): +- if zone not in self._timeouts: +- self._timeouts[zone] = { } +- self._timeouts[zone][x] = tag +- +- @dbus_handle_exceptions +- def removeTimeout(self, zone, x): +- if zone in self._timeouts and x in self._timeouts[zone]: +- GLib.source_remove(self._timeouts[zone][x]) +- del self._timeouts[zone][x] +- +- @dbus_handle_exceptions +- def cleanup_timeouts(self): +- # cleanup timeouts +- for zone in self._timeouts: +- for x in self._timeouts[zone]: +- GLib.source_remove(self._timeouts[zone][x]) +- self._timeouts[zone].clear() +- self._timeouts.clear() +- + # property handling + + @dbus_handle_exceptions +-- +2.52.0 + diff --git a/SOURCES/0061-v2.5.0-chore-fw_zone-add-utility-functions-to-suppor.patch b/SOURCES/0061-v2.5.0-chore-fw_zone-add-utility-functions-to-suppor.patch new file mode 100644 index 0000000..c6a3227 --- /dev/null +++ b/SOURCES/0061-v2.5.0-chore-fw_zone-add-utility-functions-to-suppor.patch @@ -0,0 +1,51 @@ +From dde93f3310f79a1f739c8e7400831bf4e1b78df6 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 16:34:17 -0500 +Subject: [PATCH 61/70] v2.5.0: chore(fw_zone): add utility functions to + support timeouts + +(cherry picked from commit 9f3c28e065543935a6f3c7c62e336ec0a866b1c6) +--- + src/firewall/core/fw_zone.py | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index 6c659047b97d..f55be13f8fd3 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -49,6 +49,7 @@ class FirewallZone(object): + self._fw = fw + self._zones = { } + self._zone_policies = { } ++ self._timeouts = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__, self._zones) +@@ -56,6 +57,8 @@ class FirewallZone(object): + def cleanup(self): + self._zones.clear() + self._zone_policies.clear() ++ for _id in self._timeouts: ++ self.removeTimeout(_id) + + def new_transaction(self): + t = FirewallTransaction(self._fw) +@@ -400,6 +403,15 @@ class FirewallZone(object): + else: + setting_to_fn[key][0](zone, timeout=0, sender=sender) + ++ def addTimeout(self, tag, _id): ++ if _id not in self._timeouts: ++ self._timeouts[_id] = tag ++ ++ def removeTimeout(self, _id): ++ if _id in self._timeouts: ++ GLib.source_remove(self._timeouts[_id]) ++ del self._timeouts[_id] ++ + # INTERFACES + + def check_interface(self, interface): +-- +2.52.0 + diff --git a/SOURCES/0062-v2.5.0-chore-fw_zone-support-timeouts-via-dict-API.patch b/SOURCES/0062-v2.5.0-chore-fw_zone-support-timeouts-via-dict-API.patch new file mode 100644 index 0000000..eafaaad --- /dev/null +++ b/SOURCES/0062-v2.5.0-chore-fw_zone-support-timeouts-via-dict-API.patch @@ -0,0 +1,78 @@ +From b26be86bdad0c269254f3008421480edd186cde4 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:39:47 -0500 +Subject: [PATCH 62/70] v2.5.0: chore(fw_zone): support timeouts via dict API + +(cherry picked from commit 24476b6820f36cc31ba0b7fc36e63acb07ba66a5) +--- + src/firewall/core/fw_zone.py | 14 +++++++++++--- + src/firewall/server/firewalld.py | 9 +++++++++ + 2 files changed, 20 insertions(+), 3 deletions(-) + +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index f55be13f8fd3..de01aeb30a59 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -365,6 +365,12 @@ class FirewallZone(object): + "forward": (self.add_forward, self.remove_forward), + } + ++ timeout = 0 ++ if "timeout" in settings: ++ timeout = settings["timeout"] ++ settings = copy.copy(settings) ++ del settings["timeout"] ++ + # do a full config check on a temporary object before trying to make + # the runtime changes + old_obj = self.get_zone(zone) +@@ -393,15 +399,17 @@ class FirewallZone(object): + setting_to_fn[key][0](zone, args, sender=sender) + else: + if isinstance(args, tuple): +- setting_to_fn[key][0](zone, *args, timeout=0, sender=sender) ++ setting_to_fn[key][0]( ++ zone, *args, timeout=timeout, sender=sender ++ ) + else: +- setting_to_fn[key][0](zone, args, timeout=0, sender=sender) ++ setting_to_fn[key][0](zone, args, timeout=timeout, sender=sender) + else: # bool + if key in ["icmp_block_inversion"]: + # no timeout arg + setting_to_fn[key][0](zone, sender=sender) + else: +- setting_to_fn[key][0](zone, timeout=0, sender=sender) ++ setting_to_fn[key][0](zone, timeout=timeout, sender=sender) + + def addTimeout(self, tag, _id): + if _id not in self._timeouts: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index cb786b63f93f..d796c1d45e9c 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -939,12 +939,21 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + self.fw.zone.set_config_with_settings_dict(zone, dbus_to_python(settings), sender) + self.ZoneUpdated(zone, settings) ++ if "timeout" in settings and settings["timeout"] > 0: ++ GLib.timeout_add_seconds( ++ settings["timeout"], ++ self.ZoneUpdatedCurrentSettings, ++ zone, ++ ) + + @dbus.service.signal(config.dbus.DBUS_INTERFACE_ZONE, signature='sa{sv}') + @dbus_handle_exceptions + def ZoneUpdated(self, zone, settings): + log.debug1("zone.ZoneUpdated('%s', '%s')" % (zone, settings)) + ++ def ZoneUpdatedCurrentSettings(self, zone): ++ self.ZoneUpdated(zone, self.fw.zone.get_config_with_settings_dict(zone)) ++ + @dbus_polkit_require_auth(config.dbus.PK_ACTION_CONFIG_INFO) + @dbus_service_method(config.dbus.DBUS_INTERFACE_POLICY, in_signature='s', + out_signature="a{sv}") +-- +2.52.0 + diff --git a/SOURCES/0063-v2.5.0-fix-zone-forward-support-timeout.patch b/SOURCES/0063-v2.5.0-fix-zone-forward-support-timeout.patch new file mode 100644 index 0000000..537e661 --- /dev/null +++ b/SOURCES/0063-v2.5.0-fix-zone-forward-support-timeout.patch @@ -0,0 +1,76 @@ +From 567de9771d0a916d2c2a6895d5bce4e764eefe66 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 20 Nov 2025 15:49:04 -0500 +Subject: [PATCH 63/70] v2.5.0: fix(zone): forward: support timeout + +(cherry picked from commit f1c9f6ad8c22d47906ef57ac67a7af773b783bb8) +--- + src/firewall-cmd.in | 2 +- + src/firewall/client.py | 4 ++-- + src/firewall/core/fw_zone.py | 8 ++++++++ + 3 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/src/firewall-cmd.in b/src/firewall-cmd.in +index 755e25e1c1ae..eb0ac7e48e3c 100755 +--- a/src/firewall-cmd.in ++++ b/src/firewall-cmd.in +@@ -3086,7 +3086,7 @@ elif a.query_source_port: + + # forward + elif a.add_forward: +- fw.addForward(zone) ++ fw.addForward(zone, a.timeout) + elif a.remove_forward: + fw.removeForward(zone) + elif a.query_forward: +diff --git a/src/firewall/client.py b/src/firewall/client.py +index c710df1b6edf..268a4a947da9 100644 +--- a/src/firewall/client.py ++++ b/src/firewall/client.py +@@ -3432,8 +3432,8 @@ class FirewallClient(object): + # forward + + @handle_exceptions +- def addForward(self, zone): +- self.fw_zone.setZoneSettings2(zone, {"forward": True}) ++ def addForward(self, zone, timeout=0): ++ self.fw_zone.setZoneSettings2(zone, {"forward": True, "timeout": timeout}) + + @handle_exceptions + def queryForward(self, zone): +diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py +index de01aeb30a59..302b87267c1d 100644 +--- a/src/firewall/core/fw_zone.py ++++ b/src/firewall/core/fw_zone.py +@@ -19,6 +19,8 @@ + # along with this program. If not, see . + # + ++from gi.repository import GLib ++ + import copy + from firewall.core.base import SHORTCUTS, DEFAULT_ZONE_TARGET, SOURCE_IPSET_TYPES + from firewall.core.fw_transaction import FirewallTransaction +@@ -1043,6 +1045,10 @@ class FirewallZone(object): + if _obj.applied: + self._forward(True, _zone, transaction) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds(timeout, self.remove_forward, _zone) ++ self.addTimeout(tag, ("forward", _zone)) ++ + self.__register_forward(_obj, timeout, sender) + transaction.add_fail(self.__unregister_forward, _obj) + +@@ -1071,6 +1077,8 @@ class FirewallZone(object): + if _obj.applied: + self._forward(False, _zone, transaction) + ++ self.removeTimeout(("forward", _zone)) ++ + transaction.add_post(self.__unregister_forward, _obj) + + if use_transaction is None: +-- +2.52.0 + diff --git a/SOURCES/0064-v2.5.0-test-zone-forward-move-test-to-features.patch b/SOURCES/0064-v2.5.0-test-zone-forward-move-test-to-features.patch new file mode 100644 index 0000000..09c6d4e --- /dev/null +++ b/SOURCES/0064-v2.5.0-test-zone-forward-move-test-to-features.patch @@ -0,0 +1,418 @@ +From 7d010783dbecf7d5286d777d9197e253dc07fef7 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 20 Nov 2025 15:25:02 -0500 +Subject: [PATCH 64/70] v2.5.0: test(zone): forward: move test to features + +(cherry picked from commit db12155f6e9446b8e05d237d9f1e6998eae89f67) +--- + src/tests/cli/firewall-cmd.at | 188 ----------------------------- + src/tests/features/features.at | 1 + + src/tests/features/zone_forward.at | 188 +++++++++++++++++++++++++++++ + 3 files changed, 189 insertions(+), 188 deletions(-) + create mode 100644 src/tests/features/zone_forward.at + +diff --git a/src/tests/cli/firewall-cmd.at b/src/tests/cli/firewall-cmd.at +index 4f45774bbc4a..5638e3ec65ca 100644 +--- a/src/tests/cli/firewall-cmd.at ++++ b/src/tests/cli/firewall-cmd.at +@@ -505,194 +505,6 @@ FWD_START_TEST([masquerade]) + FWD_CHECK([--permanent --query-masquerade], 1, ignore) + FWD_END_TEST + +-FWD_START_TEST([forward]) +- AT_KEYWORDS(forward gh586 gh613) +- +- FWD_CHECK([--zone=home --add-interface=dummy --add-interface=dummy2], 0, ignore) +- FWD_CHECK([--zone=home --add-forward], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_home_allow { +- oifname "dummy" accept +- oifname "dummy2" accept +- } +- } +- ]) +- dnl These two ipXtables rules correspond to: +- dnl -A FWD_home_allow -o dummy -j ACCEPT +- dnl -A FWD_home_allow -o dummy2 -j ACCEPT +- dnl although we can't assert the interface names because they don't +- dnl appear in these rule listings, unfortunately... +- IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- ::/0 ::/0 +- ACCEPT 0 -- ::/0 ::/0 +- ]) +- dnl Forward rules should be updated when the interfaces change +- FWD_CHECK([--zone=home --remove-interface=dummy2], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_home_allow { +- oifname "dummy" accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- ::/0 ::/0 +- ]) +- FWD_CHECK([--zone=home --add-interface=dummy3], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_home_allow { +- oifname "dummy" accept +- oifname "dummy3" accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- ::/0 ::/0 +- ACCEPT 0 -- ::/0 ::/0 +- ]) +- FWD_CHECK([--zone=home --query-forward], 0, ignore) +- FWD_CHECK([--zone=home --remove-forward], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_home_allow { +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ]) +- FWD_CHECK([--zone=home --query-forward], 1, ignore) +- FWD_CHECK([--zone=home --remove-interface=dummy --remove-interface=dummy3], 0, ignore) +- +- FWD_CHECK([--permanent --zone=home --add-forward], 0, ignore) +- FWD_CHECK([-q --permanent --zone=home --add-interface=dummy --add-interface=dummy3]) +- FWD_CHECK([-q --permanent --zone=home --add-source=10.10.10.0/24]) +- FWD_RELOAD +- FWD_CHECK([--permanent --zone=home --query-forward], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_home_allow { +- oifname "dummy" accept +- oifname "dummy3" accept +- ip daddr 10.10.10.0/24 accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl +- ACCEPT 0 -- ::/0 ::/0 +- ACCEPT 0 -- ::/0 ::/0 +- ]) +- FWD_CHECK([--permanent --zone=home --remove-forward], 0, ignore) +- FWD_CHECK([--permanent --zone=home --query-forward], 1, ignore) +- FWD_CHECK([-q --permanent --zone=home --remove-interface=dummy --remove-interface=dummy3]) +- FWD_CHECK([-q --permanent --zone=home --remove-source=10.10.10.0/24]) +- FWD_RELOAD +- +- dnl verify enabled in default zone doesn't add a wildcard/catch-all entry +- FWD_CHECK([--get-default-zone |grep public], 0, [ignore]) +- FWD_CHECK([-q --add-interface dummy4]) +- FWD_CHECK([-q --add-forward]) +- NFT_LIST_RULES([inet], [filter_FWD_public_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_public_allow { +- oifname "dummy4" accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_public_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_public_allow], 0, [dnl +- ACCEPT 0 -- ::/0 ::/0 +- ]) +- +- dnl zone source +- FWD_CHECK([--zone=internal --add-source=10.10.10.0/24], 0, ignore) +- IF_HOST_SUPPORTS_IPV6_RULES([ +- FWD_CHECK([--zone=internal --add-source=1234::/64], 0, ignore) +- ]) +- FWD_CHECK([--zone=internal --add-forward], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_internal_allow { +- ip daddr 10.10.10.0/24 accept +- ip6 daddr 1234::/64 accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ACCEPT 0 -- ::/0 1234::/64 +- ]) +- IF_HOST_SUPPORTS_IPV6_RULES([ +- FWD_CHECK([--zone=internal --remove-source=1234::/64], 0, ignore) +- ]) +- NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_internal_allow { +- ip daddr 10.10.10.0/24 accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ]) +- FWD_CHECK([--zone=internal --add-source=10.20.20.0/24], 0, ignore) +- IF_HOST_SUPPORTS_IPV6_RULES([ +- FWD_CHECK([--zone=internal --add-source=4321::/64], 0, ignore) +- ]) +- NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_internal_allow { +- ip daddr 10.10.10.0/24 accept +- ip daddr 10.20.20.0/24 accept +- ip6 daddr 4321::/64 accept +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 +- ACCEPT 0 -- 0.0.0.0/0 10.20.20.0/24 +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ACCEPT 0 -- ::/0 4321::/64 +- ]) +- FWD_CHECK([--zone=internal --remove-forward], 0, ignore) +- NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl +- table inet firewalld { +- chain filter_FWD_internal_allow { +- } +- } +- ]) +- IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ]) +- IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl +- ]) +-FWD_END_TEST +- + FWD_START_TEST([forward ports]) + AT_KEYWORDS(port forward_port) + +diff --git a/src/tests/features/features.at b/src/tests/features/features.at +index 83ad9d122189..8f7c6bcafec7 100644 +--- a/src/tests/features/features.at ++++ b/src/tests/features/features.at +@@ -22,3 +22,4 @@ m4_include([features/reset_defaults.at]) + m4_include([features/iptables_no_flush_on_shutdown.at]) + m4_include([features/reloadpolicy.at]) + m4_include([features/nftables_table_owner.at]) ++m4_include([features/zone_forward.at]) +diff --git a/src/tests/features/zone_forward.at b/src/tests/features/zone_forward.at +new file mode 100644 +index 000000000000..79129cee5192 +--- /dev/null ++++ b/src/tests/features/zone_forward.at +@@ -0,0 +1,188 @@ ++FWD_START_TEST([zone - forward]) ++AT_KEYWORDS(forward gh586 gh613) ++ ++FWD_CHECK([--zone=home --add-interface=dummy --add-interface=dummy2], 0, ignore) ++FWD_CHECK([--zone=home --add-forward], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_home_allow { ++ oifname "dummy" accept ++ oifname "dummy2" accept ++ } ++ } ++]) ++dnl These two ipXtables rules correspond to: ++dnl -A FWD_home_allow -o dummy -j ACCEPT ++dnl -A FWD_home_allow -o dummy2 -j ACCEPT ++dnl although we can't assert the interface names because they don't ++dnl appear in these rule listings, unfortunately... ++IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 ::/0 ++ ACCEPT 0 -- ::/0 ::/0 ++]) ++dnl Forward rules should be updated when the interfaces change ++FWD_CHECK([--zone=home --remove-interface=dummy2], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_home_allow { ++ oifname "dummy" accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 ::/0 ++]) ++FWD_CHECK([--zone=home --add-interface=dummy3], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_home_allow { ++ oifname "dummy" accept ++ oifname "dummy3" accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 ::/0 ++ ACCEPT 0 -- ::/0 ::/0 ++]) ++FWD_CHECK([--zone=home --query-forward], 0, ignore) ++FWD_CHECK([--zone=home --remove-forward], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_home_allow { ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++]) ++FWD_CHECK([--zone=home --query-forward], 1, ignore) ++FWD_CHECK([--zone=home --remove-interface=dummy --remove-interface=dummy3], 0, ignore) ++ ++FWD_CHECK([--permanent --zone=home --add-forward], 0, ignore) ++FWD_CHECK([-q --permanent --zone=home --add-interface=dummy --add-interface=dummy3]) ++FWD_CHECK([-q --permanent --zone=home --add-source=10.10.10.0/24]) ++FWD_RELOAD ++FWD_CHECK([--permanent --zone=home --query-forward], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_home_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_home_allow { ++ oifname "dummy" accept ++ oifname "dummy3" accept ++ ip daddr 10.10.10.0/24 accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++ ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_home_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 ::/0 ++ ACCEPT 0 -- ::/0 ::/0 ++]) ++FWD_CHECK([--permanent --zone=home --remove-forward], 0, ignore) ++FWD_CHECK([--permanent --zone=home --query-forward], 1, ignore) ++FWD_CHECK([-q --permanent --zone=home --remove-interface=dummy --remove-interface=dummy3]) ++FWD_CHECK([-q --permanent --zone=home --remove-source=10.10.10.0/24]) ++FWD_RELOAD ++ ++dnl verify enabled in default zone doesn't add a wildcard/catch-all entry ++FWD_CHECK([--get-default-zone |grep public], 0, [ignore]) ++FWD_CHECK([-q --add-interface dummy4]) ++FWD_CHECK([-q --add-forward]) ++NFT_LIST_RULES([inet], [filter_FWD_public_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_public_allow { ++ oifname "dummy4" accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_public_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_public_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 ::/0 ++]) ++ ++dnl zone source ++FWD_CHECK([--zone=internal --add-source=10.10.10.0/24], 0, ignore) ++IF_HOST_SUPPORTS_IPV6_RULES([ ++FWD_CHECK([--zone=internal --add-source=1234::/64], 0, ignore) ++]) ++FWD_CHECK([--zone=internal --add-forward], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_internal_allow { ++ ip daddr 10.10.10.0/24 accept ++ ip6 daddr 1234::/64 accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 1234::/64 ++]) ++IF_HOST_SUPPORTS_IPV6_RULES([ ++FWD_CHECK([--zone=internal --remove-source=1234::/64], 0, ignore) ++]) ++NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_internal_allow { ++ ip daddr 10.10.10.0/24 accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++]) ++FWD_CHECK([--zone=internal --add-source=10.20.20.0/24], 0, ignore) ++IF_HOST_SUPPORTS_IPV6_RULES([ ++FWD_CHECK([--zone=internal --add-source=4321::/64], 0, ignore) ++]) ++NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_internal_allow { ++ ip daddr 10.10.10.0/24 accept ++ ip daddr 10.20.20.0/24 accept ++ ip6 daddr 4321::/64 accept ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++ ACCEPT 0 -- 0.0.0.0/0 10.10.10.0/24 ++ ACCEPT 0 -- 0.0.0.0/0 10.20.20.0/24 ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++ ACCEPT 0 -- ::/0 4321::/64 ++]) ++FWD_CHECK([--zone=internal --remove-forward], 0, ignore) ++NFT_LIST_RULES([inet], [filter_FWD_internal_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_internal_allow { ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++]) ++IP6TABLES_LIST_RULES([filter], [FWD_internal_allow], 0, [dnl ++]) ++ ++FWD_END_TEST() +-- +2.52.0 + diff --git a/SOURCES/0065-v2.5.0-test-zone-verify-timeout-works.patch b/SOURCES/0065-v2.5.0-test-zone-verify-timeout-works.patch new file mode 100644 index 0000000..59c1e80 --- /dev/null +++ b/SOURCES/0065-v2.5.0-test-zone-verify-timeout-works.patch @@ -0,0 +1,214 @@ +From 5419b3e69790b4ee2c106d01bc7fba64ba6a2c6f Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 20 Nov 2025 15:29:07 -0500 +Subject: [PATCH 65/70] v2.5.0: test(zone): verify timeout works + +(cherry picked from commit 6214af87870637383671c45ad954be1ebae29c8e) +--- + src/tests/features/features.at | 1 + + src/tests/features/zone_timeout.at | 184 +++++++++++++++++++++++++++++ + 2 files changed, 185 insertions(+) + create mode 100644 src/tests/features/zone_timeout.at + +diff --git a/src/tests/features/features.at b/src/tests/features/features.at +index 8f7c6bcafec7..2867132f7b08 100644 +--- a/src/tests/features/features.at ++++ b/src/tests/features/features.at +@@ -23,3 +23,4 @@ m4_include([features/iptables_no_flush_on_shutdown.at]) + m4_include([features/reloadpolicy.at]) + m4_include([features/nftables_table_owner.at]) + m4_include([features/zone_forward.at]) ++m4_include([features/zone_timeout.at]) +diff --git a/src/tests/features/zone_timeout.at b/src/tests/features/zone_timeout.at +new file mode 100644 +index 000000000000..c0ef68c7cefb +--- /dev/null ++++ b/src/tests/features/zone_timeout.at +@@ -0,0 +1,184 @@ ++m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ ++FWD_START_TEST([zone - timeouts]) ++AT_KEYWORDS(zone timeout) ++ ++FWD_CHECK([--permanent --zone trusted --add-icmp-block-inversion], 0, [ignore]) ++FWD_CHECK([--permanent --zone trusted --add-interface foobar], 0, [ignore]) ++FWD_CHECK([--permanent --zone trusted --remove-forward], 0, [ignore]) ++FWD_RELOAD() ++ ++dnl $1 = firewall-cmd args ++dnl $2 = nftables expected input chain rules ++dnl $3 = nftables expected forward chain rules ++dnl $4 = nftables expected nat prerouting chain rules ++dnl $5 = nftables expected nat postrouting chain rules ++dnl $6 = iptables expected input chain rules ++dnl $7 = iptables expected forward chain rules ++dnl $8 = iptables expected nat prerouting chain rules ++dnl $9 = iptables expected nat postrouting chain rules ++m4_define([do_timeout], [dnl ++ ++FWD_CHECK([--zone trusted --timeout 2 $1], 0, [ignore]) ++FWD_CHECK([--zone trusted --add-service https], 0, [ignore]) ++ ++NFT_LIST_RULES([inet], [filter_IN_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_IN_trusted_allow { ++ $2 dnl ++ tcp dport 443 accept ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FWD_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_trusted_allow { ++ $3 dnl ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_PRE_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_PRE_trusted_allow { ++ $4 dnl ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_POST_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_POST_trusted_allow { ++ $5 dnl ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [IN_trusted_allow], 0, [dnl ++ $6 dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 ++]) ++IPTABLES_LIST_RULES([filter], [FWD_trusted_allow], 0, [dnl ++ $7 dnl ++]) ++IPTABLES_LIST_RULES([nat], [PRE_trusted_allow], 0, [dnl ++ $8 dnl ++]) ++IPTABLES_LIST_RULES([nat], [POST_trusted_allow], 0, [dnl ++ $9 dnl ++]) ++ ++sleep 5 ++NFT_LIST_RULES([inet], [filter_IN_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_IN_trusted_allow { ++ tcp dport 443 accept ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FWD_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_trusted_allow { ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_PRE_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_PRE_trusted_allow { ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_POST_trusted_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_POST_trusted_allow { ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [IN_trusted_allow], 0, [dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 ++]) ++IPTABLES_LIST_RULES([filter], [FWD_trusted_allow], 0, [dnl ++]) ++IPTABLES_LIST_RULES([nat], [PRE_trusted_allow], 0, [dnl ++]) ++IPTABLES_LIST_RULES([nat], [POST_trusted_allow], 0, [dnl ++]) ++ ++FWD_CHECK([--zone trusted --remove-service https], 0, [ignore]) ++ ++]) dnl end m4_define() ++ ++dnl ################################## ++dnl ##### Test every option that ##### ++dnl ##### supports timeouts ##### ++dnl ################################## ++ ++do_timeout([--add-port 1234/tcp], ++ tcp dport 1234 accept ++[dnl ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1234 ++], [], [], []) ++ ++do_timeout([--add-source-port 1234/tcp], ++[dnl ++ tcp sport 1234 accept ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp spt:1234 ++], [], [], []) ++ ++do_timeout([--add-protocol igmp], ++ meta l4proto igmp accept ++[dnl ++], [], [], [], ++[dnl ++ ACCEPT 2 -- 0.0.0.0/0 0.0.0.0/0 ++], [], [], []) ++ ++do_timeout([--add-service http], ++ tcp dport 80 accept ++[dnl ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 ++], [], [], []) ++ ++do_timeout([--add-rich-rule 'rule service name=irc accept'], ++[dnl ++ tcp dport 6667 accept ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:6667 ++], [], [], []) ++ ++do_timeout([--add-icmp-block echo-request], ++[dnl ++ icmp echo-request accept ++ icmpv6 echo-request accept ++], [], [], [], ++[dnl ++ ACCEPT 1 -- 0.0.0.0/0 0.0.0.0/0 icmptype 8 ++], [], [], []) ++ ++do_timeout([--add-forward], ++[], [dnl ++ oifname "foobar" accept ++], [], [], [], [dnl ++ ACCEPT 0 -- 0.0.0.0/0 0.0.0.0/0 ++], [], []) ++ ++do_timeout([--add-forward-port port=2222:proto=tcp:toport=22], ++[], [], [dnl ++ meta nfproto ipv4 tcp dport 2222 redirect to :22 ++], [], [], [], [dnl ++ DNAT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:2222 to::22 ++], []) ++ ++do_timeout([--add-masquerade], ++[], [], [], [dnl ++ meta nfproto ipv4 oifname != "lo" masquerade ++], [], [], [], [dnl ++ MASQUERADE 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++ ++m4_undefine([do_timeout]) ++FWD_END_TEST() ++]) +-- +2.52.0 + diff --git a/SOURCES/0066-v2.5.0-chore-fw_policy-support-timeouts.patch b/SOURCES/0066-v2.5.0-chore-fw_policy-support-timeouts.patch new file mode 100644 index 0000000..c9110b1 --- /dev/null +++ b/SOURCES/0066-v2.5.0-chore-fw_policy-support-timeouts.patch @@ -0,0 +1,74 @@ +From 83d090687b36ac4c704117ec619726a8d8275e86 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Mon, 1 Dec 2025 14:53:28 -0500 +Subject: [PATCH 66/70] v2.5.0: chore(fw_policy): support timeouts + +(cherry picked from commit 0749229070a3f201e435ba8101be420fa0e025ad) +--- + src/firewall/core/fw_policy.py | 14 +++++++++++--- + src/firewall/server/firewalld.py | 9 +++++++++ + 2 files changed, 20 insertions(+), 3 deletions(-) + +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 6203824166c3..624f8420dc5c 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -192,6 +192,12 @@ class FirewallPolicy(object): + "egress_zones": (self.add_egress_zone, self.remove_egress_zone), + } + ++ timeout = 0 ++ if "timeout" in settings: ++ timeout = settings["timeout"] ++ settings = copy.copy(settings) ++ del settings["timeout"] ++ + # do a full config check on a temporary object before trying to make + # the runtime changes + old_obj = self.get_policy(policy) +@@ -216,11 +222,13 @@ class FirewallPolicy(object): + if isinstance(add_settings[key], list): + for args in add_settings[key]: + if isinstance(args, tuple): +- setting_to_fn[key][0](policy, *args, timeout=0, sender=sender) ++ setting_to_fn[key][0]( ++ policy, *args, timeout=timeout, sender=sender ++ ) + else: +- setting_to_fn[key][0](policy, args, timeout=0, sender=sender) ++ setting_to_fn[key][0](policy, args, timeout=timeout, sender=sender) + else: # bool +- setting_to_fn[key][0](policy, timeout=0, sender=sender) ++ setting_to_fn[key][0](policy, timeout=timeout, sender=sender) + + def addTimeout(self, tag, _id): + if _id not in self._timeouts: +diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py +index d796c1d45e9c..ec0c3ff4b457 100644 +--- a/src/firewall/server/firewalld.py ++++ b/src/firewall/server/firewalld.py +@@ -972,12 +972,21 @@ class FirewallD(DbusServiceObject): + self.accessCheck(sender) + self.fw.policy.set_config_with_settings_dict(policy, dbus_to_python(settings), sender) + self.PolicyUpdated(policy, settings) ++ if "timeout" in settings and settings["timeout"] > 0: ++ GLib.timeout_add_seconds( ++ settings["timeout"], ++ self.PolicyUpdatedCurrentSettings, ++ policy, ++ ) + + @dbus.service.signal(config.dbus.DBUS_INTERFACE_POLICY, signature='sa{sv}') + @dbus_handle_exceptions + def PolicyUpdated(self, policy, settings): + log.debug1("policy.PolicyUpdated('%s', '%s')" % (policy, settings)) + ++ def PolicyUpdatedCurrentSettings(self, policy): ++ self.PolicyUpdated(policy, self.fw.policy.get_config_with_settings_dict(policy)) ++ + @dbus_polkit_require_auth(config.dbus.PK_ACTION_INFO) + @dbus_service_method(config.dbus.DBUS_INTERFACE, in_signature='', + out_signature='as') +-- +2.52.0 + diff --git a/SOURCES/0067-v2.5.0-fix-policy-support-timeouts.patch b/SOURCES/0067-v2.5.0-fix-policy-support-timeouts.patch new file mode 100644 index 0000000..070dc7e --- /dev/null +++ b/SOURCES/0067-v2.5.0-fix-policy-support-timeouts.patch @@ -0,0 +1,97 @@ +From 1ffa7613a57118ff62158c0a90b3b2d168c47c25 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Wed, 3 Dec 2025 16:21:24 -0500 +Subject: [PATCH 67/70] v2.5.0: fix(policy): support timeouts + +Fixes: #1381 +Fixes: RHEL-129918 +Fixes: RHEL-95705 +Fixes: RHEL-5795 +(cherry picked from commit 16d8c4dd54e43b9cc66c4707b06a39cfbbd95825) +--- + src/firewall-cmd.in | 2 +- + src/firewall/client.py | 6 ++++-- + src/firewall/core/fw_policy.py | 16 ++++++++++++++++ + 3 files changed, 21 insertions(+), 3 deletions(-) + +diff --git a/src/firewall-cmd.in b/src/firewall-cmd.in +index eb0ac7e48e3c..12df581498ef 100755 +--- a/src/firewall-cmd.in ++++ b/src/firewall-cmd.in +@@ -3007,7 +3007,7 @@ elif a.policy: + cmd.query_sequence(a.query_icmp_block, settings.queryIcmpBlock, + None, "'%s'") + +- fw.setPolicySettings(a.policy, settings) ++ fw.setPolicySettings(a.policy, settings, a.timeout) + + # endif a.policy + # +diff --git a/src/firewall/client.py b/src/firewall/client.py +index 268a4a947da9..b30b0d12f738 100644 +--- a/src/firewall/client.py ++++ b/src/firewall/client.py +@@ -3293,8 +3293,10 @@ class FirewallClient(object): + return FirewallClientPolicySettings(dbus_to_python(self.fw_policy.getPolicySettings(policy))) + + @handle_exceptions +- def setPolicySettings(self, policy, settings): +- self.fw_policy.setPolicySettings(policy, settings.getRuntimeSettingsDbusDict()) ++ def setPolicySettings(self, policy, settings, timeout=0): ++ settings = settings.getRuntimeSettingsDbusDict() ++ settings["timeout"] = timeout ++ self.fw_policy.setPolicySettings(policy, settings) + + @handle_exceptions + def getPolicies(self): +diff --git a/src/firewall/core/fw_policy.py b/src/firewall/core/fw_policy.py +index 624f8420dc5c..0a0d1ded5fe3 100644 +--- a/src/firewall/core/fw_policy.py ++++ b/src/firewall/core/fw_policy.py +@@ -286,6 +286,12 @@ class FirewallPolicy(object): + self.__register_ingress_zone(_obj, zone_id, timeout, sender) + transaction.add_fail(self.__unregister_ingress_zone, _obj, zone_id) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_ingress_zone, _policy, zone ++ ) ++ self.addTimeout(tag, ("ingress_zone", _policy, zone)) ++ + if use_transaction is None: + transaction.execute(True) + +@@ -322,6 +328,8 @@ class FirewallPolicy(object): + else: + transaction.add_post(self.__unregister_ingress_zone, _obj, zone_id) + ++ self.removeTimeout(("ingress_zone", _policy, zone)) ++ + if use_transaction is None: + transaction.execute(True) + +@@ -384,6 +392,12 @@ class FirewallPolicy(object): + self.__register_egress_zone(_obj, zone_id, timeout, sender) + transaction.add_fail(self.__unregister_egress_zone, _obj, zone_id) + ++ if timeout > 0: ++ tag = GLib.timeout_add_seconds( ++ timeout, self.remove_egress_zone, _policy, zone ++ ) ++ self.addTimeout(tag, ("egress_zone", _policy, zone)) ++ + if use_transaction is None: + transaction.execute(True) + +@@ -420,6 +434,8 @@ class FirewallPolicy(object): + else: + transaction.add_post(self.__unregister_egress_zone, _obj, zone_id) + ++ self.removeTimeout(("egress_zone", _policy, zone)) ++ + if use_transaction is None: + transaction.execute(True) + +-- +2.52.0 + diff --git a/SOURCES/0068-v2.5.0-fix-cli-policy-allow-timeout-with-ingress-zon.patch b/SOURCES/0068-v2.5.0-fix-cli-policy-allow-timeout-with-ingress-zon.patch new file mode 100644 index 0000000..00cc69f --- /dev/null +++ b/SOURCES/0068-v2.5.0-fix-cli-policy-allow-timeout-with-ingress-zon.patch @@ -0,0 +1,26 @@ +From 4f965d0dc42c0e88b4a36014e6db9984f7402416 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Fri, 5 Dec 2025 09:51:20 -0500 +Subject: [PATCH 68/70] v2.5.0: fix(cli): policy: allow timeout with + --ingress-zone/--egress-zone + +(cherry picked from commit 4227d2a9b91bdf84823724b6299b984d29385ed6) +--- + src/firewall-cmd.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/firewall-cmd.in b/src/firewall-cmd.in +index 12df581498ef..6973a643bf47 100755 +--- a/src/firewall-cmd.in ++++ b/src/firewall-cmd.in +@@ -1104,6 +1104,7 @@ else: + if a.timeout and not (a.add_service or a.add_port or a.add_protocol or \ + a.add_icmp_block or a.add_forward_port or \ + a.add_source_port or a.add_forward or \ ++ a.add_ingress_zone or a.add_egress_zone or \ + a.add_masquerade or a.add_rich_rule): + cmd.fail(parser.format_usage() + "Wrong --timeout usage") + +-- +2.52.0 + diff --git a/SOURCES/0069-v2.5.0-test-policy-verify-timeout-works.patch b/SOURCES/0069-v2.5.0-test-policy-verify-timeout-works.patch new file mode 100644 index 0000000..71f0a84 --- /dev/null +++ b/SOURCES/0069-v2.5.0-test-policy-verify-timeout-works.patch @@ -0,0 +1,237 @@ +From 9acf188c98f8c654a3b04e8aba0124fa895e2784 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Thu, 20 Nov 2025 14:55:40 -0500 +Subject: [PATCH 69/70] v2.5.0: test(policy): verify timeout works + +Coverage: #1381 +Coverage: RHEL-129918 +Coverage: RHEL-95705 +Coverage: RHEL-5795 +(cherry picked from commit 14dde1c406841af3499db18308eb4e9e4e6f66db) +--- + src/tests/features/features.at | 1 + + src/tests/features/policy_timeout.at | 203 +++++++++++++++++++++++++++ + 2 files changed, 204 insertions(+) + create mode 100644 src/tests/features/policy_timeout.at + +diff --git a/src/tests/features/features.at b/src/tests/features/features.at +index 2867132f7b08..3501e028d589 100644 +--- a/src/tests/features/features.at ++++ b/src/tests/features/features.at +@@ -24,3 +24,4 @@ m4_include([features/reloadpolicy.at]) + m4_include([features/nftables_table_owner.at]) + m4_include([features/zone_forward.at]) + m4_include([features/zone_timeout.at]) ++m4_include([features/policy_timeout.at]) +diff --git a/src/tests/features/policy_timeout.at b/src/tests/features/policy_timeout.at +new file mode 100644 +index 000000000000..a62493e5986f +--- /dev/null ++++ b/src/tests/features/policy_timeout.at +@@ -0,0 +1,203 @@ ++m4_ifdef([TESTING_FIREWALL_OFFLINE_CMD], [], [ ++FWD_START_TEST([policy - timeout]) ++AT_KEYWORDS(policy timeout RHEL-129918 RHEL-95705 RHEL-5795 gh1381) ++ ++FWD_CHECK([--permanent --zone trusted --add-interface foobar0], 0, [ignore]) ++FWD_CHECK([--permanent --new-policy foobar], 0, [ignore]) ++FWD_CHECK([--permanent --policy foobar --add-ingress-zone ANY], 0, [ignore]) ++FWD_CHECK([--permanent --policy foobar --add-egress-zone ANY], 0, [ignore]) ++FWD_RELOAD() ++ ++dnl $1 = firewall-cmd args ++dnl $2 = nftables expected forward allow chain rules ++dnl $3 = nftables expected forward deny chain rules ++dnl $4 = nftables expected nat prerouting chain rules ++dnl $5 = nftables expected nat postrouting chain rules ++dnl $6 = iptables expected forward allow chain rules ++dnl $7 = iptables expected forward deny chain rules ++dnl $8 = iptables expected nat prerouting chain rules ++dnl $9 = iptables expected nat postrouting chain rules ++m4_define([do_timeout], [dnl ++ ++FWD_CHECK([--policy foobar --timeout 2 $1], 0, [ignore]) ++FWD_CHECK([--policy foobar --add-service https], 0, [ignore]) ++ ++NFT_LIST_RULES([inet], [filter_FWD_policy_foobar_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_policy_foobar_allow { ++ $2 dnl ++ tcp dport 443 accept ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FWD_policy_foobar_deny], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_policy_foobar_deny { ++ $3 dnl ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_PRE_policy_foobar_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_PRE_policy_foobar_allow { ++ $4 dnl ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_POST_policy_foobar_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_POST_policy_foobar_allow { ++ $5 dnl ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_foobar_allow], 0, [dnl ++ $6 dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 ++]) ++IPTABLES_LIST_RULES([filter], [FWD_foobar_deny], 0, [dnl ++ $7 dnl ++]) ++IPTABLES_LIST_RULES([nat], [PRE_foobar_allow], 0, [dnl ++ $8 dnl ++]) ++IPTABLES_LIST_RULES([nat], [POST_foobar_allow], 0, [dnl ++ $9 dnl ++]) ++ ++sleep 5 ++NFT_LIST_RULES([inet], [filter_FWD_policy_foobar_allow], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_policy_foobar_allow { ++ tcp dport 443 accept ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FWD_policy_foobar_deny], 0, [dnl ++ table inet firewalld { ++ chain filter_FWD_policy_foobar_deny { ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_PRE_policy_foobar_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_PRE_policy_foobar_allow { ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [nat_POST_policy_foobar_allow], 0, [dnl ++ table inet firewalld { ++ chain nat_POST_policy_foobar_allow { ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FWD_foobar_allow], 0, [dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 ++]) ++IPTABLES_LIST_RULES([filter], [FWD_foobar_deny], 0, [dnl ++]) ++IPTABLES_LIST_RULES([nat], [PRE_foobar_allow], 0, [dnl ++]) ++IPTABLES_LIST_RULES([nat], [POST_foobar_allow], 0, [dnl ++]) ++ ++FWD_CHECK([--policy foobar --remove-service https], 0, [ignore]) ++ ++]) dnl end m4_define() ++ ++dnl ################################## ++dnl ##### Test every option that ##### ++dnl ##### supports timeouts ##### ++dnl ################################## ++ ++do_timeout([--add-port 1234/tcp], ++[dnl ++ tcp dport 1234 accept ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:1234 ++], [], [], []) ++ ++do_timeout([--add-source-port 1234/tcp], ++[dnl ++ tcp sport 1234 accept ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp spt:1234 ++], [], [], []) ++ ++do_timeout([--add-protocol igmp], ++[dnl ++ meta l4proto igmp accept ++], [], [], [], ++[dnl ++ ACCEPT 2 -- 0.0.0.0/0 0.0.0.0/0 ++], [], [], []) ++ ++do_timeout([--add-service http], ++[dnl ++ tcp dport 80 accept ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 ++], [], [], []) ++ ++do_timeout([--add-rich-rule 'rule service name=irc accept'], ++[dnl ++ tcp dport 6667 accept ++], [], [], [], ++[dnl ++ ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:6667 ++], [], [], []) ++ ++do_timeout([--add-icmp-block echo-request], ++[], [dnl ++ icmp echo-request reject with icmpx admin-prohibited ++ icmpv6 echo-request reject with icmpx admin-prohibited ++], [], [], [], ++[dnl ++ REJECT 1 -- 0.0.0.0/0 0.0.0.0/0 icmptype 8 reject-with icmp-host-prohibited ++], [], []) ++ ++do_timeout([--add-forward-port port=2222:proto=tcp:toport=22:toaddr=10.10.10.10], ++[], [], [dnl ++ meta nfproto ipv4 tcp dport 2222 dnat ip to 10.10.10.10:22 ++], [], [], [], [dnl ++ DNAT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:2222 to:10.10.10.10:22 ++], []) ++ ++do_timeout([--add-masquerade], ++[], [], [], [dnl ++ meta nfproto ipv4 oifname != "lo" masquerade ++], [], [], [], [dnl ++ MASQUERADE 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++ ++dnl for ingress-zone and egress-zone we have to check the dispatch ++FWD_CHECK([--policy foobar --remove-ingress-zone ANY], 0, [ignore]) ++FWD_CHECK([--policy foobar --timeout 2 --add-ingress-zone ANY], 0, [ignore]) ++ ++NFT_LIST_RULES([inet], [filter_FORWARD_POLICIES_pre], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_POLICIES_pre { ++ jump filter_FWD_policy_foobar ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FORWARD_POLICIES_pre], 0, [dnl ++ FWD_foobar 0 -- 0.0.0.0/0 0.0.0.0/0 ++]) ++ ++sleep 5 ++NFT_LIST_RULES([inet], [filter_FORWARD_POLICIES_pre], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_POLICIES_pre { ++ } ++ } ++]) ++IPTABLES_LIST_RULES([filter], [FORWARD_POLICIES_pre], 0, [dnl ++]) ++ ++m4_undefine([do_timeout]) ++FWD_END_TEST() ++]) +-- +2.52.0 + diff --git a/SPECS/firewalld.spec b/SPECS/firewalld.spec index 0a0775d..d2d0a86 100644 --- a/SPECS/firewalld.spec +++ b/SPECS/firewalld.spec @@ -1,7 +1,7 @@ Summary: A firewall daemon with D-Bus interface providing a dynamic firewall Name: firewalld Version: 1.3.4 -Release: 18%{?dist} +Release: 19%{?dist} URL: http://www.firewalld.org License: GPLv2+ Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.bz2 @@ -53,6 +53,27 @@ 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 +Patch49: 0049-v2.3.0-fix-policy-timeout-argument-for-rich-rules.patch +Patch50: 0050-v2.5.0-test-functions-fix-macro-CHECK_NFT_CT_HELPER.patch +Patch51: 0051-v2.5.0-chore-fw_policy-add-utility-functions-to-supp.patch +Patch52: 0052-v2.5.0-chore-zone-service-move-timeouts-to-policy.patch +Patch53: 0053-v2.5.0-chore-zone-port-move-timeouts-to-policy.patch +Patch54: 0054-v2.5.0-chore-zone-source_port-move-timeouts-to-polic.patch +Patch55: 0055-v2.5.0-chore-zone-forward_port-move-timeouts-to-poli.patch +Patch56: 0056-v2.5.0-chore-zone-icmp_block-move-timeouts-to-policy.patch +Patch57: 0057-v2.5.0-chore-zone-masquerade-move-timeouts-to-policy.patch +Patch58: 0058-v2.5.0-chore-zone-protocol-move-timeouts-to-policy.patch +Patch59: 0059-v2.5.0-chore-zone-rule-move-timeouts-to-policy.patch +Patch60: 0060-v2.5.0-chore-zone-remove-daemon-level-timeout-code.patch +Patch61: 0061-v2.5.0-chore-fw_zone-add-utility-functions-to-suppor.patch +Patch62: 0062-v2.5.0-chore-fw_zone-support-timeouts-via-dict-API.patch +Patch63: 0063-v2.5.0-fix-zone-forward-support-timeout.patch +Patch64: 0064-v2.5.0-test-zone-forward-move-test-to-features.patch +Patch65: 0065-v2.5.0-test-zone-verify-timeout-works.patch +Patch66: 0066-v2.5.0-chore-fw_policy-support-timeouts.patch +Patch67: 0067-v2.5.0-fix-policy-support-timeouts.patch +Patch68: 0068-v2.5.0-fix-cli-policy-allow-timeout-with-ingress-zon.patch +Patch69: 0069-v2.5.0-test-policy-verify-timeout-works.patch BuildArch: noarch BuildRequires: autoconf BuildRequires: automake @@ -276,6 +297,10 @@ rm -rf %{buildroot}%{_datadir}/firewalld/testsuite %{_mandir}/man1/firewall-config*.1* %changelog +* Fri Jul 10 2026 Eric Garver - 1.3.4-19 +- fix(zone): forward: support timeout +- fix(policy): support timeouts + * Tue Dec 02 2025 Eric Garver - 1.3.4-18 - fix(policy): allow-host-ipv6: allow MLD packets