Page MenuHomeVyOS Platform

No OneTemporary

Size
132 KB
Referenced Files
None
Subscribers
None
diff --git a/data/templates/frr/isis.frr.tmpl b/data/templates/frr/isis.frr.tmpl
index 4460ab3b5..7f996b134 100644
--- a/data/templates/frr/isis.frr.tmpl
+++ b/data/templates/frr/isis.frr.tmpl
@@ -1,175 +1,175 @@
!
-router isis {{ process }}
+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 }}
- ip router isis {{ process }}
+interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
+ 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
new file mode 100644
index 000000000..8b753b082
--- /dev/null
+++ b/interface-definitions/include/isis/isis-common-config.xml.i
@@ -0,0 +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>
+<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/interface-definitions/protocols-isis.xml.in b/interface-definitions/protocols-isis.xml.in
index 0afa8dcb1..1bc890446 100644
--- a/interface-definitions/protocols-isis.xml.in
+++ b/interface-definitions/protocols-isis.xml.in
@@ -1,772 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<interfaceDefinition>
<node name="protocols">
<children>
- <tagNode name="isis" owner="${vyos_conf_scripts_dir}/protocols_isis.py">
+ <node name="isis" owner="${vyos_conf_scripts_dir}/protocols_isis.py">
<properties>
<help>Intermediate System to Intermediate System (IS-IS)</help>
<priority>610</priority>
- <valueHelp>
- <format>text(TAG)</format>
- <description>ISO Routing area tag</description>
- </valueHelp>
</properties>
<children>
- <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>
- <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 <include/isis/isis-common-config.xml.i>
</children>
- </tagNode>
+ </node>
</children>
</node>
</interfaceDefinition>
diff --git a/interface-definitions/vrf.xml.in b/interface-definitions/vrf.xml.in
index de605e89b..95428eb94 100644
--- a/interface-definitions/vrf.xml.in
+++ b/interface-definitions/vrf.xml.in
@@ -1,90 +1,99 @@
<?xml version="1.0"?>
<interfaceDefinition>
<node name="vrf" owner="${vyos_conf_scripts_dir}/vrf.py">
<properties>
<help>Virtual Routing and Forwarding</help>
<!-- must be before any interface creation -->
<priority>10</priority>
</properties>
<children>
<leafNode name="bind-to-all">
<properties>
<help>Enable binding services to all VRFs</help>
<valueless/>
</properties>
</leafNode>
<tagNode name="name">
<properties>
<help>Virtual Routing and Forwarding instance</help>
<constraint>
<validator name="vrf-name"/>
</constraint>
<constraintErrorMessage>VRF instance name must be 15 characters or less and can not\nbe named as regular network interfaces.\n</constraintErrorMessage>
<valueHelp>
<format>txt</format>
<description>VRF instance name</description>
</valueHelp>
</properties>
<children>
#include <include/interface/interface-description.xml.i>
#include <include/interface/interface-disable.xml.i>
<node name="protocols">
<properties>
<help>Routing protocol parameters</help>
</properties>
<children>
- <node name="static" owner="${vyos_conf_scripts_dir}/protocols_static.py $VAR(../../@)">
- <properties>
- <help>Static route parameters</help>
- <priority>481</priority>
- </properties>
- <children>
- #include <include/static/static-route.xml.i>
- #include <include/static/static-route6.xml.i>
- </children>
- </node>
<tagNode name="bgp" owner="${vyos_conf_scripts_dir}/protocols_bgp.py $VAR(../../@)">
<properties>
<help>Border Gateway Protocol (BGP)</help>
<priority>821</priority>
<valueHelp>
<format>u32:1-4294967294</format>
<description>Autonomous System Number</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-4294967294"/>
</constraint>
</properties>
<children>
#include <include/bgp/bgp-common-config.xml.i>
</children>
</tagNode>
+ <node name="isis" owner="${vyos_conf_scripts_dir}/protocols_isis.py $VAR(../../@)">
+ <properties>
+ <help>Intermediate System to Intermediate System (IS-IS)</help>
+ <priority>611</priority>
+ </properties>
+ <children>
+ #include <include/isis/isis-common-config.xml.i>
+ </children>
+ </node>
<node name="ospf" owner="${vyos_conf_scripts_dir}/protocols_ospf.py $VAR(../../@)">
<properties>
<help>Open Shortest Path First (OSPF)</help>
<priority>621</priority>
</properties>
<children>
#include <include/ospf/ospf-common-config.xml.i>
</children>
</node>
+ <node name="static" owner="${vyos_conf_scripts_dir}/protocols_static.py $VAR(../../@)">
+ <properties>
+ <help>Static route parameters</help>
+ <priority>481</priority>
+ </properties>
+ <children>
+ #include <include/static/static-route.xml.i>
+ #include <include/static/static-route6.xml.i>
+ </children>
+ </node>
</children>
</node>
<leafNode name="table">
<properties>
<help>Routing table associated with this instance</help>
<valueHelp>
<format>100-2147483647</format>
<description>Routing table ID</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 100-2147483647"/>
</constraint>
<constraintErrorMessage>VRF routing table must be in range from 100 to 2147483647</constraintErrorMessage>
</properties>
</leafNode>
</children>
</tagNode>
</children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/include/isis-common.xml.i b/op-mode-definitions/include/isis-common.xml.i
new file mode 100644
index 000000000..b1ee3e241
--- /dev/null
+++ b/op-mode-definitions/include/isis-common.xml.i
@@ -0,0 +1,179 @@
+<!-- included start from isis-common.xml.i -->
+<node name="database">
+ <properties>
+ <help>Show IS-IS link state database</help>
+ </properties>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</node>
+<tagNode name="database">
+ <properties>
+ <help>Show IS-IS link state database PDU</help>
+ <completionHelp>
+ <list>lsp-id detail</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<leafNode name="hostname">
+ <properties>
+ <help>Show IS-IS dynamic hostname mapping</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<node name="interface">
+ <properties>
+ <help>Show IS-IS interfaces</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</node>
+<tagNode name="interface">
+ <properties>
+ <help>Show specific IS-IS interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<node name="mpls-te">
+ <properties>
+ <help>Show IS-IS MPLS traffic engineering information</help>
+ </properties>
+ <children>
+ <leafNode name="router">
+ <properties>
+ <help>Show router information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ <leafNode name="interface">
+ <properties>
+ <help>Show interface information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ <tagNode name="interface">
+ <properties>
+ <help>Show specific IS-IS interface</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </tagNode>
+ </children>
+</node>
+<node name="neighbor">
+ <properties>
+ <help>Show IS-IS neighbor adjacencies</help>
+ </properties>
+ <children>
+ <leafNode name="detail">
+ <properties>
+ <help>Show detailed information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ <command>vtysh -c "show isis neighbor"</command>
+</node>
+<tagNode name="neighbor">
+ <properties>
+ <help>Show specific IS-IS neighbor adjacency </help>
+ <completionHelp>
+ <list>system-id</list>
+ </completionHelp>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</tagNode>
+<node name="route">
+ <properties>
+ <help>Show IS-IS routing table</help>
+ </properties>
+ <children>
+ <leafNode name="level-1">
+ <properties>
+ <help>Show level-1 routes</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ <leafNode name="level-2">
+ <properties>
+ <help>Show level-2 routes</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ <command>vtysh -c "show isis route"</command>
+</node>
+<node name="segment-routing">
+ <properties>
+ <help>Show IS-IS Segment-Routing (SPRING) information</help>
+ </properties>
+ <children>
+ <leafNode name="node">
+ <properties>
+ <help>Show node information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ <leafNode name="prefix-sids">
+ <properties>
+ <help>Show prefix segment IDs</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+</node>
+<leafNode name="spf-delay-ietf">
+ <properties>
+ <help>Show IS-IS SPF delay parameters</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<leafNode name="summary">
+ <properties>
+ <help>Show IS-IS information summary</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</leafNode>
+<node name="topology">
+ <properties>
+ <help>Show IS-IS paths to Intermediate Systems</help>
+ </properties>
+ <children>
+ <leafNode name="level-1">
+ <properties>
+ <help>Show level-1 routes</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ <leafNode name="level-2">
+ <properties>
+ <help>Show level-2 routes</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </leafNode>
+ </children>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+</node>
+<!-- included end -->
diff --git a/op-mode-definitions/show-isis.xml.in b/op-mode-definitions/show-isis.xml.in
index 890d511e2..202e3214b 100644
--- a/op-mode-definitions/show-isis.xml.in
+++ b/op-mode-definitions/show-isis.xml.in
@@ -1,191 +1,27 @@
<?xml version="1.0"?>
<interfaceDefinition>
<node name="show">
<children>
<node name="isis">
<properties>
- <help>IS-IS routing protocol</help>
+ <help>Show IS-IS routing protocol</help>
</properties>
<children>
- <node name="database">
+ #include <include/isis-common.xml.i>
+ <tagNode name="vrf">
<properties>
- <help>Show IS-IS link state database</help>
- </properties>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed information</help>
- </properties>
- <command>vtysh -c "show isis database detail"</command>
- </leafNode>
- </children>
- <command>vtysh -c "show isis database"</command>
- </node>
- <tagNode name="database">
- <properties>
- <help>Show IS-IS link state database PDU</help>
- <completionHelp>
- <list>lsp-id detail</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show isis database $4"</command>
- </tagNode>
- <leafNode name="hostname">
- <properties>
- <help>Show IS-IS dynamic hostname mapping</help>
- </properties>
- <command>vtysh -c "show isis hostname"</command>
- </leafNode>
- <node name="interface">
- <properties>
- <help>Show IS-IS interfaces</help>
+ <help>Show IS-IS routing protocol for given VRF</help>
<completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
+ <path>vrf name</path>
+ <list>all</list>
</completionHelp>
</properties>
<children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed information</help>
- </properties>
- <command>vtysh -c "show isis interface detail"</command>
- </leafNode>
- </children>
- <command>vtysh -c "show isis interface"</command>
- </node>
- <tagNode name="interface">
- <properties>
- <help>Show specific IS-IS interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
- </completionHelp>
- </properties>
- <command>vtysh -c "show isis interface $4"</command>
- </tagNode>
- <node name="traffic-engineering">
- <properties>
- <help>Show IS-IS MPLS traffic engineering information</help>
- </properties>
- <children>
- <leafNode name="router">
- <properties>
- <help>Show router information</help>
- </properties>
- <command>vtysh -c "show isis mpls-te router"</command>
- </leafNode>
- <leafNode name="interface">
- <properties>
- <help>Show interface information</help>
- </properties>
- <command>vtysh -c "show isis mpls-te interface"</command>
- </leafNode>
- <tagNode name="interface">
- <properties>
- <help>Show specific IS-IS interface</help>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
- </completionHelp>
- </properties>
- <command>vtysh -c "show isis mpls-te interface $5"</command>
- </tagNode>
- </children>
- </node>
- <node name="neighbor">
- <properties>
- <help>Show IS-IS neighbor adjacencies</help>
- </properties>
- <children>
- <leafNode name="detail">
- <properties>
- <help>Show detailed information</help>
- </properties>
- <command>vtysh -c "show isis neighbor detail"</command>
- </leafNode>
+ #include <include/isis-common.xml.i>
</children>
- <command>vtysh -c "show isis neighbor"</command>
- </node>
- <tagNode name="neighbor">
- <properties>
- <help>Show specific IS-IS neighbor adjacency </help>
- <completionHelp>
- <list>system-id</list>
- </completionHelp>
- </properties>
- <command>vtysh -c "show isis neighbor $4"</command>
</tagNode>
- <node name="route">
- <properties>
- <help>Show IS-IS routing table</help>
- </properties>
- <children>
- <leafNode name="level-1">
- <properties>
- <help>Show level-1 routes</help>
- </properties>
- <command>vtysh -c "show isis route level-1"</command>
- </leafNode>
- <leafNode name="level-2">
- <properties>
- <help>Show level-2 routes</help>
- </properties>
- <command>vtysh -c "show isis route level-2"</command>
- </leafNode>
- </children>
- <command>vtysh -c "show isis route"</command>
- </node>
- <node name="segment-routing">
- <properties>
- <help>Show IS-IS Segment-Routing (SPRING) information</help>
- </properties>
- <children>
- <leafNode name="node">
- <properties>
- <help>Show node information</help>
- </properties>
- <command>vtysh -c "show isis segment-routing node"</command>
- </leafNode>
- <leafNode name="prefix-sids">
- <properties>
- <help>Show prefix segment IDs</help>
- </properties>
- <command>vtysh -c "show isis segment-routing prefix-sids"</command>
- </leafNode>
- </children>
- </node>
- <leafNode name="spf-delay">
- <properties>
- <help>Show IS-IS SPF delay parameters</help>
- </properties>
- <command>vtysh -c "show isis spf-delay-ietf"</command>
- </leafNode>
- <leafNode name="summary">
- <properties>
- <help>Show IS-IS information summary</help>
- </properties>
- <command>vtysh -c "show isis summary"</command>
- </leafNode>
- <node name="topology">
- <properties>
- <help>Show IS-IS paths to Intermediate Systems</help>
- </properties>
- <children>
- <leafNode name="level-1">
- <properties>
- <help>Show level-1 routes</help>
- </properties>
- <command>vtysh -c "show isis topology level-1"</command>
- </leafNode>
- <leafNode name="level-2">
- <properties>
- <help>Show level-2 routes</help>
- </properties>
- <command>vtysh -c "show isis topology level-2"</command>
- </leafNode>
- </children>
- <command>vtysh -c "show isis topology"</command>
- </node>
</children>
</node>
</children>
</node>
</interfaceDefinition>
diff --git a/op-mode-definitions/show-zebra.xml.in b/op-mode-definitions/show-zebra.xml.in
new file mode 100644
index 000000000..b0ad37f49
--- /dev/null
+++ b/op-mode-definitions/show-zebra.xml.in
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<interfaceDefinition>
+ <node name="show">
+ <children>
+ <node name="zebra">
+ <properties>
+ <help>Zebra routing information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ <children>
+ <node name="client">
+ <properties>
+ <help>Client information </help>
+ </properties>
+ <children>
+ <node name="summary">
+ <properties>
+ <help>Brief Summary</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </node>
+ <node name="dplane">
+ <properties>
+ <help>Zebra dataplane information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ <node name="router">
+ <properties>
+ <help>Zebra Router Information</help>
+ </properties>
+ <children>
+ <node name="table">
+ <properties>
+ <help>Table Information about this Zebra Router</help>
+ </properties>
+ <children>
+ <node name="summary">
+ <properties>
+ <help>Summary Information</help>
+ </properties>
+ <command>${vyos_op_scripts_dir}/vtysh_wrapper.sh $@</command>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+ </children>
+ </node>
+</interfaceDefinition>
diff --git a/smoketest/configs/isis-small b/smoketest/configs/isis-small
new file mode 100644
index 000000000..2c42ac9c4
--- /dev/null
+++ b/smoketest/configs/isis-small
@@ -0,0 +1,105 @@
+interfaces {
+ dummy dum0 {
+ address 203.0.113.1/24
+ }
+ ethernet eth0 {
+ duplex auto
+ speed auto
+ }
+ ethernet eth1 {
+ address 192.0.2.1/24
+ duplex auto
+ speed auto
+ }
+ ethernet eth2 {
+ duplex auto
+ speed auto
+ }
+ ethernet eth3 {
+ duplex auto
+ speed auto
+ }
+}
+policy {
+ prefix-list EXPORT-ISIS {
+ rule 10 {
+ action permit
+ prefix 203.0.113.0/24
+ }
+ }
+ route-map EXPORT-ISIS {
+ rule 10 {
+ action permit
+ match {
+ ip {
+ address {
+ prefix-list EXPORT-ISIS
+ }
+ }
+ }
+ }
+ }
+}
+protocols {
+ isis FOO {
+ interface eth1 {
+ bfd
+ }
+ net 49.0001.1921.6800.1002.00
+ redistribute {
+ ipv4 {
+ connected {
+ level-2 {
+ route-map EXPORT-ISIS
+ }
+ }
+ }
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 200
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.io
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$2Ta6TWHd/U$NmrX0x9kexCimeOcYK1MfhMpITF9ELxHcaBU/znBq.X2ukQOj61fVI2UYP/xBzP4QtiTcdkgs7WOQMHWsRymO/
+ plaintext-password ""
+ }
+ level admin
+ }
+ }
+ ntp {
+ server 0.pool.ntp.org {
+ }
+ server 1.pool.ntp.org {
+ }
+ server 2.pool.ntp.org {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+ time-zone Europe/Berlin
+}
+
+
+// Warning: Do not remove the following line.
+// vyos-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack@1:conntrack-sync@1:dhcp-relay@2:dhcp-server@5:dhcpv6-server@1:dns-forwarding@3:firewall@5:https@2:interfaces@18:ipoe-server@1:ipsec@5:l2tp@3:lldp@1:mdns@1:nat@5:ntp@1:pppoe-server@5:pptp@2:qos@1:quagga@7:rpki@1:salt@1:snmp@2:ssh@2:sstp@3:system@20:vrrp@2:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2:zone-policy@1"
+// Release version: 1.3.0-rc1
+
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
new file mode 100755
index 000000000..10c722eca
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -0,0 +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 = '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 + ['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', '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 + ['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/smoketest/scripts/cli/test_protocols_ospf.py b/smoketest/scripts/cli/test_protocols_ospf.py
index 385f50918..8d94c86cb 100755
--- a/smoketest/scripts/cli/test_protocols_ospf.py
+++ b/smoketest/scripts/cli/test_protocols_ospf.py
@@ -1,322 +1,321 @@
#!/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.ifconfig import Section
from vyos.util import process_named_running
PROCESS_NAME = 'ospfd'
base_path = ['protocols', 'ospf']
route_map = 'foo-bar-baz10'
class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase):
def setUp(self):
self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
self.cli_set(['policy', 'route-map', route_map, 'rule', '20', 'action', 'permit'])
def tearDown(self):
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
self.cli_delete(['policy', 'route-map', route_map])
self.cli_delete(base_path)
self.cli_commit()
def test_ospf_01_defaults(self):
# commit changes
self.cli_set(base_path)
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
def test_ospf_02_simple(self):
router_id = '127.0.0.1'
abr_type = 'ibm'
bandwidth = '1000'
metric = '123'
self.cli_set(base_path + ['auto-cost', 'reference-bandwidth', bandwidth])
self.cli_set(base_path + ['parameters', 'router-id', router_id])
self.cli_set(base_path + ['parameters', 'abr-type', abr_type])
self.cli_set(base_path + ['log-adjacency-changes', 'detail'])
self.cli_set(base_path + ['default-metric', metric])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' auto-cost reference-bandwidth {bandwidth}', frrconfig)
self.assertIn(f' ospf router-id {router_id}', frrconfig)
self.assertIn(f' ospf abr-type {abr_type}', frrconfig)
self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
self.assertIn(f' default-metric {metric}', frrconfig)
def test_ospf_03_access_list(self):
acl = '100'
seq = '10'
protocols = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'action', 'permit'])
self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'source', 'any'])
self.cli_set(['policy', 'access-list', acl, 'rule', seq, 'destination', 'any'])
for ptotocol in protocols:
self.cli_set(base_path + ['access-list', acl, 'export', ptotocol])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
for ptotocol in protocols:
self.assertIn(f' distribute-list {acl} out {ptotocol}', frrconfig) # defaults
self.cli_delete(['policy', 'access-list', acl])
def test_ospf_04_default_originate(self):
seq = '100'
metric = '50'
metric_type = '1'
self.cli_set(base_path + ['default-information', 'originate', 'metric', metric])
self.cli_set(base_path + ['default-information', 'originate', 'metric-type', metric_type])
self.cli_set(base_path + ['default-information', 'originate', 'route-map', route_map])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
self.assertIn(f' default-information originate metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
# Now set 'always'
self.cli_set(base_path + ['default-information', 'originate', 'always'])
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f' default-information originate always metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
def test_ospf_05_options(self):
global_distance = '128'
intra_area = '100'
inter_area = '110'
external = '120'
on_startup = '30'
on_shutdown = '60'
refresh = '50'
self.cli_set(base_path + ['distance', 'global', global_distance])
self.cli_set(base_path + ['distance', 'ospf', 'external', external])
self.cli_set(base_path + ['distance', 'ospf', 'intra-area', intra_area])
self.cli_set(base_path + ['max-metric', 'router-lsa', 'on-startup', on_startup])
self.cli_set(base_path + ['max-metric', 'router-lsa', 'on-shutdown', on_shutdown])
self.cli_set(base_path + ['mpls-te', 'enable'])
self.cli_set(base_path + ['refresh', 'timers', refresh])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' mpls-te on', frrconfig)
self.assertIn(f' mpls-te router-address 0.0.0.0', frrconfig) # default
self.assertIn(f' distance {global_distance}', frrconfig)
self.assertIn(f' distance ospf intra-area {intra_area} external {external}', frrconfig)
self.assertIn(f' max-metric router-lsa on-startup {on_startup}', frrconfig)
self.assertIn(f' max-metric router-lsa on-shutdown {on_shutdown}', frrconfig)
self.assertIn(f' refresh timer {refresh}', frrconfig)
# enable inter-area
self.cli_set(base_path + ['distance', 'ospf', 'inter-area', inter_area])
self.cli_commit()
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f' distance ospf intra-area {intra_area} inter-area {inter_area} external {external}', frrconfig)
def test_ospf_06_neighbor(self):
priority = '10'
poll_interval = '20'
neighbors = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
for neighbor in neighbors:
self.cli_set(base_path + ['neighbor', neighbor, 'priority', priority])
self.cli_set(base_path + ['neighbor', neighbor, 'poll-interval', poll_interval])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
for neighbor in neighbors:
self.assertIn(f' neighbor {neighbor} priority {priority} poll-interval {poll_interval}', frrconfig) # default
def test_ospf_07_passive_interface(self):
self.cli_set(base_path + ['passive-interface', 'default'])
interfaces = Section.interfaces('ethernet')
for interface in interfaces:
self.cli_set(base_path + ['passive-interface-exclude', interface])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' passive-interface default', frrconfig) # default
for interface in interfaces:
self.assertIn(f' no passive-interface {interface}', frrconfig) # default
def test_ospf_08_redistribute(self):
metric = '15'
metric_type = '1'
redistribute = ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']
for protocol in redistribute:
self.cli_set(base_path + ['redistribute', protocol, 'metric', metric])
self.cli_set(base_path + ['redistribute', protocol, 'route-map', route_map])
if protocol not in ['kernel', 'static']:
self.cli_set(base_path + ['redistribute', protocol, 'metric-type', metric_type])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
for protocol in redistribute:
if protocol in ['kernel', 'static']:
self.assertIn(f' redistribute {protocol} metric {metric} route-map {route_map}', frrconfig)
else:
self.assertIn(f' redistribute {protocol} metric {metric} metric-type {metric_type} route-map {route_map}', frrconfig)
def test_ospf_09_virtual_link(self):
networks = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']
area = '10'
shortcut = 'enable'
virtual_link = '192.0.2.1'
hello = '6'
retransmit = '5'
transmit = '5'
dead = '40'
self.cli_set(base_path + ['area', area, 'shortcut', shortcut])
self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'hello-interval', hello])
self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'retransmit-interval', retransmit])
self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'transmit-delay', transmit])
self.cli_set(base_path + ['area', area, 'virtual-link', virtual_link, 'dead-interval', dead])
for network in networks:
self.cli_set(base_path + ['area', area, 'network', network])
# commit changes
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' area {area} shortcut {shortcut}', frrconfig)
self.assertIn(f' area {area} virtual-link {virtual_link} hello-interval {hello} retransmit-interval {retransmit} transmit-delay {transmit} dead-interval {dead}', frrconfig)
for network in networks:
self.assertIn(f' network {network} area {area}', frrconfig)
def test_ospf_10_interface_configureation(self):
interfaces = Section.interfaces('ethernet')
password = 'vyos1234'
bandwidth = '10000'
cost = '150'
network = 'point-to-point'
priority = '200'
for interface in interfaces:
self.cli_set(base_path + ['interface', interface, 'authentication', 'plaintext-password', password])
self.cli_set(base_path + ['interface', interface, 'bandwidth', bandwidth])
self.cli_set(base_path + ['interface', interface, 'bfd'])
self.cli_set(base_path + ['interface', interface, 'cost', cost])
self.cli_set(base_path + ['interface', interface, 'mtu-ignore'])
self.cli_set(base_path + ['interface', interface, 'network', network])
self.cli_set(base_path + ['interface', interface, 'priority', priority])
# commit changes
self.cli_commit()
for interface in interfaces:
config = self.getFRRconfig(f'interface {interface}')
self.assertIn(f'interface {interface}', config)
self.assertIn(f' ip ospf authentication-key {password}', config)
self.assertIn(f' ip ospf bfd', config)
self.assertIn(f' ip ospf cost {cost}', config)
self.assertIn(f' ip ospf mtu-ignore', config)
self.assertIn(f' ip ospf network {network}', config)
self.assertIn(f' ip ospf priority {priority}', config)
self.assertIn(f' bandwidth {bandwidth}', config)
def test_ospf_11_vrfs(self):
- vrfs = ['red', 'green', 'blue']
# It is safe to assume that when the basic VRF test works, all
# other OSPF related features work, as we entirely inherit the CLI
# templates and Jinja2 FRR template.
table = '1000'
- for vrf in vrfs:
- vrf_base = ['vrf', 'name', vrf]
- self.cli_set(vrf_base + ['table', table])
- self.cli_set(vrf_base + ['protocols', 'ospf'])
- table = str(int(table) + 1000)
+ vrf = 'blue'
+ vrf_base = ['vrf', 'name', vrf]
+ vrf_iface = 'eth1'
+ self.cli_set(vrf_base + ['table', table])
+ self.cli_set(vrf_base + ['protocols', 'ospf', 'interface', vrf_iface])
+ self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf])
# Also set a default VRF OSPF config
self.cli_set(base_path)
self.cli_commit()
# Verify FRR ospfd configuration
frrconfig = self.getFRRconfig('router ospf')
self.assertIn(f'router ospf', frrconfig)
self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
- for vrf in vrfs:
- frrconfig = self.getFRRconfig(f'router ospf vrf {vrf}')
- self.assertIn(f'router ospf vrf {vrf}', frrconfig)
- self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
- self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
-
- self.cli_delete(['vrf', 'name', vrf])
+ frrconfig = self.getFRRconfig(f'router ospf vrf {vrf}')
+ self.assertIn(f'router ospf vrf {vrf}', frrconfig)
+ self.assertIn(f' auto-cost reference-bandwidth 100', frrconfig)
+ self.assertIn(f' timers throttle spf 200 1000 10000', frrconfig) # defaults
+ 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 b7afad473..bcd9960ed 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -1,168 +1,222 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2020 VyOS maintainers and contributors
+# 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 import ConfigError
+from vyos.configverify import verify_interface_exists
from vyos.util import call
from vyos.util import dict_search
-from vyos.template import render
+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()
- base = ['protocols', 'isis']
- isis = conf.get_config_dict(base, key_mangling=('-', '_'), get_first_key=True)
+ 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:
+ if not isis or 'deleted' in isis:
return None
- for process, isis_config in isis.items():
- # If more then one isis process is defined (Frr only supports one)
- # http://docs.frrouting.org/en/latest/isisd.html#isis-router
- if len(isis) > 1:
- raise ConfigError('Only one isis process can be defined')
-
- # If network entity title (net) not defined
- if 'net' not in isis_config:
- raise ConfigError('ISIS net format iso is mandatory!')
-
- # If interface not set
- if 'interface' not in isis_config:
- raise ConfigError('ISIS interface is mandatory!')
-
- # If md5 and plaintext-password set at the same time
- if 'area_password' in isis_config:
- if {'md5', 'plaintext_password'} <= set(isis_config['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_config:
- 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_config['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_config:
- proc_level = isis_config.get('level','').replace('-','_')
- for proto, proto_config in isis_config.get('redistribute', {}).get('ipv4', {}).items():
+ 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('Redistribute level-1 or level-2 should be specified in \"protocols isis {} redistribute ipv4 {}\"'.format(process, proto))
- for redistribute_level in proto_config.keys():
- if proc_level and proc_level != 'level_1_2' and proc_level != redistribute_level:
- raise ConfigError('\"protocols isis {0} redistribute ipv4 {2} {3}\" cannot be used with \"protocols isis {0} level {1}\"'.format(process, proc_level, proto, redistribute_level))
-
- # Segment routing checks
- if dict_search('segment_routing', isis_config):
- if dict_search('segment_routing.global_block', isis_config):
- high_label_value = dict_search('segment_routing.global_block.high_label_value', isis_config)
- low_label_value = dict_search('segment_routing.global_block.low_label_value', isis_config)
- # If segment routing global block high value is blank, throw error
- if low_label_value and not high_label_value:
- raise ConfigError('Segment routing global block high value must not be left blank')
- # If segment routing global block low value is blank, throw error
- if high_label_value and not low_label_value:
- raise ConfigError('Segment routing global block low value must not be left blank')
- # 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_config):
- high_label_value = dict_search('segment_routing.local_block.high_label_value', isis_config)
- low_label_value = dict_search('segment_routing.local_block.low_label_value', isis_config)
- # If segment routing local block high value is blank, throw error
- if low_label_value and not high_label_value:
- raise ConfigError('Segment routing local block high value must not be left blank')
- # If segment routing local block low value is blank, throw error
- if high_label_value and not low_label_value:
- raise ConfigError('Segment routing local block low value must not be left blank')
- # 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')
+ 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:
+ if not isis or 'deleted' in isis:
isis['new_frr_config'] = ''
return None
- # only one ISIS process is supported, so we can directly send the first key
- # of the config dict
- process = list(isis.keys())[0]
- isis[process]['process'] = process
-
- isis['new_frr_config'] = render_to_string('frr/isis.frr.tmpl',
- isis[process])
-
+ 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(daemon='isisd')
- frr_cfg.modify_section(r'interface \S+', '')
- frr_cfg.modify_section(f'router isis \S+', '')
+ 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 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(daemon='isisd')
+ 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(daemon='isisd')
-
- # Debugging
- '''
- print('')
- print('--------- DEBUGGING ----------')
- print(f'Existing config:\n{frr_cfg["original_config"]}\n\n')
- print(f'Replacement config:\n{isis["new_frr_config"]}\n\n')
- print(f'Modified config:\n{frr_cfg["modified_config"]}\n\n')
- '''
+ 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/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index 08347aa52..a655eaeca 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -1,213 +1,213 @@
#!/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 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_route_maps
from vyos.configverify import verify_interface_exists
from vyos.template import render_to_string
from vyos.util import call
from vyos.util import dict_search
from vyos.util import get_interface_config
from vyos.xml import defaults
from vyos import ConfigError
from vyos import frr
from vyos import airbag
airbag.enable()
frr_daemon = 'ospfd'
def get_config(config=None):
if config:
conf = config
else:
conf = Config()
vrf = None
if len(argv) > 1:
vrf = argv[1]
base_path = ['protocols', 'ospf']
# eqivalent of the C foo ? 'a' : 'b' statement
base = vrf and ['vrf', 'name', vrf, 'protocols', 'ospf'] or base_path
ospf = 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: ospf['vrf'] = vrf
# As we no re-use this Python handler for both VRF and non VRF instances for
# OSPF 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:
ospf['interface_removed'] = list(interfaces_removed)
# Bail out early if configuration tree does not exist
if not conf.exists(base):
ospf.update({'deleted' : ''})
return ospf
# We have gathered the dict representation of the CLI, but there are default
# options which we need to update into the dictionary retrived.
# XXX: Note that we can not call defaults(base), as defaults does not work
# on an instance of a tag node. As we use the exact same CLI definition for
# both the non-vrf and vrf version this is absolutely safe!
default_values = defaults(base_path)
# We have to cleanup the default dict, as default values could enable features
# which are not explicitly enabled on the CLI. Example: default-information
# originate comes with a default metric-type of 2, which will enable the
# entire default-information originate tree, even when not set via CLI so we
# need to check this first and probably drop that key.
if dict_search('default_information.originate', ospf) is None:
del default_values['default_information']
if dict_search('area.area_type.nssa', ospf) is None:
del default_values['area']['area_type']['nssa']
if 'mpls_te' not in ospf:
del default_values['mpls_te']
for protocol in ['bgp', 'connected', 'isis', 'kernel', 'rip', 'static']:
if dict_search(f'redistribute.{protocol}', ospf) is None:
del default_values['redistribute'][protocol]
# XXX: T2665: we currently have no nice way for defaults under tag nodes,
# clean them out and add them manually :(
del default_values['neighbor']
del default_values['area']['virtual_link']
del default_values['interface']
# merge in remaining default values
ospf = dict_merge(default_values, ospf)
if 'neighbor' in ospf:
default_values = defaults(base + ['neighbor'])
for neighbor in ospf['neighbor']:
ospf['neighbor'][neighbor] = dict_merge(default_values, ospf['neighbor'][neighbor])
if 'area' in ospf:
default_values = defaults(base + ['area', 'virtual-link'])
for area, area_config in ospf['area'].items():
if 'virtual_link' in area_config:
print(default_values)
for virtual_link in area_config['virtual_link']:
ospf['area'][area]['virtual_link'][virtual_link] = dict_merge(
default_values, ospf['area'][area]['virtual_link'][virtual_link])
if 'interface' in ospf:
for interface in ospf['interface']:
# We need to reload the defaults on every pass b/c of
# hello-multiplier dependency on dead-interval
default_values = defaults(base + ['interface'])
# If hello-multiplier is set, we need to remove the default from
# dead-interval.
if 'hello_multiplier' in ospf['interface'][interface]:
del default_values['dead_interval']
ospf['interface'][interface] = dict_merge(default_values,
ospf['interface'][interface])
# 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
ospf = dict_merge(tmp, ospf)
return ospf
def verify(ospf):
if not ospf:
return None
verify_route_maps(ospf)
if 'interface' in ospf:
for interface in ospf['interface']:
verify_interface_exists(interface)
# One can not use dead-interval and hello-multiplier at the same
# time. FRR will only activate the last option set via CLI.
if {'hello_multiplier', 'dead_interval'} <= set(ospf['interface'][interface]):
raise ConfigError(f'Can not use hello-multiplier and dead-interval ' \
f'concurrently for {interface}!')
if 'vrf' in ospf:
- # 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.
+ # 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 = ospf['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}!')
return None
def generate(ospf):
if not ospf or 'deleted' in ospf:
ospf['new_frr_config'] = ''
return None
ospf['new_frr_config'] = render_to_string('frr/ospf.frr.tmpl', ospf)
return None
def apply(ospf):
# 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 ospf:
- vrf = ospf['vrf']
- frr_cfg.modify_section(f'^router ospf vrf {vrf}$', '')
- else:
- frr_cfg.modify_section('^router ospf$', '')
+ vrf = ' vrf ' + ospf['vrf']
+ frr_cfg.modify_section(f'^router ospf{vrf}$', '')
for key in ['interface', 'interface_removed']:
if key not in ospf:
continue
for interface in ospf[key]:
- frr_cfg.modify_section(f'^interface {interface}$', '')
+ frr_cfg.modify_section(f'^interface {interface}{vrf}$', '')
frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', ospf['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 ospf['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
new file mode 100755
index 000000000..6773f4009
--- /dev/null
+++ b/src/migration-scripts/isis/0-to-1
@@ -0,0 +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
+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')
+
+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)

File Metadata

Mime Type
text/x-diff
Expires
Fri, Nov 6, 7:08 AM (15 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4640112
Default Alt Text
(132 KB)

Event Timeline