From 9bab466704e7fb77bdea4bfa33524aec052cd9e9 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Wed, 8 Jul 2026 18:24:02 +0300 Subject: [PATCH] netcfg: interface enable/disable control (ip link set eth0 down/up) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LinkDevice trait gains is_enabled() and set_enabled() with defaults. EthernetLink stores enabled flag (default: true). When disabled, link_state() reports 'down' regardless of hardware_address presence. netcfg/ifaces/eth0/enabled is rw: cat /scheme/netcfg/ifaces/eth0/enabled → 'up' or 'down' echo up > .../enabled → bring interface up echo down > .../enabled → bring interface down echo on/off/1/0/yes/no → also accepted Mirrors Linux 'ip link set dev '. Pre-existing link state (hardware_address Some/None) unchanged; the enabled flag adds a software override layer that can be toggled without restarting the netstack. --- Cargo.lock | 2 +- netstack/src/link/ethernet.rs | 18 +++++++++++++++- netstack/src/link/mod.rs | 6 ++++++ netstack/src/scheme/netcfg/mod.rs | 34 +++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96a656e90d..4e3d1e0ddb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2532,7 +2532,7 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "usb-core" -version = "0.2.5" +version = "0.3.0" [[package]] name = "usbctl" diff --git a/netstack/src/link/ethernet.rs b/netstack/src/link/ethernet.rs index 6a3eb84a96..c20f5acf68 100644 --- a/netstack/src/link/ethernet.rs +++ b/netstack/src/link/ethernet.rs @@ -87,6 +87,7 @@ pub struct EthernetLink { ip_address: Option, qdisc_config: QdiscConfig, mtu: usize, + enabled: bool, stats: Stats, arp_requests: u64, arp_replies: u64, @@ -123,6 +124,7 @@ impl EthernetLink { slaac_state: Default::default(), qdisc_config: QdiscConfig::default(), mtu: Self::MTU, + enabled: true, stats: Stats::default(), neighbor_cache: Default::default(), arp_requests: 0, @@ -882,7 +884,13 @@ impl LinkDevice for EthernetLink { } fn link_state(&self) -> &'static str { - if self.hardware_address.is_some() { "up" } else { "down" } + if !self.enabled { + "down" + } else if self.hardware_address.is_some() { + "up" + } else { + "down" + } } fn qdisc_info(&self) -> String { @@ -904,5 +912,13 @@ impl LinkDevice for EthernetLink { fn set_mtu(&mut self, mtu: usize) { self.mtu = mtu.clamp(576, 9000); } + + fn is_enabled(&self) -> bool { + self.enabled + } + + fn set_enabled(&mut self, enabled: bool) { + self.enabled = enabled; + } } diff --git a/netstack/src/link/mod.rs b/netstack/src/link/mod.rs index cf2dcba3f5..d637698c83 100644 --- a/netstack/src/link/mod.rs +++ b/netstack/src/link/mod.rs @@ -59,6 +59,12 @@ pub trait LinkDevice { fn set_mtu(&mut self, _mtu: usize) {} + fn is_enabled(&self) -> bool { + true + } + + fn set_enabled(&mut self, _enabled: bool) {} + fn link_state(&self) -> &'static str { "unknown" } diff --git a/netstack/src/scheme/netcfg/mod.rs b/netstack/src/scheme/netcfg/mod.rs index 28ba702a8f..2fe508cd37 100644 --- a/netstack/src/scheme/netcfg/mod.rs +++ b/netstack/src/scheme/netcfg/mod.rs @@ -522,6 +522,40 @@ fn mk_root_node( None => "Device not found\n".into(), } } + }, + "enabled" => { + rw [devices] (Option, None) + || { + match devices.borrow().get("eth0") { + Some(dev) => if dev.is_enabled() { "up\n".to_string() } else { "down\n".to_string() }, + None => "Device not found\n".into(), + } + } + |cur_value, line| { + let s = line.trim(); + match s { + "up" | "1" | "true" | "yes" | "on" => { + if let Some(dev) = devices.borrow_mut().get_mut("eth0") { + dev.set_enabled(true); + *cur_value = Some(true); + Ok(()) + } else { + Err(SyscallError::new(syscall::ENODEV)) + } + } + "down" | "0" | "false" | "no" | "off" => { + if let Some(dev) = devices.borrow_mut().get_mut("eth0") { + dev.set_enabled(false); + *cur_value = Some(false); + Ok(()) + } else { + Err(SyscallError::new(syscall::ENODEV)) + } + } + _ => Err(SyscallError::new(syscall::EINVAL)), + } + } + |_cur_value| { Ok(()) } } }, "lo" => {