Blob Blame History Raw
From 5964984c68b5101c372ce6b067fbe627a7a33d1b Mon Sep 17 00:00:00 2001
From: Eric Garver <e@erig.me>
Date: Tue, 13 Nov 2018 15:30:08 -0500
Subject: [PATCH 18/34] nftables: Use index for ICMP block inversion rules

(cherry picked from commit 54e1bac809fccbc83540f6151a64aeb1f058c06a)
---
 src/firewall/core/fw_zone.py  |  6 -----
 src/firewall/core/nftables.py | 43 +++++++++--------------------------
 2 files changed, 11 insertions(+), 38 deletions(-)

diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py
index db90c32be540..afa4b2ce0022 100644
--- a/src/firewall/core/fw_zone.py
+++ b/src/firewall/core/fw_zone.py
@@ -1961,12 +1961,6 @@ class FirewallZone(object):
         zone_transaction.add_chain("filter", "INPUT")
         zone_transaction.add_chain("filter", "FORWARD_IN")
 
-        # To satisfy nftables backend rule lookup we must execute pending
-        # rules. See nftables.build_zone_icmp_block_inversion_rules()
-        if enable:
-            zone_transaction.execute(enable)
-            zone_transaction.clear()
-
         for backend in self._fw.enabled_backends():
             if not backend.zones_supported:
                 continue
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index 47b1c27dc8cc..a763ed3ec103 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -1066,50 +1066,29 @@ class nftables(object):
     def build_zone_icmp_block_inversion_rules(self, enable, zone):
         table = "filter"
         rules = []
+        add_del = { True: "add", False: "delete" }[enable]
+
         for chain in ["INPUT", "FORWARD_IN"]:
             _zone = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain],
                                                zone=zone)
-            # HACK: nft position is actually a handle, so we need to lookup the
-            # handle of the rule we want to insert this after.
-            #
-            # This must be kept in sync with build_zone_chain_rules()
-            #
-            # WARN: This does not work if we haven't executed the transaction
-            # yet, because we don't have a handle for our rule_key!! As such,
-            # we execute transactions before calling this function.
-            #
-            rule_key = " ".join(["inet", "%s" % TABLE_NAME,
-                                 "%s_%s" % (table, _zone),
-                                 "jump", "%s_%s_allow" % (table, _zone)])
-            rule_handle = self.rule_to_handle[rule_key]
 
             if self._fw.zone.query_icmp_block_inversion(zone):
                 ibi_target = "%%REJECT%%"
             else:
                 ibi_target = "accept"
 
-            if enable:
-                # FIXME: can we get rid of position ?
-                rule = ["add", "rule", "inet", "%s" % TABLE_NAME,
-                        "%s_%s" % (table, _zone), "position", rule_handle]
-            else:
-                rule = ["delete", "rule", "inet", "%s" % TABLE_NAME,
-                        "%s_%s" % (table, _zone)]
-            rule += ["%%ICMP%%", ibi_target]
-            rules.append(rule)
+            # WARN: index must be kept in sync with build_zone_chain_rules()
+            rules.append([add_del, "rule", "inet", "%s" % TABLE_NAME,
+                          "%s_%s" % (table, _zone), "index", "2",
+                          "%%ICMP%%", ibi_target])
 
             if self._fw.zone.query_icmp_block_inversion(zone):
                 if self._fw.get_log_denied() != "off":
-                    if enable:
-                        # FIXME: can we get rid of position ?
-                        rule = ["add", "rule", "inet", "%s" % TABLE_NAME,
-                                "%s_%s" % (table, _zone), "position", rule_handle]
-                    else:
-                        rule = ["delete", "rule", "inet", "%s" % TABLE_NAME,
-                                "%s_%s" % (table, _zone)]
-                    rule += ["%%ICMP%%", "%%LOGTYPE%%", "log", "prefix",
-                             "\"%s_%s_ICMP_BLOCK: \"" % (table, _zone)]
-                    rules.append(rule)
+                    # WARN: index must be kept in sync with build_zone_chain_rules()
+                    rules.append([add_del, "rule", "inet", "%s" % TABLE_NAME,
+                                  "%s_%s" % (table, _zone), "index", "2",
+                                  "%%ICMP%%", "%%LOGTYPE%%", "log", "prefix",
+                                  "\"%s_%s_ICMP_BLOCK: \"" % (table, _zone)])
 
         return rules
 
-- 
2.18.0