136e2c
From 74760c43588be65303795397717d4aa5ef5e4236 Mon Sep 17 00:00:00 2001
136e2c
From: Eric Garver <eric@garver.life>
136e2c
Date: Wed, 29 May 2019 15:21:34 -0400
136e2c
Subject: [PATCH 59/73] fix: do not allow zone drifting
136e2c
136e2c
Chain zone dispatch together and always use "goto". This guarantees
136e2c
there is no fall through to other zones. This was especially problematic
136e2c
in regards to the default zone.
136e2c
136e2c
This removes the _ZONES_SOURCE chains, but adds _ZONES_IFACES. At the
136e2c
end of _ZONES we do a goto to _ZONES_IFACES. This is so sources always
136e2c
take precedence over interfaces.
136e2c
136e2c
Fixes: #258
136e2c
Fixes: #441
136e2c
(cherry picked from commit 70993581d79beb40a3d23bd8cbfb776ad5df5dca)
136e2c
(cherry picked from commit 16c7603b57d5b07389e9c2ba0ca8b4836b2aaf93)
136e2c
---
136e2c
 src/firewall/core/fw_zone.py   |  6 +--
136e2c
 src/firewall/core/ipXtables.py | 70 ++++++++++++++++------------------
136e2c
 src/firewall/core/nftables.py  | 67 +++++++++++++++-----------------
136e2c
 src/tests/firewall-cmd.at      |  8 ++--
136e2c
 4 files changed, 69 insertions(+), 82 deletions(-)
136e2c
136e2c
diff --git a/src/firewall/core/fw_zone.py b/src/firewall/core/fw_zone.py
136e2c
index ee02a161bcfb..90ae1036f124 100644
136e2c
--- a/src/firewall/core/fw_zone.py
136e2c
+++ b/src/firewall/core/fw_zone.py
136e2c
@@ -1514,8 +1514,7 @@ class FirewallZone(object):
136e2c
                         zone_transaction.add_chain(table, chain)
136e2c
 
136e2c
                     rules = backend.build_zone_source_interface_rules(enable,
136e2c
-                                        zone, self._zones[zone].target,
136e2c
-                                        interface, table, chain, append)
136e2c
+                                        zone, interface, table, chain, append)
136e2c
                     zone_transaction.add_rules(backend, rules)
136e2c
 
136e2c
     # IPSETS
136e2c
@@ -1555,8 +1554,7 @@ class FirewallZone(object):
136e2c
                         zone_transaction.add_chain(table, chain)
136e2c
 
136e2c
                     rules = backend.build_zone_source_address_rules(enable, zone,
136e2c
-                                    self._zones[zone].target, source, table,
136e2c
-                                    chain)
136e2c
+                                                        source, table, chain)
136e2c
                     zone_transaction.add_rules(backend, rules)
136e2c
 
136e2c
     def _rule_prepare(self, enable, zone, rule, mark_id, zone_transaction):
136e2c
diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py
136e2c
index 4a9c06242f08..c2339e40539a 100644
136e2c
--- a/src/firewall/core/ipXtables.py
136e2c
+++ b/src/firewall/core/ipXtables.py
136e2c
@@ -526,11 +526,11 @@ class ip4tables(object):
136e2c
                 self.our_chains["raw"].add("%s_direct" % chain)
136e2c
 
136e2c
                 if chain == "PREROUTING":
136e2c
-                    default_rules["raw"].append("-N %s_ZONES_SOURCE" % chain)
136e2c
                     default_rules["raw"].append("-N %s_ZONES" % chain)
136e2c
-                    default_rules["raw"].append("-A %s -j %s_ZONES_SOURCE" % (chain, chain))
136e2c
+                    default_rules["raw"].append("-N %s_ZONES_IFACES" % chain)
136e2c
                     default_rules["raw"].append("-A %s -j %s_ZONES" % (chain, chain))
136e2c
-                    self.our_chains["raw"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
136e2c
+                    default_rules["raw"].append("-A %s_ZONES -g %s_ZONES_IFACES" % (chain, chain))
136e2c
+                    self.our_chains["raw"].update(set(["%s_ZONES" % chain, "%s_ZONES_IFACES" % chain]))
136e2c
 
136e2c
         if self.get_available_tables("mangle"):
136e2c
             default_rules["mangle"] = [ ]
136e2c
@@ -541,11 +541,11 @@ class ip4tables(object):
136e2c
                 self.our_chains["mangle"].add("%s_direct" % chain)
136e2c
 
136e2c
                 if chain == "PREROUTING":
136e2c
-                    default_rules["mangle"].append("-N %s_ZONES_SOURCE" % chain)
136e2c
                     default_rules["mangle"].append("-N %s_ZONES" % chain)
136e2c
-                    default_rules["mangle"].append("-A %s -j %s_ZONES_SOURCE" % (chain, chain))
136e2c
+                    default_rules["mangle"].append("-N %s_ZONES_IFACES" % chain)
136e2c
                     default_rules["mangle"].append("-A %s -j %s_ZONES" % (chain, chain))
136e2c
-                    self.our_chains["mangle"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
136e2c
+                    default_rules["mangle"].append("-A %s_ZONES -g %s_ZONES_IFACES" % (chain, chain))
136e2c
+                    self.our_chains["mangle"].update(set(["%s_ZONES" % chain, "%s_ZONES_IFACES" % chain]))
136e2c
 
136e2c
         if self.get_available_tables("nat"):
136e2c
             default_rules["nat"] = [ ]
136e2c
@@ -556,22 +556,22 @@ class ip4tables(object):
136e2c
                 self.our_chains["nat"].add("%s_direct" % chain)
136e2c
 
136e2c
                 if chain in [ "PREROUTING", "POSTROUTING" ]:
136e2c
-                    default_rules["nat"].append("-N %s_ZONES_SOURCE" % chain)
136e2c
                     default_rules["nat"].append("-N %s_ZONES" % chain)
136e2c
-                    default_rules["nat"].append("-A %s -j %s_ZONES_SOURCE" % (chain, chain))
136e2c
+                    default_rules["nat"].append("-N %s_ZONES_IFACES" % chain)
136e2c
                     default_rules["nat"].append("-A %s -j %s_ZONES" % (chain, chain))
136e2c
-                    self.our_chains["nat"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
136e2c
+                    default_rules["nat"].append("-A %s_ZONES -g %s_ZONES_IFACES" % (chain, chain))
136e2c
+                    self.our_chains["nat"].update(set(["%s_ZONES" % chain, "%s_ZONES_IFACES" % chain]))
136e2c
 
136e2c
         default_rules["filter"] = [
136e2c
             "-N INPUT_direct",
136e2c
-            "-N INPUT_ZONES_SOURCE",
136e2c
             "-N INPUT_ZONES",
136e2c
+            "-N INPUT_ZONES_IFACES",
136e2c
 
136e2c
             "-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT",
136e2c
             "-A INPUT -i lo -j ACCEPT",
136e2c
             "-A INPUT -j INPUT_direct",
136e2c
-            "-A INPUT -j INPUT_ZONES_SOURCE",
136e2c
             "-A INPUT -j INPUT_ZONES",
136e2c
+            "-A INPUT_ZONES -g INPUT_ZONES_IFACES",
136e2c
         ]
136e2c
         if log_denied != "off":
136e2c
             default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '")
136e2c
@@ -582,18 +582,18 @@ class ip4tables(object):
136e2c
 
136e2c
         default_rules["filter"] += [
136e2c
             "-N FORWARD_direct",
136e2c
-            "-N FORWARD_IN_ZONES_SOURCE",
136e2c
             "-N FORWARD_IN_ZONES",
136e2c
-            "-N FORWARD_OUT_ZONES_SOURCE",
136e2c
             "-N FORWARD_OUT_ZONES",
136e2c
+            "-N FORWARD_IN_ZONES_IFACES",
136e2c
+            "-N FORWARD_OUT_ZONES_IFACES",
136e2c
 
136e2c
             "-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT",
136e2c
             "-A FORWARD -i lo -j ACCEPT",
136e2c
             "-A FORWARD -j FORWARD_direct",
136e2c
-            "-A FORWARD -j FORWARD_IN_ZONES_SOURCE",
136e2c
             "-A FORWARD -j FORWARD_IN_ZONES",
136e2c
-            "-A FORWARD -j FORWARD_OUT_ZONES_SOURCE",
136e2c
             "-A FORWARD -j FORWARD_OUT_ZONES",
136e2c
+            "-A FORWARD_IN_ZONES -g FORWARD_IN_ZONES_IFACES",
136e2c
+            "-A FORWARD_OUT_ZONES -g FORWARD_OUT_ZONES_IFACES",
136e2c
         ]
136e2c
         if log_denied != "off":
136e2c
             default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '")
136e2c
@@ -609,10 +609,10 @@ class ip4tables(object):
136e2c
             "-A OUTPUT -j OUTPUT_direct",
136e2c
         ]
136e2c
 
136e2c
-        self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES_SOURCE", "INPUT_ZONES",
136e2c
-                                    "FORWARD_direct", "FORWARD_IN_ZONES_SOURCE",
136e2c
-                                    "FORWARD_IN_ZONES", "FORWARD_OUT_ZONES_SOURCE",
136e2c
-                                    "FORWARD_OUT_ZONES", "OUTPUT_direct"])
136e2c
+        self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES", "INPUT_ZONES_IFACES"
136e2c
+                                         "FORWARD_direct", "FORWARD_IN_ZONES",
136e2c
+                                         "FORWARD_IN_ZONES_IFACES" "FORWARD_OUT_ZONES",
136e2c
+                                         "FORWARD_OUT_ZONES_IFACES", "OUTPUT_direct"])
136e2c
 
136e2c
         final_default_rules = []
136e2c
         for table in default_rules:
136e2c
@@ -639,9 +639,8 @@ class ip4tables(object):
136e2c
 
136e2c
         return {}
136e2c
 
136e2c
-    def build_zone_source_interface_rules(self, enable, zone, zone_target,
136e2c
-                                          interface, table, chain,
136e2c
-                                          append=False):
136e2c
+    def build_zone_source_interface_rules(self, enable, zone, interface,
136e2c
+                                          table, chain, append=False):
136e2c
         # handle all zones in the same way here, now
136e2c
         # trust and block zone targets are handled now in __chain
136e2c
         opt = {
136e2c
@@ -654,22 +653,20 @@ class ip4tables(object):
136e2c
         }[chain]
136e2c
 
136e2c
         target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone)
136e2c
-        if zone_target == DEFAULT_ZONE_TARGET:
136e2c
-            action = "-g"
136e2c
-        else:
136e2c
-            action = "-j"
136e2c
+        action = "-g"
136e2c
+
136e2c
         if enable and not append:
136e2c
-            rule = [ "-I", "%s_ZONES" % chain, "1" ]
136e2c
+            rule = [ "-I", "%s_ZONES_IFACES" % chain, "1" ]
136e2c
         elif enable:
136e2c
-            rule = [ "-A", "%s_ZONES" % chain ]
136e2c
+            rule = [ "-A", "%s_ZONES_IFACES" % chain ]
136e2c
         else:
136e2c
-            rule = [ "-D", "%s_ZONES" % chain ]
136e2c
+            rule = [ "-D", "%s_ZONES_IFACES" % chain ]
136e2c
         rule += [ "-t", table, opt, interface, action, target ]
136e2c
         return [rule]
136e2c
 
136e2c
-    def build_zone_source_address_rules(self, enable, zone, zone_target,
136e2c
+    def build_zone_source_address_rules(self, enable, zone,
136e2c
                                         address, table, chain):
136e2c
-        add_del = { True: "-A", False: "-D" }[enable]
136e2c
+        add_del = { True: "-I", False: "-D" }[enable]
136e2c
 
136e2c
         opt = {
136e2c
             "PREROUTING": "-s",
136e2c
@@ -681,10 +678,7 @@ class ip4tables(object):
136e2c
         }[chain]
136e2c
 
136e2c
         target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone)
