From 262d119196c4366f5f330fffe85ac7399b13db7a Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 11 Apr 2021 19:36:17 +0200 Subject: static: T3328: route-map to zebra/kernel can not be removed Removing the Zebra/Linux Kernel route-map added by "set protocols static route-map" was not removed once applied. This was because the removal must happen within the zebra daemon and not staticd. --- smoketest/scripts/cli/test_protocols_static.py | 34 +++++++++++++++++++++++--- src/conf_mode/protocols_static.py | 27 ++++++++++++++++---- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py index 75d3e6a42..0d3228cc7 100755 --- a/smoketest/scripts/cli/test_protocols_static.py +++ b/smoketest/scripts/cli/test_protocols_static.py @@ -82,7 +82,7 @@ routes = { tables = ['80', '81', '82'] -class StaticRouteTest(VyOSUnitTestSHIM.TestCase): +class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase): def setUp(self): # This is our "target" VRF when leaking routes: self.cli_set(['vrf', 'name', 'black', 'table', '43210']) @@ -100,7 +100,7 @@ class StaticRouteTest(VyOSUnitTestSHIM.TestCase): tmp = self.getFRRconfig('', end='') self.cli_commit() - def test_protocols_static(self): + def test_01_static(self): for route, route_config in routes.items(): route_type = 'route' if is_ipv6(route): @@ -187,7 +187,7 @@ class StaticRouteTest(VyOSUnitTestSHIM.TestCase): self.assertIn(tmp, frrconfig) - def test_protocols_static_table(self): + def test_02_static_table(self): for table in tables: for route, route_config in routes.items(): route_type = 'route' @@ -281,7 +281,7 @@ class StaticRouteTest(VyOSUnitTestSHIM.TestCase): self.assertIn(tmp, frrconfig) - def test_protocols_vrf_static(self): + def test_03_static_vrf(self): # Create VRF instances and apply the static routes from above to FRR. # Re-read the configured routes and match them if they are programmed # properly. This also includes VRF leaking @@ -392,5 +392,31 @@ class StaticRouteTest(VyOSUnitTestSHIM.TestCase): self.cli_delete(['vrf']) + def test_04_static_zebra_route_map(self): + # Implemented because of T3328 + self.debug = True + route_map = 'foo-static-in' + self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit']) + + self.cli_set(base_path + ['route-map', route_map]) + # commit changes + self.cli_commit() + + # Verify FRR configuration + zebra_route_map = f'ip protocol static route-map {route_map}' + frrconfig = self.getFRRconfig(zebra_route_map) + self.assertIn(zebra_route_map, frrconfig) + + # Remove the route-map again + self.cli_delete(base_path + ['route-map']) + # commit changes + self.cli_commit() + + # Verify FRR configuration + frrconfig = self.getFRRconfig(zebra_route_map) + self.assertNotIn(zebra_route_map, frrconfig) + + self.cli_delete(['policy', 'route-map', route_map]) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/protocols_static.py b/src/conf_mode/protocols_static.py index b5b2d6641..a1560afe8 100755 --- a/src/conf_mode/protocols_static.py +++ b/src/conf_mode/protocols_static.py @@ -20,6 +20,7 @@ from sys import exit from sys import argv from vyos.config import Config +from vyos.configdict import dict_merge from vyos.configverify import verify_common_route_maps from vyos.configverify import verify_vrf from vyos.template import render_to_string @@ -29,8 +30,6 @@ from vyos import frr from vyos import airbag airbag.enable() -frr_daemon = 'staticd' - def get_config(config=None): if config: conf = config @@ -49,6 +48,15 @@ def get_config(config=None): # Assign the name of our VRF context if vrf: static['vrf'] = vrf + # We also need some additional information from the config, prefix-lists + # and route-maps for instance. They will be used in verify(). + # + # XXX: one MUST always call this without the key_mangling() option! See + # vyos.configverify.verify_common_route_maps() for more information. + tmp = conf.get_config_dict(['policy']) + # Merge policy dict into "regular" config dict + static = dict_merge(tmp, static) + return static def verify(static): @@ -77,9 +85,18 @@ def generate(static): return None def apply(static): + static_daemon = 'staticd' + zebra_daemon = 'zebra' + # Save original configuration prior to starting any commit actions frr_cfg = frr.FRRConfig() - frr_cfg.load_configuration(frr_daemon) + + # The route-map used for the FIB (zebra) is part of the zebra daemon + frr_cfg.load_configuration(zebra_daemon) + frr_cfg.modify_section(r'^ip protocol static route-map [-a-zA-Z0-9.]+$', '') + frr_cfg.commit_configuration(zebra_daemon) + + frr_cfg.load_configuration(static_daemon) if 'vrf' in static: vrf = static['vrf'] @@ -89,13 +106,13 @@ def apply(static): frr_cfg.modify_section(r'^ipv6 route .*', '') frr_cfg.add_before(r'(interface .*|line vty)', static['new_frr_config']) - frr_cfg.commit_configuration(frr_daemon) + frr_cfg.commit_configuration(static_daemon) # If FRR config is blank, rerun the blank commit x times due to frr-reload # behavior/bug not properly clearing out on one commit. if static['new_frr_config'] == '': for a in range(5): - frr_cfg.commit_configuration(frr_daemon) + frr_cfg.commit_configuration(static_daemon) # Save configuration to /run/frr/config/frr.conf frr.save_configuration() -- cgit v1.2.3