mirror of https://github.com/aya-rs/aya
bpf: Handle raw tracepoint arguments
Provide an `arg()` method in `RawTracepointArgs` wrapper of `bpf_raw_tracepoint_args` and also in `RawTracepointContext`, so it's directly available in raw tracepoint programs. The methods and traits implemented here are unsafe. There is no way to reliably check the number of available arguments, so requesting a non-existing one leads to undefined behavior.pull/805/head
parent
cc29c8a74d
commit
b9ad14933f
@ -1,19 +1,25 @@
|
|||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
|
|
||||||
use crate::BpfContext;
|
use crate::{args::FromRawTracepointArgs, bindings::bpf_raw_tracepoint_args, BpfContext};
|
||||||
|
|
||||||
pub struct RawTracePointContext {
|
pub struct RawTracePointContext {
|
||||||
ctx: *mut c_void,
|
ctx: *mut bpf_raw_tracepoint_args,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawTracePointContext {
|
impl RawTracePointContext {
|
||||||
pub fn new(ctx: *mut c_void) -> RawTracePointContext {
|
pub fn new(ctx: *mut c_void) -> RawTracePointContext {
|
||||||
RawTracePointContext { ctx }
|
RawTracePointContext {
|
||||||
|
ctx: ctx as *mut bpf_raw_tracepoint_args,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn arg<T: FromRawTracepointArgs>(&self, n: usize) -> T {
|
||||||
|
T::from_argument(&*self.ctx, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BpfContext for RawTracePointContext {
|
impl BpfContext for RawTracePointContext {
|
||||||
fn as_ptr(&self) -> *mut c_void {
|
fn as_ptr(&self) -> *mut c_void {
|
||||||
self.ctx
|
self.ctx as *mut c_void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use aya_bpf::{
|
||||||
|
macros::{map, raw_tracepoint},
|
||||||
|
maps::Array,
|
||||||
|
programs::RawTracePointContext,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[map]
|
||||||
|
static RESULT: Array<SysEnterEvent> = Array::with_max_entries(1, 0);
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct SysEnterEvent {
|
||||||
|
pub common_type: u16,
|
||||||
|
pub common_flags: u8,
|
||||||
|
_padding: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SysEnterEvent {
|
||||||
|
pub fn new(common_type: u16, common_flags: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
common_type,
|
||||||
|
common_flags,
|
||||||
|
_padding: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[raw_tracepoint(tracepoint = "sys_enter")]
|
||||||
|
pub fn sys_enter(ctx: RawTracePointContext) -> i32 {
|
||||||
|
let common_type: u16 = unsafe { ctx.arg(0) };
|
||||||
|
let common_flags: u8 = unsafe { ctx.arg(1) };
|
||||||
|
|
||||||
|
if let Some(ptr) = RESULT.get_ptr_mut(0) {
|
||||||
|
unsafe {
|
||||||
|
(*ptr).common_type = common_type;
|
||||||
|
(*ptr).common_flags = common_flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
use aya::{maps::Array, programs::RawTracePoint, Bpf};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct SysEnterEvent {
|
||||||
|
pub common_type: u16,
|
||||||
|
pub common_flags: u8,
|
||||||
|
_padding: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl aya::Pod for SysEnterEvent {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_tracepoint() {
|
||||||
|
let mut bpf = Bpf::load(crate::RAW_TRACEPOINT).unwrap();
|
||||||
|
let prog: &mut RawTracePoint = bpf.program_mut("sys_enter").unwrap().try_into().unwrap();
|
||||||
|
prog.load().unwrap();
|
||||||
|
prog.attach("sys_enter").unwrap();
|
||||||
|
|
||||||
|
let map: Array<_, SysEnterEvent> = Array::try_from(bpf.map_mut("RESULT").unwrap()).unwrap();
|
||||||
|
let result = map.get(&0, 0).unwrap();
|
||||||
|
|
||||||
|
assert_ne!(result.common_type, 0);
|
||||||
|
assert_ne!(result.common_flags, 0);
|
||||||
|
}
|
Loading…
Reference in New Issue