diff options
| author | Christian Breunig <christian@breunig.cc> | 2023-07-20 21:07:40 +0200 | 
|---|---|---|
| committer | Christian Breunig <christian@breunig.cc> | 2023-07-20 22:12:54 +0200 | 
| commit | 9cdfbd77f7414ea8a13ae66df41035d2f6edef32 (patch) | |
| tree | 16f26da38ea40893e37f72f4ee4e0b67a7fedc24 | |
| parent | 8160aa1f90d93ceda2417f703344698a2e2ccbfc (diff) | |
| download | vyos-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.j2 | 21 | ||||
| -rw-r--r-- | data/templates/frr/ospfd.frr.j2 | 21 | ||||
| -rw-r--r-- | interface-definitions/include/ospf/graceful-restart.xml.i | 67 | ||||
| -rw-r--r-- | interface-definitions/include/ospf/protocol-common-config.xml.i | 17 | ||||
| -rw-r--r-- | interface-definitions/include/ospfv3/protocol-common-config.xml.i | 15 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_ospf.py | 25 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_ospfv3.py | 26 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_ospf.py | 2 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_ospfv3.py | 2 | 
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 :( | 
