diff --git a/data/templates/frr/isis.frr.tmpl b/data/templates/frr/isis.frr.tmpl index da098abac..7f996b134 100644 --- a/data/templates/frr/isis.frr.tmpl +++ b/data/templates/frr/isis.frr.tmpl @@ -1,175 +1,175 @@ ! -router isis {{ domain }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} +router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} net {{ net }} {% if dynamic_hostname is defined %} hostname dynamic {% endif %} {% if purge_originator is defined %} purge-originator {% endif %} {% if set_attached_bit is defined %} set-attached-bit {% endif %} {% if set_overload_bit is defined %} set-overload-bit {% endif %} {% if domain_password is defined and domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %} domain-password clear {{ domain_password.plaintext_password }} {% endif %} {% if lsp_gen_interval is defined and lsp_gen_interval is not none %} lsp-gen-interval {{ lsp_gen_interval }} {% endif %} {% if lsp_mtu is defined and lsp_mtu is not none %} lsp-mtu {{ lsp_mtu }} {% endif %} {% if lsp_refresh_interval is defined and lsp_refresh_interval is not none %} lsp-refresh-interval {{ lsp_refresh_interval }} {% endif %} {% if max_lsp_lifetime is defined and max_lsp_lifetime is not none %} max-lsp-lifetime {{ max_lsp_lifetime }} {% endif %} {% if spf_interval is defined and spf_interval is not none %} spf-interval {{ spf_interval }} {% endif %} {% if traffic_engineering is defined and traffic_engineering is not none %} {% if traffic_engineering.enable is defined %} mpls-te on {% endif %} {% if traffic_engineering.address is defined %} mpls-te router-address {{ traffic_engineering.address }} {% endif %} {% if traffic_engineering.inter_as is defined %} {% if traffic_engineering.inter_as.level_1 is defined %} mpls-te inter-as level-1 {% endif %} {% if traffic_engineering.inter_as.level_1_2 is defined %} mpls-te inter-as level-1-2 {% endif %} {% if traffic_engineering.inter_as.level_2 is defined %} mpls-te inter-as level-2-only {% endif %} {% else %} mpls-te inter-as {% endif %} {% endif %} {% if segment_routing is defined %} {% if segment_routing.enable is defined %} segment-routing on {% endif %} {% if segment_routing.maximum_label_depth is defined %} segment-routing node-msd {{ segment_routing.maximum_label_depth }} {% endif %} {% if segment_routing.global_block is defined %} segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} {% endif %} {% if segment_routing.local_block is defined %} segment-routing local-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.local_block.high_label_value }} {% endif %} {% if segment_routing.prefix is defined %} {% for prefixes in segment_routing.prefix %} {% if segment_routing.prefix[prefixes].absolute is defined %} {% if segment_routing.prefix[prefixes].absolute.value is defined %} segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} {% if segment_routing.prefix[prefixes].absolute.explicit_null is defined %} segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} explicit-null {% endif %} {% if segment_routing.prefix[prefixes].absolute.no_php_flag is defined %} segment-routing prefix {{ prefixes }} absolute {{ segment_routing.prefix[prefixes].absolute.value }} no-php-flag {% endif %} {% endif %} {% if segment_routing.prefix[prefixes].index is defined %} {% if segment_routing.prefix[prefixes].index.value is defined %} segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} {% if segment_routing.prefix[prefixes].index.explicit_null is defined %} segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} explicit-null {% endif %} {% if segment_routing.prefix[prefixes].index.no_php_flag is defined %} segment-routing prefix {{ prefixes }} index {{ segment_routing.prefix[prefixes].index.value }} no-php-flag {% endif %} {% endif %} {% endif %} {% endif %} {% endfor %} {% endif %} {% endif %} {% if spf_delay_ietf is defined and spf_delay_ietf.init_delay is defined and spf_delay_ietf.init_delay is not none %} spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }} {% endif %} {% if area_password is defined and area_password.md5 is defined and area_password.md5 is not none %} area-password md5 {{ area_password.md5 }} {% elif area_password is defined and area_password.plaintext_password is defined and area_password.plaintext_password is not none %} area-password clear {{ area_password.plaintext_password }} {% endif %} {% if default_information is defined and default_information.originate is defined and default_information.originate is not none %} {% for level in default_information.originate.ipv4 if default_information.originate.ipv4 is defined %} default-information originate ipv4 {{ level | replace('_', '-') }} {% endfor %} {% for level in default_information.originate.ipv6 if default_information.originate.ipv6 is defined %} default-information originate ipv6 {{ level | replace('_', '-') }} always {% endfor %} {% endif %} {% if redistribute is defined and redistribute.ipv4 is defined and redistribute.ipv4 is not none %} {% for protocol in redistribute.ipv4 %} {% for level, level_config in redistribute.ipv4[protocol].items() %} {% if level_config.metric is defined and level_config.metric is not none %} redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }} {% elif level_config.route_map is defined and level_config.route_map is not none %} redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }} {% else %} redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} {% endif %} {% endfor %} {% endfor %} {% endif %} {% if level is defined and level is not none %} {% if level == 'level-1' %} is-type level-1 {% elif level == 'level-2' %} is-type level-2-only {% elif level == 'level-1-2' %} is-type level-1-2 {% endif %} {% endif %} ! {% if interface is defined and interface is not none %} {% for iface, iface_config in interface.items() %} interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} - ip router isis {{ domain }} + ip router isis VyOS {% if iface_config.bfd is defined %} isis bfd {% endif %} {% if iface_config.network is defined and iface_config.network.point_to_point is defined %} isis network point-to-point {% endif %} {% if iface_config.circuit_type is defined %} isis circuit-type {{ iface_config.circuit_type }} {% endif %} {% if iface_config.hello_interval is defined and iface_config.hello_interval is not none %} isis hello-interval {{ iface_config.hello_interval }} {% endif %} {% if iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %} isis hello-multiplier {{ iface_config.hello_multiplier }} {% endif %} {% if iface_config.hello_padding is defined %} isis hello padding {% endif %} {% if iface_config.metric is defined and iface_config.metric is not none %} isis metric {{ iface_config.metric }} {% endif %} {% if iface_config.passive is defined %} isis passive {% endif %} {% if iface_config.password is defined and iface_config.password.plaintext_password is defined and iface_config.password.plaintext_password is not none %} isis password clear {{ iface_config.password.plaintext_password }} {% endif %} {% if iface_config.priority is defined and iface_config.priority is not none %} isis priority {{ iface_config.priority }} {% endif %} {% if iface_config.psnp_interval is defined and iface_config.psnp_interval is not none %} isis psnp-interval {{ iface_config.psnp_interval }} {% endif %} {% if iface_config.no_three_way_handshake is defined %} no isis three-way-handshake {% endif %} {% endfor %} {% endif %} diff --git a/interface-definitions/include/isis/isis-common-config.xml.i b/interface-definitions/include/isis/isis-common-config.xml.i index 94a6e3592..8b753b082 100644 --- a/interface-definitions/include/isis/isis-common-config.xml.i +++ b/interface-definitions/include/isis/isis-common-config.xml.i @@ -1,764 +1,755 @@ <!-- include start from isis/isis-common-config.xml.i --> <node name="area-password"> <properties> <help>Configure the authentication password for an area</help> </properties> <children> <leafNode name="plaintext-password"> <properties> <help>Plain-text authentication type</help> <valueHelp> <format>txt</format> <description>Level-wide password</description> </valueHelp> </properties> </leafNode> <leafNode name="md5"> <properties> <help>MD5 authentication type</help> <valueHelp> <format>txt</format> <description>Level-wide password</description> </valueHelp> </properties> </leafNode> </children> </node> <node name="default-information"> <properties> <help>Control distribution of default information</help> </properties> <children> <node name="originate"> <properties> <help>Distribute a default route</help> </properties> <children> <node name="ipv4"> <properties> <help>Distribute default route for IPv4</help> </properties> <children> <leafNode name="level-1"> <properties> <help>Distribute default route into level-1</help> <valueless/> </properties> </leafNode> <leafNode name="level-2"> <properties> <help>Distribute default route into level-2</help> <valueless/> </properties> </leafNode> </children> </node> <node name="ipv6"> <properties> <help>Distribute default route for IPv6</help> </properties> <children> <leafNode name="level-1"> <properties> <help>Distribute default route into level-1</help> <completionHelp> <list>always</list> </completionHelp> <valueHelp> <format>always</format> <description>Always advertise default route</description> </valueHelp> </properties> </leafNode> <leafNode name="level-2"> <properties> <help>Distribute default route into level-2</help> <completionHelp> <list>always</list> </completionHelp> <valueHelp> <format>always</format> <description>Always advertise default route</description> </valueHelp> </properties> </leafNode> </children> </node> </children> </node> </children> </node> -<leafNode name="domain"> - <properties> - <help>Domain name used for this instance</help> - <valueHelp> - <format>txt</format> - <description>IS-IS routing area domain/tag</description> - </valueHelp> - </properties> -</leafNode> <node name="domain-password"> <properties> <help>Set the authentication password for a routing domain</help> </properties> <children> <leafNode name="plaintext-password"> <properties> <help>Plain-text authentication type</help> <valueHelp> <format>txt</format> <description>Level-wide password</description> </valueHelp> </properties> </leafNode> <!-- <leafNode name="md5"> <properties> <help>MD5 authentication type</help> <valueHelp> <format>txt</format> <description>Level-wide password</description> </valueHelp> </properties> </leafNode> --> </children> </node> <leafNode name="dynamic-hostname"> <properties> <help>Dynamic hostname for IS-IS</help> <valueless/> </properties> </leafNode> <leafNode name="level"> <properties> <help>IS-IS level number</help> <completionHelp> <list>level-1 level-1-2 level-2</list> </completionHelp> <valueHelp> <format>level-1</format> <description>Act as a station router</description> </valueHelp> <valueHelp> <format>level-1-2</format> <description>Act as both a station and an area router</description> </valueHelp> <valueHelp> <format>level-2</format> <description>Act as an area router</description> </valueHelp> <constraint> <regex>(level-1|level-1-2|level-2)</regex> </constraint> </properties> </leafNode> <leafNode name="lsp-gen-interval"> <properties> <help>Minimum interval between regenerating same LSP</help> <valueHelp> <format>u32:1-120</format> <description>Minimum interval in seconds</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-120"/> </constraint> </properties> </leafNode> <leafNode name="lsp-mtu"> <properties> <help>Configure the maximum size of generated LSPs</help> <valueHelp> <format>u32:128-4352</format> <description>Maximum size of generated LSPs</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 128-4352"/> </constraint> </properties> </leafNode> <leafNode name="lsp-refresh-interval"> <properties> <help>LSP refresh interval</help> <valueHelp> <format>u32:1-65235</format> <description>LSP refresh interval in seconds</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-65235"/> </constraint> </properties> </leafNode> <leafNode name="max-lsp-lifetime"> <properties> <help>Maximum LSP lifetime</help> <valueHelp> <format>u32:350-65535</format> <description>LSP lifetime in seconds</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-65535"/> </constraint> </properties> </leafNode> <leafNode name="metric-style"> <properties> <help>Use old-style (ISO 10589) or new-style packet formats</help> <completionHelp> <list>narrow transition wide</list> </completionHelp> <valueHelp> <format>narrow</format> <description>Use old style of TLVs with narrow metric</description> </valueHelp> <valueHelp> <format>transition</format> <description>Send and accept both styles of TLVs during transition</description> </valueHelp> <valueHelp> <format>wide</format> <description>Use new style of TLVs to carry wider metric</description> </valueHelp> <constraint> <regex>(narrow|transition|wide)</regex> </constraint> </properties> </leafNode> <leafNode name="net"> <properties> <help>A Network Entity Title for this process (ISO only)</help> <valueHelp> <format>XX.XXXX. ... .XXX.XX</format> <description>Network entity title (NET)</description> </valueHelp> <constraint> <regex>[a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2}</regex> </constraint> </properties> </leafNode> <leafNode name="purge-originator"> <properties> <help>Use the RFC 6232 purge-originator</help> <valueless/> </properties> </leafNode> <node name="traffic-engineering"> <properties> <help>Show IS-IS neighbor adjacencies</help> </properties> <children> <leafNode name="enable"> <properties> <help>Enable MPLS traffic engineering extensions</help> <valueless/> </properties> </leafNode> <!-- <node name="inter-as"> <properties> <help>MPLS traffic engineering inter-AS support</help> </properties> <children> <leafNode name="level-1"> <properties> <help>Area native mode self originate inter-AS LSP with L1 only flooding scope</help> <valueless/> </properties> </leafNode> <leafNode name="level-1-2"> <properties> <help>Area native mode self originate inter-AS LSP with L1 and L2 flooding scope</help> <valueless/> </properties> </leafNode> <leafNode name="level-2"> <properties> <help>Area native mode self originate inter-AS LSP with L2 only flooding scope</help> <valueless/> </properties> </leafNode> </children> </node> <leafNode name="inter-as"> <properties> <help>MPLS traffic engineering inter-AS support</help> <valueless/> </properties> </leafNode> --> <leafNode name="address"> <properties> <help>MPLS traffic engineering router ID</help> <valueHelp> <format>ipv4</format> <description>IPv4 address</description> </valueHelp> <constraint> <validator name="ipv4-address"/> </constraint> </properties> </leafNode> </children> </node> <node name="segment-routing"> <properties> <help>Segment-Routing (SPRING) settings</help> </properties> <children> <leafNode name="enable"> <properties> <help>Enable segment-routing functionality</help> <valueless/> </properties> </leafNode> <node name="global-block"> <properties> <help>Global block label range</help> </properties> <children> <leafNode name="low-label-value"> <properties> <help>The lower bound of the global block</help> <valueHelp> <format>u32:16-1048575</format> <description>MPLS label value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 16-1048575"/> </constraint> </properties> </leafNode> <leafNode name="high-label-value"> <properties> <help>The upper bound of the global block</help> <valueHelp> <format>u32:16-1048575</format> <description>MPLS label value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 16-1048575"/> </constraint> </properties> </leafNode> </children> </node> <!-- <node name="local-block"> <properties> <help>Local Block label range</help> </properties> <children> <leafNode name="low-label-value"> <properties> <help>The lower bound of the local block</help> <valueHelp> <format>u32:16-1048575</format> <description>MPLS label value</description> </valueHelp> <constraint> <validator name="numeric" argument=" range 16-1048575"/> </constraint> </properties> </leafNode> <leafNode name="high-label-value"> <properties> <help>The upper bound of the local block</help> <valueHelp> <format>u32:16-1048575</format> <description>MPLS label value</description> </valueHelp> <constraint> <validator name="numeric" argument=" range 16-1048575"/> </constraint> </properties> </leafNode> </children> </node> --> <leafNode name="maximum-label-depth"> <properties> <help>Maximum MPLS labels allowed for this router</help> <valueHelp> <format>u32:1-16</format> <description>MPLS label depth</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-16"/> </constraint> </properties> </leafNode> <tagNode name="prefix"> <properties> <help>Static IPv4/IPv6 prefix segment/label mapping</help> <valueHelp> <format>ipv4net</format> <description>IPv4 prefix segment</description> </valueHelp> <valueHelp> <format>ipv6net</format> <description>IPv6 prefix segment</description> </valueHelp> <constraint> <validator name="ipv4-prefix"/> <validator name="ipv6-prefix"/> </constraint> </properties> <children> <node name="absolute"> <properties> <help>Specify the absolute value of prefix segment/label ID</help> </properties> <children> <leafNode name="value"> <properties> <help>Specify the absolute value of prefix segment/label ID</help> <valueHelp> <format>u32:16-1048575</format> <description>The absolute segment/label ID value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 16-1048575"/> </constraint> </properties> </leafNode> <leafNode name="explicit-null"> <properties> <help>Request upstream neighbor to replace segment/label with explicit null label</help> <valueless/> </properties> </leafNode> <leafNode name="no-php-flag"> <properties> <help>Do not request penultimate hop popping for segment/label</help> <valueless/> </properties> </leafNode> </children> </node> <node name="index"> <properties> <help>Specify the index value of prefix segment/label ID</help> </properties> <children> <leafNode name="value"> <properties> <help>Specify the index value of prefix segment/label ID</help> <valueHelp> <format>u32:0-65535</format> <description>The index segment/label ID value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-65535"/> </constraint> </properties> </leafNode> <leafNode name="explicit-null"> <properties> <help>Request upstream neighbor to replace segment/label with explicit null label</help> <valueless/> </properties> </leafNode> <leafNode name="no-php-flag"> <properties> <help>Do not request penultimate hop popping for segment/label</help> <valueless/> </properties> </leafNode> </children> </node> </children> </tagNode> </children> </node> <node name="redistribute"> <properties> <help>Redistribute information from another routing protocol</help> </properties> <children> <node name="ipv4"> <properties> <help>Redistribute IPv4 routes</help> </properties> <children> <node name="bgp"> <properties> <help>Border Gateway Protocol (BGP)</help> </properties> <children> #include <include/isis/isis-redistribute-ipv4.xml.i> </children> </node> <node name="connected"> <properties> <help>Redistribute connected routes into IS-IS</help> </properties> <children> #include <include/isis/isis-redistribute-ipv4.xml.i> </children> </node> <node name="kernel"> <properties> <help>Redistribute kernel routes into IS-IS</help> </properties> <children> #include <include/isis/isis-redistribute-ipv4.xml.i> </children> </node> <node name="ospf"> <properties> <help>Redistribute OSPF routes into IS-IS</help> </properties> <children> #include <include/isis/isis-redistribute-ipv4.xml.i> </children> </node> <node name="rip"> <properties> <help>Redistribute RIP routes into IS-IS</help> </properties> <children> #include <include/isis/isis-redistribute-ipv4.xml.i> </children> </node> <node name="static"> <properties> <help>Redistribute static routes into IS-IS</help> </properties> <children> #include <include/isis/isis-redistribute-ipv4.xml.i> </children> </node> </children> </node> </children> </node> <leafNode name="set-attached-bit"> <properties> <help>Set attached bit to identify as L1/L2 router for inter-area traffic</help> <valueless/> </properties> </leafNode> <leafNode name="set-overload-bit"> <properties> <help>Set overload bit to avoid any transit traffic</help> <valueless/> </properties> </leafNode> <node name="spf-delay-ietf"> <properties> <help>IETF SPF delay algorithm</help> </properties> <children> <leafNode name="init-delay"> <properties> <help>Delay used while in QUIET state</help> <valueHelp> <format>u32:0-60000</format> <description>Delay used while in QUIET state (in ms)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-60000"/> </constraint> </properties> </leafNode> <leafNode name="short-delay"> <properties> <help>Delay used while in SHORT_WAIT state</help> <valueHelp> <format>u32:0-60000</format> <description>Delay used while in SHORT_WAIT state (in ms)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-60000"/> </constraint> </properties> </leafNode> <leafNode name="long-delay"> <properties> <help>Delay used while in LONG_WAIT</help> <valueHelp> <format>u32:0-60000</format> <description>Delay used while in LONG_WAIT state (in ms)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-60000"/> </constraint> </properties> </leafNode> <leafNode name="holddown"> <properties> <help>Time with no received IGP events before considering IGP stable</help> <valueHelp> <format>u32:0-60000</format> <description>Time with no received IGP events before considering IGP stable (in ms)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-60000"/> </constraint> </properties> </leafNode> <leafNode name="time-to-learn"> <properties> <help>Maximum duration needed to learn all the events related to a single failure</help> <valueHelp> <format>u32:0-60000</format> <description>Maximum duration needed to learn all the events related to a single failure (in ms)</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-60000"/> </constraint> </properties> </leafNode> </children> </node> <leafNode name="spf-interval"> <properties> <help>Minimum interval between SPF calculations</help> <valueHelp> <format>u32:1-120</format> <description>Minimum interval between consecutive SPFs in seconds</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-120"/> </constraint> </properties> </leafNode> <tagNode name="interface"> <!-- (config-if)# ip router isis WORD (same as name of IS-IS process) if any section of "interface" pesent --> <properties> <help>Interface params</help> <completionHelp> <script>${vyos_completion_dir}/list_interfaces.py</script> </completionHelp> </properties> <children> #include <include/bfd.xml.i> <leafNode name="circuit-type"> <properties> <help>Configure circuit type for interface</help> <completionHelp> <list>level-1 level-1-2 level-2-only</list> </completionHelp> <valueHelp> <format>level-1</format> <description>Level-1 only adjacencies are formed</description> </valueHelp> <valueHelp> <format>level-1-2</format> <description>Level-1-2 adjacencies are formed</description> </valueHelp> <valueHelp> <format>level-2-only</format> <description>Level-2 only adjacencies are formed</description> </valueHelp> <constraint> <regex>(level-1|level-1-2|level-2-only)</regex> </constraint> </properties> </leafNode> <leafNode name="hello-padding"> <properties> <help>Add padding to IS-IS hello packets</help> <valueless/> </properties> </leafNode> <leafNode name="hello-interval"> <properties> <help>Set Hello interval</help> <valueHelp> <format>u32:1-600</format> <description>Set Hello interval</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 1-600"/> </constraint> </properties> </leafNode> <leafNode name="hello-multiplier"> <properties> <help>Set Hello interval</help> <valueHelp> <format>u32:2-100</format> <description>Set multiplier for Hello holding time</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 2-100"/> </constraint> </properties> </leafNode> <leafNode name="metric"> <properties> <help>Set default metric for circuit</help> <valueHelp> <format>u32:0-16777215</format> <description>Default metric value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-16777215"/> </constraint> </properties> </leafNode> <node name="network"> <properties> <help>Set network type</help> </properties> <children> <leafNode name="point-to-point"> <properties> <help>point-to-point network type</help> <valueless/> </properties> </leafNode> </children> </node> #include <include/isis/passive.xml.i> <node name="password"> <properties> <help>Configure the authentication password for a circuit</help> </properties> <children> <leafNode name="plaintext-password"> <properties> <help>Plain-text authentication type</help> <valueHelp> <format>txt</format> <description>Circuit password</description> </valueHelp> </properties> </leafNode> </children> </node> <leafNode name="priority"> <properties> <help>Set priority for Designated Router election</help> <valueHelp> <format>u32:0-127</format> <description>Priority value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-127"/> </constraint> </properties> </leafNode> <leafNode name="psnp-interval"> <properties> <help>Set PSNP interval in seconds</help> <valueHelp> <format>u32:0-127</format> <description>Priority value</description> </valueHelp> <constraint> <validator name="numeric" argument="--range 0-127"/> </constraint> </properties> </leafNode> <leafNode name="no-three-way-handshake"> <properties> <help>Disable three-way handshake</help> <valueless/> </properties> </leafNode> </children> </tagNode> <!-- include end --> diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py index 79d497186..10c722eca 100755 --- a/smoketest/scripts/cli/test_protocols_isis.py +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -1,107 +1,104 @@ #!/usr/bin/env python3 # # Copyright (C) 2021 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/>. import unittest from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSession from vyos.configsession import ConfigSessionError from vyos.ifconfig import Section from vyos.util import process_named_running PROCESS_NAME = 'isisd' base_path = ['protocols', 'isis'] -domain = 'FOOO' +domain = 'VyOS' net = '49.0001.1921.6800.1002.00' class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): def tearDown(self): self.cli_delete(base_path) self.cli_commit() # Check for running process self.assertTrue(process_named_running(PROCESS_NAME)) def test_isis_01_redistribute(self): prefix_list = 'EXPORT-ISIS' route_map = 'EXPORT-ISIS' rule = '10' self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'action', 'permit']) self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'prefix', '203.0.113.0/24']) self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'action', 'permit']) self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'match', 'ip', 'address', 'prefix-list', prefix_list]) - self.cli_set(base_path + ['domain', domain]) self.cli_set(base_path + ['net', net]) self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map]) interfaces = Section.interfaces('ethernet') for interface in interfaces: self.cli_set(base_path + ['interface', interface]) # Commit all changes self.cli_commit() # Verify all changes # XXX: FRR represents router isis with a trailing whitespace :/ tmp = self.getFRRconfig(f'router isis {domain} ') self.assertIn(f' net {net}', tmp) self.assertIn(f' redistribute ipv4 connected level-2 route-map {route_map}', tmp) for interface in interfaces: tmp = self.getFRRconfig(f'interface {interface}') self.assertIn(f' ip router isis {domain}', tmp) self.cli_delete(['policy']) def test_isis_02_vrfs(self): vrfs = ['red', 'green', 'blue'] # It is safe to assume that when the basic VRF test works, all other # IS-IS related features work, as we entirely inherit the CLI templates # and Jinja2 FRR template. table = '1000' vrf = 'red' vrf_base = ['vrf', 'name', vrf] vrf_iface = 'eth1' self.cli_set(vrf_base + ['table', table]) - self.cli_set(vrf_base + ['protocols', 'isis', 'domain', domain]) self.cli_set(vrf_base + ['protocols', 'isis', 'net', net]) self.cli_set(vrf_base + ['protocols', 'isis', 'interface', vrf_iface]) self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf]) # Also set a default VRF IS-IS config - self.cli_set(base_path + ['domain', domain]) self.cli_set(base_path + ['net', net]) self.cli_set(base_path + ['interface', 'eth0']) self.cli_commit() # Verify FRR isisd configuration # XXX: FRR represents router isis with a trailing whitespace :/ tmp = self.getFRRconfig(f'router isis {domain} ') self.assertIn(f'router isis {domain}', tmp) self.assertIn(f' net {net}', tmp) tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}') self.assertIn(f'router isis {domain} vrf {vrf}', tmp) self.assertIn(f' net {net}', tmp) self.cli_delete(['vrf', 'name', vrf]) self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf']) if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index adce00ee3..bcd9960ed 100755 --- a/src/conf_mode/protocols_isis.py +++ b/src/conf_mode/protocols_isis.py @@ -1,225 +1,222 @@ #!/usr/bin/env python3 # # Copyright (C) 2020-2021 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/>. import os from sys import exit from sys import argv from vyos.config import Config from vyos.configdict import dict_merge from vyos.configdict import node_changed from vyos.configverify import verify_interface_exists from vyos.util import call from vyos.util import dict_search from vyos.util import get_interface_config from vyos.template import render_to_string from vyos import ConfigError from vyos import frr from vyos import airbag airbag.enable() frr_daemon = 'isisd' def get_config(config=None): if config: conf = config else: conf = Config() vrf = None if len(argv) > 1: vrf = argv[1] base_path = ['protocols', 'isis'] # eqivalent of the C foo ? 'a' : 'b' statement base = vrf and ['vrf', 'name', vrf, 'protocols', 'isis'] or base_path isis = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True) # Assign the name of our VRF context. This MUST be done before the return # statement below, else on deletion we will delete the default instance # instead of the VRF instance. if vrf: isis['vrf'] = vrf # As we no re-use this Python handler for both VRF and non VRF instances for # IS-IS we need to find out if any interfaces changed so properly adjust # the FRR configuration and not by acctident change interfaces from a # different VRF. interfaces_removed = node_changed(conf, base + ['interface']) if interfaces_removed: isis['interface_removed'] = list(interfaces_removed) # Bail out early if configuration tree does not exist if not conf.exists(base): isis.update({'deleted' : ''}) return isis # We also need some additional information from the config, prefix-lists # and route-maps for instance. They will be used in verify() base = ['policy'] tmp = conf.get_config_dict(base, key_mangling=('-', '_')) # Merge policy dict into OSPF dict isis = dict_merge(tmp, isis) return isis def verify(isis): # bail out early - looks like removal from running config if not isis or 'deleted' in isis: return None - if 'domain' not in isis: - raise ConfigError('Routing domain name/tag must be set!') - if 'net' not in isis: raise ConfigError('Network entity is mandatory!') # last byte in IS-IS area address must be 0 tmp = isis['net'].split('.') if int(tmp[-1]) != 0: raise ConfigError('Last byte of IS-IS network entity title must always be 0!') # If interface not set if 'interface' not in isis: raise ConfigError('Interface used for routing updates is mandatory!') for interface in isis['interface']: verify_interface_exists(interface) if 'vrf' in isis: # If interface specific options are set, we must ensure that the # interface is bound to our requesting VRF. Due to the VyOS # priorities the interface is bound to the VRF after creation of # the VRF itself, and before any routing protocol is configured. vrf = isis['vrf'] tmp = get_interface_config(interface) if 'master' not in tmp or tmp['master'] != vrf: raise ConfigError(f'Interface {interface} is not a member of VRF {vrf}!') # If md5 and plaintext-password set at the same time if 'area_password' in isis: if {'md5', 'plaintext_password'} <= set(isis['encryption']): raise ConfigError('Can not use both md5 and plaintext-password for ISIS area-password!') # If one param from delay set, but not set others if 'spf_delay_ietf' in isis: required_timers = ['holddown', 'init_delay', 'long_delay', 'short_delay', 'time_to_learn'] exist_timers = [] for elm_timer in required_timers: if elm_timer in isis['spf_delay_ietf']: exist_timers.append(elm_timer) exist_timers = set(required_timers).difference(set(exist_timers)) if len(exist_timers) > 0: raise ConfigError('All types of delay must be specified: ' + ', '.join(exist_timers).replace('_', '-')) # If Redistribute set, but level don't set if 'redistribute' in isis: proc_level = isis.get('level','').replace('-','_') for afi in ['ipv4']: if afi not in isis['redistribute']: continue for proto, proto_config in isis['redistribute'][afi].items(): if 'level_1' not in proto_config and 'level_2' not in proto_config: raise ConfigError(f'Redistribute level-1 or level-2 should be specified in ' \ f'"protocols isis {process} redistribute {afi} {proto}"!') for redistr_level, redistr_config in proto_config.items(): if proc_level and proc_level != 'level_1_2' and proc_level != redistr_level: raise ConfigError(f'"protocols isis {process} redistribute {afi} {proto} {redistr_level}" ' \ f'can not be used with \"protocols isis {process} level {proc_level}\"') if 'route_map' in redistr_config: name = redistr_config['route_map'] tmp = name.replace('-', '_') if dict_search(f'policy.route_map.{tmp}', isis) == None: raise ConfigError(f'Route-map {name} does not exist!') # Segment routing checks if dict_search('segment_routing.global_block', isis): high_label_value = dict_search('segment_routing.global_block.high_label_value', isis) low_label_value = dict_search('segment_routing.global_block.low_label_value', isis) # If segment routing global block high value is blank, throw error if (low_label_value and not high_label_value) or (high_label_value and not low_label_value): raise ConfigError('Segment routing global block requires both low and high value!') # If segment routing global block low value is higher than the high value, throw error if int(low_label_value) > int(high_label_value): raise ConfigError('Segment routing global block low value must be lower than high value') if dict_search('segment_routing.local_block', isis): high_label_value = dict_search('segment_routing.local_block.high_label_value', isis) low_label_value = dict_search('segment_routing.local_block.low_label_value', isis) # If segment routing local block high value is blank, throw error if (low_label_value and not high_label_value) or (high_label_value and not low_label_value): raise ConfigError('Segment routing local block requires both high and low value!') # If segment routing local block low value is higher than the high value, throw error if int(low_label_value) > int(high_label_value): raise ConfigError('Segment routing local block low value must be lower than high value') return None def generate(isis): if not isis or 'deleted' in isis: isis['new_frr_config'] = '' return None isis['new_frr_config'] = render_to_string('frr/isis.frr.tmpl', isis) return None def apply(isis): # Save original configuration prior to starting any commit actions frr_cfg = frr.FRRConfig() frr_cfg.load_configuration(frr_daemon) # Generate empty helper string which can be ammended to FRR commands, # it will be either empty (default VRF) or contain the "vrf <name" statement vrf = '' if 'vrf' in isis: vrf = 'vrf ' + isis['vrf'] - frr_cfg.modify_section(f'^router isis \S+ {vrf}', '') + frr_cfg.modify_section(f'^router isis VyOS {vrf}', '') for key in ['interface', 'interface_removed']: if key not in isis: continue for interface in isis[key]: frr_cfg.modify_section(f'^interface {interface}{vrf}$', '') frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', isis['new_frr_config']) frr_cfg.commit_configuration(frr_daemon) # If FRR config is blank, rerun the blank commit x times due to frr-reload # behavior/bug not properly clearing out on one commit. if isis['new_frr_config'] == '': for a in range(5): frr_cfg.commit_configuration(frr_daemon) return None if __name__ == '__main__': try: c = get_config() verify(c) generate(c) apply(c) except ConfigError as e: print(e) exit(1) diff --git a/src/migration-scripts/isis/0-to-1 b/src/migration-scripts/isis/0-to-1 index 5f51f986e..6773f4009 100755 --- a/src/migration-scripts/isis/0-to-1 +++ b/src/migration-scripts/isis/0-to-1 @@ -1,60 +1,58 @@ #!/usr/bin/env python3 # # Copyright (C) 2021 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/>. # T3417: migrate IS-IS tagNode to node as we can only have one IS-IS process from sys import argv from sys import exit from vyos.configtree import ConfigTree if (len(argv) < 1): print("Must specify file name!") exit(1) file_name = argv[1] with open(file_name, 'r') as f: config_file = f.read() base = ['protocols', 'isis'] config = ConfigTree(config_file) if not config.exists(base): # Nothing to do exit(0) # Only one IS-IS process is supported, thus this operation is save -process = config.list_nodes(base) -isis_base = base + process +isis_base = base + config.list_nodes(base) # We need a temporary copy of the config tmp_base = ['protocols', 'isis2'] config.copy(isis_base, tmp_base) # Now it's save to delete the old configuration config.delete(base) # Rename temporary copy to new final config and set domain key config.rename(tmp_base, 'isis') -config.set(base + ['domain'], process[0]) try: with open(file_name, 'w') as f: f.write(config.to_string()) except OSError as e: print("Failed to save the modified config: {}".format(e)) sys.exit(1)