Skip to main content

kbpf_basic/
lib.rs

1//! Basic eBPF library providing essential functionalities for eBPF programs.
2//!! This library includes support for BPF maps, helper functions, and program
3//! loading mechanisms, making it easier to develop and run eBPF programs in a
4//! kernel-like environment.
5//!
6
7#![deny(missing_docs)]
8#![no_std]
9#![feature(c_variadic)]
10#![allow(unused)]
11extern crate alloc;
12use alloc::{string::String, vec::Vec};
13
14use map::UnifiedMap;
15
16use crate::preprocessor::EbpfInst;
17pub mod helper;
18pub mod linux_bpf;
19pub mod map;
20pub mod perf;
21pub mod preprocessor;
22pub mod prog;
23pub mod raw_tracepoint;
24
25/// Type alias for BPF results and errors.
26pub type BpfResult<T> = axerrno::LinuxResult<T>;
27/// Type alias for BPF errors.
28pub type BpfError = axerrno::LinuxError;
29
30/// PollWaiter trait for maps that support polling.
31pub trait PollWaker: Send + Sync {
32    /// Wake up any waiters on the map.
33    fn wake_up(&self);
34}
35
36/// The KernelAuxiliaryOps trait provides auxiliary operations which should
37/// be implemented by the kernel or a kernel-like environment.
38pub trait KernelAuxiliaryOps: Send + Sync + 'static {
39    /// Get a unified map from a pointer.
40    fn get_unified_map_from_ptr<F, R>(ptr: *const u8, func: F) -> BpfResult<R>
41    where
42        F: FnOnce(&mut UnifiedMap) -> BpfResult<R>;
43    /// Get a unified map from a file descriptor.
44    fn get_unified_map_from_fd<F, R>(map_fd: u32, func: F) -> BpfResult<R>
45    where
46        F: FnOnce(&mut UnifiedMap) -> BpfResult<R>;
47    /// Get a unified map pointer from a file descriptor.
48    fn get_unified_map_ptr_from_fd(map_fd: u32) -> BpfResult<*const u8>;
49    /// Translate eBPF instructions, which may involve relocating map file descriptors.
50    fn translate_instruction(instruction: Vec<u8>) -> BpfResult<Vec<impl preprocessor::EbpfInst>>;
51    /// Copy data from a user space pointer to a kernel space buffer.
52    fn copy_from_user(src: *const u8, size: usize, dst: &mut [u8]) -> BpfResult<()>;
53    /// Copy data from a kernel space buffer to a user space pointer.
54    fn copy_to_user(dest: *mut u8, size: usize, src: &[u8]) -> BpfResult<()>;
55    /// Get the current CPU ID.
56    fn current_cpu_id() -> u32;
57    /// Output some data to a perf buf
58    fn perf_event_output(
59        ctx: *mut core::ffi::c_void,
60        fd: u32,
61        flags: u32,
62        data: &[u8],
63    ) -> BpfResult<()>;
64    /// Read a string from a user space pointer.
65    fn string_from_user_cstr(ptr: *const u8) -> BpfResult<String>;
66    /// For ebpf print helper functions
67    fn ebpf_write_str(str: &str) -> BpfResult<()>;
68    /// For ebpf ktime helper functions
69    fn ebpf_time_ns() -> BpfResult<u64>;
70
71    /// Allocate pages in kernel space. Return the physical address of the allocated page.
72    fn alloc_page() -> BpfResult<usize>;
73    /// Free the allocated page in kernel space.
74    fn free_page(phys_addr: usize);
75    /// Create a virtual mapping for the given physical addresses. Return the virtual address.
76    fn vmap(phys_addrs: &[usize]) -> BpfResult<usize>;
77    /// Unmap the given virtual address.
78    fn unmap(vaddr: usize);
79}
80
81struct DummyAuxImpl;
82
83#[derive(Clone)]
84struct DummyInst;
85impl EbpfInst for DummyInst {
86    fn opc(&self) -> u8 {
87        0
88    }
89
90    fn imm(&self) -> i32 {
91        0
92    }
93
94    fn src(&self) -> u8 {
95        0
96    }
97
98    fn set_imm(&mut self, _imm: i32) {}
99
100    fn to_array(&self) -> [u8; 8] {
101        [0; 8]
102    }
103}
104
105impl KernelAuxiliaryOps for DummyAuxImpl {
106    fn get_unified_map_from_ptr<F, R>(_ptr: *const u8, _func: F) -> BpfResult<R>
107    where
108        F: FnOnce(&mut UnifiedMap) -> BpfResult<R>,
109    {
110        Err(BpfError::EPERM)
111    }
112
113    fn get_unified_map_from_fd<F, R>(_map_fd: u32, _func: F) -> BpfResult<R>
114    where
115        F: FnOnce(&mut UnifiedMap) -> BpfResult<R>,
116    {
117        Err(BpfError::EPERM)
118    }
119
120    fn get_unified_map_ptr_from_fd(_map_fd: u32) -> BpfResult<*const u8> {
121        Err(BpfError::EPERM)
122    }
123
124    fn translate_instruction(instruction: Vec<u8>) -> BpfResult<Vec<impl preprocessor::EbpfInst>> {
125        Err::<Vec<DummyInst>, BpfError>(BpfError::EPERM)
126    }
127
128    fn copy_from_user(_src: *const u8, _size: usize, _dst: &mut [u8]) -> BpfResult<()> {
129        Err(BpfError::EPERM)
130    }
131
132    fn copy_to_user(_dest: *mut u8, _size: usize, _src: &[u8]) -> BpfResult<()> {
133        Err(BpfError::EPERM)
134    }
135
136    fn current_cpu_id() -> u32 {
137        0
138    }
139
140    fn perf_event_output(
141        _ctx: *mut core::ffi::c_void,
142        _fd: u32,
143        _flags: u32,
144        _data: &[u8],
145    ) -> BpfResult<()> {
146        Err(BpfError::EPERM)
147    }
148
149    fn string_from_user_cstr(_ptr: *const u8) -> BpfResult<String> {
150        Err(BpfError::EPERM)
151    }
152
153    fn ebpf_write_str(_str: &str) -> BpfResult<()> {
154        Err(BpfError::EPERM)
155    }
156
157    fn ebpf_time_ns() -> BpfResult<u64> {
158        Err(BpfError::EPERM)
159    }
160
161    fn alloc_page() -> BpfResult<usize> {
162        Err(BpfError::EPERM)
163    }
164
165    fn free_page(_phys_addr: usize) {}
166
167    fn vmap(_phys_addrs: &[usize]) -> BpfResult<usize> {
168        Err(BpfError::EPERM)
169    }
170
171    fn unmap(_vaddr: usize) {}
172}