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" => {