stats: add statistics() to bridge, bond, and tun devices
Bridge: statistics() aggregates rx/tx bytes+packets from all member ports. arp_stats() delegates to each port, showing per-port breakdown. Bond: statistics() aggregates from all slaves (active+standby). arp_stats() delegates to each slave. TUN: statistics() now returns live counters tracked during send()/recv(). rx_bytes, rx_packets, tx_bytes, tx_packets increment per-packet. Previously these devices returned Stats::default() (all zeros). Now netcfg /ifaces/*/stats shows real data for bridge, bond, tun.
This commit is contained in:
@@ -18,6 +18,7 @@ use smoltcp::time::Instant;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
|
||||
|
||||
use super::LinkDevice;
|
||||
use super::Stats;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum BondMode {
|
||||
@@ -166,4 +167,28 @@ impl LinkDevice for BondDevice {
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
fn statistics(&self) -> Stats {
|
||||
let mut total = Stats::default();
|
||||
for s in self.slaves.borrow().iter() {
|
||||
let stats = s.dev.statistics();
|
||||
total.rx_bytes += stats.rx_bytes;
|
||||
total.rx_packets += stats.rx_packets;
|
||||
total.tx_bytes += stats.tx_bytes;
|
||||
total.tx_packets += stats.tx_packets;
|
||||
}
|
||||
total
|
||||
}
|
||||
|
||||
fn arp_stats(&self) -> String {
|
||||
let mut out = String::new();
|
||||
let slaves = self.slaves.borrow();
|
||||
for (i, s) in slaves.iter().enumerate() {
|
||||
let stats = s.dev.arp_stats();
|
||||
if !stats.is_empty() {
|
||||
out.push_str(&format!("slave{}: {}", i, stats));
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ use smoltcp::wire::{
|
||||
|
||||
use super::stp::{self, BPDU_MAC, PortState, StpState};
|
||||
use super::LinkDevice;
|
||||
use super::Stats;
|
||||
|
||||
const MAC_AGE_TIMEOUT: Duration = Duration::from_secs(300);
|
||||
|
||||
@@ -235,4 +236,27 @@ impl LinkDevice for BridgeDevice {
|
||||
fn link_state(&self) -> &'static str {
|
||||
if self.ports.borrow().is_empty() { "down" } else { "up" }
|
||||
}
|
||||
|
||||
fn statistics(&self) -> Stats {
|
||||
let mut total = Stats::default();
|
||||
for port in self.ports.borrow().iter() {
|
||||
let s = port.statistics();
|
||||
total.rx_bytes += s.rx_bytes;
|
||||
total.rx_packets += s.rx_packets;
|
||||
total.tx_bytes += s.tx_bytes;
|
||||
total.tx_packets += s.tx_packets;
|
||||
}
|
||||
total
|
||||
}
|
||||
|
||||
fn arp_stats(&self) -> String {
|
||||
let mut out = String::new();
|
||||
for (i, port) in self.ports.borrow().iter().enumerate() {
|
||||
let s = port.arp_stats();
|
||||
if !s.is_empty() {
|
||||
out.push_str(&format!("port{}: {}", i, s));
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ use smoltcp::time::Instant;
|
||||
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr};
|
||||
|
||||
use super::LinkDevice;
|
||||
use super::Stats;
|
||||
|
||||
pub type PacketQueue = Rc<RefCell<VecDeque<Vec<u8>>>>;
|
||||
|
||||
@@ -25,6 +26,7 @@ pub struct TunDevice {
|
||||
tx_queue: PacketQueue,
|
||||
recv_buffer: Vec<u8>,
|
||||
ip_address: Option<IpCidr>,
|
||||
stats: Stats,
|
||||
}
|
||||
|
||||
impl TunDevice {
|
||||
@@ -35,17 +37,22 @@ impl TunDevice {
|
||||
tx_queue: tx,
|
||||
recv_buffer: Vec::new(),
|
||||
ip_address: None,
|
||||
stats: Stats::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LinkDevice for TunDevice {
|
||||
fn send(&mut self, _next_hop: IpAddress, packet: &[u8], _now: Instant) {
|
||||
self.stats.tx_bytes += packet.len() as u64;
|
||||
self.stats.tx_packets += 1;
|
||||
self.tx_queue.borrow_mut().push_back(packet.to_vec());
|
||||
}
|
||||
|
||||
fn recv(&mut self, _now: Instant) -> Option<&[u8]> {
|
||||
self.recv_buffer = self.rx_queue.borrow_mut().pop_front()?;
|
||||
self.stats.rx_bytes += self.recv_buffer.len() as u64;
|
||||
self.stats.rx_packets += 1;
|
||||
Some(&self.recv_buffer)
|
||||
}
|
||||
|
||||
@@ -70,4 +77,8 @@ impl LinkDevice for TunDevice {
|
||||
fn set_ip_address(&mut self, addr: IpCidr) {
|
||||
self.ip_address = Some(addr);
|
||||
}
|
||||
|
||||
fn statistics(&self) -> Stats {
|
||||
self.stats
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user