restore: networking stack files from reflog (Phases 1-6)

Recovered from reflog commits 1c80937e and d0ecc067 after force-push data loss.
Includes: filter/, icmp_error.rs, slaac.rs, bond.rs, bridge.rs, gre.rs, ipip.rs,
qdisc.rs, tun.rs, vlan.rs, vxlan.rs, netfilter.rs, tun.rs, conntrack.rs, nat.rs,
rule.rs, table.rs, redbear-ufw/, dhcpv6d/, netdiag/ — 39 files total.
This commit is contained in:
Red Bear OS
2026-07-08 13:27:49 +03:00
parent 4506bfe02a
commit bb3e36e4e0
40 changed files with 6042 additions and 467 deletions
+141 -5
View File
@@ -7,7 +7,7 @@ use redox_scheme::{
CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket,
};
use scheme_utils::HandleMap;
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address, Ipv6Address};
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::mem;
@@ -35,6 +35,35 @@ fn gateway_cidr() -> IpCidr {
IpCidr::new(IpAddress::v4(0, 0, 0, 0), 0)
}
fn cidr_network(cidr: IpCidr) -> IpCidr {
match cidr {
IpCidr::Ipv4(c) => IpCidr::Ipv4(c.network()),
IpCidr::Ipv6(c) => {
let prefix = c.prefix_len();
let bytes = c.address().octets();
let mut masked = [0u8; 16];
let full_bytes = (prefix / 8) as usize;
let remainder = prefix % 8;
for i in 0..full_bytes {
masked[i] = bytes[i];
}
if remainder > 0 && full_bytes < 16 {
masked[full_bytes] = bytes[full_bytes] & (0xff << (8 - remainder));
}
let segments: [u16; 8] = core::array::from_fn(|i| {
u16::from_be_bytes([masked[i * 2], masked[i * 2 + 1]])
});
IpCidr::Ipv6(smoltcp::wire::Ipv6Cidr::new(
Ipv6Address::new(
segments[0], segments[1], segments[2], segments[3],
segments[4], segments[5], segments[6], segments[7],
),
prefix,
))
}
}
}
fn parse_route(value: &str, route_table: &RouteTable) -> SyscallResult<Rule> {
let mut parts = value.split_whitespace();
let cidr_str = parts.next().ok_or(SyscallError::new(syscall::EINVAL))?;
@@ -109,6 +138,35 @@ fn mk_root_node(
}
Ok(())
}
},
"nameserver6" => {
rw [dns_config, notifier] (Option<Ipv6Address>, None)
|| {
match dns_config.borrow().name_server6 {
Some(ip) => format!("{}\n", ip),
None => "Not configured\n".into(),
}
}
|cur_value, line| {
if cur_value.is_none() {
let ip = Ipv6Address::from_str(line.trim())
.map_err(|_| SyscallError::new(syscall::EINVAL))?;
if ip.is_multicast() || ip.is_unspecified() {
return Err(SyscallError::new(syscall::EINVAL));
}
*cur_value = Some(ip);
Ok(())
} else {
Err(SyscallError::new(syscall::EINVAL))
}
}
|cur_value| {
if let Some(ip) = *cur_value {
dns_config.borrow_mut().name_server6 = Some(ip);
notifier.borrow_mut().schedule_notify("resolv/nameserver6");
}
Ok(())
}
}
},
"route" => {
@@ -240,8 +298,7 @@ fn mk_root_node(
let mut route_table = route_table.borrow_mut();
if let Some(old_addr) = dev.ip_address() {
let IpCidr::Ipv4(old_v4_cidr) = old_addr;
let old_network = IpCidr::Ipv4(old_v4_cidr.network());
let old_network = cidr_network(old_addr);
route_table.remove_rule(old_network);
route_table.change_src(old_addr.address(), cidr.address());
@@ -257,8 +314,7 @@ fn mk_root_node(
// job to find give this source.
iface.borrow_mut().update_ip_addrs(|addrs| addrs.insert(0, cidr).unwrap());
let IpCidr::Ipv4(v4_cidr) = cidr;
let network_cidr = IpCidr::Ipv4(v4_cidr.network());
let network_cidr = cidr_network(cidr);
route_table.insert_rule(Rule::new(network_cidr, None, dev.name().clone(), cidr.address()))
}
notifier.borrow_mut().schedule_notify("ifaces/eth0/addr/list");
@@ -267,7 +323,85 @@ fn mk_root_node(
Ok(())
}
},
},
"arp" => {
"list" => {
ro [devices] || {
match devices.borrow().get("eth0") {
Some(dev) => dev.arp_table(),
None => "Device not found\n".into(),
}
}
},
"flush" => {
wo [devices] (Option<()>, None)
|_cur_value, _line| {
Ok(())
}
|cur_value| {
*cur_value = None;
if let Some(dev) = devices.borrow_mut().get_mut("eth0") {
dev.flush_arp();
}
Ok(())
}
},
},
"stats" => {
ro [devices] || {
match devices.borrow().get("eth0") {
Some(dev) => {
let s = dev.statistics();
format!("rx_bytes={} rx_packets={} tx_bytes={} tx_packets={}\n",
s.rx_bytes, s.rx_packets, s.tx_bytes, s.tx_packets)
}
None => "Device not found\n".into(),
}
}
},
"link" => {
ro [devices] || {
match devices.borrow().get("eth0") {
Some(dev) => format!("{}\n", dev.link_state()),
None => "Device not found\n".into(),
}
}
},
"mtu" => {
ro [devices] || {
match devices.borrow().get("eth0") {
Some(dev) => format!("{}\n", dev.mtu()),
None => "Device not found\n".into(),
}
}
}
},
"lo" => {
"addr" => {
"list" => {
ro [devices] || {
match devices.borrow().get("loopback") {
Some(dev) => match dev.ip_address() {
Some(addr) => format!("{addr}\n"),
None => "Not configured\n".into(),
},
None => "Device not found\n".into(),
}
}
}
},
"stats" => {
ro [devices] || {
match devices.borrow().get("loopback") {
Some(dev) => {
let s = dev.statistics();
format!("rx_bytes={} rx_packets={} tx_bytes={} tx_packets={}\n",
s.rx_bytes, s.rx_packets, s.tx_bytes, s.tx_packets)
}
None => "Device not found\n".into(),
}
}
},
}
}
}
@@ -275,6 +409,7 @@ fn mk_root_node(
struct DNSConfig {
name_server: Ipv4Address,
name_server6: Option<Ipv6Address>,
}
type DNSConfigRef = Rc<RefCell<DNSConfig>>;
@@ -352,6 +487,7 @@ impl NetCfgScheme {
let notifier = Notifier::new_ref();
let dns_config = Rc::new(RefCell::new(DNSConfig {
name_server: Ipv4Address::new(8, 8, 8, 8),
name_server6: None,
}));
let mut inner = NetCfgSchemeInner {
scheme_file,