netcfg: interface enable/disable control (ip link set eth0 down/up)
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 <state>'. 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.
This commit is contained in:
@@ -87,6 +87,7 @@ pub struct EthernetLink {
|
||||
ip_address: Option<IpCidr>,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -522,6 +522,40 @@ fn mk_root_node(
|
||||
None => "Device not found\n".into(),
|
||||
}
|
||||
}
|
||||
},
|
||||
"enabled" => {
|
||||
rw [devices] (Option<bool>, 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" => {
|
||||
|
||||
Reference in New Issue
Block a user