summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli/test_vrf.py
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest/scripts/cli/test_vrf.py')
-rwxr-xr-xsmoketest/scripts/cli/test_vrf.py121
1 files changed, 119 insertions, 2 deletions
diff --git a/smoketest/scripts/cli/test_vrf.py b/smoketest/scripts/cli/test_vrf.py
index 5270e758a..856baa070 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,97 @@ 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'])
+
+ def test_vrf_static_routes(self):
+ routes = {
+ '10.0.0.0/8' : {
+ 'next_hop' : '192.0.2.2',
+ 'distance' : '200',
+ 'next_hop_vrf' : 'default',
+ },
+ '172.16.0.0/12' : {
+ 'next_hop' : '192.0.2.3',
+ 'next_hop_vrf' : 'default',
+ },
+ '192.168.0.0/16' : {
+ 'next_hop' : '192.0.2.3',
+ },
+ '2001:db8:1000::/48' : {
+ 'next_hop' : '2001:db8::2',
+ },
+ }
+
+ table = '2000'
+ for vrf in vrfs:
+ base = base_path + ['name', vrf]
+ self.session.set(base + ['table', str(table)])
+
+ # required interface for leaking to default table
+ self.session.set(['interfaces', 'ethernet', 'eth0', 'address', '192.0.2.1/24'])
+
+ # we also need an interface in "UP" state to install routes
+ self.session.set(['interfaces', 'dummy', f'dum{table}', 'vrf', vrf])
+ self.session.set(['interfaces', 'dummy', f'dum{table}', 'address', '192.0.2.1/24'])
+ self.session.set(['interfaces', 'dummy', f'dum{table}', 'address', '2001:db8::1/64'])
+ table = str(int(table) + 1)
+
+ proto_base = ['protocols', 'vrf', vrf, 'static']
+ for route, route_config in routes.items():
+ route_type = 'route'
+ if is_ipv6(route):
+ route_type = 'route6'
+ self.session.set(proto_base + [route_type, route, 'next-hop', route_config['next_hop']])
+ if 'distance' in route_config:
+ self.session.set(proto_base + [route_type, route, 'next-hop', route_config['next_hop'], 'distance', route_config['distance']])
+ if 'next_hop_vrf' in route_config:
+ self.session.set(proto_base + [route_type, route, 'next-hop', route_config['next_hop'], 'next-hop-vrf', route_config['next_hop_vrf']])
+
+ # commit changes
+ self.session.commit()
+
+ # Verify routes
+ table = '2000'
+ for vrf in vrfs:
+ for route, route_config in routes.items():
+ if is_ipv6(route):
+ tmp = get_vrf_ipv6_routes(vrf)
+ else:
+ tmp = get_vrf_ipv4_routes(vrf)
+
+ found = False
+ for result in tmp:
+ if 'dst' in result and result['dst'] == route:
+ if 'gateway' in result and result['gateway'] == route_config['next_hop']:
+ found = True
+
+ self.assertTrue(found)
+
+ # Cleanup
+ self.session.delete(['protocols', 'vrf', vrf])
+ self.session.delete(['interfaces', 'dummy', f'dum{table}'])
+ self.session.delete(['interfaces', 'ethernet', 'eth0', 'address', '192.0.2.1/24'])
+
+ table = str(int(table) + 1)
+
if __name__ == '__main__':
- unittest.main(verbosity=2, failfast=True)
+ unittest.main(verbosity=2)