Pārlūkot izejas kodu

bpf: add PerfEventByteArray

Similar to PerfEventArray but allows to output variable length byte
slices
Alessandro Decina 3 gadi atpakaļ
vecāks
revīzija
0220a4192c

+ 1 - 1
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;

+ 2 - 0
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;

+ 64 - 0
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::<u32>() as u32,
+                value_size: mem::size_of::<u32>() 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::<u32>() as u32,
+                value_size: mem::size_of::<u32>() as u32,
+                max_entries,
+                map_flags: flags,
+                id: 0,
+                pinning: PinningType::ByName as u32,
+            },
+        }
+    }
+
+    pub fn output<C: BpfContext>(&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<C: BpfContext>(&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,
+            );
+        }
+    }
+}