summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraapostoliuk <a.apostoliuk@vyos.io>2025-08-27 16:34:59 +0300
committeraapostoliuk <a.apostoliuk@vyos.io>2025-08-28 13:43:29 +0300
commit5098fa8eb575afed317207c325f9126d3e0b32ae (patch)
tree323083f4e853297b8defacc79f1a0b77db59ae82
parent968409218f914d180b2f9781edf3423ddb8ac738 (diff)
downloadvyos-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.j227
-rw-r--r--interface-definitions/include/isis/exclude-interface.xml.i10
-rw-r--r--interface-definitions/include/isis/frr-maxmetric.xml.i14
-rw-r--r--interface-definitions/include/isis/node-protection.xml.i15
-rw-r--r--interface-definitions/include/isis/protocol-common-config.xml.i90
-rw-r--r--interface-definitions/include/isis/remote_lfa_tunnel.xml.i15
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_isis.py39
-rwxr-xr-xsrc/conf_mode/protocols_isis.py23
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: