addr.rs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. use crate::{
  2. driver::net::Iface,
  3. net::socket::{
  4. netlink::{
  5. message::segment::{
  6. header::{CMsgSegHdr, GetRequestFlags, SegHdrCommonFlags},
  7. CSegmentType,
  8. },
  9. route::{
  10. kern::utils::finish_response,
  11. message::{
  12. attr::addr::AddrAttr,
  13. segment::{
  14. addr::{AddrMessageFlags, AddrSegment, AddrSegmentBody, RtScope},
  15. RouteNlSegment,
  16. },
  17. },
  18. },
  19. },
  20. AddressFamily,
  21. },
  22. process::namespace::net_namespace::NetNamespace,
  23. };
  24. use alloc::ffi::CString;
  25. use alloc::sync::Arc;
  26. use alloc::vec::Vec;
  27. use core::num::NonZeroU32;
  28. use system_error::SystemError;
  29. pub(super) fn do_get_addr(
  30. request_segment: &AddrSegment,
  31. netns: Arc<NetNamespace>,
  32. ) -> Result<Vec<RouteNlSegment>, SystemError> {
  33. let dump_all = {
  34. let flags = GetRequestFlags::from_bits_truncate(request_segment.header().flags);
  35. flags.contains(GetRequestFlags::DUMP)
  36. };
  37. if !dump_all {
  38. log::error!("GetAddr request without DUMP flag is not supported yet");
  39. return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
  40. }
  41. let mut responce: Vec<RouteNlSegment> = netns
  42. .device_list()
  43. .iter()
  44. .filter_map(|(_, iface)| iface_to_new_addr(request_segment.header(), iface))
  45. .map(RouteNlSegment::NewAddr)
  46. .collect();
  47. finish_response(request_segment.header(), dump_all, &mut responce);
  48. Ok(responce)
  49. }
  50. fn iface_to_new_addr(request_header: &CMsgSegHdr, iface: &Arc<dyn Iface>) -> Option<AddrSegment> {
  51. let ipv4_addr = iface.common().ipv4_addr()?;
  52. let header = CMsgSegHdr {
  53. len: 0,
  54. type_: CSegmentType::NEWADDR as _,
  55. flags: SegHdrCommonFlags::empty().bits(),
  56. seq: request_header.seq,
  57. pid: request_header.pid,
  58. };
  59. let addr_message = AddrSegmentBody {
  60. family: AddressFamily::INet as _,
  61. prefix_len: iface.common().prefix_len().unwrap(),
  62. flags: AddrMessageFlags::PERMANENT,
  63. scope: RtScope::HOST,
  64. index: NonZeroU32::new(iface.nic_id() as u32),
  65. };
  66. let attrs = vec![
  67. AddrAttr::Address(ipv4_addr.octets()),
  68. AddrAttr::Label(CString::new(iface.iface_name()).unwrap()),
  69. AddrAttr::Local(ipv4_addr.octets()),
  70. ];
  71. Some(AddrSegment::new(header, addr_message, attrs))
  72. }