diff options
| author | aapostoliuk <a.apostoliuk@vyos.io> | 2025-08-27 16:34:59 +0300 |
|---|---|---|
| committer | aapostoliuk <a.apostoliuk@vyos.io> | 2025-08-28 13:43:29 +0300 |
| commit | 5098fa8eb575afed317207c325f9126d3e0b32ae (patch) | |
| tree | 323083f4e853297b8defacc79f1a0b77db59ae82 | |
| parent | 968409218f914d180b2f9781edf3423ddb8ac738 (diff) | |
| download | vyos-1x-5098fa8eb575afed317207c325f9126d3e0b32ae.tar.gz vyos-1x-5098fa8eb575afed317207c325f9126d3e0b32ae.zip | |
isis: T7722: Added interface fast-reroute configuration commands
Added interface fast-reroute configuration commands
| -rw-r--r-- | data/templates/frr/isisd.frr.j2 | 27 | ||||
| -rw-r--r-- | interface-definitions/include/isis/exclude-interface.xml.i | 10 | ||||
| -rw-r--r-- | interface-definitions/include/isis/frr-maxmetric.xml.i | 14 | ||||
| -rw-r--r-- | interface-definitions/include/isis/node-protection.xml.i | 15 | ||||
| -rw-r--r-- | interface-definitions/include/isis/protocol-common-config.xml.i | 90 | ||||
| -rw-r--r-- | interface-definitions/include/isis/remote_lfa_tunnel.xml.i | 15 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_isis.py | 39 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_isis.py | 23 |
8 files changed, 232 insertions, 1 deletions
diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2 index a4ea28942..6691517b4 100644 --- a/data/templates/frr/isisd.frr.j2 +++ b/data/templates/frr/isisd.frr.j2 @@ -16,6 +16,33 @@ interface {{ iface }} {% if iface_config.circuit_type is vyos_defined %} isis circuit-type {{ iface_config.circuit_type }} {% endif %} +{% if iface_config.fast_reroute.lfa is vyos_defined %} +{% for level, level_config in iface_config.fast_reroute.lfa.items() %} +{% if level_config.enable is vyos_defined %} +isis fast-reroute lfa {{ level | replace('_', '-') }} +{% endif %} +{% if level_config.exclude.interface is vyos_defined %} +{% for excl_if in level_config.exclude.interface %} +isis fast-reroute lfa {{ level | replace('_', '-') }} exclude interface {{ excl_if }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% if iface_config.fast_reroute.remote_lfa is vyos_defined %} +{% for level, level_config in iface_config.fast_reroute.remote_lfa.items() %} +{% if level_config.maximum_metric is vyos_defined %} +isis fast-reroute remote-lfa maximum-metric {{ level_config.maximum_metric }} {{ level | replace('_', '-') }} +{% endif %} +{% if level_config.tunnel.mpls_ldp is vyos_defined %} +isis fast-reroute remote-lfa tunnel mpls-ldp {{ level | replace('_', '-') }} +{% endif %} +{% endfor %} +{% endif %} +{% if iface_config.fast_reroute.ti_lfa is vyos_defined %} +{% for level, level_config in iface_config.fast_reroute.ti_lfa.items() %} +isis fast-reroute ti-lfa {{ level | replace('_', '-') }} {{ 'node-protection' if level_config.node_protection is vyos_defined }} {{ 'link-fallback' if level_config.node_protection.link_fallback is vyos_defined }} +{% endfor %} +{% endif %} {% if iface_config.hello_interval is vyos_defined %} isis hello-interval {{ iface_config.hello_interval }} {% endif %} diff --git a/interface-definitions/include/isis/exclude-interface.xml.i b/interface-definitions/include/isis/exclude-interface.xml.i new file mode 100644 index 000000000..87399b43f --- /dev/null +++ b/interface-definitions/include/isis/exclude-interface.xml.i @@ -0,0 +1,10 @@ +<!-- include start from isis/exclude-interface.xml.i --> +<node name="exclude"> + <properties> + <help>Exclude interfaces from fast reroute</help> + </properties> + <children> + #include <include/generic-interface-multi.xml.i> + </children> +</node> +<!-- include end -->
\ No newline at end of file diff --git a/interface-definitions/include/isis/frr-maxmetric.xml.i b/interface-definitions/include/isis/frr-maxmetric.xml.i new file mode 100644 index 000000000..2e1cad19d --- /dev/null +++ b/interface-definitions/include/isis/frr-maxmetric.xml.i @@ -0,0 +1,14 @@ +<!-- include start from isis/frr-maxmetric.xml.i --> +<leafNode name="maximum-metric"> + <properties> + <help>Limit remote LFA node selection within the metric</help> + <valueHelp> + <format>u32:1-16777215</format> + <description>Metric value</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 1-16777215"/> + </constraint> + </properties> +</leafNode> +<!-- include end -->
\ No newline at end of file diff --git a/interface-definitions/include/isis/node-protection.xml.i b/interface-definitions/include/isis/node-protection.xml.i new file mode 100644 index 000000000..2dda81c0c --- /dev/null +++ b/interface-definitions/include/isis/node-protection.xml.i @@ -0,0 +1,15 @@ +<!-- include start from isis/node-protection.xml.i --> +<node name="node-protection"> + <properties> + <help>Protect against node failures</help> + </properties> + <children> + <leafNode name="link-fallback"> + <properties> + <help>Enable link-protection fallback</help> + <valueless/> + </properties> + </leafNode> + </children> +</node> +<!-- include end -->
\ No newline at end of file diff --git a/interface-definitions/include/isis/protocol-common-config.xml.i b/interface-definitions/include/isis/protocol-common-config.xml.i index e75466457..459a048a2 100644 --- a/interface-definitions/include/isis/protocol-common-config.xml.i +++ b/interface-definitions/include/isis/protocol-common-config.xml.i @@ -667,6 +667,96 @@ </constraint> </properties> </leafNode> + <node name="fast-reroute"> + <properties> + <help>IS-IS fast reroute</help> + </properties> + <children> + <node name="lfa"> + <properties> + <help>Enable LFA computation</help> + </properties> + <children> + <node name="level-1"> + <properties> + <help> Enable LFA computation for Level 1 only</help> + </properties> + <children> + <leafNode name="enable"> + <properties> + <help>Enable LFA</help> + <valueless/> + </properties> + </leafNode> + #include <include/isis/exclude-interface.xml.i> + </children> + </node> + <node name="level-2"> + <properties> + <help>Enable LFA computation for Level 2 only</help> + </properties> + <children> + <leafNode name="enable"> + <properties> + <help>Enable LFA</help> + <valueless/> + </properties> + </leafNode> + #include <include/isis/exclude-interface.xml.i> + </children> + </node> + </children> + </node> + <node name="remote-lfa"> + <properties> + <help>Enable remote LFA computation</help> + </properties> + <children> + <node name="level-1"> + <properties> + <help> Enable remote LFA computation for Level 1 only</help> + </properties> + <children> + #include <include/isis/frr-maxmetric.xml.i> + #include <include/isis/remote_lfa_tunnel.xml.i> + </children> + </node> + <node name="level-2"> + <properties> + <help>Enable remote LFA computation for Level 2 only</help> + </properties> + <children> + #include <include/isis/frr-maxmetric.xml.i> + #include <include/isis/remote_lfa_tunnel.xml.i> + </children> + </node> + </children> + </node> + <node name="ti-lfa"> + <properties> + <help> Enable TI-LFA computation</help> + </properties> + <children> + <node name="level-1"> + <properties> + <help>Enable TI-LFA computation for Level 1 only</help> + </properties> + <children> + #include <include/isis/node-protection.xml.i> + </children> + </node> + <node name="level-2"> + <properties> + <help>Enable TI-LFA computation for Level 2 only</help> + </properties> + <children> + #include <include/isis/node-protection.xml.i> + </children> + </node> + </children> + </node> + </children> + </node> <leafNode name="hello-padding"> <properties> <help>Add padding to IS-IS hello packets</help> diff --git a/interface-definitions/include/isis/remote_lfa_tunnel.xml.i b/interface-definitions/include/isis/remote_lfa_tunnel.xml.i new file mode 100644 index 000000000..62091a5ee --- /dev/null +++ b/interface-definitions/include/isis/remote_lfa_tunnel.xml.i @@ -0,0 +1,15 @@ +<!-- include start from isis/remote_lfa_tunnel.xml.i --> +<node name="tunnel"> + <properties> + <help>Enable remote LFA computation using tunnels</help> + </properties> + <children> + <leafNode name="mpls-ldp"> + <properties> + <help>Use MPLS LDP tunnel to reach the remote LFA node</help> + <valueless/> + </properties> + </leafNode> + </children> +</node> +<!-- include end -->
\ No newline at end of file diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py index 54f4e513b..b901449d0 100755 --- a/smoketest/scripts/cli/test_protocols_isis.py +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -438,5 +438,44 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): # Commit for isis self.cli_commit() + def test_isis_12_frr_interface_lfa_remotelfa(self): + interface = 'eth0' + rla_metric = '10' + frr_interface_base_path = base_path + ['interface', interface, 'fast-reroute'] + self.cli_set(base_path + ['net', net]) + self.cli_set(base_path + ['interface', interface]) + self.cli_set(frr_interface_base_path + ['lfa', 'level-1', 'enable']) + self.cli_set(frr_interface_base_path + ['lfa', 'level-1', 'exclude', + 'interface', interface]) + self.cli_set(frr_interface_base_path + ['remote-lfa', 'level-1', + 'maximum-metric', rla_metric]) + self.cli_set(frr_interface_base_path + ['remote-lfa', 'level-1', + 'tunnel', 'mpls-ldp']) + + # Commit main ISIS changes + self.cli_commit() + + # Verify interface ISIS changes + tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit') + self.assertIn(f' isis fast-reroute lfa level-1', tmp) + self.assertIn(f' isis fast-reroute lfa level-1 exclude interface {interface}', tmp) + self.assertIn(f' isis fast-reroute remote-lfa maximum-metric {rla_metric} level-1', tmp) + self.assertIn(f' isis fast-reroute remote-lfa tunnel mpls-ldp level-1', tmp) + + def test_isis_13_frr_interface_tilfa(self): + interface = 'eth0' + frr_interface_base_path = base_path + ['interface', interface, 'fast-reroute'] + self.cli_set(base_path + ['net', net]) + self.cli_set(base_path + ['interface', interface]) + self.cli_set(frr_interface_base_path + ['ti-lfa', 'level-1', 'node-protection', + 'link-fallback']) + + # Commit main ISIS changes + self.cli_commit() + + # Verify interface ISIS changes + tmp = self.getFRRconfig(f'interface {interface}', endsection='^exit') + self.assertIn(f' isis fast-reroute ti-lfa level-1 node-protection link-fallback', tmp) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index 8b1408f57..f561d8458 100755 --- a/src/conf_mode/protocols_isis.py +++ b/src/conf_mode/protocols_isis.py @@ -68,7 +68,7 @@ def verify(config_dict): if 'interface' not in isis: raise ConfigError('Interface used for routing updates is mandatory!') - for interface in isis['interface']: + for interface, interface_config in isis['interface'].items(): verify_interface_exists(isis, interface) # Interface MTU must be >= configured lsp-mtu mtu = Interface(interface).get_mtu() @@ -90,6 +90,27 @@ def verify(config_dict): if 'master' not in tmp or tmp['master'] != vrf: raise ConfigError(f'Interface "{interface}" is not a member of VRF "{vrf}"!') + # Fast reroute validation + # LFA and TI-LFA of the same level can not be configured on the same interface + # To configure Remote LFA, LFA of the same level should be configured on this interface. + if 'fast_reroute' in interface_config: + isis_frr_config = interface_config['fast_reroute'] + levels = ['level_1', 'level_2'] + if 'lfa' and 'ti_lfa' in isis_frr_config: + for isis_level in levels: + if ((dict_search(f'lfa.{isis_level}.enable', isis_frr_config) is not None) + and (dict_search(f'ti_lfa.{isis_level}', isis_frr_config) is not None)): + raise ConfigError( + f'LFA and TI-LFA at the "{str(isis_level).replace("_","-")}" ' + f'can not be configured on the same interface "{interface}"!') + if 'remote_lfa' in isis_frr_config: + for isis_level in levels: + if ((dict_search(f'remote_lfa.{isis_level}', isis_frr_config) is not None) + and (dict_search(f'lfa.{isis_level}.enable', isis_frr_config) is None)): + raise ConfigError( + f'To configure Remote LFA, LFA at the same level ' + f'should be configured on interface "{interface}"!') + # If md5 and plaintext-password set at the same time for password in ['area_password', 'domain_password']: if password in isis: |
