diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index f01689509..1ce895dd2 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -249,7 +249,10 @@ pub enum ProgramSection { URetProbe { sleepable: bool, }, - TracePoint, + TracePoint { + category: Option, + name: Option, + }, SocketFilter, Xdp { frags: bool, @@ -330,7 +333,11 @@ impl FromStr for ProgramSection { }, }, "tp_btf" => BtfTracePoint, - "tracepoint" | "tp" => TracePoint, + "tracepoint" | "tp" => { + let category = pieces.next().map(|s| s.to_string()); + let name = pieces.next().map(|s| s.to_string()); + TracePoint { category, name } + } "socket" => SocketFilter, "sk_msg" => SkMsg, "sk_skb" => { @@ -2014,7 +2021,7 @@ mod tests { assert_matches!( obj.parse_section(fake_section( EbpfSectionKind::Program, - "tracepoint/foo", + "tracepoint/cat/name", bytes_of(&fake_ins()), None )), diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index bbe064b15..49ec48f28 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -30,10 +30,11 @@ use crate::{ Object, ParseError, ProgramSection, }, programs::{ - BtfTracePoint, CgroupDevice, CgroupSkb, CgroupSkbAttachType, CgroupSock, CgroupSockAddr, - CgroupSockopt, CgroupSysctl, Extension, FEntry, FExit, KProbe, LircMode2, Lsm, PerfEvent, - ProbeKind, Program, ProgramData, ProgramError, RawTracePoint, SchedClassifier, SkLookup, - SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp, + trace_point::TracePointAttachInfo, BtfTracePoint, CgroupDevice, CgroupSkb, + CgroupSkbAttachType, CgroupSock, CgroupSockAddr, CgroupSockopt, CgroupSysctl, Extension, + FEntry, FExit, KProbe, LircMode2, Lsm, PerfEvent, ProbeKind, Program, ProgramData, + ProgramError, RawTracePoint, SchedClassifier, SkLookup, SkMsg, SkSkb, SkSkbKind, SockOps, + SocketFilter, TracePoint, UProbe, Xdp, }, sys::{ bpf_load_btf, is_bpf_cookie_supported, is_bpf_global_data_supported, @@ -417,7 +418,10 @@ impl<'a> EbpfLoader<'a> { | ProgramSection::KProbe | ProgramSection::UProbe { sleepable: _ } | ProgramSection::URetProbe { sleepable: _ } - | ProgramSection::TracePoint + | ProgramSection::TracePoint { + category: _, + name: _, + } | ProgramSection::SocketFilter | ProgramSection::Xdp { frags: _, @@ -572,9 +576,19 @@ impl<'a> EbpfLoader<'a> { kind: ProbeKind::URetProbe, }) } - ProgramSection::TracePoint => Program::TracePoint(TracePoint { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), - }), + ProgramSection::TracePoint { category, name } => { + let expected_attach_info = match (category, name) { + (Some(category), Some(name)) => Some(TracePointAttachInfo { + category: category.clone(), + name: name.clone(), + }), + _ => None, + }; + Program::TracePoint(TracePoint { + data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + expected_attach_info, + }) + } ProgramSection::SocketFilter => Program::SocketFilter(SocketFilter { data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), }), diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 00d61b01d..17b80330f 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -146,6 +146,10 @@ pub enum ProgramError { #[error("the program is not attached")] NotAttached, + /// The program cannot be auto attached. + #[error("the program cannot be auto attached")] + CannotAutoAttach, + /// Loading the program failed. #[error("the BPF_PROG_LOAD syscall failed. Verifier output: {verifier_log}")] LoadError { @@ -939,7 +943,6 @@ macro_rules! impl_from_pin { // Use impl_from_pin if the program doesn't require additional data impl_from_pin!( - TracePoint, SocketFilter, SkMsg, CgroupSysctl, diff --git a/aya/src/programs/trace_point.rs b/aya/src/programs/trace_point.rs index 4ce0be9a6..54ff5c9ef 100644 --- a/aya/src/programs/trace_point.rs +++ b/aya/src/programs/trace_point.rs @@ -12,6 +12,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, }, sys::{bpf_link_get_info_by_fd, perf_event_open_trace_point, SyscallError}, + VerifierLogLevel, }; /// The type returned when attaching a [`TracePoint`] fails. @@ -28,6 +29,15 @@ pub enum TracePointError { }, } +/// Defines where to attach trace point +#[derive(Debug)] +pub struct TracePointAttachInfo { + /// Category of trace point + pub category: String, + /// Name of trace point + pub name: String, +} + /// A program that can be attached at a pre-defined kernel trace point. /// /// The kernel provides a set of pre-defined trace points that eBPF programs can @@ -53,6 +63,7 @@ pub enum TracePointError { #[doc(alias = "BPF_PROG_TYPE_TRACEPOINT")] pub struct TracePoint { pub(crate) data: ProgramData, + pub(crate) expected_attach_info: Option, } impl TracePoint { @@ -82,6 +93,18 @@ impl TracePoint { self.data.links.insert(TracePointLink::new(link)) } + /// Returns the attach info of the trace point + pub fn auto_attach(&mut self) -> Result { + let attach_info = self + .expected_attach_info + .as_ref() + .ok_or(ProgramError::CannotAutoAttach)?; + let category = attach_info.category.clone(); + let name = attach_info.name.clone(); + + self.attach(&category, &name) + } + /// Detaches from a trace point. /// /// See [TracePoint::attach]. @@ -96,6 +119,20 @@ impl TracePoint { pub fn take_link(&mut self, link_id: TracePointLinkId) -> Result { self.data.take_link(link_id) } + + /// Creates a program from a pinned entry on a bpffs. + /// + /// Existing links will not be populated. To work with existing links you should use [`crate::programs::links::PinnedLink`]. + /// + /// On drop, any managed links are detached and the program is unloaded. This will not result in + /// the program being unloaded from the kernel if it is still pinned. + pub fn from_pin>(path: P) -> Result { + let data = ProgramData::from_pinned_path(path, VerifierLogLevel::default())?; + Ok(Self { + data, + expected_attach_info: None, + }) + } } define_link_wrapper!(