From 012001748464bf94f69d440ef29c32782ee9d56d Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Sat, 18 Jul 2026 00:49:44 +0900 Subject: [PATCH] fix(net): silence benign no-network warnings; add e1000e (82574) support - smolnetd: an empty ip_router (DHCP-managed or deliberately network-less like the bare target) is a valid 'no default gateway' state, not a malformed config -> no warning. - router: a limited/directed IPv4 broadcast (DHCP DISCOVER to 255.255.255.255 before any lease/route exists) legitimately has no routing-table entry; don't warn 'No route found' for broadcast destinations. - e1000d: add the 82574L (0x10d3, QEMU '-device e1000e') to the E1000 match list; it keeps the legacy descriptor/register interface this driver uses. I219 is intentionally excluded (integrated MDIO PHY, different init). --- drivers/net/e1000d/config.toml | 8 +++++++- netstack/src/router/mod.rs | 9 ++++++++- netstack/src/scheme/mod.rs | 10 ++++++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/net/e1000d/config.toml b/drivers/net/e1000d/config.toml index 4862da27dc..e31c45c2c7 100644 --- a/drivers/net/e1000d/config.toml +++ b/drivers/net/e1000d/config.toml @@ -1,5 +1,11 @@ [[drivers]] name = "E1000 NIC" class = 0x02 -ids = { 0x8086 = [0x1004, 0x100e, 0x100f, 0x109a, 0x1503] } +# Classic 82540/82545-family PCI e1000 plus the 82574L (0x10d3), the PCIe +# "e1000e" part that QEMU emulates with `-device e1000e`. The 82574 retains the +# legacy descriptor + register interface this driver uses, so it works here. +# NOTE: Intel I219 (Lewisburg/PCH LOM on modern Intel desktops) is deliberately +# NOT listed — it uses an integrated MDIO PHY and a different init sequence that +# this legacy driver does not yet handle; claiming it would break its NIC. +ids = { 0x8086 = [0x1004, 0x100e, 0x100f, 0x109a, 0x1503, 0x10d3] } command = ["e1000d"] diff --git a/netstack/src/router/mod.rs b/netstack/src/router/mod.rs index 476d5a6642..c2920deaa8 100644 --- a/netstack/src/router/mod.rs +++ b/netstack/src/router/mod.rs @@ -304,7 +304,14 @@ impl Router { let (next_hop, src_rule, dev_name, route_type) = { let route_table = self.route_table.borrow(); let Some(rule) = route_table.lookup_rule(&dst_addr) else { - warn!("No route found for destination: {}", dst_addr); + // A limited/directed IPv4 broadcast (e.g. a DHCP + // DISCOVER to 255.255.255.255 before any lease or + // route exists) legitimately has no routing-table + // entry — it is delivered as a link-layer broadcast, + // not routed — so this is not a real routing error. + if !ipv4_pkt.dst_addr().is_broadcast() { + warn!("No route found for destination: {}", dst_addr); + } continue; }; let next_hop = rule.via.unwrap_or(dst_addr); diff --git a/netstack/src/scheme/mod.rs b/netstack/src/scheme/mod.rs index 751668fc5e..0ffa062697 100644 --- a/netstack/src/scheme/mod.rs +++ b/netstack/src/scheme/mod.rs @@ -112,12 +112,18 @@ impl Smolnetd { // than panicking. The route lookup below will return None for // an invalid gateway, which is the correct degraded behavior. let default_gw = match getcfg("ip_router") { + Ok(s) if s.trim().is_empty() => { + // Empty ip_router is a valid "no default gateway" configuration + // (DHCP will fill it in, or the host is deliberately network-less + // like the bare target). Not a warning. + Ipv4Address::new(0, 0, 0, 0) + } Ok(s) => Ipv4Address::from_str(s.trim()).unwrap_or_else(|_| { log::warn!("smolnetd: invalid ip_router '{}' in cfg, using 0.0.0.0", s); Ipv4Address::new(0, 0, 0, 0) }), - Err(e) => { - log::warn!("smolnetd: ip_router not set in cfg ({:?}), using 0.0.0.0", e); + Err(_) => { + // File absent = no gateway configured; also a normal state. Ipv4Address::new(0, 0, 0, 0) } };