aya_ebpf/maps/
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_ARRAY},
7    helpers::bpf_map_lookup_elem,
8    maps::PinningType,
9};
10
11#[repr(transparent)]
12pub struct Array<T> {
13    def: UnsafeCell<bpf_map_def>,
14    _t: PhantomData<T>,
15}
16
17unsafe impl<T: Sync> Sync for Array<T> {}
18
19impl<T> Array<T> {
20    pub const fn with_max_entries(max_entries: u32, flags: u32) -> Array<T> {
21        Array {
22            def: UnsafeCell::new(bpf_map_def {
23                type_: BPF_MAP_TYPE_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) -> Array<T> {
36        Array {
37            def: UnsafeCell::new(bpf_map_def {
38                type_: BPF_MAP_TYPE_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        // FIXME: alignment
53        unsafe { self.lookup(index).map(|p| p.as_ref()) }
54    }
55
56    #[inline(always)]
57    pub fn get_ptr(&self, index: u32) -> Option<*const T> {
58        unsafe { self.lookup(index).map(|p| p.as_ptr() as *const T) }
59    }
60
61    #[inline(always)]
62    pub fn get_ptr_mut(&self, index: u32) -> Option<*mut T> {
63        unsafe { self.lookup(index).map(|p| p.as_ptr()) }
64    }
65
66    #[inline(always)]
67    unsafe fn lookup(&self, index: u32) -> Option<NonNull<T>> {
68        let ptr = bpf_map_lookup_elem(
69            self.def.get() as *mut _,
70            &index as *const _ as *const c_void,
71        );
72        NonNull::new(ptr as *mut T)
73    }
74}