|
|
136e2c |
From f317fbc7e7ad1094b4cfb7570af29772d1a02fd7 Mon Sep 17 00:00:00 2001
|
|
|
136e2c |
From: Eric Garver <eric@garver.life>
|
|
|
136e2c |
Date: Wed, 31 Jul 2019 13:57:10 -0400
|
|
|
136e2c |
Subject: [PATCH 74/79] fix: guarantee zone source dispatch is sorted by zone
|
|
|
136e2c |
name
|
|
|
136e2c |
|
|
|
136e2c |
Apparently users depend on firewalld sorting zone dispatch for sources
|
|
|
136e2c |
by the zone name. This is used to specify precedence for overlapping
|
|
|
136e2c |
address spaces.
|
|
|
136e2c |
|
|
|
136e2c |
Since we have to track rule positions of source based dispatch we might
|
|
|
136e2c |
as well abuse this and combine the source/interface dispatch into a
|
|
|
136e2c |
single chain.
|
|
|
136e2c |
|
|
|
136e2c |
Fixes: rhbz 1734765
|
|
|
136e2c |
Fixes: 70993581d79b ("fix: do not allow zone drifting")
|
|
|
136e2c |
(cherry picked from commit afc35c20e58b00b81cd2e1f3e863b3b3bac37c77)
|
|
|
136e2c |
(cherry picked from commit a3542499510658b7d93a83d47d3de090860d6e37)
|
|
|
136e2c |
---
|
|
|
136e2c |
src/firewall/core/ipXtables.py | 93 ++++++++---
|
|
|
136e2c |
src/firewall/core/nftables.py | 93 ++++++++---
|
|
|
136e2c |
src/tests/firewall-cmd.at | 4 +-
|
|
|
136e2c |
src/tests/regression/gh258.at | 274 ++++++++++-----------------------
|
|
|
136e2c |
4 files changed, 223 insertions(+), 241 deletions(-)
|
|
|
136e2c |
|
|
|
136e2c |
diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py
|
|
|
136e2c |
index c2339e40539a..647a7a161517 100644
|
|
|
136e2c |
--- a/src/firewall/core/ipXtables.py
|
|
|
136e2c |
+++ b/src/firewall/core/ipXtables.py
|
|
|
136e2c |
@@ -20,6 +20,7 @@
|
|
|
136e2c |
#
|
|
|
136e2c |
|
|
|
136e2c |
import os.path
|
|
|
136e2c |
+import copy
|
|
|
136e2c |
|
|
|
136e2c |
from firewall.core.base import SHORTCUTS, DEFAULT_ZONE_TARGET
|
|
|
136e2c |
from firewall.core.prog import runProg
|
|
|
136e2c |
@@ -175,6 +176,7 @@ class ip4tables(object):
|
|
|
136e2c |
self.restore_wait_option = self._detect_restore_wait_option()
|
|
|
136e2c |
self.fill_exists()
|
|
|
136e2c |
self.available_tables = []
|
|
|
136e2c |
+ self.zone_source_index_cache = []
|
|
|
136e2c |
self.our_chains = {} # chains created by firewalld
|
|
|
136e2c |
|
|
|
136e2c |
def fill_exists(self):
|
|
|
136e2c |
@@ -286,10 +288,49 @@ class ip4tables(object):
|
|
|
136e2c |
chain = args[i+1]
|
|
|
136e2c |
return (table, chain)
|
|
|
136e2c |
|
|
|
136e2c |
+ def _run_replace_zone_source(self, rule, zone_source_index_cache):
|
|
|
136e2c |
+ try:
|
|
|
136e2c |
+ i = rule.index("%%ZONE_SOURCE%%")
|
|
|
136e2c |
+ rule.pop(i)
|
|
|
136e2c |
+ zone = rule.pop(i)
|
|
|
136e2c |
+ if "-m" == rule[4]: # ipset/mac
|
|
|
136e2c |
+ zone_source = (zone, rule[7]) # (zone, address)
|
|
|
136e2c |
+ else:
|
|
|
136e2c |
+ zone_source = (zone, rule[5]) # (zone, address)
|
|
|
136e2c |
+ except ValueError:
|
|
|
136e2c |
+ try:
|
|
|
136e2c |
+ i = rule.index("%%ZONE_INTERFACE%%")
|
|
|
136e2c |
+ rule.pop(i)
|
|
|
136e2c |
+ zone_source = None
|
|
|
136e2c |
+ except ValueError:
|
|
|
136e2c |
+ return
|
|
|
136e2c |
+
|
|
|
136e2c |
+ rule_add = True
|
|
|
136e2c |
+ if rule[0] in ["-D", "--delete"]:
|
|
|
136e2c |
+ rule_add = False
|
|
|
136e2c |
+
|
|
|
136e2c |
+ if zone_source and not rule_add:
|
|
|
136e2c |
+ if zone_source in zone_source_index_cache:
|
|
|
136e2c |
+ zone_source_index_cache.remove(zone_source)
|
|
|
136e2c |
+ elif rule_add:
|
|
|
136e2c |
+ if zone_source:
|
|
|
136e2c |
+ # order source based dispatch by zone name
|
|
|
136e2c |
+ if zone_source not in zone_source_index_cache:
|
|
|
136e2c |
+ zone_source_index_cache.append(zone_source)
|
|
|
136e2c |
+ zone_source_index_cache.sort(key=lambda x: x[0])
|
|
|
136e2c |
+
|
|
|
136e2c |
+ index = zone_source_index_cache.index(zone_source)
|
|
|
136e2c |
+ else:
|
|
|
136e2c |
+ index = len(zone_source_index_cache)
|
|
|
136e2c |
+
|
|
|
136e2c |
+ rule[0] = "-I"
|
|
|
136e2c |
+ rule.insert(2, "%d" % (index + 1))
|
|
|
136e2c |
+
|
|
|
136e2c |
def set_rules(self, rules, log_denied):
|
|
|
136e2c |
temp_file = tempFile()
|
|
|
136e2c |
|
|
|
136e2c |
table_rules = { }
|
|
|
136e2c |
+ zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache)
|
|
|
136e2c |
for _rule in rules:
|
|
|
136e2c |
rule = _rule[:]
|
|
|
136e2c |
|
|
|
136e2c |
@@ -313,6 +354,8 @@ class ip4tables(object):
|
|
|
136e2c |
else:
|
|
|
136e2c |
rule.pop(i)
|
|
|
136e2c |
|
|
|
136e2c |
+ self._run_replace_zone_source(rule, zone_source_index_cache)
|
|
|
136e2c |
+
|
|
|
136e2c |
table = "filter"
|
|
|
136e2c |
# get table form rule
|
|
|
136e2c |
for opt in [ "-t", "--table" ]:
|
|
|
136e2c |
@@ -374,6 +417,7 @@ class ip4tables(object):
|
|
|
136e2c |
if status != 0:
|
|
|
136e2c |
raise ValueError("'%s %s' failed: %s" % (self._restore_command,
|
|
|
136e2c |
" ".join(args), ret))
|
|
|
136e2c |
+ self.zone_source_index_cache = zone_source_index_cache
|
|
|
136e2c |
return ret
|
|
|
136e2c |
|
|
|
136e2c |
def set_rule(self, rule, log_denied):
|
|
|
136e2c |
@@ -397,7 +441,13 @@ class ip4tables(object):
|
|
|
136e2c |
else:
|
|
|
136e2c |
rule.pop(i)
|
|
|
136e2c |
|
|
|
136e2c |
- return self.__run(rule)
|
|
|
136e2c |
+ zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache)
|
|
|
136e2c |
+ self._run_replace_zone_source(rule, zone_source_index_cache)
|
|
|
136e2c |
+
|
|
|
136e2c |
+ output = self.__run(rule)
|
|
|
136e2c |
+
|
|
|
136e2c |
+ self.zone_source_index_cache = zone_source_index_cache
|
|
|
136e2c |
+ return output
|
|
|
136e2c |
|
|
|
136e2c |
def get_available_tables(self, table=None):
|
|
|
136e2c |
ret = []
|
|
|
136e2c |
@@ -447,6 +497,7 @@ class ip4tables(object):
|
|
|
136e2c |
return wait_option
|
|
|
136e2c |
|
|
|
136e2c |
def build_flush_rules(self):
|
|
|
136e2c |
+ self.zone_source_index_cache = []
|
|
|
136e2c |
rules = []
|
|
|
136e2c |
for table in BUILT_IN_CHAINS.keys():
|
|
|
136e2c |
if not self.get_available_tables(table):
|
|
|
136e2c |
@@ -527,10 +578,8 @@ class ip4tables(object):
|
|
|
136e2c |
|
|
|
136e2c |
if chain == "PREROUTING":
|
|
|
136e2c |
default_rules["raw"].append("-N %s_ZONES" % chain)
|
|
|
136e2c |
- default_rules["raw"].append("-N %s_ZONES_IFACES" % chain)
|
|
|
136e2c |
default_rules["raw"].append("-A %s -j %s_ZONES" % (chain, 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 |
+ self.our_chains["raw"].update(set(["%s_ZONES" % chain]))
|
|
|
136e2c |
|
|
|
136e2c |
if self.get_available_tables("mangle"):
|
|
|
136e2c |
default_rules["mangle"] = [ ]
|
|
|
136e2c |
@@ -542,10 +591,8 @@ class ip4tables(object):
|
|
|
136e2c |
|
|
|
136e2c |
if chain == "PREROUTING":
|
|
|
136e2c |
default_rules["mangle"].append("-N %s_ZONES" % chain)
|
|
|
136e2c |
- default_rules["mangle"].append("-N %s_ZONES_IFACES" % chain)
|
|
|
136e2c |
default_rules["mangle"].append("-A %s -j %s_ZONES" % (chain, 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 |
+ self.our_chains["mangle"].update(set(["%s_ZONES" % chain]))
|
|
|
136e2c |
|
|
|
136e2c |
if self.get_available_tables("nat"):
|
|
|
136e2c |
default_rules["nat"] = [ ]
|
|
|
136e2c |
@@ -557,21 +604,17 @@ class ip4tables(object):
|
|
|
136e2c |
|
|
|
136e2c |
if chain in [ "PREROUTING", "POSTROUTING" ]:
|
|
|
136e2c |
default_rules["nat"].append("-N %s_ZONES" % chain)
|
|
|
136e2c |
- default_rules["nat"].append("-N %s_ZONES_IFACES" % chain)
|
|
|
136e2c |
default_rules["nat"].append("-A %s -j %s_ZONES" % (chain, 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 |
+ self.our_chains["nat"].update(set(["%s_ZONES" % chain]))
|
|
|
136e2c |
|
|
|
136e2c |
default_rules["filter"] = [
|
|
|
136e2c |
"-N INPUT_direct",
|
|
|
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",
|
|
|
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 |
@@ -584,16 +627,12 @@ class ip4tables(object):
|
|
|
136e2c |
"-N FORWARD_direct",
|
|
|
136e2c |
"-N FORWARD_IN_ZONES",
|
|
|
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",
|
|
|
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 +648,9 @@ class ip4tables(object):
|
|
|
136e2c |
"-A OUTPUT -j OUTPUT_direct",
|
|
|
136e2c |
]
|
|
|
136e2c |
|
|
|
136e2c |
- self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES", "INPUT_ZONES_IFACES"
|
|
|
136e2c |
+ self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES",
|
|
|
136e2c |
"FORWARD_direct", "FORWARD_IN_ZONES",
|
|
|
136e2c |
- "FORWARD_IN_ZONES_IFACES" "FORWARD_OUT_ZONES",
|
|
|
136e2c |
- "FORWARD_OUT_ZONES_IFACES", "OUTPUT_direct"])
|
|
|
136e2c |
+ "FORWARD_OUT_ZONES", "OUTPUT_direct"])
|
|
|
136e2c |
|
|
|
136e2c |
final_default_rules = []
|
|
|
136e2c |
for table in default_rules:
|
|
|
136e2c |
@@ -656,11 +694,13 @@ class ip4tables(object):
|
|
|
136e2c |
action = "-g"
|
|
|
136e2c |
|
|
|
136e2c |
if enable and not append:
|
|
|
136e2c |
- rule = [ "-I", "%s_ZONES_IFACES" % chain, "1" ]
|
|
|
136e2c |
+ rule = [ "-I", "%s_ZONES" % chain, "%%ZONE_INTERFACE%%" ]
|
|
|
136e2c |
elif enable:
|
|
|
136e2c |
- rule = [ "-A", "%s_ZONES_IFACES" % chain ]
|
|
|
136e2c |
+ rule = [ "-A", "%s_ZONES" % chain ]
|
|
|
136e2c |
else:
|
|
|
136e2c |
- rule = [ "-D", "%s_ZONES_IFACES" % chain ]
|
|
|
136e2c |
+ rule = [ "-D", "%s_ZONES" % chain ]
|
|
|
136e2c |
+ if not append:
|
|
|
136e2c |
+ rule += ["%%ZONE_INTERFACE%%"]
|
|
|
136e2c |
rule += [ "-t", table, opt, interface, action, target ]
|
|
|
136e2c |
return [rule]
|
|
|
136e2c |
|
|
|
136e2c |
@@ -688,7 +728,8 @@ class ip4tables(object):
|
|
|
136e2c |
opt = "src"
|
|
|
136e2c |
flags = ",".join([opt] * self._fw.ipset.get_dimension(name))
|
|
|
136e2c |
rule = [ add_del,
|
|
|
136e2c |
- "%s_ZONES" % chain, "-t", table,
|
|
|
136e2c |
+ "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone,
|
|
|
136e2c |
+ "-t", table,
|
|
|
136e2c |
"-m", "set", "--match-set", name,
|
|
|
136e2c |
flags, action, target ]
|
|
|
136e2c |
else:
|
|
|
136e2c |
@@ -697,12 +738,14 @@ class ip4tables(object):
|
|
|
136e2c |
if opt == "-d":
|
|
|
136e2c |
return ""
|
|
|
136e2c |
rule = [ add_del,
|
|
|
136e2c |
- "%s_ZONES" % chain, "-t", table,
|
|
|
136e2c |
+ "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone,
|
|
|
136e2c |
+ "-t", table,
|
|
|
136e2c |
"-m", "mac", "--mac-source", address.upper(),
|
|
|
136e2c |
action, target ]
|
|
|
136e2c |
else:
|
|
|
136e2c |
rule = [ add_del,
|
|
|
136e2c |
- "%s_ZONES" % chain, "-t", table,
|
|
|
136e2c |
+ "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone,
|
|
|
136e2c |
+ "-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 0fe686a01878..05376fdd68d8 100644
|
|
|
136e2c |
--- a/src/firewall/core/nftables.py
|
|
|
136e2c |
+++ b/src/firewall/core/nftables.py
|
|
|
136e2c |
@@ -20,6 +20,7 @@
|
|
|
136e2c |
#
|
|
|
136e2c |
|
|
|
136e2c |
import os.path
|
|
|
136e2c |
+import copy
|
|
|
136e2c |
|
|
|
136e2c |
from firewall.core.base import SHORTCUTS, DEFAULT_ZONE_TARGET
|
|
|
136e2c |
from firewall.core.prog import runProg
|
|
|
136e2c |
@@ -160,11 +161,54 @@ class nftables(object):
|
|
|
136e2c |
self.available_tables = []
|
|
|
136e2c |
self.rule_to_handle = {}
|
|
|
136e2c |
self.rule_ref_count = {}
|
|
|
136e2c |
+ self.zone_source_index_cache = {}
|
|
|
136e2c |
|
|
|
136e2c |
def fill_exists(self):
|
|
|
136e2c |
self.command_exists = os.path.exists(self._command)
|
|
|
136e2c |
self.restore_command_exists = False
|
|
|
136e2c |
|
|
|
136e2c |
+ def _run_replace_zone_source(self, rule_add, rule, zone_source_index_cache):
|
|
|
136e2c |
+ try:
|
|
|
136e2c |
+ i = rule.index("%%ZONE_SOURCE%%")
|
|
|
136e2c |
+ rule.pop(i)
|
|
|
136e2c |
+ zone = rule.pop(i)
|
|
|
136e2c |
+ zone_source = (zone, rule[7]) # (zone, address)
|
|
|
136e2c |
+ except ValueError:
|
|
|
136e2c |
+ try:
|
|
|
136e2c |
+ i = rule.index("%%ZONE_INTERFACE%%")
|
|
|
136e2c |
+ rule.pop(i)
|
|
|
136e2c |
+ zone_source = None
|
|
|
136e2c |
+ except ValueError:
|
|
|
136e2c |
+ return
|
|
|
136e2c |
+
|
|
|
136e2c |
+ family = rule[2]
|
|
|
136e2c |
+
|
|
|
136e2c |
+ if zone_source and not rule_add:
|
|
|
136e2c |
+ if family in zone_source_index_cache and \
|
|
|
136e2c |
+ zone_source in zone_source_index_cache[family]:
|
|
|
136e2c |
+ zone_source_index_cache[family].remove(zone_source)
|
|
|
136e2c |
+ elif rule_add:
|
|
|
136e2c |
+ if family not in zone_source_index_cache:
|
|
|
136e2c |
+ zone_source_index_cache[family] = []
|
|
|
136e2c |
+
|
|
|
136e2c |
+ if zone_source:
|
|
|
136e2c |
+ # order source based dispatch by zone name
|
|
|
136e2c |
+ if zone_source not in zone_source_index_cache[family]:
|
|
|
136e2c |
+ zone_source_index_cache[family].append(zone_source)
|
|
|
136e2c |
+ zone_source_index_cache[family].sort(key=lambda x: x[0])
|
|
|
136e2c |
+
|
|
|
136e2c |
+ index = zone_source_index_cache[family].index(zone_source)
|
|
|
136e2c |
+ else:
|
|
|
136e2c |
+ index = len(zone_source_index_cache[family])
|
|
|
136e2c |
+
|
|
|
136e2c |
+ if index == 0:
|
|
|
136e2c |
+ rule[0] = "insert"
|
|
|
136e2c |
+ else:
|
|
|
136e2c |
+ index -= 1 # point to the rule before insertion point
|
|
|
136e2c |
+ rule[0] = "add"
|
|
|
136e2c |
+ rule.insert(i, "index")
|
|
|
136e2c |
+ rule.insert(i+1, "%d" % index)
|
|
|
136e2c |
+
|
|
|
136e2c |
def __run(self, args):
|
|
|
136e2c |
nft_opts = ["--echo", "--handle"]
|
|
|
136e2c |
_args = args[:]
|
|
|
136e2c |
@@ -198,11 +242,6 @@ class nftables(object):
|
|
|
136e2c |
rule_add = False
|
|
|
136e2c |
rule_key = _args[2:]
|
|
|
136e2c |
rule_key = " ".join(rule_key)
|
|
|
136e2c |
- # delete using rule handle
|
|
|
136e2c |
- _args = ["delete", "rule"] + _args[2:5] + \
|
|
|
136e2c |
- ["handle", self.rule_to_handle[rule_key]]
|
|
|
136e2c |
-
|
|
|
136e2c |
- _args_str = " ".join(_args)
|
|
|
136e2c |
|
|
|
136e2c |
# rule deduplication
|
|
|
136e2c |
if rule_key in self.rule_ref_count:
|
|
|
136e2c |
@@ -218,15 +257,28 @@ class nftables(object):
|
|
|
136e2c |
raise FirewallError(UNKNOWN_ERROR, "rule ref count bug: rule_key '%s', cnt %d"
|
|
|
136e2c |
% (rule_key, self.rule_ref_count[rule_key]))
|
|
|
136e2c |
log.debug2("%s: rule ref cnt %d, %s %s", self.__class__,
|
|
|
136e2c |
- self.rule_ref_count[rule_key], self._command, _args_str)
|
|
|
136e2c |
+ self.rule_ref_count[rule_key], self._command, " ".join(_args))
|
|
|
136e2c |
+
|
|
|
136e2c |
+ if rule_key:
|
|
|
136e2c |
+ zone_source_index_cache = copy.deepcopy(self.zone_source_index_cache)
|
|
|
136e2c |
+ self._run_replace_zone_source(rule_add, _args, zone_source_index_cache)
|
|
|
136e2c |
|
|
|
136e2c |
if not rule_key or (not rule_add and self.rule_ref_count[rule_key] == 0) \
|
|
|
136e2c |
or ( rule_add and rule_key not in self.rule_ref_count):
|
|
|
136e2c |
+ # delete using rule handle
|
|
|
136e2c |
+ if rule_key and not rule_add:
|
|
|
136e2c |
+ _args = ["delete", "rule"] + _args[2:5] + \
|
|
|
136e2c |
+ ["handle", self.rule_to_handle[rule_key]]
|
|
|
136e2c |
+ _args_str = " ".join(_args)
|
|
|
136e2c |
log.debug2("%s: %s %s", self.__class__, self._command, _args_str)
|
|
|
136e2c |
(status, output) = runProg(self._command, nft_opts + _args)
|
|
|
136e2c |
if status != 0:
|
|
|
136e2c |
raise ValueError("'%s %s' failed: %s" % (self._command,
|
|
|
136e2c |
_args_str, output))
|
|
|
136e2c |
+
|
|
|
136e2c |
+ if rule_key:
|
|
|
136e2c |
+ self.zone_source_index_cache = zone_source_index_cache
|
|
|
136e2c |
+
|
|
|
136e2c |
# nft requires deleting rules by handle. So we must cache the rule
|
|
|
136e2c |
# handle when adding/inserting rules.
|
|
|
136e2c |
#
|
|
|
136e2c |
@@ -303,6 +355,7 @@ class nftables(object):
|
|
|
136e2c |
def build_flush_rules(self):
|
|
|
136e2c |
self.rule_to_handle = {}
|
|
|
136e2c |
self.rule_ref_count = {}
|
|
|
136e2c |
+ self.zone_source_index_cache = {}
|
|
|
136e2c |
|
|
|
136e2c |
rules = []
|
|
|
136e2c |
for family in OUR_CHAINS.keys():
|
|
|
136e2c |
@@ -359,10 +412,8 @@ class nftables(object):
|
|
|
136e2c |
IPTABLES_TO_NFT_HOOK["raw"][chain][1]))
|
|
|
136e2c |
|
|
|
136e2c |
default_rules.append("add chain inet %s raw_%s_ZONES" % (TABLE_NAME, 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 |
- 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 |
+ OUR_CHAINS["inet"]["raw"].update(set(["%s_ZONES" % chain]))
|
|
|
136e2c |
|
|
|
136e2c |
OUR_CHAINS["inet"]["mangle"] = set()
|
|
|
136e2c |
for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys():
|
|
|
136e2c |
@@ -372,10 +423,8 @@ class nftables(object):
|
|
|
136e2c |
IPTABLES_TO_NFT_HOOK["mangle"][chain][1]))
|
|
|
136e2c |
|
|
|
136e2c |
default_rules.append("add chain inet %s mangle_%s_ZONES" % (TABLE_NAME, 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 |
- 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 |
+ OUR_CHAINS["inet"]["mangle"].update(set(["%s_ZONES" % chain]))
|
|
|
136e2c |
|
|
|
136e2c |
OUR_CHAINS["ip"]["nat"] = set()
|
|
|
136e2c |
OUR_CHAINS["ip6"]["nat"] = set()
|
|
|
136e2c |
@@ -387,10 +436,8 @@ class nftables(object):
|
|
|
136e2c |
IPTABLES_TO_NFT_HOOK["nat"][chain][1]))
|
|
|
136e2c |
|
|
|
136e2c |
default_rules.append("add chain %s %s nat_%s_ZONES" % (family, TABLE_NAME, 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 |
- 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 |
+ OUR_CHAINS[family]["nat"].update(set(["%s_ZONES" % chain]))
|
|
|
136e2c |
|
|
|
136e2c |
OUR_CHAINS["inet"]["filter"] = set()
|
|
|
136e2c |
for chain in IPTABLES_TO_NFT_HOOK["filter"].keys():
|
|
|
136e2c |
@@ -401,11 +448,9 @@ class nftables(object):
|
|
|
136e2c |
|
|
|
136e2c |
# filter, 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" % (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 |
@@ -415,15 +460,11 @@ class nftables(object):
|
|
|
136e2c |
|
|
|
136e2c |
# filter, 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_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" % (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 |
@@ -482,11 +523,14 @@ class nftables(object):
|
|
|
136e2c |
action = "goto"
|
|
|
136e2c |
|
|
|
136e2c |
if enable and not append:
|
|
|
136e2c |
- rule = ["insert", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)]
|
|
|
136e2c |
+ rule = ["insert", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain),
|
|
|
136e2c |
+ "%%ZONE_INTERFACE%%"]
|
|
|
136e2c |
elif enable:
|
|
|
136e2c |
- rule = ["add", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)]
|
|
|
136e2c |
+ rule = ["add", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)]
|
|
|
136e2c |
else:
|
|
|
136e2c |
- rule = ["delete", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES_IFACES" % (table, chain)]
|
|
|
136e2c |
+ rule = ["delete", "rule", family, "%s" % TABLE_NAME, "%s_%s_ZONES" % (table, chain)]
|
|
|
136e2c |
+ if not append:
|
|
|
136e2c |
+ rule += ["%%ZONE_INTERFACE%%"]
|
|
|
136e2c |
if interface == "*":
|
|
|
136e2c |
rule += [action, "%s_%s" % (table, target)]
|
|
|
136e2c |
else:
|
|
|
136e2c |
@@ -537,6 +581,7 @@ class nftables(object):
|
|
|
136e2c |
|
|
|
136e2c |
rule = [add_del, "rule", family, "%s" % TABLE_NAME,
|
|
|
136e2c |
"%s_%s_ZONES" % (table, chain),
|
|
|
136e2c |
+ "%%ZONE_SOURCE%%", zone,
|
|
|
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 28948636172d..6a4b670d7935 100644
|
|
|
136e2c |
--- a/src/tests/firewall-cmd.at
|
|
|
136e2c |
+++ b/src/tests/firewall-cmd.at
|
|
|
136e2c |
@@ -138,9 +138,9 @@ 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_IFACES], 0, [dnl
|
|
|
136e2c |
+ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl
|
|
|
136e2c |
table inet firewalld {
|
|
|
136e2c |
- chain filter_INPUT_ZONES_IFACES {
|
|
|
136e2c |
+ chain filter_INPUT_ZONES {
|
|
|
136e2c |
iifname "foobar*" goto filter_IN_public
|
|
|
136e2c |
iifname "foobar++*" goto filter_IN_public
|
|
|
136e2c |
goto filter_IN_trusted
|
|
|
136e2c |
diff --git a/src/tests/regression/gh258.at b/src/tests/regression/gh258.at
|
|
|
136e2c |
index 3e5e961f6599..fb863c35528e 100644
|
|
|
136e2c |
--- a/src/tests/regression/gh258.at
|
|
|
136e2c |
+++ b/src/tests/regression/gh258.at
|
|
|
136e2c |
@@ -26,13 +26,6 @@ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl
|
|
|
136e2c |
chain filter_INPUT_ZONES {
|
|
|
136e2c |
ip6 saddr dead:beef::/54 goto filter_IN_public
|
|
|
136e2c |
ip saddr 1.2.3.0/24 goto filter_IN_work
|
|
|
136e2c |
- goto filter_INPUT_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([inet], [filter_INPUT_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table inet firewalld {
|
|
|
136e2c |
- chain filter_INPUT_ZONES_IFACES {
|
|
|
136e2c |
iifname "dummy1" goto filter_IN_public
|
|
|
136e2c |
iifname "dummy0" goto filter_IN_work
|
|
|
136e2c |
goto filter_IN_public
|
|
|
136e2c |
@@ -56,13 +49,6 @@ NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES], 0, [dnl
|
|
|
136e2c |
chain filter_FORWARD_IN_ZONES {
|
|
|
136e2c |
ip6 saddr dead:beef::/54 goto filter_FWDI_public
|
|
|
136e2c |
ip saddr 1.2.3.0/24 goto filter_FWDI_work
|
|
|
136e2c |
- goto filter_FORWARD_IN_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table inet firewalld {
|
|
|
136e2c |
- chain filter_FORWARD_IN_ZONES_IFACES {
|
|
|
136e2c |
iifname "dummy1" goto filter_FWDI_public
|
|
|
136e2c |
iifname "dummy0" goto filter_FWDI_work
|
|
|
136e2c |
goto filter_FWDI_public
|
|
|
136e2c |
@@ -74,13 +60,6 @@ NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES], 0, [dnl
|
|
|
136e2c |
chain filter_FORWARD_OUT_ZONES {
|
|
|
136e2c |
ip6 daddr dead:beef::/54 goto filter_FWDO_public
|
|
|
136e2c |
ip daddr 1.2.3.0/24 goto filter_FWDO_work
|
|
|
136e2c |
- goto filter_FORWARD_OUT_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table inet firewalld {
|
|
|
136e2c |
- chain filter_FORWARD_OUT_ZONES_IFACES {
|
|
|
136e2c |
oifname "dummy1" goto filter_FWDO_public
|
|
|
136e2c |
oifname "dummy0" goto filter_FWDO_work
|
|
|
136e2c |
goto filter_FWDO_public
|
|
|
136e2c |
@@ -103,13 +82,6 @@ NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
chain raw_PREROUTING_ZONES {
|
|
|
136e2c |
ip6 saddr dead:beef::/54 goto raw_PRE_public
|
|
|
136e2c |
ip saddr 1.2.3.0/24 goto raw_PRE_work
|
|
|
136e2c |
- goto raw_PREROUTING_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table inet firewalld {
|
|
|
136e2c |
- chain raw_PREROUTING_ZONES_IFACES {
|
|
|
136e2c |
iifname "dummy1" goto raw_PRE_public
|
|
|
136e2c |
iifname "dummy0" goto raw_PRE_work
|
|
|
136e2c |
goto raw_PRE_public
|
|
|
136e2c |
@@ -128,13 +100,6 @@ NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
chain mangle_PREROUTING_ZONES {
|
|
|
136e2c |
ip6 saddr dead:beef::/54 goto mangle_PRE_public
|
|
|
136e2c |
ip saddr 1.2.3.0/24 goto mangle_PRE_work
|
|
|
136e2c |
- goto mangle_PREROUTING_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table inet firewalld {
|
|
|
136e2c |
- chain mangle_PREROUTING_ZONES_IFACES {
|
|
|
136e2c |
iifname "dummy1" goto mangle_PRE_public
|
|
|
136e2c |
iifname "dummy0" goto mangle_PRE_work
|
|
|
136e2c |
goto mangle_PRE_public
|
|
|
136e2c |
@@ -152,13 +117,6 @@ NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
table ip firewalld {
|
|
|
136e2c |
chain nat_PREROUTING_ZONES {
|
|
|
136e2c |
ip saddr 1.2.3.0/24 goto nat_PRE_work
|
|
|
136e2c |
- goto nat_PREROUTING_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table ip firewalld {
|
|
|
136e2c |
- chain nat_PREROUTING_ZONES_IFACES {
|
|
|
136e2c |
iifname "dummy1" goto nat_PRE_public
|
|
|
136e2c |
iifname "dummy0" goto nat_PRE_work
|
|
|
136e2c |
goto nat_PRE_public
|
|
|
136e2c |
@@ -176,13 +134,6 @@ NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
table ip firewalld {
|
|
|
136e2c |
chain nat_POSTROUTING_ZONES {
|
|
|
136e2c |
ip daddr 1.2.3.0/24 goto nat_POST_work
|
|
|
136e2c |
- goto nat_POSTROUTING_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table ip firewalld {
|
|
|
136e2c |
- chain nat_POSTROUTING_ZONES_IFACES {
|
|
|
136e2c |
oifname "dummy1" goto nat_POST_public
|
|
|
136e2c |
oifname "dummy0" goto nat_POST_work
|
|
|
136e2c |
goto nat_POST_public
|
|
|
136e2c |
@@ -200,13 +151,6 @@ NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
table ip6 firewalld {
|
|
|
136e2c |
chain nat_PREROUTING_ZONES {
|
|
|
136e2c |
ip6 saddr dead:beef::/54 goto nat_PRE_public
|
|
|
136e2c |
- goto nat_PREROUTING_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table ip6 firewalld {
|
|
|
136e2c |
- chain nat_PREROUTING_ZONES_IFACES {
|
|
|
136e2c |
iifname "dummy1" goto nat_PRE_public
|
|
|
136e2c |
iifname "dummy0" goto nat_PRE_work
|
|
|
136e2c |
goto nat_PRE_public
|
|
|
136e2c |
@@ -224,13 +168,6 @@ NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
table ip6 firewalld {
|
|
|
136e2c |
chain nat_POSTROUTING_ZONES {
|
|
|
136e2c |
ip6 daddr dead:beef::/54 goto nat_POST_public
|
|
|
136e2c |
- goto nat_POSTROUTING_ZONES_IFACES
|
|
|
136e2c |
- }
|
|
|
136e2c |
- }
|
|
|
136e2c |
-])
|
|
|
136e2c |
-NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- table ip firewalld {
|
|
|
136e2c |
- chain nat_POSTROUTING_ZONES_IFACES {
|
|
|
136e2c |
oifname "dummy1" goto nat_POST_public
|
|
|
136e2c |
oifname "dummy0" goto nat_POST_work
|
|
|
136e2c |
goto nat_POST_public
|
|
|
136e2c |
@@ -247,15 +184,12 @@ IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl
|
|
|
136e2c |
DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
|
|
|
136e2c |
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
|
|
|
136e2c |
])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, [dnl
|
|
|
136e2c |
- IN_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- INPUT_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([filter], [INPUT_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- IN_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- IN_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- IN_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0,
|
|
|
136e2c |
+ [[IN_work all -- 1.2.3.0/24 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ IN_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl
|
|
|
136e2c |
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
|
|
|
136e2c |
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
@@ -265,77 +199,58 @@ IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl
|
|
|
136e2c |
DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
|
|
|
136e2c |
REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
|
|
|
136e2c |
])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, [dnl
|
|
|
136e2c |
- FWDI_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- FORWARD_IN_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDI_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, [dnl
|
|
|
136e2c |
- FWDO_work all -- 0.0.0.0/0 1.2.3.0/24 @<:@goto@:>@
|
|
|
136e2c |
- FORWARD_OUT_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDO_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0,
|
|
|
136e2c |
+ [[FWDI_work all -- 1.2.3.0/24 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ FWDI_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
+IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0,
|
|
|
136e2c |
+ [[FWDO_work all -- 0.0.0.0/0 1.2.3.0/24 [goto]
|
|
|
136e2c |
+ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ FWDO_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl
|
|
|
136e2c |
PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- PRE_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PREROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl
|
|
|
136e2c |
PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- PRE_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PREROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl
|
|
|
136e2c |
PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- PRE_work all -- 1.2.3.0/24 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PREROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl
|
|
|
136e2c |
POSTROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
POSTROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- POST_work all -- 0.0.0.0/0 1.2.3.0/24 @<:@goto@:>@
|
|
|
136e2c |
- POSTROUTING_ZONES_IFACES all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- POST_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- POST_work all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
- POST_public all -- 0.0.0.0/0 0.0.0.0/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-
|
|
|
136e2c |
+IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[POST_work all -- 0.0.0.0/0 1.2.3.0/24 [goto]
|
|
|
136e2c |
+ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ POST_work all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
|
|
|
136e2c |
IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl
|
|
|
136e2c |
ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED
|
|
|
136e2c |
@@ -345,15 +260,12 @@ IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl
|
|
|
136e2c |
DROP all ::/0 ::/0 ctstate INVALID
|
|
|
136e2c |
REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited
|
|
|
136e2c |
])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, [dnl
|
|
|
136e2c |
- IN_public all dead:beef::/54 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- INPUT_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([filter], [INPUT_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- IN_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- IN_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- IN_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0,
|
|
|
136e2c |
+ [[IN_public all dead:beef::/54 ::/0 [goto]
|
|
|
136e2c |
+ IN_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ IN_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ IN_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl
|
|
|
136e2c |
ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED
|
|
|
136e2c |
ACCEPT all ::/0 ::/0
|
|
|
136e2c |
@@ -363,24 +275,18 @@ IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl
|
|
|
136e2c |
DROP all ::/0 ::/0 ctstate INVALID
|
|
|
136e2c |
REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited
|
|
|
136e2c |
])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, [dnl
|
|
|
136e2c |
- FWDI_public all dead:beef::/54 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- FORWARD_IN_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- FWDI_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDI_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDI_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, [dnl
|
|
|
136e2c |
- FWDO_public all ::/0 dead:beef::/54 @<:@goto@:>@
|
|
|
136e2c |
- FORWARD_OUT_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- FWDO_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDO_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- FWDO_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0,
|
|
|
136e2c |
+ [[FWDI_public all dead:beef::/54 ::/0 [goto]
|
|
|
136e2c |
+ FWDI_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ FWDI_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ FWDI_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0,
|
|
|
136e2c |
+ [[FWDO_public all ::/0 dead:beef::/54 [goto]
|
|
|
136e2c |
+ FWDO_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ FWDO_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ FWDO_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl
|
|
|
136e2c |
ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 134
|
|
|
136e2c |
ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 135
|
|
|
136e2c |
@@ -388,54 +294,42 @@ IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl
|
|
|
136e2c |
PREROUTING_direct all ::/0 ::/0
|
|
|
136e2c |
PREROUTING_ZONES all ::/0 ::/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- PRE_public all dead:beef::/54 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PREROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- PRE_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[PRE_public all dead:beef::/54 ::/0 [goto]
|
|
|
136e2c |
+ PRE_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ PRE_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ PRE_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl
|
|
|
136e2c |
PREROUTING_direct all ::/0 ::/0
|
|
|
136e2c |
PREROUTING_ZONES all ::/0 ::/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- PRE_public all dead:beef::/54 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PREROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- PRE_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[PRE_public all dead:beef::/54 ::/0 [goto]
|
|
|
136e2c |
+ PRE_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ PRE_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ PRE_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl
|
|
|
136e2c |
PREROUTING_direct all ::/0 ::/0
|
|
|
136e2c |
PREROUTING_ZONES all ::/0 ::/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- PRE_public all dead:beef::/54 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PREROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- PRE_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- PRE_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[PRE_public all dead:beef::/54 ::/0 [goto]
|
|
|
136e2c |
+ PRE_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ PRE_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ PRE_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl
|
|
|
136e2c |
POSTROUTING_direct all ::/0 ::/0
|
|
|
136e2c |
POSTROUTING_ZONES all ::/0 ::/0
|
|
|
136e2c |
])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, [dnl
|
|
|
136e2c |
- POST_public all ::/0 dead:beef::/54 @<:@goto@:>@
|
|
|
136e2c |
- POSTROUTING_ZONES_IFACES all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
-IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES_IFACES], 0, [dnl
|
|
|
136e2c |
- POST_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- POST_work all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
- POST_public all ::/0 ::/0 @<:@goto@:>@
|
|
|
136e2c |
-])
|
|
|
136e2c |
+IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0,
|
|
|
136e2c |
+ [[POST_public all ::/0 dead:beef::/54 [goto]
|
|
|
136e2c |
+ POST_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ POST_work all ::/0 ::/0 [goto]
|
|
|
136e2c |
+ POST_public all ::/0 ::/0 [goto]
|
|
|
136e2c |
+]])
|
|
|
136e2c |
])
|
|
|
136e2c |
|
|
|
136e2c |
FWD_END_TEST
|
|
|
136e2c |
--
|
|
|
136e2c |
2.20.1
|
|
|
136e2c |
|