pub(crate) mod ringbuf;
pub use ringbuf::RingBufMap;
use crate::{BpfError, BpfResult as Result, KernelAuxiliaryOps};
#[derive(Debug)]
struct InnerPage<F: KernelAuxiliaryOps> {
addr: usize,
_phantom: core::marker::PhantomData<F>,
}
impl<F: KernelAuxiliaryOps> InnerPage<F> {
pub fn new() -> Result<Self> {
let addr = F::alloc_page()?;
Ok(InnerPage {
addr,
_phantom: core::marker::PhantomData,
})
}
pub fn phys_addr(&self) -> usize {
self.addr
}
}
impl<F: KernelAuxiliaryOps> Drop for InnerPage<F> {
fn drop(&mut self) {
F::free_page(self.addr);
}
}
#[derive(Debug)]
#[repr(C)]
#[repr(align(8))]
pub struct BpfDynPtr {
pub data: *mut u8,
pub size: u32,
pub offset: u32,
}
const DYNPTR_MAX_SIZE: u32 = (1u32 << 24) - 1;
const DYNPTR_TYPE_SHIFT: u32 = 28;
const DYNPTR_SIZE_MASK: u32 = 0xFFFFFF;
const DYNPTR_RDONLY_BIT: u32 = 1 << 31;
impl BpfDynPtr {
pub fn check_size(size: u32) -> Result<()> {
if size > DYNPTR_MAX_SIZE {
return Err(BpfError::EINVAL);
}
Ok(())
}
pub fn init(&mut self, data: &mut [u8], dynptr_type: BpfDynptrType, offset: u32, size: u32) {
self.data = data.as_mut_ptr();
self.offset = offset;
self.size = size;
self.size |= (dynptr_type as u32) << DYNPTR_TYPE_SHIFT;
}
}
#[allow(non_camel_case_types)]
pub enum BpfDynptrType {
BPF_DYNPTR_TYPE_INVALID = 0,
BPF_DYNPTR_TYPE_LOCAL,
BPF_DYNPTR_TYPE_RINGBUF,
BPF_DYNPTR_TYPE_SKB,
BPF_DYNPTR_TYPE_XDP,
}