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