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:
@@ -0,0 +1,75 @@
|
||||
//! Stateless Address Autoconfiguration (SLAAC) for IPv6 — RFC 4862.
|
||||
//!
|
||||
//! Mirrors Linux 7.1's implementation in:
|
||||
//! - `net/ipv6/addrconf.c` — `addrconf_add_linklocal()` (link-local formation),
|
||||
//! `addrconf_prefix_rcv()` (RA prefix processing), `inet6_addr_add()`
|
||||
//! - `net/ipv6/ndisc.c` — `ndisc_send_rs()` (RS sending),
|
||||
//! `ndisc_router_discovery()` (RA processing)
|
||||
//!
|
||||
//! The autoconfiguration flow:
|
||||
//! 1. Interface gets a MAC → form link-local address `fe80::/10` + EUI-64
|
||||
//! 2. Send Router Solicitation to `ff02::2` (all-routers multicast)
|
||||
//! — mirrors Linux's `ndisc_send_rs()` (ndisc.c:674)
|
||||
//! 3. Router responds with Router Advertisement containing Prefix
|
||||
//! Information options
|
||||
//! — mirrors Linux's `ndisc_router_discovery()` (ndisc.c:1233)
|
||||
//! 4. Extract prefix, validate lifetimes, form SLAAC address
|
||||
//! — mirrors Linux's `addrconf_prefix_rcv()` (addrconf.c:2792)
|
||||
//! 5. Apply address to the interface
|
||||
|
||||
use smoltcp::wire::{EthernetAddress, Ipv6Address, Ipv6Cidr};
|
||||
|
||||
pub const LINK_LOCAL_PREFIX: Ipv6Cidr = Ipv6Cidr::new(
|
||||
Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 0),
|
||||
10,
|
||||
);
|
||||
|
||||
pub const ALL_ROUTERS_MULTICAST: Ipv6Address =
|
||||
Ipv6Address::new(0xff02, 0, 0, 0, 0, 0, 0, 2);
|
||||
|
||||
pub const ALL_NODES_MULTICAST: Ipv6Address =
|
||||
Ipv6Address::new(0xff02, 0, 0, 0, 0, 0, 0, 1);
|
||||
|
||||
pub fn eui64_from_mac(mac: EthernetAddress) -> [u8; 8] {
|
||||
let b = mac.as_bytes();
|
||||
let mut eui = [0u8; 8];
|
||||
eui[0] = b[0] ^ 0x02;
|
||||
eui[1] = b[1];
|
||||
eui[2] = b[2];
|
||||
eui[3] = 0xff;
|
||||
eui[4] = 0xfe;
|
||||
eui[5] = b[3];
|
||||
eui[6] = b[4];
|
||||
eui[7] = b[5];
|
||||
eui
|
||||
}
|
||||
|
||||
pub fn form_link_local(mac: EthernetAddress) -> Ipv6Cidr {
|
||||
let eui = eui64_from_mac(mac);
|
||||
let addr = Ipv6Address::new(
|
||||
0xfe80,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
u16::from_be_bytes([eui[0], eui[1]]),
|
||||
u16::from_be_bytes([eui[2], eui[3]]),
|
||||
u16::from_be_bytes([eui[4], eui[5]]),
|
||||
u16::from_be_bytes([eui[6], eui[7]]),
|
||||
);
|
||||
Ipv6Cidr::new(addr, 64)
|
||||
}
|
||||
|
||||
pub fn form_slaac_addr(prefix: Ipv6Cidr, mac: EthernetAddress) -> Ipv6Address {
|
||||
let eui = eui64_from_mac(mac);
|
||||
let prefix_bytes = prefix.address().octets();
|
||||
Ipv6Address::new(
|
||||
u16::from_be_bytes([prefix_bytes[0], prefix_bytes[1]]),
|
||||
u16::from_be_bytes([prefix_bytes[2], prefix_bytes[3]]),
|
||||
u16::from_be_bytes([prefix_bytes[4], prefix_bytes[5]]),
|
||||
u16::from_be_bytes([prefix_bytes[6], prefix_bytes[7]]),
|
||||
u16::from_be_bytes([eui[0], eui[1]]),
|
||||
u16::from_be_bytes([eui[2], eui[3]]),
|
||||
u16::from_be_bytes([eui[4], eui[5]]),
|
||||
u16::from_be_bytes([eui[6], eui[7]]),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user