xref: /DragonOS/kernel/src/net/net_core.rs (revision ab5c8ca46db8e7d4793a9791292122b0b9684274)
1 use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
2 use smoltcp::{socket::dhcpv4, wire};
3 
4 use crate::{
5     driver::net::NetDriver,
6     kdebug, kinfo, kwarn,
7     libs::rwlock::RwLockReadGuard,
8     net::NET_DRIVERS,
9     syscall::SystemError,
10     time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
11 };
12 
13 use super::socket::{SOCKET_SET, SOCKET_WAITQUEUE};
14 
15 /// The network poll function, which will be called by timer.
16 ///
17 /// The main purpose of this function is to poll all network interfaces.
18 struct NetWorkPollFunc();
19 impl TimerFunction for NetWorkPollFunc {
20     fn run(&mut self) {
21         poll_ifaces_try_lock(10).ok();
22         let next_time = next_n_ms_timer_jiffies(10);
23         let timer = Timer::new(Box::new(NetWorkPollFunc()), next_time);
24         timer.activate();
25     }
26 }
27 
28 pub fn net_init() -> Result<(), SystemError> {
29     dhcp_query()?;
30     // Init poll timer function
31     let next_time = next_n_ms_timer_jiffies(5);
32     let timer = Timer::new(Box::new(NetWorkPollFunc()), next_time);
33     timer.activate();
34     return Ok(());
35 }
36 fn dhcp_query() -> Result<(), SystemError> {
37     let binding = NET_DRIVERS.write();
38 
39     let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
40 
41     drop(binding);
42 
43     // Create sockets
44     let mut dhcp_socket = dhcpv4::Socket::new();
45 
46     // Set a ridiculously short max lease time to show DHCP renews work properly.
47     // This will cause the DHCP client to start renewing after 5 seconds, and give up the
48     // lease after 10 seconds if renew hasn't succeeded.
49     // IMPORTANT: This should be removed in production.
50     dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
51 
52     let mut sockets = smoltcp::iface::SocketSet::new(vec![]);
53     let dhcp_handle = sockets.add(dhcp_socket);
54 
55     const DHCP_TRY_ROUND: u8 = 10;
56     for i in 0..DHCP_TRY_ROUND {
57         kdebug!("DHCP try round: {}", i);
58         let _flag = net_face.poll(&mut sockets);
59         let event = sockets.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
60         // kdebug!("event = {event:?} !!!");
61 
62         match event {
63             None => {}
64 
65             Some(dhcpv4::Event::Configured(config)) => {
66                 // kdebug!("Find Config!! {config:?}");
67                 // kdebug!("Find ip address: {}", config.address);
68                 // kdebug!("iface.ip_addrs={:?}", net_face.inner_iface.ip_addrs());
69 
70                 net_face
71                     .update_ip_addrs(&[wire::IpCidr::Ipv4(config.address)])
72                     .ok();
73 
74                 if let Some(router) = config.router {
75                     net_face
76                         .inner_iface()
77                         .lock()
78                         .routes_mut()
79                         .add_default_ipv4_route(router)
80                         .unwrap();
81                     let cidr = net_face.inner_iface().lock().ip_addrs().first().cloned();
82                     if cidr.is_some() {
83                         let cidr = cidr.unwrap();
84                         kinfo!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
85                         return Ok(());
86                     }
87                 } else {
88                     net_face
89                         .inner_iface()
90                         .lock()
91                         .routes_mut()
92                         .remove_default_ipv4_route();
93                 }
94             }
95 
96             Some(dhcpv4::Event::Deconfigured) => {
97                 kdebug!("Dhcp v4 deconfigured");
98                 net_face
99                     .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
100                         wire::Ipv4Address::UNSPECIFIED,
101                         0,
102                     ))])
103                     .ok();
104                 net_face
105                     .inner_iface()
106                     .lock()
107                     .routes_mut()
108                     .remove_default_ipv4_route();
109             }
110         }
111     }
112 
113     return Err(SystemError::ETIMEDOUT);
114 }
115 
116 pub fn poll_ifaces() {
117     let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
118     if guard.len() == 0 {
119         kwarn!("poll_ifaces: No net driver found!");
120         return;
121     }
122     let mut sockets = SOCKET_SET.lock();
123     for (_, iface) in guard.iter() {
124         iface.poll(&mut sockets).ok();
125     }
126     SOCKET_WAITQUEUE.wakeup_all((-1i64) as u64);
127 }
128 
129 /// 对ifaces进行轮询,最多对SOCKET_SET尝试times次加锁。
130 ///
131 /// @return 轮询成功,返回Ok(())
132 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
133 /// @return 没有网卡,返回SystemError::ENODEV
134 pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
135     let mut i = 0;
136     while i < times {
137         let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
138         if guard.len() == 0 {
139             kwarn!("poll_ifaces: No net driver found!");
140             // 没有网卡,返回错误
141             return Err(SystemError::ENODEV);
142         }
143         let sockets = SOCKET_SET.try_lock();
144         // 加锁失败,继续尝试
145         if sockets.is_err() {
146             i += 1;
147             continue;
148         }
149 
150         let mut sockets = sockets.unwrap();
151         for (_, iface) in guard.iter() {
152             iface.poll(&mut sockets).ok();
153         }
154         SOCKET_WAITQUEUE.wakeup_all((-1i64) as u64);
155         return Ok(());
156     }
157 
158     // 尝试次数用完,返回错误
159     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
160 }
161