xref: /DragonOS/kernel/src/net/net_core.rs (revision cde5492f725681ed89abe1e6eb088e05d943d793)
1*cde5492fSlogin use alloc::{boxed::Box, collections::BTreeMap, sync::Arc};
213776c11Slogin use smoltcp::{socket::dhcpv4, wire};
313776c11Slogin 
4*cde5492fSlogin use crate::{
5*cde5492fSlogin     driver::net::NetDriver,
6*cde5492fSlogin     kdebug, kinfo, kwarn,
7*cde5492fSlogin     libs::rwlock::RwLockReadGuard,
8*cde5492fSlogin     net::NET_DRIVERS,
9*cde5492fSlogin     syscall::SystemError,
10*cde5492fSlogin     time::timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
11*cde5492fSlogin };
12*cde5492fSlogin 
13*cde5492fSlogin use super::socket::{SOCKET_SET, SOCKET_WAITQUEUE};
14*cde5492fSlogin 
15*cde5492fSlogin /// The network poll function, which will be called by timer.
16*cde5492fSlogin ///
17*cde5492fSlogin /// The main purpose of this function is to poll all network interfaces.
18*cde5492fSlogin struct NetWorkPollFunc();
19*cde5492fSlogin impl TimerFunction for NetWorkPollFunc {
20*cde5492fSlogin     fn run(&mut self) {
21*cde5492fSlogin         poll_ifaces_try_lock(10).ok();
22*cde5492fSlogin         let next_time = next_n_ms_timer_jiffies(10);
23*cde5492fSlogin         let timer = Timer::new(Box::new(NetWorkPollFunc()), next_time);
24*cde5492fSlogin         timer.activate();
25*cde5492fSlogin     }
26*cde5492fSlogin }
2713776c11Slogin 
2813776c11Slogin pub fn net_init() -> Result<(), SystemError> {
2913776c11Slogin     dhcp_query()?;
30*cde5492fSlogin     // Init poll timer function
31*cde5492fSlogin     let next_time = next_n_ms_timer_jiffies(5);
32*cde5492fSlogin     let timer = Timer::new(Box::new(NetWorkPollFunc()), next_time);
33*cde5492fSlogin     timer.activate();
3413776c11Slogin     return Ok(());
3513776c11Slogin }
3613776c11Slogin fn dhcp_query() -> Result<(), SystemError> {
3713776c11Slogin     let binding = NET_DRIVERS.write();
3813776c11Slogin 
39*cde5492fSlogin     let net_face = binding.get(&0).ok_or(SystemError::ENODEV)?.clone();
4013776c11Slogin 
4113776c11Slogin     drop(binding);
4213776c11Slogin 
4313776c11Slogin     // Create sockets
4413776c11Slogin     let mut dhcp_socket = dhcpv4::Socket::new();
4513776c11Slogin 
4613776c11Slogin     // Set a ridiculously short max lease time to show DHCP renews work properly.
4713776c11Slogin     // This will cause the DHCP client to start renewing after 5 seconds, and give up the
4813776c11Slogin     // lease after 10 seconds if renew hasn't succeeded.
4913776c11Slogin     // IMPORTANT: This should be removed in production.
5013776c11Slogin     dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
5113776c11Slogin 
5213776c11Slogin     let mut sockets = smoltcp::iface::SocketSet::new(vec![]);
5313776c11Slogin     let dhcp_handle = sockets.add(dhcp_socket);
5413776c11Slogin 
5513776c11Slogin     const DHCP_TRY_ROUND: u8 = 10;
5613776c11Slogin     for i in 0..DHCP_TRY_ROUND {
5713776c11Slogin         kdebug!("DHCP try round: {}", i);
5813776c11Slogin         let _flag = net_face.poll(&mut sockets);
5913776c11Slogin         let event = sockets.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
6013776c11Slogin         // kdebug!("event = {event:?} !!!");
6113776c11Slogin 
6213776c11Slogin         match event {
6313776c11Slogin             None => {}
6413776c11Slogin 
6513776c11Slogin             Some(dhcpv4::Event::Configured(config)) => {
6613776c11Slogin                 // kdebug!("Find Config!! {config:?}");
6713776c11Slogin                 // kdebug!("Find ip address: {}", config.address);
6813776c11Slogin                 // kdebug!("iface.ip_addrs={:?}", net_face.inner_iface.ip_addrs());
6913776c11Slogin 
7013776c11Slogin                 net_face
7113776c11Slogin                     .update_ip_addrs(&[wire::IpCidr::Ipv4(config.address)])
7213776c11Slogin                     .ok();
7313776c11Slogin 
7413776c11Slogin                 if let Some(router) = config.router {
7513776c11Slogin                     net_face
7613776c11Slogin                         .inner_iface()
7713776c11Slogin                         .lock()
7813776c11Slogin                         .routes_mut()
7913776c11Slogin                         .add_default_ipv4_route(router)
8013776c11Slogin                         .unwrap();
8113776c11Slogin                     let cidr = net_face.inner_iface().lock().ip_addrs().first().cloned();
8213776c11Slogin                     if cidr.is_some() {
8313776c11Slogin                         let cidr = cidr.unwrap();
8413776c11Slogin                         kinfo!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
8513776c11Slogin                         return Ok(());
8613776c11Slogin                     }
8713776c11Slogin                 } else {
8813776c11Slogin                     net_face
8913776c11Slogin                         .inner_iface()
9013776c11Slogin                         .lock()
9113776c11Slogin                         .routes_mut()
9213776c11Slogin                         .remove_default_ipv4_route();
9313776c11Slogin                 }
9413776c11Slogin             }
9513776c11Slogin 
9613776c11Slogin             Some(dhcpv4::Event::Deconfigured) => {
9713776c11Slogin                 kdebug!("Dhcp v4 deconfigured");
9813776c11Slogin                 net_face
9913776c11Slogin                     .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
10013776c11Slogin                         wire::Ipv4Address::UNSPECIFIED,
10113776c11Slogin                         0,
10213776c11Slogin                     ))])
10313776c11Slogin                     .ok();
10413776c11Slogin                 net_face
10513776c11Slogin                     .inner_iface()
10613776c11Slogin                     .lock()
10713776c11Slogin                     .routes_mut()
10813776c11Slogin                     .remove_default_ipv4_route();
10913776c11Slogin             }
11013776c11Slogin         }
11113776c11Slogin     }
11213776c11Slogin 
11313776c11Slogin     return Err(SystemError::ETIMEDOUT);
11413776c11Slogin }
115*cde5492fSlogin 
116*cde5492fSlogin pub fn poll_ifaces() {
117*cde5492fSlogin     let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
118*cde5492fSlogin     if guard.len() == 0 {
119*cde5492fSlogin         kwarn!("poll_ifaces: No net driver found!");
120*cde5492fSlogin         return;
121*cde5492fSlogin     }
122*cde5492fSlogin     let mut sockets = SOCKET_SET.lock();
123*cde5492fSlogin     for (_, iface) in guard.iter() {
124*cde5492fSlogin         iface.poll(&mut sockets).ok();
125*cde5492fSlogin     }
126*cde5492fSlogin     SOCKET_WAITQUEUE.wakeup_all((-1i64) as u64);
127*cde5492fSlogin }
128*cde5492fSlogin 
129*cde5492fSlogin /// 对ifaces进行轮询,最多对SOCKET_SET尝试times次加锁。
130*cde5492fSlogin ///
131*cde5492fSlogin /// @return 轮询成功,返回Ok(())
132*cde5492fSlogin /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK
133*cde5492fSlogin /// @return 没有网卡,返回SystemError::ENODEV
134*cde5492fSlogin pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
135*cde5492fSlogin     let mut i = 0;
136*cde5492fSlogin     while i < times {
137*cde5492fSlogin         let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn NetDriver>>> = NET_DRIVERS.read();
138*cde5492fSlogin         if guard.len() == 0 {
139*cde5492fSlogin             kwarn!("poll_ifaces: No net driver found!");
140*cde5492fSlogin             // 没有网卡,返回错误
141*cde5492fSlogin             return Err(SystemError::ENODEV);
142*cde5492fSlogin         }
143*cde5492fSlogin         let sockets = SOCKET_SET.try_lock();
144*cde5492fSlogin         // 加锁失败,继续尝试
145*cde5492fSlogin         if sockets.is_err() {
146*cde5492fSlogin             i += 1;
147*cde5492fSlogin             continue;
148*cde5492fSlogin         }
149*cde5492fSlogin 
150*cde5492fSlogin         let mut sockets = sockets.unwrap();
151*cde5492fSlogin         for (_, iface) in guard.iter() {
152*cde5492fSlogin             iface.poll(&mut sockets).ok();
153*cde5492fSlogin         }
154*cde5492fSlogin         SOCKET_WAITQUEUE.wakeup_all((-1i64) as u64);
155*cde5492fSlogin         return Ok(());
156*cde5492fSlogin     }
157*cde5492fSlogin 
158*cde5492fSlogin     // 尝试次数用完,返回错误
159*cde5492fSlogin     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
160*cde5492fSlogin }
161