summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2022-09-03 20:38:13 +0200
committerChristian Poessinger <christian@poessinger.com>2022-09-03 20:38:13 +0200
commit5a6c8b52e985df8f04817b9b529504bdc6e6d8c1 (patch)
tree99425f45c67ec29f94c5235ca70b7cedbe8d695b
parente7719b7be2f817834d988e10368a39e419c44263 (diff)
parentd9eb48a0ced1eb60bd00fe2f18559b3c780ee98a (diff)
downloadvyos-1x-5a6c8b52e985df8f04817b9b529504bdc6e6d8c1.tar.gz
vyos-1x-5a6c8b52e985df8f04817b9b529504bdc6e6d8c1.zip
Merge branch 'firewall' into current
* firewall: firewall: T4651: re-implement packet-length CLI option to use <multi/> firewall: T3568: improve default-action help string firewall: T3568: add XML include block for eq,gt,lt options smoketest: firewall: add re-usable variables when running testcases Firewall: T4651: Change proposed cli from ip-length to packet-length Firewall: T4651: Add options to match packet size on firewall rules.
-rw-r--r--interface-definitions/firewall.xml.in80
-rw-r--r--interface-definitions/include/firewall/enable-default-log.xml.i2
-rw-r--r--interface-definitions/include/firewall/eq.xml.i14
-rw-r--r--interface-definitions/include/firewall/gt.xml.i14
-rw-r--r--interface-definitions/include/firewall/lt.xml.i14
-rw-r--r--interface-definitions/include/firewall/packet-length.xml.i38
-rw-r--r--python/vyos/firewall.py12
-rwxr-xr-xsmoketest/scripts/cli/test_firewall.py205
8 files changed, 238 insertions, 141 deletions
diff --git a/interface-definitions/firewall.xml.in b/interface-definitions/firewall.xml.in
index 9488ddcdc..c2d652278 100644
--- a/interface-definitions/firewall.xml.in
+++ b/interface-definitions/firewall.xml.in
@@ -383,47 +383,15 @@
</children>
</node>
#include <include/firewall/common-rule.xml.i>
+ #include <include/firewall/packet-length.xml.i>
<node name="hop-limit">
<properties>
<help>Hop Limit</help>
</properties>
<children>
- <leafNode name="eq">
- <properties>
- <help>Value to match a hop limit equal to it</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>Hop limit equal to value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="gt">
- <properties>
- <help>Value to match a hop limit greater than or equal to it</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>Hop limit greater than value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="lt">
- <properties>
- <help>Value to match a hop limit less than or equal to it</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>Hop limit less than value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/firewall/eq.xml.i>
+ #include <include/firewall/gt.xml.i>
+ #include <include/firewall/lt.xml.i>
</children>
</node>
<node name="icmpv6">
@@ -571,6 +539,7 @@
</children>
</node>
#include <include/firewall/common-rule.xml.i>
+ #include <include/firewall/packet-length.xml.i>
<node name="icmp">
<properties>
<help>ICMP type and code information</help>
@@ -608,42 +577,9 @@
<help>Time to live limit</help>
</properties>
<children>
- <leafNode name="eq">
- <properties>
- <help>Value to match a ttl equal to it</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>ttl equal to value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="gt">
- <properties>
- <help>Value to match a ttl greater than or equal to it</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>ttl greater than value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="lt">
- <properties>
- <help>Value to match a ttl less than or equal to it</help>
- <valueHelp>
- <format>u32:0-255</format>
- <description>ttl less than value</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 0-255"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/firewall/eq.xml.i>
+ #include <include/firewall/gt.xml.i>
+ #include <include/firewall/lt.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/include/firewall/enable-default-log.xml.i b/interface-definitions/include/firewall/enable-default-log.xml.i
index 1e64edc6e..0efd8341b 100644
--- a/interface-definitions/include/firewall/enable-default-log.xml.i
+++ b/interface-definitions/include/firewall/enable-default-log.xml.i
@@ -1,7 +1,7 @@
<!-- include start from firewall/enable-default-log.xml.i -->
<leafNode name="enable-default-log">
<properties>
- <help>Option to log packets hitting default-action</help>
+ <help>Log packets hitting default-action</help>
<valueless/>
</properties>
</leafNode>
diff --git a/interface-definitions/include/firewall/eq.xml.i b/interface-definitions/include/firewall/eq.xml.i
new file mode 100644
index 000000000..e1b4f37a2
--- /dev/null
+++ b/interface-definitions/include/firewall/eq.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from firewall/eq.xml.i -->
+<leafNode name="eq">
+ <properties>
+ <help>Match on equal value</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>Equal to value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/firewall/gt.xml.i b/interface-definitions/include/firewall/gt.xml.i
new file mode 100644
index 000000000..c879171ee
--- /dev/null
+++ b/interface-definitions/include/firewall/gt.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from firewall/gt.xml.i -->
+<leafNode name="gt">
+ <properties>
+ <help>Match on greater then value</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>Greater then value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/lt.xml.i b/interface-definitions/include/firewall/lt.xml.i
new file mode 100644
index 000000000..77894d3ce
--- /dev/null
+++ b/interface-definitions/include/firewall/lt.xml.i
@@ -0,0 +1,14 @@
+<!-- include start from firewall/lt.xml.i -->
+<leafNode name="lt">
+ <properties>
+ <help>Match on less then value</help>
+ <valueHelp>
+ <format>u32:0-255</format>
+ <description>Less then value</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 0-255"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/include/firewall/packet-length.xml.i b/interface-definitions/include/firewall/packet-length.xml.i
new file mode 100644
index 000000000..043f56d16
--- /dev/null
+++ b/interface-definitions/include/firewall/packet-length.xml.i
@@ -0,0 +1,38 @@
+<!-- include start from firewall/packet-length.xml.i -->
+<leafNode name="packet-length">
+ <properties>
+ <help>Payload size in bytes, including header and data to match</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Packet length to match</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;start-end&gt;</format>
+ <description>Packet length range to match</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ <validator name="range" argument="--min=1 --max=65535"/>
+ </constraint>
+ <multi/>
+ </properties>
+</leafNode>
+<leafNode name="packet-length-exclude">
+ <properties>
+ <help>Payload size in bytes, including header and data not to match</help>
+ <valueHelp>
+ <format>u32:1-65535</format>
+ <description>Packet length not to match</description>
+ </valueHelp>
+ <valueHelp>
+ <format>&lt;start-end&gt;</format>
+ <description>Packet length range not to match</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ <validator name="range" argument="--min=1 --max=65535"/>
+ </constraint>
+ <multi/>
+ </properties>
+</leafNode>
+<!-- include end -->
diff --git a/python/vyos/firewall.py b/python/vyos/firewall.py
index 663c4394a..0bc5378db 100644
--- a/python/vyos/firewall.py
+++ b/python/vyos/firewall.py
@@ -150,7 +150,7 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name):
if suffix[0] == '!':
suffix = f'!= {suffix[1:]}'
output.append(f'{ip_name} {prefix}addr {suffix}')
-
+
if dict_search_args(side_conf, 'geoip', 'country_code'):
operator = ''
if dict_search_args(side_conf, 'geoip', 'inverse_match') != None:
@@ -265,6 +265,16 @@ def parse_rule(rule_conf, fw_name, rule_id, ip_name):
if 'type' in rule_conf[icmp]:
output.append(icmp + ' type ' + rule_conf[icmp]['type'])
+
+ if 'packet_length' in rule_conf:
+ lengths_str = ','.join(rule_conf['packet_length'])
+ output.append(f'ip{def_suffix} length {{{lengths_str}}}')
+
+ if 'packet_length_exclude' in rule_conf:
+ negated_lengths_str = ','.join(rule_conf['packet_length_exclude'])
+ output.append(f'ip{def_suffix} length != {{{negated_lengths_str}}}')
+
+
if 'ipsec' in rule_conf:
if 'match_ipsec' in rule_conf['ipsec']:
output.append('meta ipsec == 1')
diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py
index 684a07681..1517180de 100755
--- a/smoketest/scripts/cli/test_firewall.py
+++ b/smoketest/scripts/cli/test_firewall.py
@@ -36,6 +36,8 @@ sysfs_config = {
'twa_hazards_protection': {'sysfs': '/proc/sys/net/ipv4/tcp_rfc1337', 'default': '0', 'test_value': 'enable'}
}
+eth0_addr = '172.16.10.1/24'
+
class TestFirewall(VyOSUnitTestSHIM.TestCase):
@classmethod
def setUpClass(cls):
@@ -45,11 +47,11 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
# out the current configuration :)
cls.cli_delete(cls, ['firewall'])
- cls.cli_set(cls, ['interfaces', 'ethernet', 'eth0', 'address', '172.16.10.1/24'])
+ cls.cli_set(cls, ['interfaces', 'ethernet', 'eth0', 'address', eth0_addr])
@classmethod
def tearDownClass(cls):
- cls.cli_delete(cls, ['interfaces', 'ethernet', 'eth0', 'address', '172.16.10.1/24'])
+ cls.cli_delete(cls, ['interfaces', 'ethernet', 'eth0', 'address', eth0_addr])
super(TestFirewall, cls).tearDownClass()
def tearDown(self):
@@ -95,6 +97,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
['ip saddr @GEOIP_CC_smoketest_1', 'drop'],
['ip saddr != @GEOIP_CC_smoketest_2', 'return']
]
+
# -t prevents 1000+ GeoIP elements being returned
self.verify_nftables(nftables_search, 'ip filter', args='-t')
@@ -114,6 +117,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.cli_set(['firewall', 'group', 'port-group', 'smoketest_port', 'port', '123'])
self.cli_set(['firewall', 'group', 'domain-group', 'smoketest_domain', 'address', 'example.com'])
self.cli_set(['firewall', 'group', 'domain-group', 'smoketest_domain', 'address', 'example.org'])
+
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'group', 'network-group', 'smoketest_network'])
self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
@@ -176,78 +180,142 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
self.verify_nftables(nftables_search, 'ip filter')
- def test_basic_rules(self):
+ def test_ipv4_basic_rules(self):
+ name = 'smoketest'
+ interface = 'eth0'
mss_range = '501-1460'
- self.cli_set(['firewall', 'name', 'smoketest', 'default-action', 'drop'])
- self.cli_set(['firewall', 'name', 'smoketest', 'enable-default-log'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'source', 'address', '172.16.20.10'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'destination', 'address', '172.16.10.10'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'log', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'log-level', 'debug'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'ttl', 'eq', '15'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'reject'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'protocol', 'tcp'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'destination', 'port', '8888'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'log', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'log-level', 'err'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'syn'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'ttl', 'gt', '102'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'protocol', 'tcp'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'destination', 'port', '22'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'limit', 'rate', '5/minute'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'log', 'disable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'action', 'drop'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'protocol', 'tcp'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'destination', 'port', '22'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'recent', 'count', '10'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'recent', 'time', 'minute'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '5', 'action', 'accept'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '5', 'protocol', 'tcp'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '5', 'tcp', 'flags', 'syn'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '5', 'tcp', 'mss', mss_range])
- self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
+ self.cli_set(['firewall', 'name', name, 'default-action', 'drop'])
+ self.cli_set(['firewall', 'name', name, 'enable-default-log'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'source', 'address', '172.16.20.10'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'destination', 'address', '172.16.10.10'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'log', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'log-level', 'debug'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'ttl', 'eq', '15'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'action', 'reject'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'destination', 'port', '8888'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'log', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'log-level', 'err'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'tcp', 'flags', 'syn'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'tcp', 'flags', 'not', 'ack'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'ttl', 'gt', '102'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'limit', 'rate', '5/minute'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'log', 'disable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'action', 'drop'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'destination', 'port', '22'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'recent', 'count', '10'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'recent', 'time', 'minute'])
+ self.cli_set(['firewall', 'name', name, 'rule', '5', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '5', 'protocol', 'tcp'])
+ self.cli_set(['firewall', 'name', name, 'rule', '5', 'tcp', 'flags', 'syn'])
+ self.cli_set(['firewall', 'name', name, 'rule', '5', 'tcp', 'mss', mss_range])
+
+ self.cli_set(['interfaces', 'ethernet', interface, 'firewall', 'in', 'name', name])
self.cli_commit()
nftables_search = [
- ['iifname "eth0"', 'jump NAME_smoketest'],
+ [f'iifname "{interface}"', f'jump NAME_{name}'],
['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[smoketest-1-A]" level debug', 'ip ttl 15','return'],
['tcp flags & (syn | ack) == syn', 'tcp dport { 8888 }', 'log prefix "[smoketest-2-R]" level err', 'ip ttl > 102', 'reject'],
['tcp dport { 22 }', 'limit rate 5/minute', 'return'],
['log prefix "[smoketest-default-D]"','smoketest default-action', 'drop'],
['tcp dport { 22 }', 'add @RECENT_smoketest_4 { ip saddr limit rate over 10/minute burst 10 packets }', 'drop'],
- [f'tcp flags & syn == syn tcp option maxseg size {mss_range}']
+ [f'tcp flags & syn == syn tcp option maxseg size {mss_range}'],
+ ]
+
+ self.verify_nftables(nftables_search, 'ip filter')
+
+ def test_ipv4_packet_length(self):
+ name = 'smoketest-plen'
+ interface = 'eth0'
+
+ self.cli_set(['firewall', 'name', name, 'default-action', 'drop'])
+ self.cli_set(['firewall', 'name', name, 'enable-default-log'])
+
+ self.cli_set(['firewall', 'name', name, 'rule', '6', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '64'])
+ self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '512'])
+ self.cli_set(['firewall', 'name', name, 'rule', '6', 'packet-length', '1024'])
+
+ self.cli_set(['firewall', 'name', name, 'rule', '7', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '7', 'packet-length', '1-30000'])
+ self.cli_set(['firewall', 'name', name, 'rule', '7', 'packet-length-exclude', '60000-65535'])
+
+ self.cli_set(['interfaces', 'ethernet', interface, 'firewall', 'in', 'name', name])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'iifname "{interface}"', f'jump NAME_{name}'],
+ ['ip length { 64, 512, 1024 }', 'return'],
+ ['ip length { 1-30000 }', 'ip length != { 60000-65535 }', 'return'],
+ [f'log prefix "[{name}-default-D]" drop']
]
self.verify_nftables(nftables_search, 'ip filter')
- def test_basic_rules_ipv6(self):
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'default-action', 'drop'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'enable-default-log'])
+ def test_ipv6_basic_rules(self):
+ name = 'v6-smoketest'
+ interface = 'eth0'
+
+ self.cli_set(['firewall', 'ipv6-name', name, 'default-action', 'drop'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'enable-default-log'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'action', 'accept'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'source', 'address', '2002::1'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'destination', 'address', '2002::1:1'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'log', 'enable'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '1', 'log-level', 'crit'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'source', 'address', '2002::1'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'destination', 'address', '2002::1:1'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'log', 'enable'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '1', 'log-level', 'crit'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '2', 'action', 'reject'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '2', 'protocol', 'tcp_udp'])
- self.cli_set(['firewall', 'ipv6-name', 'v6-smoketest', 'rule', '2', 'destination', 'port', '8888'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'action', 'reject'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'protocol', 'tcp_udp'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '2', 'destination', 'port', '8888'])
- self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'ipv6-name', 'v6-smoketest'])
+ self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'ipv6-name', name])
self.cli_commit()
nftables_search = [
- ['iifname "eth0"', 'jump NAME6_v6-smoketest'],
+ [f'iifname "{interface}"', f'jump NAME6_{name}'],
['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[v6-smoketest-1-A]" level crit', 'return'],
['meta l4proto { tcp, udp }', 'th dport { 8888 }', 'reject'],
- ['smoketest default-action', 'log prefix "[v6-smoketest-default-D]"', 'drop']
+ ['smoketest default-action', f'log prefix "[{name}-default-D]"', 'drop']
+ ]
+
+ self.verify_nftables(nftables_search, 'ip6 filter')
+
+ def test_ipv6_packet_length(self):
+ name = 'v6-smoketest-plen'
+ interface = 'eth0'
+
+ self.cli_set(['firewall', 'ipv6-name', name, 'default-action', 'drop'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'enable-default-log'])
+
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '65'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '513'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '3', 'packet-length', '1025'])
+
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'action', 'accept'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'packet-length', '1-1999'])
+ self.cli_set(['firewall', 'ipv6-name', name, 'rule', '4', 'packet-length-exclude', '60000-65535'])
+
+ self.cli_set(['interfaces', 'ethernet', interface, 'firewall', 'in', 'ipv6-name', name])
+
+ self.cli_commit()
+
+ nftables_search = [
+ [f'iifname "{interface}"', f'jump NAME6_{name}'],
+ ['ip6 length { 65, 513, 1025 }', 'return'],
+ ['ip6 length { 1-1999 }', 'ip6 length != { 60000-65535 }', 'return'],
+ [f'log prefix "[{name}-default-D]"', 'drop']
]
self.verify_nftables(nftables_search, 'ip6 filter')
@@ -269,33 +337,36 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase):
nftables_output = cmd(f'sudo nft list chain {table} {chain}')
self.assertTrue('jump VYOS_STATE_POLICY' in nftables_output)
- def test_state_and_status_rules(self):
- self.cli_set(['firewall', 'name', 'smoketest', 'default-action', 'drop'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'action', 'accept'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'state', 'established', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '1', 'state', 'related', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'action', 'reject'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '2', 'state', 'invalid', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'action', 'accept'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'state', 'new', 'enable'])
+ def test_ipv4_state_and_status_rules(self):
+ name = 'smoketest-state'
+ interface = 'eth0'
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '3', 'connection-status', 'nat', 'destination'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'action', 'accept'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'state', 'new', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'state', 'established', 'enable'])
- self.cli_set(['firewall', 'name', 'smoketest', 'rule', '4', 'connection-status', 'nat', 'source'])
+ self.cli_set(['firewall', 'name', name, 'default-action', 'drop'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'state', 'established', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '1', 'state', 'related', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'action', 'reject'])
+ self.cli_set(['firewall', 'name', name, 'rule', '2', 'state', 'invalid', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'state', 'new', 'enable'])
- self.cli_set(['interfaces', 'ethernet', 'eth0', 'firewall', 'in', 'name', 'smoketest'])
+ self.cli_set(['firewall', 'name', name, 'rule', '3', 'connection-status', 'nat', 'destination'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'action', 'accept'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'state', 'new', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'state', 'established', 'enable'])
+ self.cli_set(['firewall', 'name', name, 'rule', '4', 'connection-status', 'nat', 'source'])
+
+ self.cli_set(['interfaces', 'ethernet', interface, 'firewall', 'in', 'name', name])
self.cli_commit()
nftables_search = [
- ['iifname "eth0"', 'jump NAME_smoketest'],
+ [f'iifname "{interface}"', f'jump NAME_{name}'],
['ct state { established, related }', 'return'],
['ct state { invalid }', 'reject'],
['ct state { new }', 'ct status { dnat }', 'return'],
['ct state { established, new }', 'ct status { snat }', 'return'],
- ['smoketest default-action', 'drop']
+ ['drop', f'comment "{name} default-action drop"']
]
self.verify_nftables(nftables_search, 'ip filter')