diff options
Diffstat (limited to 'smoketest/scripts/cli/test_protocols_bgp.py')
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_bgp.py | 198 |
1 files changed, 194 insertions, 4 deletions
diff --git a/smoketest/scripts/cli/test_protocols_bgp.py b/smoketest/scripts/cli/test_protocols_bgp.py index 967958cab..08a6e1696 100755 --- a/smoketest/scripts/cli/test_protocols_bgp.py +++ b/smoketest/scripts/cli/test_protocols_bgp.py @@ -16,12 +16,15 @@ import unittest +from time import sleep + from base_vyostest_shim import VyOSUnitTestSHIM from vyos.ifconfig import Section from vyos.configsession import ConfigSessionError from vyos.template import is_ipv6 from vyos.utils.process import process_named_running +from vyos.utils.process import cmd PROCESS_NAME = 'bgpd' ASN = '64512' @@ -174,9 +177,16 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): def setUpClass(cls): super(TestProtocolsBGP, cls).setUpClass() + # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same + cls.daemon_pid = process_named_running(PROCESS_NAME) + # ensure we can also run this test on a live system - so lets clean # out the current configuration :) cls.cli_delete(cls, base_path) + cls.cli_delete(cls, ['policy', 'route-map']) + cls.cli_delete(cls, ['policy', 'prefix-list']) + cls.cli_delete(cls, ['policy', 'prefix-list6']) + cls.cli_delete(cls, ['vrf']) cls.cli_set(cls, ['policy', 'route-map', route_map_in, 'rule', '10', 'action', 'permit']) cls.cli_set(cls, ['policy', 'route-map', route_map_out, 'rule', '10', 'action', 'permit']) @@ -192,18 +202,23 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): @classmethod def tearDownClass(cls): - cls.cli_delete(cls, ['policy']) + cls.cli_delete(cls, ['policy', 'route-map']) + cls.cli_delete(cls, ['policy', 'prefix-list']) + cls.cli_delete(cls, ['policy', 'prefix-list6']) def setUp(self): self.cli_set(base_path + ['system-as', ASN]) def tearDown(self): + # cleanup any possible VRF mess self.cli_delete(['vrf']) + # always destrox the entire bgpd configuration to make the processes + # life as hard as possible self.cli_delete(base_path) self.cli_commit() - # Check for running process - self.assertTrue(process_named_running(PROCESS_NAME)) + # check process health and continuity + self.assertEqual(self.daemon_pid, process_named_running(PROCESS_NAME)) def create_bgp_instances_for_import_test(self): table = '1000' @@ -304,8 +319,11 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): tcp_keepalive_interval = '77' tcp_keepalive_probes = '22' - self.cli_set(base_path + ['parameters', 'router-id', router_id]) + self.cli_set(base_path + ['parameters', 'allow-martian-nexthop']) + self.cli_set(base_path + ['parameters', 'no-hard-administrative-reset']) self.cli_set(base_path + ['parameters', 'log-neighbor-changes']) + self.cli_set(base_path + ['parameters', 'labeled-unicast', 'explicit-null']) + self.cli_set(base_path + ['parameters', 'router-id', router_id]) # System AS number MUST be defined - as this is set in setUp() we remove # this once for testing of the proper error @@ -340,6 +358,8 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): # AFI maximum path support self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ebgp', max_path_v4]) self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'maximum-paths', 'ibgp', max_path_v4ibgp]) + self.cli_set(base_path + ['address-family', 'ipv4-labeled-unicast', 'maximum-paths', 'ebgp', max_path_v4]) + self.cli_set(base_path + ['address-family', 'ipv4-labeled-unicast', 'maximum-paths', 'ibgp', max_path_v4ibgp]) self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'maximum-paths', 'ebgp', max_path_v6]) self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'maximum-paths', 'ibgp', max_path_v6ibgp]) @@ -350,12 +370,15 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): frrconfig = self.getFRRconfig(f'router bgp {ASN}') self.assertIn(f'router bgp {ASN}', frrconfig) self.assertIn(f' bgp router-id {router_id}', frrconfig) + self.assertIn(f' bgp allow-martian-nexthop', frrconfig) self.assertIn(f' bgp log-neighbor-changes', frrconfig) self.assertIn(f' bgp default local-preference {local_pref}', frrconfig) self.assertIn(f' bgp conditional-advertisement timer {cond_adv_timer}', frrconfig) self.assertIn(f' bgp fast-convergence', frrconfig) self.assertIn(f' bgp graceful-restart stalepath-time {stalepath_time}', frrconfig) self.assertIn(f' bgp graceful-shutdown', frrconfig) + self.assertIn(f' no bgp hard-administrative-reset', frrconfig) + self.assertIn(f' bgp labeled-unicast explicit-null', frrconfig) self.assertIn(f' bgp bestpath as-path multipath-relax', frrconfig) self.assertIn(f' bgp bestpath bandwidth default-weight-for-missing', frrconfig) self.assertIn(f' bgp bestpath compare-routerid', frrconfig) @@ -373,6 +396,10 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' maximum-paths {max_path_v4}', afiv4_config) self.assertIn(f' maximum-paths ibgp {max_path_v4ibgp}', afiv4_config) + afiv4_config = self.getFRRconfig(' address-family ipv4 labeled-unicast') + self.assertIn(f' maximum-paths {max_path_v4}', afiv4_config) + self.assertIn(f' maximum-paths ibgp {max_path_v4ibgp}', afiv4_config) + afiv6_config = self.getFRRconfig(' address-family ipv6 unicast') self.assertIn(f' maximum-paths {max_path_v6}', afiv6_config) self.assertIn(f' maximum-paths ibgp {max_path_v6ibgp}', afiv6_config) @@ -722,15 +749,25 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): def test_bgp_07_l2vpn_evpn(self): vnis = ['10010', '10020', '10030'] neighbors = ['192.0.2.10', '192.0.2.20', '192.0.2.30'] + evi_limit = '1000' + route_targets = ['1.1.1.1:100', '1.1.1.1:200', '1.1.1.1:300'] self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-all-vni']) self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-default-gw']) self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'advertise-svi-ip']) self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'flooding', 'disable']) + self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'default-originate', 'ipv4']) + self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'default-originate', 'ipv6']) + self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'disable-ead-evi-rx']) + self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'disable-ead-evi-tx']) for vni in vnis: self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-default-gw']) self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'vni', vni, 'advertise-svi-ip']) + self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'ead-es-frag', 'evi-limit', evi_limit]) + for route_target in route_targets: + self.cli_set(base_path + ['address-family', 'l2vpn-evpn', 'ead-es-route-target', 'export', route_target]) + # commit changes self.cli_commit() @@ -741,12 +778,20 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' advertise-all-vni', frrconfig) self.assertIn(f' advertise-default-gw', frrconfig) self.assertIn(f' advertise-svi-ip', frrconfig) + self.assertIn(f' default-originate ipv4', frrconfig) + self.assertIn(f' default-originate ipv6', frrconfig) + self.assertIn(f' disable-ead-evi-rx', frrconfig) + self.assertIn(f' disable-ead-evi-tx', frrconfig) self.assertIn(f' flooding disable', frrconfig) for vni in vnis: vniconfig = self.getFRRconfig(f' vni {vni}') self.assertIn(f'vni {vni}', vniconfig) self.assertIn(f' advertise-default-gw', vniconfig) self.assertIn(f' advertise-svi-ip', vniconfig) + self.assertIn(f' ead-es-frag evi-limit {evi_limit}', frrconfig) + for route_target in route_targets: + self.assertIn(f' ead-es-route-target export {route_target}', frrconfig) + def test_bgp_09_distance_and_flowspec(self): distance_external = '25' @@ -1097,5 +1142,150 @@ class TestProtocolsBGP(VyOSUnitTestSHIM.TestCase): self.assertIn(f' mpls bgp forwarding', frrconfig) self.cli_delete(['interfaces', 'ethernet', interface, 'vrf']) + def test_bgp_24_srv6_sid(self): + locator_name = 'VyOS_foo' + sid = 'auto' + nexthop_ipv4 = '192.0.0.1' + nexthop_ipv6 = '2001:db8:100:200::2' + + self.cli_set(base_path + ['srv6', 'locator', locator_name]) + self.cli_set(base_path + ['sid', 'vpn', 'per-vrf', 'export', sid]) + self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'sid', 'vpn', 'export', sid]) + # verify() - SID per VRF and SID per address-family are mutually exclusive! + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_delete(base_path + ['address-family', 'ipv4-unicast', 'sid']) + self.cli_commit() + + frrconfig = self.getFRRconfig(f'router bgp {ASN}') + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' segment-routing srv6', frrconfig) + self.assertIn(f' locator {locator_name}', frrconfig) + self.assertIn(f' sid vpn per-vrf export {sid}', frrconfig) + + # Now test AFI SID + self.cli_delete(base_path + ['sid']) + self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'sid', 'vpn', 'export', sid]) + self.cli_set(base_path + ['address-family', 'ipv4-unicast', 'nexthop', 'vpn', 'export', nexthop_ipv4]) + self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'sid', 'vpn', 'export', sid]) + self.cli_set(base_path + ['address-family', 'ipv6-unicast', 'nexthop', 'vpn', 'export', nexthop_ipv6]) + + self.cli_commit() + + frrconfig = self.getFRRconfig(f'router bgp {ASN}') + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' segment-routing srv6', frrconfig) + self.assertIn(f' locator {locator_name}', frrconfig) + + afiv4_config = self.getFRRconfig(' address-family ipv4 unicast') + self.assertIn(f' sid vpn export {sid}', afiv4_config) + self.assertIn(f' nexthop vpn export {nexthop_ipv4}', afiv4_config) + afiv6_config = self.getFRRconfig(' address-family ipv6 unicast') + self.assertIn(f' sid vpn export {sid}', afiv6_config) + self.assertIn(f' nexthop vpn export {nexthop_ipv6}', afiv4_config) + + def test_bgp_25_ipv4_labeled_unicast_peer_group(self): + pg_ipv4 = 'foo4' + ipv4_max_prefix = '20' + ipv4_prefix = '192.0.2.0/24' + + self.cli_set(base_path + ['listen', 'range', ipv4_prefix, 'peer-group', pg_ipv4]) + self.cli_set(base_path + ['parameters', 'labeled-unicast', 'ipv4-explicit-null']) + self.cli_set(base_path + ['peer-group', pg_ipv4, 'address-family', 'ipv4-labeled-unicast', 'maximum-prefix', ipv4_max_prefix]) + self.cli_set(base_path + ['peer-group', pg_ipv4, 'remote-as', 'external']) + + self.cli_commit() + + frrconfig = self.getFRRconfig(f'router bgp {ASN}') + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' neighbor {pg_ipv4} peer-group', frrconfig) + self.assertIn(f' neighbor {pg_ipv4} remote-as external', frrconfig) + self.assertIn(f' bgp listen range {ipv4_prefix} peer-group {pg_ipv4}', frrconfig) + self.assertIn(f' bgp labeled-unicast ipv4-explicit-null', frrconfig) + + afiv4_config = self.getFRRconfig(' address-family ipv4 labeled-unicast') + self.assertIn(f' neighbor {pg_ipv4} activate', afiv4_config) + self.assertIn(f' neighbor {pg_ipv4} maximum-prefix {ipv4_max_prefix}', afiv4_config) + + def test_bgp_26_ipv6_labeled_unicast_peer_group(self): + pg_ipv6 = 'foo6' + ipv6_max_prefix = '200' + ipv6_prefix = '2001:db8:1000::/64' + + self.cli_set(base_path + ['listen', 'range', ipv6_prefix, 'peer-group', pg_ipv6]) + self.cli_set(base_path + ['parameters', 'labeled-unicast', 'ipv6-explicit-null']) + + self.cli_set(base_path + ['peer-group', pg_ipv6, 'address-family', 'ipv6-labeled-unicast', 'maximum-prefix', ipv6_max_prefix]) + self.cli_set(base_path + ['peer-group', pg_ipv6, 'remote-as', 'external']) + + self.cli_commit() + + frrconfig = self.getFRRconfig(f'router bgp {ASN}') + self.assertIn(f'router bgp {ASN}', frrconfig) + self.assertIn(f' neighbor {pg_ipv6} peer-group', frrconfig) + self.assertIn(f' neighbor {pg_ipv6} remote-as external', frrconfig) + self.assertIn(f' bgp listen range {ipv6_prefix} peer-group {pg_ipv6}', frrconfig) + self.assertIn(f' bgp labeled-unicast ipv6-explicit-null', frrconfig) + + afiv6_config = self.getFRRconfig(' address-family ipv6 labeled-unicast') + self.assertIn(f' neighbor {pg_ipv6} activate', afiv6_config) + self.assertIn(f' neighbor {pg_ipv6} maximum-prefix {ipv6_max_prefix}', afiv6_config) + + def test_bgp_99_bmp(self): + target_name = 'instance-bmp' + target_address = '127.0.0.1' + target_port = '5000' + min_retry = '1024' + max_retry = '2048' + monitor_ipv4 = 'pre-policy' + monitor_ipv6 = 'pre-policy' + mirror_buffer = '32000000' + bmp_path = base_path + ['bmp'] + target_path = bmp_path + ['target', target_name] + + # by default the 'bmp' module not loaded for the bgpd expect Error + self.cli_set(bmp_path) + if not process_named_running('bgpd', 'bmp'): + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + # add required 'bmp' module to bgpd and restart bgpd + self.cli_delete(bmp_path) + self.cli_set(['system', 'frr', 'bmp']) + self.cli_commit() + + # restart bgpd to apply "-M bmp" and update PID + cmd(f'sudo kill -9 {self.daemon_pid}') + # let the bgpd process recover + sleep(10) + # update daemon PID - this was a planned daemon restart + self.daemon_pid = process_named_running(PROCESS_NAME) + + # set bmp config but not set address + self.cli_set(target_path + ['port', target_port]) + # address is not set, expect Error + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + # config other bmp options + self.cli_set(target_path + ['address', target_address]) + self.cli_set(bmp_path + ['mirror-buffer-limit', mirror_buffer]) + self.cli_set(target_path + ['port', target_port]) + self.cli_set(target_path + ['min-retry', min_retry]) + self.cli_set(target_path + ['max-retry', max_retry]) + self.cli_set(target_path + ['mirror']) + self.cli_set(target_path + ['monitor', 'ipv4-unicast', monitor_ipv4]) + self.cli_set(target_path + ['monitor', 'ipv6-unicast', monitor_ipv6]) + self.cli_commit() + + # Verify bgpd bmp configuration + frrconfig = self.getFRRconfig(f'router bgp {ASN}') + self.assertIn(f'bmp mirror buffer-limit {mirror_buffer}', frrconfig) + self.assertIn(f'bmp targets {target_name}', frrconfig) + self.assertIn(f'bmp mirror', frrconfig) + self.assertIn(f'bmp monitor ipv4 unicast {monitor_ipv4}', frrconfig) + self.assertIn(f'bmp monitor ipv6 unicast {monitor_ipv6}', frrconfig) + self.assertIn(f'bmp connect {target_address} port {target_port} min-retry {min_retry} max-retry {max_retry}', frrconfig) + if __name__ == '__main__': unittest.main(verbosity=2) |