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