136e2c
-        if zone_target == DEFAULT_ZONE_TARGET:
136e2c
-            action = "-g"
136e2c
-        else:
136e2c
-            action = "-j"
136e2c
+        action = "-g"
136e2c
 
136e2c
         if address.startswith("ipset:"):
136e2c
             name = address[6:]
136e2c
@@ -694,7 +688,7 @@ class ip4tables(object):
136e2c
                 opt = "src"
136e2c
             flags = ",".join([opt] * self._fw.ipset.get_dimension(name))
136e2c
             rule = [ add_del,
136e2c
-                     "%s_ZONES_SOURCE" % chain, "-t", table,
136e2c
+                     "%s_ZONES" % chain, "-t", table,
136e2c
                      "-m", "set", "--match-set", name,
136e2c
                      flags, action, target ]
136e2c
         else:
136e2c
@@ -703,12 +697,12 @@ class ip4tables(object):
136e2c
                 if opt == "-d":
136e2c
                     return ""
136e2c
                 rule = [ add_del,
136e2c
-                         "%s_ZONES_SOURCE" % chain, "-t", table,
136e2c
+                         "%s_ZONES" % chain, "-t", table,
136e2c
                          "-m", "mac", "--mac-source", address.upper(),
136e2c
                          action, target ]
136e2c
             else:
136e2c
                 rule = [ add_del,
136e2c
-                         "%s_ZONES_SOURCE" % chain, "-t", table,
136e2c
+                         "%s_ZONES" % chain, "-t", table,
136e2c
                          opt, address, action, target ]
136e2c
         return [rule]
136e2c
 
136e2c
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
136e2c
index bf41ed98a542..0fe686a01878 100644
136e2c
--- a/src/firewall/core/nftables.py
136e2c
+++ b/src/firewall/core/nftables.py
136e2c
@@ -358,11 +358,11 @@ class nftables(object):
136e2c
                                   IPTABLES_TO_NFT_HOOK["raw"][chain][0],
136e2c
                                   IPTABLES_TO_NFT_HOOK["raw"][chain][1]))
136e2c
 
136e2c
-            default_rules.append("add chain inet %s raw_%s_ZONES_SOURCE" % (TABLE_NAME, chain))
136e2c
             default_rules.append("add chain inet %s raw_%s_ZONES" % (TABLE_NAME, chain))
136e2c
-            default_rules.append("add rule inet %s raw_%s jump raw_%s_ZONES_SOURCE" % (TABLE_NAME, chain, chain))
136e2c
+            default_rules.append("add chain inet %s raw_%s_ZONES_IFACES" % (TABLE_NAME, chain))
136e2c
             default_rules.append("add rule inet %s raw_%s jump raw_%s_ZONES" % (TABLE_NAME, chain, chain))
136e2c
-            OUR_CHAINS["inet"]["raw"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
136e2c
+            default_rules.append("add rule inet %s raw_%s_ZONES goto raw_%s_ZONES_IFACES" % (TABLE_NAME, chain, chain))
136e2c
+            OUR_CHAINS["inet"]["raw"].update(set(["%s_ZONES_IFACES" % chain, "%s_ZONES" % chain]))
136e2c
 
136e2c
         OUR_CHAINS["inet"]["mangle"] = set()
136e2c
         for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys():
136e2c
@@ -371,11 +371,11 @@ class nftables(object):
136e2c
                                   IPTABLES_TO_NFT_HOOK["mangle"][chain][0],
136e2c
                                   IPTABLES_TO_NFT_HOOK["mangle"][chain][1]))
136e2c
 
136e2c
-            default_rules.append("add chain inet %s mangle_%s_ZONES_SOURCE" % (TABLE_NAME, chain))
136e2c
             default_rules.append("add chain inet %s mangle_%s_ZONES" % (TABLE_NAME, chain))
