aya_ebpf/maps/
per_cpu_array.rs

1use core::{cell::UnsafeCell, marker::PhantomData, mem, ptr::NonNull};
2
3use aya_ebpf_cty::c_void;
4
5use crate::{
6    bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY},
7    helpers::bpf_map_lookup_elem,
8    maps::PinningType,
9};
10
11#[repr(transparent)]
12pub struct PerCpuArray<T> {
13    def: UnsafeCell<bpf_map_def>,
14    _t: PhantomData<T>,
15}
16
17unsafe impl<T> Sync for PerCpuArray<T> {}
18
19impl<T> PerCpuArray<T> {
20    pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerCpuArray<T> {
21        PerCpuArray {
22            def: UnsafeCell::new(bpf_map_def {
23                type_: BPF_MAP_TYPE_PERCPU_ARRAY,
24                key_size: mem::size_of::<u32>() as u32,
25                value_size: mem::size_of::<T>() as u32,
26                max_entries,
27                map_flags: flags,
28                id: 0,
29                pinning: PinningType::None as u32,
30            }),
31            _t: PhantomData,
32        }
33    }
34
35    pub const fn pinned(max_entries: u32, flags: u32) -> PerCpuArray<T> {
36        PerCpuArray {
37            def: UnsafeCell::new(bpf_map_def {
38                type_: BPF_MAP_TYPE_PERCPU_ARRAY,
39                key_size: mem::size_of::<u32>() as u32,
40                value_size: mem::size_of::<T>() as u32,
41                max_entries,
42                map_flags: flags,
43                id: 0,
44                pinning: PinningType::ByName as u32,
45            }),
46            _t: PhantomData,
47        }
48    }
49
50    #[inline(always)]
51    pub fn get(&self, index: u32) -> Option<&T> {
52        unsafe {
53            // FIXME: alignment
54            self.lookup(index).map(|p| p.as_ref())
55        }
56    }
57
58    #[inline(always)]
59    pub fn get_ptr(&self, index: u32) -> Option<*const T> {
60        unsafe { self.lookup(index).map(|p| p.as_ptr() as *const T) }
61    }
62
63    #[inline(always)]
64    pub fn get_ptr_mut(&self, index: u32) -> Option<*mut T> {
65        unsafe { self.lookup(index).map(|p| p.as_ptr()) }
66    }
67
68    #[inline(always)]
69    unsafe fn lookup(&self, index: u32) -> Option<NonNull<T>> {
70        let ptr = bpf_map_lookup_elem(
71            self.def.get() as *mut _,
72            &index as *const _ as *const c_void,
73        );
74        NonNull::new(ptr as *mut T)
75    }
76}