diff --git a/netstack/src/scheme/netfilter.rs b/netstack/src/scheme/netfilter.rs index 84ba4d5a48..893d78e311 100644 --- a/netstack/src/scheme/netfilter.rs +++ b/netstack/src/scheme/netfilter.rs @@ -44,7 +44,7 @@ use syscall::schemev2::NewFdFlags; use syscall::{Error as SyscallError, Result as SyscallResult}; use crate::error::{Error, Result}; -use crate::filter::{parse_nat_rule, parse_rule, FilterTable, Hook, Verdict}; +use crate::filter::{parse_nat_rule, parse_rule, FilterTable, Hook, NatType, Verdict}; const WRITE_BUFFER_MAX_SIZE: usize = 0xffff; @@ -195,6 +195,24 @@ impl NetFilterSchemeInner { (format!("{}\n", policy.name()).into_bytes(), true, true) } ["reset"] => (Vec::new(), false, true), + ["stats"] => { + let table = self.table.borrow(); + let mut out = String::new(); + for &hook in &Hook::ALL { + let name = hook.name(); + let (pkts, bytes) = table.chain_counters.get(&hook).copied().unwrap_or((0, 0)); + let policy = table.default_policy.get(&hook).copied().unwrap_or(Verdict::Accept); + out.push_str(&format!("{}: packets={} bytes={} policy={}\n", name, pkts, bytes, policy.name())); + } + let snat_count = table.nat_table.rules.iter().filter(|r| r.nat_type == NatType::Snat).count(); + let dnat_count = table.nat_table.rules.len() - snat_count; + out.push_str(&format!("rules: {} active (snat={} dnat={})\n", + table.rules.len(), snat_count, dnat_count)); + if let Some(ref ct) = table.conntrack { + out.push_str(&format!("conntrack: {}\n", ct.len())); + } + (out.into_bytes(), true, false) + }, _ => return Err(SyscallError::new(syscall::ENOENT)), };