summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheeze_It <none@none.com>2021-01-03 15:52:10 -0700
committerCheeze_It <none@none.com>2021-01-05 10:06:25 -0700
commit8773a20c5a32c348ebc5ce958bd73d9ff79a07f3 (patch)
tree463a636929782e7f2da2ea56a60c3e8fc5fdcacf
parentf4625c9ee2f54992ed96f113ff52c5a9993ea769 (diff)
downloadvyos-1x-8773a20c5a32c348ebc5ce958bd73d9ff79a07f3.tar.gz
vyos-1x-8773a20c5a32c348ebc5ce958bd73d9ff79a07f3.zip
ISIS: T3156: Adding segment routing for ISIS
In this commit we add the segment routing portion for ISIS. There's also an additional check that is added so that the global block label ranges are properly configured. Also added traffic engineering configurations as well.
-rw-r--r--data/templates/frr/isis.frr.tmpl61
-rw-r--r--interface-definitions/protocols-isis.xml.in221
-rwxr-xr-xsrc/conf_mode/protocols_isis.py33
3 files changed, 312 insertions, 3 deletions
diff --git a/data/templates/frr/isis.frr.tmpl b/data/templates/frr/isis.frr.tmpl
index a1dae0c7c..0477f2599 100644
--- a/data/templates/frr/isis.frr.tmpl
+++ b/data/templates/frr/isis.frr.tmpl
@@ -31,6 +31,67 @@ router isis {{ process }}
{% 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 %}
diff --git a/interface-definitions/protocols-isis.xml.in b/interface-definitions/protocols-isis.xml.in
index 2ceb05180..2340079a6 100644
--- a/interface-definitions/protocols-isis.xml.in
+++ b/interface-definitions/protocols-isis.xml.in
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="utf-8"?>
<!-- Protocol IS-IS configuration -->
<interfaceDefinition>
<node name="protocols">
@@ -246,6 +246,225 @@
<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>
+ <completionHelp>
+ <list>&lt;x.x.x.x/x&gt; &lt;h:h:h:h:h:h:h:h/h&gt;</list>
+ </completionHelp>
+ </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>
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index 97ab79583..b7afad473 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -22,6 +22,7 @@ from vyos.config import Config
from vyos.configdict import node_changed
from vyos import ConfigError
from vyos.util import call
+from vyos.util import dict_search
from vyos.template import render
from vyos.template import render_to_string
from vyos import frr
@@ -48,7 +49,7 @@ def verify(isis):
# 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 definded')
+ raise ConfigError('Only one isis process can be defined')
# If network entity title (net) not defined
if 'net' not in isis_config:
@@ -63,7 +64,7 @@ def verify(isis):
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 deley set, but not set others
+ # 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 = []
@@ -85,6 +86,34 @@ def verify(isis):
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')
+
return None
def generate(isis):