From fbb4f315eee8cd701aade8845ea842567a56dc64 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Mon, 3 Jul 2023 20:58:59 +0200 Subject: ospf: T5334: add support for external route summarisation Type-5 and Type-7 LSAs * set protocols ospf aggregation timer * set protocols ospf summary-address x.x.x.x/x [tag 1-4294967295] * set protocols ospf summary-address x.x.x.x/x no-advertise --- data/templates/frr/ospfd.frr.j2 | 8 ++++ .../include/ospf/protocol-common-config.xml.i | 52 ++++++++++++++++++++++ smoketest/scripts/cli/test_protocols_ospf.py | 23 ++++++++++ src/conf_mode/protocols_ospf.py | 7 +++ 4 files changed, 90 insertions(+) diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2 index 3f97b7325..1ee8d8752 100644 --- a/data/templates/frr/ospfd.frr.j2 +++ b/data/templates/frr/ospfd.frr.j2 @@ -72,6 +72,9 @@ router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% endfor %} {% endfor %} {% endif %} +{% if aggregation.timer is vyos_defined %} + aggregation timer {{ aggregation.timer }} +{% endif %} {% if area is vyos_defined %} {% for area_id, area_config in area.items() %} {% if area_config.area_type is vyos_defined %} @@ -200,6 +203,11 @@ router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% if refresh.timers is vyos_defined %} refresh timer {{ refresh.timers }} {% endif %} +{% if summary_address is vyos_defined %} +{% for prefix, prefix_options in summary_address.items() %} + summary-address {{ prefix }} {{ 'tag ' + prefix_options.tag if prefix_options.tag is vyos_defined }}{{ 'no-advertise' if prefix_options.no_advertise is vyos_defined }} +{% endfor %} +{% endif %} {% if segment_routing is vyos_defined %} {% if segment_routing.maximum_label_depth is vyos_defined %} segment-routing node-msd {{ segment_routing.maximum_label_depth }} diff --git a/interface-definitions/include/ospf/protocol-common-config.xml.i b/interface-definitions/include/ospf/protocol-common-config.xml.i index b7f22cb88..3492b873f 100644 --- a/interface-definitions/include/ospf/protocol-common-config.xml.i +++ b/interface-definitions/include/ospf/protocol-common-config.xml.i @@ -1,4 +1,24 @@ + + + External route aggregation + + + + + Delay timer + + u32:5-1800 + Timer interval in seconds + + + + + + 5 + + + Access list to filter networks in routing updates @@ -816,6 +836,38 @@ + + + External summary address + + ipv4net + OSPF area number in dotted decimal notation + + + + + + + + + Don not advertise summary route + + + + + + Router tag + + u32:1-4294967295 + Router tag value + + + + + + + + Adjust routing timers diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py index 6fe6dd979..e4907596e 100755 --- a/smoketest/scripts/cli/test_protocols_ospf.py +++ b/smoketest/scripts/cli/test_protocols_ospf.py @@ -159,6 +159,12 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): on_startup = '30' on_shutdown = '60' refresh = '50' + aggregation_timer = '100' + summary_nets = { + '10.0.1.0/24' : {}, + '10.0.2.0/24' : {'tag' : '50'}, + '10.0.3.0/24' : {'no_advertise' : {}}, + } self.cli_set(base_path + ['distance', 'global', global_distance]) self.cli_set(base_path + ['distance', 'ospf', 'external', external]) @@ -170,6 +176,15 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['mpls-te', 'enable']) self.cli_set(base_path + ['refresh', 'timers', refresh]) + self.cli_set(base_path + ['aggregation', 'timer', aggregation_timer]) + + for summary, summary_options in summary_nets.items(): + self.cli_set(base_path + ['summary-address', summary]) + if 'tag' in summary_options: + self.cli_set(base_path + ['summary-address', summary, 'tag', summary_options['tag']]) + if 'no_advertise' in summary_options: + self.cli_set(base_path + ['summary-address', summary, 'no-advertise']) + # commit changes self.cli_commit() @@ -184,6 +199,14 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): self.assertIn(f' max-metric router-lsa on-shutdown {on_shutdown}', frrconfig) self.assertIn(f' refresh timer {refresh}', frrconfig) + self.assertIn(f' aggregation timer {aggregation_timer}', frrconfig) + for summary, summary_options in summary_nets.items(): + self.assertIn(f' summary-address {summary}', frrconfig) + if 'tag' in summary_options: + tag = summary_options['tag'] + self.assertIn(f' summary-address {summary} tag {tag}', frrconfig) + if 'no_advertise' in summary_options: + self.assertIn(f' summary-address {summary} no-advertise', frrconfig) # enable inter-area self.cli_set(base_path + ['distance', 'ospf', 'inter-area', inter_area]) diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py index b73483470..460c9f1a4 100755 --- a/src/conf_mode/protocols_ospf.py +++ b/src/conf_mode/protocols_ospf.py @@ -250,6 +250,13 @@ def verify(ospf): raise ConfigError(f'Segment routing prefix {prefix} cannot have both explicit-null '\ f'and no-php-flag configured at the same time.') + # Check route summarisation + if 'summary_address' in ospf: + for prefix, prefix_options in ospf['summary_address'].items(): + if {'tag', 'no_advertise'} <= set(prefix_options): + raise ConfigError(f'Can not set both "tag" and "no-advertise" for Type-5 '\ + f'and Type-7 route summarisation of "{prefix}"!') + return None def generate(ospf): -- cgit v1.2.3