//! Network namespace tests for Linux. //! //! These tests verify MTU detection behavior in complex networking scenarios //! using Linux network namespaces. They require root privileges and will //! skip automatically if not running as root. //! //! Run with: `sudo -E cargo test --package mtu --test netns`
#![cfg(target_os = "linux")]
use std::{
fs::File,
io,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
os::fd::AsRawFd as _,
process::{Command, Stdio},
sync::{
Once,
atomic::{AtomicU32, Ordering},
},
};
use mtu::interface_and_mtu;
static COUNTER: AtomicU32 = AtomicU32::new(0); static SKIP_MESSAGE: Once = Once::new();
fn unique_name(prefix: &str) -> String { let id = COUNTER.fetch_add(1, Ordering::Relaxed);
format!("{prefix}_{}_{id}", std::process::id())
}
/// Run a closure inside this namespace. fn run<F, T>(&self, f: F) -> io::Result<T> where
F: FnOnce() -> T,
{ // Open current namespace to restore later. let orig = File::open("/proc/self/ns/net")?;
// Open target namespace. let path = format!("/var/run/netns/{}", self.name); let target = File::open(&path)?;
impl Drop for VethPair { fn drop(&mutself) {
ip(&["link", "delete", &self.0]);
}
}
/// A test network with a namespace and connected interfaces. struct TestNet {
ns: Option<NetNs>,
_veths: (Option<VethPair>, Option<VethPair>),
}
impl TestNet { /// Create a network with one interface pair. fn new(inside_ip: &str, outside_ip: &str, mtu: u32) -> Option<Self> { let name = unique_name("ns"); let vi = unique_name("vi"); let vo = unique_name("vo"); let mtu_s = mtu.to_string();
let ns = NetNs::new(&name)?; let veth = VethPair::new(&vi, &vo)?;
#[test] fn loopback_v4() {
require_root!(); let net = TestNet::loopback().unwrap(); let (iface, mtu) = net.lookup(Ipv4Addr::LOCALHOST.into()).unwrap();
assert_eq!(iface, "lo");
assert_eq!(mtu, 65536);
}
#[test] fn loopback_v6() {
require_root!(); let net = TestNet::loopback().unwrap(); let (iface, mtu) = net.lookup(Ipv6Addr::LOCALHOST.into()).unwrap();
assert_eq!(iface, "lo");
assert_eq!(mtu, 65536);
}
/// Verify that MTU lookup respects policy routing rules. #[test] fn policy_routing() {
require_root!();
let name = unique_name("ns"); let main_inside = unique_name("vmi"); let main_outside = unique_name("vmo"); let vpn_inside = unique_name("vvi"); let vpn_outside = unique_name("vvo");
let ns = NetNs::new(&name).unwrap(); let _veth_main = VethPair::new(&main_inside, &main_outside).unwrap(); let _veth_vpn = VethPair::new(&vpn_inside, &vpn_outside).unwrap();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.