summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2021-01-05 18:36:41 +0100
committerGitHub <noreply@github.com>2021-01-05 18:36:41 +0100
commit344e6d6a9074e2da8e5865f46b4122edfe1ef6a3 (patch)
treedde877dae0743fc813ccab5d52c51d0f2a2ae1ab
parentce809eee91aa2b7f2980dbfd191cdb9ad2947674 (diff)
parent8773a20c5a32c348ebc5ce958bd73d9ff79a07f3 (diff)
downloadvyos-1x-344e6d6a9074e2da8e5865f46b4122edfe1ef6a3.tar.gz
vyos-1x-344e6d6a9074e2da8e5865f46b4122edfe1ef6a3.zip
Merge pull request #667 from Cheeze-It/current
ISIS: T3156: Adding segment routing for ISIS
-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):