os/net/
interface.rs

1use crate::device::DeviceType;
2use crate::device::net::net_device::NetDevice;
3use crate::println;
4use crate::sync::SpinLock;
5use alloc::string::{String, ToString};
6use alloc::sync::Arc;
7use alloc::vec::Vec;
8use lazy_static::lazy_static;
9use smoltcp::iface::Interface;
10use smoltcp::time::Instant;
11use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
12
13/// 网络接口管理器
14pub struct NetworkInterfaceManager {
15    interfaces: Vec<Arc<NetworkInterface>>,
16}
17
18impl NetworkInterfaceManager {
19    /// 创建新的网络接口管理器
20    pub fn new() -> Self {
21        Self {
22            interfaces: Vec::new(),
23        }
24    }
25
26    /// 添加网络接口
27    pub fn add_interface(&mut self, interface: Arc<NetworkInterface>) {
28        self.interfaces.push(interface);
29    }
30
31    /// 获取所有网络接口
32    pub fn get_interfaces(&self) -> &[Arc<NetworkInterface>] {
33        &self.interfaces
34    }
35
36    /// 通过名称查找网络接口
37    pub fn find_interface_by_name(&self, name: &str) -> Option<&Arc<NetworkInterface>> {
38        self.interfaces.iter().find(|iface| iface.name() == name)
39    }
40}
41
42lazy_static! {
43    /// 全局网络接口管理器
44    pub static ref NETWORK_INTERFACE_MANAGER: SpinLock<NetworkInterfaceManager> =
45        SpinLock::new(NetworkInterfaceManager::new());
46}
47
48/// Smoltcp 接口包装器,确保 Device 和 Interface 有相同的生命周期
49pub struct SmoltcpInterface {
50    device_adapter: NetDeviceAdapter,
51    iface: Interface,
52}
53
54impl SmoltcpInterface {
55    /// 创建新的 smoltcp 接口包装器
56    fn new(device: Arc<dyn NetDevice>, mac_address: EthernetAddress) -> Self {
57        let mut device_adapter = NetDeviceAdapter::new(device);
58
59        let config =
60            smoltcp::iface::Config::new(smoltcp::wire::HardwareAddress::Ethernet(mac_address));
61        let iface = Interface::new(
62            config,
63            &mut device_adapter,
64            smoltcp::time::Instant::from_millis(0),
65        );
66
67        Self {
68            device_adapter,
69            iface,
70        }
71    }
72
73    /// 轮询网络接口,处理接收和发送
74    ///
75    /// # 参数
76    /// * `timestamp` - 当前时间戳
77    /// * `sockets` - Socket 集合,用于处理网络协议栈的 socket 操作
78    ///
79    /// # 返回值
80    /// 返回轮询结果,指示是否有事件被处理
81    pub fn poll(
82        &mut self,
83        timestamp: Instant,
84        sockets: &mut smoltcp::iface::SocketSet,
85    ) -> smoltcp::iface::PollResult {
86        self.iface
87            .poll(timestamp, &mut self.device_adapter, sockets)
88    }
89
90    /// 获取可变的 smoltcp Interface 引用
91    pub fn interface_mut(&mut self) -> &mut Interface {
92        &mut self.iface
93    }
94
95    /// 获取不可变的 smoltcp Interface 引用
96    pub fn interface(&self) -> &Interface {
97        &self.iface
98    }
99
100    /// 获取可变的 device adapter 引用
101    pub fn device_adapter_mut(&mut self) -> &mut NetDeviceAdapter {
102        &mut self.device_adapter
103    }
104
105    /// 消费包装器,返回内部的Interface
106    pub fn into_interface(self) -> Interface {
107        self.iface
108    }
109}
110
111/// 网络接口
112pub struct NetworkInterface {
113    name: String,
114    mac_address: EthernetAddress,
115    device: Arc<dyn NetDevice>,
116    ip_addresses: SpinLock<Vec<IpCidr>>,
117    ipv4_gateway: SpinLock<Option<Ipv4Address>>,
118    interrupt_enabled: SpinLock<bool>,
119    last_interrupt_time: SpinLock<Instant>,
120}
121
122impl NetworkInterface {
123    /// 创建新的网络接口
124    pub fn new(name: String, device: Arc<dyn NetDevice>) -> Self {
125        let mac_address = EthernetAddress(device.mac_address());
126        Self {
127            name,
128            mac_address,
129            device,
130            ip_addresses: SpinLock::new(Vec::new()),
131            ipv4_gateway: SpinLock::new(None),
132            interrupt_enabled: SpinLock::new(true),
133            last_interrupt_time: SpinLock::new(Instant::from_millis(0)),
134        }
135    }
136
137    /// 获取接口名称
138    pub fn name(&self) -> &str {
139        &self.name
140    }
141
142    /// 获取MAC地址
143    pub fn mac_address(&self) -> EthernetAddress {
144        self.mac_address
145    }
146
147    /// 获取底层网络设备
148    pub fn device(&self) -> &Arc<dyn NetDevice> {
149        &self.device
150    }
151
152    /// 设置IP地址
153    pub fn add_ip_address(&self, ip_cidr: IpCidr) {
154        let mut ip_addresses = self.ip_addresses.lock();
155        if !ip_addresses.contains(&ip_cidr) {
156            ip_addresses.push(ip_cidr);
157        }
158    }
159
160    /// 获取所有IP地址
161    pub fn ip_addresses(&self) -> Vec<IpCidr> {
162        self.ip_addresses.lock().clone()
163    }
164
165    /// 设置IPv4网关
166    pub fn set_ipv4_gateway(&self, gateway: Option<Ipv4Address>) {
167        *self.ipv4_gateway.lock() = gateway;
168    }
169
170    /// 获取IPv4网关
171    pub fn ipv4_gateway(&self) -> Option<Ipv4Address> {
172        *self.ipv4_gateway.lock()
173    }
174
175    /// 启用中断
176    pub fn enable_interrupt(&self) {
177        *self.interrupt_enabled.lock() = true;
178        println!("Interrupt enabled for interface {}", self.name());
179    }
180
181    /// 禁用中断
182    pub fn disable_interrupt(&self) {
183        *self.interrupt_enabled.lock() = false;
184        println!("Interrupt disabled for interface {}", self.name());
185    }
186
187    /// 检查中断是否启用
188    pub fn is_interrupt_enabled(&self) -> bool {
189        *self.interrupt_enabled.lock()
190    }
191
192    /// 更新最后中断时间
193    pub fn update_interrupt_time(&self) {
194        // 在实际系统中,这里应该使用真实的时间源
195        // 这里使用一个简单的计数器模拟
196        *self.last_interrupt_time.lock() =
197            Instant::from_millis(self.last_interrupt_time.lock().total_millis() + 1);
198    }
199
200    /// 创建smoltcp以太网接口
201    ///
202    /// 返回一个 SmoltcpInterface 包装器,它拥有 NetDeviceAdapter 和 Interface,
203    /// 确保两者有相同的生命周期,避免悬垂指针问题。
204    pub fn create_smoltcp_interface(&self) -> SmoltcpInterface {
205        // 创建包装器(内部会创建 device_adapter 和 interface)
206        let mut smoltcp_iface = SmoltcpInterface::new(self.device.clone(), self.mac_address());
207
208        // 设置IP地址
209        for ip_cidr in self.ip_addresses.lock().iter() {
210            smoltcp_iface.interface_mut().update_ip_addrs(|addrs| {
211                addrs.push(*ip_cidr);
212            });
213        }
214
215        // 设置路由
216        if let Some(gateway) = self.ipv4_gateway() {
217            smoltcp_iface
218                .interface_mut()
219                .routes_mut()
220                .add_default_ipv4_route(gateway)
221                .ok();
222        }
223
224        smoltcp_iface
225    }
226}
227
228/// 网络设备适配器,用于将NetDevice适配到smoltcp需要的Device trait
229pub struct NetDeviceAdapter {
230    device: Arc<dyn NetDevice>,
231    rx_buffer: [u8; 2048],
232}
233
234impl NetDeviceAdapter {
235    /// 创建新的网络设备适配器
236    pub fn new(device: Arc<dyn NetDevice>) -> Self {
237        Self {
238            device,
239            rx_buffer: [0; 2048],
240        }
241    }
242}
243
244// 实现smoltcp 0.12.0的Device trait
245impl smoltcp::phy::Device for NetDeviceAdapter {
246    type RxToken<'a> = NetRxToken<'a>;
247    type TxToken<'a> = NetTxToken<'a>;
248
249    fn receive(
250        &mut self,
251        _timestamp: smoltcp::time::Instant,
252    ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
253        // 尝试接收数据包
254        match self.device.receive(&mut self.rx_buffer) {
255            Ok(size) if size > 0 => Some((
256                NetRxToken {
257                    buffer: &self.rx_buffer[..size],
258                },
259                NetTxToken {
260                    device: &self.device,
261                },
262            )),
263            _ => None,
264        }
265    }
266
267    fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
268        Some(NetTxToken {
269            device: &self.device,
270        })
271    }
272
273    fn capabilities(&self) -> smoltcp::phy::DeviceCapabilities {
274        let mut caps = smoltcp::phy::DeviceCapabilities::default();
275        caps.max_transmission_unit = self.device.mtu() as usize;
276        caps.medium = smoltcp::phy::Medium::Ethernet;
277        caps.max_burst_size = Some(1);
278        caps
279    }
280}
281/// 接收令牌
282pub struct NetRxToken<'a> {
283    buffer: &'a [u8],
284}
285
286impl smoltcp::phy::RxToken for NetRxToken<'_> {
287    fn consume<R, F>(self, f: F) -> R
288    where
289        F: FnOnce(&[u8]) -> R,
290    {
291        f(self.buffer)
292    }
293
294    fn meta(&self) -> smoltcp::phy::PacketMeta {
295        smoltcp::phy::PacketMeta::default()
296    }
297}
298
299/// 发送令牌
300pub struct NetTxToken<'a> {
301    device: &'a Arc<dyn NetDevice>,
302}
303
304impl smoltcp::phy::TxToken for NetTxToken<'_> {
305    fn consume<R, F>(self, len: usize, f: F) -> R
306    where
307        F: FnOnce(&mut [u8]) -> R,
308    {
309        // 创建发送缓冲区
310        let mut buffer = alloc::vec![0; len];
311        let result = f(&mut buffer);
312
313        // 发送数据
314        if let Err(_) = self.device.send(&buffer) {
315            // 在实际实现中,这里应该有错误处理,但根据trait定义,我们不能返回错误
316            // 所以我们只能忽略发送错误
317        }
318
319        result
320    }
321
322    fn set_meta(&mut self, _meta: smoltcp::phy::PacketMeta) {}
323}
324
325/// 实现Driver trait
326impl crate::device::Driver for NetworkInterface {
327    fn try_handle_interrupt(&self, irq: Option<usize>) -> bool {
328        // 检查中断是否启用
329        if !self.is_interrupt_enabled() {
330            return false;
331        }
332
333        // 记录中断信息
334        if let Some(irq_num) = irq {
335            println!(
336                "Network interface {} received interrupt on IRQ {}",
337                self.name(),
338                irq_num
339            );
340        } else {
341            println!(
342                "Network interface {} received interrupt without IRQ number",
343                self.name()
344            );
345        }
346
347        // 更新最后中断时间
348        self.update_interrupt_time();
349
350        // 处理接收中断:尝试接收数据包
351        let mut buffer = [0u8; 2048];
352        match self.device.receive(&mut buffer) {
353            Ok(size) if size > 0 => {
354                println!(
355                    "Received {} bytes of data on interface {}",
356                    size,
357                    self.name()
358                );
359                // Wake up tasks waiting in ppoll
360                crate::kernel::syscall::io::wake_poll_waiters();
361                true
362            }
363            Err(e) => {
364                println!("Error receiving data: {:?}", e);
365                true // 仍然返回true表示我们处理了这个中断
366            }
367            _ => {
368                // 没有接收到数据,但可能是发送完成中断等
369                true
370            }
371        }
372    }
373
374    fn device_type(&self) -> DeviceType {
375        DeviceType::Net
376    }
377
378    fn get_id(&self) -> alloc::string::String {
379        self.name.clone()
380    }
381
382    fn as_net(&self) -> Option<&dyn crate::device::net::net_device::NetDevice> {
383        Some(self.device.as_ref())
384    }
385
386    fn as_net_arc(self: Arc<Self>) -> Option<Arc<dyn crate::device::net::net_device::NetDevice>> {
387        Some(self.device.clone())
388    }
389
390    fn as_block(&self) -> Option<&dyn crate::device::block::BlockDriver> {
391        None
392    }
393
394    fn as_rtc(&self) -> Option<&dyn crate::device::rtc::RtcDriver> {
395        None
396    }
397}