diff --git a/bpf/aya-bpf/src/maps/mod.rs b/bpf/aya-bpf/src/maps/mod.rs index 9a8dd632..71db366a 100644 --- a/bpf/aya-bpf/src/maps/mod.rs +++ b/bpf/aya-bpf/src/maps/mod.rs @@ -1,5 +1,6 @@ pub mod array; pub mod hash_map; +pub mod per_cpu_array; pub mod perf_map; pub mod queue; pub mod sock_hash; @@ -8,6 +9,7 @@ pub mod stack_trace; pub use array::Array; pub use hash_map::HashMap; +pub use per_cpu_array::PerCpuArray; pub use perf_map::PerfMap; pub use queue::Queue; pub use sock_hash::SockHash; diff --git a/bpf/aya-bpf/src/maps/per_cpu_array.rs b/bpf/aya-bpf/src/maps/per_cpu_array.rs new file mode 100644 index 00000000..cfa264ad --- /dev/null +++ b/bpf/aya-bpf/src/maps/per_cpu_array.rs @@ -0,0 +1,59 @@ +use core::{marker::PhantomData, mem}; + +use aya_bpf_cty::c_void; + +use crate::{ + bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY}, + helpers::bpf_map_lookup_elem, +}; + +#[repr(transparent)] +pub struct PerCpuArray { + def: bpf_map_def, + _t: PhantomData, +} + +impl PerCpuArray { + pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerCpuArray { + PerCpuArray { + def: bpf_map_def { + type_: BPF_MAP_TYPE_PERCPU_ARRAY, + key_size: mem::size_of::() as u32, + value_size: mem::size_of::() as u32, + max_entries, + map_flags: flags, + id: 0, + pinning: 0, + }, + _t: PhantomData, + } + } + + #[inline(always)] + pub unsafe fn get(&mut self, index: u32) -> Option<&T> { + let value = bpf_map_lookup_elem( + &mut self.def as *mut _ as *mut _, + &index as *const _ as *const c_void, + ); + if value.is_null() { + None + } else { + // FIXME: alignment + Some(&*(value as *const T)) + } + } + + #[inline(always)] + pub unsafe fn get_mut(&mut self, index: u32) -> Option<&mut T> { + let value = bpf_map_lookup_elem( + &mut self.def as *mut _ as *mut _, + &index as *const _ as *const c_void, + ); + if value.is_null() { + None + } else { + // FIXME: alignment + Some(&mut *(value as *mut T)) + } + } +}