diff options
Diffstat (limited to 'smoketest/scripts/cli')
-rw-r--r-- | smoketest/scripts/cli/base_interfaces_test.py | 8 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_dependency_graph.py | 54 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_firewall.py | 63 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_ethernet.py | 9 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_openvpn.py | 76 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_vxlan.py | 50 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_wireless.py | 3 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_load_balancing_wan.py | 7 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_nat.py | 5 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_netns.py (renamed from smoketest/scripts/cli/test_interfaces_netns.py) | 52 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_policy_route.py | 4 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_pim6.py | 110 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_system_conntrack.py | 57 |
13 files changed, 327 insertions, 171 deletions
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py index 820024dc9..51ccbc9e6 100644 --- a/smoketest/scripts/cli/base_interfaces_test.py +++ b/smoketest/scripts/cli/base_interfaces_test.py @@ -834,8 +834,12 @@ class BasicInterfaceTest: self.assertEqual('1', tmp) if cli_defined(self._base_path + ['ip'], 'source-validation'): - tmp = read_file(f'{proc_base}/rp_filter') - self.assertEqual('2', tmp) + base_options = f'iifname "{interface}"' + out = cmd('sudo nft list chain ip raw vyos_rpfilter') + for line in out.splitlines(): + if line.startswith(base_options): + self.assertIn('fib saddr oif 0', line) + self.assertIn('drop', line) def test_interface_ipv6_options(self): if not self._test_ipv6: diff --git a/smoketest/scripts/cli/test_dependency_graph.py b/smoketest/scripts/cli/test_dependency_graph.py deleted file mode 100755 index 45a40acc4..000000000 --- a/smoketest/scripts/cli/test_dependency_graph.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2022 VyOS maintainers and contributors -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 or later as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -import json -import unittest -from graphlib import TopologicalSorter, CycleError - -DEP_FILE = '/usr/share/vyos/config-mode-dependencies.json' - -def graph_from_dict(d): - g = {} - for k in list(d): - g[k] = set() - # add the dependencies for every sub-case; should there be cases - # that are mutally exclusive in the future, the graphs will be - # distinguished - for el in list(d[k]): - g[k] |= set(d[k][el]) - return g - -class TestDependencyGraph(unittest.TestCase): - def setUp(self): - with open(DEP_FILE) as f: - dd = json.load(f) - self.dependency_graph = graph_from_dict(dd) - - def test_cycles(self): - ts = TopologicalSorter(self.dependency_graph) - out = None - try: - # get node iterator - order = ts.static_order() - # try iteration - _ = [*order] - except CycleError as e: - out = e.args - - self.assertIsNone(out) - -if __name__ == '__main__': - unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_firewall.py b/smoketest/scripts/cli/test_firewall.py index ee6ccb710..391ef03ff 100755 --- a/smoketest/scripts/cli/test_firewall.py +++ b/smoketest/scripts/cli/test_firewall.py @@ -274,8 +274,8 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['meta l4proto gre', f'oifname != "{interface}"', 'drop'], ['meta l4proto icmp', f'ct mark {mark_hex}', 'return'], ['chain NAME_smoketest'], - ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'], - ['tcp flags syn / syn,ack', 'tcp dport 8888', 'log prefix "[smoketest-2-R]" log level err', 'ip ttl > 102', 'reject'], + ['saddr 172.16.20.10', 'daddr 172.16.10.10', 'log prefix "[ipv4-NAM-smoketest-1-A]" log level debug', 'ip ttl 15', 'accept'], + ['tcp flags syn / syn,ack', 'tcp dport 8888', 'log prefix "[ipv4-NAM-smoketest-2-R]" log level err', 'ip ttl > 102', 'reject'], ['log prefix "[smoketest-default-D]"','smoketest default-action', 'drop'] ] @@ -331,7 +331,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): [f'meta l4proto tcp','queue to 3'], [f'meta l4proto udp','queue flags bypass,fanout to 0-15'], [f'chain NAME_{name}'], - ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'accept'], + ['ip length { 64, 512, 1024 }', 'ip dscp { 0x11, 0x34 }', f'log prefix "[ipv4-NAM-{name}-6-A]" log group 66 snaplen 6666 queue-threshold 32000', 'accept'], ['ip length 1-30000', 'ip length != 60000-65535', 'ip dscp 0x03-0x0b', 'ip dscp != 0x15-0x19', 'accept'], [f'log prefix "[{name}-default-D]"', 'drop'] ] @@ -412,7 +412,7 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): ['type filter hook output priority filter; policy drop;'], ['meta l4proto gre', f'oifname "{interface}"', 'return'], [f'chain NAME6_{name}'], - ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[v6-smoketest-1-A]" log level crit', 'accept'], + ['saddr 2002::1', 'daddr 2002::1:1', 'log prefix "[ipv6-NAM-v6-smoketest-1-A]" log level crit', 'accept'], [f'"{name} default-action drop"', f'log prefix "[{name}-default-D]"', 'drop'] ] @@ -526,26 +526,65 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): self.verify_nftables_chain([['accept']], 'raw', 'FW_CONNTRACK') self.verify_nftables_chain([['return']], 'ip6 raw', 'FW_CONNTRACK') + def test_bridge_basic_rules(self): + name = 'smoketest' + interface_in = 'eth0' + mac_address = '00:53:00:00:00:01' + vlan_id = '12' + vlan_prior = '3' + + self.cli_set(['firewall', 'bridge', 'name', name, 'default-action', 'accept']) + self.cli_set(['firewall', 'bridge', 'name', name, 'enable-default-log']) + self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'source', 'mac-address', mac_address]) + self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'inbound-interface', 'interface-name', interface_in]) + self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'log', 'enable']) + self.cli_set(['firewall', 'bridge', 'name', name, 'rule', '1', 'log-options', 'level', 'crit']) + + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'default-action', 'drop']) + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '1', 'action', 'accept']) + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '1', 'vlan', 'id', vlan_id]) + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'action', 'jump']) + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'jump-target', name]) + self.cli_set(['firewall', 'bridge', 'forward', 'filter', 'rule', '2', 'vlan', 'priority', vlan_prior]) + + self.cli_commit() + + nftables_search = [ + ['chain VYOS_FORWARD_filter'], + ['type filter hook forward priority filter; policy drop;'], + [f'vlan id {vlan_id}', 'accept'], + [f'vlan pcp {vlan_prior}', f'jump NAME_{name}'], + [f'chain NAME_{name}'], + [f'ether saddr {mac_address}', f'iifname "{interface_in}"', f'log prefix "[bri-NAM-{name}-1-A]" log level crit', 'accept'] + ] + + self.verify_nftables(nftables_search, 'bridge vyos_filter') + def test_source_validation(self): # Strict self.cli_set(['firewall', 'global-options', 'source-validation', 'strict']) + self.cli_set(['firewall', 'global-options', 'ipv6-source-validation', 'strict']) self.cli_commit() nftables_strict_search = [ ['fib saddr . iif oif 0', 'drop'] ] - self.verify_nftables(nftables_strict_search, 'inet vyos_global_rpfilter') + self.verify_nftables_chain(nftables_strict_search, 'ip raw', 'vyos_global_rpfilter') + self.verify_nftables_chain(nftables_strict_search, 'ip6 raw', 'vyos_global_rpfilter') # Loose self.cli_set(['firewall', 'global-options', 'source-validation', 'loose']) + self.cli_set(['firewall', 'global-options', 'ipv6-source-validation', 'loose']) self.cli_commit() nftables_loose_search = [ ['fib saddr oif 0', 'drop'] ] - self.verify_nftables(nftables_loose_search, 'inet vyos_global_rpfilter') + self.verify_nftables_chain(nftables_loose_search, 'ip raw', 'vyos_global_rpfilter') + self.verify_nftables_chain(nftables_loose_search, 'ip6 raw', 'vyos_global_rpfilter') def test_sysfs(self): for name, conf in sysfs_config.items(): @@ -564,5 +603,17 @@ class TestFirewall(VyOSUnitTestSHIM.TestCase): with open(path, 'r') as f: self.assertNotEqual(f.read().strip(), conf['default'], msg=path) + def test_flow_offload_software(self): + self.cli_set(['firewall', 'global-options', 'flow-offload', 'software', 'interface', 'eth0']) + self.cli_commit() + nftables_search = [ + ['flowtable VYOS_FLOWTABLE_software'], + ['hook ingress priority filter - 1'], + ['devices = { eth0 }'], + ['flow add @VYOS_FLOWTABLE_software'], + ] + self.verify_nftables(nftables_search, 'inet vyos_offload') + + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_ethernet.py b/smoketest/scripts/cli/test_interfaces_ethernet.py index 5ea21fea8..a39b81348 100755 --- a/smoketest/scripts/cli/test_interfaces_ethernet.py +++ b/smoketest/scripts/cli/test_interfaces_ethernet.py @@ -250,10 +250,19 @@ class EthernetInterfaceTest(BasicInterfaceTest.TestCase): for interface in self._interfaces: # Enable EAPoL self.cli_set(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-server-ca-intermediate']) + self.cli_set(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-client-ca-intermediate']) self.cli_set(self._base_path + [interface, 'eapol', 'certificate', cert_name]) self.cli_commit() + # Test multiple CA chains + self.assertEqual(get_certificate_count(interface, 'ca'), 4) + + for interface in self._interfaces: + self.cli_delete(self._base_path + [interface, 'eapol', 'ca-certificate', 'eapol-client-ca-intermediate']) + + self.cli_commit() + # Check for running process self.assertTrue(process_named_running('wpa_supplicant')) diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py index d1ece84d6..4a7e2418c 100755 --- a/smoketest/scripts/cli/test_interfaces_openvpn.py +++ b/smoketest/scripts/cli/test_interfaces_openvpn.py @@ -421,7 +421,7 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase): # IP pool configuration netmask = IPv4Network(subnet).netmask network = IPv4Network(subnet).network_address - self.assertIn(f'server {network} {netmask} nopool', config) + self.assertIn(f'server {network} {netmask}', config) # Verify client client_config = read_file(client_config_file) @@ -442,80 +442,6 @@ class TestInterfacesOpenVPN(VyOSUnitTestSHIM.TestCase): interface = f'vtun{ii}' self.assertNotIn(interface, interfaces()) - def test_openvpn_server_net30_topology(self): - # Create OpenVPN server interfaces (net30) using different client - # subnets. Validate configuration afterwards. - auth_hash = 'sha256' - num_range = range(20, 25) - port = '' - for ii in num_range: - interface = f'vtun{ii}' - subnet = f'192.0.{ii}.0/24' - path = base_path + [interface] - port = str(2000 + ii) - - self.cli_set(path + ['device-type', 'tun']) - self.cli_set(path + ['encryption', 'cipher', 'aes192']) - self.cli_set(path + ['hash', auth_hash]) - self.cli_set(path + ['mode', 'server']) - self.cli_set(path + ['local-port', port]) - self.cli_set(path + ['server', 'subnet', subnet]) - self.cli_set(path + ['server', 'topology', 'net30']) - self.cli_set(path + ['replace-default-route']) - self.cli_set(path + ['keep-alive', 'failure-count', '10']) - self.cli_set(path + ['keep-alive', 'interval', '5']) - self.cli_set(path + ['tls', 'ca-certificate', 'ovpn_test']) - self.cli_set(path + ['tls', 'certificate', 'ovpn_test']) - self.cli_set(path + ['tls', 'dh-params', 'ovpn_test']) - self.cli_set(path + ['vrf', vrf_name]) - - self.cli_commit() - - for ii in num_range: - interface = f'vtun{ii}' - subnet = f'192.0.{ii}.0/24' - start_addr = inc_ip(subnet, '4') - stop_addr = dec_ip(last_host_address(subnet), '1') - port = str(2000 + ii) - - config_file = f'/run/openvpn/{interface}.conf' - config = read_file(config_file) - - self.assertIn(f'dev {interface}', config) - self.assertIn(f'dev-type tun', config) - self.assertIn(f'persist-key', config) - self.assertIn(f'proto udp', config) # default protocol - self.assertIn(f'auth {auth_hash}', config) - self.assertIn(f'cipher AES-192-CBC', config) - self.assertIn(f'topology net30', config) - self.assertIn(f'lport {port}', config) - self.assertIn(f'push "redirect-gateway def1"', config) - self.assertIn(f'keepalive 5 50', config) - - # TLS options - self.assertIn(f'ca /run/openvpn/{interface}_ca.pem', config) - self.assertIn(f'cert /run/openvpn/{interface}_cert.pem', config) - self.assertIn(f'key /run/openvpn/{interface}_cert.key', config) - self.assertIn(f'dh /run/openvpn/{interface}_dh.pem', config) - - # IP pool configuration - netmask = IPv4Network(subnet).netmask - network = IPv4Network(subnet).network_address - self.assertIn(f'server {network} {netmask} nopool', config) - self.assertIn(f'ifconfig-pool {start_addr} {stop_addr}', config) - - self.assertTrue(process_named_running(PROCESS_NAME)) - self.assertEqual(get_vrf(interface), vrf_name) - self.assertIn(interface, interfaces()) - - # check that no interface remained after deleting them - self.cli_delete(base_path) - self.cli_commit() - - for ii in num_range: - interface = f'vtun{ii}' - self.assertNotIn(interface, interfaces()) - def test_openvpn_site2site_verify(self): # Create one OpenVPN site2site interface and check required # verify() stages diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py index f6b203de4..e9c9e68fd 100755 --- a/smoketest/scripts/cli/test_interfaces_vxlan.py +++ b/smoketest/scripts/cli/test_interfaces_vxlan.py @@ -20,6 +20,8 @@ from vyos.configsession import ConfigSessionError from vyos.ifconfig import Interface from vyos.utils.network import get_bridge_fdb from vyos.utils.network import get_interface_config +from vyos.utils.network import interface_exists +from vyos.utils.network import get_vxlan_vlan_tunnels from vyos.template import is_ipv6 from base_interfaces_test import BasicInterfaceTest @@ -133,5 +135,53 @@ class VXLANInterfaceTest(BasicInterfaceTest.TestCase): self.assertTrue(options['linkinfo']['info_data']['external']) self.assertEqual('vxlan', options['linkinfo']['info_kind']) + def test_vxlan_vlan_vni_mapping(self): + bridge = 'br0' + interface = 'vxlan0' + source_interface = 'eth0' + + vlan_to_vni = { + '10': '10010', + '11': '10011', + '12': '10012', + '13': '10013', + '20': '10020', + '30': '10030', + '31': '10031', + } + + self.cli_set(self._base_path + [interface, 'external']) + self.cli_set(self._base_path + [interface, 'source-interface', source_interface]) + + for vlan, vni in vlan_to_vni.items(): + self.cli_set(self._base_path + [interface, 'vlan-to-vni', vlan, 'vni', vni]) + + # This must fail as this VXLAN interface is not associated with any bridge + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(['interfaces', 'bridge', bridge, 'member', 'interface', interface]) + + # It is not allowed to use duplicate VNIs + self.cli_set(self._base_path + [interface, 'vlan-to-vni', '11', 'vni', vlan_to_vni['10']]) + with self.assertRaises(ConfigSessionError): + self.cli_commit() + # restore VLAN - VNI mappings + for vlan, vni in vlan_to_vni.items(): + self.cli_set(self._base_path + [interface, 'vlan-to-vni', vlan, 'vni', vni]) + + # commit configuration + self.cli_commit() + + self.assertTrue(interface_exists(bridge)) + self.assertTrue(interface_exists(interface)) + + tmp = get_interface_config(interface) + self.assertEqual(tmp['master'], bridge) + + tmp = get_vxlan_vlan_tunnels('vxlan0') + self.assertEqual(tmp, list(vlan_to_vni)) + + self.cli_delete(['interfaces', 'bridge', bridge]) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py index f8686edd8..95246a7b9 100755 --- a/smoketest/scripts/cli/test_interfaces_wireless.py +++ b/smoketest/scripts/cli/test_interfaces_wireless.py @@ -97,6 +97,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase): vht_opt = { # VyOS CLI option hostapd - ht_capab setting + 'channel-set-width 3' : '[VHT160-80PLUS80]', 'stbc tx' : '[TX-STBC-2BY1]', 'stbc rx 12' : '[RX-STBC-12]', 'ldpc' : '[RXLDPC]', @@ -104,7 +105,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.TestCase): 'vht-cf' : '[HTC-VHT]', 'antenna-pattern-fixed' : '[RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN]', 'max-mpdu 11454' : '[MAX-MPDU-11454]', - 'max-mpdu-exp 2' : '[MAX-A-MPDU-LEN-EXP-2][VHT160]', + 'max-mpdu-exp 2' : '[MAX-A-MPDU-LEN-EXP-2]', 'link-adaptation both' : '[VHT-LINK-ADAPT3]', 'short-gi 80' : '[SHORT-GI-80]', 'short-gi 160' : '[SHORT-GI-160]', diff --git a/smoketest/scripts/cli/test_load_balancing_wan.py b/smoketest/scripts/cli/test_load_balancing_wan.py index 9b2cb0fac..47ca19b27 100755 --- a/smoketest/scripts/cli/test_load_balancing_wan.py +++ b/smoketest/scripts/cli/test_load_balancing_wan.py @@ -124,11 +124,12 @@ class TestLoadBalancingWan(VyOSUnitTestSHIM.TestCase): self.assertEqual(tmp, original) # Delete veth interfaces and netns - for iface in [iface1, iface2, iface3, container_iface1, container_iface2, container_iface3]: + for iface in [iface1, iface2, iface3]: call(f'sudo ip link del dev {iface}') delete_netns(ns1) delete_netns(ns2) + delete_netns(ns3) def test_check_chains(self): @@ -246,11 +247,13 @@ class TestLoadBalancingWan(VyOSUnitTestSHIM.TestCase): self.assertEqual(tmp, nat_vyos_pre_snat_hook) # Delete veth interfaces and netns - for iface in [iface1, iface2, iface3, container_iface1, container_iface2, container_iface3]: + for iface in [iface1, iface2, iface3]: call(f'sudo ip link del dev {iface}') delete_netns(ns1) delete_netns(ns2) + delete_netns(ns3) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py index 31dfcef87..703e5ab28 100755 --- a/smoketest/scripts/cli/test_nat.py +++ b/smoketest/scripts/cli/test_nat.py @@ -155,11 +155,6 @@ class TestNAT(VyOSUnitTestSHIM.TestCase): rule = '5' self.cli_set(src_path + ['rule', rule, 'source', 'address', '192.0.2.0/24']) - # check validate() - outbound-interface must be defined - with self.assertRaises(ConfigSessionError): - self.cli_commit() - self.cli_set(src_path + ['rule', rule, 'outbound-interface', 'eth0']) - # check validate() - translation address not specified with self.assertRaises(ConfigSessionError): self.cli_commit() diff --git a/smoketest/scripts/cli/test_interfaces_netns.py b/smoketest/scripts/cli/test_netns.py index b8bebb221..fd04dd520 100755 --- a/smoketest/scripts/cli/test_interfaces_netns.py +++ b/smoketest/scripts/cli/test_netns.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2021 VyOS maintainers and contributors +# Copyright (C) 2021-2023 VyOS maintainers and contributors # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 or later as @@ -16,7 +16,6 @@ import unittest -from netifaces import interfaces from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSession @@ -24,56 +23,61 @@ from vyos.configsession import ConfigSessionError from vyos.ifconfig import Interface from vyos.ifconfig import Section from vyos.utils.process import cmd +from vyos.utils.network import is_netns_interface +from vyos.utils.network import get_netns_all base_path = ['netns'] -namespaces = ['mgmt', 'front', 'back', 'ams-ix'] +interfaces = ['dum10', 'dum12', 'dum50'] -class NETNSTest(VyOSUnitTestSHIM.TestCase): - def setUp(self): - self._interfaces = ['dum10', 'dum12', 'dum50'] +class NetNSTest(VyOSUnitTestSHIM.TestCase): + def tearDown(self): + self.cli_delete(base_path) + # commit changes + self.cli_commit() + + # There should be no network namespace remaining + tmp = cmd('ip netns ls') + self.assertFalse(tmp) + + super(NetNSTest, self).tearDown() - def test_create_netns(self): + def test_netns_create(self): + namespaces = ['mgmt', 'front', 'back'] for netns in namespaces: - base = base_path + ['name', netns] - self.cli_set(base) + self.cli_set(base_path + ['name', netns]) # commit changes self.cli_commit() - netns_list = cmd('ip netns ls') - # Verify NETNS configuration for netns in namespaces: - self.assertTrue(netns in netns_list) - + self.assertIn(netns, get_netns_all()) - def test_netns_assign_interface(self): + def test_netns_interface(self): netns = 'foo' - self.cli_set(['netns', 'name', netns]) + self.cli_set(base_path + ['name', netns]) # Set - for iface in self._interfaces: + for iface in interfaces: self.cli_set(['interfaces', 'dummy', iface, 'netns', netns]) # commit changes self.cli_commit() - netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show') - - for iface in self._interfaces: - self.assertTrue(iface in netns_iface_list) + for interface in interfaces: + self.assertTrue(is_netns_interface(interface, netns)) # Delete - for iface in self._interfaces: - self.cli_delete(['interfaces', 'dummy', iface, 'netns', netns]) + for interface in interfaces: + self.cli_delete(['interfaces', 'dummy', interface]) # commit changes self.cli_commit() netns_iface_list = cmd(f'sudo ip netns exec {netns} ip link show') - for iface in self._interfaces: - self.assertNotIn(iface, netns_iface_list) + for interface in interfaces: + self.assertFalse(is_netns_interface(interface, netns)) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_policy_route.py b/smoketest/scripts/cli/test_policy_route.py index d9b64544a..118b1d3a2 100755 --- a/smoketest/scripts/cli/test_policy_route.py +++ b/smoketest/scripts/cli/test_policy_route.py @@ -250,7 +250,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): ['meta l4proto udp', 'drop'], ['tcp flags syn / syn,ack', 'meta mark set ' + mark_hex], ['ct state new', 'tcp dport 22', 'ip saddr 198.51.100.0/24', 'ip ttl > 2', 'meta mark set ' + mark_hex], - ['meta l4proto icmp', 'log prefix "[smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex], + ['meta l4proto icmp', 'log prefix "[ipv4-route-smoketest-4-A]"', 'icmp type echo-request', 'ip length { 128, 1024-2048 }', 'meta pkttype other', 'meta mark set ' + mark_hex], ['ip dscp { 0x29, 0x39-0x3b }', 'meta mark set ' + mark_hex] ] @@ -262,7 +262,7 @@ class TestPolicyRoute(VyOSUnitTestSHIM.TestCase): ['meta l4proto udp', 'drop'], ['tcp flags syn / syn,ack', 'meta mark set ' + mark_hex], ['ct state new', 'tcp dport 22', 'ip6 saddr 2001:db8::/64', 'ip6 hoplimit > 2', 'meta mark set ' + mark_hex], - ['meta l4proto ipv6-icmp', 'log prefix "[smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta pkttype multicast', 'meta mark set ' + mark_hex], + ['meta l4proto ipv6-icmp', 'log prefix "[ipv6-route6-smoketest6-4-A]"', 'icmpv6 type echo-request', 'ip6 length != { 128, 1024-2048 }', 'meta pkttype multicast', 'meta mark set ' + mark_hex], ['ip6 dscp != { 0x0e-0x13, 0x3d }', 'meta mark set ' + mark_hex] ] diff --git a/smoketest/scripts/cli/test_protocols_pim6.py b/smoketest/scripts/cli/test_protocols_pim6.py new file mode 100755 index 000000000..1be12836d --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_pim6.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2023 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import unittest + +from base_vyostest_shim import VyOSUnitTestSHIM +from vyos.configsession import ConfigSessionError +from vyos.ifconfig import Section +from vyos.utils.process import process_named_running + +PROCESS_NAME = 'pim6d' +base_path = ['protocols', 'pim6'] + + +class TestProtocolsPIMv6(VyOSUnitTestSHIM.TestCase): + def tearDown(self): + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + self.cli_delete(base_path) + self.cli_commit() + + def test_pim6_01_mld_simple(self): + # commit changes + interfaces = Section.interfaces('ethernet') + + for interface in interfaces: + self.cli_set(base_path + ['interface', interface]) + + self.cli_commit() + + # Verify FRR pim6d configuration + for interface in interfaces: + config = self.getFRRconfig( + f'interface {interface}', daemon=PROCESS_NAME) + self.assertIn(f'interface {interface}', config) + self.assertIn(f' ipv6 mld', config) + self.assertNotIn(f' ipv6 mld version 1', config) + + # Change to MLD version 1 + for interface in interfaces: + self.cli_set(base_path + ['interface', + interface, 'mld', 'version', '1']) + + self.cli_commit() + + # Verify FRR pim6d configuration + for interface in interfaces: + config = self.getFRRconfig( + f'interface {interface}', daemon=PROCESS_NAME) + self.assertIn(f'interface {interface}', config) + self.assertIn(f' ipv6 mld', config) + self.assertIn(f' ipv6 mld version 1', config) + + def test_pim6_02_mld_join(self): + # commit changes + interfaces = Section.interfaces('ethernet') + + # Use an invalid multiple group address + for interface in interfaces: + self.cli_set(base_path + ['interface', + interface, 'mld', 'join', 'fd00::1234']) + + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(base_path + ['interface']) + + # Use a valid multiple group address + for interface in interfaces: + self.cli_set(base_path + ['interface', + interface, 'mld', 'join', 'ff18::1234']) + + self.cli_commit() + + # Verify FRR pim6d configuration + for interface in interfaces: + config = self.getFRRconfig( + f'interface {interface}', daemon=PROCESS_NAME) + self.assertIn(f'interface {interface}', config) + self.assertIn(f' ipv6 mld join ff18::1234', config) + + # Join a source-specific multicast group + for interface in interfaces: + self.cli_set(base_path + ['interface', interface, + 'mld', 'join', 'ff38::5678', 'source', '2001:db8::5678']) + + self.cli_commit() + + # Verify FRR pim6d configuration + for interface in interfaces: + config = self.getFRRconfig( + f'interface {interface}', daemon=PROCESS_NAME) + self.assertIn(f'interface {interface}', config) + self.assertIn(f' ipv6 mld join ff38::5678 2001:db8::5678', config) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_system_conntrack.py b/smoketest/scripts/cli/test_system_conntrack.py index 2a89aa98b..ea304783d 100755 --- a/smoketest/scripts/cli/test_system_conntrack.py +++ b/smoketest/scripts/cli/test_system_conntrack.py @@ -35,6 +35,17 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase): self.cli_delete(base_path) self.cli_commit() + def verify_nftables(self, nftables_search, table, inverse=False, args=''): + nftables_output = cmd(f'sudo nft {args} list table {table}') + + for search in nftables_search: + matched = False + for line in nftables_output.split("\n"): + if all(item in line for item in search): + matched = True + break + self.assertTrue(not matched if inverse else matched, msg=search) + def test_conntrack_options(self): conntrack_config = { 'net.netfilter.nf_conntrack_expect_max' : { @@ -232,5 +243,51 @@ class TestSystemConntrack(VyOSUnitTestSHIM.TestCase): tmp = read_file('/etc/modprobe.d/vyatta_nf_conntrack.conf') self.assertIn(hash_size_default, tmp) + def test_conntrack_ignore(self): + address_group = 'conntracktest' + address_group_member = '192.168.0.1' + ipv6_address_group = 'conntracktest6' + ipv6_address_group_member = 'dead:beef::1' + + self.cli_set(['firewall', 'group', 'address-group', address_group, 'address', address_group_member]) + self.cli_set(['firewall', 'group', 'ipv6-address-group', ipv6_address_group, 'address', ipv6_address_group_member]) + + self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'source', 'address', '192.0.2.1']) + self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'destination', 'address', '192.0.2.2']) + self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'destination', 'port', '22']) + self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '1', 'protocol', 'tcp']) + + self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '2', 'source', 'address', '192.0.2.1']) + self.cli_set(base_path + ['ignore', 'ipv4', 'rule', '2', 'destination', 'group', 'address-group', address_group]) + + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'source', 'address', 'fe80::1']) + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'destination', 'address', 'fe80::2']) + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'destination', 'port', '22']) + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '11', 'protocol', 'tcp']) + + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '12', 'source', 'address', 'fe80::1']) + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '12', 'destination', 'group', 'address-group', ipv6_address_group]) + + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '13', 'source', 'address', 'fe80::1']) + self.cli_set(base_path + ['ignore', 'ipv6', 'rule', '13', 'destination', 'address', '!fe80::3']) + + self.cli_commit() + + nftables_search = [ + ['ip saddr 192.0.2.1', 'ip daddr 192.0.2.2', 'tcp dport 22', 'notrack'], + ['ip saddr 192.0.2.1', 'ip daddr @A_conntracktest', 'notrack'] + ] + + nftables6_search = [ + ['ip6 saddr fe80::1', 'ip6 daddr fe80::2', 'tcp dport 22', 'notrack'], + ['ip6 saddr fe80::1', 'ip6 daddr @A6_conntracktest6', 'notrack'], + ['ip6 saddr fe80::1', 'ip6 daddr != fe80::3', 'notrack'] + ] + + self.verify_nftables(nftables_search, 'raw') + self.verify_nftables(nftables6_search, 'ip6 raw') + + self.cli_delete(['firewall']) + if __name__ == '__main__': unittest.main(verbosity=2) |