xref: /DragonOS/kernel/src/net/net_core.rs (revision 91e9d4ab55ef960f57a1b6287bc523ca4341f67a)
1 use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
2 use smoltcp::{iface::SocketHandle, socket::dhcpv4, wire};
3 use system_error::SystemError;
4 
5 use crate::{
6     driver::net::NetDriver,
7     kdebug, kinfo, kwarn,
8     libs::rwlock::RwLockReadGuard,
9     net::{socket::SocketPollMethod, NET_DRIVERS},
10     time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
11 };
12 
13 use super::{
14     event_poll::EPollEventType,
15     socket::{TcpSocket, HANDLE_MAP, SOCKET_SET},
16 };
17 
18 /// The network poll function, which will be called by timer.
19 ///
20 /// The main purpose of this function is to poll all network interfaces.
21 #[derive(Debug)]
22 struct NetWorkPollFunc;
23 
24 impl TimerFunction for NetWorkPollFunc {
25     fn run(&mut self) -> Result<(), SystemError> {
26         poll_ifaces_try_lock(10).ok();
27         let next_time = next_n_ms_timer_jiffies(10);
28         let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
29         timer.activate();
30         return Ok(());
31     }
32 }
33 
34 pub fn net_init() -> Result<(), SystemError> {
35     dhcp_query()?;
36     // Init poll timer function
37     // let next_time = next_n_ms_timer_jiffies(5);
38     // let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
39     // timer.activate();
40     return Ok(());
41 }
42 
43 fn dhcp_query() -> Result<(), SystemError> {
44     let binding = NET_DRIVERS.write();
45 
46     let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
47 
48     drop(binding);
49 
50     // Create sockets
51     let mut dhcp_socket = dhcpv4::Socket::new();
52 
53     // Set a ridiculously short max lease time to show DHCP renews work properly.
54     // This will cause the DHCP client to start renewing after 5 seconds, and give up the
55     // lease after 10 seconds if renew hasn't succeeded.
56     // IMPORTANT: This should be removed in production.
57     dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
58 
59     let dhcp_handle = SOCKET_SET.lock().add(dhcp_socket);
60 
61     const DHCP_TRY_ROUND: u8 = 10;
62     for i in 0..DHCP_TRY_ROUND {
63         kdebug!("DHCP try round: {}", i);
64         net_face.poll(&mut SOCKET_SET.lock()).ok();
65         let mut binding = SOCKET_SET.lock();
66         let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
67 
68         match event {
69             None => {}
70 
71             Some(dhcpv4::Event::Configured(config)) => {
72                 // kdebug!("Find Config!! {config:?}");
73                 // kdebug!("Find ip address: {}", config.address);
74                 // kdebug!("iface.ip_addrs={:?}", net_face.inner_iface.ip_addrs());
75 
76                 net_face
77                     .update_ip_addrs(&[wire::IpCidr::Ipv4(config.address)])
78                     .ok();
79 
80                 if let Some(router) = config.router {
81                     net_face
82                         .inner_iface()
83                         .lock()
84                         .routes_mut()
85                         .add_default_ipv4_route(router)
86                         .unwrap();
87                     let cidr = net_face.inner_iface().lock().ip_addrs().first().cloned();
88                     if cidr.is_some() {
89                         let cidr = cidr.unwrap();
90                         kinfo!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
91                         return Ok(());
92                     }
93                 } else {
94                     net_face
95                         .inner_iface()
96                         .lock()
97                         .routes_mut()
98                         .remove_default_ipv4_route();
99                 }
100             }
101 
102             Some(dhcpv4::Event::Deconfigured) => {
103                 kdebug!("Dhcp v4 deconfigured");
104                 net_face
105                     .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
106                         wire::Ipv4Address::UNSPECIFIED,
107                         0,
108                     ))])
109                     .ok();
110                 net_face
111                     .inner_iface()
112                     .lock()
113                     .routes_mut()
114                     .remove_default_ipv4_route();
115             }
116         }
117     }
118 
119     return Err(SystemError::ETIMEDOUT);
120 }
121 
122 pub fn poll_ifaces() {
123     let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
124     if guard.len() == 0 {
125         kwarn!("poll_ifaces: No net driver found!");
126         return;
127     }
128     let mut sockets = SOCKET_SET.lock();
129     for (_, iface) in guard.iter() {
130         iface.poll(&mut sockets).ok();
131     }
132     let _ = send_event(&sockets);
133 }
134 
135 /// 对ifaces进行轮询,最多对SOCKET_SET尝试times次加锁。
136 ///
137 /// @return 轮询成功,返回Ok(())
138 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
139 /// @return 没有网卡,返回SystemError::ENODEV
140 pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
141     let mut i = 0;
142     while i < times {
143         let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
144         if guard.len() == 0 {
145             kwarn!("poll_ifaces: No net driver found!");
146             // 没有网卡,返回错误
147             return Err(SystemError::ENODEV);
148         }
149         let sockets = SOCKET_SET.try_lock();
150         // 加锁失败,继续尝试
151         if sockets.is_err() {
152             i += 1;
153             continue;
154         }
155 
156         let mut sockets = sockets.unwrap();
157         for (_, iface) in guard.iter() {
158             iface.poll(&mut sockets).ok();
159         }
160         let _ = send_event(&sockets);
161         return Ok(());
162     }
163 
164     // 尝试次数用完,返回错误
165     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
166 }
167 
168 /// 对ifaces进行轮询,最多对SOCKET_SET尝试一次加锁。
169 ///
170 /// @return 轮询成功,返回Ok(())
171 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
172 /// @return 没有网卡,返回SystemError::ENODEV
173 pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
174     let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
175     if guard.len() == 0 {
176         kwarn!("poll_ifaces: No net driver found!");
177         // 没有网卡,返回错误
178         return Err(SystemError::ENODEV);
179     }
180     let mut sockets = SOCKET_SET.try_lock()?;
181     for (_, iface) in guard.iter() {
182         iface.poll(&mut sockets).ok();
183     }
184     send_event(&sockets)?;
185     return Ok(());
186 }
187 
188 /// ### 处理轮询后的事件
189 fn send_event(sockets: &smoltcp::iface::SocketSet) -> Result<(), SystemError> {
190     for (handle, socket_type) in sockets.iter() {
191         let handle_guard = HANDLE_MAP.read_irqsave();
192         let item = handle_guard.get(&handle);
193         if item.is_none() {
194             continue;
195         }
196 
197         let handle_item = item.unwrap();
198 
199         // 获取socket上的事件
200         let mut events =
201             SocketPollMethod::poll(socket_type, handle_item.shutdown_type()).bits() as u64;
202 
203         // 分发到相应类型socket处理
204         match socket_type {
205             smoltcp::socket::Socket::Raw(_) | smoltcp::socket::Socket::Udp(_) => {
206                 handle_guard
207                     .get(&handle)
208                     .unwrap()
209                     .wait_queue
210                     .wakeup_any(events);
211             }
212             smoltcp::socket::Socket::Icmp(_) => unimplemented!("Icmp socket hasn't unimplemented"),
213             smoltcp::socket::Socket::Tcp(inner_socket) => {
214                 if inner_socket.is_active() {
215                     events |= TcpSocket::CAN_ACCPET;
216                 }
217                 if inner_socket.state() == smoltcp::socket::tcp::State::Established {
218                     events |= TcpSocket::CAN_CONNECT;
219                 }
220                 handle_guard
221                     .get(&handle)
222                     .unwrap()
223                     .wait_queue
224                     .wakeup_any(events);
225             }
226             smoltcp::socket::Socket::Dhcpv4(_) => {}
227             smoltcp::socket::Socket::Dns(_) => unimplemented!("Dns socket hasn't unimplemented"),
228         }
229         drop(handle_guard);
230         wakeup_epoll(handle, events as u32)?;
231         // crate::kdebug!(
232         //     "{} send_event {:?}",
233         //     handle,
234         //     EPollEventType::from_bits_truncate(events as u32)
235         // );
236     }
237     Ok(())
238 }
239 
240 /// ### 处理epoll
241 fn wakeup_epoll(handle: SocketHandle, events: u32) -> Result<(), SystemError> {
242     let mut handle_guard = HANDLE_MAP.write_irqsave();
243     let handle_item = handle_guard.get_mut(&handle).unwrap();
244     let mut epitems_guard = handle_item.epitems.try_lock()?;
245 
246     // 从events拿到epoll相关事件
247     let pollflags = EPollEventType::from_bits_truncate(events);
248 
249     // 一次只取一个,因为一次也只有一个进程能拿到对应文件的��
250     if let Some(epitem) = epitems_guard.pop_front() {
251         let epoll = epitem.epoll().upgrade().unwrap();
252         let mut epoll_guard = epoll.try_lock()?;
253         let binding = epitem.clone();
254         let event_guard = binding.event().read();
255         let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
256 
257         // 检查事件合理性以及是否有感兴趣的事件
258         if !(ep_events
259             .difference(EPollEventType::EP_PRIVATE_BITS)
260             .is_empty()
261             || pollflags.difference(ep_events).is_empty())
262         {
263             // TODO: 未处理pm相关
264 
265             // 首先将就绪的epitem加入等待队列
266             epoll_guard.ep_add_ready(epitem.clone());
267 
268             if epoll_guard.ep_has_waiter() {
269                 if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE)
270                     && !pollflags.contains(EPollEventType::POLLFREE)
271                 {
272                     // 避免惊群
273                     epoll_guard.ep_wake_one();
274                 } else {
275                     epoll_guard.ep_wake_all();
276                 }
277             }
278         }
279 
280         epitems_guard.push_back(epitem);
281     }
282     Ok(())
283 }
284