mod.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. mod util;
  2. mod verifier;
  3. use super::Result;
  4. use crate::bpf::map::BpfMap;
  5. use crate::bpf::prog::util::{BpfProgMeta, BpfProgVerifierInfo};
  6. use crate::bpf::prog::verifier::BpfProgVerifier;
  7. use crate::filesystem::vfs::file::{File, FileMode};
  8. use crate::filesystem::vfs::syscall::ModeType;
  9. use crate::filesystem::vfs::{FilePrivateData, FileSystem, FileType, IndexNode, Metadata};
  10. use crate::include::bindings::linux_bpf::bpf_attr;
  11. use crate::libs::spinlock::SpinLockGuard;
  12. use crate::process::ProcessManager;
  13. use alloc::string::String;
  14. use alloc::sync::Arc;
  15. use alloc::vec::Vec;
  16. use core::any::Any;
  17. use system_error::SystemError;
  18. #[derive(Debug)]
  19. pub struct BpfProg {
  20. meta: BpfProgMeta,
  21. raw_file_ptr: Vec<usize>,
  22. }
  23. impl BpfProg {
  24. pub fn new(meta: BpfProgMeta) -> Self {
  25. Self {
  26. meta,
  27. raw_file_ptr: Vec::new(),
  28. }
  29. }
  30. pub fn insns(&self) -> &[u8] {
  31. &self.meta.insns
  32. }
  33. pub fn insns_mut(&mut self) -> &mut [u8] {
  34. &mut self.meta.insns
  35. }
  36. pub fn insert_map(&mut self, map_ptr: usize) {
  37. self.raw_file_ptr.push(map_ptr);
  38. }
  39. }
  40. impl IndexNode for BpfProg {
  41. fn open(&self, _data: SpinLockGuard<FilePrivateData>, _mode: &FileMode) -> Result<()> {
  42. Ok(())
  43. }
  44. fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<()> {
  45. Ok(())
  46. }
  47. fn read_at(
  48. &self,
  49. _offset: usize,
  50. _len: usize,
  51. _buf: &mut [u8],
  52. _data: SpinLockGuard<FilePrivateData>,
  53. ) -> Result<usize> {
  54. Err(SystemError::ENOSYS)
  55. }
  56. fn write_at(
  57. &self,
  58. _offset: usize,
  59. _len: usize,
  60. _buf: &[u8],
  61. _data: SpinLockGuard<FilePrivateData>,
  62. ) -> Result<usize> {
  63. Err(SystemError::ENOSYS)
  64. }
  65. fn metadata(&self) -> Result<Metadata> {
  66. let meta = Metadata {
  67. mode: ModeType::from_bits_truncate(0o755),
  68. file_type: FileType::File,
  69. ..Default::default()
  70. };
  71. Ok(meta)
  72. }
  73. fn resize(&self, _len: usize) -> Result<()> {
  74. Ok(())
  75. }
  76. fn fs(&self) -> Arc<dyn FileSystem> {
  77. panic!("BpfProg does not have a filesystem")
  78. }
  79. fn as_any_ref(&self) -> &dyn Any {
  80. self
  81. }
  82. fn list(&self) -> Result<Vec<String>> {
  83. Err(SystemError::ENOSYS)
  84. }
  85. fn absolute_path(&self) -> core::result::Result<String, SystemError> {
  86. Ok(String::from("BPF Program"))
  87. }
  88. }
  89. impl Drop for BpfProg {
  90. fn drop(&mut self) {
  91. unsafe {
  92. for ptr in self.raw_file_ptr.iter() {
  93. let file = Arc::from_raw(*ptr as *const u8 as *const BpfMap);
  94. drop(file)
  95. }
  96. }
  97. }
  98. }
  99. /// Load a BPF program into the kernel.
  100. ///
  101. /// See https://ebpf-docs.dylanreimerink.nl/linux/syscall/BPF_PROG_LOAD/
  102. pub fn bpf_prog_load(attr: &bpf_attr) -> Result<usize> {
  103. let args = BpfProgMeta::try_from(attr)?;
  104. // info!("bpf_prog_load: {:#?}", args);
  105. let log_info = BpfProgVerifierInfo::from(attr);
  106. let prog = BpfProg::new(args);
  107. let fd_table = ProcessManager::current_pcb().fd_table();
  108. let prog = BpfProgVerifier::new(prog, log_info.log_level, &mut []).verify(&fd_table)?;
  109. let file = File::new(Arc::new(prog), FileMode::O_RDWR)?;
  110. let fd = fd_table.write().alloc_fd(file, None).map(|x| x as usize)?;
  111. Ok(fd)
  112. }