aya_ebpf/maps/
stack.rs

1use core::{marker::PhantomData, mem};
2
3use crate::{
4    bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_STACK},
5    helpers::{bpf_map_pop_elem, bpf_map_push_elem},
6    maps::PinningType,
7};
8
9#[repr(transparent)]
10pub struct Stack<T> {
11    def: bpf_map_def,
12    _t: PhantomData<T>,
13}
14
15impl<T> Stack<T> {
16    pub const fn with_max_entries(max_entries: u32, flags: u32) -> Stack<T> {
17        Stack {
18            def: bpf_map_def {
19                type_: BPF_MAP_TYPE_STACK,
20                key_size: 0,
21                value_size: mem::size_of::<T>() as u32,
22                max_entries,
23                map_flags: flags,
24                id: 0,
25                pinning: PinningType::None as u32,
26            },
27            _t: PhantomData,
28        }
29    }
30
31    pub const fn pinned(max_entries: u32, flags: u32) -> Stack<T> {
32        Stack {
33            def: bpf_map_def {
34                type_: BPF_MAP_TYPE_STACK,
35                key_size: 0,
36                value_size: mem::size_of::<T>() as u32,
37                max_entries,
38                map_flags: flags,
39                id: 0,
40                pinning: PinningType::ByName as u32,
41            },
42            _t: PhantomData,
43        }
44    }
45
46    pub fn push(&mut self, value: &T, flags: u64) -> Result<(), i64> {
47        let ret = unsafe {
48            bpf_map_push_elem(
49                &mut self.def as *mut _ as *mut _,
50                value as *const _ as *const _,
51                flags,
52            )
53        };
54        (ret == 0).then_some(()).ok_or(ret)
55    }
56
57    pub fn pop(&mut self) -> Option<T> {
58        unsafe {
59            let mut value = mem::MaybeUninit::uninit();
60            let ret = bpf_map_pop_elem(
61                &mut self.def as *mut _ as *mut _,
62                value.as_mut_ptr() as *mut _,
63            );
64            (ret == 0).then_some(value.assume_init())
65        }
66    }
67}