From 5acbdc31a56f4b680323ba7aa92383da9e9f25fa Mon Sep 17 00:00:00 2001 From: Eric Garver Date: Wed, 22 Jul 2020 09:18:42 -0400 Subject: [PATCH 41/45] fix(rich): icmptypes with one family They were mistakenly being added to both families which fails. Fixes: rhbz 1855140 (cherry picked from commit 0112e36c4e225504b15a1feef3d453a757a00b21) (cherry picked from commit bd61af7db6f92d48a79fb1e84405aef4f522ffbf) --- src/firewall/core/fw_zone.py | 26 +++++++++++--------------- src/firewall/core/nftables.py | 2 +- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py index 5677effab146..b9fe1f6aae97 100644 --- a/src/firewall/core/fw_zone.py +++ b/src/firewall/core/fw_zone.py @@ -1522,14 +1522,17 @@ class FirewallZone(object): transaction.add_rules(backend, rules) def _rule_prepare(self, enable, zone, rule, transaction): - if rule.family is not None: + ipvs = [] + if rule.family: ipvs = [ rule.family ] - else: - ipvs = [ipv for ipv in ["ipv4", "ipv6"] if self._fw.is_ipv_enabled(ipv)] + elif rule.element and (isinstance(rule.element, Rich_IcmpBlock) or isinstance(rule.element, Rich_IcmpType)): + ict = self._fw.icmptype.get_icmptype(rule.element.name) + if ict.destination: + ipvs = [ipv for ipv in ["ipv4", "ipv6"] if ipv in ict.destination] source_ipv = self._rule_source_ipv(rule.source) - if source_ipv is not None and source_ipv != "": - if rule.family is not None: + if source_ipv: + if rule.family: # rule family is defined by user, no way to change it if rule.family != source_ipv: raise FirewallError(errors.INVALID_RULE, @@ -1538,6 +1541,9 @@ class FirewallZone(object): # use the source family as rule family ipvs = [ source_ipv ] + if not ipvs: + ipvs = [ipv for ipv in ["ipv4", "ipv6"] if self._fw.is_ipv_enabled(ipv)] + # add an element to object to allow backends to know what ipvs this applies to rule.ipvs = ipvs @@ -1699,16 +1705,6 @@ class FirewallZone(object): # icmp block might have reject or drop action, but not accept raise FirewallError(errors.INVALID_RULE, "IcmpBlock not usable with accept action") - if ict.destination: - for ipv in ipvs: - if ipv in ict.destination \ - and not backend.is_ipv_supported(ipv): - raise FirewallError( - errors.INVALID_RULE, - "Icmp%s %s not usable with %s" % \ - ("Block" if type(rule.element) == \ - Rich_IcmpBlock else "Type", - rule.element.name, backend.name)) table = "filter" if enable: diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py index 85c790b5b51e..0198200b2372 100644 --- a/src/firewall/core/nftables.py +++ b/src/firewall/core/nftables.py @@ -1383,7 +1383,7 @@ class nftables(object): return ICMP_TYPES_FRAGMENTS[ipv][icmp_type] else: raise FirewallError(INVALID_ICMPTYPE, - "ICMP type '%s' not supported by %s" % (icmp_type, self.name)) + "ICMP type '%s' not supported by %s for %s" % (icmp_type, self.name, ipv)) def build_zone_icmp_block_rules(self, enable, zone, ict, rich_rule=None): table = "filter" -- 2.27.0