From 0220a4192c0eea8ed0b871e4ace98a45112234bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=C2=A0Decina?= Date: Sat, 2 Oct 2021 10:55:12 +0000 Subject: [PATCH] bpf: add PerfEventByteArray Similar to PerfEventArray but allows to output variable length byte slices --- bpf/aya-bpf/src/maps/mod.rs | 2 +- bpf/aya-bpf/src/maps/perf/mod.rs | 2 + .../src/maps/perf/perf_event_byte_array.rs | 64 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 bpf/aya-bpf/src/maps/perf/perf_event_byte_array.rs diff --git a/bpf/aya-bpf/src/maps/mod.rs b/bpf/aya-bpf/src/maps/mod.rs index bc766c70..0ba88308 100644 --- a/bpf/aya-bpf/src/maps/mod.rs +++ b/bpf/aya-bpf/src/maps/mod.rs @@ -17,7 +17,7 @@ pub mod stack_trace; pub use array::Array; pub use hash_map::HashMap; pub use per_cpu_array::PerCpuArray; -pub use perf::PerfEventArray; +pub use perf::{PerfEventArray, PerfEventByteArray}; pub use queue::Queue; pub use sock_hash::SockHash; pub use sock_map::SockMap; diff --git a/bpf/aya-bpf/src/maps/perf/mod.rs b/bpf/aya-bpf/src/maps/perf/mod.rs index 0faba365..5b4d310f 100644 --- a/bpf/aya-bpf/src/maps/perf/mod.rs +++ b/bpf/aya-bpf/src/maps/perf/mod.rs @@ -1,3 +1,5 @@ mod perf_event_array; +mod perf_event_byte_array; pub use perf_event_array::PerfEventArray; +pub use perf_event_byte_array::PerfEventByteArray; diff --git a/bpf/aya-bpf/src/maps/perf/perf_event_byte_array.rs b/bpf/aya-bpf/src/maps/perf/perf_event_byte_array.rs new file mode 100644 index 00000000..1863c896 --- /dev/null +++ b/bpf/aya-bpf/src/maps/perf/perf_event_byte_array.rs @@ -0,0 +1,64 @@ +use core::{marker::PhantomData, mem}; + +use crate::{ + bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_F_CURRENT_CPU}, + helpers::bpf_perf_event_output, + maps::PinningType, + BpfContext, +}; + +#[repr(transparent)] +pub struct PerfEventByteArray { + def: bpf_map_def, +} + +impl PerfEventByteArray { + pub const fn new(flags: u32) -> PerfEventByteArray { + PerfEventByteArray::with_max_entries(0, flags) + } + + pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerfEventByteArray { + PerfEventByteArray { + def: bpf_map_def { + type_: BPF_MAP_TYPE_PERF_EVENT_ARRAY, + key_size: mem::size_of::() as u32, + value_size: mem::size_of::() as u32, + max_entries, + map_flags: flags, + id: 0, + pinning: PinningType::None as u32, + }, + } + } + + pub const fn pinned(max_entries: u32, flags: u32) -> PerfEventByteArray { + PerfEventByteArray { + def: bpf_map_def { + type_: BPF_MAP_TYPE_PERF_EVENT_ARRAY, + key_size: mem::size_of::() as u32, + value_size: mem::size_of::() as u32, + max_entries, + map_flags: flags, + id: 0, + pinning: PinningType::ByName as u32, + }, + } + } + + pub fn output(&mut self, ctx: &C, data: &[u8], flags: u32) { + self.output_at_index(ctx, BPF_F_CURRENT_CPU as u32, data, flags) + } + + pub fn output_at_index(&mut self, ctx: &C, index: u32, data: &[u8], flags: u32) { + let flags = (flags as u64) << 32 | index as u64; + unsafe { + bpf_perf_event_output( + ctx.as_ptr(), + &mut self.def as *mut _ as *mut _, + flags, + data.as_ptr() as *mut _, + data.len() as u64, + ); + } + } +}