diff options
| author | Christian Breunig <christian@breunig.cc> | 2026-03-04 20:27:21 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-04 20:27:21 +0100 |
| commit | ddaae274187916b3a7932372ee8944ddce8c5423 (patch) | |
| tree | 3d06206bb683bf87a57b64a84e33f5c707135521 | |
| parent | d69bff60c25781ffe52ba744ba5b5d7e8c6ddeea (diff) | |
| parent | f831da31dd0c02238a8e045087e1ab53173cb05f (diff) | |
| download | vyos-1x-ddaae274187916b3a7932372ee8944ddce8c5423.tar.gz vyos-1x-ddaae274187916b3a7932372ee8944ddce8c5423.zip | |
Merge pull request #4962 from jvoss/srv6_isis
isis: T6978: add IS-IS SRv6 node-msd configuration
| -rw-r--r-- | data/templates/frr/isisd.frr.j2 | 23 | ||||
| -rw-r--r-- | interface-definitions/include/isis/protocol-common-config.xml.i | 107 | ||||
| -rw-r--r-- | op-mode-definitions/include/isis-common.xml.i | 15 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_isis.py | 46 | ||||
| -rw-r--r-- | src/completion/list_srv6_locators.sh | 21 | ||||
| -rwxr-xr-x | src/conf_mode/protocols_isis.py | 7 |
6 files changed, 198 insertions, 21 deletions
diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2 index 8df8e90d1..8128c6711 100644 --- a/data/templates/frr/isisd.frr.j2 +++ b/data/templates/frr/isisd.frr.j2 @@ -152,9 +152,30 @@ advertise-passive-only {% if segment_routing.maximum_label_depth is vyos_defined %} segment-routing node-msd {{ segment_routing.maximum_label_depth }} {% endif %} -{% if segment_routing.srv6.locator is vyos_defined %} +{% if segment_routing.srv6 is vyos_defined %} segment-routing srv6 +{% if segment_routing.srv6.locator is vyos_defined %} locator {{ segment_routing.srv6.locator }} +{% endif %} +{% if segment_routing.srv6.node_msd is vyos_defined %} + node-msd +{% if segment_routing.srv6.node_msd.max_end_d is vyos_defined %} + max-end-d {{ segment_routing.srv6.node_msd.max_end_d }} +{% endif %} +{% if segment_routing.srv6.node_msd.max_end_pop is vyos_defined %} + max-end-pop {{ segment_routing.srv6.node_msd.max_end_pop }} +{% endif %} +{% if segment_routing.srv6.node_msd.max_h_encaps is vyos_defined %} + max-h-encaps {{ segment_routing.srv6.node_msd.max_h_encaps }} +{% endif %} +{% if segment_routing.srv6.node_msd.max_segs_left is vyos_defined %} + max-segs-left {{ segment_routing.srv6.node_msd.max_segs_left }} +{% endif %} + exit +{% endif %} +{% if segment_routing.srv6.interface is vyos_defined %} + interface {{ segment_routing.srv6.interface }} +{% endif %} exit {% endif %} {% if segment_routing.global_block is vyos_defined %} diff --git a/interface-definitions/include/isis/protocol-common-config.xml.i b/interface-definitions/include/isis/protocol-common-config.xml.i index 1b5b41ad2..6a7388c99 100644 --- a/interface-definitions/include/isis/protocol-common-config.xml.i +++ b/interface-definitions/include/isis/protocol-common-config.xml.i @@ -298,25 +298,6 @@ #include <include/segment-routing-label-value.xml.i> </children> </node> - <node name="srv6"> - <properties> - <help>Segment-Routing SRv6 configuration</help> - </properties> - <children> - <leafNode name="locator"> - <properties> - <help>Specify SRv6 locator</help> - <valueHelp> - <format>txt</format> - <description>SRv6 locator name</description> - </valueHelp> - <constraint> - #include <include/constraint/alpha-numeric-hyphen-underscore.xml.i> - </constraint> - </properties> - </leafNode> - </children> - </node> <leafNode name="maximum-label-depth"> <properties> <help>Maximum MPLS labels allowed for this router</help> @@ -410,6 +391,94 @@ </node> </children> </tagNode> + <node name="srv6"> + <properties> + <help>Segment-Routing over IPv6 (SRv6) configuration</help> + </properties> + <children> + <leafNode name="locator"> + <properties> + <help>Specify SRv6 locator</help> + <valueHelp> + <format>txt</format> + <description>SRv6 locator name</description> + </valueHelp> + <completionHelp> + <script>${vyos_completion_dir}/list_srv6_locators.sh</script> + </completionHelp> + <constraint> + #include <include/constraint/alpha-numeric-hyphen-underscore.xml.i> + </constraint> + </properties> + </leafNode> + <node name="node-msd"> + <properties> + <help>SRv6 Maximum Segment ID (SID) Depth (MSD)</help> + </properties> + <children> + <leafNode name="max-end-d"> + <properties> + <help>Maximum Segment Identifier for End-of-Data</help> + <valueHelp> + <format>u32:0-255</format> + <description>Maximum End D MSD</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-255"/> + </constraint> + </properties> + </leafNode> + <leafNode name="max-end-pop"> + <properties> + <help>Maximum number of SIDs in Segment-Routing Header (SRH) for segment pop</help> + <valueHelp> + <format>u32:0-255</format> + <description>Maximum End Pop MSD</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-255"/> + </constraint> + </properties> + </leafNode> + <leafNode name="max-h-encaps"> + <properties> + <help>Maximum Headend Encapsulation in MSD</help> + <valueHelp> + <format>u32:0-255</format> + <description>Maximum Headend encaps in MSD</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-255"/> + </constraint> + </properties> + </leafNode> + <leafNode name="max-segs-left"> + <properties> + <help>Maximum Segments left in MSD</help> + <valueHelp> + <format>u32:0-255</format> + <description>Maximum Segments Left</description> + </valueHelp> + <constraint> + <validator name="numeric" argument="--range 0-255"/> + </constraint> + </properties> + </leafNode> + </children> + </node> + <leafNode name="interface"> + <properties> + <help>Interface for Segment-Routing over IPv6 (SRv6)</help> + <completionHelp> + <script>${vyos_completion_dir}/list_interfaces</script> + </completionHelp> + <constraint> + #include <include/constraint/interface-name.xml.i> + </constraint> + </properties> + </leafNode> + </children> + </node> </children> </node> <node name="redistribute"> diff --git a/op-mode-definitions/include/isis-common.xml.i b/op-mode-definitions/include/isis-common.xml.i index cda46736d..17132b857 100644 --- a/op-mode-definitions/include/isis-common.xml.i +++ b/op-mode-definitions/include/isis-common.xml.i @@ -143,7 +143,7 @@ </node> <node name="segment-routing"> <properties> - <help>Show IS-IS Segment-Routing (SPRING) information</help> + <help>Show IS-IS Segment Routing (SPRING) information</help> </properties> <children> <leafNode name="node"> @@ -152,6 +152,19 @@ </properties> <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> </leafNode> + <node name="srv6"> + <properties> + <help>Segment Routing over IPv6 (SRv6)</help> + </properties> + <children> + <leafNode name="node"> + <properties> + <help>SRv6 node information</help> + </properties> + <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command> + </leafNode> + </children> + </node> </children> </node> <leafNode name="spf-delay-ietf"> diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py index 58ba77ea0..5d61f4ce0 100755 --- a/smoketest/scripts/cli/test_protocols_isis.py +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -420,10 +420,15 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): def test_isis_11_srv6(self): locator = "TEST" interface = 'lo' + srv6_iface = 'dum6' + + # The dummy interface used to install SRv6 SIDs in the Linux data plane + self.cli_set(['interfaces', 'dummy', srv6_iface]) self.cli_set(base_path + ['net', net]) self.cli_set(base_path + ['interface', interface]) self.cli_set(base_path + ['segment-routing', 'srv6', 'locator', locator]) + self.cli_set(base_path + ['segment-routing', 'srv6', 'interface', srv6_iface]) # Commit main ISIS changes self.cli_commit() @@ -476,5 +481,46 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): tmp = self.getFRRconfig(f'interface {interface}', stop_section='^exit') self.assertIn(f' isis fast-reroute ti-lfa level-1 node-protection link-fallback', tmp) + def test_isis_14_segment_routing_srv6_advanced(self): + # Configure system SRv6 locator and interface + locator = 'TEST' + sr_base = ['protocols', 'segment-routing'] + self.cli_set(sr_base + ['srv6', 'locator', 'TEST', 'prefix', '2001:db8::/64']) + self.cli_set(sr_base + ['interface', 'lo']) + + # The dummy interface used to install SRv6 SIDs in the Linux data plane + dum_iface = 'dum6' + self.cli_set(['interfaces', 'dummy', dum_iface]) + + # Set a basic IS-IS config + self.cli_set(base_path + ['net', net]) + self.cli_set(base_path + ['interface', 'lo']) + + # Configure IS-IS SRv6 + srv6_base_path = base_path + ['segment-routing', 'srv6'] + self.cli_set(srv6_base_path + ['locator', locator]) + self.cli_set(srv6_base_path + ['interface', dum_iface]) + self.cli_commit() + + tmp = self.getFRRconfig(f'router isis {domain}', stop_section='^exit') + self.assertIn(' segment-routing srv6', tmp) + self.assertIn(f' locator {locator}', tmp) + self.assertIn(f' interface {dum_iface}', tmp) + + # Test node-msd configuration + self.cli_set(srv6_base_path + ['node-msd', 'max-end-d', '40']) + self.cli_set(srv6_base_path + ['node-msd', 'max-end-pop', '50']) + self.cli_set(srv6_base_path + ['node-msd', 'max-h-encaps', '60']) + self.cli_set(srv6_base_path + ['node-msd', 'max-segs-left', '70']) + self.cli_commit() + + tmp = self.getFRRconfig(f'router isis {domain}', stop_section='^exit') + self.assertIn(' node-msd', tmp) + self.assertIn(' max-end-d 40', tmp) + self.assertIn(' max-end-pop 50', tmp) + self.assertIn(' max-h-encaps 60', tmp) + self.assertIn(' max-segs-left 70', tmp) + + if __name__ == '__main__': unittest.main(verbosity=2, failfast=VyOSUnitTestSHIM.TestCase.debug_on()) diff --git a/src/completion/list_srv6_locators.sh b/src/completion/list_srv6_locators.sh new file mode 100644 index 000000000..03ca499d8 --- /dev/null +++ b/src/completion/list_srv6_locators.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Copyright (C) VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# This script is completion helper to list all configured SRv6 locators that +# are visible to FRR + +seg6LocatorsJson=$(vtysh -c 'show segment-routing srv6 locator json') +echo "$(echo "$seg6LocatorsJson" | jq -r '[.locators[].name][]')" diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index 151c5450a..3d172087e 100755 --- a/src/conf_mode/protocols_isis.py +++ b/src/conf_mode/protocols_isis.py @@ -261,6 +261,13 @@ def verify(config_dict): f'max-lsp-lifetime must be greater or equal to lsp-refresh-interval + 300' ) + # Check IS-IS SRv6 + if dict_search('segment_routing.srv6', isis): + # The interface used to install SRv6 SIDs in the Linux data plane. + # https://docs.frrouting.org/en/stable-10.2/isisd.html#clicmd-interface-NAME + if not dict_search('segment_routing.srv6.interface', isis): + raise ConfigError('Missing interface used for installing SRv6 SIDs') + return None def generate(config_dict): |
