summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/templates/frr/policy.frr.j24
-rw-r--r--data/templates/frr/static_routes_macro.j27
-rw-r--r--interface-definitions/include/static/static-route-bfd.xml.i37
-rw-r--r--interface-definitions/include/static/static-route.xml.i1
-rw-r--r--interface-definitions/include/static/static-route6.xml.i1
-rw-r--r--interface-definitions/policy.xml.in59
-rw-r--r--op-mode-definitions/counters.xml.in80
-rwxr-xr-xop-mode-definitions/generate-system-login-user.xml.in12
-rw-r--r--op-mode-definitions/openvpn.xml.in8
-rw-r--r--op-mode-definitions/reboot.xml.in2
-rw-r--r--op-mode-definitions/show-acceleration.xml.in2
-rw-r--r--op-mode-definitions/show-bfd.xml.in13
-rw-r--r--op-mode-definitions/show-interfaces-bonding.xml.in12
-rw-r--r--op-mode-definitions/show-interfaces-bridge.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-dummy.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-ethernet.xml.in12
-rw-r--r--op-mode-definitions/show-interfaces-geneve.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-input.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-l2tpv3.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-loopback.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-pppoe.xml.in6
-rw-r--r--op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-sstpc.xml.in6
-rw-r--r--op-mode-definitions/show-interfaces-tunnel.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-virtual-ethernet.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-vti.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-vxlan.xml.in8
-rw-r--r--op-mode-definitions/show-interfaces-wireguard.xml.in6
-rw-r--r--op-mode-definitions/show-interfaces-wireless.xml.in12
-rw-r--r--op-mode-definitions/show-interfaces-wwan.xml.in6
-rw-r--r--op-mode-definitions/vpn-ipsec.xml.in4
-rw-r--r--python/vyos/opmode.py5
-rw-r--r--python/vyos/utils/__init__.py0
-rw-r--r--python/vyos/utils/dict.py235
-rw-r--r--smoketest/configs/vrf-bgp-pppoe-underlay473
-rwxr-xr-xsmoketest/scripts/cli/test_policy.py23
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_static.py13
-rwxr-xr-xsrc/conf_mode/protocols_isis.py2
-rwxr-xr-xsrc/conf_mode/protocols_ospf.py2
-rwxr-xr-xsrc/conf_mode/protocols_ospfv3.py2
-rwxr-xr-xsrc/op_mode/bgp.py170
41 files changed, 1101 insertions, 202 deletions
diff --git a/data/templates/frr/policy.frr.j2 b/data/templates/frr/policy.frr.j2
index 9b5e80aed..ed5876ae9 100644
--- a/data/templates/frr/policy.frr.j2
+++ b/data/templates/frr/policy.frr.j2
@@ -245,6 +245,10 @@ route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
{% if rule_config.match.peer is vyos_defined %}
match peer {{ rule_config.match.peer }}
{% endif %}
+{% if rule_config.match.protocol is vyos_defined %}
+{% set source_protocol = 'ospf6' if rule_config.match.protocol == 'ospfv3' else rule_config.match.protocol %}
+ match source-protocol {{ source_protocol }}
+{% endif %}
{% if rule_config.match.rpki is vyos_defined %}
match rpki {{ rule_config.match.rpki }}
{% endif %}
diff --git a/data/templates/frr/static_routes_macro.j2 b/data/templates/frr/static_routes_macro.j2
index 1c64ac58b..8afd4a68a 100644
--- a/data/templates/frr/static_routes_macro.j2
+++ b/data/templates/frr/static_routes_macro.j2
@@ -18,7 +18,12 @@
{% endif %}
{% if prefix_config.next_hop is vyos_defined and prefix_config.next_hop is not none %}
{% for next_hop, next_hop_config in prefix_config.next_hop.items() if next_hop_config.disable is not defined %}
-{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is vyos_defined }} {{ next_hop_config.distance if next_hop_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ next_hop_config.vrf if next_hop_config.vrf is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
+{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} {{ next_hop_config.interface if next_hop_config.interface is vyos_defined }} {{ next_hop_config.distance if next_hop_config.distance is vyos_defined }} {{ 'nexthop-vrf ' ~ next_hop_config.vrf if next_hop_config.vrf is vyos_defined }} {{ 'bfd profile ' ~ next_hop_config.bfd.profile if next_hop_config.bfd.profile is vyos_defined }} {{ 'table ' ~ table if table is vyos_defined }}
+{% if next_hop_config.bfd.multi_hop.source is vyos_defined %}
+{% for source, source_config in next_hop_config.bfd.multi_hop.source.items() %}
+{{ ip_ipv6 }} route {{ prefix }} {{ next_hop }} bfd multi-hop source {{ source }} profile {{ source_config.profile }}
+{% endfor %}
+{% endif %}
{% endfor %}
{% endif %}
{% endmacro %}
diff --git a/interface-definitions/include/static/static-route-bfd.xml.i b/interface-definitions/include/static/static-route-bfd.xml.i
new file mode 100644
index 000000000..a05a08d12
--- /dev/null
+++ b/interface-definitions/include/static/static-route-bfd.xml.i
@@ -0,0 +1,37 @@
+<!-- include start from static/static-route-bfd.xml.i -->
+<node name="bfd">
+ <properties>
+ <help>BFD monitoring</help>
+ </properties>
+ <children>
+ #include <include/bfd/profile.xml.i>
+ <node name="multi-hop">
+ <properties>
+ <help>Use BFD multi hop session</help>
+ </properties>
+ <children>
+ <tagNode name="source">
+ <properties>
+ <help>Use source for BFD session</help>
+ <valueHelp>
+ <format>ipv4</format>
+ <description>IPv4 source address</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ipv6</format>
+ <description>IPv6 source address</description>
+ </valueHelp>
+ <constraint>
+ <validator name="ipv4-address"/>
+ <validator name="ipv6-address"/>
+ </constraint>
+ </properties>
+ <children>
+ #include <include/bfd/profile.xml.i>
+ </children>
+ </tagNode>
+ </children>
+ </node>
+ </children>
+</node>
+<!-- include end --> \ No newline at end of file
diff --git a/interface-definitions/include/static/static-route.xml.i b/interface-definitions/include/static/static-route.xml.i
index 268cfa005..29921a731 100644
--- a/interface-definitions/include/static/static-route.xml.i
+++ b/interface-definitions/include/static/static-route.xml.i
@@ -51,6 +51,7 @@
#include <include/static/static-route-distance.xml.i>
#include <include/static/static-route-interface.xml.i>
#include <include/static/static-route-vrf.xml.i>
+ #include <include/static/static-route-bfd.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/include/static/static-route6.xml.i b/interface-definitions/include/static/static-route6.xml.i
index 1f8d54108..a83cc230b 100644
--- a/interface-definitions/include/static/static-route6.xml.i
+++ b/interface-definitions/include/static/static-route6.xml.i
@@ -50,6 +50,7 @@
#include <include/static/static-route-distance.xml.i>
#include <include/static/static-route-interface.xml.i>
#include <include/static/static-route-vrf.xml.i>
+ #include <include/static/static-route-bfd.xml.i>
</children>
</tagNode>
</children>
diff --git a/interface-definitions/policy.xml.in b/interface-definitions/policy.xml.in
index 7d5fe79ef..02828c4f6 100644
--- a/interface-definitions/policy.xml.in
+++ b/interface-definitions/policy.xml.in
@@ -971,6 +971,65 @@
</constraint>
</properties>
</leafNode>
+ <leafNode name="protocol">
+ <properties>
+ <help>Match protocol via which the route was learnt</help>
+ <completionHelp>
+ <list>babel bgp connected isis kernel ospf ospfv3 rip ripng static table vnc</list>
+ </completionHelp>
+ <valueHelp>
+ <format>babel</format>
+ <description>Babel routing protocol (Babel)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>bgp</format>
+ <description>Border Gateway Protocol (BGP)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>connected</format>
+ <description>Connected routes (directly attached subnet or host)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>isis</format>
+ <description>Intermediate System to Intermediate System (IS-IS)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>kernel</format>
+ <description>Kernel routes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ospf</format>
+ <description>Open Shortest Path First (OSPFv2)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ospfv3</format>
+ <description>Open Shortest Path First (IPv6) (OSPFv3)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>rip</format>
+ <description>Routing Information Protocol (RIP)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>ripng</format>
+ <description>Routing Information Protocol next-generation (IPv6) (RIPng)</description>
+ </valueHelp>
+ <valueHelp>
+ <format>static</format>
+ <description>Statically configured routes</description>
+ </valueHelp>
+ <valueHelp>
+ <format>table</format>
+ <description>Non-main Kernel Routing Table</description>
+ </valueHelp>
+ <valueHelp>
+ <format>vnc</format>
+ <description>Virtual Network Control (VNC)</description>
+ </valueHelp>
+ <constraint>
+ <regex>(babel|bgp|connected|isis|kernel|ospf|ospfv3|rip|ripng|static|table|vnc)</regex>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="rpki">
<properties>
<help>Match RPKI validation result</help>
diff --git a/op-mode-definitions/counters.xml.in b/op-mode-definitions/counters.xml.in
index 4bf08d201..f563cb9a0 100644
--- a/op-mode-definitions/counters.xml.in
+++ b/op-mode-definitions/counters.xml.in
@@ -19,7 +19,7 @@
<properties>
<help>Clear all bonding interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -35,7 +35,7 @@
<properties>
<help>Clear interface counters for a given bonding interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -48,7 +48,7 @@
<properties>
<help>Clear all bridge interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -64,7 +64,7 @@
<properties>
<help>Clear interface counters for a given bridge interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -77,7 +77,7 @@
<properties>
<help>Clear all dummy interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -93,7 +93,7 @@
<properties>
<help>Clear interface counters for a given dummy interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -106,7 +106,7 @@
<properties>
<help>Clear all ethernet interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -122,7 +122,7 @@
<properties>
<help>Clear interface counters for a given ethernet interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -135,7 +135,7 @@
<properties>
<help>Clear all GENEVE interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -151,7 +151,7 @@
<properties>
<help>Clear interface counters for a given GENEVE interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -164,7 +164,7 @@
<properties>
<help>Clear all Input interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -180,7 +180,7 @@
<properties>
<help>Clear interface counters for a given Input interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -193,7 +193,7 @@
<properties>
<help>Clear all L2TPv3 interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -209,7 +209,7 @@
<properties>
<help>Clear interface counters for a given L2TPv3 interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -222,7 +222,7 @@
<properties>
<help>Clear all loopback interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -238,7 +238,7 @@
<properties>
<help>Clear interface counters for a given loopback interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -251,7 +251,7 @@
<properties>
<help>Clear all MACsec interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -267,7 +267,7 @@
<properties>
<help>Clear interface counters for a given MACsec interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -280,7 +280,7 @@
<properties>
<help>Clear all OpenVPN interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -296,7 +296,7 @@
<properties>
<help>Clear interface counters for a given OpenVPN interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -309,7 +309,7 @@
<properties>
<help>Clear all PPPoE interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -325,7 +325,7 @@
<properties>
<help>Clear interface counters for a given PPPoE interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -338,7 +338,7 @@
<properties>
<help>Clear all Pseudo-Ethernet interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -354,7 +354,7 @@
<properties>
<help>Clear interface counters for a given Pseudo-Ethernet interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -367,7 +367,7 @@
<properties>
<help>Clear all SSTP interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -383,7 +383,7 @@
<properties>
<help>Clear interface counters for a given SSTP interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -396,7 +396,7 @@
<properties>
<help>Clear all tunnel interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -412,7 +412,7 @@
<properties>
<help>Clear interface counters for a given tunnel interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -425,7 +425,7 @@
<properties>
<help>Clear all virtual-ethernet interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -441,7 +441,7 @@
<properties>
<help>Clear interface counters for a given virtual-ethernet interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -454,7 +454,7 @@
<properties>
<help>Clear all VTI interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -470,7 +470,7 @@
<properties>
<help>Clear interface counters for a given VTI interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -483,7 +483,7 @@
<properties>
<help>Clear all VXLAN interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -499,7 +499,7 @@
<properties>
<help>Clear interface counters for a given VXLAN interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -512,7 +512,7 @@
<properties>
<help>Clear all Wireguard interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</node>
</children>
</node>
@@ -528,7 +528,7 @@
<properties>
<help>Clear interface counters for a given Wireguard interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -541,7 +541,7 @@
<properties>
<help>Clear all wireless interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</leafNode>
</children>
</node>
@@ -557,7 +557,7 @@
<properties>
<help>Clear counters for a given wireless interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
@@ -570,7 +570,7 @@
<properties>
<help>Clear all WWAN interface counters</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_type "$3"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-type "$3"</command>
</leafNode>
</children>
</node>
@@ -586,7 +586,7 @@
<properties>
<help>Clear counters for a given WWAN interface</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf_name "$4"</command>
+ <command>sudo ${vyos_op_scripts_dir}/interfaces.py clear_counters --intf-name "$4"</command>
</leafNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/generate-system-login-user.xml.in b/op-mode-definitions/generate-system-login-user.xml.in
index d0519b6bd..237a13610 100755
--- a/op-mode-definitions/generate-system-login-user.xml.in
+++ b/op-mode-definitions/generate-system-login-user.xml.in
@@ -35,19 +35,19 @@
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9"</command>
+ <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate-limit "$9"</command>
<children>
<tagNode name="rate-time">
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9" --rate_time "${11}" </command>
+ <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate-limit "$9" --rate-time "${11}" </command>
<children>
<tagNode name="window-size">
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "$9" --rate_time "${11}" --window_size "${13}"</command>
+ <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate-limit "$9" --rate-time "${11}" --window-size "${13}"</command>
</tagNode>
</children>
</tagNode>
@@ -57,19 +57,19 @@
<properties>
<help>The number of digits in the one-time password</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --window_size "${9}"</command>
+ <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --window-size "${9}"</command>
<children>
<tagNode name="rate-limit">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "${11}" --window_size "${9}"</command>
+ <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate-limit "${11}" --window-size "${9}"</command>
<children>
<tagNode name="rate-time">
<properties>
<help>Duration of single time interval</help>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate_limit "${11}" --rate_time "${13}" --window_size "${9}"</command>
+ <command>sudo ${vyos_op_scripts_dir}/generate_system_login_user.py --username "$5" --rate-limit "${11}" --rate-time "${13}" --window-size "${9}"</command>
</tagNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/openvpn.xml.in b/op-mode-definitions/openvpn.xml.in
index 94647af02..f205b0026 100644
--- a/op-mode-definitions/openvpn.xml.in
+++ b/op-mode-definitions/openvpn.xml.in
@@ -37,13 +37,13 @@
<properties>
<help>Show OpenVPN interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=openvpn</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=openvpn</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed OpenVPN interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=openvpn</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=openvpn</command>
</leafNode>
</children>
</node>
@@ -54,7 +54,7 @@
<script>sudo ${vyos_completion_dir}/list_interfaces --type openvpn</script>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name=$4</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name=$4</command>
<children>
<tagNode name="user">
<properties>
@@ -95,7 +95,7 @@
<properties>
<help>Show summary of specified OpenVPN interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4"</command>
</leafNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/reboot.xml.in b/op-mode-definitions/reboot.xml.in
index 6414742d9..d5a71f561 100644
--- a/op-mode-definitions/reboot.xml.in
+++ b/op-mode-definitions/reboot.xml.in
@@ -25,7 +25,7 @@
<list>&lt;Minutes&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot_in $3 $4</command>
+ <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot-in $3 $4</command>
</tagNode>
<tagNode name="at">
<properties>
diff --git a/op-mode-definitions/show-acceleration.xml.in b/op-mode-definitions/show-acceleration.xml.in
index 6fd3babf5..fccfba5e3 100644
--- a/op-mode-definitions/show-acceleration.xml.in
+++ b/op-mode-definitions/show-acceleration.xml.in
@@ -21,7 +21,7 @@
<properties>
<help>Show QAT information for a given acceleration device</help>
<completionHelp>
- <script>${vyos_op_scripts_dir}/show_acceleration.py --dev_list</script>
+ <script>${vyos_op_scripts_dir}/show_acceleration.py --dev-list</script>
</completionHelp>
</properties>
<children>
diff --git a/op-mode-definitions/show-bfd.xml.in b/op-mode-definitions/show-bfd.xml.in
index 39e42e6ec..87d672e04 100644
--- a/op-mode-definitions/show-bfd.xml.in
+++ b/op-mode-definitions/show-bfd.xml.in
@@ -49,6 +49,19 @@
</leafNode>
</children>
</node>
+ <node name="static">
+ <properties>
+ <help>Show route Routing Table</help>
+ </properties>
+ <children>
+ <leafNode name="routes">
+ <properties>
+ <help>Showing BFD monitored static routes</help>
+ </properties>
+ <command>vtysh -c "show bfd static route"</command>
+ </leafNode>
+ </children>
+ </node>
</children>
</node>
</children>
diff --git a/op-mode-definitions/show-interfaces-bonding.xml.in b/op-mode-definitions/show-interfaces-bonding.xml.in
index c41e7bd5f..aa224e6cf 100644
--- a/op-mode-definitions/show-interfaces-bonding.xml.in
+++ b/op-mode-definitions/show-interfaces-bonding.xml.in
@@ -11,13 +11,13 @@
<path>interfaces bonding</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=bonding</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified bonding interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=bonding</command>
</leafNode>
<leafNode name="detail">
<properties>
@@ -38,13 +38,13 @@
<path>interfaces bonding ${COMP_WORDS[3]} vif</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4.$6" --intf_type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=bonding</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of specified virtual network interface (vif) information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4.$6" --intf_type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=bonding</command>
</leafNode>
</children>
</tagNode>
@@ -60,13 +60,13 @@
<properties>
<help>Show Bonding interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=bonding</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed bonding interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=bonding</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=bonding</command>
</leafNode>
<leafNode name="slaves">
<properties>
diff --git a/op-mode-definitions/show-interfaces-bridge.xml.in b/op-mode-definitions/show-interfaces-bridge.xml.in
index 22cd3ee67..dc813682d 100644
--- a/op-mode-definitions/show-interfaces-bridge.xml.in
+++ b/op-mode-definitions/show-interfaces-bridge.xml.in
@@ -11,13 +11,13 @@
<path>interfaces bridge</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=bridge</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=bridge</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified bridge interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=bridge</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=bridge</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show Bridge interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=bridge</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=bridge</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed bridge interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=bridge</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=bridge</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-dummy.xml.in b/op-mode-definitions/show-interfaces-dummy.xml.in
index 958d3483d..b8ec7da91 100644
--- a/op-mode-definitions/show-interfaces-dummy.xml.in
+++ b/op-mode-definitions/show-interfaces-dummy.xml.in
@@ -11,13 +11,13 @@
<path>interfaces dummy</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=dummy</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=dummy</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified dummy interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=dummy</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=dummy</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show Dummy interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=dummy</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=dummy</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed dummy interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=dummy</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=dummy</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-ethernet.xml.in b/op-mode-definitions/show-interfaces-ethernet.xml.in
index 81759c2b6..7c12d6084 100644
--- a/op-mode-definitions/show-interfaces-ethernet.xml.in
+++ b/op-mode-definitions/show-interfaces-ethernet.xml.in
@@ -11,13 +11,13 @@
<path>interfaces ethernet</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=ethernet</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified ethernet interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=ethernet</command>
</leafNode>
<leafNode name="identify">
<properties>
@@ -58,13 +58,13 @@
<path>interfaces ethernet ${COMP_WORDS[3]} vif</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4.$6" --intf_type=ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=ethernet</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of specified virtual network interface (vif) information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4.$6" --intf_type=ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=ethernet</command>
</leafNode>
</children>
</tagNode>
@@ -80,13 +80,13 @@
<properties>
<help>Show Ethernet interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=ethernet</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed ethernet interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=ethernet</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-geneve.xml.in b/op-mode-definitions/show-interfaces-geneve.xml.in
index 3cf45878d..d3d188031 100644
--- a/op-mode-definitions/show-interfaces-geneve.xml.in
+++ b/op-mode-definitions/show-interfaces-geneve.xml.in
@@ -11,13 +11,13 @@
<path>interfaces geneve</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=geneve</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=geneve</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified GENEVE interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=geneve</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=geneve</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show GENEVE interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=geneve</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=geneve</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed GENEVE interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=geneve</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=geneve</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-input.xml.in b/op-mode-definitions/show-interfaces-input.xml.in
index 5d93dcee6..e5d420056 100644
--- a/op-mode-definitions/show-interfaces-input.xml.in
+++ b/op-mode-definitions/show-interfaces-input.xml.in
@@ -11,13 +11,13 @@
<path>interfaces input</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=input</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=input</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified input interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=input</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=input</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show Input (ifb) interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=input</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=input</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed input interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=input</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=input</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-l2tpv3.xml.in b/op-mode-definitions/show-interfaces-l2tpv3.xml.in
index 713e36dac..2d165171c 100644
--- a/op-mode-definitions/show-interfaces-l2tpv3.xml.in
+++ b/op-mode-definitions/show-interfaces-l2tpv3.xml.in
@@ -11,13 +11,13 @@
<path>interfaces l2tpv3</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=l2tpv3</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=l2tpv3</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified L2TPv3 interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=l2tpv3</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=l2tpv3</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show L2TPv3 interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=l2tpv3</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=l2tpv3</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed L2TPv3 interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=l2tpv3</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=l2tpv3</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-loopback.xml.in b/op-mode-definitions/show-interfaces-loopback.xml.in
index a24151cc3..d341a6359 100644
--- a/op-mode-definitions/show-interfaces-loopback.xml.in
+++ b/op-mode-definitions/show-interfaces-loopback.xml.in
@@ -11,13 +11,13 @@
<path>interfaces loopback</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=loopback</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=loopback</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified Loopback interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=loopback</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=loopback</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show Loopback interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=loopback</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=loopback</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed Loopback interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=loopback</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=loopback</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-pppoe.xml.in b/op-mode-definitions/show-interfaces-pppoe.xml.in
index a34473148..1c6e0b83e 100644
--- a/op-mode-definitions/show-interfaces-pppoe.xml.in
+++ b/op-mode-definitions/show-interfaces-pppoe.xml.in
@@ -11,7 +11,7 @@
<path>interfaces pppoe</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=pppoe</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=pppoe</command>
<children>
<leafNode name="log">
<properties>
@@ -34,13 +34,13 @@
<properties>
<help>Show PPPoE interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=pppoe</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=pppoe</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed PPPoE interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=pppoe</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=pppoe</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in b/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in
index cb62639ee..4ab2a5fbb 100644
--- a/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in
+++ b/op-mode-definitions/show-interfaces-pseudo-ethernet.xml.in
@@ -11,13 +11,13 @@
<path>interfaces pseudo-ethernet</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=pseudo-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=pseudo-ethernet</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified pseudo-ethernet/MACvlan interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=pseudo-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=pseudo-ethernet</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show Pseudo-Ethernet/MACvlan interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=pseudo-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=pseudo-ethernet</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed pseudo-ethernet/MACvlan interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=pseudo-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=pseudo-ethernet</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-sstpc.xml.in b/op-mode-definitions/show-interfaces-sstpc.xml.in
index a619a9fd2..307276f72 100644
--- a/op-mode-definitions/show-interfaces-sstpc.xml.in
+++ b/op-mode-definitions/show-interfaces-sstpc.xml.in
@@ -11,7 +11,7 @@
<path>interfaces sstpc</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=sstpc</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=sstpc</command>
<children>
<leafNode name="log">
<properties>
@@ -34,13 +34,13 @@
<properties>
<help>Show SSTP client interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=sstpc</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=sstpc</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed SSTP client interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=sstpc</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=sstpc</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-tunnel.xml.in b/op-mode-definitions/show-interfaces-tunnel.xml.in
index 10e10e655..b99b0cbb2 100644
--- a/op-mode-definitions/show-interfaces-tunnel.xml.in
+++ b/op-mode-definitions/show-interfaces-tunnel.xml.in
@@ -11,13 +11,13 @@
<path>interfaces tunnel</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=tunnel</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=tunnel</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified tunnel interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=tunnel</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=tunnel</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show Tunnel interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=tunnel</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=tunnel</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed tunnel interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=tunnel</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=tunnel</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in b/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in
index c743492fb..18ae806b7 100644
--- a/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in
+++ b/op-mode-definitions/show-interfaces-virtual-ethernet.xml.in
@@ -11,13 +11,13 @@
<path>interfaces virtual-ethernet</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=virtual-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=virtual-ethernet</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified virtual-ethernet interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=virtual-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=virtual-ethernet</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show virtual-ethernet interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=virtual-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=virtual-ethernet</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed virtual-ethernet interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=virtual-ethernet</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=virtual-ethernet</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-vti.xml.in b/op-mode-definitions/show-interfaces-vti.xml.in
index d532894b7..ae5cfeb9c 100644
--- a/op-mode-definitions/show-interfaces-vti.xml.in
+++ b/op-mode-definitions/show-interfaces-vti.xml.in
@@ -11,13 +11,13 @@
<path>interfaces vti</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=vti</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=vti</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified vti interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=vti</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=vti</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show VTI interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=vti</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=vti</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed vti interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=vti</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=vti</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-vxlan.xml.in b/op-mode-definitions/show-interfaces-vxlan.xml.in
index fde832551..fd729b986 100644
--- a/op-mode-definitions/show-interfaces-vxlan.xml.in
+++ b/op-mode-definitions/show-interfaces-vxlan.xml.in
@@ -11,13 +11,13 @@
<path>interfaces vxlan</path>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=vxlan</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=vxlan</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified VXLAN interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=vxlan</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=vxlan</command>
</leafNode>
</children>
</tagNode>
@@ -25,13 +25,13 @@
<properties>
<help>Show VXLAN interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=vxlan</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=vxlan</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed VXLAN interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=vxlan</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=vxlan</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-wireguard.xml.in b/op-mode-definitions/show-interfaces-wireguard.xml.in
index d045beafc..bab7f19c8 100644
--- a/op-mode-definitions/show-interfaces-wireguard.xml.in
+++ b/op-mode-definitions/show-interfaces-wireguard.xml.in
@@ -11,7 +11,7 @@
<script>${vyos_completion_dir}/list_interfaces --type wireguard</script>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=wireguard</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wireguard</command>
<children>
<leafNode name="allowed-ips">
<properties>
@@ -49,13 +49,13 @@
<properties>
<help>Show WireGuard interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=wireguard</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=wireguard</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed Wireguard interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=wireguard</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=wireguard</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/show-interfaces-wireless.xml.in b/op-mode-definitions/show-interfaces-wireless.xml.in
index f39d402f1..27c0f43db 100644
--- a/op-mode-definitions/show-interfaces-wireless.xml.in
+++ b/op-mode-definitions/show-interfaces-wireless.xml.in
@@ -8,13 +8,13 @@
<properties>
<help>Show Wireless (WLAN) interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=wireless</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed wireless interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=wireless</command>
</leafNode>
<leafNode name="info">
<properties>
@@ -31,13 +31,13 @@
<script>${vyos_completion_dir}/list_interfaces --type wireless</script>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wireless</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of the specified wireless interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4" --intf_type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4" --intf-type=wireless</command>
</leafNode>
<node name="scan">
<properties>
@@ -63,13 +63,13 @@
<properties>
<help>Show specified virtual network interface (vif) information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4.$6" --intf_type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4.$6" --intf-type=wireless</command>
<children>
<leafNode name="brief">
<properties>
<help>Show summary of specified virtual network interface (vif) information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4.$6" --intf_type=wireless</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-name="$4.$6" --intf-type=wireless</command>
</leafNode>
</children>
</tagNode>
diff --git a/op-mode-definitions/show-interfaces-wwan.xml.in b/op-mode-definitions/show-interfaces-wwan.xml.in
index 17d4111a9..2707c0d8e 100644
--- a/op-mode-definitions/show-interfaces-wwan.xml.in
+++ b/op-mode-definitions/show-interfaces-wwan.xml.in
@@ -12,7 +12,7 @@
<script>cd /sys/class/net; ls -d wwan*</script>
</completionHelp>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4" --intf_type=wirelessmodem</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-name="$4" --intf-type=wirelessmodem</command>
<children>
<leafNode name="capabilities">
<properties>
@@ -86,13 +86,13 @@
<properties>
<help>Show Wireless Modem (WWAN) interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=wirelessmodem</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf-type=wirelessmodem</command>
<children>
<leafNode name="detail">
<properties>
<help>Show detailed Wireless Modem (WWAN( interface information</help>
</properties>
- <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=wirelessmodem</command>
+ <command>${vyos_op_scripts_dir}/interfaces.py show --intf-type=wirelessmodem</command>
</leafNode>
</children>
</node>
diff --git a/op-mode-definitions/vpn-ipsec.xml.in b/op-mode-definitions/vpn-ipsec.xml.in
index 1eb5a3709..c7ba780a3 100644
--- a/op-mode-definitions/vpn-ipsec.xml.in
+++ b/op-mode-definitions/vpn-ipsec.xml.in
@@ -35,7 +35,7 @@
<list>&lt;x.x.x.x&gt; &lt;h:h:h:h:h:h:h:h&gt;</list>
</completionHelp>
</properties>
- <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_profile_dst --profile="$5" --tunnel="$7" --nbma_dst="$9"</command>
+ <command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_profile_dst --profile="$5" --tunnel="$7" --nbma-dst="$9"</command>
</tagNode>
</children>
<command>sudo ${vyos_op_scripts_dir}/ipsec.py reset_profile_all --profile="$5" --tunnel="$7"</command>
@@ -219,7 +219,7 @@
<properties>
<help>Show detail active IKEv2 RA sessions by connection-id</help>
</properties>
- <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_ra_detail --conn_id="$6"; else echo "IPsec process not running" ; fi</command>
+ <command>if systemctl is-active --quiet strongswan ; then sudo ${vyos_op_scripts_dir}/ipsec.py show_ra_detail --conn-id="$6"; else echo "IPsec process not running" ; fi</command>
</tagNode>
<node name="summary">
<properties>
diff --git a/python/vyos/opmode.py b/python/vyos/opmode.py
index d7172a0b5..230a85541 100644
--- a/python/vyos/opmode.py
+++ b/python/vyos/opmode.py
@@ -209,6 +209,11 @@ def run(module):
for opt in type_hints:
th = type_hints[opt]
+ # Function argument names use underscores as separators
+ # but command-line options should use hyphens
+ # Without this, we'd get options like "--foo_bar"
+ opt = re.sub(r'_', '-', opt)
+
if _get_arg_type(th) == bool:
subparser.add_argument(f"--{opt}", action='store_true')
else:
diff --git a/python/vyos/utils/__init__.py b/python/vyos/utils/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/python/vyos/utils/__init__.py
diff --git a/python/vyos/utils/dict.py b/python/vyos/utils/dict.py
new file mode 100644
index 000000000..66b40d92b
--- /dev/null
+++ b/python/vyos/utils/dict.py
@@ -0,0 +1,235 @@
+# Copyright 2023 VyOS maintainers and contributors <maintainers@vyos.io>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+
+
+def colon_separated_to_dict(data_string, uniquekeys=False):
+ """ Converts a string containing newline-separated entries
+ of colon-separated key-value pairs into a dict.
+
+ Such files are common in Linux /proc filesystem
+
+ Args:
+ data_string (str): data string
+ uniquekeys (bool): whether to insist that keys are unique or not
+
+ Returns: dict
+
+ Raises:
+ ValueError: if uniquekeys=True and the data string has
+ duplicate keys.
+
+ Note:
+ If uniquekeys=True, then dict entries are always strings,
+ otherwise they are always lists of strings.
+ """
+ import re
+ key_value_re = re.compile('([^:]+)\s*\:\s*(.*)')
+
+ data_raw = re.split('\n', data_string)
+
+ data = {}
+
+ for l in data_raw:
+ l = l.strip()
+ if l:
+ match = re.match(key_value_re, l)
+ if match and (len(match.groups()) == 2):
+ key = match.groups()[0].strip()
+ value = match.groups()[1].strip()
+ else:
+ raise ValueError(f"""Line "{l}" could not be parsed a colon-separated pair """, l)
+ if key in data.keys():
+ if uniquekeys:
+ raise ValueError("Data string has duplicate keys: {0}".format(key))
+ else:
+ data[key].append(value)
+ else:
+ if uniquekeys:
+ data[key] = value
+ else:
+ data[key] = [value]
+ else:
+ pass
+
+ return data
+
+def _mangle_dict_keys(data, regex, replacement, abs_path=[], no_tag_node_value_mangle=False, mod=0):
+ """ Mangles dict keys according to a regex and replacement character.
+ Some libraries like Jinja2 do not like certain characters in dict keys.
+ This function can be used for replacing all offending characters
+ with something acceptable.
+
+ Args:
+ data (dict): Original dict to mangle
+
+ Returns: dict
+ """
+ from vyos.xml import is_tag
+
+ new_dict = {}
+
+ for key in data.keys():
+ save_mod = mod
+ save_path = abs_path[:]
+
+ abs_path.append(key)
+
+ if not is_tag(abs_path):
+ new_key = re.sub(regex, replacement, key)
+ else:
+ if mod%2:
+ new_key = key
+ else:
+ new_key = re.sub(regex, replacement, key)
+ if no_tag_node_value_mangle:
+ mod += 1
+
+ value = data[key]
+
+ if isinstance(value, dict):
+ new_dict[new_key] = _mangle_dict_keys(value, regex, replacement, abs_path=abs_path, mod=mod, no_tag_node_value_mangle=no_tag_node_value_mangle)
+ else:
+ new_dict[new_key] = value
+
+ mod = save_mod
+ abs_path = save_path[:]
+
+ return new_dict
+
+def mangle_dict_keys(data, regex, replacement, abs_path=[], no_tag_node_value_mangle=False):
+ return _mangle_dict_keys(data, regex, replacement, abs_path=abs_path, no_tag_node_value_mangle=no_tag_node_value_mangle, mod=0)
+
+def _get_sub_dict(d, lpath):
+ k = lpath[0]
+ if k not in d.keys():
+ return {}
+ c = {k: d[k]}
+ lpath = lpath[1:]
+ if not lpath:
+ return c
+ elif not isinstance(c[k], dict):
+ return {}
+ return _get_sub_dict(c[k], lpath)
+
+def get_sub_dict(source, lpath, get_first_key=False):
+ """ Returns the sub-dict of a nested dict, defined by path of keys.
+
+ Args:
+ source (dict): Source dict to extract from
+ lpath (list[str]): sequence of keys
+
+ Returns: source, if lpath is empty, else
+ {key : source[..]..[key]} for key the last element of lpath, if exists
+ {} otherwise
+ """
+ if not isinstance(source, dict):
+ raise TypeError("source must be of type dict")
+ if not isinstance(lpath, list):
+ raise TypeError("path must be of type list")
+ if not lpath:
+ return source
+
+ ret = _get_sub_dict(source, lpath)
+
+ if get_first_key and lpath and ret:
+ tmp = next(iter(ret.values()))
+ if not isinstance(tmp, dict):
+ raise TypeError("Data under node is not of type dict")
+ ret = tmp
+
+ return ret
+
+def dict_search(path, dict_object):
+ """ Traverse Python dictionary (dict_object) delimited by dot (.).
+ Return value of key if found, None otherwise.
+
+ This is faster implementation then jmespath.search('foo.bar', dict_object)"""
+ if not isinstance(dict_object, dict) or not path:
+ return None
+
+ parts = path.split('.')
+ inside = parts[:-1]
+ if not inside:
+ if path not in dict_object:
+ return None
+ return dict_object[path]
+ c = dict_object
+ for p in parts[:-1]:
+ c = c.get(p, {})
+ return c.get(parts[-1], None)
+
+def dict_search_args(dict_object, *path):
+ # Traverse dictionary using variable arguments
+ # Added due to above function not allowing for '.' in the key names
+ # Example: dict_search_args(some_dict, 'key', 'subkey', 'subsubkey', ...)
+ if not isinstance(dict_object, dict) or not path:
+ return None
+
+ for item in path:
+ if item not in dict_object:
+ return None
+ dict_object = dict_object[item]
+ return dict_object
+
+def dict_search_recursive(dict_object, key, path=[]):
+ """ Traverse a dictionary recurisvely and return the value of the key
+ we are looking for.
+
+ Thankfully copied from https://stackoverflow.com/a/19871956
+
+ Modified to yield optional path to found keys
+ """
+ if isinstance(dict_object, list):
+ for i in dict_object:
+ new_path = path + [i]
+ for x in dict_search_recursive(i, key, new_path):
+ yield x
+ elif isinstance(dict_object, dict):
+ if key in dict_object:
+ new_path = path + [key]
+ yield dict_object[key], new_path
+ for k, j in dict_object.items():
+ new_path = path + [k]
+ for x in dict_search_recursive(j, key, new_path):
+ yield x
+
+def dict_to_list(d, save_key_to=None):
+ """ Convert a dict to a list of dicts.
+
+ Optionally, save the original key of the dict inside
+ dicts stores in that list.
+ """
+ def save_key(i, k):
+ if isinstance(i, dict):
+ i[save_key_to] = k
+ return
+ elif isinstance(i, list):
+ for _i in i:
+ save_key(_i, k)
+ else:
+ raise ValueError(f"Cannot save the key: the item is {type(i)}, not a dict")
+
+ collect = []
+
+ for k,_ in d.items():
+ item = d[k]
+ if save_key_to is not None:
+ save_key(item, k)
+ if isinstance(item, list):
+ collect += item
+ else:
+ collect.append(item)
+
+ return collect
diff --git a/smoketest/configs/vrf-bgp-pppoe-underlay b/smoketest/configs/vrf-bgp-pppoe-underlay
new file mode 100644
index 000000000..cba35eab1
--- /dev/null
+++ b/smoketest/configs/vrf-bgp-pppoe-underlay
@@ -0,0 +1,473 @@
+interfaces {
+ bridge br50 {
+ address 192.168.0.1/24
+ member {
+ interface eth0.50 {
+ }
+ interface eth2 {
+ }
+ interface eth3 {
+ }
+ }
+ }
+ dummy dum0 {
+ address 100.64.51.252/32
+ address 2001:db8:200:ffff::1/128
+ vrf vyos-test-01
+ }
+ ethernet eth0 {
+ offload {
+ gro
+ gso
+ rps
+ sg
+ tso
+ }
+ ring-buffer {
+ rx 256
+ tx 256
+ }
+ vif 5 {
+ address 2001:db8:200:f0::114/64
+ address 100.64.50.121/28
+ vrf vyos-test-01
+ }
+ vif 10 {
+ address 2001:db8:200:10::ffff/64
+ address 2001:db8:200::ffff/64
+ address 100.64.50.62/26
+ vrf vyos-test-01
+ }
+ vif 15 {
+ address 100.64.50.78/28
+ address 2001:db8:200:15::ffff/64
+ vrf vyos-test-01
+ }
+ vif 50 {
+ description "Member of bridge br50"
+ }
+ vif 110 {
+ address 100.64.51.190/27
+ address 100.64.51.158/28
+ address 2001:db8:200:101::ffff/64
+ vrf vyos-test-01
+ }
+ vif 410 {
+ address 100.64.51.206/28
+ address 2001:db8:200:104::ffff/64
+ vrf vyos-test-01
+ }
+ vif 500 {
+ address 100.64.51.238/28
+ address 2001:db8:200:50::ffff/64
+ vrf vyos-test-01
+ }
+ vif 520 {
+ address 100.64.50.190/28
+ address 2001:db8:200:520::ffff/64
+ vrf vyos-test-01
+ }
+ vif 666 {
+ address 2001:db8:200:ff::101:1/112
+ address 100.64.51.223/31
+ vrf vyos-test-01
+ }
+ vif 800 {
+ address 2001:db8:200:ff::104:1/112
+ address 100.64.51.212/31
+ vrf vyos-test-01
+ }
+ vif 810 {
+ address 100.64.51.30/27
+ address 2001:db8:200:102::ffff/64
+ vrf vyos-test-01
+ }
+ }
+ ethernet eth1 {
+ offload {
+ gro
+ gso
+ rps
+ sg
+ tso
+ }
+ ring-buffer {
+ rx 256
+ tx 256
+ }
+ }
+ ethernet eth2 {
+ offload {
+ gro
+ gso
+ sg
+ tso
+ }
+ }
+ ethernet eth3 {
+ offload {
+ gro
+ gso
+ sg
+ tso
+ }
+ }
+ loopback lo {
+ }
+ pppoe pppoe7 {
+ authentication {
+ password vyos
+ username vyos
+ }
+ dhcpv6-options {
+ pd 0 {
+ interface br50 {
+ address 1
+ }
+ length 56
+ }
+ }
+ ip {
+ adjust-mss 1452
+ }
+ ipv6 {
+ address {
+ autoconf
+ }
+ adjust-mss 1432
+ }
+ mtu 1492
+ no-peer-dns
+ source-interface eth1
+ }
+ virtual-ethernet veth0 {
+ address 100.64.51.220/31
+ address 2001:db8:200:ff::105:1/112
+ description "Core: connect vyos-test-01 and default VRF"
+ peer-name veth1
+ }
+ virtual-ethernet veth1 {
+ address 100.64.51.221/31
+ address 2001:db8:200:ff::105:2/112
+ description "Core: connect vyos-test-01 and default VRF"
+ peer-name veth0
+ vrf vyos-test-01
+ }
+ wireguard wg500 {
+ address 100.64.51.209/31
+ mtu 1500
+ peer A {
+ address 192.0.2.1
+ allowed-ips 0.0.0.0/0
+ port 5500
+ public-key KGSXF4QckzGe7f7CT+r6VZ5brOD/pVYk8yvrxOQ+X0Y=
+ }
+ port 5500
+ private-key iLJh6Me6AdPJtNv3dgGhUbtyFxExxmNU4v0Fs6YE2Xc=
+ vrf vyos-test-01
+ }
+ wireguard wg501 {
+ address 2001:db8:200:ff::102:2/112
+ mtu 1500
+ peer A {
+ address 2001:db8:300::1
+ allowed-ips ::/0
+ port 5501
+ public-key OF+1OJ+VfQ0Yw1mgVtQ2ion4CnAdy8Bvx7yEiO4+Pn8=
+ }
+ port 5501
+ private-key 0MP5X0PW58O4q2LDpuIXgZ0ySyAoWH8/kdpvQccCbUU=
+ vrf vyos-test-01
+ }
+ wireguard wg666 {
+ address 172.29.0.0/31
+ mtu 1500
+ peer B {
+ allowed-ips 0.0.0.0/0
+ public-key 2HT+RfwcqJMYNYzdmtmpem8Ht0dL37o31APHVwmh024=
+ }
+ port 50666
+ private-key zvPnp2MLAoX7SotuHLFLDyy4sdlD7ttbD1xNEqA3mkU=
+ }
+}
+nat {
+ source {
+ rule 100 {
+ outbound-interface pppoe7
+ source {
+ address 192.168.0.0/24
+ }
+ translation {
+ address masquerade
+ }
+ }
+ }
+}
+policy {
+ prefix-list AS100-origin-v4 {
+ rule 10 {
+ action permit
+ prefix 100.64.0.0/12
+ }
+ rule 100 {
+ action permit
+ prefix 0.0.0.0/0
+ }
+ }
+ prefix-list AS200-origin-v4 {
+ rule 10 {
+ action permit
+ prefix 10.0.0.0/8
+ }
+ rule 20 {
+ action permit
+ prefix 172.16.0.0/12
+ }
+
+ }
+ prefix-list6 AS100-origin-v6 {
+ rule 10 {
+ action permit
+ prefix 2001:db8:200::/40
+ }
+ }
+ prefix-list6 AS200-origin-v6 {
+ rule 10 {
+ action permit
+ prefix 2001:db8:100::/40
+ }
+ }
+}
+protocols {
+ static {
+ route 192.0.2.255/32 {
+ interface pppoe7 {
+ }
+ }
+ route 100.64.50.0/23 {
+ next-hop 100.64.51.221 {
+ }
+ }
+ route6 2001:db8:ffff:ffff:ffff:ffff:ffff:ffff/128 {
+ interface pppoe7 {
+ }
+ }
+ }
+}
+qos {
+ interface pppoe7 {
+ egress isp-out
+ }
+ policy {
+ shaper isp-out {
+ bandwidth 38mbit
+ default {
+ bandwidth 100%
+ burst 15k
+ queue-limit 1000
+ queue-type fq-codel
+ }
+ }
+ }
+}
+service {
+ router-advert {
+ interface br50 {
+ prefix ::/64 {
+ preferred-lifetime 2700
+ valid-lifetime 5400
+ }
+ }
+ interface eth0.500 {
+ default-preference high
+ name-server 2001:db8:200::1
+ name-server 2001:db8:200::2
+ prefix 2001:db8:200:50::/64 {
+ valid-lifetime infinity
+ }
+ }
+ interface eth0.520 {
+ default-preference high
+ name-server 2001:db8:200::1
+ name-server 2001:db8:200::2
+ prefix 2001:db8:200:520::/64 {
+ valid-lifetime infinity
+ }
+ }
+ }
+ ssh {
+ disable-host-validation
+ dynamic-protection {
+ allow-from 100.64.0.0/10
+ allow-from 2001:db8:200::/40
+ }
+ }
+}
+system {
+ config-management {
+ commit-revisions 100
+ }
+ conntrack {
+ modules {
+ ftp
+ h323
+ nfs
+ pptp
+ sip
+ sqlnet
+ tftp
+ }
+ }
+ console {
+ device ttyS0 {
+ speed 115200
+ }
+ }
+ domain-name vyos.net
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password $6$O5gJRlDYQpj$MtrCV9lxMnZPMbcxlU7.FI793MImNHznxGoMFgm3Q6QP3vfKJyOSRCt3Ka/GzFQyW1yZS4NS616NLHaIPPFHc0
+ plaintext-password ""
+ }
+ }
+ }
+ name-server 192.168.0.1
+ syslog {
+ global {
+ facility all {
+ level info
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+ time-zone Europe/Berlin
+}
+vrf {
+ bind-to-all
+ name vyos-test-01 {
+ protocols {
+ bgp {
+ address-family {
+ ipv4-unicast {
+ network 100.64.50.0/23 {
+ }
+ }
+ ipv6-unicast {
+ network 2001:db8:200:ffff::1/128 {
+ }
+ }
+ }
+ neighbor 100.64.51.208 {
+ peer-group AS100v4
+ }
+ neighbor 100.64.51.222 {
+ address-family {
+ ipv4-unicast {
+ default-originate {
+ }
+ maximum-prefix 10
+ prefix-list {
+ export AS100-origin-v4
+ import AS200-origin-v4
+ }
+ soft-reconfiguration {
+ inbound
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as 200
+ }
+ neighbor 100.64.51.251 {
+ peer-group AS100v4
+ shutdown
+ }
+ neighbor 100.64.51.254 {
+ peer-group AS100v4
+ shutdown
+ }
+ neighbor 2001:db8:200:ffff::2 {
+ peer-group AS100v6
+ shutdown
+ }
+ neighbor 2001:db8:200:ffff::a {
+ peer-group AS100v6
+ }
+ neighbor 2001:db8:200:ff::101:2 {
+ address-family {
+ ipv6-unicast {
+ maximum-prefix 10
+ prefix-list {
+ export AS100-origin-v6
+ import AS200-origin-v6
+ }
+ soft-reconfiguration {
+ inbound
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as 200
+ }
+ peer-group AS100v4 {
+ address-family {
+ ipv4-unicast {
+ nexthop-self {
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as internal
+ update-source dum0
+ }
+ peer-group AS100v6 {
+ address-family {
+ ipv6-unicast {
+ nexthop-self {
+ }
+ }
+ }
+ capability {
+ dynamic
+ }
+ remote-as internal
+ update-source dum0
+ }
+ system-as 100
+ }
+ static {
+ route 192.168.0.0/24 {
+ next-hop 100.64.51.220 {
+ }
+ }
+ route 100.64.50.0/23 {
+ blackhole {
+ }
+ }
+ route 100.64.51.32/27 {
+ next-hop 100.64.51.5 {
+ }
+ }
+ route6 2001:db8:2fe:ffff::/64 {
+ next-hop 2001:db8:200:102::5 {
+ }
+ }
+ }
+ }
+ table 1000
+ }
+}
+
+// Warning: Do not remove the following line.
+// vyos-config-version: "bgp@3:broadcast-relay@1:cluster@1:config-management@1:conntrack@3:conntrack-sync@2:container@1:dhcp-relay@2:dhcp-server@6:dhcpv6-server@1:dns-forwarding@3:firewall@9:flow-accounting@1:https@4:ids@1:interfaces@28:ipoe-server@1:ipsec@12:isis@2:l2tp@4:lldp@1:mdns@1:monitoring@1:nat@5:nat66@1:ntp@2:openconnect@2:ospf@1:policy@5:pppoe-server@6:pptp@2:qos@2:quagga@10:rpki@1:salt@1:snmp@3:ssh@2:sstp@4:system@25:vrf@3:vrrp@3:vyos-accel-ppp@2:wanloadbalance@3:webproxy@2"
+// Release version: 1.4-rolling-202303160317
diff --git a/smoketest/scripts/cli/test_policy.py b/smoketest/scripts/cli/test_policy.py
index 3a4ef666a..f35cdaa4c 100755
--- a/smoketest/scripts/cli/test_policy.py
+++ b/smoketest/scripts/cli/test_policy.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2021-2022 VyOS maintainers and contributors
+# Copyright (C) 2021-2023 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
@@ -1071,6 +1071,22 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
},
},
},
+ 'match-protocol' : {
+ 'rule' : {
+ '10' : {
+ 'action' : 'permit',
+ 'match' : {
+ 'protocol' : 'static',
+ },
+ },
+ '20' : {
+ 'action' : 'permit',
+ 'match' : {
+ 'protocol' : 'bgp',
+ },
+ },
+ },
+ },
'relative-metric' : {
'rule' : {
'10' : {
@@ -1202,6 +1218,8 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
self.cli_set(path + ['rule', rule, 'match', 'rpki', 'notfound'])
if 'rpki-valid' in rule_config['match']:
self.cli_set(path + ['rule', rule, 'match', 'rpki', 'valid'])
+ if 'protocol' in rule_config['match']:
+ self.cli_set(path + ['rule', rule, 'match', 'protocol', rule_config['match']['protocol']])
if 'tag' in rule_config['match']:
self.cli_set(path + ['rule', rule, 'match', 'tag', rule_config['match']['tag']])
@@ -1368,6 +1386,9 @@ class TestPolicy(VyOSUnitTestSHIM.TestCase):
if 'peer' in rule_config['match']:
tmp = f'match peer {rule_config["match"]["peer"]}'
self.assertIn(tmp, config)
+ if 'protocol' in rule_config['match']:
+ tmp = f'match source-protocol {rule_config["match"]["protocol"]}'
+ self.assertIn(tmp, config)
if 'rpki-invalid' in rule_config['match']:
tmp = f'match rpki invalid'
self.assertIn(tmp, config)
diff --git a/smoketest/scripts/cli/test_protocols_static.py b/smoketest/scripts/cli/test_protocols_static.py
index 706663ce5..275f1a1df 100755
--- a/smoketest/scripts/cli/test_protocols_static.py
+++ b/smoketest/scripts/cli/test_protocols_static.py
@@ -31,6 +31,8 @@ routes = {
'192.0.2.100' : { 'distance' : '100' },
'192.0.2.110' : { 'distance' : '110', 'interface' : 'eth0' },
'192.0.2.120' : { 'distance' : '120', 'disable' : '' },
+ '192.0.2.130' : { 'bfd' : '' },
+ '192.0.2.140' : { 'bfd_source' : '192.0.2.10' },
},
'interface' : {
'eth0' : { 'distance' : '130' },
@@ -67,6 +69,8 @@ routes = {
'2001:db8::1' : { 'distance' : '10' },
'2001:db8::2' : { 'distance' : '20', 'interface' : 'eth0' },
'2001:db8::3' : { 'distance' : '30', 'disable' : '' },
+ '2001:db8::4' : { 'bfd' : '' },
+ '2001:db8::5' : { 'bfd_source' : '2001:db8::ffff' },
},
'interface' : {
'eth0' : { 'distance' : '40', 'vrf' : 'black' },
@@ -117,6 +121,7 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
def test_01_static(self):
+ bfd_profile = 'vyos-test'
for route, route_config in routes.items():
route_type = 'route'
if is_ipv6(route):
@@ -133,6 +138,10 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
self.cli_set(base + ['next-hop', next_hop, 'interface', next_hop_config['interface']])
if 'vrf' in next_hop_config:
self.cli_set(base + ['next-hop', next_hop, 'vrf', next_hop_config['vrf']])
+ if 'bfd' in next_hop_config:
+ self.cli_set(base + ['next-hop', next_hop, 'bfd', 'profile', bfd_profile ])
+ if 'bfd_source' in next_hop_config:
+ self.cli_set(base + ['next-hop', next_hop, 'bfd', 'multi-hop', 'source', next_hop_config['bfd_source'], 'profile', bfd_profile])
if 'interface' in route_config:
@@ -187,6 +196,10 @@ class TestProtocolsStatic(VyOSUnitTestSHIM.TestCase):
tmp += ' ' + next_hop_config['distance']
if 'vrf' in next_hop_config:
tmp += ' nexthop-vrf ' + next_hop_config['vrf']
+ if 'bfd' in next_hop_config:
+ tmp += ' bfd profile ' + bfd_profile
+ if 'bfd_source' in next_hop_config:
+ tmp += ' bfd multi-hop source ' + next_hop_config['bfd_source'] + ' profile ' + bfd_profile
if 'disable' in next_hop_config:
self.assertNotIn(tmp, frrconfig)
diff --git a/src/conf_mode/protocols_isis.py b/src/conf_mode/protocols_isis.py
index af2937db8..ecca87db0 100755
--- a/src/conf_mode/protocols_isis.py
+++ b/src/conf_mode/protocols_isis.py
@@ -129,7 +129,7 @@ def verify(isis):
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}!')
+ raise ConfigError(f'Interface "{interface}" is not a member of VRF "{vrf}"!')
# If md5 and plaintext-password set at the same time
for password in ['area_password', 'domain_password']:
diff --git a/src/conf_mode/protocols_ospf.py b/src/conf_mode/protocols_ospf.py
index fbb876123..b73483470 100755
--- a/src/conf_mode/protocols_ospf.py
+++ b/src/conf_mode/protocols_ospf.py
@@ -196,7 +196,7 @@ def verify(ospf):
vrf = ospf['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}!')
+ raise ConfigError(f'Interface "{interface}" is not a member of VRF "{vrf}"!')
# Segment routing checks
if dict_search('segment_routing.global_block', ospf):
diff --git a/src/conf_mode/protocols_ospfv3.py b/src/conf_mode/protocols_ospfv3.py
index ee1fdd399..cb21bd83c 100755
--- a/src/conf_mode/protocols_ospfv3.py
+++ b/src/conf_mode/protocols_ospfv3.py
@@ -138,7 +138,7 @@ def verify(ospfv3):
vrf = ospfv3['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}!')
+ raise ConfigError(f'Interface "{interface}" is not a member of VRF "{vrf}"!')
return None
diff --git a/src/op_mode/bgp.py b/src/op_mode/bgp.py
index 3f6d45dd7..af9ea788b 100755
--- a/src/op_mode/bgp.py
+++ b/src/op_mode/bgp.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
-# Copyright (C) 2022 VyOS maintainers and contributors
+# Copyright (C) 2023 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
@@ -15,101 +15,133 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Purpose:
-# Displays bgp neighbors information.
-# Used by the "show bgp (vrf <tag>) ipv4|ipv6 neighbors" commands.
+# Displays BGP neighbors and tables information.
import re
import sys
import typing
-import jmespath
from jinja2 import Template
-from humps import decamelize
-
-from vyos.configquery import ConfigTreeQuery
import vyos.opmode
-ArgFamily = typing.Literal['inet', 'inet6']
-
frr_command_template = Template("""
-{% if family %}
- show bgp
- {{ 'vrf ' ~ vrf if vrf else '' }}
- {{ 'ipv6' if family == 'inet6' else 'ipv4'}}
- {{ 'neighbor ' ~ peer if peer else 'summary' }}
+show bgp
+
+{## VRF and family modifiers that may precede any options ##}
+
+{% if vrf %}
+ vrf {{vrf}}
+{% endif %}
+
+{% if family == "inet" %}
+ ipv4
+{% elif family == "inet6" %}
+ ipv6
+{% elif family == "l2vpn" %}
+ l2vpn evpn
+{% endif %}
+
+{% if family_modifier == "unicast" %}
+ unicast
+{% elif family_modifier == "multicast" %}
+ multicast
+{% elif family_modifier == "flowspec" %}
+ flowspec
+{% elif family_modifier == "vpn" %}
+ vpn
+{% endif %}
+
+{## Mutually exclusive query parameters ##}
+
+{# Network prefix #}
+{% if prefix %}
+ {{prefix}}
+
+ {% if longer_prefixes %}
+ longer-prefixes
+ {% elif best_path %}
+ bestpath
+ {% endif %}
{% endif %}
+{# Regex #}
+{% if regex %}
+ regex {{regex}}
+{% endif %}
+
+{## Raw modifier ##}
+
{% if raw %}
json
{% endif %}
""")
+ArgFamily = typing.Literal['inet', 'inet6', 'l2vpn']
+ArgFamilyModifier = typing.Literal['unicast', 'labeled_unicast', 'multicast', 'vpn', 'flowspec']
+
+def show_summary(raw: bool):
+ from vyos.util import cmd
+
+ if raw:
+ from json import loads
+
+ output = cmd(f"vtysh -c 'show bgp summary json'").strip()
-def _verify(func):
- """Decorator checks if BGP config exists
- BGP configuration can be present under vrf <tag>
- If we do npt get arg 'peer' then it can be 'bgp summary'
- """
- from functools import wraps
-
- @wraps(func)
- def _wrapper(*args, **kwargs):
- config = ConfigTreeQuery()
- afi = 'ipv6' if kwargs.get('family') == 'inet6' else 'ipv4'
- global_vrfs = ['all', 'default']
- peer = kwargs.get('peer')
- vrf = kwargs.get('vrf')
- unconf_message = f'BGP or neighbor is not configured'
- # Add option to check the specific neighbor if we have arg 'peer'
- peer_opt = f'neighbor {peer} address-family {afi}-unicast' if peer else ''
- vrf_opt = ''
- if vrf and vrf not in global_vrfs:
- vrf_opt = f'vrf name {vrf}'
- # Check if config does not exist
- if not config.exists(f'{vrf_opt} protocols bgp {peer_opt}'):
- raise vyos.opmode.UnconfiguredSubsystem(unconf_message)
- return func(*args, **kwargs)
-
- return _wrapper
-
-
-@_verify
-def show_neighbors(raw: bool,
- family: ArgFamily,
- peer: typing.Optional[str],
- vrf: typing.Optional[str]):
- kwargs = dict(locals())
- frr_command = frr_command_template.render(kwargs)
- frr_command = re.sub(r'\s+', ' ', frr_command)
+ # FRR 8.5 correctly returns an empty object when BGP is not running,
+ # we don't need to do anything special here
+ return loads(output)
+ else:
+ output = cmd(f"vtysh -c 'show bgp summary'")
+ return output
+def show_neighbors(raw: bool):
from vyos.util import cmd
- output = cmd(f"vtysh -c '{frr_command}'")
+ from vyos.utils.dict import dict_to_list
if raw:
from json import loads
- data = loads(output)
- # Get list of the peers
- peers = jmespath.search('*.peers | [0]', data)
- if peers:
- # Create new dict, delete old key 'peers'
- # add key 'peers' neighbors to the list
- list_peers = []
- new_dict = jmespath.search('* | [0]', data)
- if 'peers' in new_dict:
- new_dict.pop('peers')
-
- for neighbor, neighbor_options in peers.items():
- neighbor_options['neighbor'] = neighbor
- list_peers.append(neighbor_options)
- new_dict['peers'] = list_peers
- return decamelize(new_dict)
- data = jmespath.search('* | [0]', data)
- return decamelize(data)
+ output = cmd(f"vtysh -c 'show bgp neighbors json'").strip()
+ d = loads(output)
+ return dict_to_list(d, save_key_to="neighbor")
else:
+ output = cmd(f"vtysh -c 'show bgp neighbors'")
return output
+def show(raw: bool,
+ family: ArgFamily,
+ family_modifier: ArgFamilyModifier,
+ prefix: typing.Optional[str],
+ longer_prefixes: typing.Optional[bool],
+ best_path: typing.Optional[bool],
+ regex: typing.Optional[str],
+ vrf: typing.Optional[str]):
+ from vyos.utils.dict import dict_to_list
+
+ if (longer_prefixes or best_path) and (prefix is None):
+ raise ValueError("longer_prefixes and best_path can only be used when prefix is given")
+ elif (family == "l2vpn") and (family_modifier is not None):
+ raise ValueError("l2vpn family does not accept any modifiers")
+ else:
+ kwargs = dict(locals())
+
+ frr_command = frr_command_template.render(kwargs)
+ frr_command = re.sub(r'\s+', ' ', frr_command)
+
+ from vyos.util import cmd
+ output = cmd(f"vtysh -c '{frr_command}'")
+
+ if raw:
+ from json import loads
+ d = loads(output)
+ if not ("routes" in d):
+ raise vyos.opmode.InternalError("FRR returned a BGP table with no routes field")
+ d = d["routes"]
+ routes = dict_to_list(d, save_key_to="route_key")
+ return routes
+ else:
+ return output
if __name__ == '__main__':
try: