|
|
21c891 |
From fb83f0f12e3ce0a972943b2e087375986983e959 Mon Sep 17 00:00:00 2001
|
|
|
21c891 |
From: Eric Garver <e@erig.me>
|
|
|
21c891 |
Date: Thu, 18 Oct 2018 16:26:54 -0400
|
|
|
21c891 |
Subject: [PATCH 19/34] rich: add support for rule priorities
|
|
|
21c891 |
|
|
|
21c891 |
(cherry picked from commit aeac75088ef2263a7a91c52956c914e69bee8a4b)
|
|
|
21c891 |
---
|
|
|
21c891 |
src/firewall/core/io/zone.py | 9 +++++++--
|
|
|
21c891 |
src/firewall/core/rich.py | 19 +++++++++++++++++--
|
|
|
21c891 |
src/firewall/errors.py | 1 +
|
|
|
21c891 |
3 files changed, 25 insertions(+), 4 deletions(-)
|
|
|
21c891 |
|
|
|
21c891 |
diff --git a/src/firewall/core/io/zone.py b/src/firewall/core/io/zone.py
|
|
|
21c891 |
index 05368e9c73eb..68b2a7c9567c 100644
|
|
|
21c891 |
--- a/src/firewall/core/io/zone.py
|
|
|
21c891 |
+++ b/src/firewall/core/io/zone.py
|
|
|
21c891 |
@@ -88,7 +88,7 @@ class Zone(IO_Object):
|
|
|
21c891 |
"zone": [ "name", "immutable", "target", "version" ],
|
|
|
21c891 |
"masquerade": [ "enabled" ],
|
|
|
21c891 |
"forward-port": [ "to-port", "to-addr" ],
|
|
|
21c891 |
- "rule": [ "family" ],
|
|
|
21c891 |
+ "rule": [ "family", "priority" ],
|
|
|
21c891 |
"source": [ "address", "mac", "invert", "family", "ipset" ],
|
|
|
21c891 |
"destination": [ "invert" ],
|
|
|
21c891 |
"log": [ "prefix", "level" ],
|
|
|
21c891 |
@@ -627,6 +627,7 @@ class zone_ContentHandler(IO_Object_ContentHandler):
|
|
|
21c891 |
|
|
|
21c891 |
elif name == "rule":
|
|
|
21c891 |
family = None
|
|
|
21c891 |
+ priority = 0
|
|
|
21c891 |
if "family" in attrs:
|
|
|
21c891 |
family = attrs["family"]
|
|
|
21c891 |
if family not in [ "ipv4", "ipv6" ]:
|
|
|
21c891 |
@@ -634,7 +635,9 @@ class zone_ContentHandler(IO_Object_ContentHandler):
|
|
|
21c891 |
attrs["family"])
|
|
|
21c891 |
self._rule_error = True
|
|
|
21c891 |
return
|
|
|
21c891 |
- self._rule = rich.Rich_Rule(family)
|
|
|
21c891 |
+ if "priority" in attrs:
|
|
|
21c891 |
+ priority = int(attrs["priority"])
|
|
|
21c891 |
+ self._rule = rich.Rich_Rule(family=family, priority=priority)
|
|
|
21c891 |
|
|
|
21c891 |
elif name == "limit":
|
|
|
21c891 |
if not self._limit_ok:
|
|
|
21c891 |
@@ -834,6 +837,8 @@ def zone_writer(zone, path=None):
|
|
|
21c891 |
attrs = { }
|
|
|
21c891 |
if rule.family:
|
|
|
21c891 |
attrs["family"] = rule.family
|
|
|
21c891 |
+ if rule.priority != 0:
|
|
|
21c891 |
+ attrs["priority"] = str(rule.priority)
|
|
|
21c891 |
handler.ignorableWhitespace(" ")
|
|
|
21c891 |
handler.startElement("rule", attrs)
|
|
|
21c891 |
handler.ignorableWhitespace("\n")
|
|
|
21c891 |
diff --git a/src/firewall/core/rich.py b/src/firewall/core/rich.py
|
|
|
21c891 |
index 04791da612a2..c415bf39212f 100644
|
|
|
21c891 |
--- a/src/firewall/core/rich.py
|
|
|
21c891 |
+++ b/src/firewall/core/rich.py
|
|
|
21c891 |
@@ -266,12 +266,16 @@ class Rich_Limit(object):
|
|
|
21c891 |
return ''
|
|
|
21c891 |
|
|
|
21c891 |
class Rich_Rule(object):
|
|
|
21c891 |
- def __init__(self, family=None, rule_str=None):
|
|
|
21c891 |
+ priority_min = -32768
|
|
|
21c891 |
+ priority_max = 32767
|
|
|
21c891 |
+
|
|
|
21c891 |
+ def __init__(self, family=None, rule_str=None, priority=0):
|
|
|
21c891 |
if family is not None:
|
|
|
21c891 |
self.family = str(family)
|
|
|
21c891 |
else:
|
|
|
21c891 |
self.family = None
|
|
|
21c891 |
|
|
|
21c891 |
+ self.priority = priority
|
|
|
21c891 |
self.source = None
|
|
|
21c891 |
self.destination = None
|
|
|
21c891 |
self.element = None
|
|
|
21c891 |
@@ -303,6 +307,7 @@ class Rich_Rule(object):
|
|
|
21c891 |
if not rule_str:
|
|
|
21c891 |
raise FirewallError(errors.INVALID_RULE, 'empty rule')
|
|
|
21c891 |
|
|
|
21c891 |
+ self.priority = 0
|
|
|
21c891 |
self.family = None
|
|
|
21c891 |
self.source = None
|
|
|
21c891 |
self.destination = None
|
|
|
21c891 |
@@ -325,7 +330,7 @@ class Rich_Rule(object):
|
|
|
21c891 |
#print ("in_elements: ", in_elements)
|
|
|
21c891 |
#print ("index: %s, element: %s, attribute: %s=%s" % (index, element, attr_name, attr_value))
|
|
|
21c891 |
if attr_name: # attribute
|
|
|
21c891 |
- if attr_name not in ['family', 'address', 'mac', 'ipset',
|
|
|
21c891 |
+ if attr_name not in ['priority', 'family', 'address', 'mac', 'ipset',
|
|
|
21c891 |
'invert', 'value',
|
|
|
21c891 |
'port', 'protocol', 'to-port', 'to-addr',
|
|
|
21c891 |
'name', 'prefix', 'level', 'type',
|
|
|
21c891 |
@@ -360,6 +365,8 @@ class Rich_Rule(object):
|
|
|
21c891 |
if not element and attr_name:
|
|
|
21c891 |
if attr_name == 'family':
|
|
|
21c891 |
raise FirewallError(errors.INVALID_RULE, "'family' outside of rule. Use 'rule family=...'.")
|
|
|
21c891 |
+ elif attr_name == 'priority':
|
|
|
21c891 |
+ raise FirewallError(errors.INVALID_RULE, "'priority' outside of rule. Use 'rule priority=...'.")
|
|
|
21c891 |
else:
|
|
|
21c891 |
raise FirewallError(errors.INVALID_RULE, "'%s' outside of any element. Use 'rule <element> %s= ...'." % (attr_name, attr_name))
|
|
|
21c891 |
elif 'rule' not in element:
|
|
|
21c891 |
@@ -371,6 +378,8 @@ class Rich_Rule(object):
|
|
|
21c891 |
if attr_value not in ['ipv4', 'ipv6']:
|
|
|
21c891 |
raise FirewallError(errors.INVALID_RULE, "'family' attribute cannot have '%s' value. Use 'ipv4' or 'ipv6' instead." % attr_value)
|
|
|
21c891 |
self.family = attr_value
|
|
|
21c891 |
+ elif attr_name == 'priority':
|
|
|
21c891 |
+ self.priority = int(attr_value)
|
|
|
21c891 |
elif attr_name:
|
|
|
21c891 |
if attr_name == 'protocol':
|
|
|
21c891 |
err_msg = "wrong 'protocol' usage. Use either 'rule protocol value=...' or 'rule [forward-]port protocol=...'."
|
|
|
21c891 |
@@ -528,6 +537,10 @@ class Rich_Rule(object):
|
|
|
21c891 |
if type(self.element) == Rich_ForwardPort:
|
|
|
21c891 |
raise FirewallError(errors.MISSING_FAMILY)
|
|
|
21c891 |
|
|
|
21c891 |
+ if self.priority < self.priority_min or self.priority > self.priority_max:
|
|
|
21c891 |
+ raise FirewallError(errors.INVALID_PRIORITY, "'priority' attribute must be between %d and %d." \
|
|
|
21c891 |
+ % (self.priority_min, self.priority_max))
|
|
|
21c891 |
+
|
|
|
21c891 |
if self.element is None:
|
|
|
21c891 |
if self.action is None:
|
|
|
21c891 |
raise FirewallError(errors.INVALID_RULE, "no element, no action")
|
|
|
21c891 |
@@ -679,6 +692,8 @@ class Rich_Rule(object):
|
|
|
21c891 |
|
|
|
21c891 |
def __str__(self):
|
|
|
21c891 |
ret = 'rule'
|
|
|
21c891 |
+ if self.priority:
|
|
|
21c891 |
+ ret += ' priority="%d"' % self.priority
|
|
|
21c891 |
if self.family:
|
|
|
21c891 |
ret += ' family="%s"' % self.family
|
|
|
21c891 |
if self.source:
|
|
|
21c891 |
diff --git a/src/firewall/errors.py b/src/firewall/errors.py
|
|
|
21c891 |
index a48038028f25..4589f60848b9 100644
|
|
|
21c891 |
--- a/src/firewall/errors.py
|
|
|
21c891 |
+++ b/src/firewall/errors.py
|
|
|
21c891 |
@@ -87,6 +87,7 @@ INVALID_IPSET = 135
|
|
|
21c891 |
INVALID_ENTRY = 136
|
|
|
21c891 |
INVALID_OPTION = 137
|
|
|
21c891 |
INVALID_HELPER = 138
|
|
|
21c891 |
+INVALID_PRIORITY = 139
|
|
|
21c891 |
|
|
|
21c891 |
MISSING_TABLE = 200
|
|
|
21c891 |
MISSING_CHAIN = 201
|
|
|
21c891 |
--
|
|
|
21c891 |
2.18.0
|
|
|
21c891 |
|