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