net_core.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  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. use crate::{
  6. driver::net::{Iface, Operstate},
  7. libs::rwlock::RwLockReadGuard,
  8. net::NET_DEVICES,
  9. time::{
  10. sleep::nanosleep,
  11. timer::{next_n_ms_timer_jiffies, Timer, TimerFunction},
  12. PosixTimeSpec,
  13. },
  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. #[derive(Debug)]
  19. #[allow(dead_code)]
  20. struct NetWorkPollFunc;
  21. impl TimerFunction for NetWorkPollFunc {
  22. fn run(&mut self) -> Result<(), SystemError> {
  23. poll_ifaces();
  24. let next_time = next_n_ms_timer_jiffies(10);
  25. let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
  26. timer.activate();
  27. return Ok(());
  28. }
  29. }
  30. pub fn net_init() -> Result<(), SystemError> {
  31. dhcp_query()?;
  32. // Init poll timer function
  33. // let next_time = next_n_ms_timer_jiffies(5);
  34. // let timer = Timer::new(Box::new(NetWorkPollFunc), next_time);
  35. // timer.activate();
  36. return Ok(());
  37. }
  38. fn dhcp_query() -> Result<(), SystemError> {
  39. let binding = NET_DEVICES.write_irqsave();
  40. // log::debug!("binding: {:?}", *binding);
  41. //由于现在os未实现在用户态为网卡动态分配内存,而lo网卡的id最先分配且ip固定不能被分配
  42. //所以特判取用id为1的网卡(也就是virtio_net)
  43. let net_face = binding.get(&1).ok_or(SystemError::ENODEV)?.clone();
  44. drop(binding);
  45. // Create sockets
  46. let mut dhcp_socket = dhcpv4::Socket::new();
  47. // Set a ridiculously short max lease time to show DHCP renews work properly.
  48. // This will cause the DHCP client to start renewing after 5 seconds, and give up the
  49. // lease after 10 seconds if renew hasn't succeeded.
  50. // IMPORTANT: This should be removed in production.
  51. dhcp_socket.set_max_lease_duration(Some(smoltcp::time::Duration::from_secs(10)));
  52. let sockets = || net_face.sockets().lock_irqsave();
  53. // let dhcp_handle = SOCKET_SET.lock_irqsave().add(dhcp_socket);
  54. let dhcp_handle = sockets().add(dhcp_socket);
  55. const DHCP_TRY_ROUND: u8 = 100;
  56. for i in 0..DHCP_TRY_ROUND {
  57. log::debug!("DHCP try round: {}", i);
  58. net_face.poll();
  59. let mut binding = sockets();
  60. let event = binding.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
  61. match event {
  62. None => {}
  63. Some(dhcpv4::Event::Configured(config)) => {
  64. // debug!("Find Config!! {config:?}");
  65. // debug!("Find ip address: {}", config.address);
  66. // debug!("iface.ip_addrs={:?}", net_face.inner_iface.ip_addrs());
  67. net_face
  68. .update_ip_addrs(&[wire::IpCidr::Ipv4(config.address)])
  69. .ok();
  70. if let Some(router) = config.router {
  71. let mut smol_iface = net_face.smol_iface().lock();
  72. smol_iface.routes_mut().update(|table| {
  73. let _ = table.push(smoltcp::iface::Route {
  74. cidr: smoltcp::wire::IpCidr::Ipv4(smoltcp::wire::Ipv4Cidr::new(
  75. smoltcp::wire::Ipv4Address::new(127, 0, 0, 0),
  76. 8,
  77. )),
  78. via_router: smoltcp::wire::IpAddress::v4(127, 0, 0, 1),
  79. preferred_until: None,
  80. expires_at: None,
  81. });
  82. });
  83. if smol_iface
  84. .routes_mut()
  85. .add_default_ipv4_route(router)
  86. .is_err()
  87. {
  88. log::warn!("Route table full");
  89. }
  90. let cidr = smol_iface.ip_addrs().first().cloned();
  91. if let Some(cidr) = cidr {
  92. // 这里先在这里将网卡设置为up,后面等netlink实现了再修改
  93. net_face.set_operstate(Operstate::IF_OPER_UP);
  94. info!("Successfully allocated ip by Dhcpv4! Ip:{}", cidr);
  95. return Ok(());
  96. }
  97. } else {
  98. net_face
  99. .smol_iface()
  100. .lock()
  101. .routes_mut()
  102. .remove_default_ipv4_route();
  103. }
  104. }
  105. Some(dhcpv4::Event::Deconfigured) => {
  106. debug!("Dhcp v4 deconfigured");
  107. net_face
  108. .update_ip_addrs(&[smoltcp::wire::IpCidr::Ipv4(wire::Ipv4Cidr::new(
  109. wire::Ipv4Address::UNSPECIFIED,
  110. 0,
  111. ))])
  112. .ok();
  113. net_face
  114. .smol_iface()
  115. .lock()
  116. .routes_mut()
  117. .remove_default_ipv4_route();
  118. }
  119. }
  120. // 在睡眠前释放锁
  121. drop(binding);
  122. let sleep_time = PosixTimeSpec {
  123. tv_sec: 0,
  124. tv_nsec: 50,
  125. };
  126. let _ = nanosleep(sleep_time)?;
  127. }
  128. return Err(SystemError::ETIMEDOUT);
  129. }
  130. pub fn poll_ifaces() {
  131. log::debug!("poll_ifaces");
  132. let guard: RwLockReadGuard<BTreeMap<usize, Arc<dyn Iface>>> = NET_DEVICES.read_irqsave();
  133. if guard.len() == 0 {
  134. warn!("poll_ifaces: No net driver found!");
  135. return;
  136. }
  137. for (_, iface) in guard.iter() {
  138. iface.poll();
  139. }
  140. }