136e2c
-            default_rules.append("add rule inet %s mangle_%s jump mangle_%s_ZONES_SOURCE" % (TABLE_NAME, chain, chain))
136e2c
+            default_rules.append("add chain inet %s mangle_%s_ZONES_IFACES" % (TABLE_NAME, chain))
136e2c
             default_rules.append("add rule inet %s mangle_%s jump mangle_%s_ZONES" % (TABLE_NAME, chain, chain))
136e2c
-            OUR_CHAINS["inet"]["mangle"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
136e2c
+            default_rules.append("add rule inet %s mangle_%s_ZONES goto mangle_%s_ZONES_IFACES" % (TABLE_NAME, chain, chain))
136e2c
+            OUR_CHAINS["inet"]["mangle"].update(set(["%s_ZONES_IFACES" % chain, "%s_ZONES" % chain]))
136e2c
 
136e2c
         OUR_CHAINS["ip"]["nat"] = set()
136e2c
         OUR_CHAINS["ip6"]["nat"] = set()
136e2c
@@ -386,11 +386,11 @@ class nftables(object):
136e2c
                                       IPTABLES_TO_NFT_HOOK["nat"][chain][0],
136e2c
                                       IPTABLES_TO_NFT_HOOK["nat"][chain][1]))
136e2c
 
136e2c
-                default_rules.append("add chain %s %s nat_%s_ZONES_SOURCE" % (family, TABLE_NAME, chain))
136e2c
                 default_rules.append("add chain %s %s nat_%s_ZONES" % (family, TABLE_NAME, chain))
136e2c
-                default_rules.append("add rule %s %s nat_%s jump nat_%s_ZONES_SOURCE" % (family, TABLE_NAME, chain, chain))
136e2c
+                default_rules.append("add chain %s %s nat_%s_ZONES_IFACES" % (family, TABLE_NAME, chain))
136e2c
                 default_rules.append("add rule %s %s nat_%s jump nat_%s_ZONES" % (family, TABLE_NAME, chain, chain))
136e2c
-                OUR_CHAINS[family]["nat"].update(set(["%s_ZONES_SOURCE" % chain, "%s_ZONES" % chain]))
136e2c
+                default_rules.append("add rule %s %s nat_%s_ZONES goto nat_%s_ZONES_IFACES" % (family, TABLE_NAME, chain, chain))
136e2c
+                OUR_CHAINS[family]["nat"].update(set(["%s_ZONES_IFACES" % chain, "%s_ZONES" % chain]))
136e2c
 
136e2c
         OUR_CHAINS["inet"]["filter"] = set()
136e2c
         for chain in IPTABLES_TO_NFT_HOOK["filter"].keys():
136e2c
@@ -400,12 +400,12 @@ class nftables(object):
136e2c
                                   IPTABLES_TO_NFT_HOOK["filter"][chain][1]))
136e2c
 
136e2c
         # filter, INPUT
136e2c
-        default_rules.append("add chain inet %s filter_%s_ZONES_SOURCE" % (TABLE_NAME, "INPUT"))
136e2c
         default_rules.append("add chain inet %s filter_%s_ZONES" % (TABLE_NAME, "INPUT"))
136e2c
+        default_rules.append("add chain inet %s filter_%s_ZONES_IFACES" % (TABLE_NAME, "INPUT"))
136e2c
         default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "INPUT"))
136e2c
         default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "INPUT"))
136e2c
-        default_rules.append("add rule inet %s filter_%s jump filter_%s_ZONES_SOURCE" % (TABLE_NAME, "INPUT", "INPUT"))
136e2c
         default_rules.append("add rule inet %s filter_%s jump filter_%s_ZONES" % (TABLE_NAME, "INPUT", "INPUT"))
136e2c
+        default_rules.append("add rule inet %s filter_%s_ZONES goto filter_%s_ZONES_IFACES" % (TABLE_NAME, "INPUT", "INPUT"))
136e2c
         if log_denied != "off":
136e2c
             default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "INPUT"))
136e2c
         default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "INPUT"))
