summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Jenkinsfile7
-rw-r--r--data/templates/frr/rip.frr.tmpl35
-rw-r--r--interface-definitions/include/ospf-authentication.xml.i11
-rw-r--r--interface-definitions/include/ospf-route-map.xml.i4
-rw-r--r--interface-definitions/include/rip-access-list6.xml.i39
-rw-r--r--interface-definitions/include/rip-default-information.xml.i15
-rw-r--r--interface-definitions/include/rip-default-metric.xml.i14
-rw-r--r--interface-definitions/include/rip-interface.xml.i85
-rw-r--r--interface-definitions/include/rip-prefix-list6.xml.i33
-rw-r--r--interface-definitions/include/rip-redistribute.xml.i13
-rw-r--r--interface-definitions/include/rip-timers.xml.i48
-rw-r--r--interface-definitions/protocols-ospf.xml.in7
-rw-r--r--interface-definitions/protocols-rip.xml.in91
-rw-r--r--interface-definitions/protocols-ripng.xml.in228
-rw-r--r--smoketest/configs/rip-router138
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_rip.py2
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_ripng.py133
-rwxr-xr-xsrc/conf_mode/protocols_rip.py11
-rwxr-xr-xsrc/migration-scripts/interfaces/18-to-1994
-rwxr-xr-xsrc/migration-scripts/rpki/0-to-17
-rwxr-xr-xsrc/migration-scripts/system/18-to-194
21 files changed, 650 insertions, 369 deletions
diff --git a/Jenkinsfile b/Jenkinsfile
index 7a760b40b..21a6829c0 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,4 +1,4 @@
-// Copyright (C) 2020 VyOS maintainers and contributors
+// Copyright (C) 2020-2021 VyOS maintainers and contributors
//
// This program is free software; you can redistribute it and/or modify
// in order to easy exprort images built to "external" world
@@ -12,7 +12,6 @@
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-
@NonCPS
// Using a version specifier library, use 'current' branch. The underscore (_)
@@ -20,5 +19,5 @@
// @Library annotation is not an import statement!
@Library('vyos-build@current')_
-// Start package build using library function from https://github.com/c-po/vyos-build
-buildPackage()
+// Start package build using library function from https://github.com/vyos/vyos-build
+buildPackage(null, null, null, true)
diff --git a/data/templates/frr/rip.frr.tmpl b/data/templates/frr/rip.frr.tmpl
index eeaee7199..c0d062fc6 100644
--- a/data/templates/frr/rip.frr.tmpl
+++ b/data/templates/frr/rip.frr.tmpl
@@ -1,4 +1,39 @@
!
+{# RIP key-chain definition #}
+{% if interface is defined and interface is not none %}
+{% for iface, iface_config in interface.items() %}
+{% if iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
+key chain {{ iface }}-rip
+{% for key_id, key_options in iface_config.authentication.md5.items() %}
+ key {{ key_id }}
+{% if key_options.password is defined and key_options.password is not none %}
+ key-string {{ key_options.password }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+!
+{# Interface specific configuration #}
+{% if interface is defined and interface is not none %}
+{% for iface, iface_config in interface.items() %}
+interface {{ iface }}
+{% if iface_config.authentication is defined and iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
+ ip rip authentication mode text
+ ip rip authentication string {{ iface_config.authentication.plaintext_password }}
+{% elif iface_config.authentication is defined and iface_config.authentication.md5 is defined and iface_config.authentication.md5 is not none %}
+ ip rip authentication key-chain {{ iface }}-rip
+ ip rip authentication mode md5
+{% endif %}
+{% if iface_config.split_horizon is defined and iface_config.split_horizon.disable is defined %}
+ no ip rip split-horizon
+{% endif %}
+{% if iface_config.split_horizon is defined and iface_config.split_horizon.poison_reverse is defined %}
+ ip rip split-horizon poisoned-reverse
+{% endif %}
+{% endfor %}
+{% endif %}
+!
router rip
{% if default_information is defined and default_information.originate is defined %}
default-information originate
diff --git a/interface-definitions/include/ospf-authentication.xml.i b/interface-definitions/include/ospf-authentication.xml.i
index 0963e5cc0..efb29c1f0 100644
--- a/interface-definitions/include/ospf-authentication.xml.i
+++ b/interface-definitions/include/ospf-authentication.xml.i
@@ -16,6 +16,9 @@
<format>u32:1-255</format>
<description>MD5 key id</description>
</valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-255"/>
+ </constraint>
</properties>
<children>
<leafNode name="md5-key">
@@ -25,6 +28,10 @@
<format>txt</format>
<description>MD5 Key (16 characters or less)</description>
</valueHelp>
+ <constraint>
+ <regex>^[^[:space:]]{1,16}$</regex>
+ </constraint>
+ <constraintErrorMessage>Password must be 16 characters or less</constraintErrorMessage>
</properties>
</leafNode>
</children>
@@ -38,6 +45,10 @@
<format>txt</format>
<description>Plain text password (8 characters or less)</description>
</valueHelp>
+ <constraint>
+ <regex>^[^[:space:]]{1,8}$</regex>
+ </constraint>
+ <constraintErrorMessage>Password must be 8 characters or less</constraintErrorMessage>
</properties>
</leafNode>
</children>
diff --git a/interface-definitions/include/ospf-route-map.xml.i b/interface-definitions/include/ospf-route-map.xml.i
index 8dc5b37da..943a477c0 100644
--- a/interface-definitions/include/ospf-route-map.xml.i
+++ b/interface-definitions/include/ospf-route-map.xml.i
@@ -2,6 +2,10 @@
<leafNode name="route-map">
<properties>
<help>Route map reference</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Route map reference</description>
+ </valueHelp>
<completionHelp>
<path>policy route-map</path>
</completionHelp>
diff --git a/interface-definitions/include/rip-access-list6.xml.i b/interface-definitions/include/rip-access-list6.xml.i
new file mode 100644
index 000000000..6a8a37607
--- /dev/null
+++ b/interface-definitions/include/rip-access-list6.xml.i
@@ -0,0 +1,39 @@
+<!-- included start from rip-access-list.xml.i -->
+<node name="access-list">
+ <properties>
+ <help>Access-list</help>
+ </properties>
+ <children>
+ <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>
+ </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>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- included end -->
diff --git a/interface-definitions/include/rip-default-information.xml.i b/interface-definitions/include/rip-default-information.xml.i
new file mode 100644
index 000000000..22a2f6ac7
--- /dev/null
+++ b/interface-definitions/include/rip-default-information.xml.i
@@ -0,0 +1,15 @@
+<!-- included start from rip-default-information.xml.i -->
+<node name="default-information">
+ <properties>
+ <help>Control distribution of default route</help>
+ </properties>
+ <children>
+ <leafNode name="originate">
+ <properties>
+ <help>Distribute a default route</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- included end -->
diff --git a/interface-definitions/include/rip-default-metric.xml.i b/interface-definitions/include/rip-default-metric.xml.i
new file mode 100644
index 000000000..a5e6016d6
--- /dev/null
+++ b/interface-definitions/include/rip-default-metric.xml.i
@@ -0,0 +1,14 @@
+<!-- included start from rip-default-metric.xml.i -->
+<leafNode name="default-metric">
+ <properties>
+ <help>Metric of redistributed routes</help>
+ <valueHelp>
+ <format>u32:1-16</format>
+ <description>Default metric</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-16"/>
+ </constraint>
+ </properties>
+</leafNode>
+<!-- included end -->
diff --git a/interface-definitions/include/rip-interface.xml.i b/interface-definitions/include/rip-interface.xml.i
new file mode 100644
index 000000000..1d5e6f949
--- /dev/null
+++ b/interface-definitions/include/rip-interface.xml.i
@@ -0,0 +1,85 @@
+<!-- included start from rip-interface.xml.i -->
+<tagNode name="interface">
+ <properties>
+ <help>Interface name</help>
+ <completionHelp>
+ <script>${vyos_completion_dir}/list_interfaces.py</script>
+ </completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
+ </properties>
+ <children>
+ <node name="authentication">
+ <properties>
+ <help>Authentication</help>
+ </properties>
+ <children>
+ <tagNode name="md5">
+ <properties>
+ <help>MD5 key id</help>
+ <valueHelp>
+ <format>u32:1-255</format>
+ <description>OSPF key id</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-255"/>
+ </constraint>
+ </properties>
+ <children>
+ <leafNode name="password">
+ <properties>
+ <help>Authentication password</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>MD5 Key (16 characters or less)</description>
+ </valueHelp>
+ <constraint>
+ <regex>^[^[:space:]]{1,16}$</regex>
+ </constraint>
+ <constraintErrorMessage>Password must be 16 characters or less</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </tagNode>
+ <leafNode name="plaintext-password">
+ <properties>
+ <help>Plain text password</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Plain text password (16 characters or less)</description>
+ </valueHelp>
+ <constraint>
+ <regex>^[^[:space:]]{1,16}$</regex>
+ </constraint>
+ <constraintErrorMessage>Password must be 16 characters or less</constraintErrorMessage>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ <node name="split-horizon">
+ <properties>
+ <help>Split horizon parameters</help>
+ </properties>
+ <children>
+ <leafNode name="disable">
+ <properties>
+ <help>Disable split horizon on specified interface</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ <leafNode name="poison-reverse">
+ <properties>
+ <help>Disable split horizon on specified interface</help>
+ <valueless/>
+ </properties>
+ </leafNode>
+ </children>
+ </node>
+ </children>
+</tagNode>
+<!-- included end -->
diff --git a/interface-definitions/include/rip-prefix-list6.xml.i b/interface-definitions/include/rip-prefix-list6.xml.i
new file mode 100644
index 000000000..f73f77d05
--- /dev/null
+++ b/interface-definitions/include/rip-prefix-list6.xml.i
@@ -0,0 +1,33 @@
+<!-- included start from rip-prefix-list.xml.i -->
+<node name="prefix-list">
+ <properties>
+ <help>Prefix-list</help>
+ </properties>
+ <children>
+ <leafNode name="in">
+ <properties>
+ <help>Prefix-list to apply to input packets</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Prefix-list to apply to input packets</description>
+ </valueHelp>
+ <completionHelp>
+ <path>policy prefix-list6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ <leafNode name="out">
+ <properties>
+ <help>Prefix-list to apply to output packets</help>
+ <valueHelp>
+ <format>txt</format>
+ <description>Prefix-list to apply to output packets</description>
+ </valueHelp>
+ <completionHelp>
+ <path>policy prefix-list6</path>
+ </completionHelp>
+ </properties>
+ </leafNode>
+ </children>
+</node>
+<!-- included end -->
diff --git a/interface-definitions/include/rip-redistribute.xml.i b/interface-definitions/include/rip-redistribute.xml.i
index f9dba3ffe..c7b9d2c09 100644
--- a/interface-definitions/include/rip-redistribute.xml.i
+++ b/interface-definitions/include/rip-redistribute.xml.i
@@ -11,16 +11,5 @@
</constraint>
</properties>
</leafNode>
-<leafNode name="route-map">
- <properties>
- <help>Route map reference</help>
- <valueHelp>
- <format>txt</format>
- <description>Route map reference</description>
- </valueHelp>
- <completionHelp>
- <path>policy route-map</path>
- </completionHelp>
- </properties>
-</leafNode>
+#include <include/ospf-route-map.xml.i>
<!-- included end -->
diff --git a/interface-definitions/include/rip-timers.xml.i b/interface-definitions/include/rip-timers.xml.i
new file mode 100644
index 000000000..5ba19bb06
--- /dev/null
+++ b/interface-definitions/include/rip-timers.xml.i
@@ -0,0 +1,48 @@
+<!-- included start from rip-timers.xml.i -->
+<node name="timers">
+ <properties>
+ <help>RIPng timer values</help>
+ </properties>
+ <children>
+ <leafNode name="garbage-collection">
+ <properties>
+ <help>Garbage collection timer</help>
+ <valueHelp>
+ <format>u32:5-2147483647</format>
+ <description>Garbage colletion time (default 120)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-2147483647"/>
+ </constraint>
+ </properties>
+ <defaultValue>120</defaultValue>
+ </leafNode>
+ <leafNode name="timeout">
+ <properties>
+ <help>Routing information timeout timer</help>
+ <valueHelp>
+ <format>u32:5-2147483647</format>
+ <description>Routing information timeout timer (default 180)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-2147483647"/>
+ </constraint>
+ </properties>
+ <defaultValue>180</defaultValue>
+ </leafNode>
+ <leafNode name="update">
+ <properties>
+ <help>Routing table update timer</help>
+ <valueHelp>
+ <format>u32:5-2147483647</format>
+ <description>Routing table update timer in seconds (default 30)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 5-2147483647"/>
+ </constraint>
+ </properties>
+ <defaultValue>30</defaultValue>
+ </leafNode>
+ </children>
+</node>
+<!-- included end -->
diff --git a/interface-definitions/protocols-ospf.xml.in b/interface-definitions/protocols-ospf.xml.in
index ee350fb17..a616c0e60 100644
--- a/interface-definitions/protocols-ospf.xml.in
+++ b/interface-definitions/protocols-ospf.xml.in
@@ -404,6 +404,13 @@
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py</script>
</completionHelp>
+ <valueHelp>
+ <format>txt</format>
+ <description>Interface name</description>
+ </valueHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
</properties>
<children>
#include <include/ospf-authentication.xml.i>
diff --git a/interface-definitions/protocols-rip.xml.in b/interface-definitions/protocols-rip.xml.in
index 2587e94c3..4ced26d8a 100644
--- a/interface-definitions/protocols-rip.xml.in
+++ b/interface-definitions/protocols-rip.xml.in
@@ -19,31 +19,8 @@
</constraint>
</properties>
</leafNode>
- <node name="default-information">
- <properties>
- <help>Control distribution of default route</help>
- </properties>
- <children>
- <leafNode name="originate">
- <properties>
- <help>Distribute a default route</help>
- <valueless/>
- </properties>
- </leafNode>
- </children>
- </node>
- <leafNode name="default-metric">
- <properties>
- <help>Metric of redistributed routes</help>
- <valueHelp>
- <format>u32:1-16</format>
- <description>Redistributed routes metric</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-16"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/rip-default-information.xml.i>
+ #include <include/rip-default-metric.xml.i>
<node name="distribute-list">
<properties>
<help>Filter networks in routing updates</help>
@@ -60,6 +37,9 @@
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py</script>
</completionHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
</properties>
<children>
#include <include/rip-access-list.xml.i>
@@ -69,19 +49,7 @@
#include <include/rip-prefix-list.xml.i>
</children>
</node>
- <leafNode name="interface">
- <properties>
- <help>Interface name</help>
- <valueHelp>
- <format>txt</format>
- <description>Apply filtering to an interface</description>
- </valueHelp>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
- </completionHelp>
- <multi/>
- </properties>
- </leafNode>
+ #include <include/rip-interface.xml.i>
<leafNode name="neighbor">
<properties>
<help>Neighbor router</help>
@@ -196,52 +164,7 @@
<multi/>
</properties>
</leafNode>
- <node name="timers">
- <properties>
- <help>RIP timer values</help>
- </properties>
- <children>
- <leafNode name="garbage-collection">
- <properties>
- <help>Garbage collection timer (default: 120)</help>
- <valueHelp>
- <format>u32:5-2147483647</format>
- <description>Garbage colletion time</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 5-2147483647"/>
- </constraint>
- </properties>
- <defaultValue>120</defaultValue>
- </leafNode>
- <leafNode name="timeout">
- <properties>
- <help>Routing information timeout timer (default: 180)</help>
- <valueHelp>
- <format>u32:5-2147483647</format>
- <description>Routing information timeout timer</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 5-2147483647"/>
- </constraint>
- </properties>
- <defaultValue>180</defaultValue>
- </leafNode>
- <leafNode name="update">
- <properties>
- <help>Routing table update timer (default: 30)</help>
- <valueHelp>
- <format>u32:5-2147483647</format>
- <description>Routing table update timer in seconds</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 5-2147483647"/>
- </constraint>
- </properties>
- <defaultValue>30</defaultValue>
- </leafNode>
- </children>
- </node>
+ #include <include/rip-timers.xml.i>
</children>
</node>
</children>
diff --git a/interface-definitions/protocols-ripng.xml.in b/interface-definitions/protocols-ripng.xml.in
index 2fca0f5dd..74f720e89 100644
--- a/interface-definitions/protocols-ripng.xml.in
+++ b/interface-definitions/protocols-ripng.xml.in
@@ -20,67 +20,14 @@
<multi/>
</properties>
</leafNode>
- <node name="default-information">
- <properties>
- <help>Control distribution of default route</help>
- </properties>
- <children>
- <leafNode name="originate">
- <properties>
- <help>Distribute a default route</help>
- <valueless/>
- </properties>
- </leafNode>
- </children>
- </node>
- <leafNode name="default-metric">
- <properties>
- <help>Metric of redistributed routes</help>
- <valueHelp>
- <format>u32:1-16</format>
- <description>Default metric</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-16"/>
- </constraint>
- </properties>
- </leafNode>
+ #include <include/rip-default-information.xml.i>
+ #include <include/rip-default-metric.xml.i>
<node name="distribute-list">
<properties>
<help>Filter networks in routing updates</help>
</properties>
<children>
- <node name="access-list">
- <properties>
- <help>Access-list</help>
- </properties>
- <children>
- <leafNode name="in">
- <properties>
- <help>Access list to apply to input packets</help>
- <valueHelp>
- <format>u32:1-4294967295</format>
- <description>Access list to apply to input packets</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-4294967295"/>
- </constraint>
- </properties>
- </leafNode>
- <leafNode name="out">
- <properties>
- <help>Access list to apply to output packets</help>
- <valueHelp>
- <format>u32:1-4294967295</format>
- <description>Access list to apply to output packets</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 1-4294967295"/>
- </constraint>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/rip-access-list6.xml.i>
<tagNode name="interface">
<properties>
<help>Apply filtering to an interface</help>
@@ -91,118 +38,19 @@
<completionHelp>
<script>${vyos_completion_dir}/list_interfaces.py</script>
</completionHelp>
+ <constraint>
+ <validator name="interface-name"/>
+ </constraint>
</properties>
<children>
- <node name="access-list">
- <properties>
- <help>Access list</help>
- </properties>
- <children>
- <leafNode name="in">
- <properties>
- <help>Access list to apply to input packets</help>
- <valueHelp>
- <format>u32:1-4294967295</format>
- <description>Access list to apply to input packets</description>
- </valueHelp>
- <completionHelp>
- <path>policy access-list6</path>
- </completionHelp>
- </properties>
- </leafNode>
- <leafNode name="out">
- <properties>
- <help>Access list to apply to output packets</help>
- <valueHelp>
- <format>u32:1-4294967295</format>
- <description>Access list to apply to output packets</description>
- </valueHelp>
- <completionHelp>
- <path>policy access-list</path>
- </completionHelp>
- </properties>
- </leafNode>
- </children>
- </node>
- <node name="prefix-list">
- <properties>
- <help>Prefix-list</help>
- </properties>
- <children>
- <leafNode name="in">
- <properties>
- <help>Prefix-list to apply to input packets</help>
- <valueHelp>
- <format>txt</format>
- <description>Prefix-list to apply to input packets</description>
- </valueHelp>
- <completionHelp>
- <path>policy prefix-list6</path>
- </completionHelp>
- </properties>
- </leafNode>
- <leafNode name="out">
- <properties>
- <help>Prefix-list to apply to output packets</help>
- <valueHelp>
- <format>txt</format>
- <description>Prefix-list to apply to output packets</description>
- </valueHelp>
- <completionHelp>
- <path>policy prefix-list6</path>
- </completionHelp>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/rip-access-list6.xml.i>
+ #include <include/rip-prefix-list6.xml.i>
</children>
</tagNode>
- <node name="prefix-list">
- <properties>
- <help>Prefix-list</help>
- </properties>
- <children>
- <leafNode name="in">
- <properties>
- <help>Prefix-list to apply to input packets</help>
- <valueHelp>
- <format>txt</format>
- <description>Prefix-list to apply to input packets</description>
- </valueHelp>
- <completionHelp>
- <path>policy prefix-list</path>
- </completionHelp>
- </properties>
- </leafNode>
- <leafNode name="out">
- <properties>
- <help>Prefix-list to apply to output packets</help>
- <valueHelp>
- <format>txt</format>
- <description>Prefix-list to apply to output packets</description>
- </valueHelp>
- <completionHelp>
- <path>policy prefix-list</path>
- </completionHelp>
- </properties>
- </leafNode>
- </children>
- </node>
+ #include <include/rip-prefix-list6.xml.i>
</children>
</node>
- <leafNode name="interface">
- <properties>
- <help>Interface name</help>
- <valueHelp>
- <format>txt</format>
- <description>Apply filtering to an interface</description>
- </valueHelp>
- <completionHelp>
- <script>${vyos_completion_dir}/list_interfaces.py</script>
- </completionHelp>
- <multi/>
- </properties>
- </leafNode>
+ #include <include/rip-interface.xml.i>
<leafNode name="network">
<properties>
<help>RIPng network</help>
@@ -289,60 +137,8 @@
<multi/>
</properties>
</leafNode>
- <leafNode name="route-map">
- <properties>
- <help>Filter routes installed in local route map</help>
- <completionHelp>
- <path>policy route-map</path>
- </completionHelp>
- </properties>
- </leafNode>
- <node name="timers">
- <properties>
- <help>RIPng timer values</help>
- </properties>
- <children>
- <leafNode name="garbage-collection">
- <properties>
- <help>Garbage collection timer</help>
- <valueHelp>
- <format>u32:5-2147483647</format>
- <description>Garbage colletion time (default 120)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 5-2147483647"/>
- </constraint>
- </properties>
- <defaultValue>120</defaultValue>
- </leafNode>
- <leafNode name="timeout">
- <properties>
- <help>Routing information timeout timer</help>
- <valueHelp>
- <format>u32:5-2147483647</format>
- <description>Routing information timeout timer (default 180)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 5-2147483647"/>
- </constraint>
- </properties>
- <defaultValue>180</defaultValue>
- </leafNode>
- <leafNode name="update">
- <properties>
- <help>Routing table update timer</help>
- <valueHelp>
- <format>u32:5-2147483647</format>
- <description>Routing table update timer in seconds (default 30)</description>
- </valueHelp>
- <constraint>
- <validator name="numeric" argument="--range 5-2147483647"/>
- </constraint>
- </properties>
- <defaultValue>30</defaultValue>
- </leafNode>
- </children>
- </node>
+ #include <include/ospf-route-map.xml.i>
+ #include <include/rip-timers.xml.i>
</children>
</node>
</children>
diff --git a/smoketest/configs/rip-router b/smoketest/configs/rip-router
new file mode 100644
index 000000000..0a3a41103
--- /dev/null
+++ b/smoketest/configs/rip-router
@@ -0,0 +1,138 @@
+interfaces {
+ dummy dum0 {
+ address 192.0.2.0/32
+ }
+ ethernet eth0 {
+ duplex auto
+ ip {
+ rip {
+ authentication {
+ md5 1 {
+ password VyOSsecure
+ }
+ }
+ split-horizon {
+ poison-reverse
+ }
+ }
+ }
+ smp-affinity auto
+ speed auto
+ address 172.18.202.10/24
+ }
+ ethernet eth1 {
+ duplex auto
+ smp-affinity auto
+ speed auto
+ vif 20 {
+ ip {
+ rip {
+ authentication {
+ plaintext-password VyOSsecure
+ }
+ split-horizon {
+ poison-reverse
+ }
+ }
+ }
+ }
+ vif-s 200 {
+ ip {
+ rip {
+ authentication {
+ md5 1 {
+ password VyOSsecure
+ }
+ }
+ split-horizon {
+ disable
+ }
+ }
+ }
+ vif-c 2000 {
+ ip {
+ rip {
+ authentication {
+ md5 1 {
+ password VyOSsecure
+ }
+ }
+ }
+ }
+ }
+ vif-c 3000 {
+ ip {
+ rip {
+ split-horizon {
+ disable
+ }
+ }
+ }
+ }
+ }
+ }
+}
+protocols {
+ rip {
+ default-distance 20
+ default-information {
+ originate
+ }
+ interface eth0
+ interface eth1.20
+ interface eth1.200
+ interface eth1.200.2000
+ interface eth1.200.3000
+ network 192.168.0.0/24
+ redistribute {
+ connected {
+ }
+ }
+ }
+}
+service {
+ ssh {
+ port 22
+ }
+}
+system {
+ config-management {
+ commit-revisions 100
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+ ntp {
+ server 0.pool.ntp.org {
+ }
+ server 1.pool.ntp.org {
+ }
+ server 2.pool.ntp.org {
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+}
+
+/* Warning: Do not remove the following line. */
+/* === vyatta-config-version: "broadcast-relay@1:cluster@1:config-management@1:conntrack-sync@1:conntrack@1:dhcp-relay@2:dhcp-server@5:dns-forwarding@1:firewall@5:ipsec@5:l2tp@1:mdns@1:nat@4:ntp@1:pptp@1:qos@1:quagga@6:snmp@1:ssh@1:system@10:vrrp@2:wanloadbalance@3:webgui@1:webproxy@1:webproxy@2:zone-policy@1" === */
+/* Release version: 1.2.6-S1 */
diff --git a/smoketest/scripts/cli/test_protocols_rip.py b/smoketest/scripts/cli/test_protocols_rip.py
index 1bd069638..2c5c9030a 100755
--- a/smoketest/scripts/cli/test_protocols_rip.py
+++ b/smoketest/scripts/cli/test_protocols_rip.py
@@ -64,7 +64,7 @@ class TestProtocolsRIP(unittest.TestCase):
# Check for running process
self.assertTrue(process_named_running(PROCESS_NAME))
- def test_rip_simple(self):
+ def test_rip(self):
distance = '40'
network_distance = '66'
metric = '8'
diff --git a/smoketest/scripts/cli/test_protocols_ripng.py b/smoketest/scripts/cli/test_protocols_ripng.py
new file mode 100755
index 000000000..90cbaccd8
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_ripng.py
@@ -0,0 +1,133 @@
+#!/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 <http://www.gnu.org/licenses/>.
+
+import os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.ifconfig import Section
+from vyos.util import cmd
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'ripngd'
+acl_in = '198'
+acl_out = '199'
+prefix_list_in = 'foo-prefix'
+prefix_list_out = 'bar-prefix'
+route_map = 'FooBar123'
+
+base_path = ['protocols', 'ripng']
+
+def getFRRconfig():
+ return cmd('vtysh -c "show run" | sed -n "/router ripng/,/^!/p"')
+
+class TestProtocolsRIPng(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+
+ self.session.set(['policy', 'access-list6', acl_in, 'rule', '10', 'action', 'permit'])
+ self.session.set(['policy', 'access-list6', acl_in, 'rule', '10', 'source', 'any'])
+ self.session.set(['policy', 'access-list6', acl_out, 'rule', '20', 'action', 'deny'])
+ self.session.set(['policy', 'access-list6', acl_out, 'rule', '20', 'source', 'any'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'action', 'permit'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_in, 'rule', '100', 'prefix', '2001:db8::/32'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'action', 'deny'])
+ self.session.set(['policy', 'prefix-list6', prefix_list_out, 'rule', '200', 'prefix', '2001:db8::/32'])
+ self.session.set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ self.session.delete(['policy', 'access-list6', acl_in])
+ self.session.delete(['policy', 'access-list6', acl_out])
+ self.session.delete(['policy', 'prefix-list6', prefix_list_in])
+ self.session.delete(['policy', 'prefix-list6', prefix_list_out])
+ self.session.delete(['policy', 'route-map', route_map])
+
+ self.session.commit()
+ del self.session
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_ripng(self):
+ metric = '8'
+ interfaces = Section.interfaces('ethernet')
+ aggregates = ['2001:db8:1000::/48', '2001:db8:2000::/48', '2001:db8:3000::/48']
+ networks = ['2001:db8:1000::/64', '2001:db8:1001::/64', '2001:db8:2000::/64', '2001:db8:2001::/64']
+ redistribute = ['bgp', 'connected', 'kernel', 'ospfv3', 'static']
+ timer_garbage = '888'
+ timer_timeout = '1000'
+ timer_update = '90'
+
+ self.session.set(base_path + ['default-information', 'originate'])
+ self.session.set(base_path + ['default-metric', metric])
+ self.session.set(base_path + ['distribute-list', 'access-list', 'in', acl_in])
+ self.session.set(base_path + ['distribute-list', 'access-list', 'out', acl_out])
+ self.session.set(base_path + ['distribute-list', 'prefix-list', 'in', prefix_list_in])
+ self.session.set(base_path + ['distribute-list', 'prefix-list', 'out', prefix_list_out])
+ self.session.set(base_path + ['passive-interface', 'default'])
+ self.session.set(base_path + ['timers', 'garbage-collection', timer_garbage])
+ self.session.set(base_path + ['timers', 'timeout', timer_timeout])
+ self.session.set(base_path + ['timers', 'update', timer_update])
+ for aggregate in aggregates:
+ self.session.set(base_path + ['aggregate-address', aggregate])
+
+ for interface in interfaces:
+ self.session.set(base_path + ['interface', interface])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'in', acl_in])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'access-list', 'out', acl_out])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'in', prefix_list_in])
+ self.session.set(base_path + ['distribute-list', 'interface', interface, 'prefix-list', 'out', prefix_list_out])
+ for network in networks:
+ self.session.set(base_path + ['network', network])
+ self.session.set(base_path + ['route', network])
+ for proto in redistribute:
+ self.session.set(base_path + ['redistribute', proto, 'metric', metric])
+ self.session.set(base_path + ['redistribute', proto, 'route-map', route_map])
+
+
+ # commit changes
+ self.session.commit()
+
+ # Verify FRR ospfd configuration
+ frrconfig = getFRRconfig()
+ self.assertIn(f'router ripng', frrconfig)
+ self.assertIn(f' default-information originate', frrconfig)
+ self.assertIn(f' default-metric {metric}', frrconfig)
+ self.assertIn(f' distribute-list {acl_in} in', frrconfig)
+ self.assertIn(f' distribute-list {acl_out} out', frrconfig)
+ self.assertIn(f' distribute-list prefix {prefix_list_in} in', frrconfig)
+ self.assertIn(f' distribute-list prefix {prefix_list_out} out', frrconfig)
+ self.assertIn(f' passive-interface default', frrconfig)
+ self.assertIn(f' timers basic {timer_update} {timer_timeout} {timer_garbage}', frrconfig)
+ for aggregate in aggregates:
+ self.assertIn(f' aggregate-address {aggregate}', frrconfig)
+ for interface in interfaces:
+ self.assertIn(f' network {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list {acl_in} in {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list {acl_out} out {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in} in {interface}', frrconfig)
+ self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out} out {interface}', frrconfig)
+ for network in networks:
+ self.assertIn(f' network {network}', frrconfig)
+ self.assertIn(f' route {network}', frrconfig)
+ for proto in redistribute:
+ if proto == 'ospfv3':
+ proto = 'ospf6'
+ self.assertIn(f' redistribute {proto} metric {metric} route-map {route_map}', frrconfig)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/conf_mode/protocols_rip.py b/src/conf_mode/protocols_rip.py
index bb3790fb2..06d7c6d49 100755
--- a/src/conf_mode/protocols_rip.py
+++ b/src/conf_mode/protocols_rip.py
@@ -89,6 +89,16 @@ def verify(rip):
if prefix_list_out and prefix_list_out.replace('-','_') not in (dict_search('policy.prefix_list', rip) or []):
raise ConfigError(f'Outbound prefix-list "{prefix_list_out}" does not exist!')
+ if 'interface' in rip:
+ for interface, interface_options in rip['interface'].items():
+ if 'authentication' in interface_options:
+ if {'md5', 'plaintext_password'} <= set(interface_options['authentication']):
+ raise ConfigError('Can not use both md5 and plaintext-password at the same time!')
+ if 'split_horizon' in interface_options:
+ if {'disable', 'poison_reverse'} <= set(interface_options['split_horizon']):
+ raise ConfigError(f'You can not have "split-horizon poison-reverse" enabled ' \
+ f'with "split-horizon disable" for "{interface}"!')
+
verify_route_maps(rip)
def generate(rip):
@@ -106,6 +116,7 @@ def apply(rip):
# Save original configuration prior to starting any commit actions
frr_cfg = frr.FRRConfig()
frr_cfg.load_configuration(frr_daemon)
+ frr_cfg.modify_section(r'key chain \S+', '')
frr_cfg.modify_section(r'interface \S+', '')
frr_cfg.modify_section('router rip', '')
frr_cfg.add_before(r'(ip prefix-list .*|route-map .*|line vty)', rip['new_frr_config'])
diff --git a/src/migration-scripts/interfaces/18-to-19 b/src/migration-scripts/interfaces/18-to-19
index 965b76a04..31e253098 100755
--- a/src/migration-scripts/interfaces/18-to-19
+++ b/src/migration-scripts/interfaces/18-to-19
@@ -18,6 +18,34 @@ from sys import argv
from sys import exit
from vyos.configtree import ConfigTree
+def migrate_ospf(config, path, interface):
+ path = path + ['ospf']
+ if config.exists(path):
+ new_base = ['protocols', 'ospf', 'interface']
+ config.set(new_base)
+ config.set_tag(new_base)
+ config.copy(path, new_base + [interface])
+ config.delete(path)
+
+ # if "ip ospf" was the only setting, we can clean out the empty
+ # ip node afterwards
+ if len(config.list_nodes(path[:-1])) == 0:
+ config.delete(path[:-1])
+
+def migrate_rip(config, path, interface):
+ path = path + ['rip']
+ if config.exists(path):
+ new_base = ['protocols', 'rip', 'interface']
+ config.set(new_base)
+ config.set_tag(new_base)
+ config.copy(path, new_base + [interface])
+ config.delete(path)
+
+ # if "ip rip" was the only setting, we can clean out the empty
+ # ip node afterwards
+ if len(config.list_nodes(path[:-1])) == 0:
+ config.delete(path[:-1])
+
if __name__ == '__main__':
if (len(argv) < 1):
print("Must specify file name!")
@@ -34,64 +62,33 @@ if __name__ == '__main__':
#
for type in config.list_nodes(['interfaces']):
for interface in config.list_nodes(['interfaces', type]):
-
- ip_ospf = ['interfaces', type, interface, 'ip', 'ospf']
- if config.exists(ip_ospf):
- config.set(['protocols', 'ospf', 'interface'])
- config.set_tag(['protocols', 'ospf', 'interface'])
- config.copy(ip_ospf, ['protocols', 'ospf', 'interface', interface])
- config.delete(ip_ospf)
-
- # if "ip ospf" was the only setting, we can clean out the empty
- # ip node afterwards
- if len(config.list_nodes(ip_ospf[:-1])) == 0:
- config.delete(ip_ospf[:-1])
+ if_base = ['interfaces', type, interface, 'ip']
+ migrate_rip(config, if_base, interface)
+ migrate_ospf(config, if_base, interface)
vif_path = ['interfaces', type, interface, 'vif']
if config.exists(vif_path):
for vif in config.list_nodes(vif_path):
- vif_ospf_path = vif_path + [vif, 'ip', 'ospf']
- if config.exists(vif_ospf_path):
- config.set(['protocols', 'ospf', 'interface'])
- config.set_tag(['protocols', 'ospf', 'interface'])
- config.copy(vif_ospf_path, ['protocols', 'ospf', 'interface', f'{interface}.{vif}'])
- config.delete(vif_ospf_path)
-
- # if "ip ospf" was the only setting, we can clean out the empty
- # ip node afterwards
- if len(config.list_nodes(vif_ospf_path[:-1])) == 0:
- config.delete(vif_ospf_path[:-1])
+ vif_if_base = vif_path + [vif, 'ip']
+ migrate_rip(config, vif_if_base, f'{interface}.{vif}')
+ migrate_ospf(config, vif_if_base, f'{interface}.{vif}')
vif_s_path = ['interfaces', type, interface, 'vif-s']
if config.exists(vif_s_path):
for vif_s in config.list_nodes(vif_s_path):
- vif_s_ospf_path = vif_s_path + [vif_s, 'ip', 'ospf']
- if config.exists(vif_s_ospf_path):
- config.set(['protocols', 'ospf', 'interface'])
- config.set_tag(['protocols', 'ospf', 'interface'])
- config.copy(vif_s_ospf_path, ['protocols', 'ospf', 'interface', f'{interface}.{vif_s}'])
+ vif_s_if_base = vif_s_path + [vif_s, 'ip']
- vif_c_path = ['interfaces', type, interface, 'vif-s', vif_s, 'vif-c']
- if config.exists(vif_c_path):
- for vif_c in config.list_nodes(vif_c_path):
- vif_c_ospf_path = vif_c_path + [vif_c, 'ip', 'ospf']
- if config.exists(vif_c_ospf_path):
- config.set(['protocols', 'ospf', 'interface'])
- config.set_tag(['protocols', 'ospf', 'interface'])
- config.copy(vif_c_ospf_path, ['protocols', 'ospf', 'interface', f'{interface}.{vif_s}.{vif_c}'])
- config.delete(vif_c_ospf_path)
+ # vif-c interfaces MUST be migrated before their parent vif-s
+ # interface as the migrate_*() functions delete the path!
+ vif_c_path = ['interfaces', type, interface, 'vif-s', vif_s, 'vif-c']
+ if config.exists(vif_c_path):
+ for vif_c in config.list_nodes(vif_c_path):
+ vif_c_if_base = vif_c_path + [vif_c, 'ip']
+ migrate_rip(config, vif_c_if_base, f'{interface}.{vif_s}.{vif_c}')
+ migrate_ospf(config, vif_c_if_base, f'{interface}.{vif_s}.{vif_c}')
- # if "ip ospf" was the only setting, we can clean out the empty
- # ip node afterwards
- if len(config.list_nodes(vif_c_ospf_path[:-1])) == 0:
- config.delete(vif_c_ospf_path[:-1])
-
- config.delete(vif_s_ospf_path)
-
- # if "ip ospf" was the only setting, we can clean out the empty
- # ip node afterwards
- if len(config.list_nodes(vif_s_ospf_path[:-1])) == 0:
- config.delete(vif_s_ospf_path[:-1])
+ migrate_rip(config, vif_s_if_base, f'{interface}.{vif_s}')
+ migrate_ospf(config, vif_s_if_base, f'{interface}.{vif_s}')
try:
with open(file_name, 'w') as f:
@@ -99,4 +96,3 @@ if __name__ == '__main__':
except OSError as e:
print("Failed to save the modified config: {}".format(e))
exit(1)
-
diff --git a/src/migration-scripts/rpki/0-to-1 b/src/migration-scripts/rpki/0-to-1
index 9058af016..5b4893205 100755
--- a/src/migration-scripts/rpki/0-to-1
+++ b/src/migration-scripts/rpki/0-to-1
@@ -48,7 +48,12 @@ if config.exists(base + ['cache']):
# Increase preference for the next caching peer - actually VyOS 1.2
# supported only one but better save then sorry (T3253)
preference += 1
- config.rename(base + ['cache', cache], address)
+
+ # T3293: If the RPKI cache name equals the configured address,
+ # renaming is not possible, as rename expects the new path to not
+ # exist.
+ if not config.exists(base + ['cache', address]):
+ config.rename(base + ['cache', cache], address)
try:
with open(file_name, 'w') as f:
diff --git a/src/migration-scripts/system/18-to-19 b/src/migration-scripts/system/18-to-19
index dd2abce00..fd0e15d42 100755
--- a/src/migration-scripts/system/18-to-19
+++ b/src/migration-scripts/system/18-to-19
@@ -80,8 +80,8 @@ else:
dhcp_interfaces.append(f'{intf}.{vif_s}')
# try vif-c
- if config.exists(intf_base + ['vif-c', vif_c]):
- for vif_c in config.list_nodes(vif_s_base + ['vif-c', vif_c]):
+ if config.exists(intf_base + ['vif-c']):
+ for vif_c in config.list_nodes(vif_s_base + ['vif-c']):
vif_c_base = vif_s_base + ['vif-c', vif_c]
if config.exists(vif_c_base + ['address']):
for addr in config.return_values(vif_c_base + ['address']):