aya_friday/programs/fentry.rs
1//! Fentry programs.
2
3use aya_obj::{
4 btf::{Btf, BtfKind},
5 generated::{bpf_attach_type::BPF_TRACE_FENTRY, bpf_prog_type::BPF_PROG_TYPE_TRACING},
6};
7
8use crate::programs::{
9 FdLink, FdLinkId, ProgramData, ProgramError, ProgramType, define_link_wrapper,
10 load_program_with_attach_type, utils::attach_raw_tracepoint,
11};
12
13/// A program that can be attached to the entry point of (almost) any kernel
14/// function.
15///
16/// [`FEntry`] programs are similar to [kprobes](crate::programs::KProbe), but
17/// the difference is that fentry has practically zero overhead to call before
18/// kernel function. Fentry programs can be also attached to other eBPF
19/// programs.
20///
21/// # Minimum kernel version
22///
23/// The minimum kernel version required to use this feature is 5.5.
24///
25/// # Examples
26///
27/// ```no_run
28/// # #[derive(thiserror::Error, Debug)]
29/// # enum Error {
30/// # #[error(transparent)]
31/// # BtfError(#[from] aya::BtfError),
32/// # #[error(transparent)]
33/// # Program(#[from] aya::programs::ProgramError),
34/// # #[error(transparent)]
35/// # Ebpf(#[from] aya::EbpfError),
36/// # }
37/// # let mut bpf = Ebpf::load_file("ebpf_programs.o")?;
38/// use aya::{Ebpf, programs::FEntry, BtfError, Btf};
39///
40/// let btf = Btf::from_sys_fs()?;
41/// let program: &mut FEntry = bpf.program_mut("filename_lookup").unwrap().try_into()?;
42/// program.load("filename_lookup", &btf)?;
43/// program.attach()?;
44/// # Ok::<(), Error>(())
45/// ```
46#[derive(Debug)]
47#[doc(alias = "BPF_TRACE_FENTRY")]
48#[doc(alias = "BPF_PROG_TYPE_TRACING")]
49pub struct FEntry {
50 pub(crate) data: ProgramData<FEntryLink>,
51}
52
53impl FEntry {
54 /// The type of the program according to the kernel.
55 pub const PROGRAM_TYPE: ProgramType = ProgramType::Tracing;
56
57 /// Loads the program inside the kernel.
58 ///
59 /// Loads the program so it's executed when the kernel function `fn_name`
60 /// is entered. The `btf` argument must contain the BTF info for the
61 /// running kernel.
62 pub fn load(&mut self, fn_name: &str, btf: &Btf) -> Result<(), ProgramError> {
63 let Self { data } = self;
64 data.attach_btf_id = Some(btf.id_by_type_name_kind(fn_name, BtfKind::Func)?);
65 load_program_with_attach_type(BPF_PROG_TYPE_TRACING, BPF_TRACE_FENTRY, data)
66 }
67
68 /// Attaches the program.
69 ///
70 /// The returned value can be used to detach, see [`FEntry::detach`].
71 pub fn attach(&mut self) -> Result<FEntryLinkId, ProgramError> {
72 attach_raw_tracepoint(&mut self.data, None)
73 }
74}
75
76define_link_wrapper!(FEntryLink, FEntryLinkId, FdLink, FdLinkId, FEntry);