xref: /DragonOS/kernel/src/driver/net/loopback.rs (revision 79ad6e5ba4cf7fd624dfa91a1de35d7e60bdda43)
1 use crate::arch::rand::rand;
2 use crate::driver::base::class::Class;
3 use crate::driver::base::device::bus::Bus;
4 use crate::driver::base::device::driver::Driver;
5 use crate::driver::base::device::{Device, DeviceType, IdTable};
6 use crate::driver::base::kobject::{KObjType, KObject, KObjectState};
7 use crate::init::initcall::INITCALL_DEVICE;
8 use crate::libs::spinlock::SpinLock;
9 use crate::net::{generate_iface_id, NET_DEVICES};
10 use crate::time::Instant;
11 use alloc::collections::VecDeque;
12 use alloc::fmt::Debug;
13 use alloc::string::{String, ToString};
14 use alloc::sync::{Arc, Weak};
15 use alloc::vec::Vec;
16 use core::cell::UnsafeCell;
17 use core::ops::{Deref, DerefMut};
18 use log::debug;
19 use smoltcp::wire::HardwareAddress;
20 use smoltcp::{
21     phy::{self},
22     wire::{IpAddress, IpCidr},
23 };
24 use system_error::SystemError;
25 use unified_init::macros::unified_init;
26 
27 use super::NetDevice;
28 
29 const DEVICE_NAME: &str = "loopback";
30 
31 /// ## 环回接收令牌
32 /// 用于储存lo网卡接收到的数据
33 pub struct LoopbackRxToken {
34     buffer: Vec<u8>,
35 }
36 
37 impl phy::RxToken for LoopbackRxToken {
38     /// ## 实现Rxtoken的consume函数
39     /// 接受一个函数 `f`,并在 `self.buffer` 上调用它。
40     ///
41     /// ## 参数
42     /// - mut self :一个可变的 `LoopbackRxToken` 实例。
43     /// - f :接受一个可变的 u8 切片,并返回类型 `R` 的结果。
44     ///
45     /// ## 返回值
46     /// 返回函数 `f` 在 `self.buffer` 上的调用结果。
47     fn consume<R, F>(mut self, f: F) -> R
48     where
49         F: FnOnce(&mut [u8]) -> R,
50     {
51         f(self.buffer.as_mut_slice())
52     }
53 }
54 
55 /// ## 环回发送令牌
56 /// 返回驱动用于操作lo设备
57 pub struct LoopbackTxToken {
58     driver: LoopbackDriver,
59 }
60 
61 impl phy::TxToken for LoopbackTxToken {
62     /// ## 实现TxToken的consume函数
63     /// 向lo的队列推入待发送的数据报,实现环回
64     ///
65     /// ## 参数
66     /// - self
67     /// - len:数据包的长度
68     /// - f:接受一个可变的 u8 切片,并返回类型 `R` 的结果。
69     ///
70     /// ## 返回值
71     /// 返回f对数据包操纵的结果
72     fn consume<R, F>(self, len: usize, f: F) -> R
73     where
74         F: FnOnce(&mut [u8]) -> R,
75     {
76         let mut buffer = vec![0; len];
77         let result = f(buffer.as_mut_slice());
78         let mut device = self.driver.inner.lock();
79         device.loopback_transmit(buffer);
80         result
81     }
82 }
83 
84 /// ## Loopback设备
85 /// 成员是一个队列,用来存放接受到的数据包。
86 /// 当使用lo发送数据包时,不会把数据包传到link层,而是直接发送到该队列,实现环回。
87 pub struct Loopback {
88     //回环设备的缓冲区,接受的数据包会存放在这里,发送的数据包也会发送到这里,实现环回
89     queue: VecDeque<Vec<u8>>,
90 }
91 
92 impl Loopback {
93     /// ## Loopback创建函数
94     /// 创建lo设备
95     pub fn new() -> Self {
96         let queue = VecDeque::new();
97         Loopback { queue }
98     }
99     /// ## Loopback处理接受到的数据包函数
100     /// Loopback接受到数据后会调用这个函数来弹出接收的数据,返回给协议栈
101     ///
102     /// ## 参数
103     /// - &mut self :自身可变引用
104     ///
105     /// ## 返回值
106     /// - queue的头部数据包
107     pub fn loopback_receive(&mut self) -> Vec<u8> {
108         let buffer = self.queue.pop_front();
109         match buffer {
110             Some(buffer) => {
111                 //debug!("lo receive:{:?}", buffer);
112                 return buffer;
113             }
114             None => {
115                 return Vec::new();
116             }
117         }
118     }
119     /// ## Loopback发送数据包的函数
120     /// Loopback发送数据包给自己的接收队列,实现环回
121     ///
122     /// ## 参数
123     /// - &mut self:自身可变引用
124     /// - buffer:需要发送的数据包
125     pub fn loopback_transmit(&mut self, buffer: Vec<u8>) {
126         //debug!("lo transmit!");
127         self.queue.push_back(buffer)
128     }
129 }
130 
131 /// ## driver的包裹器
132 /// 为实现获得不可变引用的Interface的内部可变性,故为Driver提供UnsafeCell包裹器
133 ///
134 /// 参考virtio_net.rs
135 struct LoopbackDriverWapper(UnsafeCell<LoopbackDriver>);
136 unsafe impl Send for LoopbackDriverWapper {}
137 unsafe impl Sync for LoopbackDriverWapper {}
138 
139 /// ## deref 方法返回一个指向 `LoopbackDriver` 的引用。
140 impl Deref for LoopbackDriverWapper {
141     type Target = LoopbackDriver;
142     fn deref(&self) -> &Self::Target {
143         unsafe { &*self.0.get() }
144     }
145 }
146 /// ## `deref_mut` 方法返回一个指向可变 `LoopbackDriver` 的引用。
147 impl DerefMut for LoopbackDriverWapper {
148     fn deref_mut(&mut self) -> &mut Self::Target {
149         unsafe { &mut *self.0.get() }
150     }
151 }
152 
153 impl LoopbackDriverWapper {
154     /// ## force_get_mut返回一个指向可变 `LoopbackDriver` 的引用。
155     #[allow(clippy::mut_from_ref)]
156     #[allow(clippy::mut_from_ref)]
157     fn force_get_mut(&self) -> &mut LoopbackDriver {
158         unsafe { &mut *self.0.get() }
159     }
160 }
161 
162 /// ## Loopback驱动
163 /// 负责操作Loopback设备实现基本的网卡功能
164 pub struct LoopbackDriver {
165     pub inner: Arc<SpinLock<Loopback>>,
166 }
167 
168 impl LoopbackDriver {
169     /// ## LoopbackDriver创建函数
170     pub fn new() -> Self {
171         let inner = Arc::new(SpinLock::new(Loopback::new()));
172         LoopbackDriver { inner }
173     }
174 }
175 
176 impl Clone for LoopbackDriver {
177     fn clone(&self) -> Self {
178         LoopbackDriver {
179             inner: self.inner.clone(),
180         }
181     }
182 }
183 
184 impl phy::Device for LoopbackDriver {
185     type RxToken<'a> = LoopbackRxToken where Self: 'a;
186     type TxToken<'a> = LoopbackTxToken where Self: 'a;
187     /// ## 返回设备的物理层特性。
188     /// lo设备的最大传输单元为65535,最大突发大小为1,传输介质默认为Ethernet
189     fn capabilities(&self) -> phy::DeviceCapabilities {
190         let mut result = phy::DeviceCapabilities::default();
191         result.max_transmission_unit = 65535;
192         result.max_burst_size = Some(1);
193         result.medium = smoltcp::phy::Medium::Ethernet;
194         return result;
195     }
196     /// ## Loopback驱动处理接受数据事件
197     /// 驱动调用Loopback的receive函数,处理buffer封装成(rx,tx)返回给上层
198     ///
199     /// ## 参数
200     /// - `&mut self` :自身可变引用
201     /// - `_timestamp`
202     ///
203     /// ## 返回值
204     /// - None: 如果接收队列为空,返回 `None`,以通知上层没有可以接收的包
205     /// - Option::Some((rx, tx)):如果接收队列不为空,返回 `Some`,其中包含一个接收令牌 `rx` 和一个发送令牌 `tx`
206     fn receive(
207         &mut self,
208         _timestamp: smoltcp::time::Instant,
209     ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
210         let buffer = self.inner.lock().loopback_receive();
211         //receive队列为为空,返回NONE值以通知上层没有可以receive的包
212         if buffer.is_empty() {
213             return Option::None;
214         }
215         let rx = LoopbackRxToken { buffer };
216         let tx = LoopbackTxToken {
217             driver: self.clone(),
218         };
219         return Option::Some((rx, tx));
220     }
221     /// ## Loopback驱动处理发送数据包事件
222     /// Loopback驱动在需要发送数据时会调用这个函数来获取一个发送令牌。
223     ///
224     /// ## 参数
225     /// - `&mut self` :自身可变引用
226     /// - `_timestamp`
227     ///
228     /// ## 返回值
229     /// - 返回一个 `Some`,其中包含一个发送令牌,该令牌包含一个对自身的克隆引用
230     fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
231         Some(LoopbackTxToken {
232             driver: self.clone(),
233         })
234     }
235 }
236 
237 /// ## LoopbackInterface结构
238 /// 封装驱动包裹器和iface,设置接口名称
239 pub struct LoopbackInterface {
240     driver: LoopbackDriverWapper,
241     iface_id: usize,
242     iface: SpinLock<smoltcp::iface::Interface>,
243     name: String,
244 }
245 
246 impl LoopbackInterface {
247     /// ## `new` 是一个公共函数,用于创建一个新的 `LoopbackInterface` 实例。
248     /// 生成一个新的接口 ID。创建一个新的接口配置,设置其硬件地址和随机种子,使用接口配置和驱动器创建一个新的 `smoltcp::iface::Interface` 实例。
249     /// 设置接口的 IP 地址为 127.0.0.1。
250     /// 创建一个新的 `LoopbackDriverWapper` 实例,包装驱动器。
251     /// 创建一个新的 `LoopbackInterface` 实例,包含驱动器、接口 ID、接口和名称,并将其封装在一个 `Arc` 中。
252     /// ## 参数
253     /// - `driver`:一个 `LoopbackDriver` 实例,用于驱动网络环回操作。
254     ///
255     /// ## 返回值
256     /// 返回一个 `Arc<Self>`,即一个指向新创建的 `LoopbackInterface` 实例的智能指针。
257     pub fn new(mut driver: LoopbackDriver) -> Arc<Self> {
258         let iface_id = generate_iface_id();
259         let mut iface_config = smoltcp::iface::Config::new(HardwareAddress::Ethernet(
260             smoltcp::wire::EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]),
261         ));
262         iface_config.random_seed = rand() as u64;
263 
264         let mut iface =
265             smoltcp::iface::Interface::new(iface_config, &mut driver, Instant::now().into());
266         //设置网卡地址为127.0.0.1
267         iface.update_ip_addrs(|ip_addrs| {
268             ip_addrs
269                 .push(IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8))
270                 .unwrap();
271         });
272         let driver = LoopbackDriverWapper(UnsafeCell::new(driver));
273         Arc::new(LoopbackInterface {
274             driver,
275             iface_id,
276             iface: SpinLock::new(iface),
277             name: "lo".to_string(),
278         })
279     }
280 }
281 
282 impl Debug for LoopbackInterface {
283     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
284         f.debug_struct("LoopbackInterface")
285             .field("iface_id", &self.iface_id)
286             .field("iface", &"smtoltcp::iface::Interface")
287             .field("name", &self.name)
288             .finish()
289     }
290 }
291 //TODO: 向sysfs注册lo设备
292 impl KObject for LoopbackInterface {
293     fn as_any_ref(&self) -> &dyn core::any::Any {
294         self
295     }
296 
297     fn set_inode(&self, _inode: Option<Arc<crate::filesystem::kernfs::KernFSInode>>) {
298         todo!()
299     }
300 
301     fn inode(&self) -> Option<Arc<crate::filesystem::kernfs::KernFSInode>> {
302         todo!()
303     }
304 
305     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
306         todo!()
307     }
308 
309     fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
310         todo!()
311     }
312 
313     fn kset(&self) -> Option<Arc<crate::driver::base::kset::KSet>> {
314         todo!()
315     }
316 
317     fn set_kset(&self, _kset: Option<Arc<crate::driver::base::kset::KSet>>) {
318         todo!()
319     }
320 
321     fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
322         todo!()
323     }
324 
325     fn name(&self) -> String {
326         self.name.clone()
327     }
328 
329     fn set_name(&self, _name: String) {
330         todo!()
331     }
332 
333     fn kobj_state(
334         &self,
335     ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
336         todo!()
337     }
338 
339     fn kobj_state_mut(
340         &self,
341     ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
342         todo!()
343     }
344 
345     fn set_kobj_state(&self, _state: KObjectState) {
346         todo!()
347     }
348 
349     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
350         todo!()
351     }
352 }
353 
354 impl Device for LoopbackInterface {
355     fn dev_type(&self) -> DeviceType {
356         DeviceType::Net
357     }
358 
359     fn id_table(&self) -> IdTable {
360         IdTable::new(DEVICE_NAME.to_string(), None)
361     }
362 
363     fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
364         todo!()
365     }
366 
367     fn set_class(&self, _class: Option<Weak<dyn Class>>) {
368         todo!()
369     }
370 
371     fn driver(&self) -> Option<Arc<dyn Driver>> {
372         todo!()
373     }
374 
375     fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
376         todo!()
377     }
378 
379     fn is_dead(&self) -> bool {
380         todo!()
381     }
382 
383     fn can_match(&self) -> bool {
384         todo!()
385     }
386 
387     fn set_can_match(&self, _can_match: bool) {
388         todo!()
389     }
390 
391     fn state_synced(&self) -> bool {
392         true
393     }
394 }
395 
396 impl NetDevice for LoopbackInterface {
397     /// 由于lo网卡设备不是实际的物理设备,其mac地址需要手动设置为一个默认值,这里默认为0200000001
398     fn mac(&self) -> smoltcp::wire::EthernetAddress {
399         let mac = [0x02, 0x00, 0x00, 0x00, 0x00, 0x01];
400         smoltcp::wire::EthernetAddress(mac)
401     }
402 
403     #[inline]
404     fn nic_id(&self) -> usize {
405         self.iface_id
406     }
407 
408     #[inline]
409     fn name(&self) -> String {
410         self.name.clone()
411     }
412     /// ## `update_ip_addrs` 用于更新接口的 IP 地址。
413     ///
414     /// ## 参数
415     /// - `&self` :自身引用
416     /// - `ip_addrs` :一个包含 `smoltcp::wire::IpCidr` 的切片,表示要设置的 IP 地址和子网掩码
417     ///
418     /// ## 返回值
419     /// - 如果 `ip_addrs` 的长度不为 1,返回 `Err(SystemError::EINVAL)`,表示输入参数无效
420     /// - 如果更新成功,返回 `Ok(())`
421     fn update_ip_addrs(
422         &self,
423         ip_addrs: &[smoltcp::wire::IpCidr],
424     ) -> Result<(), system_error::SystemError> {
425         if ip_addrs.len() != 1 {
426             return Err(SystemError::EINVAL);
427         }
428 
429         self.iface.lock().update_ip_addrs(|addrs| {
430             let dest = addrs.iter_mut().next();
431 
432             if let Some(dest) = dest {
433                 *dest = ip_addrs[0];
434             } else {
435                 addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
436             }
437         });
438         return Ok(());
439     }
440     /// ## `poll` 用于轮询接口的状态。
441     ///
442     /// ## 参数
443     /// - `&self` :自身引用
444     /// - `sockets` :一个可变引用到 `smoltcp::iface::SocketSet`,表示要轮询的套接字集
445     ///
446     /// ## 返回值
447     /// - 如果轮询成功,返回 `Ok(())`
448     /// - 如果轮询失败,返回 `Err(SystemError::EAGAIN_OR_EWOULDBLOCK)`,表示需要再次尝试或者操作会阻塞
449     fn poll(&self, sockets: &mut smoltcp::iface::SocketSet) -> Result<(), SystemError> {
450         let timestamp: smoltcp::time::Instant = Instant::now().into();
451         let mut guard = self.iface.lock();
452         let poll_res = guard.poll(timestamp, self.driver.force_get_mut(), sockets);
453         if poll_res {
454             return Ok(());
455         }
456         return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
457     }
458 
459     #[inline(always)]
460     fn inner_iface(&self) -> &SpinLock<smoltcp::iface::Interface> {
461         return &self.iface;
462     }
463 }
464 
465 pub fn loopback_probe() {
466     loopback_driver_init();
467 }
468 /// ## lo网卡设备初始化函数
469 /// 创建驱动和iface,初始化一个lo网卡,添加到全局NET_DEVICES中
470 pub fn loopback_driver_init() {
471     let driver = LoopbackDriver::new();
472     let iface = LoopbackInterface::new(driver);
473 
474     NET_DEVICES
475         .write_irqsave()
476         .insert(iface.iface_id, iface.clone());
477 }
478 
479 /// ## lo网卡设备的注册函数
480 #[unified_init(INITCALL_DEVICE)]
481 pub fn loopback_init() -> Result<(), SystemError> {
482     loopback_probe();
483     return Ok(());
484 }
485