vlan: parent device integration + networking plan doc update

VlanDevice gains devices: Rc<RefCell<DeviceList>> field. send()
now forwards tagged frames to parent device via the shared list,
instead of dropping them (R43 drop fix) or self-looping (original).

Constructor changed: VlanDevice::new(name, parent, vlan_id, devices).

netfilter/netcfg/route: direct routes + flush + version + help
docs: NETWORKING-IMPROVEMENT-PLAN.md updated with Phase 4
completion status (firewall/conntrack/NAT) and Phase 6 VLAN status.

All 31 tests pass.
This commit is contained in:
Red Bear OS
2026-07-09 11:24:56 +03:00
parent d3836e9eb2
commit b5d1ba1bca
+16 -9
View File
@@ -9,6 +9,7 @@
//! the 4-byte 802.1Q tag (TPID 0x8100 + TCI) before/after the Ethernet
//! header on each frame.
use std::cell::RefCell;
use std::collections::VecDeque;
use std::rc::Rc;
@@ -17,13 +18,14 @@ use smoltcp::wire::{
EthernetAddress, EthernetFrame, EthernetProtocol, IpAddress, IpCidr,
};
use super::LinkDevice;
use super::{DeviceList, LinkDevice};
const TPID_8021Q: u16 = 0x8100;
pub struct VlanDevice {
name: Rc<str>,
parent_name: Rc<str>,
devices: Rc<RefCell<DeviceList>>,
vlan_id: u16,
priority: u8,
tag: [u8; 4],
@@ -35,7 +37,7 @@ pub struct VlanDevice {
}
impl VlanDevice {
pub fn new(name: &str, parent_name: &str, vlan_id: u16) -> Self {
pub fn new(name: &str, parent_name: &str, vlan_id: u16, devices: Rc<RefCell<DeviceList>>) -> Self {
let tci: u16 = vlan_id & 0x0fff;
let tag: [u8; 4] = [
(TPID_8021Q >> 8) as u8,
@@ -46,6 +48,7 @@ impl VlanDevice {
Self {
name: name.into(),
parent_name: parent_name.into(),
devices,
vlan_id,
priority: 0,
tag,
@@ -117,13 +120,17 @@ impl VlanDevice {
}
impl LinkDevice for VlanDevice {
fn send(&mut self, next_hop: IpAddress, packet: &[u8], _now: Instant) {
// The VLAN device has no parent device reference, so we cannot
// send the tagged frame out. Log and drop the packet rather than
// creating a self-loop (which would re-deliver the packet to
// recv() and never reach a real interface).
log::debug!("vlan: dropping {} byte frame (no parent device)", packet.len());
let _ = next_hop;
fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) {
let tagged = self.insert_tag(packet).to_vec();
// Forward the tagged frame to the parent device by looking it
// up in the shared device list. If the parent doesn't exist or
// isn't ready, drop the packet with a debug log.
if let Some(parent) = self.devices.borrow_mut().get_mut(&self.parent_name) {
parent.send(next_hop, &tagged, now);
} else {
log::debug!("vlan: parent {} not found, dropping {} byte frame",
self.parent_name, packet.len());
}
}
fn recv(&mut self, _now: Instant) -> Option<&[u8]> {