//! TUN virtual network device — mirrors Linux 7.1's `drivers/net/tun.c`. //! //! The TUN device operates at layer 3 (IP), providing a virtual network //! interface that exchanges raw IP packets with a userspace program via //! the `scheme:tun` interface. This enables VPN software, custom routing //! daemons, and container networking. //! //! Linux reference: `tun_net_xmit()` (kernel→userspace) and //! `tun_get_user()` (userspace→kernel) in `drivers/net/tun.c`. use std::cell::RefCell; use std::collections::VecDeque; use std::rc::Rc; use smoltcp::time::Instant; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use super::LinkDevice; use super::Stats; pub type PacketQueue = Rc>>>; pub struct TunDevice { name: Rc, rx_queue: PacketQueue, tx_queue: PacketQueue, recv_buffer: Vec, ip_address: Option, stats: Stats, } impl TunDevice { pub fn new(name: &str, rx: PacketQueue, tx: PacketQueue) -> Self { Self { name: name.into(), rx_queue: rx, tx_queue: tx, recv_buffer: Vec::new(), ip_address: None, stats: Stats::default(), } } } impl LinkDevice for TunDevice { fn send(&mut self, _next_hop: IpAddress, packet: &[u8], _now: Instant) { self.stats.tx_bytes += packet.len() as u64; self.stats.tx_packets += 1; self.tx_queue.borrow_mut().push_back(packet.to_vec()); } fn recv(&mut self, _now: Instant) -> Option<&[u8]> { self.recv_buffer = self.rx_queue.borrow_mut().pop_front()?; self.stats.rx_bytes += self.recv_buffer.len() as u64; self.stats.rx_packets += 1; Some(&self.recv_buffer) } fn name(&self) -> &Rc { &self.name } fn can_recv(&self) -> bool { !self.rx_queue.borrow().is_empty() } fn mac_address(&self) -> Option { None } fn set_mac_address(&mut self, _addr: EthernetAddress) {} fn ip_address(&self) -> Option { self.ip_address } fn set_ip_address(&mut self, addr: IpCidr) { self.ip_address = Some(addr); } fn statistics(&self) -> Stats { self.stats } }