From f7f9093219fda73b0efb5417efccfc7e7925c6b3 Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 13:00:17 +0100 Subject: [PATCH 1/7] feat(cli): reorder command codes Signed-off-by: Fredi Raspall --- cli/src/cliproto.rs | 78 +++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/cli/src/cliproto.rs b/cli/src/cliproto.rs index 75aa89f4a..5cf7a2321 100644 --- a/cli/src/cliproto.rs +++ b/cli/src/cliproto.rs @@ -129,38 +129,34 @@ pub enum CliAction { Help, Quit, + // config + ShowConfigSummary, + + // config: gateways & communities + ShowGatewayGroups, + ShowGatewayCommunities, + + // config: tracing ShowTracingTargets, ShowTracingTagGroups, - SetLoglevel, - // cpi + // config: vpcs & peerings + ShowVpc, + ShowVpcPeerings, + + // router: Eventlog + RouterEventLog, + + // router: cpi ShowCpiStats, CpiRequestRefresh, - // frrmi + // router: frrmi ShowFrrmiStats, ShowFrrmiLastConfig, FrrmiApplyLastConfig, - // Eventlog - RouterEventLog, - - // flow table - ShowFlowTable, - - // flow filter - ShowFlowFilter, - - // vpcs - ShowVpc, - ShowVpcPeerings, - - // pipelines - ShowPipeline, - ShowPipelineStages, - ShowPipelineStats, - - // router + // router: internal state ShowRouterInterfaces, ShowRouterInterfaceAddresses, ShowRouterVrfs, @@ -177,25 +173,37 @@ pub enum CliAction { ShowRouterIpv4FibGroups, ShowRouterIpv6FibGroups, - // DPDK - ShowDpdkPort, - ShowDpdkPortStats, - - // kernel - ShowKernelInterfaces, - - // nat + // NF: nat ShowPortForwarding, ShowStaticNat, ShowMasquerading, - // gateways - ShowGatewayGroups, - ShowGatewayCommunities, + // NF: flow table + ShowFlowTable, - // config - ShowConfigSummary, + // NF: flow filter + ShowFlowFilter, + + // internal config ShowConfigInternal, + + ShowTech, + + /* == Not supported yet == */ + // pipelines + ShowPipeline, + ShowPipelineStages, + ShowPipelineStats, + + // kernel + ShowKernelInterfaces, + + // DPDK + ShowDpdkPort, + ShowDpdkPortStats, + + // loglevel + SetLoglevel, } impl CliAction { From a23af0709ba242bf080bde5f5312a2609190e649 Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 13:54:42 +0100 Subject: [PATCH 2/7] feat(flow-filter): add heading to display Signed-off-by: Fredi Raspall --- flow-filter/src/display.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/flow-filter/src/display.rs b/flow-filter/src/display.rs index 2f1103ea1..29b54731d 100644 --- a/flow-filter/src/display.rs +++ b/flow-filter/src/display.rs @@ -3,7 +3,7 @@ //! Display implementations -use common::cliprovider::{CliData, CliDataProvider}; +use common::cliprovider::{CliData, CliDataProvider, Heading}; use indenter::indented; use std::collections::BTreeMap; @@ -21,6 +21,8 @@ impl CliDataProvider for FlowFilterTable { impl Display for FlowFilterTable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Heading("Flow filter").fmt(f)?; + // Collect into a BTreeMap to get a deterministic order when dumping the entries writeln!(f, "subtable for TCP/UDP:")?; for (src_vpcd, table) in self From b568f50e2790153f99c5cbd33a67afdbd8b2604a Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 13:55:40 +0100 Subject: [PATCH 3/7] feat(cli): add show tech command Signed-off-by: Fredi Raspall --- cli/bin/cmdtree_dp.rs | 7 +++++++ cli/src/cliproto.rs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/cli/bin/cmdtree_dp.rs b/cli/bin/cmdtree_dp.rs index 668de3415..ed856dd7e 100644 --- a/cli/bin/cmdtree_dp.rs +++ b/cli/bin/cmdtree_dp.rs @@ -287,6 +287,12 @@ fn cmd_show_config_summary() -> Node { root } +fn cmd_show_tech() -> Node { + Node::new("tech") + .desc("Dump dataplanes state") + .action(CliAction::ShowTech as u16) +} + fn cmd_show() -> Node { let mut root: Node = Node::new("show"); root += cmd_show_router(); @@ -301,6 +307,7 @@ fn cmd_show() -> Node { root += cmd_show_flow_filter(); root += cmd_show_gateway(); root += cmd_show_config_summary(); + root += cmd_show_tech(); root } fn cmd_loglevel() -> Node { diff --git a/cli/src/cliproto.rs b/cli/src/cliproto.rs index 5cf7a2321..b3af1b64e 100644 --- a/cli/src/cliproto.rs +++ b/cli/src/cliproto.rs @@ -121,7 +121,7 @@ impl CliResponse { #[repr(u16)] #[allow(unused)] -#[derive(Debug, Clone, Serialize, Deserialize, EnumIter)] +#[derive(Debug, Clone, Serialize, Deserialize, EnumIter, PartialEq)] pub enum CliAction { Clear = 0, Connect, From f1f3df41dbe4ca3a2abc636ab2aaf4cc319297e5 Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 13:57:29 +0100 Subject: [PATCH 4/7] feat(routing): handle show tech cli command We handle it by iterating over all handlers, pretending that they were individually invoked, and merging all of the results into one response. Signed-off-by: Fredi Raspall --- Cargo.lock | 1 + routing/Cargo.toml | 1 + routing/src/cli/handler.rs | 39 +++++++++++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3cba13dad..df1d851bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1675,6 +1675,7 @@ dependencies = [ "procfs", "rand 0.10.0", "serde", + "strum 0.28.0", "thiserror 2.0.18", "tokio", "tokio-util", diff --git a/routing/Cargo.toml b/routing/Cargo.toml index 1b27ea25d..e331da9ab 100644 --- a/routing/Cargo.toml +++ b/routing/Cargo.toml @@ -37,6 +37,7 @@ mio = { workspace = true, features = ["os-ext", "net"] } netgauze-bgp-pkt = { workspace = true } netgauze-bmp-pkt = { workspace = true } serde = { workspace = true, features = ["derive"] } +strum = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["fs", "io-util", "macros", "rt", "sync", "rt", "sync", "net", "macros"] } tokio-util = { workspace = true, features = ["codec"] } diff --git a/routing/src/cli/handler.rs b/routing/src/cli/handler.rs index 8eb8d2357..37a1fbb3c 100644 --- a/routing/src/cli/handler.rs +++ b/routing/src/cli/handler.rs @@ -20,15 +20,19 @@ use crate::router::revent::ROUTER_EVENTS; use crate::router::rio::Rio; use crate::routingdb::RoutingDb; -use cli::cliproto::{CliAction, CliError, CliRequest, CliResponse, CliSerialize, RouteProtocol}; +use chrono::Local; +use cli::cliproto::{ + CliAction, CliError, CliRequest, CliResponse, CliSerialize, RequestArgs, RouteProtocol, +}; use config::{ConfigSummary, GwConfig, GwConfigMeta}; use lpm::prefix::{Ipv4Prefix, Ipv6Prefix}; use net::vxlan::Vni; use std::os::unix::net::SocketAddr; use std::sync::Arc; +use strum::IntoEnumIterator; use tracing::{error, trace}; -use common::cliprovider::{CliData, CliDataProvider}; +use common::cliprovider::{CliData, CliDataProvider, Heading}; use tracectl::{get_trace_ctl, trace_target}; trace_target!("cli", LevelFilter::OFF, &[]); @@ -391,7 +395,10 @@ fn show_config(request: CliRequest, config: Option<&Arc>) -> CliRespon CliAction::ShowVpcPeerings => vpc_table.as_peerings().to_string(), CliAction::ShowGatewayGroups => config.external.gwgroups.to_string(), CliAction::ShowGatewayCommunities => config.external.communities.to_string(), - CliAction::ShowConfigInternal => format!("{:#?}", config.internal), + CliAction::ShowConfigInternal => { + let heading = Heading("Internal configuration").to_string(); + format!("{heading}{:#?}", config.internal) + } _ => unreachable!(), }; CliResponse::from_request_ok(request, contents) @@ -400,6 +407,31 @@ fn show_config_summary(request: CliRequest, summary: &[GwConfigMeta]) -> CliResp CliResponse::from_request_ok(request, ConfigSummary(summary).to_string()) } +fn show_tech( + request: CliRequest, + db: &RoutingDb, + rio: &mut Rio, + sources: &CliSources, +) -> CliResponse { + let excluded = [ + CliAction::ShowTech, + CliAction::CpiRequestRefresh, + CliAction::FrrmiApplyLastConfig, + ]; + let time = Local::now(); + let mut data = format!("time: {}\n", time.format("%Y-%m-%d %H:%M:%S")); + for action in CliAction::iter().filter(|a| !excluded.contains(a)) { + let request = CliRequest::new(action, RequestArgs::default()); + if let Ok(response) = do_handle_cli_request(request, db, rio, sources) { + if let Ok(output) = response.result { + data += output.as_str(); + data += "\n"; + } + } + } + CliResponse::from_request_ok(request, data) +} + #[allow(clippy::too_many_lines)] fn do_handle_cli_request( request: CliRequest, @@ -410,6 +442,7 @@ fn do_handle_cli_request( let cpi_s = &rio.cpistats; let frrmi = &rio.frrmi; let response = match request.action { + CliAction::ShowTech => show_tech(request, db, rio, sources), CliAction::ShowVpc | CliAction::ShowVpcPeerings | CliAction::ShowGatewayCommunities From 665d57db83f6610090b23ab44592e65f9b3110f0 Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 16:16:17 +0100 Subject: [PATCH 5/7] feat(tracectl): use common utils for Display Signed-off-by: Fredi Raspall --- Cargo.lock | 1 + tracectl/Cargo.toml | 1 + tracectl/src/display.rs | 10 +++------- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df1d851bd..bc90548d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1736,6 +1736,7 @@ name = "dataplane-tracectl" version = "0.14.0" dependencies = [ "color-eyre", + "dataplane-common", "linkme", "ordermap", "serial_test", diff --git a/tracectl/Cargo.toml b/tracectl/Cargo.toml index e0165a9c6..9a1fac2fa 100644 --- a/tracectl/Cargo.toml +++ b/tracectl/Cargo.toml @@ -7,6 +7,7 @@ version.workspace = true [dependencies] color-eyre = { workspace = true , features = [ "capture-spantrace", "color-spantrace", "tracing-error", "track-caller" ] } +common = { workspace = true } linkme = { workspace = true } ordermap = { workspace = true, features = ["std"] } thiserror = { workspace = true } diff --git a/tracectl/src/display.rs b/tracectl/src/display.rs index 5932504e1..66d446295 100644 --- a/tracectl/src/display.rs +++ b/tracectl/src/display.rs @@ -5,6 +5,7 @@ use crate::control::{TargetCfg, TargetCfgDb}; use crate::targets::TRACING_TAG_ALL; +use common::cliprovider::Heading; use std::fmt::Display; macro_rules! TARGET_FMT { @@ -41,11 +42,7 @@ impl Display for TargetCfg { impl Display for TargetCfgDb { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f)?; - let sep = " ".repeat(34); - writeln!( - f, - "{sep}───────────── Tracing configuration per target ─────────────" - )?; + Heading("Tracing configuration per target").fmt(f)?; fmt_target_heading(f)?; self.targets.values().for_each(|unit| { let _ = writeln!(f, "{unit}"); @@ -63,8 +60,7 @@ pub(crate) struct TargetCfgDbByTag<'a>(pub(crate) &'a TargetCfgDb); impl Display for TargetCfgDbByTag<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { writeln!(f)?; - let sep = " ".repeat(34); - writeln!(f, "{sep}──────── Tracing targets tags ────────")?; + Heading("Tracing tags").fmt(f)?; let db = self.0; fmt_target_heading(f)?; From 2c4745bf62c3f0aa9aaf4137fe7d701b8e359cdf Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 16:17:11 +0100 Subject: [PATCH 6/7] feat(routing): use common utils for Display Signed-off-by: Fredi Raspall --- common/src/cliprovider.rs | 2 +- routing/src/cli/display.rs | 24 +++++++++++++++--------- routing/src/event.rs | 7 +++---- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/common/src/cliprovider.rs b/common/src/cliprovider.rs index 91ca575d5..ae1455dec 100644 --- a/common/src/cliprovider.rs +++ b/common/src/cliprovider.rs @@ -65,7 +65,7 @@ impl CliString for &str {} pub struct Heading(pub T); impl Display for Heading { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, " {:─^100}", format!(" {} ", self.0)) + writeln!(f, " {:━^100}", format!(" {} ", self.0)) } } diff --git a/routing/src/cli/display.rs b/routing/src/cli/display.rs index a034de560..de8a121fa 100644 --- a/routing/src/cli/display.rs +++ b/routing/src/cli/display.rs @@ -271,7 +271,7 @@ fn fmt_vrf_oneline(vrf: &Vrf, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Resu let description = vrf.description.clone().unwrap_or_else(|| "--".to_string()); writeln!( f, - "\n ━━━━━━━━━\n Vrf: '{}' (id: {}) description: {description}", + " Vrf: '{}' (id: {}) description: {description}\n", vrf.name, vrf.vrfid )?; Ok(()) @@ -308,8 +308,9 @@ impl Fn(&'a (&Ipv4Prefix, &Route)) -> bool> Display for VrfViewV4<'_, // displayed routes let mut displayed = 0; - fmt_vrf_oneline(self.vrf, f)?; Heading(format!("Ipv4 routes ({total_routes})")).fmt(f)?; + fmt_vrf_oneline(self.vrf, f)?; + for (prefix, route) in rt_iter { write!(f, " {} {prefix:?} {route}", route.flags)?; displayed += 1; @@ -342,8 +343,9 @@ impl Fn(&'a (&Ipv6Prefix, &Route)) -> bool> Display for VrfViewV6<'_, // displayed routes let mut displayed = 0; - fmt_vrf_oneline(self.vrf, f)?; Heading(format!("Ipv6 routes ({total_routes})")).fmt(f)?; + fmt_vrf_oneline(self.vrf, f)?; + for (prefix, route) in rt_iter { write!(f, " {} {prefix:?} {route}", route.flags)?; displayed += 1; @@ -363,8 +365,9 @@ impl Fn(&'a (&Ipv6Prefix, &Route)) -> bool> Display for VrfViewV6<'_, pub struct VrfV4Nexthops<'a>(pub &'a Vrf); impl Display for VrfV4Nexthops<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fmt_vrf_oneline(self.0, f)?; Heading("Ipv4 Next-hops").fmt(f)?; + fmt_vrf_oneline(self.0, f)?; + let iter = self.0.nhstore.iter().filter(|nh| { nh.key.address.is_some_and(|a| a.is_ipv4()) || nh.key.address.is_none() @@ -379,8 +382,9 @@ impl Display for VrfV4Nexthops<'_> { pub struct VrfV6Nexthops<'a>(pub &'a Vrf); impl Display for VrfV6Nexthops<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - fmt_vrf_oneline(self.0, f)?; Heading("Ipv6 Next-hops").fmt(f)?; + fmt_vrf_oneline(self.0, f)?; + let iter = self.0.nhstore.iter().filter(|nh| { nh.key.address.is_some_and(|a| a.is_ipv6()) || nh.key.address.is_none() @@ -604,7 +608,7 @@ impl Display for RmacEntry { } impl Display for RmacStore { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - Heading(format!("Rmac store ({})", self.len())).fmt(f)?; + Heading(format!("Router macs ({})", self.len())).fmt(f)?; fmt_rmac_heading(f)?; for rmac in self.values() { writeln!(f, "{rmac}")?; @@ -616,7 +620,7 @@ impl Display for RmacStore { //========================= Rmac Store ================================// impl Display for Vtep { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "\n ───────── Local VTEP configuration ─────────")?; + Heading("Local VTEP configuration").fmt(f)?; fmt_opt_value(f, " ip address", self.get_ip().as_ref(), true)?; fmt_opt_value(f, " Mac address", self.get_mac().as_ref(), true) } @@ -768,8 +772,9 @@ impl Fn(&'a (&Ipv4Prefix, &FibRoute)) -> bool> Display for FibViewV4< let total_entries = fibr.len_v4(); let mut displayed = 0; - fmt_vrf_oneline(self.vrf, f)?; Heading(format!("Ipv4 FIB ({total_entries} destinations)")).fmt(f)?; + fmt_vrf_oneline(self.vrf, f)?; + for (prefix, route) in rt_iter { write!(f, " {prefix:?} {route}")?; displayed += 1; @@ -805,8 +810,9 @@ impl Fn(&'a (&Ipv6Prefix, &FibRoute)) -> bool> Display for FibViewV6< let total_entries = fibr.len_v6(); let mut displayed = 0; - fmt_vrf_oneline(self.vrf, f)?; Heading(format!("Ipv6 FIB ({total_entries} destinations)")).fmt(f)?; + fmt_vrf_oneline(self.vrf, f)?; + for (prefix, route) in rt_iter { write!(f, " {prefix:?} {route}")?; displayed += 1; diff --git a/routing/src/event.rs b/routing/src/event.rs index 6c66615b4..58cf5dae8 100644 --- a/routing/src/event.rs +++ b/routing/src/event.rs @@ -5,6 +5,7 @@ use chrono::DateTime; use chrono::Local; +use common::cliprovider::Heading; use std::fmt::Display; /// An `Event` is a wrapper over a generic type T that represents something that happened. @@ -74,14 +75,12 @@ impl Display for Event { impl Display for EventLog { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, " {}", self.name)?; + Heading(self.name.as_str()).fmt(f)?; writeln!( f, - " generated: {} stored: {} capacity: {}", + " generated: {} stored: {} capacity: {}\n", self.ord, self.count, self.max )?; - writeln!(f, " ━━━━━━━━━━━━━")?; - for num in 0..self.count { let index = (self.next + num) % self.max; let event = &self.items[index]; From 97596d11f798c4a3fada74d1e9cd253969a27c5f Mon Sep 17 00:00:00 2001 From: Fredi Raspall Date: Wed, 18 Mar 2026 17:35:45 +0100 Subject: [PATCH 7/7] feat(net,flow-entry): improve Display of flows - Simplify the impl of Display for FlowKey so that no strings are created for intermediate data. - Move impl Display of FlowInfo together with impl Display for FlowKey and rename file. - Adjust the layout of the flow table to improve readability - Use upper case for protocol acronyms Signed-off-by: Fredi Raspall --- flow-entry/src/flow_table/display.rs | 4 +- net/src/flows/display.rs | 80 ++++++++++++++++++++++++++++ net/src/flows/flow_info.rs | 41 -------------- net/src/flows/flow_key.rs | 8 +++ net/src/flows/flow_key_display.rs | 53 ------------------ net/src/flows/mod.rs | 2 +- net/src/ip/mod.rs | 2 +- 7 files changed, 92 insertions(+), 98 deletions(-) create mode 100644 net/src/flows/display.rs delete mode 100644 net/src/flows/flow_key_display.rs diff --git a/flow-entry/src/flow_table/display.rs b/flow-entry/src/flow_table/display.rs index 4aa9ae284..25b344899 100644 --- a/flow-entry/src/flow_table/display.rs +++ b/flow-entry/src/flow_table/display.rs @@ -12,8 +12,8 @@ impl Display for FlowTable { for entry in table.iter() { let key = entry.key(); match entry.value().upgrade() { - Some(value) => writeln!(f, "key = {key}\ndata = {value}")?, - None => writeln!(f, "key = {key} NONE")?, + Some(value) => writeln!(f, "{key}\n{value}")?, + None => writeln!(f, "{key}: NONE")?, } } } else { diff --git a/net/src/flows/display.rs b/net/src/flows/display.rs new file mode 100644 index 000000000..f3f4793ef --- /dev/null +++ b/net/src/flows/display.rs @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Open Network Fabric Authors + +//! Flow keys + +use super::flow_info::{FlowInfo, FlowInfoLocked}; +use super::flow_key::{FlowKey, FlowKeyData}; + +use std::fmt::Display; +use std::time::Instant; + +impl Display for FlowKeyData { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(vpcd) = self.src_vpcd() { + write!(f, "from: {vpcd},")?; + } + let ports = self.ports(); + let proto = self.proto(); + let src_ip = self.src_ip(); + let dst_ip = self.dst_ip(); + if let Some((src_port, dst_port)) = ports { + write!(f, "{src_ip}:{src_port} -> {dst_ip}:{dst_port} {proto}")?; + } else { + write!(f, "{src_ip} -> {dst_ip} {proto}")?; + } + if let Some(id) = self.icmp_id() { + write!(f, " id:{id}")?; + } + Ok(()) + } +} + +impl Display for FlowKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FlowKey::Unidirectional(data) => write!(f, "{data}"), + } + } +} + +impl Display for FlowInfoLocked { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(data) = &self.dst_vpcd { + writeln!(f, " dst-vpcd:{data}")?; + } + if let Some(data) = &self.port_fw_state { + writeln!(f, " port-forwarding:{data}")?; + } + if let Some(data) = &self.nat_state { + writeln!(f, " nat-state:{data}")?; + } + Ok(()) + } +} + +impl Display for FlowInfo { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let expires_at = self.expires_at(); + let expires_in = expires_at.saturating_duration_since(Instant::now()); + let genid = self.genid(); + + if let Ok(info) = self.locked.try_read() { + write!(f, "{info}")?; + } else { + write!(f, "could not lock!")?; + } + let has_related = self + .related + .as_ref() + .and_then(std::sync::Weak::upgrade) + .map_or("no", |_| "yes"); + + writeln!( + f, + " status: {:?}, expires in {}s, related: {has_related}, genid: {genid}", + self.status(), + expires_in.as_secs(), + ) + } +} diff --git a/net/src/flows/flow_info.rs b/net/src/flows/flow_info.rs index 2b4bfa024..c0f0cc54a 100644 --- a/net/src/flows/flow_info.rs +++ b/net/src/flows/flow_info.rs @@ -392,44 +392,3 @@ impl FlowInfo { .store(status, std::sync::atomic::Ordering::Relaxed); } } - -impl Display for FlowInfoLocked { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(data) = &self.dst_vpcd { - writeln!(f, " dst-vpcd:{data}")?; - } - if let Some(data) = &self.port_fw_state { - writeln!(f, " port-forwarding:{data}")?; - } - if let Some(data) = &self.nat_state { - writeln!(f, " nat-state:{data}")?; - } - Ok(()) - } -} - -impl Display for FlowInfo { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let expires_at = self.expires_at.load(Ordering::Relaxed); - let expires_in = expires_at.saturating_duration_since(Instant::now()); - let genid = self.genid(); - writeln!(f)?; - if let Ok(info) = self.locked.try_read() { - write!(f, "{info}")?; - } else { - write!(f, "could not lock!")?; - } - let has_related = self - .related - .as_ref() - .and_then(std::sync::Weak::upgrade) - .map_or("no", |_| "yes"); - - writeln!( - f, - " status: {:?}, expires in {}s, related: {has_related}, genid: {genid}", - self.status, - expires_in.as_secs(), - ) - } -} diff --git a/net/src/flows/flow_key.rs b/net/src/flows/flow_key.rs index 5621f298a..fb1366a9d 100644 --- a/net/src/flows/flow_key.rs +++ b/net/src/flows/flow_key.rs @@ -487,6 +487,14 @@ impl FlowKeyData { &self.dst_ip } + #[must_use] + pub fn icmp_id(&self) -> Option { + match &self.proto_key_info { + IpProtoKey::Icmp(IcmpProtoKey::QueryMsgData(id)) => Some(*id), + _ => None, + } + } + #[must_use] pub fn src_port(&self) -> Option> { match self.proto_key_info { diff --git a/net/src/flows/flow_key_display.rs b/net/src/flows/flow_key_display.rs deleted file mode 100644 index 911b9f261..000000000 --- a/net/src/flows/flow_key_display.rs +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// Copyright Open Network Fabric Authors - -//! Flow keys - -use super::flow_key::{FlowKey, FlowKeyData, IcmpProtoKey, IpProtoKey}; -use std::fmt::Display; - -impl Display for FlowKeyData { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let (protocol, source, destination, icmp_data) = match self.proto_key_info() { - IpProtoKey::Tcp(key) => ( - "TCP", - format!("{}:{}", self.src_ip(), key.src_port.as_u16()), - format!("{}:{}", self.dst_ip(), key.dst_port.as_u16()), - String::new(), - ), - IpProtoKey::Udp(key) => ( - "UDP", - format!("{}:{}", self.src_ip(), key.src_port.as_u16()), - format!("{}:{}", self.dst_ip(), key.dst_port.as_u16()), - String::new(), - ), - IpProtoKey::Icmp(key) => { - let icmp_data_str = match key { - IcmpProtoKey::QueryMsgData(id) => format!("id:{id}"), - IcmpProtoKey::ErrorMsgData(Some(_)) => "".to_string(), - IcmpProtoKey::ErrorMsgData(None) | IcmpProtoKey::Unsupported => String::new(), - }; - ( - "ICMP", - format!("{}", self.src_ip()), - format!("{}", self.dst_ip()), - icmp_data_str, - ) - } - }; - - match self.src_vpcd() { - Some(vpcd) => write!(f, "{{ VPCs({vpcd}"), - None => write!(f, "{{ VPCs(None->"), - }?; - write!(f, " {protocol} ({source}, {destination}){icmp_data} }}") - } -} - -impl Display for FlowKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - FlowKey::Unidirectional(data) => write!(f, "{data}"), - } - } -} diff --git a/net/src/flows/mod.rs b/net/src/flows/mod.rs index 22306bf25..32f8d6e42 100644 --- a/net/src/flows/mod.rs +++ b/net/src/flows/mod.rs @@ -9,8 +9,8 @@ pub mod atomic_instant; pub mod flow_info; pub mod flow_info_item; +pub mod display; pub mod flow_key; -pub mod flow_key_display; pub use atomic_instant::AtomicInstant; pub use flow_info::*; diff --git a/net/src/ip/mod.rs b/net/src/ip/mod.rs index 93334a7ea..bc734b2d8 100644 --- a/net/src/ip/mod.rs +++ b/net/src/ip/mod.rs @@ -122,7 +122,7 @@ impl Display for UnicastIpAddr { impl Display for NextHeader { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self.0.keyword_str() { - Some(s) => write!(f, "{}", s.to_lowercase()), + Some(s) => write!(f, "{s}"), None => write!(f, "{}", self.0.0), } }