summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest/scripts/cli')
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py9
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bonding.py40
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py35
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_dummy.py8
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_erspan.py135
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_ethernet.py46
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_geneve.py16
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_l2tpv3.py16
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_loopback.py18
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_macsec.py20
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_openvpn.py10
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pppoe.py21
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_pseudo_ethernet.py26
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_tunnel.py28
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_vxlan.py18
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireguard.py2
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wireless.py14
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_wirelessmodem.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bfd.py181
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_bgp.py230
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py60
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py63
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_rip.py138
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ripng.py133
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_rpki.py159
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static.py385
-rwxr-xr-xsmoketest/scripts/cli/test_service_bcast-relay.py1
-rwxr-xr-xsmoketest/scripts/cli/test_vrf.py50
28 files changed, 1596 insertions, 268 deletions
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 8f21ec70e..1426e80c2 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -402,12 +402,13 @@ class BasicInterfaceTest:
tmp = read_file(f'/proc/sys/net/ipv6/conf/{interface}/dad_transmits')
self.assertEqual(dad_transmits, tmp)
- def test_dhcpv6_client_options(self):
+ def test_dhcpv6_clinet_options(self):
if not self._test_ipv6_dhcpc6:
self.skipTest('not supported')
- duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:10'
+ duid_base = 10
for interface in self._interfaces:
+ duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:{}'.format(duid_base)
path = self._base_path + [interface]
for option in self._options.get(interface, []):
self.session.set(path + option.split())
@@ -417,10 +418,13 @@ class BasicInterfaceTest:
self.session.set(path + ['dhcpv6-options', 'rapid-commit'])
self.session.set(path + ['dhcpv6-options', 'parameters-only'])
self.session.set(path + ['dhcpv6-options', 'duid', duid])
+ duid_base += 1
self.session.commit()
+ duid_base = 10
for interface in self._interfaces:
+ duid = '00:01:00:01:27:71:db:f0:00:50:00:00:00:{}'.format(duid_base)
dhcpc6_config = read_file(f'/run/dhcp6c/dhcp6c.{interface}.conf')
self.assertIn(f'interface {interface} ' + '{', dhcpc6_config)
self.assertIn(f' request domain-name-servers;', dhcpc6_config)
@@ -430,6 +434,7 @@ class BasicInterfaceTest:
self.assertIn(f' send rapid-commit;', dhcpc6_config)
self.assertIn(f' send client-id {duid};', dhcpc6_config)
self.assertIn('};', dhcpc6_config)
+ duid_base += 1
# Check for running process
self.assertTrue(process_named_running('dhcp6c'))
diff --git a/smoketest/scripts/cli/test_interfaces_bonding.py b/smoketest/scripts/cli/test_interfaces_bonding.py
index 882d38760..b65d97d30 100755
--- a/smoketest/scripts/cli/test_interfaces_bonding.py
+++ b/smoketest/scripts/cli/test_interfaces_bonding.py
@@ -25,34 +25,32 @@ from vyos.configsession import ConfigSessionError
from vyos.util import read_file
class BondingInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._test_ipv6_pd = True
- self._test_ipv6_dhcpc6 = True
- self._test_mtu = True
- self._test_vlan = True
- self._test_qinq = True
- self._base_path = ['interfaces', 'bonding']
- self._interfaces = ['bond0']
- self._mirror_interfaces = ['dum21354']
- self._members = []
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._test_ipv6_pd = True
+ cls._test_ipv6_dhcpc6 = True
+ cls._test_mtu = True
+ cls._test_vlan = True
+ cls._test_qinq = True
+ cls._base_path = ['interfaces', 'bonding']
+ cls._interfaces = ['bond0']
+ cls._mirror_interfaces = ['dum21354']
+ cls._members = []
# we need to filter out VLAN interfaces identified by a dot (.)
# in their name - just in case!
if 'TEST_ETH' in os.environ:
- self._members = os.environ['TEST_ETH'].split()
+ cls._members = os.environ['TEST_ETH'].split()
else:
- for tmp in Section.interfaces("ethernet"):
+ for tmp in Section.interfaces('ethernet'):
if not '.' in tmp:
- self._members.append(tmp)
-
- self._options['bond0'] = []
- for member in self._members:
- self._options['bond0'].append(f'member interface {member}')
-
- super().setUp()
+ cls._members.append(tmp)
+ cls._options['bond0'] = []
+ for member in cls._members:
+ cls._options['bond0'].append(f'member interface {member}')
def test_add_single_ip_address(self):
super().test_add_single_ip_address()
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index 33c2e7dad..f64b527b3 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -28,31 +28,30 @@ from vyos.util import read_file
from vyos.validate import is_intf_addr_assigned
class BridgeInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._test_ipv6_pd = True
- self._test_ipv6_dhcpc6 = True
- self._test_vlan = True
- self._base_path = ['interfaces', 'bridge']
- self._mirror_interfaces = ['dum21354']
- self._members = []
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._test_ipv6_pd = True
+ cls._test_ipv6_dhcpc6 = True
+ cls._test_vlan = True
+ cls._base_path = ['interfaces', 'bridge']
+ cls._mirror_interfaces = ['dum21354']
+ cls._members = []
# we need to filter out VLAN interfaces identified by a dot (.)
# in their name - just in case!
if 'TEST_ETH' in os.environ:
- self._members = os.environ['TEST_ETH'].split()
+ cls._members = os.environ['TEST_ETH'].split()
else:
- for tmp in Section.interfaces("ethernet"):
+ for tmp in Section.interfaces('ethernet'):
if not '.' in tmp:
- self._members.append(tmp)
+ cls._members.append(tmp)
- self._options['br0'] = []
- for member in self._members:
- self._options['br0'].append(f'member interface {member}')
- self._interfaces = list(self._options)
-
- super().setUp()
+ cls._options['br0'] = []
+ for member in cls._members:
+ cls._options['br0'].append(f'member interface {member}')
+ cls._interfaces = list(cls._options)
def tearDown(self):
for intf in self._interfaces:
diff --git a/smoketest/scripts/cli/test_interfaces_dummy.py b/smoketest/scripts/cli/test_interfaces_dummy.py
index 60465a1d5..6e462bccf 100755
--- a/smoketest/scripts/cli/test_interfaces_dummy.py
+++ b/smoketest/scripts/cli/test_interfaces_dummy.py
@@ -19,10 +19,10 @@ import unittest
from base_interfaces_test import BasicInterfaceTest
class DummyInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._base_path = ['interfaces', 'dummy']
- self._interfaces = ['dum435', 'dum8677', 'dum0931', 'dum089']
- super().setUp()
+ @classmethod
+ def setUpClass(cls):
+ cls._base_path = ['interfaces', 'dummy']
+ cls._interfaces = ['dum435', 'dum8677', 'dum0931', 'dum089']
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_erspan.py b/smoketest/scripts/cli/test_interfaces_erspan.py
new file mode 100755
index 000000000..c180f0a34
--- /dev/null
+++ b/smoketest/scripts/cli/test_interfaces_erspan.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 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
+import json
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.util import cmd
+
+from base_interfaces_test import BasicInterfaceTest
+
+mtu = 1500
+
+def erspan_conf(interface):
+ tmp = cmd(f'ip -d -j link show {interface}')
+ '''
+ [
+ {
+ "ifindex": 17,
+ "link": null,
+ "ifname": "ersp0",
+ "flags": [
+ "BROADCAST",
+ "MULTICAST"
+ ],
+ "mtu": 1450,
+ "qdisc": "noop",
+ "operstate": "DOWN",
+ "linkmode": "DEFAULT",
+ "group": "default",
+ "txqlen": 1000,
+ "link_type": "ether",
+ "address": "22:27:14:7b:0d:79",
+ "broadcast": "ff:ff:ff:ff:ff:ff",
+ "promiscuity": 0,
+ "min_mtu": 68,
+ "max_mtu": 0,
+ "linkinfo": {
+ "info_kind": "erspan",
+ "info_data": {
+ "remote": "10.2.2.2",
+ "local": "10.1.1.1",
+ "ttl": 0,
+ "pmtudisc": true,
+ "ikey": "0.0.0.123",
+ "okey": "0.0.0.123",
+ "iseq": true,
+ "oseq": true,
+ "erspan_index": 0,
+ "erspan_ver": 1
+ }
+ },
+ "inet6_addr_gen_mode": "eui64",
+ "num_tx_queues": 1,
+ "num_rx_queues": 1,
+ "gso_max_size": 65536,
+ "gso_max_segs": 65535
+ }
+ ]
+ '''
+ return json.loads(tmp)[0]
+
+class ERSPanTunnelInterfaceTest(BasicInterfaceTest.BaseTest):
+ def setUp(self):
+ super().setUp()
+
+ self._base_path = ['interfaces', 'erspan']
+ self._test_mtu = True
+
+ self.local_v4 = '10.1.1.1'
+ self.local_v6 = '2001:db8::1'
+ self.remote_v4 = '10.2.2.2'
+ self.remote_v6 = '2001:db9::1'
+
+ def tearDown(self):
+ self.session.delete(['interfaces', 'erspan'])
+ super().tearDown()
+
+ def test_erspan_ipv4(self):
+ interface = 'ersp100'
+ encapsulation = 'erspan'
+ key = 123
+
+ 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', self.remote_v4])
+ self.session.set(self._base_path + [interface, 'parameters', 'ip' , 'key', str(key)])
+
+ self.session.commit()
+
+ conf = erspan_conf(interface)
+ self.assertEqual(interface, conf['ifname'])
+ self.assertEqual(encapsulation, conf['linkinfo']['info_kind'])
+ self.assertEqual(mtu, conf['mtu'])
+
+ self.assertEqual(self.local_v4, conf['linkinfo']['info_data']['local'])
+ self.assertEqual(self.remote_v4, conf['linkinfo']['info_data']['remote'])
+
+
+ def test_erspan_ipv6(self):
+ interface = 'ersp1000'
+ encapsulation = 'ip6erspan'
+ key = 123
+
+ 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', self.remote_v6])
+ self.session.set(self._base_path + [interface, 'parameters', 'ip' , 'key', str(key)])
+
+ self.session.commit()
+
+ conf = erspan_conf(interface)
+ self.assertEqual(interface, conf['ifname'])
+ self.assertEqual(encapsulation, conf['linkinfo']['info_kind'])
+ self.assertEqual(mtu, conf['mtu'])
+
+ self.assertEqual(self.local_v6, conf['linkinfo']['info_data']['local'])
+ self.assertEqual(self.remote_v6, conf['linkinfo']['info_data']['remote'])
+
+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 6c6e66008..772ff248f 100755
--- a/smoketest/scripts/cli/test_interfaces_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_ethernet.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
@@ -35,38 +35,31 @@ def get_wpa_supplicant_value(interface, key):
return tmp[0]
class EthernetInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._test_ipv6_pd = True
- self._test_ipv6_dhcpc6 = True
- self._test_mtu = True
- self._test_vlan = True
- self._test_qinq = True
- self._base_path = ['interfaces', 'ethernet']
- self._mirror_interfaces = ['dum21354']
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._test_ipv6_pd = True
+ cls._test_ipv6_dhcpc6 = True
+ cls._test_mtu = True
+ cls._test_vlan = True
+ cls._test_qinq = True
+ cls._base_path = ['interfaces', 'ethernet']
+ cls._mirror_interfaces = ['dum21354']
# we need to filter out VLAN interfaces identified by a dot (.)
# in their name - just in case!
if 'TEST_ETH' in os.environ:
tmp = os.environ['TEST_ETH'].split()
- self._interfaces = tmp
+ cls._interfaces = tmp
else:
- for tmp in Section.interfaces("ethernet"):
+ for tmp in Section.interfaces('ethernet'):
if not '.' in tmp:
- self._interfaces.append(tmp)
+ cls._interfaces.append(tmp)
- self._macs = {}
- for interface in self._interfaces:
- try:
- mac = self.session.show_config(self._base_path +
- [interface, 'hw-id']).split()[1]
- except:
- # during initial system startup there is no hw-id node
- mac = read_file(f'/sys/class/net/{interface}/address')
- self._macs[interface] = mac
-
- super().setUp()
+ cls._macs = {}
+ for interface in cls._interfaces:
+ cls._macs[interface] = read_file(f'/sys/class/net/{interface}/address')
def tearDown(self):
@@ -102,8 +95,7 @@ class EthernetInterfaceTest(BasicInterfaceTest.BaseTest):
# Validate interface state
for interface in self._interfaces:
- with open(f'/sys/class/net/{interface}/flags', 'r') as f:
- flags = f.read()
+ flags = read_file(f'/sys/class/net/{interface}/flags')
self.assertEqual(int(flags, 16) & 1, 0)
def test_offloading_rps(self):
diff --git a/smoketest/scripts/cli/test_interfaces_geneve.py b/smoketest/scripts/cli/test_interfaces_geneve.py
index 12cded400..b708b5437 100755
--- a/smoketest/scripts/cli/test_interfaces_geneve.py
+++ b/smoketest/scripts/cli/test_interfaces_geneve.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
@@ -20,16 +20,16 @@ from vyos.configsession import ConfigSession
from base_interfaces_test import BasicInterfaceTest
class GeneveInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._base_path = ['interfaces', 'geneve']
- self._options = {
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._base_path = ['interfaces', 'geneve']
+ cls._options = {
'gnv0': ['vni 10', 'remote 127.0.1.1'],
'gnv1': ['vni 20', 'remote 127.0.1.2'],
}
- self._interfaces = list(self._options)
- super().setUp()
+ cls._interfaces = list(cls._options)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_l2tpv3.py b/smoketest/scripts/cli/test_interfaces_l2tpv3.py
index 81af6d7f4..a89895b92 100755
--- a/smoketest/scripts/cli/test_interfaces_l2tpv3.py
+++ b/smoketest/scripts/cli/test_interfaces_l2tpv3.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
@@ -21,11 +21,12 @@ from base_interfaces_test import BasicInterfaceTest
from vyos.util import cmd
class GeneveInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._base_path = ['interfaces', 'l2tpv3']
- self._options = {
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._base_path = ['interfaces', 'l2tpv3']
+ cls._options = {
'l2tpeth10': ['local-ip 127.0.0.1', 'remote-ip 127.10.10.10',
'tunnel-id 100', 'peer-tunnel-id 10',
'session-id 100', 'peer-session-id 10',
@@ -35,8 +36,7 @@ class GeneveInterfaceTest(BasicInterfaceTest.BaseTest):
'session-id 20', 'tunnel-id 200',
'source-port 2020', 'destination-port 20202'],
}
- self._interfaces = list(self._options)
- super().setUp()
+ cls._interfaces = list(cls._options)
def test_add_single_ip_address(self):
super().test_add_single_ip_address()
diff --git a/smoketest/scripts/cli/test_interfaces_loopback.py b/smoketest/scripts/cli/test_interfaces_loopback.py
index 36000c3ff..77dd4c1b5 100755
--- a/smoketest/scripts/cli/test_interfaces_loopback.py
+++ b/smoketest/scripts/cli/test_interfaces_loopback.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
@@ -21,13 +21,13 @@ from netifaces import interfaces
from vyos.validate import is_intf_addr_assigned
+loopbacks = ['127.0.0.1', '::1']
+
class LoopbackInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- super().setUp()
- # these addresses are never allowed to be removed from the system
- self._loopback_addresses = ['127.0.0.1', '::1']
- self._base_path = ['interfaces', 'loopback']
- self._interfaces = ['lo']
+ @classmethod
+ def setUpClass(cls):
+ cls._base_path = ['interfaces', 'loopback']
+ cls._interfaces = ['lo']
def tearDown(self):
self.session.delete(self._base_path)
@@ -40,12 +40,12 @@ class LoopbackInterfaceTest(BasicInterfaceTest.BaseTest):
def test_add_single_ip_address(self):
super().test_add_single_ip_address()
- for addr in self._loopback_addresses:
+ for addr in loopbacks:
self.assertTrue(is_intf_addr_assigned('lo', addr))
def test_add_multiple_ip_addresses(self):
super().test_add_multiple_ip_addresses()
- for addr in self._loopback_addresses:
+ for addr in loopbacks:
self.assertTrue(is_intf_addr_assigned('lo', addr))
def test_interface_disable(self):
diff --git a/smoketest/scripts/cli/test_interfaces_macsec.py b/smoketest/scripts/cli/test_interfaces_macsec.py
index 89743e5fd..3a3e7bff3 100755
--- a/smoketest/scripts/cli/test_interfaces_macsec.py
+++ b/smoketest/scripts/cli/test_interfaces_macsec.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
@@ -31,19 +31,19 @@ def get_config_value(interface, key):
return tmp[0]
class MACsecInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- super().setUp()
- self._test_ip = True
- self._test_ipv6 = True
- self._base_path = ['interfaces', 'macsec']
- self._options = { 'macsec0': ['source-interface eth0', 'security cipher gcm-aes-128'] }
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._base_path = ['interfaces', 'macsec']
+ cls._options = { 'macsec0': ['source-interface eth0', 'security cipher gcm-aes-128'] }
# if we have a physical eth1 interface, add a second macsec instance
- if 'eth1' in Section.interfaces("ethernet"):
+ if 'eth1' in Section.interfaces('ethernet'):
macsec = { 'macsec1': [f'source-interface eth1', 'security cipher gcm-aes-128'] }
- self._options.update(macsec)
+ cls._options.update(macsec)
- self._interfaces = list(self._options)
+ cls._interfaces = list(cls._options)
def test_macsec_encryption(self):
# MACsec can be operating in authentication and encryption mode - both
diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py
index 00db3f667..a2a1a85ec 100755
--- a/smoketest/scripts/cli/test_interfaces_openvpn.py
+++ b/smoketest/scripts/cli/test_interfaces_openvpn.py
@@ -625,27 +625,27 @@ if __name__ == '__main__':
# Generate mandatory SSL certificate
tmp = f'openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 '\
f'-keyout {ssl_key} -out {ssl_cert} -subj {subject}'
- print(cmd(tmp))
+ cmd(tmp)
if not os.path.isfile(ca_cert):
# Generate "CA"
tmp = f'openssl req -new -x509 -key {ssl_key} -out {ca_cert} -subj {subject}'
- print(cmd(tmp))
+ cmd(tmp)
if not os.path.isfile(dh_pem):
# Generate "DH" key
tmp = f'openssl dhparam -out {dh_pem} 2048'
- print(cmd(tmp))
+ cmd(tmp)
if not os.path.isfile(s2s_key):
# Generate site-2-site key
tmp = f'openvpn --genkey --secret {s2s_key}'
- print(cmd(tmp))
+ cmd(tmp)
if not os.path.isfile(auth_key):
# Generate TLS auth key
tmp = f'openvpn --genkey --secret {auth_key}'
- print(cmd(tmp))
+ cmd(tmp)
for file in [ca_cert, ssl_cert, ssl_key, dh_pem, s2s_key, auth_key]:
cmd(f'sudo chown openvpn:openvpn {file}')
diff --git a/smoketest/scripts/cli/test_interfaces_pppoe.py b/smoketest/scripts/cli/test_interfaces_pppoe.py
index 6bfe35d86..285c756e2 100755
--- a/smoketest/scripts/cli/test_interfaces_pppoe.py
+++ b/smoketest/scripts/cli/test_interfaces_pppoe.py
@@ -97,6 +97,27 @@ class PPPoEInterfaceTest(unittest.TestCase):
self.assertTrue(running)
+
+ def test_pppoe_clent_disabled_interface(self):
+ # Check if PPPoE Client can be disabled
+ for interface in self._interfaces:
+ self.session.set(base_path + [interface, 'authentication', 'user', 'vyos'])
+ self.session.set(base_path + [interface, 'authentication', 'password', 'vyos'])
+ self.session.set(base_path + [interface, 'source-interface', self._source_interface])
+ self.session.set(base_path + [interface, 'disable'])
+
+ self.session.commit()
+
+ # Validate PPPoE client process
+ running = False
+ for interface in self._interfaces:
+ for proc in process_iter():
+ if interface in proc.cmdline():
+ running = True
+
+ self.assertFalse(running)
+
+
def test_pppoe_dhcpv6pd(self):
# Check if PPPoE dialer can be configured with DHCPv6-PD
address = '1'
diff --git a/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py b/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py
index 1a5debb79..f4cb4cdc9 100755
--- a/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.py
+++ b/smoketest/scripts/cli/test_interfaces_pseudo_ethernet.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
@@ -19,21 +19,21 @@ import unittest
from base_interfaces_test import BasicInterfaceTest
class PEthInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._test_ipv6_pd = True
- self._test_ipv6_dhcpc6 = True
- self._test_mtu = True
- self._test_vlan = True
- self._test_qinq = True
- self._base_path = ['interfaces', 'pseudo-ethernet']
- self._options = {
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._test_ipv6_pd = True
+ cls._test_ipv6_dhcpc6 = True
+ cls._test_mtu = True
+ cls._test_vlan = True
+ cls._test_qinq = True
+ cls._base_path = ['interfaces', 'pseudo-ethernet']
+ cls._options = {
'peth0': ['source-interface eth1'],
'peth1': ['source-interface eth1'],
}
- self._interfaces = list(self._options)
- super().setUp()
+ cls._interfaces = list(cls._options)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py
index 8405fc7d0..a9250e3e5 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
@@ -61,22 +61,22 @@ def tunnel_conf(interface):
return json.loads(tmp)[0]
class TunnelInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- 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],
+ @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-ip 192.0.2.10', 'local-ip ' + cls.local_v4],
+ 'tun20': ['encapsulation gre', 'remote-ip 192.0.2.20', 'local-ip ' + cls.local_v4],
}
+ cls._interfaces = list(cls._options)
- 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'])
diff --git a/smoketest/scripts/cli/test_interfaces_vxlan.py b/smoketest/scripts/cli/test_interfaces_vxlan.py
index a726aa610..fcc1b15ce 100755
--- a/smoketest/scripts/cli/test_interfaces_vxlan.py
+++ b/smoketest/scripts/cli/test_interfaces_vxlan.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
@@ -20,17 +20,17 @@ from vyos.configsession import ConfigSession, ConfigSessionError
from base_interfaces_test import BasicInterfaceTest
class VXLANInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._test_ipv6 = True
- self._test_mtu = True
- self._base_path = ['interfaces', 'vxlan']
- self._options = {
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._test_ipv6 = True
+ cls._test_mtu = True
+ cls._base_path = ['interfaces', 'vxlan']
+ cls._options = {
'vxlan0': ['vni 10', 'remote 127.0.0.2'],
'vxlan1': ['vni 20', 'group 239.1.1.1', 'source-interface eth0'],
}
- self._interfaces = list(self._options)
- super().setUp()
+ cls._interfaces = list(cls._options)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_interfaces_wireguard.py b/smoketest/scripts/cli/test_interfaces_wireguard.py
index d9a51b146..e70324f96 100755
--- a/smoketest/scripts/cli/test_interfaces_wireguard.py
+++ b/smoketest/scripts/cli/test_interfaces_wireguard.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
diff --git a/smoketest/scripts/cli/test_interfaces_wireless.py b/smoketest/scripts/cli/test_interfaces_wireless.py
index 51d97f032..39e8cd5b8 100755
--- a/smoketest/scripts/cli/test_interfaces_wireless.py
+++ b/smoketest/scripts/cli/test_interfaces_wireless.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
@@ -32,10 +32,11 @@ def get_config_value(interface, key):
return tmp[0]
class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
- def setUp(self):
- self._test_ip = True
- self._base_path = ['interfaces', 'wireless']
- self._options = {
+ @classmethod
+ def setUpClass(cls):
+ cls._test_ip = True
+ cls._base_path = ['interfaces', 'wireless']
+ cls._options = {
'wlan0': ['physical-device phy0', 'ssid VyOS-WIFI-0',
'type station', 'address 192.0.2.1/30'],
'wlan1': ['physical-device phy0', 'ssid VyOS-WIFI-1', 'country-code se',
@@ -45,8 +46,7 @@ class WirelessInterfaceTest(BasicInterfaceTest.BaseTest):
'wlan11': ['physical-device phy1', 'ssid VyOS-WIFI-3', 'country-code se',
'type access-point', 'address 192.0.2.13/30', 'channel 0'],
}
- self._interfaces = list(self._options)
- super().setUp()
+ cls._interfaces = list(cls._options)
def test_wireless_add_single_ip_address(self):
# derived method to check if member interfaces are enslaved properly
diff --git a/smoketest/scripts/cli/test_interfaces_wirelessmodem.py b/smoketest/scripts/cli/test_interfaces_wirelessmodem.py
index 696a6946b..023f57305 100755
--- a/smoketest/scripts/cli/test_interfaces_wirelessmodem.py
+++ b/smoketest/scripts/cli/test_interfaces_wirelessmodem.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
diff --git a/smoketest/scripts/cli/test_protocols_bfd.py b/smoketest/scripts/cli/test_protocols_bfd.py
new file mode 100755
index 000000000..80e5daa7c
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_bfd.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'bfdd'
+base_path = ['protocols', 'bfd']
+
+dum_if = 'dum1001'
+peers = {
+ '192.0.2.10' : {
+ 'intv_rx' : '500',
+ 'intv_tx' : '600',
+ 'multihop' : '',
+ 'source_addr': '192.0.2.254',
+ },
+ '192.0.2.20' : {
+ 'echo_mode' : '',
+ 'intv_echo' : '100',
+ 'intv_mult' : '100',
+ 'intv_rx' : '222',
+ 'intv_tx' : '333',
+ 'shutdown' : '',
+ 'source_intf': dum_if,
+ },
+ '2001:db8::a' : {
+ 'source_addr': '2001:db8::1',
+ 'source_intf': dum_if,
+ },
+ '2001:db8::b' : {
+ 'source_addr': '2001:db8::1',
+ 'multihop' : '',
+ },
+}
+
+profiles = {
+ 'foo' : {
+ 'echo_mode' : '',
+ 'intv_echo' : '100',
+ 'intv_mult' : '101',
+ 'intv_rx' : '222',
+ 'intv_tx' : '333',
+ 'shutdown' : '',
+ },
+ 'bar' : {
+ 'intv_mult' : '102',
+ 'intv_rx' : '444',
+ },
+}
+
+def getFRRconfig():
+ return cmd('vtysh -c "show run" | sed -n "/^bfd/,/^!/p"')
+
+def getBFDPeerconfig(peer):
+ return cmd(f'vtysh -c "show run" | sed -n "/^ {peer}/,/^!/p"')
+
+def getBFDProfileconfig(profile):
+ return cmd(f'vtysh -c "show run" | sed -n "/^ {profile}/,/^!/p"')
+
+class TestProtocolsBFD(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ self.session.commit()
+ del self.session
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_bfd_peer(self):
+ for peer, peer_config in peers.items():
+ if 'echo_mode' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'echo-mode'])
+ if 'intv_echo' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'interval', 'echo-interval', peer_config["intv_echo"]])
+ if 'intv_mult' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'interval', 'multiplier', peer_config["intv_mult"]])
+ if 'intv_rx' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'interval', 'receive', peer_config["intv_rx"]])
+ if 'intv_tx' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'interval', 'transmit', peer_config["intv_tx"]])
+ if 'multihop' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'multihop'])
+ if 'shutdown' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'shutdown'])
+ if 'source_addr' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'source', 'address', peer_config["source_addr"]])
+ if 'source_intf' in peer_config:
+ self.session.set(base_path + ['peer', peer, 'source', 'interface', peer_config["source_intf"]])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR bgpd configuration
+ frrconfig = getFRRconfig()
+ for peer, peer_config in peers.items():
+ tmp = f'peer {peer}'
+ if 'multihop' in peer_config:
+ tmp += f' multihop'
+ if 'source_addr' in peer_config:
+ tmp += f' local-address {peer_config["source_addr"]}'
+ if 'source_intf' in peer_config:
+ tmp += f' interface {peer_config["source_intf"]}'
+
+ self.assertIn(tmp, frrconfig)
+ peerconfig = getBFDPeerconfig(tmp)
+
+ if 'echo_mode' in peer_config:
+ self.assertIn(f' echo-mode', peerconfig)
+ if 'intv_echo' in peer_config:
+ self.assertIn(f' echo-interval {peer_config["intv_echo"]}', peerconfig)
+ if 'intv_mult' in peer_config:
+ self.assertIn(f' detect-multiplier {peer_config["intv_mult"]}', peerconfig)
+ if 'intv_rx' in peer_config:
+ self.assertIn(f' receive-interval {peer_config["intv_rx"]}', peerconfig)
+ if 'intv_tx' in peer_config:
+ self.assertIn(f' transmit-interval {peer_config["intv_tx"]}', peerconfig)
+ if 'shutdown' not in peer_config:
+ self.assertIn(f' no shutdown', peerconfig)
+
+ def test_bfd_profile(self):
+ peer = '192.0.2.10'
+
+ for profile, profile_config in profiles.items():
+ if 'echo_mode' in profile_config:
+ self.session.set(base_path + ['profile', profile, 'echo-mode'])
+ if 'intv_echo' in profile_config:
+ self.session.set(base_path + ['profile', profile, 'interval', 'echo-interval', profile_config["intv_echo"]])
+ if 'intv_mult' in profile_config:
+ self.session.set(base_path + ['profile', profile, 'interval', 'multiplier', profile_config["intv_mult"]])
+ if 'intv_rx' in profile_config:
+ self.session.set(base_path + ['profile', profile, 'interval', 'receive', profile_config["intv_rx"]])
+ if 'intv_tx' in profile_config:
+ self.session.set(base_path + ['profile', profile, 'interval', 'transmit', profile_config["intv_tx"]])
+ if 'shutdown' in profile_config:
+ self.session.set(base_path + ['profile', profile, 'shutdown'])
+
+ self.session.set(base_path + ['peer', peer, 'profile', list(profiles)[0]])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR bgpd configuration
+ for profile, profile_config in profiles.items():
+ config = getBFDProfileconfig(f'profile {profile}')
+ if 'echo_mode' in profile_config:
+ self.assertIn(f' echo-mode', config)
+ if 'intv_echo' in profile_config:
+ self.assertIn(f' echo-interval {profile_config["intv_echo"]}', config)
+ if 'intv_mult' in profile_config:
+ self.assertIn(f' detect-multiplier {profile_config["intv_mult"]}', config)
+ if 'intv_rx' in profile_config:
+ self.assertIn(f' receive-interval {profile_config["intv_rx"]}', config)
+ if 'intv_tx' in profile_config:
+ self.assertIn(f' transmit-interval {profile_config["intv_tx"]}', config)
+ if 'shutdown' not in profile_config:
+ self.assertIn(f' no shutdown', config)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py
index 87d10eb85..b6a6a493c 100755
--- a/smoketest/scripts/cli/test_protocols_bgp.py
+++ b/smoketest/scripts/cli/test_protocols_bgp.py
@@ -19,6 +19,7 @@ import unittest
from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
+from vyos.template import is_ipv6
from vyos.util import cmd
from vyos.util import process_named_running
@@ -30,6 +31,8 @@ route_map_in = 'foo-map-in'
route_map_out = 'foo-map-out'
prefix_list_in = 'pfx-foo-in'
prefix_list_out = 'pfx-foo-out'
+prefix_list_in6 = 'pfx-foo-in6'
+prefix_list_out6 = 'pfx-foo-out6'
neighbor_config = {
'192.0.2.1' : {
@@ -45,6 +48,8 @@ neighbor_config = {
'local_as' : '300',
'route_map_in' : route_map_in,
'route_map_out': route_map_out,
+ 'no_send_comm_ext' : '',
+ 'addpath_all' : '',
},
'192.0.2.2' : {
'remote_as' : '200',
@@ -54,6 +59,7 @@ neighbor_config = {
'cap_strict' : '',
'pfx_list_in' : prefix_list_in,
'pfx_list_out' : prefix_list_out,
+ 'no_send_comm_std' : '',
},
'192.0.2.3' : {
'description' : 'foo bar baz',
@@ -62,6 +68,32 @@ neighbor_config = {
'multi_hop' : '5',
'update_src' : 'lo',
},
+ '2001:db8::1' : {
+ 'cap_dynamic' : '',
+ 'cap_ext_next' : '',
+ 'remote_as' : '123',
+ 'adv_interv' : '400',
+ 'passive' : '',
+ 'password' : 'VyOS-Secure123',
+ 'shutdown' : '',
+ 'cap_over' : '',
+ 'ttl_security' : '5',
+ 'local_as' : '300',
+ 'route_map_in' : route_map_in,
+ 'route_map_out': route_map_out,
+ 'no_send_comm_std' : '',
+ 'addpath_per_as' : '',
+ },
+ '2001:db8::2' : {
+ 'remote_as' : '456',
+ 'shutdown' : '',
+ 'no_cap_nego' : '',
+ 'port' : '667',
+ 'cap_strict' : '',
+ 'pfx_list_in' : prefix_list_in6,
+ 'pfx_list_out' : prefix_list_out6,
+ 'no_send_comm_ext' : '',
+ },
}
peer_group_config = {
@@ -82,6 +114,7 @@ peer_group_config = {
'local_as' : '300',
'pfx_list_in' : prefix_list_in,
'pfx_list_out' : prefix_list_out,
+ 'no_send_comm_ext' : '',
},
'baz' : {
'cap_dynamic' : '',
@@ -96,10 +129,13 @@ peer_group_config = {
}
def getFRRBGPconfig():
- return cmd(f'vtysh -c "show run" | sed -n "/router bgp {ASN}/,/^!/p"')
+ return cmd(f'vtysh -c "show run" | sed -n "/^router bgp {ASN}/,/^!/p"')
+
+def getFRRBGPVNIconfig(vni):
+ return cmd(f'vtysh -c "show run" | sed -n "/^ vni {vni}/,/^!/p"')
def getFRRRPKIconfig():
- return cmd(f'vtysh -c "show run" | sed -n "/rpki/,/^!/p"')
+ return cmd(f'vtysh -c "show run" | sed -n "/^rpki/,/^!/p"')
class TestProtocolsBGP(unittest.TestCase):
def setUp(self):
@@ -112,16 +148,26 @@ class TestProtocolsBGP(unittest.TestCase):
self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'action', 'permit'])
self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '10', 'prefix', '192.0.2.128/25'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_in6, 'rule', '10', 'prefix', '2001:db8:1000::/64'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'action', 'deny'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_out6, 'rule', '10', 'prefix', '2001:db8:2000::/64'])
+
def tearDown(self):
self.session.delete(['policy', 'route-map', route_map_in])
self.session.delete(['policy', 'route-map', route_map_out])
self.session.delete(['policy', 'prefix-list', prefix_list_in])
self.session.delete(['policy', 'prefix-list', prefix_list_out])
+ self.session.delete(['policy', 'prefix-list6', prefix_list_in6])
+ self.session.delete(['policy', 'prefix-list6', prefix_list_out6])
self.session.delete(base_path)
self.session.commit()
del self.session
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
def verify_frr_config(self, peer, peer_config, frrconfig):
# recurring patterns to verify for both a simple neighbor and a peer-group
if 'cap_dynamic' in peer_config:
@@ -158,11 +204,20 @@ class TestProtocolsBGP(unittest.TestCase):
self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_in"]} in', frrconfig)
if 'pfx_list_out' in peer_config:
self.assertIn(f' neighbor {peer} prefix-list {peer_config["pfx_list_out"]} out', frrconfig)
+ if 'no_send_comm_std' in peer_config:
+ self.assertIn(f' no neighbor {peer} send-community', frrconfig)
+ if 'no_send_comm_ext' in peer_config:
+ self.assertIn(f' no neighbor {peer} send-community extended', frrconfig)
+ if 'addpath_all' in peer_config:
+ self.assertIn(f' neighbor {peer} addpath-tx-all-paths', frrconfig)
+ if 'addpath_per_as' in peer_config:
+ self.assertIn(f' neighbor {peer} addpath-tx-bestpath-per-AS', frrconfig)
def test_bgp_01_simple(self):
router_id = '127.0.0.1'
local_pref = '500'
+ stalepath_time = '60'
self.session.set(base_path + ['parameters', 'router-id', router_id])
self.session.set(base_path + ['parameters', 'log-neighbor-changes'])
@@ -170,6 +225,8 @@ class TestProtocolsBGP(unittest.TestCase):
self.session.set(base_path + ['parameters', 'default', 'local-pref', local_pref])
# Deactivate IPv4 unicast for a peer by default
self.session.set(base_path + ['parameters', 'default', 'no-ipv4-unicast'])
+ self.session.set(base_path + ['parameters', 'graceful-restart', 'stalepath-time', stalepath_time])
+ self.session.set(base_path + ['parameters', 'graceful-shutdown'])
# commit changes
self.session.commit()
@@ -181,54 +238,66 @@ class TestProtocolsBGP(unittest.TestCase):
self.assertIn(f' bgp log-neighbor-changes', frrconfig)
self.assertIn(f' bgp default local-preference {local_pref}', frrconfig)
self.assertIn(f' no bgp default ipv4-unicast', frrconfig)
+ self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig)
+ self.assertIn(f' bgp graceful-shutdown', frrconfig)
- # Check for running process
- self.assertTrue(process_named_running(PROCESS_NAME))
def test_bgp_02_neighbors(self):
# Test out individual neighbor configuration items, not all of them are
# also available to a peer-group!
- for neighbor, config in neighbor_config.items():
- if 'adv_interv' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'advertisement-interval', config["adv_interv"]])
- if 'cap_dynamic' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'capability', 'dynamic'])
- if 'cap_ext_next' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'capability', 'extended-nexthop'])
- if 'description' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'description', config["description"]])
- if 'no_cap_nego' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'disable-capability-negotiation'])
- if 'multi_hop' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'ebgp-multihop', config["multi_hop"]])
- if 'local_as' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'local-as', config["local_as"]])
- if 'cap_over' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'override-capability'])
- if 'passive' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'passive'])
- if 'password' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'password', config["password"]])
- if 'port' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'port', config["port"]])
- if 'remote_as' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'remote-as', config["remote_as"]])
- if 'cap_strict' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'strict-capability-match'])
- if 'shutdown' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'shutdown'])
- if 'ttl_security' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'ttl-security', 'hops', config["ttl_security"]])
- if 'update_src' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'update-source', config["update_src"]])
- if 'route_map_in' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-map', 'import', config["route_map_in"]])
- if 'route_map_out' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'route-map', 'export', config["route_map_out"]])
- if 'pfx_list_in' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]])
- if 'pfx_list_out' in config:
- self.session.set(base_path + ['neighbor', neighbor, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]])
+ for peer, peer_config in neighbor_config.items():
+ afi = 'ipv4-unicast'
+ if is_ipv6(peer):
+ afi = 'ipv6-unicast'
+
+ if 'adv_interv' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'advertisement-interval', peer_config["adv_interv"]])
+ if 'cap_dynamic' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'capability', 'dynamic'])
+ if 'cap_ext_next' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'capability', 'extended-nexthop'])
+ if 'description' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'description', peer_config["description"]])
+ if 'no_cap_nego' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'disable-capability-negotiation'])
+ if 'multi_hop' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'ebgp-multihop', peer_config["multi_hop"]])
+ if 'local_as' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'local-as', peer_config["local_as"]])
+ if 'cap_over' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'override-capability'])
+ if 'passive' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'passive'])
+ if 'password' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'password', peer_config["password"]])
+ if 'port' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'port', peer_config["port"]])
+ if 'remote_as' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'remote-as', peer_config["remote_as"]])
+ if 'cap_strict' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'strict-capability-match'])
+ if 'shutdown' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'shutdown'])
+ if 'ttl_security' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'ttl-security', 'hops', peer_config["ttl_security"]])
+ if 'update_src' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'update-source', peer_config["update_src"]])
+ if 'route_map_in' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'import', peer_config["route_map_in"]])
+ if 'route_map_out' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'route-map', 'export', peer_config["route_map_out"]])
+ if 'pfx_list_in' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'prefix-list', 'import', peer_config["pfx_list_in"]])
+ if 'pfx_list_out' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'prefix-list', 'export', peer_config["pfx_list_out"]])
+ if 'no_send_comm_std' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'disable-send-community', 'standard'])
+ if 'no_send_comm_ext' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'disable-send-community', 'extended'])
+ if 'addpath_all' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-all'])
+ if 'addpath_per_as' in peer_config:
+ self.session.set(base_path + ['neighbor', peer, 'address-family', afi, 'addpath-tx-per-as'])
# commit changes
self.session.commit()
@@ -238,11 +307,11 @@ class TestProtocolsBGP(unittest.TestCase):
self.assertIn(f'router bgp {ASN}', frrconfig)
for peer, peer_config in neighbor_config.items():
- if 'adv_interv' in config:
+ if 'adv_interv' in peer_config:
self.assertIn(f' neighbor {peer} advertisement-interval {peer_config["adv_interv"]}', frrconfig)
- if 'port' in config:
+ if 'port' in peer_config:
self.assertIn(f' neighbor {peer} port {peer_config["port"]}', frrconfig)
- if 'cap_strict' in config:
+ if 'cap_strict' in peer_config:
self.assertIn(f' neighbor {peer} strict-capability-match', frrconfig)
self.verify_frr_config(peer, peer_config, frrconfig)
@@ -284,6 +353,14 @@ class TestProtocolsBGP(unittest.TestCase):
self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'import', config["pfx_list_in"]])
if 'pfx_list_out' in config:
self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'prefix-list', 'export', config["pfx_list_out"]])
+ if 'no_send_comm_std' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'disable-send-community', 'standard'])
+ if 'no_send_comm_ext' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'disable-send-community', 'extended'])
+ if 'addpath_all' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-all'])
+ if 'addpath_per_as' in config:
+ self.session.set(base_path + ['peer-group', peer_group, 'address-family', 'ipv4-unicast', 'addpath-tx-per-as'])
# commit changes
self.session.commit()
@@ -311,7 +388,7 @@ class TestProtocolsBGP(unittest.TestCase):
}
# We want to redistribute ...
- redistributes = ['connected', 'kernel', 'ospf', 'rip', 'static']
+ redistributes = ['connected', 'isis', 'kernel', 'ospf', 'rip', 'static']
for redistribute in redistributes:
self.session.set(base_path + ['address-family', 'ipv4-unicast',
'redistribute', redistribute])
@@ -348,12 +425,12 @@ class TestProtocolsBGP(unittest.TestCase):
def test_bgp_05_afi_ipv6(self):
networks = {
'2001:db8:100::/48' : {
- },
+ },
'2001:db8:200::/48' : {
- },
+ },
'2001:db8:300::/48' : {
'summary_only' : '',
- },
+ },
}
# We want to redistribute ...
@@ -420,38 +497,33 @@ class TestProtocolsBGP(unittest.TestCase):
self.assertIn(f' bgp listen range {prefix} peer-group {peer_group}', frrconfig)
- def test_bgp_07_rpki(self):
- rpki_path = ['protocols', 'rpki']
- init_tmo = '50'
- polling = '400'
- preference = '100'
- timeout = '900'
-
- cache = {
- 'foo' : { 'address' : '1.1.1.1', 'port' : '8080' },
-# T3253 only one peer supported
-# 'bar' : { 'address' : '2.2.2.2', 'port' : '9090' },
- }
-
- self.session.set(rpki_path + ['polling-period', polling])
- self.session.set(rpki_path + ['preference', preference])
-
- for name, config in cache.items():
- self.session.set(rpki_path + ['cache', name, 'address', config['address']])
- self.session.set(rpki_path + ['cache', name, 'port', config['port']])
+ def test_bgp_07_l2vpn_evpn(self):
+ vnis = ['10010', '10020', '10030']
+ neighbors = ['192.0.2.10', '192.0.2.20', '192.0.2.30']
+ self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-all-vni'])
+ self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-default-gw'])
+ self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-svi-ip'])
+ self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'flooding', 'disable'])
+ for vni in vnis:
+ self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-default-gw'])
+ self.session.set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-svi-ip'])
# commit changes
self.session.commit()
# Verify FRR bgpd configuration
- frrconfig = getFRRRPKIconfig()
- self.assertIn(f'rpki polling_period {polling}', frrconfig)
-
- for name, config in cache.items():
- self.assertIn('rpki cache {address} {port} preference 1'.format(**config), frrconfig)
-
- self.session.delete(rpki_path)
-
+ frrconfig = getFRRBGPconfig()
+ self.assertIn(f'router bgp {ASN}', frrconfig)
+ self.assertIn(f' address-family l2vpn evpn', frrconfig)
+ self.assertIn(f' advertise-all-vni', frrconfig)
+ self.assertIn(f' advertise-default-gw', frrconfig)
+ self.assertIn(f' advertise-svi-ip', frrconfig)
+ self.assertIn(f' flooding disable', frrconfig)
+ for vni in vnis:
+ vniconfig = getFRRBGPVNIconfig(vni)
+ self.assertIn(f'vni {vni}', vniconfig)
+ self.assertIn(f' advertise-default-gw', vniconfig)
+ self.assertIn(f' advertise-svi-ip', vniconfig)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index d47838d8c..0ca8bb3bd 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -30,6 +30,9 @@ route_map = 'foo-bar-baz10'
def getFRROSPFconfig():
return cmd('vtysh -c "show run" | sed -n "/router ospf/,/^!/p"')
+def getFRRInterfaceConfig(interface):
+ return cmd(f'vtysh -c "show run" | sed -n "/^interface {interface}$/,/^!/p"')
+
class TestProtocolsOSPF(unittest.TestCase):
def setUp(self):
self.session = ConfigSession(os.getpid())
@@ -85,7 +88,7 @@ class TestProtocolsOSPF(unittest.TestCase):
def test_ospf_03_access_list(self):
acl = '100'
seq = '10'
- protocols = ['bgp', 'connected', 'kernel', 'rip', 'static']
+ protocols = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
self.session.set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit'])
self.session.set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any'])
@@ -212,7 +215,7 @@ class TestProtocolsOSPF(unittest.TestCase):
def test_ospf_08_redistribute(self):
metric = '15'
metric_type = '1'
- redistribute = ['bgp', 'connected', 'kernel', 'rip', 'static']
+ redistribute = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
for protocol in redistribute:
self.session.set(base_path + ['redistribute', protocol, 'metric', metric])
@@ -232,24 +235,8 @@ class TestProtocolsOSPF(unittest.TestCase):
else:
self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
-
- def test_ospf_09_area(self):
- area = '0'
+ def test_ospf_09_virtual_link(self):
networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
- for network in networks:
- self.session.set(base_path + ['area', area, 'network', network])
-
- # commit changes
- self.session.commit()
-
- # Verify FRR ospfd configuration
- frrconfig = getFRROSPFconfig()
- self.assertIn(f'router ospf', frrconfig)
- for network in networks:
- self.assertIn(f' network {network} area {area}', frrconfig)
-
-
- def test_ospf_10_virtual_link(self):
area = '10'
shortcut = 'enable'
virtual_link = '192.0.2.1'
@@ -263,6 +250,8 @@ class TestProtocolsOSPF(unittest.TestCase):
self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'retransmit-interval', retransmit])
self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'transmit-delay', transmit])
self.session.set(base_path + ['area', area, 'virtual-link', virtual_link, 'dead-interval', dead])
+ for network in networks:
+ self.session.set(base_path + ['area', area, 'network', network])
# commit changes
self.session.commit()
@@ -272,6 +261,39 @@ class TestProtocolsOSPF(unittest.TestCase):
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' area {area} shortcut {shortcut}', frrconfig)
self.assertIn(f' area {area} virtual-link {virtual_link} hello-interval {hello} retransmit-interval {retransmit} transmit-delay {transmit} dead-interval {dead}', frrconfig)
+ for network in networks:
+ self.assertIn(f' network {network} area {area}', frrconfig)
+
+ def test_ospf_10_interface_configureation(self):
+ interfaces = Section.interfaces('ethernet')
+ password = 'vyos1234'
+ bandwidth = '10000'
+ cost = '150'
+ network = 'point-to-point'
+ priority = '200'
+
+ for interface in interfaces:
+ self.session.set(base_path + ['interface', interface, 'authentication', 'plaintext-password', password])
+ self.session.set(base_path + ['interface', interface, 'bandwidth', bandwidth])
+ self.session.set(base_path + ['interface', interface, 'bfd'])
+ self.session.set(base_path + ['interface', interface, 'cost', cost])
+ self.session.set(base_path + ['interface', interface, 'mtu-ignore'])
+ self.session.set(base_path + ['interface', interface, 'network', network])
+ self.session.set(base_path + ['interface', interface, 'priority', priority])
+
+ # commit changes
+ self.session.commit()
+
+ for interface in interfaces:
+ config = getFRRInterfaceConfig(interface)
+ self.assertIn(f'interface {interface}', config)
+ self.assertIn(f' ip ospf authentication-key {password}', config)
+ self.assertIn(f' ip ospf bfd', config)
+ self.assertIn(f' ip ospf cost {cost}', config)
+ self.assertIn(f' ip ospf mtu-ignore', config)
+ self.assertIn(f' ip ospf network {network}', config)
+ self.assertIn(f' ip ospf priority {priority}', config)
+ self.assertIn(f' bandwidth {bandwidth}', config)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ospfv3.py b/smoketest/scripts/cli/test_protocols_ospfv3.py
index 297d5d996..754c4488f 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -25,10 +25,15 @@ from vyos.util import process_named_running
PROCESS_NAME = 'ospf6d'
base_path = ['protocols', 'ospfv3']
+router_id = '192.0.2.1'
+default_area = '0'
def getFRROSPFconfig():
return cmd('vtysh -c "show run" | sed -n "/router ospf6/,/^!/p"')
+def getFRRIFconfig(iface):
+ return cmd(f'vtysh -c "show run" | sed -n "/^interface {iface}/,/^!/p"')
+
class TestProtocolsOSPFv3(unittest.TestCase):
def setUp(self):
self.session = ConfigSession(os.getpid())
@@ -43,23 +48,21 @@ class TestProtocolsOSPFv3(unittest.TestCase):
def test_ospfv3_01_basic(self):
- area = '0'
seq = '10'
prefix = '2001:db8::/32'
acl_name = 'foo-acl-100'
- router_id = '192.0.2.1'
self.session.set(['policy', 'access-list6', acl_name, 'rule', seq, 'action', 'permit'])
self.session.set(['policy', 'access-list6', acl_name, 'rule', seq, 'source', 'any'])
self.session.set(base_path + ['parameters', 'router-id', router_id])
- self.session.set(base_path + ['area', area, 'range', prefix, 'advertise'])
- self.session.set(base_path + ['area', area, 'export-list', acl_name])
- self.session.set(base_path + ['area', area, 'import-list', acl_name])
+ self.session.set(base_path + ['area', default_area, 'range', prefix, 'advertise'])
+ self.session.set(base_path + ['area', default_area, 'export-list', acl_name])
+ self.session.set(base_path + ['area', default_area, 'import-list', acl_name])
interfaces = Section.interfaces('ethernet')
for interface in interfaces:
- self.session.set(base_path + ['area', area, 'interface', interface])
+ self.session.set(base_path + ['area', default_area, 'interface', interface])
# commit changes
self.session.commit()
@@ -67,13 +70,13 @@ class TestProtocolsOSPFv3(unittest.TestCase):
# Verify FRR ospfd configuration
frrconfig = getFRROSPFconfig()
self.assertIn(f'router ospf6', frrconfig)
- self.assertIn(f' area {area} range {prefix}', frrconfig)
+ self.assertIn(f' area {default_area} range {prefix}', frrconfig)
self.assertIn(f' ospf6 router-id {router_id}', frrconfig)
- self.assertIn(f' area {area} import-list {acl_name}', frrconfig)
- self.assertIn(f' area {area} export-list {acl_name}', frrconfig)
+ self.assertIn(f' area {default_area} import-list {acl_name}', frrconfig)
+ self.assertIn(f' area {default_area} export-list {acl_name}', frrconfig)
for interface in interfaces:
- self.assertIn(f' interface {interface} area {area}', frrconfig)
+ self.assertIn(f' interface {interface} area {default_area}', frrconfig)
self.session.delete(['policy', 'access-list6', acl_name])
@@ -118,6 +121,46 @@ class TestProtocolsOSPFv3(unittest.TestCase):
for protocol in redistribute:
self.assertIn(f' redistribute {protocol} route-map {route_map}', frrconfig)
+ def test_ospfv3_0104_interfaces(self):
+
+ self.session.set(base_path + ['parameters', 'router-id', router_id])
+ self.session.set(base_path + ['area', default_area])
+
+ cost = '100'
+ priority = '10'
+ interfaces = Section.interfaces('ethernet')
+ for interface in interfaces:
+ if_base = base_path + ['interface', interface]
+ self.session.set(if_base + ['bfd'])
+ self.session.set(if_base + ['cost', cost])
+ self.session.set(if_base + ['instance-id', '0'])
+ self.session.set(if_base + ['mtu-ignore'])
+ self.session.set(if_base + ['network', 'point-to-point'])
+ self.session.set(if_base + ['passive'])
+ self.session.set(if_base + ['priority', priority])
+ cost = str(int(cost) + 10)
+ priority = str(int(priority) + 5)
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRROSPFconfig()
+ self.assertIn(f'router ospf6', frrconfig)
+
+ cost = '100'
+ priority = '10'
+ for interface in interfaces:
+ if_config = getFRRIFconfig(interface)
+ self.assertIn(f'interface {interface}', if_config)
+ self.assertIn(f' ipv6 ospf6 bfd', if_config)
+ self.assertIn(f' ipv6 ospf6 cost {cost}', if_config)
+ self.assertIn(f' ipv6 ospf6 mtu-ignore', if_config)
+ self.assertIn(f' ipv6 ospf6 network point-to-point', if_config)
+ self.assertIn(f' ipv6 ospf6 passive', if_config)
+ self.assertIn(f' ipv6 ospf6 priority {priority}', if_config)
+ cost = str(int(cost) + 10)
+ priority = str(int(priority) + 5)
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_rip.py b/smoketest/scripts/cli/test_protocols_rip.py
new file mode 100755
index 000000000..f42ea0c0a
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_rip.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.ifconfig import Section
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'ripd'
+acl_in = '198'
+acl_out = '199'
+prefix_list_in = 'foo-prefix'
+prefix_list_out = 'bar-prefix'
+route_map = 'FooBar123'
+
+base_path = ['protocols', 'rip']
+
+def getFRRconfig():
+ return cmd('vtysh -c "show run" | sed -n "/router rip/,/^!/p"')
+
+class TestProtocolsRIP(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ self.session.set(['policy', 'access-list', acl_in, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'access-list', acl_in, 'rule', '10', 'source', 'any'])
+ self.session.set(['policy', 'access-list', acl_in, 'rule', '10', 'destination', 'any'])
+ self.session.set(['policy', 'access-list', acl_out, 'rule', '20', 'action', 'deny'])
+ self.session.set(['policy', 'access-list', acl_out, 'rule', '20', 'source', 'any'])
+ self.session.set(['policy', 'access-list', acl_out, 'rule', '20', 'destination', 'any'])
+ self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '100', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list', prefix_list_in, 'rule', '100', 'prefix', '192.0.2.0/24'])
+ self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '200', 'action', 'deny'])
+ self.session.set(['policy', 'prefix-list', prefix_list_out, 'rule', '200', 'prefix', '192.0.2.0/24'])
+ self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ self.session.delete(['policy', 'access-list', acl_in])
+ self.session.delete(['policy', 'access-list', acl_out])
+ self.session.delete(['policy', 'prefix-list', prefix_list_in])
+ self.session.delete(['policy', 'prefix-list', prefix_list_out])
+ self.session.delete(['policy', 'route-map', route_map])
+
+ self.session.commit()
+ del self.session
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_rip(self):
+ distance = '40'
+ network_distance = '66'
+ metric = '8'
+ interfaces = Section.interfaces('ethernet')
+ neighbors = ['1.2.3.4', '1.2.3.5', '1.2.3.6']
+ networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
+ redistribute = ['bgp', 'connected', 'isis', 'kernel', 'ospf', 'static']
+ timer_garbage = '888'
+ timer_timeout = '1000'
+ timer_update = '90'
+
+ self.session.set(base_path + ['default-distance', distance])
+ self.session.set(base_path + ['default-information', 'originate'])
+ self.session.set(base_path + ['default-metric', metric])
+ self.session.set(base_path + ['distribute-list', 'access-list', 'in', acl_in])
+ self.session.set(base_path + ['distribute-list', 'access-list', 'out', acl_out])
+ self.session.set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in])
+ self.session.set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out])
+ self.session.set(base_path + ['passive-interface', 'default'])
+ self.session.set(base_path + ['timers', 'garbage-collection', timer_garbage])
+ self.session.set(base_path + ['timers', 'timeout', timer_timeout])
+ self.session.set(base_path + ['timers', 'update', timer_update])
+ for interface in interfaces:
+ self.session.set(base_path + ['interface', interface])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out])
+ for neighbor in neighbors:
+ self.session.set(base_path + ['neighbor', neighbor])
+ for network in networks:
+ self.session.set(base_path + ['network', network])
+ self.session.set(base_path + ['network-distance', network, 'distance', network_distance])
+ self.session.set(base_path + ['route', network])
+ for proto in redistribute:
+ self.session.set(base_path + ['redistribute', proto, 'metric', metric])
+ self.session.set(base_path + ['redistribute', proto, 'route-map', route_map])
+
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRRconfig()
+ self.assertIn(f'router rip', frrconfig)
+ self.assertIn(f' distance {distance}', frrconfig)
+ self.assertIn(f' default-information originate', frrconfig)
+ self.assertIn(f' default-metric {metric}', frrconfig)
+ self.assertIn(f' distribute-list {acl_in} in', frrconfig)
+ self.assertIn(f' distribute-list {acl_out} out', frrconfig)
+ self.assertIn(f' distribute-list prefix {prefix_list_in} in', frrconfig)
+ self.assertIn(f' distribute-list prefix {prefix_list_out} out', frrconfig)
+ self.assertIn(f' passive-interface default', frrconfig)
+ self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig)
+ for interface in interfaces:
+ self.assertIn(f' network {interface}', frrconfig)
+ self.assertIn(f' distribute-list {acl_in} in {interface}', frrconfig)
+ self.assertIn(f' distribute-list {acl_out} out {interface}', frrconfig)
+ self.assertIn(f' distribute-list prefix {prefix_list_in} in {interface}', frrconfig)
+ self.assertIn(f' distribute-list prefix {prefix_list_out} out {interface}', frrconfig)
+ for neighbor in neighbors:
+ self.assertIn(f' neighbor {neighbor}', frrconfig)
+ for network in networks:
+ self.assertIn(f' network {network}', frrconfig)
+ self.assertIn(f' distance {network_distance} {network}', frrconfig)
+ self.assertIn(f' route {network}', frrconfig)
+ for proto in redistribute:
+ self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py
new file mode 100755
index 000000000..6850b60d3
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_ripng.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.ifconfig import Section
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'ripngd'
+acl_in = '198'
+acl_out = '199'
+prefix_list_in = 'foo-prefix'
+prefix_list_out = 'bar-prefix'
+route_map = 'FooBar123'
+
+base_path = ['protocols', 'ripng']
+
+def getFRRconfig():
+ return cmd('vtysh -c "show run" | sed -n "/router ripng/,/^!/p"')
+
+class TestProtocolsRIPng(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ self.session.set(['policy', 'access-list6', acl_in, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'access-list6', acl_in, 'rule', '10', 'source', 'any'])
+ self.session.set(['policy', 'access-list6', acl_out, 'rule', '20', 'action', 'deny'])
+ self.session.set(['policy', 'access-list6', acl_out, 'rule', '20', 'source', 'any'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'prefix', '2001:db8::/32'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'action', 'deny'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'prefix', '2001:db8::/32'])
+ self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ self.session.delete(['policy', 'access-list6', acl_in])
+ self.session.delete(['policy', 'access-list6', acl_out])
+ self.session.delete(['policy', 'prefix-list6', prefix_list_in])
+ self.session.delete(['policy', 'prefix-list6', prefix_list_out])
+ self.session.delete(['policy', 'route-map', route_map])
+
+ self.session.commit()
+ del self.session
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_ripng(self):
+ metric = '8'
+ interfaces = Section.interfaces('ethernet')
+ aggregates = ['2001:db8:1000::/48', '2001:db8:2000::/48', '2001:db8:3000::/48']
+ networks = ['2001:db8:1000::/64', '2001:db8:1001::/64', '2001:db8:2000::/64', '2001:db8:2001::/64']
+ redistribute = ['bgp', 'connected', 'kernel', 'ospfv3', 'static']
+ timer_garbage = '888'
+ timer_timeout = '1000'
+ timer_update = '90'
+
+ self.session.set(base_path + ['default-information', 'originate'])
+ self.session.set(base_path + ['default-metric', metric])
+ self.session.set(base_path + ['distribute-list', 'access-list', 'in', acl_in])
+ self.session.set(base_path + ['distribute-list', 'access-list', 'out', acl_out])
+ self.session.set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in])
+ self.session.set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out])
+ self.session.set(base_path + ['passive-interface', 'default'])
+ self.session.set(base_path + ['timers', 'garbage-collection', timer_garbage])
+ self.session.set(base_path + ['timers', 'timeout', timer_timeout])
+ self.session.set(base_path + ['timers', 'update', timer_update])
+ for aggregate in aggregates:
+ self.session.set(base_path + ['aggregate-address', aggregate])
+
+ for interface in interfaces:
+ self.session.set(base_path + ['interface', interface])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out])
+ for network in networks:
+ self.session.set(base_path + ['network', network])
+ self.session.set(base_path + ['route', network])
+ for proto in redistribute:
+ self.session.set(base_path + ['redistribute', proto, 'metric', metric])
+ self.session.set(base_path + ['redistribute', proto, 'route-map', route_map])
+
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRRconfig()
+ self.assertIn(f'router ripng', frrconfig)
+ self.assertIn(f' default-information originate', frrconfig)
+ self.assertIn(f' default-metric {metric}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list {acl_in} in', frrconfig)
+ self.assertIn(f' ipv6 distribute-list {acl_out} out', frrconfig)
+ self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in', frrconfig)
+ self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out', frrconfig)
+ self.assertIn(f' passive-interface default', frrconfig)
+ self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig)
+ for aggregate in aggregates:
+ self.assertIn(f' aggregate-address {aggregate}', frrconfig)
+ for interface in interfaces:
+ self.assertIn(f' network {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list {acl_in} in {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list {acl_out} out {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out {interface}', frrconfig)
+ for network in networks:
+ self.assertIn(f' network {network}', frrconfig)
+ self.assertIn(f' route {network}', frrconfig)
+ for proto in redistribute:
+ if proto == 'ospfv3':
+ proto = 'ospf6'
+ self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_rpki.py b/smoketest/scripts/cli/test_protocols_rpki.py
new file mode 100755
index 000000000..bec4ef76f
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_rpki.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+base_path = ['protocols', 'rpki']
+PROCESS_NAME = 'bgpd'
+
+rpki_known_hosts = '/config/auth/known_hosts'
+rpki_ssh_key = '/config/auth/id_rsa_rpki'
+rpki_ssh_pub = f'{rpki_ssh_key}.pub'
+
+def getFRRRPKIconfig():
+ return cmd(f'vtysh -c "show run" | sed -n "/rpki/,/^!/p"')
+
+class TestProtocolsRPKI(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ self.session.commit()
+ del self.session
+
+ # Nothing RPKI specific should be left over in the config
+ #
+ # Disabled until T3266 is resolved
+ # frrconfig = getFRRRPKIconfig()
+ # self.assertNotIn('rpki', frrconfig)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_rpki(self):
+ polling = '7200'
+ cache = {
+ '192.0.2.1' : {
+ 'port' : '8080',
+ 'preference' : '1'
+ },
+ '192.0.2.2' : {
+ 'port' : '9090',
+ 'preference' : '2'
+ },
+ '2001:db8::1' : {
+ 'port' : '1234',
+ 'preference' : '3'
+ },
+ '2001:db8::2' : {
+ 'port' : '5678',
+ 'preference' : '4'
+ },
+ }
+
+ self.session.set(base_path + ['polling-period', polling])
+ for peer, peer_config in cache.items():
+ self.session.set(base_path + ['cache', peer, 'port', peer_config['port']])
+ self.session.set(base_path + ['cache', peer, 'preference', peer_config['preference']])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR configuration
+ frrconfig = getFRRRPKIconfig()
+ self.assertIn(f'rpki polling_period {polling}', frrconfig)
+
+ for peer, peer_config in cache.items():
+ port = peer_config['port']
+ preference = peer_config['preference']
+ self.assertIn(f'rpki cache {peer} {port} preference {preference}', frrconfig)
+
+ def test_rpki_ssh(self):
+ polling = '7200'
+ cache = {
+ '192.0.2.3' : {
+ 'port' : '1234',
+ 'username' : 'foo',
+ 'preference' : '10'
+ },
+ '192.0.2.4' : {
+ 'port' : '5678',
+ 'username' : 'bar',
+ 'preference' : '20'
+ },
+ }
+
+ self.session.set(base_path + ['polling-period', polling])
+
+ for peer, peer_config in cache.items():
+ self.session.set(base_path + ['cache', peer, 'port', peer_config['port']])
+ self.session.set(base_path + ['cache', peer, 'preference', peer_config['preference']])
+ self.session.set(base_path + ['cache', peer, 'ssh', 'username', peer_config['username']])
+ self.session.set(base_path + ['cache', peer, 'ssh', 'public-key-file', rpki_ssh_pub])
+ self.session.set(base_path + ['cache', peer, 'ssh', 'private-key-file', rpki_ssh_key])
+ self.session.set(base_path + ['cache', peer, 'ssh', 'known-hosts-file', rpki_known_hosts])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR configuration
+ frrconfig = getFRRRPKIconfig()
+ self.assertIn(f'rpki polling_period {polling}', frrconfig)
+
+ for peer, peer_config in cache.items():
+ port = peer_config['port']
+ preference = peer_config['preference']
+ username = peer_config['username']
+ self.assertIn(f'rpki cache {peer} {port} {username} {rpki_ssh_key} {rpki_known_hosts} preference {preference}', frrconfig)
+
+
+ def test_rpki_verify_preference(self):
+ cache = {
+ '192.0.2.1' : {
+ 'port' : '8080',
+ 'preference' : '1'
+ },
+ '192.0.2.2' : {
+ 'port' : '9090',
+ 'preference' : '1'
+ },
+ }
+
+ for peer, peer_config in cache.items():
+ self.session.set(base_path + ['cache', peer, 'port', peer_config['port']])
+ self.session.set(base_path + ['cache', peer, 'preference', peer_config['preference']])
+
+ # check validate() - preferences must be unique
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+
+
+if __name__ == '__main__':
+ # Create OpenSSH keypair used in RPKI tests
+ if not os.path.isfile(rpki_ssh_key):
+ cmd(f'ssh-keygen -t rsa -f {rpki_ssh_key} -N ""')
+
+ if not os.path.isfile(rpki_known_hosts):
+ cmd(f'touch {rpki_known_hosts}')
+
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py
new file mode 100755
index 000000000..cf591f060
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_static.py
@@ -0,0 +1,385 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 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
+# 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 os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.template import is_ipv6
+from vyos.util import cmd
+
+base_path = ['protocols', 'static']
+vrf_path = ['protocols', 'vrf']
+
+def getFRRCconfig(vrf=None):
+ if vrf:
+ return cmd(f'vtysh -c "show run" | sed -n "/^vrf {vrf}/,/^!/p"')
+ else:
+ return cmd(f'vtysh -c "show run" | sed -n "/^ip route/,/^!/p"')
+
+routes = {
+ '10.0.0.0/8' : {
+ 'next_hop' : {
+ '192.0.2.100' : { 'distance' : '100' },
+ '192.0.2.110' : { 'distance' : '110', 'interface' : 'eth0' },
+ '192.0.2.120' : { 'distance' : '120', 'disable' : '' },
+ },
+ 'interface' : {
+ 'eth0' : { 'distance' : '130' },
+ 'eth1' : { 'distance' : '140' },
+ },
+ 'blackhole' : { 'distance' : '250', 'tag' : '500' },
+ },
+ '172.16.0.0/12' : {
+ 'interface' : {
+ 'eth0' : { 'distance' : '50', 'vrf' : 'black' },
+ 'eth1' : { 'distance' : '60', 'vrf' : 'black' },
+ },
+ 'blackhole' : { 'distance' : '90' },
+ },
+ '192.0.2.0/24' : {
+ 'interface' : {
+ 'eth0' : { 'distance' : '50', 'vrf' : 'black' },
+ 'eth1' : { 'disable' : '' },
+ },
+ 'blackhole' : { 'distance' : '90' },
+ },
+ '100.64.0.0/10' : {
+ 'blackhole' : { },
+ },
+ '2001:db8:100::/40' : {
+ 'next_hop' : {
+ '2001:db8::1' : { 'distance' : '10' },
+ '2001:db8::2' : { 'distance' : '20', 'interface' : 'eth0' },
+ '2001:db8::3' : { 'distance' : '30', 'disable' : '' },
+ },
+ 'interface' : {
+ 'eth0' : { 'distance' : '40', 'vrf' : 'black' },
+ 'eth1' : { 'distance' : '50', 'disable' : '' },
+ },
+ 'blackhole' : { 'distance' : '250', 'tag' : '500' },
+ },
+ '2001:db8:200::/40' : {
+ 'interface' : {
+ 'eth0' : { 'distance' : '40' },
+ 'eth1' : { 'distance' : '50', 'disable' : '' },
+ },
+ 'blackhole' : { 'distance' : '250', 'tag' : '500' },
+ },
+ '2001:db8::/32' : {
+ 'blackhole' : { 'distance' : '200', 'tag' : '600' },
+ },
+}
+
+vrfs = ['red', 'green', 'blue']
+tables = ['80', '81', '82']
+
+class StaticRouteTest(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ def tearDown(self):
+ for route, route_config in routes.items():
+ route_type = 'route'
+ if is_ipv6(route):
+ route_type = 'route6'
+ self.session.delete(base_path + [route_type, route])
+
+ for vrf in vrfs:
+ self.session.delete(vrf_path + [vrf])
+
+ for table in tables:
+ self.session.delete(base_path + ['table', table])
+
+ self.session.commit()
+ del self.session
+
+ def test_protocols_static(self):
+ for route, route_config in routes.items():
+ route_type = 'route'
+ if is_ipv6(route):
+ route_type = 'route6'
+ base = base_path + [route_type, route]
+ if 'next_hop' in route_config:
+ for next_hop, next_hop_config in route_config['next_hop'].items():
+ self.session.set(base + ['next-hop', next_hop])
+ if 'disable' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'disable'])
+ if 'distance' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
+ if 'interface' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
+ if 'vrf' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
+
+
+ if 'interface' in route_config:
+ for interface, interface_config in route_config['interface'].items():
+ self.session.set(base + ['interface', interface])
+ if 'disable' in interface_config:
+ self.session.set(base + ['interface', interface, 'disable'])
+ if 'distance' in interface_config:
+ self.session.set(base + ['interface', interface, 'distance', interface_config['distance']])
+ if 'vrf' in interface_config:
+ self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']])
+
+ if 'blackhole' in route_config:
+ self.session.set(base + ['blackhole'])
+ if 'distance' in route_config['blackhole']:
+ self.session.set(base + ['blackhole', 'distance', route_config['blackhole']['distance']])
+ if 'tag' in route_config['blackhole']:
+ self.session.set(base + ['blackhole', 'tag', route_config['blackhole']['tag']])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR bgpd configuration
+ frrconfig = getFRRCconfig()
+
+ # Verify routes
+ for route, route_config in routes.items():
+ ip_ipv6 = 'ip'
+ if is_ipv6(route):
+ ip_ipv6 = 'ipv6'
+
+ if 'next_hop' in route_config:
+ for next_hop, next_hop_config in route_config['next_hop'].items():
+ tmp = f'{ip_ipv6} route {route} {next_hop}'
+ if 'interface' in next_hop_config:
+ tmp += ' ' + next_hop_config['interface']
+ if 'distance' in next_hop_config:
+ tmp += ' ' + next_hop_config['distance']
+ if 'vrf' in next_hop_config:
+ tmp += ' nexthop-vrf ' + next_hop_config['vrf']
+
+ if 'disable' in next_hop_config:
+ self.assertNotIn(tmp, frrconfig)
+ else:
+ self.assertIn(tmp, frrconfig)
+
+ if 'interface' in route_config:
+ for interface, interface_config in route_config['interface'].items():
+ tmp = f'{ip_ipv6} route {route} {interface}'
+ if 'interface' in interface_config:
+ tmp += ' ' + interface_config['interface']
+ if 'distance' in interface_config:
+ tmp += ' ' + interface_config['distance']
+ if 'vrf' in interface_config:
+ tmp += ' nexthop-vrf ' + interface_config['vrf']
+
+ if 'disable' in interface_config:
+ self.assertNotIn(tmp, frrconfig)
+ else:
+ self.assertIn(tmp, frrconfig)
+
+ if 'blackhole' in route_config:
+ tmp = f'{ip_ipv6} route {route} blackhole'
+ if 'tag' in route_config['blackhole']:
+ tmp += ' tag ' + route_config['blackhole']['tag']
+ if 'distance' in route_config['blackhole']:
+ tmp += ' ' + route_config['blackhole']['distance']
+
+ self.assertIn(tmp, frrconfig)
+
+ def test_protocols_static_table(self):
+ for table in tables:
+ for route, route_config in routes.items():
+ route_type = 'route'
+ if is_ipv6(route):
+ route_type = 'route6'
+ base = base_path + ['table', table, route_type, route]
+
+ if 'next_hop' in route_config:
+ for next_hop, next_hop_config in route_config['next_hop'].items():
+ self.session.set(base + ['next-hop', next_hop])
+ if 'disable' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'disable'])
+ if 'distance' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
+ if 'interface' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
+ if 'vrf' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
+
+
+ if 'interface' in route_config:
+ for interface, interface_config in route_config['interface'].items():
+ self.session.set(base + ['interface', interface])
+ if 'disable' in interface_config:
+ self.session.set(base + ['interface', interface, 'disable'])
+ if 'distance' in interface_config:
+ self.session.set(base + ['interface', interface, 'distance', interface_config['distance']])
+ if 'vrf' in interface_config:
+ self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']])
+
+ if 'blackhole' in route_config:
+ self.session.set(base + ['blackhole'])
+ if 'distance' in route_config['blackhole']:
+ self.session.set(base + ['blackhole', 'distance', route_config['blackhole']['distance']])
+ if 'tag' in route_config['blackhole']:
+ self.session.set(base + ['blackhole', 'tag', route_config['blackhole']['tag']])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR bgpd configuration
+ frrconfig = getFRRCconfig()
+
+ for table in tables:
+ # Verify routes
+ for route, route_config in routes.items():
+ ip_ipv6 = 'ip'
+ if is_ipv6(route):
+ ip_ipv6 = 'ipv6'
+
+ if 'next_hop' in route_config:
+ for next_hop, next_hop_config in route_config['next_hop'].items():
+ tmp = f'{ip_ipv6} route {route} {next_hop}'
+ if 'interface' in next_hop_config:
+ tmp += ' ' + next_hop_config['interface']
+ if 'distance' in next_hop_config:
+ tmp += ' ' + next_hop_config['distance']
+ if 'vrf' in next_hop_config:
+ tmp += ' nexthop-vrf ' + next_hop_config['vrf']
+
+ tmp += ' table ' + table
+ if 'disable' in next_hop_config:
+ self.assertNotIn(tmp, frrconfig)
+ else:
+ self.assertIn(tmp, frrconfig)
+
+ if 'interface' in route_config:
+ for interface, interface_config in route_config['interface'].items():
+ tmp = f'{ip_ipv6} route {route} {interface}'
+ if 'interface' in interface_config:
+ tmp += ' ' + interface_config['interface']
+ if 'distance' in interface_config:
+ tmp += ' ' + interface_config['distance']
+ if 'vrf' in interface_config:
+ tmp += ' nexthop-vrf ' + interface_config['vrf']
+
+ tmp += ' table ' + table
+ if 'disable' in interface_config:
+ self.assertNotIn(tmp, frrconfig)
+ else:
+ self.assertIn(tmp, frrconfig)
+
+ if 'blackhole' in route_config:
+ tmp = f'{ip_ipv6} route {route} blackhole'
+ if 'tag' in route_config['blackhole']:
+ tmp += ' tag ' + route_config['blackhole']['tag']
+ if 'distance' in route_config['blackhole']:
+ tmp += ' ' + route_config['blackhole']['distance']
+
+ tmp += ' table ' + table
+ self.assertIn(tmp, frrconfig)
+
+
+ def test_protocols_vrf_static(self):
+ for vrf in vrfs:
+ for route, route_config in routes.items():
+ route_type = 'route'
+ if is_ipv6(route):
+ route_type = 'route6'
+ base = vrf_path + [vrf, 'static', route_type, route]
+
+ if 'next_hop' in route_config:
+ for next_hop, next_hop_config in route_config['next_hop'].items():
+ self.session.set(base + ['next-hop', next_hop])
+ if 'disable' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'disable'])
+ if 'distance' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'distance', next_hop_config['distance']])
+ if 'interface' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
+ if 'vrf' in next_hop_config:
+ self.session.set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
+
+
+ if 'interface' in route_config:
+ for interface, interface_config in route_config['interface'].items():
+ self.session.set(base + ['interface', interface])
+ if 'disable' in interface_config:
+ self.session.set(base + ['interface', interface, 'disable'])
+ if 'distance' in interface_config:
+ self.session.set(base + ['interface', interface, 'distance', interface_config['distance']])
+ if 'vrf' in interface_config:
+ self.session.set(base + ['interface', interface, 'vrf', interface_config['vrf']])
+
+ if 'blackhole' in route_config:
+ self.session.set(base + ['blackhole'])
+ if 'distance' in route_config['blackhole']:
+ self.session.set(base + ['blackhole', 'distance', route_config['blackhole']['distance']])
+ if 'tag' in route_config['blackhole']:
+ self.session.set(base + ['blackhole', 'tag', route_config['blackhole']['tag']])
+
+ # commit changes
+ self.session.commit()
+
+ for vrf in vrfs:
+ # Verify FRR bgpd configuration
+ frrconfig = getFRRCconfig(vrf)
+ self.assertIn(f'vrf {vrf}', frrconfig)
+
+ # Verify routes
+ for route, route_config in routes.items():
+ ip_ipv6 = 'ip'
+ if is_ipv6(route):
+ ip_ipv6 = 'ipv6'
+
+ if 'next_hop' in route_config:
+ for next_hop, next_hop_config in route_config['next_hop'].items():
+ tmp = f'{ip_ipv6} route {route} {next_hop}'
+ if 'interface' in next_hop_config:
+ tmp += ' ' + next_hop_config['interface']
+ if 'distance' in next_hop_config:
+ tmp += ' ' + next_hop_config['distance']
+ if 'vrf' in next_hop_config:
+ tmp += ' nexthop-vrf ' + next_hop_config['vrf']
+
+ if 'disable' in next_hop_config:
+ self.assertNotIn(tmp, frrconfig)
+ else:
+ self.assertIn(tmp, frrconfig)
+
+ if 'interface' in route_config:
+ for interface, interface_config in route_config['interface'].items():
+ tmp = f'{ip_ipv6} route {route} {interface}'
+ if 'interface' in interface_config:
+ tmp += ' ' + interface_config['interface']
+ if 'distance' in interface_config:
+ tmp += ' ' + interface_config['distance']
+ if 'vrf' in interface_config:
+ tmp += ' nexthop-vrf ' + interface_config['vrf']
+
+ if 'disable' in interface_config:
+ self.assertNotIn(tmp, frrconfig)
+ else:
+ self.assertIn(tmp, frrconfig)
+
+ if 'blackhole' in route_config:
+ tmp = f'{ip_ipv6} route {route} blackhole'
+ if 'tag' in route_config['blackhole']:
+ tmp += ' tag ' + route_config['blackhole']['tag']
+ if 'distance' in route_config['blackhole']:
+ tmp += ' ' + route_config['blackhole']['distance']
+
+ self.assertIn(tmp, frrconfig)
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_service_bcast-relay.py b/smoketest/scripts/cli/test_service_bcast-relay.py
index c28509714..00d7750aa 100755
--- a/smoketest/scripts/cli/test_service_bcast-relay.py
+++ b/smoketest/scripts/cli/test_service_bcast-relay.py
@@ -30,7 +30,6 @@ class TestServiceBroadcastRelay(unittest.TestCase):
self.session = ConfigSession(os.getpid())
self.session.set(['interfaces', 'dummy', 'dum1001', 'address', self._address1])
self.session.set(['interfaces', 'dummy', 'dum1002', 'address', self._address2])
- self.session.commit()
def tearDown(self):
self.session.delete(['interfaces', 'dummy', 'dum1001'])
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index 5270e758a..8e977d407 100755
--- a/smoketest/scripts/cli/test_vrf.py
+++ b/smoketest/scripts/cli/test_vrf.py
@@ -16,19 +16,44 @@
import re
import os
+import json
import unittest
+
from netifaces import interfaces
from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Interface
+from vyos.ifconfig import Section
+from vyos.template import is_ipv6
+from vyos.util import cmd
from vyos.util import read_file
from vyos.validate import is_intf_addr_assigned
-from vyos.ifconfig import Interface
base_path = ['vrf']
vrfs = ['red', 'green', 'blue', 'foo-bar', 'baz_foo']
+def get_vrf_ipv4_routes(vrf):
+ return json.loads(cmd(f'ip -4 -j route show vrf {vrf}'))
+
+def get_vrf_ipv6_routes(vrf):
+ return json.loads(cmd(f'ip -6 -j route show vrf {vrf}'))
+
class VRFTest(unittest.TestCase):
+ _interfaces = []
+
+ @classmethod
+ def setUpClass(cls):
+ # we need to filter out VLAN interfaces identified by a dot (.)
+ # in their name - just in case!
+ if 'TEST_ETH' in os.environ:
+ tmp = os.environ['TEST_ETH'].split()
+ cls._interfaces = tmp
+ else:
+ for tmp in Section.interfaces('ethernet'):
+ if not '.' in tmp:
+ cls._interfaces.append(tmp)
+
def setUp(self):
self.session = ConfigSession(os.getpid())
@@ -120,5 +145,26 @@ class VRFTest(unittest.TestCase):
with self.assertRaises(ConfigSessionError):
self.session.commit()
+ def test_vrf_assign_interface(self):
+ vrf = vrfs[0]
+ table = '5000'
+ self.session.set(['vrf', 'name', vrf, 'table', table])
+
+ for interface in self._interfaces:
+ section = Section.section(interface)
+ self.session.set(['interfaces', section, interface, 'vrf', vrf])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify & cleanup
+ for interface in self._interfaces:
+ # os.readlink resolves to: '../../../../../virtual/net/foovrf'
+ tmp = os.readlink(f'/sys/class/net/{interface}/master').split('/')[-1]
+ self.assertEqual(tmp, vrf)
+ # cleanup
+ section = Section.section(interface)
+ self.session.delete(['interfaces', section, interface, 'vrf'])
+
if __name__ == '__main__':
- unittest.main(verbosity=2, failfast=True)
+ unittest.main(verbosity=2)