diff options
Diffstat (limited to 'smoketest/scripts/cli/test_interfaces_tunnel.py')
| -rwxr-xr-x | smoketest/scripts/cli/test_interfaces_tunnel.py | 447 |
1 files changed, 152 insertions, 295 deletions
diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py index ca68cb8ba..6af31ddff 100755 --- a/smoketest/scripts/cli/test_interfaces_tunnel.py +++ b/smoketest/scripts/cli/test_interfaces_tunnel.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (C) 2020 VyOS maintainers and contributors +# Copyright (C) 2020-2021 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 @@ -15,365 +15,222 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import unittest -import json - -from vyos.configsession import ConfigSession -from vyos.configsession import ConfigSessionError -from vyos.util import cmd from base_interfaces_test import BasicInterfaceTest +from vyos.configsession import ConfigSessionError +from vyos.util import get_interface_config +from vyos.template import inc_ip + remote_ip4 = '192.0.2.100' remote_ip6 = '2001:db8::ffff' source_if = 'dum2222' mtu = 1476 -def tunnel_conf(interface): - tmp = cmd(f'ip -d -j link show {interface}') - # {'address': '2.2.2.2', - # 'broadcast': '192.0.2.10', - # 'flags': ['POINTOPOINT', 'NOARP', 'UP', 'LOWER_UP'], - # 'group': 'default', - # 'gso_max_segs': 65535, - # 'gso_max_size': 65536, - # 'ifindex': 10, - # 'ifname': 'tun10', - # 'inet6_addr_gen_mode': 'none', - # 'link': None, - # 'link_pointtopoint': True, - # 'link_type': 'gre', - # 'linkinfo': {'info_data': {'local': '2.2.2.2', - # 'pmtudisc': True, - # 'remote': '192.0.2.10', - # 'tos': '0x1', - # 'ttl': 255}, - # 'info_kind': 'gre'}, - # 'linkmode': 'DEFAULT', - # 'max_mtu': 65511, - # 'min_mtu': 68, - # 'mtu': 1476, - # 'num_rx_queues': 1, - # 'num_tx_queues': 1, - # 'operstate': 'UNKNOWN', - # 'promiscuity': 0, - # 'qdisc': 'noqueue', - # 'txqlen': 1000} - return json.loads(tmp)[0] - -class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): - def setUp(self): - self._test_mtu = True - self._base_path = ['interfaces', 'tunnel'] - self.local_v4 = '192.0.2.1' - self.local_v6 = '2001:db8::1' - - self._options = { - 'tun10': ['encapsulation ipip', 'remote-ip 192.0.2.10', 'local-ip ' + self.local_v4], - 'tun20': ['encapsulation gre', 'remote-ip 192.0.2.20', 'local-ip ' + self.local_v4], +class TunnelInterfaceTest(BasicInterfaceTest.TestCase): + @classmethod + def setUpClass(cls): + cls._test_ip = True + cls._test_ipv6 = True + cls._test_mtu = True + cls._base_path = ['interfaces', 'tunnel'] + cls.local_v4 = '192.0.2.1' + cls.local_v6 = '2001:db8::1' + cls._options = { + 'tun10': ['encapsulation ipip', 'remote 192.0.2.10', 'source-address ' + cls.local_v4], + 'tun20': ['encapsulation gre', 'remote 192.0.2.20', 'source-address ' + cls.local_v4], } + cls._interfaces = list(cls._options) + # call base-classes classmethod + super(cls, cls).setUpClass() - self._interfaces = list(self._options) + def setUp(self): super().setUp() - - self.session.set(['interfaces', 'dummy', source_if, 'address', self.local_v4 + '/32']) - self.session.set(['interfaces', 'dummy', source_if, 'address', self.local_v6 + '/128']) + self.cli_set(['interfaces', 'dummy', source_if, 'address', self.local_v4 + '/32']) + self.cli_set(['interfaces', 'dummy', source_if, 'address', self.local_v6 + '/128']) def tearDown(self): - self.session.delete(['interfaces', 'dummy', source_if]) + self.cli_delete(['interfaces', 'dummy', source_if]) super().tearDown() - def test_ipip(self): - interface = 'tun100' - encapsulation = 'ipip' - local_if_addr = '10.10.10.1/24' - - self.session.set(self._base_path + [interface, 'address', local_if_addr]) - - # Must provide an "encapsulation" for tunnel tun10 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - - # Must configure either local-ip or dhcp-interface for tunnel ipip tun100 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) - - # missing required option remote for ipip - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) - - # Configure Tunnel Source interface - self.session.set(self._base_path + [interface, 'source-interface', source_if]) - - self.session.commit() - - conf = tunnel_conf(interface) - self.assertEqual(interface, conf['ifname']) - self.assertEqual(encapsulation, conf['link_type']) - self.assertEqual(mtu, conf['mtu']) - self.assertEqual(source_if, conf['link']) - - self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) - - def test_ipip6(self): - interface = 'tun110' - encapsulation = 'ipip6' - local_if_addr = '10.10.10.1/24' - - self.session.set(self._base_path + [interface, 'address', local_if_addr]) - - # Must provide an "encapsulation" for tunnel tun10 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - - # Must configure either local-ip or dhcp-interface for tunnel ipip tun100 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) - - # missing required option remote for ipip - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip6]) - - # Configure Tunnel Source interface - self.session.set(self._base_path + [interface, 'source-interface', source_if]) - - self.session.commit() - - conf = tunnel_conf(interface) - self.assertEqual(interface, conf['ifname']) - self.assertEqual('tunnel6', conf['link_type']) - self.assertEqual(mtu, conf['mtu']) - self.assertEqual(source_if, conf['link']) - - self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote']) - - def test_tunnel_verify_ipv4_local_remote_addr(self): + def test_ipv4_encapsulations(self): # When running tests ensure that for certain encapsulation types the # local and remote IP address is actually an IPv4 address interface = f'tun1000' local_if_addr = f'10.10.200.1/24' - for encapsulation in ['ipip', 'sit', 'gre']: - self.session.set(self._base_path + [interface, 'address', local_if_addr]) - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip6]) + for encapsulation in ['ipip', 'sit', 'gre', 'gretap']: + self.cli_set(self._base_path + [interface, 'address', local_if_addr]) + self.cli_set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.cli_set(self._base_path + [interface, 'source-address', self.local_v6]) + self.cli_set(self._base_path + [interface, 'remote', remote_ip6]) - # Encapsulation mode requires IPv4 local-ip + # Encapsulation mode requires IPv4 source-address with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) + self.cli_commit() + self.cli_set(self._base_path + [interface, 'source-address', self.local_v4]) - # Encapsulation mode requires IPv4 local-ip + # Encapsulation mode requires IPv4 remote with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) + self.cli_commit() + self.cli_set(self._base_path + [interface, 'remote', remote_ip4]) + self.cli_set(self._base_path + [interface, 'source-interface', source_if]) + + # Source interface can not be used with sit and gretap + if encapsulation in ['sit', 'gretap']: + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(self._base_path + [interface, 'source-interface']) # Check if commit is ok - self.session.commit() + self.cli_commit() + + conf = get_interface_config(interface) + if encapsulation not in ['sit', 'gretap']: + self.assertEqual(source_if, conf['link']) + + self.assertEqual(interface, conf['ifname']) + self.assertEqual(mtu, conf['mtu']) + self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) + self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) + self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) + self.assertTrue(conf['linkinfo']['info_data']['pmtudisc']) # cleanup this instance - self.session.delete(self._base_path + [interface]) - self.session.commit() + self.cli_delete(self._base_path + [interface]) + self.cli_commit() - def test_tunnel_verify_ipv6_local_remote_addr(self): + def test_ipv6_encapsulations(self): # When running tests ensure that for certain encapsulation types the # local and remote IP address is actually an IPv6 address interface = f'tun1010' local_if_addr = f'10.10.200.1/24' - for encapsulation in ['ipip6', 'ip6ip6', 'ip6gre']: - self.session.set(self._base_path + [interface, 'address', local_if_addr]) - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) + for encapsulation in ['ipip6', 'ip6ip6', 'ip6gre', 'ip6gretap']: + self.cli_set(self._base_path + [interface, 'address', local_if_addr]) + self.cli_set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.cli_set(self._base_path + [interface, 'source-address', self.local_v4]) + self.cli_set(self._base_path + [interface, 'remote', remote_ip4]) - # Encapsulation mode requires IPv6 local-ip + # Encapsulation mode requires IPv6 source-address with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) + self.cli_commit() + self.cli_set(self._base_path + [interface, 'source-address', self.local_v6]) - # Encapsulation mode requires IPv6 local-ip + # Encapsulation mode requires IPv6 remote with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip6]) + self.cli_commit() + self.cli_set(self._base_path + [interface, 'remote', remote_ip6]) - # Check if commit is ok - self.session.commit() + # Configure Tunnel Source interface + self.cli_set(self._base_path + [interface, 'source-interface', source_if]) + # Source interface can not be used with ip6gretap + if encapsulation in ['ip6gretap']: + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(self._base_path + [interface, 'source-interface']) - # cleanup this instance - self.session.delete(self._base_path + [interface]) - self.session.commit() + # Check if commit is ok + self.cli_commit() - def test_tunnel_verify_local_dhcp(self): - # We can not use local-ip and dhcp-interface at the same time + conf = get_interface_config(interface) + if encapsulation not in ['ip6gretap']: + self.assertEqual(source_if, conf['link']) - interface = f'tun1020' - local_if_addr = f'10.0.0.1/24' + self.assertEqual(interface, conf['ifname']) + self.assertEqual(mtu, conf['mtu']) - self.session.set(self._base_path + [interface, 'address', local_if_addr]) - self.session.set(self._base_path + [interface, 'encapsulation', 'gre']) - self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) - self.session.set(self._base_path + [interface, 'dhcp-interface', 'eth0']) + # Not applicable for ip6gre + if 'proto' in conf['linkinfo']['info_data']: + self.assertEqual(encapsulation, conf['linkinfo']['info_data']['proto']) - # local-ip and dhcp-interface can not be used at the same time - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.delete(self._base_path + [interface, 'dhcp-interface']) + # remap encapsulation protocol(s) only for ipip6, ip6ip6 + if encapsulation in ['ipip6', 'ip6ip6']: + encapsulation = 'ip6tnl' - # Check if commit is ok - self.session.commit() + self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) + self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local']) + self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote']) - def test_tunnel_ip6ip6(self): - interface = 'tun120' - encapsulation = 'ip6ip6' - local_if_addr = '2001:db8:f00::1/24' + # cleanup this instance + self.cli_delete(self._base_path + [interface]) + self.cli_commit() - self.session.set(self._base_path + [interface, 'address', local_if_addr]) + def test_tunnel_verify_local_dhcp(self): + # We can not use source-address and dhcp-interface at the same time - # Must provide an "encapsulation" for tunnel tun10 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) + interface = f'tun1020' + local_if_addr = f'10.0.0.1/24' - # Must configure either local-ip or dhcp-interface for tunnel ipip tun100 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) + self.cli_set(self._base_path + [interface, 'address', local_if_addr]) + self.cli_set(self._base_path + [interface, 'encapsulation', 'gre']) + self.cli_set(self._base_path + [interface, 'source-address', self.local_v4]) + self.cli_set(self._base_path + [interface, 'remote', remote_ip4]) + self.cli_set(self._base_path + [interface, 'dhcp-interface', 'eth0']) - # missing required option remote for ipip + # source-address and dhcp-interface can not be used at the same time with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip6]) - - # Configure Tunnel Source interface - self.session.set(self._base_path + [interface, 'source-interface', source_if]) + self.cli_commit() + self.cli_delete(self._base_path + [interface, 'dhcp-interface']) - self.session.commit() - - conf = tunnel_conf(interface) - self.assertEqual(interface, conf['ifname']) - self.assertEqual('tunnel6', conf['link_type']) - self.assertEqual(mtu, conf['mtu']) - self.assertEqual(source_if, conf['link']) - - self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote']) + # Check if commit is ok + self.cli_commit() - def test_tunnel_gre_ipv4(self): - interface = 'tun200' + def test_tunnel_parameters_gre(self): + interface = f'tun1030' + gre_key = '10' encapsulation = 'gre' - local_if_addr = '172.16.1.1/24' + tos = '20' - self.session.set(self._base_path + [interface, 'address', local_if_addr]) + self.cli_set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.cli_set(self._base_path + [interface, 'source-address', self.local_v4]) + self.cli_set(self._base_path + [interface, 'remote', remote_ip4]) - # Must provide an "encapsulation" for tunnel tun10 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - - # Must configure either local-ip or dhcp-interface - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) - - # No assertion is raised for GRE remote-ip when missing - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) - - # Configure Tunnel Source interface - self.session.set(self._base_path + [interface, 'source-interface', source_if]) - - self.session.commit() + self.cli_set(self._base_path + [interface, 'parameters', 'ip', 'no-pmtu-discovery']) + self.cli_set(self._base_path + [interface, 'parameters', 'ip', 'key', gre_key]) + self.cli_set(self._base_path + [interface, 'parameters', 'ip', 'tos', tos]) - conf = tunnel_conf(interface) - self.assertEqual(interface, conf['ifname']) - self.assertEqual(encapsulation, conf['link_type']) - self.assertEqual(mtu, conf['mtu']) - self.assertEqual(source_if, conf['link']) + # Check if commit is ok + self.cli_commit() + conf = get_interface_config(interface) + self.assertEqual(mtu, conf['mtu']) + self.assertEqual(interface, conf['ifname']) + self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) - - - def test_gre_ipv6(self): - interface = 'tun210' - encapsulation = 'ip6gre' - local_if_addr = '2001:db8:f01::1/24' + self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) + self.assertEqual(0, conf['linkinfo']['info_data']['ttl']) + self.assertFalse( conf['linkinfo']['info_data']['pmtudisc']) - self.session.set(self._base_path + [interface, 'address', local_if_addr]) + def test_gretap_parameters_change(self): + interface = f'tun1040' + gre_key = '10' + encapsulation = 'gretap' + tos = '20' - # Must provide an "encapsulation" for tunnel tun10 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - - # Must configure either local-ip or dhcp-interface - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) + self.cli_set(self._base_path + [interface, 'encapsulation', encapsulation]) + self.cli_set(self._base_path + [interface, 'source-address', self.local_v4]) + self.cli_set(self._base_path + [interface, 'remote', remote_ip4]) - # No assertion is raised for GRE remote-ip when missing - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip6]) - - # Configure Tunnel Source interface - self.session.set(self._base_path + [interface, 'source-interface', source_if]) - - self.session.commit() - - conf = tunnel_conf(interface) - self.assertEqual(interface, conf['ifname']) - self.assertEqual(encapsulation, conf['link_type']) - self.assertEqual(mtu, conf['mtu']) - self.assertEqual(source_if, conf['link']) - - self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip6, conf['linkinfo']['info_data']['remote']) - - - def test_tunnel_sit(self): - interface = 'tun300' - encapsulation = 'sit' - local_if_addr = '172.16.2.1/24' - - self.session.set(self._base_path + [interface, 'address', local_if_addr]) - - # Must provide an "encapsulation" for tunnel tun10 - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'encapsulation', encapsulation]) - - # Must configure either local-ip or dhcp-interface - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) - - # No assertion is raised for GRE remote-ip when missing - self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) - - # Source interface can not be used with sit - self.session.set(self._base_path + [interface, 'source-interface', source_if]) - with self.assertRaises(ConfigSessionError): - self.session.commit() - self.session.delete(self._base_path + [interface, 'source-interface']) - - self.session.commit() - - conf = tunnel_conf(interface) - self.assertEqual(interface, conf['ifname']) - self.assertEqual(encapsulation, conf['link_type']) - self.assertEqual(mtu, conf['mtu']) + # Check if commit is ok + self.cli_commit() + conf = get_interface_config(interface) + self.assertEqual(mtu, conf['mtu']) + self.assertEqual(interface, conf['ifname']) + self.assertEqual(encapsulation, conf['linkinfo']['info_kind']) self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local']) - self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) + self.assertEqual(remote_ip4, conf['linkinfo']['info_data']['remote']) + self.assertEqual(0, conf['linkinfo']['info_data']['ttl']) + + # Change remote ip address (inc host by 2 + new_remote = inc_ip(remote_ip4, 2) + self.cli_set(self._base_path + [interface, 'remote', new_remote]) + # Check if commit is ok + self.cli_commit() + conf = get_interface_config(interface) + self.assertEqual(new_remote, conf['linkinfo']['info_data']['remote']) if __name__ == '__main__': unittest.main(verbosity=2) |
