summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-definitions/include/babel/redistribute-common.xml.i38
-rw-r--r--interface-definitions/include/rip/access-list6.xml.i22
-rw-r--r--interface-definitions/protocols_babel.xml.in84
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_babel.py218
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)