xref: /DragonOS/kernel/src/net/net_core.rs (revision 634349e0ebfca487e6aa2761a796f04895908718)
1 use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
2 use log::{debug, info, warn};
3 use smoltcp::{socket::dhcpv4, wire};
4 use system_error::SystemError;
5 
6 use crate::{
7     driver::net::NetDevice,
8     libs::rwlock::RwLockReadGuard,
9     net::{socket::SocketPollMethod, NET_DEVICES},
10     time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
11 };
12 
13 use super::{
14     event_poll::{EPollEventType, EventPoll},
15     socket::{handle::GlobalSocketHandle, inet::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_DEVICES.write_irqsave();
45 
46     //由于现在os未实现在用户态为网卡动态分配内存,而lo网卡的id最先分配且ip固定不能被分配
47     //所以特判取用id为1的网卡(也就是virto_net)
48     let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone();
49 
50     drop(binding);
51 
52     // Create sockets
53     let mut dhcp_socket = dhcpv4::Socket::new();
54 
55     // Set a ridiculously short max lease time to show DHCP renews work properly.
56     // This will cause the DHCP client to start renewing after 5 seconds, and give up the
57     // lease after 10 seconds if renew hasn't succeeded.
58     // IMPORTANT: This should be removed in production.
59     dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
60 
61     let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
62 
63     const DHCP_TRY_ROUND: u8 = 10;
64     for i in 0..DHCP_TRY_ROUND {
65         debug!("DHCP try round: {}", i);
66         net_face.poll(&mut SOCKET_SET.lock_irqsave()).ok();
67         let mut binding = SOCKET_SET.lock_irqsave();
68         let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
69 
70         match event {
71             None => {}
72 
73             Some(dhcpv4::Event::Configured(config)) => {
74                 // debug!("Find Config!! {config:?}");
75                 // debug!("Find ip address: {}", config.address);
76                 // debug!("iface.ip_addrs={:?}", net_face.inner_iface.ip_addrs());
77 
78                 net_face
79                     .update_ip_addrs(&[wire::IpCidr::Ipv4(config.address)])
80                     .ok();
81 
82                 if let Some(router) = config.router {
83                     net_face
84                         .inner_iface()
85                         .lock()
86                         .routes_mut()
87                         .add_default_ipv4_route(router)
88                         .unwrap();
89                     let cidr = net_face.inner_iface().lock().ip_addrs().first().cloned();
90                     if let Some(cidr) = cidr {
91                         info!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
92                         return Ok(());
93                     }
94                 } else {
95                     net_face
96                         .inner_iface()
97                         .lock()
98                         .routes_mut()
99                         .remove_default_ipv4_route();
100                 }
101             }
102 
103             Some(dhcpv4::Event::Deconfigured) => {
104                 debug!("Dhcp v4 deconfigured");
105                 net_face
106                     .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
107                         wire::Ipv4Address::UNSPECIFIED,
108                         0,
109                     ))])
110                     .ok();
111                 net_face
112                     .inner_iface()
113                     .lock()
114                     .routes_mut()
115                     .remove_default_ipv4_route();
116             }
117         }
118     }
119 
120     return Err(SystemError::ETIMEDOUT);
121 }
122 
123 pub fn poll_ifaces() {
124     let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDevice>>> = NET_DEVICES.read_irqsave();
125     if guard.len() == 0 {
126         warn!("poll_ifaces: No net driver found!");
127         return;
128     }
129     let mut sockets = SOCKET_SET.lock_irqsave();
130     for (_, iface) in guard.iter() {
131         iface.poll(&mut sockets).ok();
132     }
133     let _ = send_event(&sockets);
134 }
135 
136 /// 对ifaces进行轮询,最多对SOCKET_SET尝试times次加锁。
137 ///
138 /// @return 轮询成功,返回Ok(())
139 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
140 /// @return 没有网卡,返回SystemError::ENODEV
141 pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
142     let mut i = 0;
143     while i < times {
144         let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDevice>>> =
145             NET_DEVICES.read_irqsave();
146         if guard.len() == 0 {
147             warn!("poll_ifaces: No net driver found!");
148             // 没有网卡,返回错误
149             return Err(SystemError::ENODEV);
150         }
151         let sockets = SOCKET_SET.try_lock_irqsave();
152         // 加锁失败,继续尝试
153         if sockets.is_err() {
154             i += 1;
155             continue;
156         }
157 
158         let mut sockets = sockets.unwrap();
159         for (_, iface) in guard.iter() {
160             iface.poll(&mut sockets).ok();
161         }
162         send_event(&sockets)?;
163         return Ok(());
164     }
165     // 尝试次数用完,返回错误
166     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
167 }
168 
169 /// 对ifaces进行轮询,最多对SOCKET_SET尝试一次加锁。
170 ///
171 /// @return 轮询成功,返回Ok(())
172 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
173 /// @return 没有网卡,返回SystemError::ENODEV
174 pub fn poll_ifaces_try_lock_onetime() -> Result<(), SystemError> {
175     let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDevice>>> = NET_DEVICES.read_irqsave();
176     if guard.len() == 0 {
177         warn!("poll_ifaces: No net driver found!");
178         // 没有网卡,返回错误
179         return Err(SystemError::ENODEV);
180     }
181     let mut sockets = SOCKET_SET.try_lock_irqsave()?;
182     for (_, iface) in guard.iter() {
183         iface.poll(&mut sockets).ok();
184     }
185     send_event(&sockets)?;
186     return Ok(());
187 }
188 
189 /// ### 处理轮询后的事件
190 fn send_event(sockets: &smoltcp::iface::SocketSet) -> Result<(), SystemError> {
191     for (handle, socket_type) in sockets.iter() {
192         let handle_guard = HANDLE_MAP.read_irqsave();
193         let global_handle = GlobalSocketHandle::new_smoltcp_handle(handle);
194         let item: Option<&super::socket::SocketHandleItem> = handle_guard.get(&global_handle);
195         if item.is_none() {
196             continue;
197         }
198 
199         let handle_item = item.unwrap();
200         let posix_item = handle_item.posix_item();
201         if posix_item.is_none() {
202             continue;
203         }
204         let posix_item = posix_item.unwrap();
205 
206         // 获取socket上的事件
207         let mut events = SocketPollMethod::poll(socket_type, handle_item).bits() as u64;
208 
209         // 分发到相应类型socket处理
210         match socket_type {
211             smoltcp::socket::Socket::Raw(_) | smoltcp::socket::Socket::Udp(_) => {
212                 posix_item.wakeup_any(events);
213             }
214             smoltcp::socket::Socket::Icmp(_) => unimplemented!("Icmp socket hasn't unimplemented"),
215             smoltcp::socket::Socket::Tcp(inner_socket) => {
216                 if inner_socket.is_active() {
217                     events |= TcpSocket::CAN_ACCPET;
218                 }
219                 if inner_socket.state() == smoltcp::socket::tcp::State::Established {
220                     events |= TcpSocket::CAN_CONNECT;
221                 }
222                 if inner_socket.state() == smoltcp::socket::tcp::State::CloseWait {
223                     events |= EPollEventType::EPOLLHUP.bits() as u64;
224                 }
225 
226                 posix_item.wakeup_any(events);
227             }
228             smoltcp::socket::Socket::Dhcpv4(_) => {}
229             smoltcp::socket::Socket::Dns(_) => unimplemented!("Dns socket hasn't unimplemented"),
230         }
231         EventPoll::wakeup_epoll(
232             &posix_item.epitems,
233             EPollEventType::from_bits_truncate(events as u32),
234         )?;
235         drop(handle_guard);
236         // crate::debug!(
237         //     "{} send_event {:?}",
238         //     handle,
239         //     EPollEventType::from_bits_truncate(events as u32)
240         // );
241     }
242     Ok(())
243 }
244