From 88d20a0c990a89f7f51e417a900953e43b96ebab Mon Sep 17 00:00:00 2001 From: Michal Rostecki Date: Mon, 4 Nov 2024 10:57:55 +0100 Subject: [PATCH] feat(aya): Add iterator program type BPF iterators[0] are a way to dump kernel data into user-space and an alternative to `/proc` filesystem. This change adds support for BPF iterators on the user-space side. It provides a possibility to retrieve the outputs of BPF iterator programs both from sync and async Rust code. [0] https://docs.kernel.org/bpf/bpf_iterators.html --- Cargo.toml | 3 +- aya-obj/src/obj.rs | 5 + aya/Cargo.toml | 5 +- aya/src/bpf.rs | 17 +- aya/src/programs/iter.rs | 225 ++++++++++++++++++++++++ aya/src/programs/mod.rs | 18 +- aya/src/sys/bpf.rs | 18 ++ test/integration-test/bpf/iter.bpf.c | 22 +++ test/integration-test/build.rs | 1 + test/integration-test/src/lib.rs | 1 + test/integration-test/src/tests.rs | 1 + test/integration-test/src/tests/iter.rs | 45 +++++ xtask/public-api/aya-obj.txt | 4 + xtask/public-api/aya.txt | 221 +++++++++++++++++++++++ 14 files changed, 578 insertions(+), 8 deletions(-) create mode 100644 aya/src/programs/iter.rs create mode 100644 test/integration-test/bpf/iter.bpf.c create mode 100644 test/integration-test/src/tests/iter.rs diff --git a/Cargo.toml b/Cargo.toml index 2834e050..231cb24c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,8 @@ edition = "2021" [workspace.dependencies] anyhow = { version = "1", default-features = false } assert_matches = { version = "1.5.0", default-features = false } -async-io = { version = "2.0", default-features = false } +async-fs = { version = "2.1", default-features = false } +async-io = { version = "2.4", default-features = false } bindgen = { version = "0.70", default-features = false } bitflags = { version = "2.2.1", default-features = false } bytes = { version = "1", default-features = false } diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index 7d304426..4f115024 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -288,6 +288,9 @@ pub enum ProgramSection { attach_type: CgroupSockAttachType, }, CgroupDevice, + Iter { + sleepable: bool, + }, } impl FromStr for ProgramSection { @@ -439,6 +442,8 @@ impl FromStr for ProgramSection { "fexit.s" => FExit { sleepable: true }, "freplace" => Extension, "sk_lookup" => SkLookup, + "iter" => Iter { sleepable: false }, + "iter.s" => Iter { sleepable: true }, _ => { return Err(ParseError::InvalidProgramSection { section: section.to_owned(), diff --git a/aya/Cargo.toml b/aya/Cargo.toml index 14099ff3..4019d59c 100644 --- a/aya/Cargo.toml +++ b/aya/Cargo.toml @@ -14,6 +14,7 @@ edition.workspace = true [dependencies] assert_matches = { workspace = true } +async-fs = { workspace = true, optional = true } async-io = { workspace = true, optional = true } aya-obj = { path = "../aya-obj", version = "^0.2.1", features = ["std"] } bitflags = { workspace = true } @@ -30,8 +31,8 @@ tempfile = { workspace = true } [features] default = [] -async_tokio = ["tokio/net"] -async_std = ["dep:async-io"] +async_tokio = ["tokio/fs", "tokio/io-util", "tokio/net"] +async_std = ["dep:async-fs", "dep:async-io"] [package.metadata.docs.rs] all-features = true diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index bbe064b1..b111b1f7 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -31,9 +31,9 @@ use crate::{ }, 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, + CgroupSockopt, CgroupSysctl, Extension, FEntry, FExit, Iter, 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, @@ -410,7 +410,8 @@ impl<'a> EbpfLoader<'a> { | ProgramSection::FEntry { sleepable: _ } | ProgramSection::FExit { sleepable: _ } | ProgramSection::Lsm { sleepable: _ } - | ProgramSection::BtfTracePoint => { + | ProgramSection::BtfTracePoint + | ProgramSection::Iter { sleepable: _ } => { return Err(EbpfError::BtfError(err)) } ProgramSection::KRetProbe @@ -688,6 +689,14 @@ impl<'a> EbpfLoader<'a> { ProgramSection::CgroupDevice => Program::CgroupDevice(CgroupDevice { data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), }), + ProgramSection::Iter { sleepable } => { + let mut data = + ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level); + if *sleepable { + data.flags = BPF_F_SLEEPABLE; + } + Program::Iter(Iter { data }) + } } }; (name, program) diff --git a/aya/src/programs/iter.rs b/aya/src/programs/iter.rs new file mode 100644 index 00000000..157d4fad --- /dev/null +++ b/aya/src/programs/iter.rs @@ -0,0 +1,225 @@ +//! Iterators. +use std::{ + mem::ManuallyDrop, + os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd}, +}; + +use crate::{ + generated::{bpf_attach_type::BPF_TRACE_ITER, bpf_prog_type}, + obj::{ + btf::{Btf, BtfKind}, + generated::bpf_link_type, + }, + programs::{ + define_link_wrapper, load_program, FdLink, LinkError, PerfLinkIdInner, PerfLinkInner, + ProgramData, ProgramError, + }, + sys::{bpf_create_iter, bpf_link_create, bpf_link_get_info_by_fd, LinkTarget, SyscallError}, +}; + +/// An eBPF iterator which allows to dump into user space. +/// +/// It can be seen as an alternative to `/proc` filesystem, which offers more +/// flexibility about what information should be retrieved and how it should be +/// formatted. +/// +/// # Minimum kernel version +/// +/// The minimum kernel version required to use this feature is 5.8. +/// +/// # Examples +/// +/// ## Non-async Rust +/// +/// ```no_run +/// use std::io::{BufRead, BufReader}; +/// use aya::{programs::{Iter, ProgramError}, BtfError, Btf, Ebpf}; +/// # let mut ebpf = Ebpf::load_file("ebpf_programs.o")?; +/// +/// let btf = Btf::from_sys_fs()?; +/// let program: &mut Iter = ebpf.program_mut("iter_prog").unwrap().try_into()?; +/// program.load("task", &btf)?; +/// +/// let link_id = program.attach()?; +/// let link = program.take_link(link_id)?; +/// let file = link.into_file()?; +/// let reader = BufReader::new(file); +/// +/// let mut lines = reader.lines(); +/// for line in lines { +/// let line = line?; +/// println!("{line}"); +/// } +/// # Ok::<(), Box>(()) +/// ``` +#[derive(Debug)] +pub struct Iter { + pub(crate) data: ProgramData, +} + +impl Iter { + /// Loads the program inside the kernel. + pub fn load(&mut self, iter_type: &str, btf: &Btf) -> Result<(), ProgramError> { + self.data.expected_attach_type = Some(BPF_TRACE_ITER); + let type_name = format!("bpf_iter_{iter_type}"); + self.data.attach_btf_id = + Some(btf.id_by_type_name_kind(type_name.as_str(), BtfKind::Func)?); + load_program(bpf_prog_type::BPF_PROG_TYPE_TRACING, &mut self.data) + } + + /// Attaches the program. + /// + /// The returned value can be used to detach, see [Iter::detach]. + pub fn attach(&mut self) -> Result { + let prog_fd = self.fd()?; + let prog_fd = prog_fd.as_fd(); + let link_fd = bpf_link_create(prog_fd, LinkTarget::Iter, BPF_TRACE_ITER, None, 0, None) + .map_err(|(_, io_error)| SyscallError { + call: "bpf_link_create", + io_error, + })?; + + self.data + .links + .insert(IterLink::new(PerfLinkInner::FdLink(FdLink::new(link_fd)))) + } + + /// Detaches the program. + /// + /// See [Iter::attach]. + pub fn detach(&mut self, link_id: IterLinkId) -> Result<(), ProgramError> { + self.data.links.remove(link_id) + } + + /// Takes ownership of the link referenced by the provided link_id. + /// + /// The link will be detached on `Drop` and the caller is now responsible + /// for managing its lifetime. + pub fn take_link(&mut self, link_id: IterLinkId) -> Result { + self.data.take_link(link_id) + } +} + +/// An iterator descriptor. +#[derive(Debug)] +pub struct IterFd { + fd: crate::MockableFd, +} + +impl AsFd for IterFd { + fn as_fd(&self) -> BorrowedFd<'_> { + let Self { fd } = self; + fd.as_fd() + } +} + +impl TryFrom for FdLink { + type Error = LinkError; + + fn try_from(value: IterLink) -> Result { + if let PerfLinkInner::FdLink(fd) = value.into_inner() { + Ok(fd) + } else { + Err(LinkError::InvalidLink) + } + } +} + +impl TryFrom for IterLink { + type Error = LinkError; + + fn try_from(fd_link: FdLink) -> Result { + let info = bpf_link_get_info_by_fd(fd_link.fd.as_fd())?; + if info.type_ == (bpf_link_type::BPF_LINK_TYPE_ITER as u32) { + return Ok(Self::new(PerfLinkInner::FdLink(fd_link))); + } + Err(LinkError::InvalidLink) + } +} + +define_link_wrapper!( + /// The link used by [Iter] programs. + IterLink, + /// The type returned by [Iter::attach]. Can be passed to [Iter::detach]. + IterLinkId, + PerfLinkInner, + PerfLinkIdInner +); + +impl IterLink { + /// Converts [IterLink] into a [std::fs::File]. That file can be used to + /// retrieve the outputs of the iterator program. + pub fn into_file(self) -> Result { + if let PerfLinkInner::FdLink(fd) = self.into_inner() { + let fd = bpf_create_iter(fd.fd.as_fd()).map_err(|(_, error)| { + LinkError::SyscallError(SyscallError { + call: "bpf_iter_create", + io_error: error, + }) + })?; + // We don't want to drop the descriptor when going out of the scope + // of this method. The lifecycle of the descriptor is going to be + // managed by the `File` created below. + let fd = ManuallyDrop::new(fd); + // SAFETY: We are sure that the file descriptor is valid. This + // `File` takes responsibility of closing it. + let file = unsafe { std::fs::File::from_raw_fd(fd.as_raw_fd()) }; + Ok(file) + } else { + Err(LinkError::InvalidLink) + } + } + + /// Converts [IterLink] into an [async_fs::File]. That file can be used to + /// retrieve the outputs of the iterator program. + #[cfg(feature = "async_std")] + pub fn into_async_io_file(self) -> Result { + if let PerfLinkInner::FdLink(fd) = self.into_inner() { + let fd = bpf_create_iter(fd.fd.as_fd()).map_err(|(_, error)| { + LinkError::SyscallError(SyscallError { + call: "bpf_iter_create", + io_error: error, + }) + })?; + // We don't want to drop the descriptor when going out of the scope + // of this method. The lifecycle of the descriptor is going to be + // managed by the `File` created below. + let fd = ManuallyDrop::new(fd); + // SAFETY: We are sure that the file descriptor is valid. This + // `File` takes responsibility of closing it. + // + // NOTE: Unfortunately, there is no `async_fs::File::from_raw_fd` + // method, so we have to work around that with creating + // `std::fs::File` and then converting it into `async_fs::File`. + let file = unsafe { std::fs::File::from_raw_fd(fd.as_raw_fd()) }; + let file: async_fs::File = file.into(); + Ok(file) + } else { + Err(LinkError::InvalidLink) + } + } + + /// Converts [IterLink] into a [tokio::fs::File]. That file can be used to + /// retrieve the outputs of the iterator program. + #[cfg(feature = "async_tokio")] + pub fn into_tokio_file(self) -> Result { + if let PerfLinkInner::FdLink(fd) = self.into_inner() { + let fd = bpf_create_iter(fd.fd.as_fd()).map_err(|(_, error)| { + LinkError::SyscallError(SyscallError { + call: "bpf_iter_create", + io_error: error, + }) + })?; + // We don't want to drop the descriptor when going out of the scope + // of this method. The lifecycle of the descriptor is going to be + // managed by the `File` created below. + let fd = ManuallyDrop::new(fd); + // SAFETY: We are sure that the file descriptor is valid. This + // `File` takes responsibility of closing it. + let file = unsafe { tokio::fs::File::from_raw_fd(fd.as_raw_fd()) }; + Ok(file) + } else { + Err(LinkError::InvalidLink) + } + } +} diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 00d61b01..589f6a87 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -51,6 +51,7 @@ pub mod cgroup_sysctl; pub mod extension; pub mod fentry; pub mod fexit; +pub mod iter; pub mod kprobe; pub mod links; pub mod lirc_mode2; @@ -94,6 +95,7 @@ pub use crate::programs::{ extension::{Extension, ExtensionError}, fentry::FEntry, fexit::FExit, + iter::Iter, kprobe::{KProbe, KProbeError}, links::{CgroupAttachMode, Link, LinkOrder}, lirc_mode2::LircMode2, @@ -303,6 +305,8 @@ pub enum Program { CgroupSock(CgroupSock), /// A [`CgroupDevice`] program CgroupDevice(CgroupDevice), + /// An [`Iter`] program + Iter(Iter), } impl Program { @@ -324,7 +328,9 @@ impl Program { Self::PerfEvent(_) => ProgramType::PerfEvent, Self::RawTracePoint(_) => ProgramType::RawTracePoint, Self::Lsm(_) => ProgramType::Lsm, - Self::BtfTracePoint(_) | Self::FEntry(_) | Self::FExit(_) => ProgramType::Tracing, + Self::BtfTracePoint(_) | Self::FEntry(_) | Self::FExit(_) | Self::Iter(_) => { + ProgramType::Tracing + } Self::Extension(_) => ProgramType::Extension, Self::CgroupSockAddr(_) => ProgramType::CgroupSockAddr, Self::SkLookup(_) => ProgramType::SkLookup, @@ -360,6 +366,7 @@ impl Program { Self::SkLookup(p) => p.pin(path), Self::CgroupSock(p) => p.pin(path), Self::CgroupDevice(p) => p.pin(path), + Self::Iter(p) => p.pin(path), } } @@ -390,6 +397,7 @@ impl Program { Self::SkLookup(mut p) => p.unload(), Self::CgroupSock(mut p) => p.unload(), Self::CgroupDevice(mut p) => p.unload(), + Self::Iter(mut p) => p.unload(), } } @@ -422,6 +430,7 @@ impl Program { Self::SkLookup(p) => p.fd(), Self::CgroupSock(p) => p.fd(), Self::CgroupDevice(p) => p.fd(), + Self::Iter(p) => p.fd(), } } @@ -455,6 +464,7 @@ impl Program { Self::SkLookup(p) => p.info(), Self::CgroupSock(p) => p.info(), Self::CgroupDevice(p) => p.info(), + Self::Iter(p) => p.info(), } } } @@ -771,6 +781,7 @@ impl_program_unload!( SockOps, CgroupSock, CgroupDevice, + Iter, ); macro_rules! impl_fd { @@ -811,6 +822,7 @@ impl_fd!( SockOps, CgroupSock, CgroupDevice, + Iter, ); /// Trait implemented by the [`Program`] types which support the kernel's @@ -916,6 +928,7 @@ impl_program_pin!( SockOps, CgroupSock, CgroupDevice, + Iter, ); macro_rules! impl_from_pin { @@ -954,6 +967,7 @@ impl_from_pin!( SkLookup, SockOps, CgroupDevice, + Iter, ); macro_rules! impl_try_from_program { @@ -1009,6 +1023,7 @@ impl_try_from_program!( SkLookup, CgroupSock, CgroupDevice, + Iter, ); impl_info!( @@ -1036,6 +1051,7 @@ impl_info!( SockOps, CgroupSock, CgroupDevice, + Iter, ); // TODO(https://github.com/aya-rs/aya/issues/645): this API is currently used in tests. Stabilize diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index a405b3be..99e26f4f 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -36,6 +36,16 @@ use crate::{ Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN, FEATURES, }; +pub(crate) fn bpf_create_iter(link_fd: BorrowedFd<'_>) -> SysResult { + let mut attr = unsafe { mem::zeroed::() }; + + let u = unsafe { &mut attr.iter_create }; + u.link_fd = link_fd.as_raw_fd() as u32; + + // SAFETY: BPF_ITER_CREATE returns a new file descriptor. + unsafe { fd_sys_bpf(bpf_cmd::BPF_ITER_CREATE, &mut attr) } +} + pub(crate) fn bpf_create_map( name: &CStr, def: &obj::Map, @@ -377,6 +387,7 @@ pub(crate) fn bpf_map_freeze(fd: BorrowedFd<'_>) -> SysResult { pub(crate) enum LinkTarget<'f> { Fd(BorrowedFd<'f>), IfIndex(u32), + Iter, } // since kernel 5.7 @@ -399,6 +410,13 @@ pub(crate) fn bpf_link_create( LinkTarget::IfIndex(ifindex) => { attr.link_create.__bindgen_anon_2.target_ifindex = ifindex; } + // When attaching to the iterator program, there is no target FD. + // We need to set it to 0. + // + // https://elixir.bootlin.com/linux/v6.11.8/source/tools/lib/bpf/libbpf.c#L12790 + LinkTarget::Iter => { + attr.link_create.__bindgen_anon_2.target_fd = 0; + } }; attr.link_create.attach_type = attach_type as u32; diff --git a/test/integration-test/bpf/iter.bpf.c b/test/integration-test/bpf/iter.bpf.c new file mode 100644 index 00000000..1e6b2c50 --- /dev/null +++ b/test/integration-test/bpf/iter.bpf.c @@ -0,0 +1,22 @@ +// clang-format off +#include +#include +// clang-format on + +char _license[] SEC("license") = "GPL"; + +SEC("iter/task") +int iter_task(struct bpf_iter__task *ctx) { + struct seq_file *seq = ctx->meta->seq; + struct task_struct *task = ctx->task; + if (task == NULL) { + return 0; + } + + if (ctx->meta->seq_num == 0) { + BPF_SEQ_PRINTF(seq, "tgid pid name\n"); + } + BPF_SEQ_PRINTF(seq, "%-8d %-8d %s\n", task->tgid, task->pid, task->comm); + + return 0; +} diff --git a/test/integration-test/build.rs b/test/integration-test/build.rs index 5266a8ea..dfa78789 100644 --- a/test/integration-test/build.rs +++ b/test/integration-test/build.rs @@ -67,6 +67,7 @@ fn main() { const C_BPF: &[(&str, bool)] = &[ ("ext.bpf.c", false), + ("iter.bpf.c", true), ("main.bpf.c", false), ("multimap-btf.bpf.c", false), ("reloc.bpf.c", true), diff --git a/test/integration-test/src/lib.rs b/test/integration-test/src/lib.rs index ffed5dd4..e854e10e 100644 --- a/test/integration-test/src/lib.rs +++ b/test/integration-test/src/lib.rs @@ -1,6 +1,7 @@ use aya::include_bytes_aligned; pub const EXT: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/ext.bpf.o")); +pub const ITER_TASK: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/iter.bpf.o")); pub const MAIN: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/main.bpf.o")); pub const MULTIMAP_BTF: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/multimap-btf.bpf.o")); diff --git a/test/integration-test/src/tests.rs b/test/integration-test/src/tests.rs index 61f490cf..e8141dfb 100644 --- a/test/integration-test/src/tests.rs +++ b/test/integration-test/src/tests.rs @@ -2,6 +2,7 @@ mod bpf_probe_read; mod btf_relocations; mod elf; mod info; +mod iter; mod load; mod log; mod rbpf; diff --git a/test/integration-test/src/tests/iter.rs b/test/integration-test/src/tests/iter.rs new file mode 100644 index 00000000..8f7349ff --- /dev/null +++ b/test/integration-test/src/tests/iter.rs @@ -0,0 +1,45 @@ +use std::io::BufRead; + +use aya::{programs::Iter, Btf, Ebpf}; +use test_log::test; +use tokio::io::AsyncBufReadExt; + +#[test] +fn iter_task() { + let mut ebpf = Ebpf::load(crate::ITER_TASK).unwrap(); + let btf = Btf::from_sys_fs().unwrap(); + let prog: &mut Iter = ebpf.program_mut("iter_task").unwrap().try_into().unwrap(); + prog.load("task", &btf).unwrap(); + + let link_id = prog.attach().unwrap(); + let link = prog.take_link(link_id).unwrap(); + let file = link.into_file().unwrap(); + let reader = std::io::BufReader::new(file); + + let mut lines = reader.lines(); + let line_title = lines.next().unwrap().unwrap(); + let line_init = lines.next().unwrap().unwrap(); + + assert_eq!(line_title, "tgid pid name"); + assert!(line_init == "1 1 init" || line_init == "1 1 systemd"); +} + +#[test(tokio::test)] +async fn iter_async_task() { + let mut ebpf = Ebpf::load(crate::ITER_TASK).unwrap(); + let btf = Btf::from_sys_fs().unwrap(); + let prog: &mut Iter = ebpf.program_mut("iter_task").unwrap().try_into().unwrap(); + prog.load("task", &btf).unwrap(); + + let link_id = prog.attach().unwrap(); + let link = prog.take_link(link_id).unwrap(); + let file = link.into_tokio_file().unwrap(); + let reader = tokio::io::BufReader::new(file); + + let mut lines = reader.lines(); + let line_title = lines.next_line().await.unwrap().unwrap(); + let line_init = lines.next_line().await.unwrap().unwrap(); + + assert_eq!(line_title, "tgid pid name"); + assert!(line_init == "1 1 init" || line_init == "1 1 systemd"); +} diff --git a/xtask/public-api/aya-obj.txt b/xtask/public-api/aya-obj.txt index 2fd11620..b767ea65 100644 --- a/xtask/public-api/aya-obj.txt +++ b/xtask/public-api/aya-obj.txt @@ -7190,6 +7190,8 @@ pub aya_obj::obj::ProgramSection::FEntry pub aya_obj::obj::ProgramSection::FEntry::sleepable: bool pub aya_obj::obj::ProgramSection::FExit pub aya_obj::obj::ProgramSection::FExit::sleepable: bool +pub aya_obj::obj::ProgramSection::Iter +pub aya_obj::obj::ProgramSection::Iter::sleepable: bool pub aya_obj::obj::ProgramSection::KProbe pub aya_obj::obj::ProgramSection::KRetProbe pub aya_obj::obj::ProgramSection::LircMode2 @@ -8050,6 +8052,8 @@ pub aya_obj::ProgramSection::FEntry pub aya_obj::ProgramSection::FEntry::sleepable: bool pub aya_obj::ProgramSection::FExit pub aya_obj::ProgramSection::FExit::sleepable: bool +pub aya_obj::ProgramSection::Iter +pub aya_obj::ProgramSection::Iter::sleepable: bool pub aya_obj::ProgramSection::KProbe pub aya_obj::ProgramSection::KRetProbe pub aya_obj::ProgramSection::LircMode2 diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 7e5cb7a7..e3275163 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -3632,6 +3632,157 @@ impl core::borrow::BorrowMut for aya::programs::fexit::FExitLinkId where T pub fn aya::programs::fexit::FExitLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::fexit::FExitLinkId pub fn aya::programs::fexit::FExitLinkId::from(t: T) -> T +pub mod aya::programs::iter +pub struct aya::programs::iter::Iter +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::attach(&mut self) -> core::result::Result +pub fn aya::programs::iter::Iter::detach(&mut self, link_id: aya::programs::iter::IterLinkId) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::Iter::load(&mut self, iter_type: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::Iter::take_link(&mut self, link_id: aya::programs::iter::IterLinkId) -> core::result::Result +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError> +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::from_pin>(path: P) -> core::result::Result +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::info(&self) -> core::result::Result +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +pub fn aya::programs::iter::Iter::unpin(self) -> core::result::Result<(), std::io::error::Error> +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError> +impl core::fmt::Debug for aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::ops::drop::Drop for aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::drop(&mut self) +impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::iter::Iter +pub type &'a aya::programs::iter::Iter::Error = aya::programs::ProgramError +pub fn &'a aya::programs::iter::Iter::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::iter::Iter, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::iter::Iter +pub type &'a mut aya::programs::iter::Iter::Error = aya::programs::ProgramError +pub fn &'a mut aya::programs::iter::Iter::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::iter::Iter, aya::programs::ProgramError> +impl core::marker::Freeze for aya::programs::iter::Iter +impl core::marker::Send for aya::programs::iter::Iter +impl core::marker::Sync for aya::programs::iter::Iter +impl core::marker::Unpin for aya::programs::iter::Iter +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::iter::Iter +impl core::panic::unwind_safe::UnwindSafe for aya::programs::iter::Iter +impl core::convert::Into for aya::programs::iter::Iter where U: core::convert::From +pub fn aya::programs::iter::Iter::into(self) -> U +impl core::convert::TryFrom for aya::programs::iter::Iter where U: core::convert::Into +pub type aya::programs::iter::Iter::Error = core::convert::Infallible +pub fn aya::programs::iter::Iter::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::iter::Iter where U: core::convert::TryFrom +pub type aya::programs::iter::Iter::Error = >::Error +pub fn aya::programs::iter::Iter::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::iter::Iter where T: 'static + core::marker::Sized +pub fn aya::programs::iter::Iter::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::iter::Iter where T: core::marker::Sized +pub fn aya::programs::iter::Iter::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::iter::Iter where T: core::marker::Sized +pub fn aya::programs::iter::Iter::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::from(t: T) -> T +pub struct aya::programs::iter::IterFd +impl core::fmt::Debug for aya::programs::iter::IterFd +pub fn aya::programs::iter::IterFd::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl std::os::fd::owned::AsFd for aya::programs::iter::IterFd +pub fn aya::programs::iter::IterFd::as_fd(&self) -> std::os::fd::owned::BorrowedFd<'_> +impl core::marker::Freeze for aya::programs::iter::IterFd +impl core::marker::Send for aya::programs::iter::IterFd +impl core::marker::Sync for aya::programs::iter::IterFd +impl core::marker::Unpin for aya::programs::iter::IterFd +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::iter::IterFd +impl core::panic::unwind_safe::UnwindSafe for aya::programs::iter::IterFd +impl core::convert::Into for aya::programs::iter::IterFd where U: core::convert::From +pub fn aya::programs::iter::IterFd::into(self) -> U +impl core::convert::TryFrom for aya::programs::iter::IterFd where U: core::convert::Into +pub type aya::programs::iter::IterFd::Error = core::convert::Infallible +pub fn aya::programs::iter::IterFd::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::iter::IterFd where U: core::convert::TryFrom +pub type aya::programs::iter::IterFd::Error = >::Error +pub fn aya::programs::iter::IterFd::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::iter::IterFd where T: 'static + core::marker::Sized +pub fn aya::programs::iter::IterFd::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::iter::IterFd where T: core::marker::Sized +pub fn aya::programs::iter::IterFd::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::iter::IterFd where T: core::marker::Sized +pub fn aya::programs::iter::IterFd::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::iter::IterFd +pub fn aya::programs::iter::IterFd::from(t: T) -> T +pub struct aya::programs::iter::IterLink(_) +impl aya::programs::iter::IterLink +pub fn aya::programs::iter::IterLink::into_async_io_file(self) -> core::result::Result +pub fn aya::programs::iter::IterLink::into_file(self) -> core::result::Result +pub fn aya::programs::iter::IterLink::into_tokio_file(self) -> core::result::Result +impl aya::programs::links::Link for aya::programs::iter::IterLink +pub type aya::programs::iter::IterLink::Id = aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::IterLink::id(&self) -> Self::Id +impl core::convert::TryFrom for aya::programs::links::FdLink +pub type aya::programs::links::FdLink::Error = aya::programs::links::LinkError +pub fn aya::programs::links::FdLink::try_from(value: aya::programs::iter::IterLink) -> core::result::Result +impl core::convert::TryFrom for aya::programs::iter::IterLink +pub type aya::programs::iter::IterLink::Error = aya::programs::links::LinkError +pub fn aya::programs::iter::IterLink::try_from(fd_link: aya::programs::links::FdLink) -> core::result::Result +impl core::fmt::Debug for aya::programs::iter::IterLink +pub fn aya::programs::iter::IterLink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::ops::drop::Drop for aya::programs::iter::IterLink +pub fn aya::programs::iter::IterLink::drop(&mut self) +impl core::marker::Freeze for aya::programs::iter::IterLink +impl core::marker::Send for aya::programs::iter::IterLink +impl core::marker::Sync for aya::programs::iter::IterLink +impl core::marker::Unpin for aya::programs::iter::IterLink +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::iter::IterLink +impl core::panic::unwind_safe::UnwindSafe for aya::programs::iter::IterLink +impl core::convert::Into for aya::programs::iter::IterLink where U: core::convert::From +pub fn aya::programs::iter::IterLink::into(self) -> U +impl core::convert::TryFrom for aya::programs::iter::IterLink where U: core::convert::Into +pub type aya::programs::iter::IterLink::Error = core::convert::Infallible +pub fn aya::programs::iter::IterLink::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::iter::IterLink where U: core::convert::TryFrom +pub type aya::programs::iter::IterLink::Error = >::Error +pub fn aya::programs::iter::IterLink::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::iter::IterLink where T: 'static + core::marker::Sized +pub fn aya::programs::iter::IterLink::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::iter::IterLink where T: core::marker::Sized +pub fn aya::programs::iter::IterLink::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::iter::IterLink where T: core::marker::Sized +pub fn aya::programs::iter::IterLink::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::iter::IterLink +pub fn aya::programs::iter::IterLink::from(t: T) -> T +pub struct aya::programs::iter::IterLinkId(_) +impl core::cmp::Eq for aya::programs::iter::IterLinkId +impl core::cmp::PartialEq for aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLinkId::eq(&self, other: &aya::programs::iter::IterLinkId) -> bool +impl core::fmt::Debug for aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLinkId::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::hash::Hash for aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLinkId::hash<__H: core::hash::Hasher>(&self, state: &mut __H) +impl core::marker::StructuralPartialEq for aya::programs::iter::IterLinkId +impl core::marker::Freeze for aya::programs::iter::IterLinkId +impl core::marker::Send for aya::programs::iter::IterLinkId +impl core::marker::Sync for aya::programs::iter::IterLinkId +impl core::marker::Unpin for aya::programs::iter::IterLinkId +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::iter::IterLinkId +impl core::panic::unwind_safe::UnwindSafe for aya::programs::iter::IterLinkId +impl equivalent::Equivalent for aya::programs::iter::IterLinkId where Q: core::cmp::Eq + core::marker::Sized, K: core::borrow::Borrow + core::marker::Sized +pub fn aya::programs::iter::IterLinkId::equivalent(&self, key: &K) -> bool +impl core::convert::Into for aya::programs::iter::IterLinkId where U: core::convert::From +pub fn aya::programs::iter::IterLinkId::into(self) -> U +impl core::convert::TryFrom for aya::programs::iter::IterLinkId where U: core::convert::Into +pub type aya::programs::iter::IterLinkId::Error = core::convert::Infallible +pub fn aya::programs::iter::IterLinkId::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::iter::IterLinkId where U: core::convert::TryFrom +pub type aya::programs::iter::IterLinkId::Error = >::Error +pub fn aya::programs::iter::IterLinkId::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::iter::IterLinkId where T: 'static + core::marker::Sized +pub fn aya::programs::iter::IterLinkId::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::iter::IterLinkId where T: core::marker::Sized +pub fn aya::programs::iter::IterLinkId::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::iter::IterLinkId where T: core::marker::Sized +pub fn aya::programs::iter::IterLinkId::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLinkId::from(t: T) -> T pub mod aya::programs::kprobe pub enum aya::programs::kprobe::KProbeError pub aya::programs::kprobe::KProbeError::FileError @@ -3902,9 +4053,15 @@ impl core::convert::From for aya::progra pub fn aya::programs::links::FdLink::from(w: aya::programs::sk_lookup::SkLookupLink) -> aya::programs::links::FdLink impl core::convert::From for aya::programs::links::FdLink pub fn aya::programs::links::FdLink::from(w: aya::programs::tp_btf::BtfTracePointLink) -> aya::programs::links::FdLink +impl core::convert::TryFrom for aya::programs::links::FdLink +pub type aya::programs::links::FdLink::Error = aya::programs::links::LinkError +pub fn aya::programs::links::FdLink::try_from(value: aya::programs::iter::IterLink) -> core::result::Result impl core::convert::TryFrom for aya::programs::links::FdLink pub type aya::programs::links::FdLink::Error = aya::programs::links::LinkError pub fn aya::programs::links::FdLink::try_from(value: aya::programs::kprobe::KProbeLink) -> core::result::Result +impl core::convert::TryFrom for aya::programs::iter::IterLink +pub type aya::programs::iter::IterLink::Error = aya::programs::links::LinkError +pub fn aya::programs::iter::IterLink::try_from(fd_link: aya::programs::links::FdLink) -> core::result::Result impl core::convert::TryFrom for aya::programs::kprobe::KProbeLink pub type aya::programs::kprobe::KProbeLink::Error = aya::programs::links::LinkError pub fn aya::programs::kprobe::KProbeLink::try_from(fd_link: aya::programs::links::FdLink) -> core::result::Result @@ -4174,6 +4331,10 @@ impl aya::programs::links::Link for aya::programs::fexit::FExitLink pub type aya::programs::fexit::FExitLink::Id = aya::programs::fexit::FExitLinkId pub fn aya::programs::fexit::FExitLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::fexit::FExitLink::id(&self) -> Self::Id +impl aya::programs::links::Link for aya::programs::iter::IterLink +pub type aya::programs::iter::IterLink::Id = aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::IterLink::id(&self) -> Self::Id impl aya::programs::links::Link for aya::programs::kprobe::KProbeLink pub type aya::programs::kprobe::KProbeLink::Id = aya::programs::kprobe::KProbeLinkId pub fn aya::programs::kprobe::KProbeLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> @@ -6818,6 +6979,7 @@ pub aya::programs::Program::CgroupSysctl(aya::programs::cgroup_sysctl::CgroupSys pub aya::programs::Program::Extension(aya::programs::extension::Extension) pub aya::programs::Program::FEntry(aya::programs::fentry::FEntry) pub aya::programs::Program::FExit(aya::programs::fexit::FExit) +pub aya::programs::Program::Iter(aya::programs::iter::Iter) pub aya::programs::Program::KProbe(aya::programs::kprobe::KProbe) pub aya::programs::Program::LircMode2(aya::programs::lirc_mode2::LircMode2) pub aya::programs::Program::Lsm(aya::programs::lsm::Lsm) @@ -6867,6 +7029,9 @@ pub fn &'a aya::programs::fentry::FEntry::try_from(program: &'a aya::programs::P impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::fexit::FExit pub type &'a aya::programs::fexit::FExit::Error = aya::programs::ProgramError pub fn &'a aya::programs::fexit::FExit::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::fexit::FExit, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::iter::Iter +pub type &'a aya::programs::iter::Iter::Error = aya::programs::ProgramError +pub fn &'a aya::programs::iter::Iter::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::iter::Iter, aya::programs::ProgramError> impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::kprobe::KProbe pub type &'a aya::programs::kprobe::KProbe::Error = aya::programs::ProgramError pub fn &'a aya::programs::kprobe::KProbe::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::kprobe::KProbe, aya::programs::ProgramError> @@ -6939,6 +7104,9 @@ pub fn &'a mut aya::programs::fentry::FEntry::try_from(program: &'a mut aya::pro impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::fexit::FExit pub type &'a mut aya::programs::fexit::FExit::Error = aya::programs::ProgramError pub fn &'a mut aya::programs::fexit::FExit::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::fexit::FExit, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::iter::Iter +pub type &'a mut aya::programs::iter::Iter::Error = aya::programs::ProgramError +pub fn &'a mut aya::programs::iter::Iter::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::iter::Iter, aya::programs::ProgramError> impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::kprobe::KProbe pub type &'a mut aya::programs::kprobe::KProbe::Error = aya::programs::ProgramError pub fn &'a mut aya::programs::kprobe::KProbe::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::kprobe::KProbe, aya::programs::ProgramError> @@ -7949,6 +8117,55 @@ impl core::borrow::BorrowMut for aya::programs::fexit::FExit where T: core pub fn aya::programs::fexit::FExit::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::fexit::FExit pub fn aya::programs::fexit::FExit::from(t: T) -> T +pub struct aya::programs::Iter +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::attach(&mut self) -> core::result::Result +pub fn aya::programs::iter::Iter::detach(&mut self, link_id: aya::programs::iter::IterLinkId) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::Iter::load(&mut self, iter_type: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::Iter::take_link(&mut self, link_id: aya::programs::iter::IterLinkId) -> core::result::Result +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError> +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::from_pin>(path: P) -> core::result::Result +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::info(&self) -> core::result::Result +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +pub fn aya::programs::iter::Iter::unpin(self) -> core::result::Result<(), std::io::error::Error> +impl aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError> +impl core::fmt::Debug for aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::ops::drop::Drop for aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::drop(&mut self) +impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::iter::Iter +pub type &'a aya::programs::iter::Iter::Error = aya::programs::ProgramError +pub fn &'a aya::programs::iter::Iter::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::iter::Iter, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::iter::Iter +pub type &'a mut aya::programs::iter::Iter::Error = aya::programs::ProgramError +pub fn &'a mut aya::programs::iter::Iter::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::iter::Iter, aya::programs::ProgramError> +impl core::marker::Freeze for aya::programs::iter::Iter +impl core::marker::Send for aya::programs::iter::Iter +impl core::marker::Sync for aya::programs::iter::Iter +impl core::marker::Unpin for aya::programs::iter::Iter +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::iter::Iter +impl core::panic::unwind_safe::UnwindSafe for aya::programs::iter::Iter +impl core::convert::Into for aya::programs::iter::Iter where U: core::convert::From +pub fn aya::programs::iter::Iter::into(self) -> U +impl core::convert::TryFrom for aya::programs::iter::Iter where U: core::convert::Into +pub type aya::programs::iter::Iter::Error = core::convert::Infallible +pub fn aya::programs::iter::Iter::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::iter::Iter where U: core::convert::TryFrom +pub type aya::programs::iter::Iter::Error = >::Error +pub fn aya::programs::iter::Iter::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::iter::Iter where T: 'static + core::marker::Sized +pub fn aya::programs::iter::Iter::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::iter::Iter where T: core::marker::Sized +pub fn aya::programs::iter::Iter::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::iter::Iter where T: core::marker::Sized +pub fn aya::programs::iter::Iter::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::iter::Iter +pub fn aya::programs::iter::Iter::from(t: T) -> T pub struct aya::programs::KProbe impl aya::programs::kprobe::KProbe pub fn aya::programs::kprobe::KProbe::attach>(&mut self, fn_name: T, offset: u64) -> core::result::Result @@ -8927,6 +9144,10 @@ impl aya::programs::links::Link for aya::programs::fexit::FExitLink pub type aya::programs::fexit::FExitLink::Id = aya::programs::fexit::FExitLinkId pub fn aya::programs::fexit::FExitLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::fexit::FExitLink::id(&self) -> Self::Id +impl aya::programs::links::Link for aya::programs::iter::IterLink +pub type aya::programs::iter::IterLink::Id = aya::programs::iter::IterLinkId +pub fn aya::programs::iter::IterLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::iter::IterLink::id(&self) -> Self::Id impl aya::programs::links::Link for aya::programs::kprobe::KProbeLink pub type aya::programs::kprobe::KProbeLink::Id = aya::programs::kprobe::KProbeLinkId pub fn aya::programs::kprobe::KProbeLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError>