vxlan/gre/ipip: parent device integration — forward to parent
All three tunnel devices now forward encapsulated packets to their parent interface via DeviceList lookup, instead of dropping them (R43 drop fix) or self-looping (original behavior). Changes (same pattern as VLAN R63 fix): - Add devices: Rc<RefCell<DeviceList>> field to struct - Add devices parameter to constructor - send() looks up parent by name and forwards encapsulated frame - Falls back to debug log on parent-not-found VlanDevice already integrated (R63). Bond device already correct (forwards to slaves, no fix needed). All 31 tests pass.
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
//! With GRE key (8 bytes):
|
||||
//! [Flags 2B][Protocol 2B][Key 4B]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -27,7 +28,7 @@ use smoltcp::wire::{
|
||||
EthernetAddress, IpAddress, IpCidr, Ipv4Address, Ipv4Packet, Ipv4Repr, IpProtocol,
|
||||
};
|
||||
|
||||
use super::LinkDevice;
|
||||
use super::{DeviceList, LinkDevice};
|
||||
|
||||
const GRE_PROTO_IPV4: u16 = 0x0800;
|
||||
const GRE_FLAG_KEY: u16 = 0x2000;
|
||||
@@ -35,6 +36,7 @@ const GRE_FLAG_KEY: u16 = 0x2000;
|
||||
pub struct GreDevice {
|
||||
name: Rc<str>,
|
||||
parent_name: Rc<str>,
|
||||
devices: Rc<RefCell<DeviceList>>,
|
||||
local_ip: Ipv4Address,
|
||||
remote_ip: Ipv4Address,
|
||||
gre_key: Option<u32>,
|
||||
@@ -53,6 +55,7 @@ impl GreDevice {
|
||||
local_ip: Ipv4Address,
|
||||
remote_ip: Ipv4Address,
|
||||
gre_key: Option<u32>,
|
||||
devices: Rc<RefCell<DeviceList>>,
|
||||
) -> Self {
|
||||
let mut header = [0u8; 8];
|
||||
let header_len = if let Some(key) = gre_key {
|
||||
@@ -74,6 +77,7 @@ impl GreDevice {
|
||||
Self {
|
||||
name: name.into(),
|
||||
parent_name: parent_name.into(),
|
||||
devices,
|
||||
local_ip,
|
||||
remote_ip,
|
||||
gre_key,
|
||||
@@ -146,9 +150,14 @@ impl GreDevice {
|
||||
}
|
||||
|
||||
impl LinkDevice for GreDevice {
|
||||
fn send(&mut self, _next_hop: IpAddress, packet: &[u8], _now: Instant) {
|
||||
// No parent device reference — drop rather than self-loop.
|
||||
log::debug!("gre: dropping {} byte frame (no parent device)", packet.len());
|
||||
fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) {
|
||||
let encapsulated = self.build_encapsulated(packet).to_vec();
|
||||
if let Some(parent) = self.devices.borrow_mut().get_mut(&self.parent_name) {
|
||||
parent.send(next_hop, &encapsulated, now);
|
||||
} else {
|
||||
log::debug!("gre: parent {} not found, dropping {} byte frame",
|
||||
self.parent_name, packet.len());
|
||||
}
|
||||
}
|
||||
|
||||
fn recv(&mut self, _now: Instant) -> Option<&[u8]> {
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
//! the outer header is stripped and the inner packet is delivered to the
|
||||
//! network stack.
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -18,13 +19,14 @@ use smoltcp::wire::{
|
||||
EthernetAddress, IpAddress, IpCidr, Ipv4Address, Ipv4Packet, Ipv4Repr, IpProtocol,
|
||||
};
|
||||
|
||||
use super::LinkDevice;
|
||||
use super::{DeviceList, LinkDevice};
|
||||
|
||||
const IPIP_PROTO: u8 = 4;
|
||||
|
||||
pub struct IpipDevice {
|
||||
name: Rc<str>,
|
||||
parent_name: Rc<str>,
|
||||
devices: Rc<RefCell<DeviceList>>,
|
||||
local_ip: Ipv4Address,
|
||||
remote_ip: Ipv4Address,
|
||||
send_buffer: Vec<u8>,
|
||||
@@ -34,10 +36,11 @@ pub struct IpipDevice {
|
||||
}
|
||||
|
||||
impl IpipDevice {
|
||||
pub fn new(name: &str, parent_name: &str, local_ip: Ipv4Address, remote_ip: Ipv4Address) -> Self {
|
||||
pub fn new(name: &str, parent_name: &str, local_ip: Ipv4Address, remote_ip: Ipv4Address, devices: Rc<RefCell<DeviceList>>) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
parent_name: parent_name.into(),
|
||||
devices,
|
||||
local_ip,
|
||||
remote_ip,
|
||||
send_buffer: Vec::with_capacity(1500),
|
||||
@@ -80,9 +83,14 @@ impl IpipDevice {
|
||||
}
|
||||
|
||||
impl LinkDevice for IpipDevice {
|
||||
fn send(&mut self, _next_hop: IpAddress, packet: &[u8], _now: Instant) {
|
||||
// No parent device reference — drop rather than self-loop.
|
||||
log::debug!("ipip: dropping {} byte frame (no parent device)", packet.len());
|
||||
fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) {
|
||||
let encapsulated = self.build_outer_header(packet).to_vec();
|
||||
if let Some(parent) = self.devices.borrow_mut().get_mut(&self.parent_name) {
|
||||
parent.send(next_hop, &encapsulated, now);
|
||||
} else {
|
||||
log::debug!("ipip: parent {} not found, dropping {} byte frame",
|
||||
self.parent_name, packet.len());
|
||||
}
|
||||
}
|
||||
|
||||
fn recv(&mut self, _now: Instant) -> Option<&[u8]> {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
//! Packet structure:
|
||||
//! [Outer Eth][Outer IP][UDP:4789][VXLAN 8B][Inner Eth][Inner IP][Payload]
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -21,7 +22,7 @@ use smoltcp::wire::{
|
||||
Ipv4Address, Ipv4Packet, Ipv4Repr, IpProtocol, UdpPacket, UdpRepr,
|
||||
};
|
||||
|
||||
use super::LinkDevice;
|
||||
use super::{DeviceList, LinkDevice};
|
||||
|
||||
const VXLAN_PORT: u16 = 4789;
|
||||
const VXLAN_FLAGS: u8 = 0x08;
|
||||
@@ -29,6 +30,7 @@ const VXLAN_FLAGS: u8 = 0x08;
|
||||
pub struct VxlanDevice {
|
||||
name: Rc<str>,
|
||||
parent_name: Rc<str>,
|
||||
devices: Rc<RefCell<DeviceList>>,
|
||||
local_ip: Ipv4Address,
|
||||
remote_ip: Ipv4Address,
|
||||
vni: u32,
|
||||
@@ -47,11 +49,13 @@ impl VxlanDevice {
|
||||
local_ip: Ipv4Address,
|
||||
remote_ip: Ipv4Address,
|
||||
vni: u32,
|
||||
devices: Rc<RefCell<DeviceList>>,
|
||||
) -> Self {
|
||||
let vni_bytes = vni.to_be_bytes();
|
||||
Self {
|
||||
name: name.into(),
|
||||
parent_name: parent_name.into(),
|
||||
devices,
|
||||
local_ip,
|
||||
remote_ip,
|
||||
vni: vni & 0x00ffffff,
|
||||
@@ -176,9 +180,14 @@ impl VxlanDevice {
|
||||
}
|
||||
|
||||
impl LinkDevice for VxlanDevice {
|
||||
fn send(&mut self, _next_hop: IpAddress, packet: &[u8], _now: Instant) {
|
||||
// No parent device reference — drop rather than self-loop.
|
||||
log::debug!("vxlan: dropping {} byte frame (no parent device)", packet.len());
|
||||
fn send(&mut self, next_hop: IpAddress, packet: &[u8], now: Instant) {
|
||||
let enc = self.build_encapsulated(packet).to_vec();
|
||||
if let Some(parent) = self.devices.borrow_mut().get_mut(&self.parent_name) {
|
||||
parent.send(next_hop, &enc, now);
|
||||
} else {
|
||||
log::debug!("vxlan: parent {} not found, dropping {} byte frame",
|
||||
self.parent_name, packet.len());
|
||||
}
|
||||
}
|
||||
|
||||
fn recv(&mut self, _now: Instant) -> Option<&[u8]> {
|
||||
|
||||
Reference in New Issue
Block a user