136e2c
@@ -414,16 +414,16 @@ class nftables(object):
136e2c
         default_rules.append("add rule inet %s filter_%s reject with icmpx type admin-prohibited" % (TABLE_NAME, "INPUT"))
136e2c
 
136e2c
         # filter, FORWARD
136e2c
-        default_rules.append("add chain inet %s filter_%s_IN_ZONES_SOURCE" % (TABLE_NAME, "FORWARD"))
136e2c
         default_rules.append("add chain inet %s filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD"))
136e2c
-        default_rules.append("add chain inet %s filter_%s_OUT_ZONES_SOURCE" % (TABLE_NAME, "FORWARD"))
136e2c
+        default_rules.append("add chain inet %s filter_%s_IN_ZONES_IFACES" % (TABLE_NAME, "FORWARD"))
136e2c
         default_rules.append("add chain inet %s filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD"))
136e2c
+        default_rules.append("add chain inet %s filter_%s_OUT_ZONES_IFACES" % (TABLE_NAME, "FORWARD"))
136e2c
         default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "FORWARD"))
136e2c
         default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "FORWARD"))
136e2c
-        default_rules.append("add rule inet %s filter_%s jump filter_%s_IN_ZONES_SOURCE" % (TABLE_NAME, "FORWARD", "FORWARD"))
136e2c
         default_rules.append("add rule inet %s filter_%s jump filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD"))
136e2c
-        default_rules.append("add rule inet %s filter_%s jump filter_%s_OUT_ZONES_SOURCE" % (TABLE_NAME, "FORWARD", "FORWARD"))
136e2c
         default_rules.append("add rule inet %s filter_%s jump filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD"))
136e2c
+        default_rules.append("add rule inet %s filter_%s_IN_ZONES goto filter_%s_IN_ZONES_IFACES" % (TABLE_NAME, "FORWARD", "FORWARD"))
136e2c
+        default_rules.append("add rule inet %s filter_%s_OUT_ZONES goto filter_%s_OUT_ZONES_IFACES" % (TABLE_NAME, "FORWARD", "FORWARD"))
136e2c
         if log_denied != "off":
136e2c
             default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "FORWARD"))
136e2c
         default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "FORWARD"))
136e2c
@@ -452,16 +452,16 @@ class nftables(object):
136e2c
 
136e2c
         return {}
136e2c
 
136e2c
-    def build_zone_source_interface_rules(self, enable, zone, zone_target,
136e2c
-                                          interface, table, chain,
136e2c
-                                          append=False, family="inet"):
136e2c
+    def build_zone_source_interface_rules(self, enable, zone, interface,
136e2c
+                                          table, chain, append=False,
136e2c
+                                          family="inet"):
136e2c
         # nat tables needs to use ip/ip6 family
136e2c
         if table == "nat" and family == "inet":
136e2c
             rules = []
136e2c
             rules.extend(self.build_zone_source_interface_rules(enable, zone,
136e2c
-                            zone_target, interface, table, chain, append, "ip"))
136e2c
+                            interface, table, chain, append, "ip"))
136e2c
             rules.extend(self.build_zone_source_interface_rules(enable, zone,
136e2c
-                            zone_target, interface, table, chain, append, "ip6"))
136e2c
+                            interface, table, chain, append, "ip6"))
136e2c
             return rules
136e2c
 
136e2c
         # handle all zones in the same way here, now
136e2c
@@ -479,36 +479,34 @@ class nftables(object):
136e2c
             interface = interface[:len(interface)-1] + "*"
136e2c
 
136e2c
         target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone)
136e2c
-        if zone_target == DEFAULT_ZONE_TARGET:
136e2c
-            action = "goto"
136e2c
-        else:
136e2c
-            action = "jump"
136e2c
+        action = "goto"
136e2c
+
136e2c
         if enable and not append:
136e2c
-            rule = ["insert", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)]
136e2c
+            rule = ["insert", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)]
136e2c
         elif enable:
136e2c
-            rule = ["add", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)]
136e2c
+            rule = ["add", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)]
136e2c
         else:
136e2c
-            rule = ["delete", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)]
136e2c
+            rule = ["delete", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)]
136e2c
         if interface == "*":
136e2c
             rule += [action, "%s_%s" % (table, target)]
136e2c
         else:
136e2c
             rule += [opt, "\"" + interface + "\"", action, "%s_%s" % (table, target)]
136e2c
         return [rule]
136e2c
 
136e2c
-    def build_zone_source_address_rules(self, enable, zone, zone_target,
136e2c
+    def build_zone_source_address_rules(self, enable, zone,
136e2c
                                         address, table, chain, family="inet"):
136e2c
         # nat tables needs to use ip/ip6 family
136e2c
         if table == "nat" and family == "inet":
136e2c
             rules = []
136e2c
             if check_address("ipv4", address) or check_mac(address):
136e2c
                 rules.extend(self.build_zone_source_address_rules(enable, zone,
136e2c
-                                    zone_target, address, table, chain, "ip"))
136e2c
+                                    address, table, chain, "ip"))
136e2c
             if check_address("ipv6", address) or check_mac(address):
136e2c
                 rules.extend(self.build_zone_source_address_rules(enable, zone,
136e2c
-                                    zone_target, address, table, chain, "ip6"))
136e2c
+                                    address, table, chain, "ip6"))
136e2c
             return rules
136e2c
 
136e2c
-        add_del = { True: "add", False: "delete" }[enable]
136e2c
+        add_del = { True: "insert", False: "delete" }[enable]
136e2c
 
136e2c
         opt = {
136e2c
             "PREROUTING": "saddr",
136e2c
@@ -520,10 +518,7 @@ class nftables(object):
136e2c
         }[chain]
136e2c
 
136e2c
         target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone)
136e2c
-        if zone_target == DEFAULT_ZONE_TARGET:
136e2c
-            action = "goto"
136e2c
-        else:
136e2c
-            action = "jump"
136e2c
+        action = "goto"
136e2c
 
136e2c
         if address.startswith("ipset:"):
136e2c
             ipset = address[len("ipset:"):]
136e2c
@@ -541,7 +536,7 @@ class nftables(object):
136e2c
                 rule_family = "ip6"
136e2c
 
136e2c
         rule = [add_del, "rule", family, "%s" % TABLE_NAME,
136e2c
-                "%s_%s_ZONES_SOURCE" % (table, chain),
136e2c
+                "%s_%s_ZONES" % (table, chain),
136e2c
                 rule_family, opt, address, action, "%s_%s" % (table, target)]
136e2c
         return [rule]
136e2c
 
136e2c
diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at
136e2c
index a3844151aeb3..0f9cac204ccd 100644
136e2c
--- a/src/tests/firewall-cmd.at
136e2c
+++ b/src/tests/firewall-cmd.at
136e2c
@@ -138,14 +138,14 @@ FWD_START_TEST([zone interfaces])
136e2c
     FWD_CHECK([--add-interface=foobar+++], 0, ignore)
136e2c
     FWD_CHECK([--add-interface=foobar+], 0, ignore)
136e2c
     m4_if(nftables, FIREWALL_BACKEND, [
136e2c
-    NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl
136e2c
+    NFT_LIST_RULES([inet], [filter_INPUT_ZONES_IFACES], 0, [dnl
136e2c
         table inet firewalld {
136e2c
-        chain filter_INPUT_ZONES {
136e2c
+        chain filter_INPUT_ZONES_IFACES {
136e2c
             iifname "foobar*" goto filter_IN_public
136e2c
             iifname "foobar++*" goto filter_IN_public
136e2c
-            jump filter_IN_trusted
136e2c
+            goto filter_IN_trusted
136e2c
             iifname "perm_dummy" goto filter_IN_work
136e2c
-            iifname "perm_dummy2" jump filter_IN_trusted
136e2c
+            iifname "perm_dummy2" goto filter_IN_trusted
136e2c
             goto filter_IN_public
136e2c
         }
136e2c
         }
136e2c
-- 
136e2c
2.20.1
136e2c