diff options
22 files changed, 496 insertions, 82 deletions
diff --git a/data/op-mode-standardized.json b/data/op-mode-standardized.json index a69cf55e9..2ea4d945a 100644 --- a/data/op-mode-standardized.json +++ b/data/op-mode-standardized.json @@ -7,6 +7,7 @@ "cpu.py", "dhcp.py", "dns.py", +"interfaces.py", "log.py", "memory.py", "nat.py", diff --git a/op-mode-definitions/openvpn.xml.in b/op-mode-definitions/openvpn.xml.in index aec09fa48..b2763da81 100644 --- a/op-mode-definitions/openvpn.xml.in +++ b/op-mode-definitions/openvpn.xml.in @@ -37,12 +37,13 @@ <properties> <help>Show OpenVPN interface information</help> </properties> + <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}/show_interfaces.py --intf-type=openvpn --action=show</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=openvpn</command> </leafNode> </children> </node> @@ -53,7 +54,7 @@ <script>sudo ${vyos_completion_dir}/list_interfaces.py --type openvpn</script> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf=$4</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name=$4</command> <children> <tagNode name="user"> <properties> @@ -94,7 +95,7 @@ <properties> <help>Show summary of specified OpenVPN interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> diff --git a/op-mode-definitions/show-interfaces-bonding.xml.in b/op-mode-definitions/show-interfaces-bonding.xml.in index c5f82b70e..6908153dd 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified bonding interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</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}/show_interfaces.py --intf="$4.$6"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4.$6"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of specified virtual network interface (vif) information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4.$6"</command> </leafNode> </children> </tagNode> @@ -60,13 +60,13 @@ <properties> <help>Show Bonding interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=bonding --action=show-brief</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}/show_interfaces.py --intf-type=bonding --action=show</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 e1444bd84..b950c3a17 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified bridge interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show Bridge interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=bridge --action=show-brief</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}/show_interfaces.py --intf-type=bridge --action=show</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 52d2cc7ee..398e00636 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified dummy interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show Dummy interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=dummy --action=show-brief</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}/show_interfaces.py --intf-type=dummy --action=show</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 f8d1c9395..40d4adbb2 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified ethernet interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</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}/show_interfaces.py --intf="$4.$6"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4.$6"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of specified virtual network interface (vif) information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4.$6"</command> </leafNode> </children> </tagNode> @@ -80,13 +80,13 @@ <properties> <help>Show Ethernet interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=ethernet --action=show-brief</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}/show_interfaces.py --intf-type=ethernet --action=show</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 a47933315..be3084af3 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified GENEVE interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show GENEVE interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=geneve --action=show-brief</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}/show_interfaces.py --intf-type=geneve --action=show</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 9ae3828c8..1f8505160 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified input interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show Input (ifb) interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=input --action=show-brief</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}/show_interfaces.py --intf-type=input --action=show</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 2a1d6a1c6..ff08b8266 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified L2TPv3 interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show L2TPv3 interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=l2tpv3 --action=show-brief</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}/show_interfaces.py --intf-type=l2tpv3 --action=show</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 25a75ffff..9919bf32b 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> - <help>Show summary of the specified dummy interface information</help> + <help>Show summary of the specified Loopback interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show Loopback interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=loopback --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_type=loopback</command> <children> <leafNode name="detail"> <properties> - <help>Show detailed dummy interface information</help> + <help>Show detailed Loopback interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=dummy --action=show</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 09608bc04..80bfd00ff 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="log"> <properties> @@ -34,13 +34,13 @@ <properties> <help>Show PPPoE interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=pppoe --action=show-brief</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}/show_interfaces.py --intf-type=pppoe --action=show</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 2ae4b5a9e..0c00dbdd0 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified pseudo-ethernet/MACvlan interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show Pseudo-Ethernet/MACvlan interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=pseudo-ethernet --action=show-brief</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}/show_interfaces.py --intf-type=pseudo-ethernet --action=show</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 e66d3a0ac..c473f9822 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="log"> <properties> @@ -34,13 +34,13 @@ <properties> <help>Show SSTP client interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=sstpc --action=show-brief</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}/show_interfaces.py --intf-type=sstpc --action=show</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 51b25efd9..4af90b813 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified tunnel interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show Tunnel interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=tunnel --action=show-brief</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}/show_interfaces.py --intf-type=tunnel --action=show</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 c70f1e3d1..2aa71c687 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified virtual-ethernet interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show virtual-ethernet interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=virtual-ethernet --action=show-brief</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}/show_interfaces.py --intf-type=virtual-ethernet --action=show</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 b436b8414..195e1d5da 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified vti interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show VTI interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=vti --action=show-brief</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}/show_interfaces.py --intf-type=vti --action=show</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 1befd428c..a1d01a6af 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified VXLAN interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</command> </leafNode> </children> </tagNode> @@ -25,13 +25,13 @@ <properties> <help>Show VXLAN interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=vxlan --action=show-brief</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}/show_interfaces.py --intf-type=vxlan --action=show</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 c9b754dcd..55879cfff 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.py --type wireguard</script> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="allowed-ips"> <properties> @@ -49,13 +49,13 @@ <properties> <help>Show WireGuard interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf-type=wireguard --action=show-brief</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}/show_interfaces.py --intf-type=wireguard --action=show</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 4a37417aa..7ae2c8ce4 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}/show_interfaces.py --intf-type=wireless --action=show-brief</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}/show_interfaces.py --intf-type=wireless --action=show</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.py --type wireless</script> </completionHelp> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of the specified wireless interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4"</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}/show_interfaces.py --intf="$4.$6"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4.$6"</command> <children> <leafNode name="brief"> <properties> <help>Show summary of specified virtual network interface (vif) information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --intf="$4.$6" --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary --intf_name="$4.$6"</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 3cd29b38a..8ac5933a2 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}/show_interfaces.py --intf="$4"</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_name="$4"</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}/show_interfaces.py --intf-type=wirelessmodem --action=show-brief</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}/show_interfaces.py --intf-type=wirelessmodem --action=show</command> + <command>${vyos_op_scripts_dir}/interfaces.py show --intf_type=wirelessmodem</command> </leafNode> </children> </node> diff --git a/op-mode-definitions/show-interfaces.xml.in b/op-mode-definitions/show-interfaces.xml.in index 39b0f0a2c..dc61a6f5c 100644 --- a/op-mode-definitions/show-interfaces.xml.in +++ b/op-mode-definitions/show-interfaces.xml.in @@ -6,19 +6,19 @@ <properties> <help>Show network interface information</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --action=show-brief</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_summary</command> <children> <leafNode name="counters"> <properties> <help>Show network interface counters</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --action=show-count</command> + <command>${vyos_op_scripts_dir}/interfaces.py show_counters</command> </leafNode> <leafNode name="detail"> <properties> <help>Show detailed information of all interfaces</help> </properties> - <command>${vyos_op_scripts_dir}/show_interfaces.py --action=show</command> + <command>${vyos_op_scripts_dir}/interfaces.py show</command> </leafNode> </children> </node> diff --git a/src/op_mode/interfaces.py b/src/op_mode/interfaces.py new file mode 100755 index 000000000..678c74980 --- /dev/null +++ b/src/op_mode/interfaces.py @@ -0,0 +1,412 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 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 re +import sys +import glob +import json +import typing +from datetime import datetime +from tabulate import tabulate + +import vyos.opmode +from vyos.ifconfig import Section +from vyos.ifconfig import Interface +from vyos.ifconfig import VRRP +from vyos.util import cmd, rc_cmd, call + +def catch_broken_pipe(func): + def wrapped(*args, **kwargs): + try: + func(*args, **kwargs) + except (BrokenPipeError, KeyboardInterrupt): + # Flush output to /dev/null and bail out. + os.dup2(os.open(os.devnull, os.O_WRONLY), sys.stdout.fileno()) + return wrapped + +# The original implementation of filtered_interfaces has signature: +# (ifnames: list, iftypes: typing.Union[str, list], vif: bool, vrrp: bool) -> intf: Interface: +# Arg types allowed in CLI (ifnames: str, iftypes: str) were manually +# re-typed from argparse args. +# We include the function in a general form, however op-mode standard +# functions will restrict to the CLI-allowed arg types, wrapped in Optional. +def filtered_interfaces(ifnames: typing.Union[str, list], + iftypes: typing.Union[str, list], + vif: bool, vrrp: bool) -> Interface: + """ + get all interfaces from the OS and return them; ifnames can be used to + filter which interfaces should be considered + + ifnames: a list of interface names to consider, empty do not filter + + return an instance of the Interface class + """ + if isinstance(ifnames, str): + ifnames = [ifnames] if ifnames else [] + if isinstance(iftypes, list): + for iftype in iftypes: + yield from filtered_interfaces(ifnames, iftype, vif, vrrp) + + for ifname in Section.interfaces(iftypes): + # Bail out early if interface name not part of our search list + if ifnames and ifname not in ifnames: + continue + + # As we are only "reading" from the interface - we must use the + # generic base class which exposes all the data via a common API + interface = Interface(ifname, create=False, debug=False) + + # VLAN interfaces have a '.' in their name by convention + if vif and not '.' in ifname: + continue + + if vrrp: + vrrp_interfaces = VRRP.active_interfaces() + if ifname not in vrrp_interfaces: + continue + + yield interface + +def _split_text(text, used=0): + """ + take a string and attempt to split it to fit with the width of the screen + + text: the string to split + used: number of characted already used in the screen + """ + no_tty = call('tty -s') + + returned = cmd('stty size') if not no_tty else '' + returned = returned.split() + if len(returned) == 2: + _, columns = tuple(int(_) for _ in returned) + else: + _, columns = (40, 80) + + desc_len = columns - used + + line = '' + for word in text.split(): + if len(line) + len(word) < desc_len: + line = f'{line} {word}' + continue + if line: + yield line[1:] + else: + line = f'{line} {word}' + + yield line[1:] + +def _get_counter_val(prev, now): + """ + attempt to correct a counter if it wrapped, copied from perl + + prev: previous counter + now: the current counter + """ + # This function has to deal with both 32 and 64 bit counters + if prev == 0: + return now + + # device is using 64 bit values assume they never wrap + value = now - prev + if (now >> 32) != 0: + return value + + # The counter has rolled. If the counter has rolled + # multiple times since the prev value, then this math + # is meaningless. + if value < 0: + value = (4294967296 - prev) + now + + return value + +def _pppoe(ifname): + out = cmd('ps -C pppd -f') + if ifname in out: + return 'C' + if ifname in [_.split('/')[-1] for _ in glob.glob('/etc/ppp/peers/pppoe*')]: + return 'D' + return '' + +def _find_intf_by_ifname(intf_l: list, name: str): + for d in intf_l: + if d['ifname'] == name: + return d + return {} + +# lifted out of operational.py to separate formatting from data +def _format_stats(stats, indent=4): + stat_names = { + 'rx': ['bytes', 'packets', 'errors', 'dropped', 'overrun', 'mcast'], + 'tx': ['bytes', 'packets', 'errors', 'dropped', 'carrier', 'collisions'], + } + + stats_dir = { + 'rx': ['rx_bytes', 'rx_packets', 'rx_errors', 'rx_dropped', 'rx_over_errors', 'multicast'], + 'tx': ['tx_bytes', 'tx_packets', 'tx_errors', 'tx_dropped', 'tx_carrier_errors', 'collisions'], + } + tabs = [] + for rtx in list(stats_dir): + tabs.append([f'{rtx.upper()}:', ] + stat_names[rtx]) + tabs.append(['', ] + [stats[_] for _ in stats_dir[rtx]]) + + s = tabulate( + tabs, + stralign="right", + numalign="right", + tablefmt="plain" + ) + + p = ' '*indent + return f'{p}' + s.replace('\n', f'\n{p}') + +def _get_raw_data(ifname: typing.Optional[str], + iftype: typing.Optional[str], + vif: bool, vrrp: bool) -> list: + if ifname is None: + ifname = '' + if iftype is None: + iftype = '' + ret =[] + for interface in filtered_interfaces(ifname, iftype, vif, vrrp): + res_intf = {} + cache = interface.operational.load_counters() + + out = cmd(f'ip -json addr show {interface.ifname}') + res_intf_l = json.loads(out) + res_intf = res_intf_l[0] + + if res_intf['link_type'] == 'tunnel6': + # Note that 'ip -6 tun show {interface.ifname}' is not json + # aware, so find in list + out = cmd('ip -json -6 tun show') + tunnel = json.loads(out) + res_intf['tunnel6'] = _find_intf_by_ifname(tunnel, + interface.ifname) + if 'ip6_tnl_f_use_orig_tclass' in res_intf['tunnel6']: + res_intf['tunnel6']['tclass'] = 'inherit' + del res_intf['tunnel6']['ip6_tnl_f_use_orig_tclass'] + + res_intf['counters_last_clear'] = int(cache.get('timestamp', 0)) + + res_intf['description'] = interface.get_alias() + + res_intf['stats'] = interface.operational.get_stats() + + ret.append(res_intf) + + # find pppoe interfaces that are in a transitional/dead state + if ifname.startswith('pppoe') and not _find_intf_by_ifname(ret, ifname): + pppoe_intf = {} + pppoe_intf['unhandled'] = None + pppoe_intf['ifname'] = ifname + pppoe_intf['state'] = _pppoe(ifname) + ret.append(pppoe_intf) + + return ret + +def _get_summary_data(ifname: typing.Optional[str], + iftype: typing.Optional[str], + vif: bool, vrrp: bool) -> list: + if ifname is None: + ifname = '' + if iftype is None: + iftype = '' + ret = [] + for interface in filtered_interfaces(ifname, iftype, vif, vrrp): + res_intf = {} + + res_intf['ifname'] = interface.ifname + res_intf['oper_state'] = interface.operational.get_state() + res_intf['admin_state'] = interface.get_admin_state() + res_intf['addr'] = [_ for _ in interface.get_addr() if not _.startswith('fe80::')] + res_intf['description'] = interface.get_alias() + + ret.append(res_intf) + + # find pppoe interfaces that are in a transitional/dead state + if ifname.startswith('pppoe') and not _find_intf_by_ifname(ret, ifname): + pppoe_intf = {} + pppoe_intf['unhandled'] = None + pppoe_intf['ifname'] = ifname + pppoe_intf['state'] = _pppoe(ifname) + ret.append(pppoe_intf) + + return ret + +def _get_counter_data(ifname: typing.Optional[str], + iftype: typing.Optional[str], + vif: bool, vrrp: bool) -> list: + if ifname is None: + ifname = '' + if iftype is None: + iftype = '' + ret = [] + for interface in filtered_interfaces(ifname, iftype, vif, vrrp): + res_intf = {} + + oper = interface.operational.get_state() + + if oper not in ('up','unknown'): + continue + + stats = interface.operational.get_stats() + cache = interface.operational.load_counters() + res_intf['ifname'] = interface.ifname + res_intf['rx_packets'] = _get_counter_val(cache['rx_packets'], stats['rx_packets']) + res_intf['rx_bytes'] = _get_counter_val(cache['rx_bytes'], stats['rx_bytes']) + res_intf['tx_packets'] = _get_counter_val(cache['tx_packets'], stats['tx_packets']) + res_intf['tx_bytes'] = _get_counter_val(cache['tx_bytes'], stats['tx_bytes']) + + ret.append(res_intf) + + return ret + +@catch_broken_pipe +def _format_show_data(data: list): + unhandled = [] + for intf in data: + if 'unhandled' in intf: + unhandled.append(intf) + continue + # instead of reformatting data, call non-json output: + rc, out = rc_cmd(f"ip addr show {intf['ifname']}") + if rc != 0: + continue + out = re.sub('^\d+:\s+','',out) + # add additional data already collected + if 'tunnel6' in intf: + t6_d = intf['tunnel6'] + t6_str = 'encaplimit %s hoplimit %s tclass %s flowlabel %s (flowinfo %s)' % ( + t6_d.get('encap_limit', ''), t6_d.get('hoplimit', ''), + t6_d.get('tclass', ''), t6_d.get('flowlabel', ''), + t6_d.get('flowinfo', '')) + out = re.sub('(\n\s+)(link/tunnel6)', f'\g<1>{t6_str}\g<1>\g<2>', out) + print(out) + ts = intf.get('counters_last_clear', 0) + if ts: + when = datetime.fromtimestamp(ts).strftime("%a %b %d %R:%S %Z %Y") + print(f' Last clear: {when}') + description = intf.get('description', '') + if description: + print(f' Description: {description}') + + stats = intf.get('stats', {}) + if stats: + print() + print(_format_stats(stats)) + + for intf in unhandled: + string = { + 'C': 'Coming up', + 'D': 'Link down' + }[intf['state']] + print(f"{intf['ifname']}: {string}") + + return 0 + +@catch_broken_pipe +def _format_show_summary(data): + format1 = '%-16s %-33s %-4s %s' + format2 = '%-16s %s' + + print('Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down') + print(format1 % ("Interface", "IP Address", "S/L", "Description")) + print(format1 % ("---------", "----------", "---", "-----------")) + + unhandled = [] + for intf in data: + if 'unhandled' in intf: + unhandled.append(intf) + continue + ifname = [intf['ifname'],] + oper = ['u',] if intf['oper_state'] in ('up', 'unknown') else ['D',] + admin = ['u',] if intf['admin_state'] in ('up', 'unknown') else ['A',] + addrs = intf['addr'] or ['-',] + descs = list(_split_text(intf['description'], 0)) + + while ifname or oper or admin or addrs or descs: + i = ifname.pop(0) if ifname else '' + a = addrs.pop(0) if addrs else '' + d = descs.pop(0) if descs else '' + s = [admin.pop(0)] if admin else [] + l = [oper.pop(0)] if oper else [] + if len(a) < 33: + print(format1 % (i, a, '/'.join(s+l), d)) + else: + print(format2 % (i, a)) + print(format1 % ('', '', '/'.join(s+l), d)) + + for intf in unhandled: + string = { + 'C': 'u/D', + 'D': 'A/D' + }[intf['state']] + print(format1 % (ifname, '', string, '')) + + return 0 + +@catch_broken_pipe +def _format_show_counters(data: list): + formatting = '%-12s %10s %10s %10s %10s' + print(formatting % ('Interface', 'Rx Packets', 'Rx Bytes', 'Tx Packets', 'Tx Bytes')) + + for intf in data: + print(formatting % ( + intf['ifname'], + intf['rx_packets'], + intf['rx_bytes'], + intf['tx_packets'], + intf['tx_bytes'] + )) + + return 0 + +def show(raw: bool, intf_name: typing.Optional[str], + intf_type: typing.Optional[str], + vif: bool, vrrp: bool): + data = _get_raw_data(intf_name, intf_type, vif, vrrp) + if raw: + return data + return _format_show_data(data) + +def show_summary(raw: bool, intf_name: typing.Optional[str], + intf_type: typing.Optional[str], + vif: bool, vrrp: bool): + data = _get_summary_data(intf_name, intf_type, vif, vrrp) + if raw: + return data + return _format_show_summary(data) + +def show_counters(raw: bool, intf_name: typing.Optional[str], + intf_type: typing.Optional[str], + vif: bool, vrrp: bool): + data = _get_counter_data(intf_name, intf_type, vif, vrrp) + if raw: + return data + return _format_show_counters(data) + +if __name__ == '__main__': + try: + res = vyos.opmode.run(sys.modules[__name__]) + if res: + print(res) + except (ValueError, vyos.opmode.Error) as e: + print(e) + sys.exit(1) |