From 62b45651761d84739d3b9bccc03017092f0360a3 Mon Sep 17 00:00:00 2001 From: Paul Wekesa Date: Tue, 12 Nov 2024 02:26:16 +0300 Subject: [PATCH 1/3] vrrp: introduce vrrp commands introduce the following commands: show vrrp show vrrp vrid VRID show vrrp interface NAME These commands help you get either general information on VRRP or filtered. Todo: Add virtual IP details ( currently an issue from the holod end) Signed-off-by: Paul Wekesa --- cmd | 1 + src/internal_commands.rs | 67 +++++++++++++++++++++++++++++---------- src/internal_commands.xml | 19 ++++++++--- src/token_xml.rs | 1 + vrrp.conf | 23 ++++++++++++++ 5 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 cmd create mode 100644 vrrp.conf diff --git a/cmd b/cmd new file mode 100644 index 0000000..f2989fd --- /dev/null +++ b/cmd @@ -0,0 +1 @@ +show state xpath /ietf-interfaces:interfaces/interface[name='wlo1'] diff --git a/src/internal_commands.rs b/src/internal_commands.rs index 35d85cf..b4c502e 100644 --- a/src/internal_commands.rs +++ b/src/internal_commands.rs @@ -192,8 +192,13 @@ impl<'a> YangTableBuilder<'a> { } // Builds and displays the table. - pub fn show(self) -> Result<(), String> { - let xpath_req = "/ietf-routing:routing/control-plane-protocols"; + pub fn show(self, xpath_req: Option) -> Result<(), String> { + // have a default xpath (ietf-routing:routing/control-plane-protocols) + // which is used by most of the other protocols. + let xpath_req = xpath_req.unwrap_or(String::from( + "/ietf-routing:routing/control-plane-protocols", + )); + let xpath_req = xpath_req.as_str(); // Fetch data. let data = fetch_data(self.session, self.data_type, xpath_req)?; @@ -724,6 +729,37 @@ pub(crate) fn cmd_show_yang_modules( Ok(false) } +// ===== VRRP "show" commands ===== + +const XPATH_INTERFACE: &str = "/ietf-interfaces:interfaces/interface"; +const XPATH_INTERFACE_IPV4: &str = "ietf-ip:ipv4"; +const PROTOCOL_VRRP: &str = "ietf-vrrp:vrrp"; + +pub(crate) fn cmd_show_vrrp_details( + _commands: &Commands, + session: &mut Session, + mut args: ParsedArgs, +) -> Result { + YangTableBuilder::new(session, DataType::All) + .xpath(XPATH_INTERFACE) + .filter_list_key("name", get_opt_arg(&mut args, "name")) // filter by interface name + .xpath(XPATH_INTERFACE_IPV4) + .xpath(PROTOCOL_VRRP) + .xpath("vrrp-instance") + .filter_list_key("vrid", get_opt_arg(&mut args, "vrid")) // filter by vrid + .column_leaf("VRID", "vrid") + .xpath("statistics") + .column_leaf("Master Transitions", "master-transitions") + .column_leaf("Adverts received", "advertisement-rcvd") + .column_leaf("Adverts sent", "advertisement-sent") + .column_leaf("Interval Errors", "interval-errors") + .column_leaf("Priority Zero Pkts Received", "priority-zero-pkts-rcvd") + .column_leaf("Priority Zero Pkts Sent", "priority-zero-pkts-sent") + .column_leaf("Packet Length Errors", "packet-length-errors") + .show(Some(String::from("/ietf-interfaces:interfaces")))?; + Ok(false) +} + // ===== IS-IS "show" commands ===== const PROTOCOL_ISIS: &str = "ietf-isis:isis"; @@ -747,7 +783,7 @@ pub(crate) fn cmd_show_isis_interface( .column_leaf("Type", "interface-type") .column_leaf("Circuit ID", "circuit-id") .column_leaf("State", "state") - .show()?; + .show(None)?; Ok(false) } @@ -770,7 +806,7 @@ pub(crate) fn cmd_show_isis_adjacency( .column_leaf("Level", "usage") .column_leaf("State", "state") .column_leaf("Holdtime", "hold-timer") - .show()?; + .show(None)?; Ok(false) } @@ -791,7 +827,7 @@ pub(crate) fn cmd_show_isis_database( .column_leaf_hex32("Sequence", "sequence") .column_leaf_hex16("Checksum", "checksum") .column_leaf("Lifetime", "remaining-lifetime") - .show()?; + .show(None)?; Ok(false) } @@ -840,7 +876,7 @@ pub(crate) fn cmd_show_ospf_interface( format!("{} ({})", interval, remaining) }), ) - .show()?; + .show(None)?; Ok(false) } @@ -951,7 +987,7 @@ pub(crate) fn cmd_show_ospf_neighbor( format!("{} ({})", interval, remaining) }), ) - .show()?; + .show(None)?; Ok(false) } @@ -1071,7 +1107,7 @@ pub(crate) fn cmd_show_ospf_route( .xpath(XPATH_OSPF_NEXTHOP) .column_leaf("Nexthop Interface", "outgoing-interface") .column_leaf("Nexthop Address", "next-hop") - .show()?; + .show(None)?; Ok(false) } @@ -1103,7 +1139,7 @@ pub(crate) fn cmd_show_rip_interface( .filter_list_key("interface", get_opt_arg(&mut args, "name")) .column_leaf("Name", "interface") .column_leaf("State", "oper-status") - .show()?; + .show(None)?; Ok(false) } @@ -1202,7 +1238,7 @@ pub(crate) fn cmd_show_rip_neighbor( .filter_list_key(address, get_opt_arg(&mut args, "address")) .column_leaf("Address", address) .column_leaf("Last update", "last-update") - .show()?; + .show(None)?; Ok(false) } @@ -1296,7 +1332,7 @@ pub(crate) fn cmd_show_rip_route( .column_leaf("Tag", "route-tag") .column_leaf("Nexthop Interface", "interface") .column_leaf("Nexthop Address", "next-hop") - .show()?; + .show(None)?; Ok(false) } @@ -1338,7 +1374,7 @@ pub(crate) fn cmd_show_mpls_ldp_interface( .column_leaf("Adjacent address", "adjacent-address") .xpath(XPATH_MPLS_LDP_ADJACENCY_PEER) .column_leaf("Neighbor lsr-id", "lsr-id") - .show()?; + .show(None)?; Ok(false) } @@ -1462,7 +1498,7 @@ pub(crate) fn cmd_show_mpls_ldp_peer( .xpath(XPATH_MPLS_LDP_ADJACENCY) .column_leaf("Local address", "local-address") .column_leaf("Adjacent address", "adjacent-address") - .show()?; + .show(None)?; Ok(false) } @@ -1659,11 +1695,10 @@ pub(crate) fn cmd_show_mpls_ldp_binding_address( output }), ) - .show()?; + .show(None)?; Ok(false) } - pub(crate) fn cmd_show_mpls_ldp_binding_fec( _commands: &Commands, session: &mut Session, @@ -1708,7 +1743,7 @@ pub(crate) fn cmd_show_mpls_ldp_binding_fec( }), ) .column_leaf("In use", "used-in-forwarding") - .show()?; + .show(None)?; Ok(false) } diff --git a/src/internal_commands.xml b/src/internal_commands.xml index d4047b7..86bf814 100644 --- a/src/internal_commands.xml +++ b/src/internal_commands.xml @@ -18,10 +18,10 @@ - + - + @@ -34,9 +34,20 @@ - - + + + + + + + + + + + + + diff --git a/src/token_xml.rs b/src/token_xml.rs index 0db444c..8322ebc 100644 --- a/src/token_xml.rs +++ b/src/token_xml.rs @@ -120,6 +120,7 @@ fn parse_tag_token( "cmd_show_mpls_ldp_binding_fec" => { internal_commands::cmd_show_mpls_ldp_binding_fec } + "cmd_show_vrrp_details" => internal_commands::cmd_show_vrrp_details, _ => panic!("unknown command name: {}", name), }); diff --git a/vrrp.conf b/vrrp.conf new file mode 100644 index 0000000..f983ada --- /dev/null +++ b/vrrp.conf @@ -0,0 +1,23 @@ +! +interfaces interface wlo1 + type iana-if-type:ethernetCsmacd + ipv4 + ! + ipv4 vrrp vrrp-instance 30 + ! + virtual-ipv4-addresses virtual-ipv4-address 10.0.30.1 + ! + virtual-ipv4-addresses virtual-ipv4-address 10.0.30.2 + ! + ipv4 vrrp vrrp-instance 50 + ! + virtual-ipv4-addresses virtual-ipv4-address 10.0.50.1 + ! + virtual-ipv4-addresses virtual-ipv4-address 10.0.50.2 + ! + ipv4 vrrp vrrp-instance 70 + ! + virtual-ipv4-addresses virtual-ipv4-address 10.0.70.1 + ! + virtual-ipv4-addresses virtual-ipv4-address 10.0.70.2 +! From dc5e2b9a6166635957b5aeef91baa8d0f3156d38 Mon Sep 17 00:00:00 2001 From: Paul Wekesa Date: Sat, 23 Nov 2024 01:19:07 +0300 Subject: [PATCH 2/3] delete local files delete local files introduced accidentally. Signed-off-by: Paul Wekesa --- cmd | 1 - vrrp.conf | 23 ----------------------- 2 files changed, 24 deletions(-) delete mode 100644 cmd delete mode 100644 vrrp.conf diff --git a/cmd b/cmd deleted file mode 100644 index f2989fd..0000000 --- a/cmd +++ /dev/null @@ -1 +0,0 @@ -show state xpath /ietf-interfaces:interfaces/interface[name='wlo1'] diff --git a/vrrp.conf b/vrrp.conf deleted file mode 100644 index f983ada..0000000 --- a/vrrp.conf +++ /dev/null @@ -1,23 +0,0 @@ -! -interfaces interface wlo1 - type iana-if-type:ethernetCsmacd - ipv4 - ! - ipv4 vrrp vrrp-instance 30 - ! - virtual-ipv4-addresses virtual-ipv4-address 10.0.30.1 - ! - virtual-ipv4-addresses virtual-ipv4-address 10.0.30.2 - ! - ipv4 vrrp vrrp-instance 50 - ! - virtual-ipv4-addresses virtual-ipv4-address 10.0.50.1 - ! - virtual-ipv4-addresses virtual-ipv4-address 10.0.50.2 - ! - ipv4 vrrp vrrp-instance 70 - ! - virtual-ipv4-addresses virtual-ipv4-address 10.0.70.1 - ! - virtual-ipv4-addresses virtual-ipv4-address 10.0.70.2 -! From 13927ff732049ff3efb5aa0db1623ca42000ecac Mon Sep 17 00:00:00 2001 From: Paul Wekesa Date: Thu, 19 Dec 2024 13:36:16 +0300 Subject: [PATCH 3/3] clippy: linter issues Fix clippy issue with unnecessary match statement Signed-off-by: Paul Wekesa --- src/parser.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index de1767a..94f5839 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -27,10 +27,7 @@ pub type ParsedArgs = VecDeque<(String, String)>; pub(crate) fn normalize_input_line(line: &str) -> Option { // Ignore "!" comments. // TODO: allow "!" within user input like interface descriptions - let line = match line.split('!').next() { - Some(line) => line, - None => return None, - }; + let line = line.split('!').next()?; // Remove redundant whitespaces. let line = line.split_whitespace().collect::>().join(" ");