diff options
| -rw-r--r-- | interface-definitions/include/babel/redistribute-common.xml.i | 38 | ||||
| -rw-r--r-- | interface-definitions/include/rip/access-list6.xml.i | 22 | ||||
| -rw-r--r-- | interface-definitions/protocols_babel.xml.in | 84 | ||||
| -rwxr-xr-x | smoketest/scripts/cli/test_protocols_babel.py | 218 | 
4 files changed, 268 insertions, 94 deletions
| diff --git a/interface-definitions/include/babel/redistribute-common.xml.i b/interface-definitions/include/babel/redistribute-common.xml.i new file mode 100644 index 000000000..93efe68dd --- /dev/null +++ b/interface-definitions/include/babel/redistribute-common.xml.i @@ -0,0 +1,38 @@ +<!-- include start from babel/redistribute-common.xml.i --> +<leafNode name="bgp"> +    <properties> +      <help>Border Gateway Protocol (BGP)</help> +      <valueless/> +    </properties> +  </leafNode> +  <leafNode name="connected"> +    <properties> +      <help>Connected routes (directly attached subnet or host)</help> +      <valueless/> +    </properties> +  </leafNode> +  <leafNode name="isis"> +    <properties> +      <help>Intermediate System to Intermediate System (IS-IS)</help> +      <valueless/> +    </properties> +  </leafNode> +  <leafNode name="kernel"> +    <properties> +      <help>Redistribute Kernel routes (not installed via the zebra RIB)</help> +      <valueless/> +    </properties> +  </leafNode> +  <leafNode name="openfabric"> +    <properties> +      <help>OpenFabric Routing Protocol</help> +      <valueless/> +    </properties> +  </leafNode> +  <leafNode name="static"> +    <properties> +      <help>Statically configured routes</help> +      <valueless/> +    </properties> +  </leafNode> +<!-- include end --> diff --git a/interface-definitions/include/rip/access-list6.xml.i b/interface-definitions/include/rip/access-list6.xml.i index 732135253..395d21c14 100644 --- a/interface-definitions/include/rip/access-list6.xml.i +++ b/interface-definitions/include/rip/access-list6.xml.i @@ -7,31 +7,25 @@      <leafNode name="in">        <properties>          <help>Access list to apply to input packets</help> -        <valueHelp> -          <format>u32</format> -          <description>Access list to apply to input packets</description> -        </valueHelp>          <completionHelp>            <path>policy access-list6</path>          </completionHelp> -        <constraint> -          <validator name="numeric" argument="--range 0-4294967295"/> -        </constraint> +        <valueHelp> +          <format>txt</format> +          <description>Name of IPv6 access-list</description> +        </valueHelp>        </properties>      </leafNode>      <leafNode name="out">        <properties>          <help>Access list to apply to output packets</help> -        <valueHelp> -          <format>u32</format> -          <description>Access list to apply to output packets</description> -        </valueHelp>          <completionHelp>            <path>policy access-list6</path>          </completionHelp> -        <constraint> -          <validator name="numeric" argument="--range 0-4294967295"/> -        </constraint> +        <valueHelp> +          <format>txt</format> +          <description>Name of IPv6 access-list</description> +        </valueHelp>        </properties>      </leafNode>    </children> diff --git a/interface-definitions/protocols_babel.xml.in b/interface-definitions/protocols_babel.xml.in index 49fffe230..2795a7dd4 100644 --- a/interface-definitions/protocols_babel.xml.in +++ b/interface-definitions/protocols_babel.xml.in @@ -71,42 +71,7 @@                    <help>Redistribute IPv4 routes</help>                  </properties>                  <children> -                  <leafNode name="bgp"> -                    <properties> -                      <help>Redistribute BGP routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="connected"> -                    <properties> -                      <help>Redistribute connected routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="eigrp"> -                    <properties> -                      <help>Redistribute EIGRP routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="isis"> -                    <properties> -                      <help>Redistribute IS-IS routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="kernel"> -                    <properties> -                      <help>Redistribute kernel routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="nhrp"> -                    <properties> -                      <help>Redistribute NHRP routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> +                  #include <include/babel/redistribute-common.xml.i>                    <leafNode name="ospf">                      <properties>                        <help>Redistribute OSPF routes</help> @@ -119,12 +84,6 @@                        <valueless/>                      </properties>                    </leafNode> -                  <leafNode name="static"> -                    <properties> -                      <help>Redistribute static routes</help> -                      <valueless/> -                    </properties> -                  </leafNode>                  </children>                </node>                <node name="ipv6"> @@ -132,51 +91,16 @@                    <help>Redistribute IPv6 routes</help>                  </properties>                  <children> -                  <leafNode name="bgp"> -                    <properties> -                      <help>Redistribute BGP routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="connected"> -                    <properties> -                      <help>Redistribute connected routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="isis"> -                    <properties> -                      <help>Redistribute IS-IS routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="kernel"> -                    <properties> -                      <help>Redistribute kernel routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="nhrp"> -                    <properties> -                      <help>Redistribute NHRP routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> +                  #include <include/babel/redistribute-common.xml.i>                    <leafNode name="ospfv3">                      <properties> -                      <help>Redistribute OSPFv3 routes</help> +                      <help>Open Shortest Path First (IPv6) (OSPFv3)</help>                        <valueless/>                      </properties>                    </leafNode>                    <leafNode name="ripng">                      <properties> -                      <help>Redistribute RIPng routes</help> -                      <valueless/> -                    </properties> -                  </leafNode> -                  <leafNode name="static"> -                    <properties> -                      <help>Redistribute static routes</help> +                      <help>Routing Information Protocol next-generation (IPv6) (RIPng)</help>                        <valueless/>                      </properties>                    </leafNode> diff --git a/smoketest/scripts/cli/test_protocols_babel.py b/smoketest/scripts/cli/test_protocols_babel.py new file mode 100755 index 000000000..606c1efd3 --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_babel.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 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.utils.process import process_named_running +from vyos.xml_ref import default_value + +PROCESS_NAME = 'babeld' +base_path = ['protocols', 'babel'] + +class TestProtocolsBABEL(VyOSUnitTestSHIM.TestCase): +    @classmethod +    def setUpClass(cls): +        cls._interfaces = Section.interfaces('ethernet', vlan=False) +        # call base-classes classmethod +        super(TestProtocolsBABEL, cls).setUpClass() +        # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same +        cls.daemon_pid = process_named_running(PROCESS_NAME) +        # ensure we can also run this test on a live system - so lets clean +        # out the current configuration :) +        cls.cli_delete(cls, base_path) +        cls.cli_delete(cls, ['policy', 'prefix-list']) +        cls.cli_delete(cls, ['policy', 'prefix-list6']) + +    def tearDown(self): +        # always destroy the entire babel configuration to make the processes +        # life as hard as possible +        self.cli_delete(base_path) +        self.cli_delete(['policy', 'prefix-list']) +        self.cli_delete(['policy', 'prefix-list6']) +        self.cli_commit() + +        # check process health and continuity +        self.assertEqual(self.daemon_pid, process_named_running(PROCESS_NAME)) + +    def test_babel_interfaces(self): +        def_update_interval = default_value(base_path + ['interface', 'eth0', 'update-interval']) +        channel = '20' +        hello_interval = '1000' +        max_rtt_penalty = '100' +        rtt_decay = '23' +        rtt_max = '119' +        rtt_min = '11' +        rxcost = '40000' +        type = 'wired' + +        for interface in self._interfaces: +            self.cli_set(base_path + ['interface', interface]) +            self.cli_set(base_path + ['interface', interface, 'channel', channel]) +            self.cli_set(base_path + ['interface', interface, 'enable-timestamps']) +            self.cli_set(base_path + ['interface', interface, 'hello-interval', hello_interval]) +            self.cli_set(base_path + ['interface', interface, 'max-rtt-penalty', max_rtt_penalty]) +            self.cli_set(base_path + ['interface', interface, 'rtt-decay', rtt_decay]) +            self.cli_set(base_path + ['interface', interface, 'rtt-max', rtt_max]) +            self.cli_set(base_path + ['interface', interface, 'rtt-min', rtt_min]) +            self.cli_set(base_path + ['interface', interface, 'enable-timestamps']) +            self.cli_set(base_path + ['interface', interface, 'rxcost', rxcost]) +            self.cli_set(base_path + ['interface', interface, 'split-horizon', 'disable']) +            self.cli_set(base_path + ['interface', interface, 'type', type]) + +        self.cli_commit() + +        frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) +        for interface in self._interfaces: +            self.assertIn(f' network {interface}', frrconfig) + +            iface_config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME) +            self.assertIn(f' babel channel {channel}', iface_config) +            self.assertIn(f' babel enable-timestamps', iface_config) +            self.assertIn(f' babel update-interval {def_update_interval}', iface_config) +            self.assertIn(f' babel hello-interval {hello_interval}', iface_config) +            self.assertIn(f' babel rtt-decay {rtt_decay}', iface_config) +            self.assertIn(f' babel rtt-max {rtt_max}', iface_config) +            self.assertIn(f' babel rtt-min {rtt_min}', iface_config) +            self.assertIn(f' babel rxcost {rxcost}', iface_config) +            self.assertIn(f' babel max-rtt-penalty {max_rtt_penalty}', iface_config) +            self.assertIn(f' no babel split-horizon', iface_config) +            self.assertIn(f' babel {type}', iface_config) + +    def test_babel_redistribute(self): +        ipv4_protos = ['bgp', 'connected', 'isis', 'kernel', 'ospf', 'rip', 'static'] +        ipv6_protos = ['bgp', 'connected', 'isis', 'kernel', 'ospfv3', 'ripng', 'static'] + +        for protocol in ipv4_protos: +            self.cli_set(base_path + ['redistribute', 'ipv4', protocol]) +        for protocol in ipv6_protos: +            self.cli_set(base_path + ['redistribute', 'ipv6', protocol]) + +        self.cli_commit() + +        frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) +        for protocol in ipv4_protos: +            self.assertIn(f' redistribute ipv4 {protocol}', frrconfig) +        for protocol in ipv6_protos: +            if protocol == 'ospfv3': +                protocol = 'ospf6' +            self.assertIn(f' redistribute ipv6 {protocol}', frrconfig) + +    def test_babel_basic(self): +        diversity_factor = '64' +        resend_delay = '100' +        smoothing_half_life = '400' + +        self.cli_set(base_path + ['parameters', 'diversity']) +        self.cli_set(base_path + ['parameters', 'diversity-factor', diversity_factor]) +        self.cli_set(base_path + ['parameters', 'resend-delay', resend_delay]) +        self.cli_set(base_path + ['parameters', 'smoothing-half-life', smoothing_half_life]) + +        self.cli_commit() + +        frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) +        self.assertIn(f' babel diversity', frrconfig) +        self.assertIn(f' babel diversity-factor {diversity_factor}', frrconfig) +        self.assertIn(f' babel resend-delay {resend_delay}', frrconfig) +        self.assertIn(f' babel smoothing-half-life {smoothing_half_life}', frrconfig) + +    def test_babel_distribute_list(self): +        access_list_in4 = '40' +        access_list_out4 = '50' +        access_list_in4_iface = '44' +        access_list_out4_iface = '55' +        access_list_in6 = 'AL-foo-in6' +        access_list_out6 = 'AL-foo-out6' + +        prefix_list_in4 = 'PL-foo-in4' +        prefix_list_out4 = 'PL-foo-out4' +        prefix_list_in6 = 'PL-foo-in6' +        prefix_list_out6 = 'PL-foo-out6' + +        self.cli_set(['policy', 'access-list', access_list_in4]) +        self.cli_set(['policy', 'access-list', access_list_out4]) +        self.cli_set(['policy', 'access-list6', access_list_in6]) +        self.cli_set(['policy', 'access-list6', access_list_out6]) + +        self.cli_set(['policy', 'access-list', f'{access_list_in4_iface}']) +        self.cli_set(['policy', 'access-list', f'{access_list_out4_iface}']) + +        self.cli_set(['policy', 'prefix-list', prefix_list_in4]) +        self.cli_set(['policy', 'prefix-list', prefix_list_out4]) +        self.cli_set(['policy', 'prefix-list6', prefix_list_in6]) +        self.cli_set(['policy', 'prefix-list6', prefix_list_out6]) + +        self.cli_set(base_path + ['distribute-list', 'ipv4', 'access-list', 'in', access_list_in4]) +        self.cli_set(base_path + ['distribute-list', 'ipv4', 'access-list', 'out', access_list_out4]) +        self.cli_set(base_path + ['distribute-list', 'ipv6', 'access-list', 'in', access_list_in6]) +        self.cli_set(base_path + ['distribute-list', 'ipv6', 'access-list', 'out', access_list_out6]) + +        self.cli_set(base_path + ['distribute-list', 'ipv4', 'prefix-list', 'in', prefix_list_in4]) +        self.cli_set(base_path + ['distribute-list', 'ipv4', 'prefix-list', 'out', prefix_list_out4]) +        self.cli_set(base_path + ['distribute-list', 'ipv6', 'prefix-list', 'in', prefix_list_in6]) +        self.cli_set(base_path + ['distribute-list', 'ipv6', 'prefix-list', 'out', prefix_list_out6]) + +        for interface in self._interfaces: +            self.cli_set(base_path + ['interface', interface]) + +            self.cli_set(['policy', 'access-list6', f'{access_list_in6}-{interface}']) +            self.cli_set(['policy', 'access-list6', f'{access_list_out6}-{interface}']) + +            self.cli_set(['policy', 'prefix-list', f'{prefix_list_in4}-{interface}']) +            self.cli_set(['policy', 'prefix-list', f'{prefix_list_out4}-{interface}']) +            self.cli_set(['policy', 'prefix-list6', f'{prefix_list_in6}-{interface}']) +            self.cli_set(['policy', 'prefix-list6', f'{prefix_list_out6}-{interface}']) + +            tmp_path = base_path + ['distribute-list', 'ipv4', 'interface', interface] +            self.cli_set(tmp_path + ['access-list', 'in', f'{access_list_in4_iface}']) +            self.cli_set(tmp_path + ['access-list', 'out', f'{access_list_out4_iface}']) +            self.cli_set(tmp_path + ['prefix-list', 'in', f'{prefix_list_in4}-{interface}']) +            self.cli_set(tmp_path + ['prefix-list', 'out', f'{prefix_list_out4}-{interface}']) + +            tmp_path = base_path + ['distribute-list', 'ipv6', 'interface', interface] +            self.cli_set(tmp_path + ['access-list', 'in', f'{access_list_in6}-{interface}']) +            self.cli_set(tmp_path + ['access-list', 'out', f'{access_list_out6}-{interface}']) +            self.cli_set(tmp_path + ['prefix-list', 'in', f'{prefix_list_in6}-{interface}']) +            self.cli_set(tmp_path + ['prefix-list', 'out', f'{prefix_list_out6}-{interface}']) + +        self.cli_commit() + +        frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) +        self.assertIn(f' distribute-list {access_list_in4} in', frrconfig) +        self.assertIn(f' distribute-list {access_list_out4} out', frrconfig) +        self.assertIn(f' ipv6 distribute-list {access_list_in6} in', frrconfig) +        self.assertIn(f' ipv6 distribute-list {access_list_out6} out', frrconfig) + +        self.assertIn(f' distribute-list prefix {prefix_list_in4} in', frrconfig) +        self.assertIn(f' distribute-list prefix {prefix_list_out4} out', frrconfig) +        self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in6} in', frrconfig) +        self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out6} out', frrconfig) + +        for interface in self._interfaces: +            self.assertIn(f' distribute-list {access_list_in4_iface} in {interface}', frrconfig) +            self.assertIn(f' distribute-list {access_list_out4_iface} out {interface}', frrconfig) +            self.assertIn(f' ipv6 distribute-list {access_list_in6}-{interface} in {interface}', frrconfig) +            self.assertIn(f' ipv6 distribute-list {access_list_out6}-{interface} out {interface}', frrconfig) + +            self.assertIn(f' distribute-list prefix {prefix_list_in4}-{interface} in {interface}', frrconfig) +            self.assertIn(f' distribute-list prefix {prefix_list_out4}-{interface} out {interface}', frrconfig) +            self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in6}-{interface} in {interface}', frrconfig) +            self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out6}-{interface} out {interface}', frrconfig) + +if __name__ == '__main__': +    unittest.main(verbosity=2) | 
