summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Breunig <christian@breunig.cc>2023-07-20 21:07:40 +0200
committerChristian Breunig <christian@breunig.cc>2023-07-20 22:12:54 +0200
commit9cdfbd77f7414ea8a13ae66df41035d2f6edef32 (patch)
tree16f26da38ea40893e37f72f4ee4e0b67a7fedc24
parent8160aa1f90d93ceda2417f703344698a2e2ccbfc (diff)
downloadvyos-1x-9cdfbd77f7414ea8a13ae66df41035d2f6edef32.tar.gz
vyos-1x-9cdfbd77f7414ea8a13ae66df41035d2f6edef32.zip
ospf: T5377: add graceful restart FRR feature (RFC 3623)
New CLI commands: * set protocols ospf graceful-restart grace-period 300 * set protocols ospf graceful-restart helper planned-only * set protocols ospf graceful-restart helper no-strict-lsa-checking * set protocols ospf graceful-restart helper supported-grace-time 400 * set protocols ospf graceful-restart helper enable router-id 192.0.2.1 * set protocols ospf graceful-restart helper enable router-id 192.0.2.2 * set protocols ospfv3 graceful-restart grace-period 300 * set protocols ospfv3 graceful-restart helper planned-only * set protocols ospfv3 graceful-restart helper lsa-check-disable * set protocols ospfv3 graceful-restart helper supported-grace-time 400 * set protocols ospfv3 graceful-restart helper enable router-id 192.0.2.1 * set protocols ospfv3 graceful-restart helper enable router-id 192.0.2.2
-rw-r--r--data/templates/frr/ospf6d.frr.j221
-rw-r--r--data/templates/frr/ospfd.frr.j221
-rw-r--r--interface-definitions/include/ospf/graceful-restart.xml.i67
-rw-r--r--interface-definitions/include/ospf/protocol-common-config.xml.i17
-rw-r--r--interface-definitions/include/ospfv3/protocol-common-config.xml.i15
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospf.py25
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ospfv3.py26
-rwxr-xr-xsrc/conf_mode/protocols_ospf.py2
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py2
9 files changed, 195 insertions, 1 deletions
diff --git a/data/templates/frr/ospf6d.frr.j2 b/data/templates/frr/ospf6d.frr.j2
index 84394ed1a..b0b5663dd 100644
--- a/data/templates/frr/ospf6d.frr.j2
+++ b/data/templates/frr/ospf6d.frr.j2
@@ -80,6 +80,27 @@ router ospf6 {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
{% if distance.ospfv3 is vyos_defined %}
distance ospf6 {{ 'intra-area ' ~ distance.ospfv3.intra_area if distance.ospfv3.intra_area is vyos_defined }} {{ 'inter-area ' ~ distance.ospfv3.inter_area if distance.ospfv3.inter_area is vyos_defined }} {{ 'external ' ~ distance.ospfv3.external if distance.ospfv3.external is vyos_defined }}
{% endif %}
+{% if graceful_restart is vyos_defined %}
+{% if graceful_restart.grace_period is vyos_defined %}
+ graceful-restart grace-period {{ graceful_restart.grace_period }}
+{% endif %}
+{% if graceful_restart.helper.enable.router_id is vyos_defined %}
+{% for router_id in graceful_restart.helper.enable.router_id %}
+ graceful-restart helper enable {{ router_id }}
+{% endfor %}
+{% elif graceful_restart.helper.enable is vyos_defined %}
+ graceful-restart helper enable
+{% endif %}
+{% if graceful_restart.helper.planned_only is vyos_defined %}
+ graceful-restart helper planned-only
+{% endif %}
+{% if graceful_restart.helper.lsa_check_disable is vyos_defined %}
+ graceful-restart helper lsa-check-disable
+{% endif %}
+{% if graceful_restart.helper.supported_grace_time is vyos_defined %}
+ graceful-restart helper supported-grace-time {{ graceful_restart.helper.supported_grace_time }}
+{% endif %}
+{% endif %}
{% if log_adjacency_changes is vyos_defined %}
log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }}
{% endif %}
diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2
index 1ee8d8752..121ecf677 100644
--- a/data/templates/frr/ospfd.frr.j2
+++ b/data/templates/frr/ospfd.frr.j2
@@ -153,6 +153,27 @@ router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }}
{% if distance.ospf is vyos_defined %}
distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is vyos_defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is vyos_defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is vyos_defined }}
{% endif %}
+{% if graceful_restart is vyos_defined %}
+{% if graceful_restart.grace_period is vyos_defined %}
+ graceful-restart grace-period {{ graceful_restart.grace_period }}
+{% endif %}
+{% if graceful_restart.helper.enable.router_id is vyos_defined %}
+{% for router_id in graceful_restart.helper.enable.router_id %}
+ graceful-restart helper enable {{ router_id }}
+{% endfor %}
+{% elif graceful_restart.helper.enable is vyos_defined %}
+ graceful-restart helper enable
+{% endif %}
+{% if graceful_restart.helper.planned_only is vyos_defined %}
+ graceful-restart helper planned-only
+{% endif %}
+{% if graceful_restart.helper.no_strict_lsa_checking is vyos_defined %}
+ no graceful-restart helper strict-lsa-checking
+{% endif %}
+{% if graceful_restart.helper.supported_grace_time is vyos_defined %}
+ graceful-restart helper supported-grace-time {{ graceful_restart.helper.supported_grace_time }}
+{% endif %}
+{% endif %}
{% if log_adjacency_changes is vyos_defined %}
log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is vyos_defined }}
{% endif %}
diff --git a/interface-definitions/include/ospf/graceful-restart.xml.i b/interface-definitions/include/ospf/graceful-restart.xml.i
new file mode 100644
index 000000000..37d9a7f13
--- /dev/null
+++ b/interface-definitions/include/ospf/graceful-restart.xml.i
@@ -0,0 +1,67 @@
+<!-- include start from ospf/graceful-restart.xml.i -->
+<node name="graceful-restart">
+ <properties>
+ <help>Graceful Restart</help>
+ </properties>
+ <children>
+ <leafNode name="grace-period">
+ <properties>
+ <help>Maximum length of the grace period</help>
+ <valueHelp>
+ <format>u32:1-1800</format>
+ <description>Maximum length of the grace period in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-1800"/>
+ </constraint>
+ </properties>
+ <defaultValue>120</defaultValue>
+ </leafNode>
+ <node name="helper">
+ <properties>
+ <help>OSPF graceful-restart helpers</help>
+ </properties>
+ <children>
+ <node name="enable">
+ <properties>
+ <help>Enable helper support</help>
+ </properties>
+ <children>
+ <leafNode name="router-id">
+ <properties>
+ <help>Advertising Router-ID</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>Router-ID in IP address format</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ </constraint>
+ <multi/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <leafNode name="planned-only">
+ <properties>
+ <help>Supported only planned restart</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="supported-grace-time">
+ <properties>
+ <help>Supported grace timer</help>
+ <valueHelp>
+ <format>u32:10-1800</format>
+ <description>Grace interval in seconds</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 10-1800"/>
+ </constraint>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end -->
diff --git a/interface-definitions/include/ospf/protocol-common-config.xml.i b/interface-definitions/include/ospf/protocol-common-config.xml.i
index 3492b873f..438093222 100644
--- a/interface-definitions/include/ospf/protocol-common-config.xml.i
+++ b/interface-definitions/include/ospf/protocol-common-config.xml.i
@@ -339,6 +339,21 @@
</constraint>
</properties>
</leafNode>
+#include <include/ospf/graceful-restart.xml.i>
+<node name="graceful-restart">
+ <children>
+ <node name="helper">
+ <children>
+ <leafNode name="no-strict-lsa-checking">
+ <properties>
+ <help>Disable strict LSA check</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</node>
<leafNode name="maximum-paths">
<properties>
<help>Maximum multiple paths (ECMP)</help>
@@ -928,4 +943,4 @@
</node>
</children>
</node>
-<!-- include end --> \ No newline at end of file
+<!-- include end -->
diff --git a/interface-definitions/include/ospfv3/protocol-common-config.xml.i b/interface-definitions/include/ospfv3/protocol-common-config.xml.i
index a7de50638..4c3ca68e1 100644
--- a/interface-definitions/include/ospfv3/protocol-common-config.xml.i
+++ b/interface-definitions/include/ospfv3/protocol-common-config.xml.i
@@ -107,6 +107,21 @@
</node>
</children>
</node>
+#include <include/ospf/graceful-restart.xml.i>
+<node name="graceful-restart">
+ <children>
+ <node name="helper">
+ <children>
+ <leafNode name="lsa-check-disable">
+ <properties>
+ <help>Disable strict LSA check</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</node>
<tagNode name="interface">
<properties>
<help>Enable routing on an IPv6 interface</help>
diff --git a/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index 977376bdd..f4b540694 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -479,5 +479,30 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
self.assertIn(f' ip ospf dead-interval 40', config)
self.assertIn(f' no ip ospf mpls ldp-sync', config)
+ def test_ospf_16_graceful_restart(self):
+ period = '300'
+ supported_grace_time = '400'
+ router_ids = ['192.0.2.1', '192.0.2.2']
+
+ self.cli_set(base_path + ['graceful-restart', 'grace-period', period])
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'planned-only'])
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'no-strict-lsa-checking'])
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'supported-grace-time', supported_grace_time])
+ for router_id in router_ids:
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'enable', 'router-id', router_id])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf')
+ self.assertIn(f'router ospf', frrconfig)
+ self.assertIn(f' graceful-restart grace-period {period}', frrconfig)
+ self.assertIn(f' graceful-restart helper planned-only', frrconfig)
+ self.assertIn(f' no graceful-restart helper strict-lsa-checking', frrconfig)
+ self.assertIn(f' graceful-restart helper supported-grace-time {supported_grace_time}', frrconfig)
+ for router_id in router_ids:
+ self.assertIn(f' graceful-restart helper enable {router_id}', frrconfig)
+
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 b67bfaac7..64dfa18db 100755
--- a/smoketest/scripts/cli/test_protocols_ospfv3.py
+++ b/smoketest/scripts/cli/test_protocols_ospfv3.py
@@ -281,5 +281,31 @@ class TestProtocolsOSPFv3(VyOSUnitTestSHIM.TestCase):
self.cli_delete(['vrf', 'name', vrf])
self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf'])
+
+ def test_ospfv3_09_graceful_restart(self):
+ period = '300'
+ supported_grace_time = '400'
+ router_ids = ['192.0.2.1', '192.0.2.2']
+
+ self.cli_set(base_path + ['graceful-restart', 'grace-period', period])
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'planned-only'])
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'lsa-check-disable'])
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'supported-grace-time', supported_grace_time])
+ for router_id in router_ids:
+ self.cli_set(base_path + ['graceful-restart', 'helper', 'enable', 'router-id', router_id])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = self.getFRRconfig('router ospf6')
+ self.assertIn(f'router ospf6', frrconfig)
+ self.assertIn(f' graceful-restart grace-period {period}', frrconfig)
+ self.assertIn(f' graceful-restart helper planned-only', frrconfig)
+ self.assertIn(f' graceful-restart helper lsa-check-disable', frrconfig)
+ self.assertIn(f' graceful-restart helper supported-grace-time {supported_grace_time}', frrconfig)
+ for router_id in router_ids:
+ self.assertIn(f' graceful-restart helper enable {router_id}', frrconfig)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index 509d4f501..f2075d25b 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -88,6 +88,8 @@ def get_config(config=None):
del default_values['area']['area_type']['nssa']
if 'mpls_te' not in ospf:
del default_values['mpls_te']
+ if 'graceful_restart' not in ospf:
+ del default_values['graceful_restart']
for protocol in ['babel', 'bgp', 'connected', 'isis', 'kernel', 'rip', 'static', 'table']:
# table is a tagNode thus we need to clean out all occurances for the
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index 7f50d8624..fbea51f56 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -83,6 +83,8 @@ def get_config(config=None):
# need to check this first and probably drop that key.
if dict_search('default_information.originate', ospfv3) is None:
del default_values['default_information']
+ if 'graceful_restart' not in ospfv3:
+ del default_values['graceful_restart']
# XXX: T2665: we currently have no nice way for defaults under tag nodes,
# clean them out and add them manually :(