From 1d6cb2d5587e352af6fd73a7703961d7a8bad189 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 21 Mar 2021 12:10:08 +0100 Subject: smoketest: add initial IS-IS testcase --- smoketest/scripts/cli/test_protocols_isis.py | 71 ++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100755 smoketest/scripts/cli/test_protocols_isis.py (limited to 'smoketest/scripts/cli') diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py new file mode 100755 index 000000000..765e0ef4e --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -0,0 +1,71 @@ +#!/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 . + +import unittest + +from base_vyostest_shim import VyOSUnitTestSHIM +from vyos.configsession import ConfigSession +from vyos.configsession import ConfigSessionError +from vyos.ifconfig import Section +from vyos.util import process_named_running + +PROCESS_NAME = 'isisd' +base_path = ['protocols', 'isis'] + +domain = 'FOOO' +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_redistribute(self): + prefix_list = 'EXPORT-ISIS' + route_map = 'EXPORT-ISIS' + rule = '10' + self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'action', 'permit']) + self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'prefix', '203.0.113.0/24']) + self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'action', 'permit']) + self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'match', 'ip', 'address', 'prefix-list', prefix_list]) + + self.cli_set(base_path + ['domain', domain]) + self.cli_set(base_path + ['net', net]) + self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map]) + + interfaces = Section.interfaces('ethernet') + for interface in interfaces: + self.cli_set(base_path + ['interface', interface]) + + # Commit all changes + self.cli_commit() + + # Verify all changes + tmp = self.getFRRconfig(f'router isis {domain}', end='') + 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']) + +if __name__ == '__main__': + unittest.main(verbosity=2) -- cgit v1.2.3 From a234f616b9fff24b74f2b33dc83cf7c7edef3342 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 21 Mar 2021 13:33:06 +0100 Subject: isis: T3417: add VRF support VRF support can be tested using: set vrf name red table 1000 set vrf name red protocols isis domain FOOO set vrf name red protocols isis net 49.0001.1921.6800.1002.00 set vrf name red protocols isis interface eth1 --- data/templates/frr/isis.frr.tmpl | 4 +- .../include/isis/isis-common-config.xml.i | 764 +++++++++++++++++++++ interface-definitions/protocols-isis.xml.in | 763 +------------------- interface-definitions/vrf.xml.in | 29 +- smoketest/scripts/cli/test_protocols_isis.py | 40 +- src/conf_mode/protocols_isis.py | 72 +- 6 files changed, 887 insertions(+), 785 deletions(-) create mode 100644 interface-definitions/include/isis/isis-common-config.xml.i (limited to 'smoketest/scripts/cli') diff --git a/data/templates/frr/isis.frr.tmpl b/data/templates/frr/isis.frr.tmpl index d4500403c..da098abac 100644 --- a/data/templates/frr/isis.frr.tmpl +++ b/data/templates/frr/isis.frr.tmpl @@ -1,5 +1,5 @@ ! -router isis {{ domain }} +router isis {{ domain }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} net {{ net }} {% if dynamic_hostname is defined %} hostname dynamic @@ -133,7 +133,7 @@ router isis {{ domain }} ! {% if interface is defined and interface is not none %} {% for iface, iface_config in interface.items() %} -interface {{ iface }} +interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} ip router isis {{ domain }} {% if iface_config.bfd is defined %} isis bfd 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..94a6e3592 --- /dev/null +++ b/interface-definitions/include/isis/isis-common-config.xml.i @@ -0,0 +1,764 @@ + + + + Configure the authentication password for an area + + + + + Plain-text authentication type + + txt + Level-wide password + + + + + + MD5 authentication type + + txt + Level-wide password + + + + + + + + Control distribution of default information + + + + + Distribute a default route + + + + + Distribute default route for IPv4 + + + + + Distribute default route into level-1 + + + + + + Distribute default route into level-2 + + + + + + + + Distribute default route for IPv6 + + + + + Distribute default route into level-1 + + always + + + always + Always advertise default route + + + + + + Distribute default route into level-2 + + always + + + always + Always advertise default route + + + + + + + + + + + + Domain name used for this instance + + txt + IS-IS routing area domain/tag + + + + + + Set the authentication password for a routing domain + + + + + Plain-text authentication type + + txt + Level-wide password + + + + + + + + + Dynamic hostname for IS-IS + + + + + + IS-IS level number + + level-1 level-1-2 level-2 + + + level-1 + Act as a station router + + + level-1-2 + Act as both a station and an area router + + + level-2 + Act as an area router + + + (level-1|level-1-2|level-2) + + + + + + Minimum interval between regenerating same LSP + + u32:1-120 + Minimum interval in seconds + + + + + + + + + Configure the maximum size of generated LSPs + + u32:128-4352 + Maximum size of generated LSPs + + + + + + + + + LSP refresh interval + + u32:1-65235 + LSP refresh interval in seconds + + + + + + + + + Maximum LSP lifetime + + u32:350-65535 + LSP lifetime in seconds + + + + + + + + + Use old-style (ISO 10589) or new-style packet formats + + narrow transition wide + + + narrow + Use old style of TLVs with narrow metric + + + transition + Send and accept both styles of TLVs during transition + + + wide + Use new style of TLVs to carry wider metric + + + (narrow|transition|wide) + + + + + + A Network Entity Title for this process (ISO only) + + XX.XXXX. ... .XXX.XX + Network entity title (NET) + + + [a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2} + + + + + + Use the RFC 6232 purge-originator + + + + + + Show IS-IS neighbor adjacencies + + + + + Enable MPLS traffic engineering extensions + + + + + + + MPLS traffic engineering router ID + + ipv4 + IPv4 address + + + + + + + + + + + Segment-Routing (SPRING) settings + + + + + Enable segment-routing functionality + + + + + + Global block label range + + + + + The lower bound of the global block + + u32:16-1048575 + MPLS label value + + + + + + + + + The upper bound of the global block + + u32:16-1048575 + MPLS label value + + + + + + + + + + + + Maximum MPLS labels allowed for this router + + u32:1-16 + MPLS label depth + + + + + + + + + Static IPv4/IPv6 prefix segment/label mapping + + ipv4net + IPv4 prefix segment + + + ipv6net + IPv6 prefix segment + + + + + + + + + + Specify the absolute value of prefix segment/label ID + + + + + Specify the absolute value of prefix segment/label ID + + u32:16-1048575 + The absolute segment/label ID value + + + + + + + + + Request upstream neighbor to replace segment/label with explicit null label + + + + + + Do not request penultimate hop popping for segment/label + + + + + + + + Specify the index value of prefix segment/label ID + + + + + Specify the index value of prefix segment/label ID + + u32:0-65535 + The index segment/label ID value + + + + + + + + + Request upstream neighbor to replace segment/label with explicit null label + + + + + + Do not request penultimate hop popping for segment/label + + + + + + + + + + + + Redistribute information from another routing protocol + + + + + Redistribute IPv4 routes + + + + + Border Gateway Protocol (BGP) + + + #include + + + + + Redistribute connected routes into IS-IS + + + #include + + + + + Redistribute kernel routes into IS-IS + + + #include + + + + + Redistribute OSPF routes into IS-IS + + + #include + + + + + Redistribute RIP routes into IS-IS + + + #include + + + + + Redistribute static routes into IS-IS + + + #include + + + + + + + + + Set attached bit to identify as L1/L2 router for inter-area traffic + + + + + + Set overload bit to avoid any transit traffic + + + + + + IETF SPF delay algorithm + + + + + Delay used while in QUIET state + + u32:0-60000 + Delay used while in QUIET state (in ms) + + + + + + + + + Delay used while in SHORT_WAIT state + + u32:0-60000 + Delay used while in SHORT_WAIT state (in ms) + + + + + + + + + Delay used while in LONG_WAIT + + u32:0-60000 + Delay used while in LONG_WAIT state (in ms) + + + + + + + + + Time with no received IGP events before considering IGP stable + + u32:0-60000 + Time with no received IGP events before considering IGP stable (in ms) + + + + + + + + + Maximum duration needed to learn all the events related to a single failure + + u32:0-60000 + Maximum duration needed to learn all the events related to a single failure (in ms) + + + + + + + + + + + Minimum interval between SPF calculations + + u32:1-120 + Minimum interval between consecutive SPFs in seconds + + + + + + + + + + Interface params + + + + + + #include + + + Configure circuit type for interface + + level-1 level-1-2 level-2-only + + + level-1 + Level-1 only adjacencies are formed + + + level-1-2 + Level-1-2 adjacencies are formed + + + level-2-only + Level-2 only adjacencies are formed + + + (level-1|level-1-2|level-2-only) + + + + + + Add padding to IS-IS hello packets + + + + + + Set Hello interval + + u32:1-600 + Set Hello interval + + + + + + + + + Set Hello interval + + u32:2-100 + Set multiplier for Hello holding time + + + + + + + + + Set default metric for circuit + + u32:0-16777215 + Default metric value + + + + + + + + + Set network type + + + + + point-to-point network type + + + + + + #include + + + Configure the authentication password for a circuit + + + + + Plain-text authentication type + + txt + Circuit password + + + + + + + + Set priority for Designated Router election + + u32:0-127 + Priority value + + + + + + + + + Set PSNP interval in seconds + + u32:0-127 + Priority value + + + + + + + + + Disable three-way handshake + + + + + + diff --git a/interface-definitions/protocols-isis.xml.in b/interface-definitions/protocols-isis.xml.in index e6982aca3..1bc890446 100644 --- a/interface-definitions/protocols-isis.xml.in +++ b/interface-definitions/protocols-isis.xml.in @@ -8,768 +8,7 @@ 610 - - - Configure the authentication password for an area - - - - - Plain-text authentication type - - txt - Level-wide password - - - - - - MD5 authentication type - - txt - Level-wide password - - - - - - - - Control distribution of default information - - - - - Distribute a default route - - - - - Distribute default route for IPv4 - - - - - Distribute default route into level-1 - - - - - - Distribute default route into level-2 - - - - - - - - Distribute default route for IPv6 - - - - - Distribute default route into level-1 - - always - - - always - Always advertise default route - - - - - - Distribute default route into level-2 - - always - - - always - Always advertise default route - - - - - - - - - - - - Domain name used for this instance - - txt - IS-IS routing area domain/tag - - - - - - Set the authentication password for a routing domain - - - - - Plain-text authentication type - - txt - Level-wide password - - - - - - - - - Dynamic hostname for IS-IS - - - - - - IS-IS level number - - level-1 level-1-2 level-2 - - - level-1 - Act as a station router - - - level-1-2 - Act as both a station and an area router - - - level-2 - Act as an area router - - - (level-1|level-1-2|level-2) - - - - - - Minimum interval between regenerating same LSP - - u32:1-120 - Minimum interval in seconds - - - - - - - - - Configure the maximum size of generated LSPs - - u32:128-4352 - Maximum size of generated LSPs - - - - - - - - - LSP refresh interval - - u32:1-65235 - LSP refresh interval in seconds - - - - - - - - - Maximum LSP lifetime - - u32:350-65535 - LSP lifetime in seconds - - - - - - - - - Use old-style (ISO 10589) or new-style packet formats - - narrow transition wide - - - narrow - Use old style of TLVs with narrow metric - - - transition - Send and accept both styles of TLVs during transition - - - wide - Use new style of TLVs to carry wider metric - - - (narrow|transition|wide) - - - - - - A Network Entity Title for this process (ISO only) - - XX.XXXX. ... .XXX.XX - Network entity title (NET) - - - [a-fA-F0-9]{2}(\.[a-fA-F0-9]{4}){3,9}\.[a-fA-F0-9]{2} - - - - - - Use the RFC 6232 purge-originator - - - - - - Show IS-IS neighbor adjacencies - - - - - Enable MPLS traffic engineering extensions - - - - - - - MPLS traffic engineering router ID - - ipv4 - IPv4 address - - - - - - - - - - - Segment-Routing (SPRING) settings - - - - - Enable segment-routing functionality - - - - - - Global block label range - - - - - The lower bound of the global block - - u32:16-1048575 - MPLS label value - - - - - - - - - The upper bound of the global block - - u32:16-1048575 - MPLS label value - - - - - - - - - - - - Maximum MPLS labels allowed for this router - - u32:1-16 - MPLS label depth - - - - - - - - - Static IPv4/IPv6 prefix segment/label mapping - - ipv4net - IPv4 prefix segment - - - ipv6net - IPv6 prefix segment - - - - - - - - - - Specify the absolute value of prefix segment/label ID - - - - - Specify the absolute value of prefix segment/label ID - - u32:16-1048575 - The absolute segment/label ID value - - - - - - - - - Request upstream neighbor to replace segment/label with explicit null label - - - - - - Do not request penultimate hop popping for segment/label - - - - - - - - Specify the index value of prefix segment/label ID - - - - - Specify the index value of prefix segment/label ID - - u32:0-65535 - The index segment/label ID value - - - - - - - - - Request upstream neighbor to replace segment/label with explicit null label - - - - - - Do not request penultimate hop popping for segment/label - - - - - - - - - - - - Redistribute information from another routing protocol - - - - - Redistribute IPv4 routes - - - - - Border Gateway Protocol (BGP) - - - #include - - - - - Redistribute connected routes into IS-IS - - - #include - - - - - Redistribute kernel routes into IS-IS - - - #include - - - - - Redistribute OSPF routes into IS-IS - - - #include - - - - - Redistribute RIP routes into IS-IS - - - #include - - - - - Redistribute static routes into IS-IS - - - #include - - - - - - - - - Set attached bit to identify as L1/L2 router for inter-area traffic - - - - - - Set overload bit to avoid any transit traffic - - - - - - IETF SPF delay algorithm - - - - - Delay used while in QUIET state - - u32:0-60000 - Delay used while in QUIET state (in ms) - - - - - - - - - Delay used while in SHORT_WAIT state - - u32:0-60000 - Delay used while in SHORT_WAIT state (in ms) - - - - - - - - - Delay used while in LONG_WAIT - - u32:0-60000 - Delay used while in LONG_WAIT state (in ms) - - - - - - - - - Time with no received IGP events before considering IGP stable - - u32:0-60000 - Time with no received IGP events before considering IGP stable (in ms) - - - - - - - - - Maximum duration needed to learn all the events related to a single failure - - u32:0-60000 - Maximum duration needed to learn all the events related to a single failure (in ms) - - - - - - - - - - - Minimum interval between SPF calculations - - u32:1-120 - Minimum interval between consecutive SPFs in seconds - - - - - - - - - - Interface params - - - - - - #include - - - Configure circuit type for interface - - level-1 level-1-2 level-2-only - - - level-1 - Level-1 only adjacencies are formed - - - level-1-2 - Level-1-2 adjacencies are formed - - - level-2-only - Level-2 only adjacencies are formed - - - (level-1|level-1-2|level-2-only) - - - - - - Add padding to IS-IS hello packets - - - - - - Set Hello interval - - u32:1-600 - Set Hello interval - - - - - - - - - Set Hello interval - - u32:2-100 - Set multiplier for Hello holding time - - - - - - - - - Set default metric for circuit - - u32:0-16777215 - Default metric value - - - - - - - - - Set network type - - - - - point-to-point network type - - - - - - #include - - - Configure the authentication password for a circuit - - - - - Plain-text authentication type - - txt - Circuit password - - - - - - - - Set priority for Designated Router election - - u32:0-127 - Priority value - - - - - - - - - Set PSNP interval in seconds - - u32:0-127 - Priority value - - - - - - - - - Disable three-way handshake - - - - - + #include 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 @@ -33,16 +33,6 @@ Routing protocol parameters - - - Static route parameters - 481 - - - #include - #include - - Border Gateway Protocol (BGP) @@ -59,6 +49,15 @@ #include + + + Intermediate System to Intermediate System (IS-IS) + 611 + + + #include + + Open Shortest Path First (OSPF) @@ -68,6 +67,16 @@ #include + + + Static route parameters + 481 + + + #include + #include + + diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py index 765e0ef4e..79d497186 100755 --- a/smoketest/scripts/cli/test_protocols_isis.py +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -36,7 +36,7 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): # Check for running process self.assertTrue(process_named_running(PROCESS_NAME)) - def test_isis_redistribute(self): + def test_isis_01_redistribute(self): prefix_list = 'EXPORT-ISIS' route_map = 'EXPORT-ISIS' rule = '10' @@ -57,7 +57,8 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): self.cli_commit() # Verify all changes - tmp = self.getFRRconfig(f'router isis {domain}', end='') + # 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) @@ -67,5 +68,40 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): self.cli_delete(['policy']) + + def test_isis_02_vrfs(self): + vrfs = ['red', 'green', 'blue'] + # It is safe to assume that when the basic VRF test works, all other + # IS-IS related features work, as we entirely inherit the CLI templates + # and Jinja2 FRR template. + table = '1000' + vrf = 'red' + vrf_base = ['vrf', 'name', vrf] + vrf_iface = 'eth1' + self.cli_set(vrf_base + ['table', table]) + self.cli_set(vrf_base + ['protocols', 'isis', 'domain', domain]) + self.cli_set(vrf_base + ['protocols', 'isis', 'net', net]) + self.cli_set(vrf_base + ['protocols', 'isis', 'interface', vrf_iface]) + self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf]) + + # Also set a default VRF IS-IS config + self.cli_set(base_path + ['domain', domain]) + self.cli_set(base_path + ['net', net]) + self.cli_set(base_path + ['interface', 'eth0']) + self.cli_commit() + + # Verify FRR isisd configuration + # XXX: FRR represents router isis with a trailing whitespace :/ + tmp = self.getFRRconfig(f'router isis {domain} ') + self.assertIn(f'router isis {domain}', tmp) + self.assertIn(f' net {net}', tmp) + + tmp = self.getFRRconfig(f'router isis {domain} vrf {vrf}') + self.assertIn(f'router isis {domain} vrf {vrf}', tmp) + self.assertIn(f' net {net}', tmp) + + self.cli_delete(['vrf', 'name', vrf]) + self.cli_delete(['interfaces', 'ethernet', vrf_iface, 'vrf']) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index 24db52567..8acff58cc 100755 --- a/src/conf_mode/protocols_isis.py +++ b/src/conf_mode/protocols_isis.py @@ -17,30 +17,61 @@ import os from sys import exit +from sys import argv 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.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'] + + 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 + 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 if 'domain' not in isis: @@ -53,6 +84,17 @@ def verify(isis): if 'interface' not in isis: raise ConfigError('Interface used for routing updates is mandatory!') + for interface in isis['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']): @@ -111,7 +153,7 @@ def verify(isis): return None def generate(isis): - if not isis: + if not isis or 'deleted' in isis: isis['new_frr_config'] = '' return None @@ -121,17 +163,29 @@ def generate(isis): 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('^interface \S+$', '') - frr_cfg.modify_section('^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 Date: Sun, 21 Mar 2021 13:52:25 +0100 Subject: ospf: vrf: T2271: ease FRR interaction for config reload Instead of multiple if/else paths, use a common vrf string variable which is either populated or not. In addtion when interfaces are configured for a given VRF, harden the regex for config reload. --- smoketest/scripts/cli/test_protocols_ospf.py | 25 ++++++++++++------------- src/conf_mode/protocols_ospf.py | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 23 deletions(-) (limited to 'smoketest/scripts/cli') 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 @@ -288,16 +288,16 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): 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) @@ -309,14 +309,13 @@ class TestProtocolsOSPF(VyOSUnitTestSHIM.TestCase): 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_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 @@ -154,11 +154,10 @@ def verify(ospf): 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: @@ -179,17 +178,18 @@ def apply(ospf): 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 Date: Sun, 21 Mar 2021 19:26:22 +0100 Subject: isis: T3417: drop artificial "domain" node identifying the IS-IS process name As we and FRR do not support multiple FRR process instances, there is no need to make this configurable for a user. We rather rely on a solid default "VyOS". --- data/templates/frr/isis.frr.tmpl | 4 ++-- interface-definitions/include/isis/isis-common-config.xml.i | 9 --------- smoketest/scripts/cli/test_protocols_isis.py | 5 +---- src/conf_mode/protocols_isis.py | 5 +---- src/migration-scripts/isis/0-to-1 | 4 +--- 5 files changed, 5 insertions(+), 22 deletions(-) (limited to 'smoketest/scripts/cli') diff --git a/data/templates/frr/isis.frr.tmpl b/data/templates/frr/isis.frr.tmpl index da098abac..7f996b134 100644 --- a/data/templates/frr/isis.frr.tmpl +++ b/data/templates/frr/isis.frr.tmpl @@ -1,5 +1,5 @@ ! -router isis {{ domain }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} +router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} net {{ net }} {% if dynamic_hostname is defined %} hostname dynamic @@ -134,7 +134,7 @@ router isis {{ domain }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none } {% if interface is defined and interface is not none %} {% for iface, iface_config in interface.items() %} interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }} - ip router isis {{ domain }} + ip router isis VyOS {% if iface_config.bfd is defined %} isis bfd {% endif %} diff --git a/interface-definitions/include/isis/isis-common-config.xml.i b/interface-definitions/include/isis/isis-common-config.xml.i index 94a6e3592..8b753b082 100644 --- a/interface-definitions/include/isis/isis-common-config.xml.i +++ b/interface-definitions/include/isis/isis-common-config.xml.i @@ -88,15 +88,6 @@ - - - Domain name used for this instance - - txt - IS-IS routing area domain/tag - - - Set the authentication password for a routing domain diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py index 79d497186..10c722eca 100755 --- a/smoketest/scripts/cli/test_protocols_isis.py +++ b/smoketest/scripts/cli/test_protocols_isis.py @@ -25,7 +25,7 @@ from vyos.util import process_named_running PROCESS_NAME = 'isisd' base_path = ['protocols', 'isis'] -domain = 'FOOO' +domain = 'VyOS' net = '49.0001.1921.6800.1002.00' class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): @@ -45,7 +45,6 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'action', 'permit']) self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'match', 'ip', 'address', 'prefix-list', prefix_list]) - self.cli_set(base_path + ['domain', domain]) self.cli_set(base_path + ['net', net]) self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map]) @@ -79,13 +78,11 @@ class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase): vrf_base = ['vrf', 'name', vrf] vrf_iface = 'eth1' self.cli_set(vrf_base + ['table', table]) - self.cli_set(vrf_base + ['protocols', 'isis', 'domain', domain]) self.cli_set(vrf_base + ['protocols', 'isis', 'net', net]) self.cli_set(vrf_base + ['protocols', 'isis', 'interface', vrf_iface]) self.cli_set(['interfaces', 'ethernet', vrf_iface, 'vrf', vrf]) # Also set a default VRF IS-IS config - self.cli_set(base_path + ['domain', domain]) self.cli_set(base_path + ['net', net]) self.cli_set(base_path + ['interface', 'eth0']) self.cli_commit() diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py index adce00ee3..bcd9960ed 100755 --- a/src/conf_mode/protocols_isis.py +++ b/src/conf_mode/protocols_isis.py @@ -83,9 +83,6 @@ def verify(isis): if not isis or 'deleted' in isis: return None - if 'domain' not in isis: - raise ConfigError('Routing domain name/tag must be set!') - if 'net' not in isis: raise ConfigError('Network entity is mandatory!') @@ -196,7 +193,7 @@ def apply(isis): if 'vrf' in isis: vrf = 'vrf ' + isis['vrf'] - frr_cfg.modify_section(f'^router isis \S+ {vrf}', '') + frr_cfg.modify_section(f'^router isis VyOS {vrf}', '') for key in ['interface', 'interface_removed']: if key not in isis: continue diff --git a/src/migration-scripts/isis/0-to-1 b/src/migration-scripts/isis/0-to-1 index 5f51f986e..6773f4009 100755 --- a/src/migration-scripts/isis/0-to-1 +++ b/src/migration-scripts/isis/0-to-1 @@ -38,8 +38,7 @@ if not config.exists(base): exit(0) # Only one IS-IS process is supported, thus this operation is save -process = config.list_nodes(base) -isis_base = base + process +isis_base = base + config.list_nodes(base) # We need a temporary copy of the config tmp_base = ['protocols', 'isis2'] @@ -50,7 +49,6 @@ config.delete(base) # Rename temporary copy to new final config and set domain key config.rename(tmp_base, 'isis') -config.set(base + ['domain'], process[0]) try: with open(file_name, 'w') as f: -- cgit v1.2.3