Blob Blame History Raw
From 244d1bfe190f2cc32c10d0fecaf81536761ecc09 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Tue, 1 Sep 2020 13:16:23 -0400
Subject: [PATCH 59/62] fix(icmptype): nftables: runtimeToPermanent if
 ip6tables not available

We were not filling the runtime ipv6 icmptypes list if the active
backend was nftables and ip6tables wasn't available. This caused "ipv6"
to be dropped from the supported ipvs/destinations for the icmptype.
This also caused runtimeToPermanent to fail because the runtime
icmptypes definition dropped "ipv6" causing runtimeToPermanent to copy
the runtime icmptype to permanent because they were different... this
caused sanity checks on the permanent configuration to fail.

(cherry picked from commit c92d43dcdf5622e82e28454652acd6a981b015f9)
(cherry picked from commit 6f23f727be818f356625e39682fb226a81925647)
---
 src/firewall/core/fw.py          | 24 ++++++++++++++----------
 src/firewall/core/fw_icmptype.py |  8 ++++----
 src/firewall/core/ipXtables.py   |  2 +-
 src/firewall/core/nftables.py    |  6 +++---
 src/firewall/server/firewalld.py |  4 ++--
 5 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
index c767f416f3d2..1df916efb10f 100644
--- a/src/firewall/core/fw.py
+++ b/src/firewall/core/fw.py
@@ -76,10 +76,10 @@ class Firewall(object):
         else:
             self.ip4tables_backend = ipXtables.ip4tables(self)
             self.ip4tables_enabled = True
-            self.ip4tables_supported_icmp_types = [ ]
+            self.ipv4_supported_icmp_types = [ ]
             self.ip6tables_backend = ipXtables.ip6tables(self)
             self.ip6tables_enabled = True
-            self.ip6tables_supported_icmp_types = [ ]
+            self.ipv6_supported_icmp_types = [ ]
             self.ebtables_backend = ebtables.ebtables()
             self.ebtables_enabled = True
             self.ipset_backend = ipset.ipset()
@@ -172,11 +172,13 @@ class Firewall(object):
                 log.warning("iptables-restore and iptables are missing, "
                             "disabling IPv4 firewall.")
                 self.ip4tables_enabled = False
-        if self.ip4tables_enabled:
-            self.ip4tables_supported_icmp_types = \
-                self.ip4tables_backend.supported_icmp_types()
+        if self.nftables_enabled:
+            self.ipv4_supported_icmp_types = self.nftables_backend.supported_icmp_types("ipv4")
         else:
-            self.ip4tables_supported_icmp_types = [ ]
+            if self.ip4tables_enabled:
+                self.ipv4_supported_icmp_types = self.ip4tables_backend.supported_icmp_types()
+            else:
+                self.ipv4_supported_icmp_types = [ ]
         self.ip6tables_backend.fill_exists()
         if not self.ip6tables_backend.restore_command_exists:
             if self.ip6tables_backend.command_exists:
@@ -186,11 +188,13 @@ class Firewall(object):
                 log.warning("ip6tables-restore and ip6tables are missing, "
                             "disabling IPv6 firewall.")
                 self.ip6tables_enabled = False
-        if self.ip6tables_enabled:
-            self.ip6tables_supported_icmp_types = \
-                self.ip6tables_backend.supported_icmp_types()
+        if self.nftables_enabled:
+            self.ipv6_supported_icmp_types = self.nftables_backend.supported_icmp_types("ipv6")
         else:
-            self.ip6tables_supported_icmp_types = [ ]
+            if self.ip6tables_enabled:
+                self.ipv6_supported_icmp_types = self.ip6tables_backend.supported_icmp_types()
+            else:
+                self.ipv6_supported_icmp_types = [ ]
         self.ebtables_backend.fill_exists()
         if not self.ebtables_backend.restore_command_exists:
             if self.ebtables_backend.command_exists:
diff --git a/src/firewall/core/fw_icmptype.py b/src/firewall/core/fw_icmptype.py
index afe9f91d6bf6..a565bb6d8733 100644
--- a/src/firewall/core/fw_icmptype.py
+++ b/src/firewall/core/fw_icmptype.py
@@ -57,13 +57,13 @@ class FirewallIcmpType(object):
         ipvs = orig_ipvs[:]
         for ipv in orig_ipvs:
             if ipv == "ipv4":
-                if not self._fw.ip4tables_enabled:
+                if not self._fw.ip4tables_enabled and not self._fw.nftables_enabled:
                     continue
-                supported_icmps = self._fw.ip4tables_supported_icmp_types
+                supported_icmps = self._fw.ipv4_supported_icmp_types
             elif ipv == "ipv6":
-                if not self._fw.ip6tables_enabled:
+                if not self._fw.ip6tables_enabled and not self._fw.nftables_enabled:
                     continue
-                supported_icmps = self._fw.ip6tables_supported_icmp_types
+                supported_icmps = self._fw.ipv6_supported_icmp_types
             else:
                 supported_icmps = [ ]
             if obj.name.lower() not in supported_icmps:
diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py
index c4535f2e5818..450e427c08b5 100644
--- a/src/firewall/core/ipXtables.py
+++ b/src/firewall/core/ipXtables.py
@@ -612,7 +612,7 @@ class ip4tables(object):
                 rules.append(["-t", table, "-P", chain, _policy])
         return rules
 
-    def supported_icmp_types(self):
+    def supported_icmp_types(self, ipv=None):
         """Return ICMP types that are supported by the iptables/ip6tables command and kernel"""
         ret = [ ]
         output = ""
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index daa7ace085a2..0a73c2c2669d 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -480,13 +480,13 @@ class nftables(object):
 
         return rules
 
-    def supported_icmp_types(self):
+    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 ICMP_TYPES_FRAGMENTS.keys():
-            supported.update(ICMP_TYPES_FRAGMENTS[ipv].keys())
+        for _ipv in [ipv] if ipv else ICMP_TYPES_FRAGMENTS.keys():
+            supported.update(ICMP_TYPES_FRAGMENTS[_ipv].keys())
 
         return list(supported)
 
diff --git a/src/firewall/server/firewalld.py b/src/firewall/server/firewalld.py
index 10b085d48660..949f577053cc 100644
--- a/src/firewall/server/firewalld.py
+++ b/src/firewall/server/firewalld.py
@@ -162,7 +162,7 @@ class FirewallD(slip.dbus.service.Object):
             return dbus.Boolean(self.fw.ip4tables_enabled)
 
         elif prop == "IPv4ICMPTypes":
-            return dbus.Array(self.fw.ip4tables_supported_icmp_types, "s")
+            return dbus.Array(self.fw.ipv4_supported_icmp_types, "s")
 
         elif prop == "IPv6":
             return dbus.Boolean(self.fw.ip6tables_enabled)
@@ -171,7 +171,7 @@ class FirewallD(slip.dbus.service.Object):
             return dbus.Boolean(self.fw.ipv6_rpfilter_enabled)
 
         elif prop == "IPv6ICMPTypes":
-            return dbus.Array(self.fw.ip6tables_supported_icmp_types, "s")
+            return dbus.Array(self.fw.ipv6_supported_icmp_types, "s")
 
         elif prop == "BRIDGE":
             return dbus.Boolean(self.fw.ebtables_enabled)
-- 
2.28.0