From b2b52aac9eb63c73371c52805ed382b8d9ff1f31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Medina?= Date: Thu, 20 Jul 2023 00:33:21 -0700 Subject: [PATCH] aya: Use `OwnedFd` when loading BTF fd This fixes an existing file descriptor leak when there is BTF data in the loaded object. There is a required breaking change in that now the btf fd will be passed in the programs and maps when loading them instead of them storing a raw fd to them as to avoid the maps/programs needing to be tied by lifetime to the btf fd (since they aren't needed at load time). To avoid lifetime issues caused by the bpf object owning both the btf fd and the map of programs/maps but needing to reference the fd while mutating the programs these fields are now made public. As far as I can tell there are no safety issues with making these fields public, the only issue would be tying that struct's public API more. I did make the structure non exhaustive so that adding fields wouldn't become a breaking change. --- README.md | 2 +- aya/README.md | 2 +- aya/src/bpf.rs | 134 ++++++++++++------ aya/src/maps/bloom_filter.rs | 9 -- aya/src/maps/hash_map/hash_map.rs | 22 --- aya/src/maps/lpm_trie.rs | 12 -- aya/src/maps/mod.rs | 24 ++-- aya/src/maps/sock/sock_hash.rs | 2 +- aya/src/maps/sock/sock_map.rs | 4 +- aya/src/programs/cgroup_device.rs | 17 ++- aya/src/programs/cgroup_skb.rs | 17 ++- aya/src/programs/cgroup_sock.rs | 17 ++- aya/src/programs/cgroup_sock_addr.rs | 17 ++- aya/src/programs/cgroup_sockopt.rs | 17 ++- aya/src/programs/cgroup_sysctl.rs | 17 ++- aya/src/programs/extension.rs | 30 ++-- aya/src/programs/fentry.rs | 21 ++- aya/src/programs/fexit.rs | 21 ++- aya/src/programs/kprobe.rs | 17 ++- aya/src/programs/links.rs | 4 +- aya/src/programs/lirc_mode2.rs | 16 ++- aya/src/programs/lsm.rs | 21 ++- aya/src/programs/mod.rs | 23 +-- aya/src/programs/perf_event.rs | 16 ++- aya/src/programs/raw_trace_point.rs | 16 ++- aya/src/programs/sk_lookup.rs | 16 ++- aya/src/programs/sk_msg.rs | 16 ++- aya/src/programs/sk_skb.rs | 20 ++- aya/src/programs/sock_ops.rs | 16 ++- aya/src/programs/socket_filter.rs | 16 ++- aya/src/programs/tc.rs | 16 ++- aya/src/programs/tp_btf.rs | 21 ++- aya/src/programs/trace_point.rs | 16 ++- aya/src/programs/uprobe.rs | 15 +- aya/src/programs/xdp.rs | 23 ++- aya/src/sys/bpf.rs | 19 +-- .../src/tests/bpf_probe_read.rs | 5 +- .../src/tests/btf_relocations.rs | 6 +- test/integration-test/src/tests/load.rs | 29 ++-- test/integration-test/src/tests/log.rs | 4 +- .../integration-test/src/tests/relocations.rs | 5 +- test/integration-test/src/tests/smoke.rs | 8 +- 42 files changed, 496 insertions(+), 253 deletions(-) diff --git a/README.md b/README.md index de31ec77..8f154fe8 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ use aya::programs::{CgroupSkb, CgroupSkbAttachType}; let mut bpf = Bpf::load_file("bpf.o")?; // get the `ingress_filter` program compiled into `bpf.o`. -let ingress: &mut CgroupSkb = bpf.program_mut("ingress_filter")?.try_into()?; +let mut ingress: aya::WithBtfFd = bpf.program_mut("ingress_filter")?.try_into()?; // load the program into the kernel ingress.load()?; diff --git a/aya/README.md b/aya/README.md index 873612af..a24109c1 100644 --- a/aya/README.md +++ b/aya/README.md @@ -82,7 +82,7 @@ use aya::programs::{CgroupSkb, CgroupSkbAttachType}; let mut bpf = Bpf::load_file("bpf.o")?; // get the `ingress_filter` program compiled into `bpf.o`. -let ingress: &mut CgroupSkb = bpf.program_mut("ingress_filter")?.try_into()?; +let mut ingress: aya::WithBtfFd = bpf.program_mut("ingress_filter")?.try_into()?; // load the program into the kernel ingress.load()?; diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 818a063b..7fa55c6a 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -3,7 +3,11 @@ use std::{ collections::{HashMap, HashSet}, ffi::CString, fs, io, - os::{fd::RawFd, raw::c_int}, + ops::{Deref, DerefMut}, + os::{ + fd::{AsFd, BorrowedFd, OwnedFd, RawFd}, + raw::c_int, + }, path::{Path, PathBuf}, }; @@ -473,7 +477,6 @@ impl<'a> BpfLoader<'a> { obj, fd: None, pinned: false, - btf_fd, }; let fd = match map.obj.pinning() { PinningType::ByName => { @@ -488,7 +491,7 @@ impl<'a> BpfLoader<'a> { fd as RawFd } Err(_) => { - let fd = map.create(&name)?; + let fd = map.create(&name, btf_fd.as_ref())?; map.pin(&name, path).map_err(|error| MapError::PinError { name: Some(name.to_string()), error, @@ -497,7 +500,7 @@ impl<'a> BpfLoader<'a> { } } } - PinningType::None => map.create(&name)?, + PinningType::None => map.create(&name, btf_fd.as_ref())?, }; if !map.obj.data().is_empty() && map.obj.section_kind() != BpfSectionKind::Bss { bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data_mut().as_mut_ptr(), 0) @@ -545,70 +548,69 @@ impl<'a> BpfLoader<'a> { let program = if extensions.contains(name.as_str()) { Program::Extension(Extension { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }) } else { match §ion { ProgramSection::KProbe { .. } => Program::KProbe(KProbe { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), kind: ProbeKind::KProbe, }), ProgramSection::KRetProbe { .. } => Program::KProbe(KProbe { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), kind: ProbeKind::KRetProbe, }), ProgramSection::UProbe { .. } => Program::UProbe(UProbe { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), kind: ProbeKind::UProbe, }), ProgramSection::URetProbe { .. } => Program::UProbe(UProbe { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), kind: ProbeKind::URetProbe, }), ProgramSection::TracePoint { .. } => Program::TracePoint(TracePoint { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::SocketFilter { .. } => { Program::SocketFilter(SocketFilter { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }) } ProgramSection::Xdp { frags, .. } => { - let mut data = - ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level); + let mut data = ProgramData::new(prog_name, obj, *verifier_log_level); if *frags { data.flags = BPF_F_XDP_HAS_FRAGS; } Program::Xdp(Xdp { data }) } ProgramSection::SkMsg { .. } => Program::SkMsg(SkMsg { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::CgroupSysctl { .. } => { Program::CgroupSysctl(CgroupSysctl { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }) } ProgramSection::CgroupSockopt { attach_type, .. } => { Program::CgroupSockopt(CgroupSockopt { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), attach_type: *attach_type, }) } ProgramSection::SkSkbStreamParser { .. } => Program::SkSkb(SkSkb { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), kind: SkSkbKind::StreamParser, }), ProgramSection::SkSkbStreamVerdict { .. } => Program::SkSkb(SkSkb { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), kind: SkSkbKind::StreamVerdict, }), ProgramSection::SockOps { .. } => Program::SockOps(SockOps { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::SchedClassifier { .. } => { Program::SchedClassifier(SchedClassifier { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), name: unsafe { CString::from_vec_unchecked(Vec::from(name.clone())) .into_boxed_c_str() @@ -616,37 +618,36 @@ impl<'a> BpfLoader<'a> { }) } ProgramSection::CgroupSkb { .. } => Program::CgroupSkb(CgroupSkb { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), expected_attach_type: None, }), ProgramSection::CgroupSkbIngress { .. } => Program::CgroupSkb(CgroupSkb { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), expected_attach_type: Some(CgroupSkbAttachType::Ingress), }), ProgramSection::CgroupSkbEgress { .. } => Program::CgroupSkb(CgroupSkb { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), expected_attach_type: Some(CgroupSkbAttachType::Egress), }), ProgramSection::CgroupSockAddr { attach_type, .. } => { Program::CgroupSockAddr(CgroupSockAddr { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), attach_type: *attach_type, }) } ProgramSection::LircMode2 { .. } => Program::LircMode2(LircMode2 { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::PerfEvent { .. } => Program::PerfEvent(PerfEvent { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::RawTracePoint { .. } => { Program::RawTracePoint(RawTracePoint { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }) } ProgramSection::Lsm { sleepable, .. } => { - let mut data = - ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level); + let mut data = ProgramData::new(prog_name, obj, *verifier_log_level); if *sleepable { data.flags = BPF_F_SLEEPABLE; } @@ -654,30 +655,30 @@ impl<'a> BpfLoader<'a> { } ProgramSection::BtfTracePoint { .. } => { Program::BtfTracePoint(BtfTracePoint { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }) } ProgramSection::FEntry { .. } => Program::FEntry(FEntry { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::FExit { .. } => Program::FExit(FExit { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::Extension { .. } => Program::Extension(Extension { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::SkLookup { .. } => Program::SkLookup(SkLookup { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }), ProgramSection::CgroupSock { attach_type, .. } => { Program::CgroupSock(CgroupSock { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), attach_type: *attach_type, }) } ProgramSection::CgroupDevice { .. } => { Program::CgroupDevice(CgroupDevice { - data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + data: ProgramData::new(prog_name, obj, *verifier_log_level), }) } } @@ -699,7 +700,11 @@ impl<'a> BpfLoader<'a> { })?; }; - Ok(Bpf { maps, programs }) + Ok(Bpf { + maps, + programs, + btf_fd, + }) } } @@ -741,11 +746,53 @@ impl<'a> Default for BpfLoader<'a> { } } +/// A program with a BTF file descriptor +pub struct WithBtfFd<'p, P> { + /// The program underneath + pub program: &'p mut P, + pub(crate) btf_fd: Option>, +} + +impl<'f, P> Deref for WithBtfFd<'f, P> { + type Target = P; + + fn deref(&self) -> &Self::Target { + &*self.program + } +} + +impl<'f, P> DerefMut for WithBtfFd<'f, P> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.program + } +} + +impl<'p, P, T> AsRef for WithBtfFd<'p, P> +where + T: ?Sized, + as Deref>::Target: AsRef, +{ + fn as_ref(&self) -> &T { + self.deref().as_ref() + } +} + +impl<'p, P, T> AsMut for WithBtfFd<'p, P> +where + as Deref>::Target: AsMut, +{ + fn as_mut(&mut self) -> &mut T { + self.deref_mut().as_mut() + } +} + /// The main entry point into the library, used to work with eBPF programs and maps. #[derive(Debug)] +#[non_exhaustive] pub struct Bpf { maps: HashMap, programs: HashMap, + btf_fd: Option, } impl Bpf { @@ -882,13 +929,16 @@ impl Bpf { /// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::programs::UProbe; /// - /// let program: &mut UProbe = bpf.program_mut("SSL_read").unwrap().try_into()?; + /// let mut program: aya::WithBtfFd = bpf.program_mut("SSL_read").unwrap().try_into()?; /// program.load()?; /// program.attach(Some("SSL_read"), 0, "libssl", None)?; /// # Ok::<(), aya::BpfError>(()) /// ``` - pub fn program_mut(&mut self, name: &str) -> Option<&mut Program> { - self.programs.get_mut(name) + pub fn program_mut(&mut self, name: &str) -> Option> { + self.programs.get_mut(name).map(|program| WithBtfFd { + program, + btf_fd: self.btf_fd.as_ref().map(|p| p.as_fd()), + }) } /// An iterator over all the programs. @@ -993,12 +1043,12 @@ pub enum BpfError { ProgramError(#[from] ProgramError), } -fn load_btf(raw_btf: Vec, verifier_log_level: VerifierLogLevel) -> Result { +fn load_btf(raw_btf: Vec, verifier_log_level: VerifierLogLevel) -> Result { let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| { bpf_load_btf(raw_btf.as_slice(), logger, verifier_log_level) }); match ret { - Ok(fd) => Ok(fd as RawFd), + Ok(fd) => Ok(fd), Err((_, io_error)) => Err(BtfError::LoadError { io_error, verifier_log, diff --git a/aya/src/maps/bloom_filter.rs b/aya/src/maps/bloom_filter.rs index f646c2bb..93df55fe 100644 --- a/aya/src/maps/bloom_filter.rs +++ b/aya/src/maps/bloom_filter.rs @@ -118,7 +118,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( BloomFilter::<_, u16>::new(&map), @@ -147,7 +146,6 @@ mod tests { }), fd: None, pinned: false, - btf_fd: None, }; let map = Map::PerfEventArray(map_data); @@ -164,7 +162,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( @@ -179,7 +176,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; assert!(BloomFilter::<_, u32>::new(&mut map).is_ok()); @@ -191,7 +187,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let map = Map::BloomFilter(map_data); @@ -206,7 +201,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let bloom_filter = BloomFilter::<_, u32>::new(&mut map).unwrap(); @@ -230,7 +224,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let bloom_filter = BloomFilter::<_, u32>::new(&mut map).unwrap(); @@ -244,7 +237,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let bloom_filter = BloomFilter::<_, u32>::new(&map).unwrap(); @@ -267,7 +259,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let bloom_filter = BloomFilter::<_, u32>::new(&map).unwrap(); diff --git a/aya/src/maps/hash_map/hash_map.rs b/aya/src/maps/hash_map/hash_map.rs index 2fcb1334..93b6228d 100644 --- a/aya/src/maps/hash_map/hash_map.rs +++ b/aya/src/maps/hash_map/hash_map.rs @@ -149,7 +149,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( HashMap::<_, u8, u32>::new(&map), @@ -166,7 +165,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( HashMap::<_, u32, u16>::new(&map), @@ -183,7 +181,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; let map = Map::Array(map_data); @@ -199,7 +196,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; let map = Map::HashMap(map_data); @@ -218,7 +214,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( @@ -233,7 +228,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; assert!(HashMap::<_, u32, u32>::new(&mut map).is_ok()); @@ -245,7 +239,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let map = Map::HashMap(map_data); @@ -270,7 +263,6 @@ mod tests { }), fd: Some(42), pinned: false, - btf_fd: None, }; let map = Map::HashMap(map_data); @@ -286,7 +278,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut hm = HashMap::<_, u32, u32>::new(&mut map).unwrap(); @@ -310,7 +301,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut hm = HashMap::<_, u32, u32>::new(&mut map).unwrap(); @@ -331,7 +321,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut hm = HashMap::<_, u32, u32>::new(&mut map).unwrap(); @@ -346,7 +335,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut hm = HashMap::<_, u32, u32>::new(&mut map).unwrap(); @@ -370,7 +358,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut hm = HashMap::<_, u32, u32>::new(&mut map).unwrap(); @@ -384,7 +371,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); @@ -407,7 +393,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); @@ -444,7 +429,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); let keys = hm.keys().collect::, _>>(); @@ -493,7 +477,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); @@ -526,7 +509,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); @@ -561,7 +543,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); let items = hm.iter().collect::, _>>().unwrap(); @@ -599,7 +580,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); @@ -638,7 +618,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); @@ -683,7 +662,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); diff --git a/aya/src/maps/lpm_trie.rs b/aya/src/maps/lpm_trie.rs index 4adb3f47..55c7f3b9 100644 --- a/aya/src/maps/lpm_trie.rs +++ b/aya/src/maps/lpm_trie.rs @@ -237,7 +237,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( LpmTrie::<_, u16, u32>::new(&map), @@ -254,7 +253,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( LpmTrie::<_, u32, u16>::new(&map), @@ -282,7 +280,6 @@ mod tests { data: Vec::new(), }), fd: None, - btf_fd: None, pinned: false, }; @@ -300,7 +297,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, }; assert_matches!( @@ -315,7 +311,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; assert!(LpmTrie::<_, u32, u32>::new(&mut map).is_ok()); @@ -327,7 +322,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let map = Map::LpmTrie(map_data); @@ -342,7 +336,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap(); let ipaddr = Ipv4Addr::new(8, 8, 8, 8); @@ -367,7 +360,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap(); @@ -384,7 +376,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap(); let ipaddr = Ipv4Addr::new(8, 8, 8, 8); @@ -409,7 +400,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let mut trie = LpmTrie::<_, u32, u32>::new(&mut map).unwrap(); let ipaddr = Ipv4Addr::new(8, 8, 8, 8); @@ -424,7 +414,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let trie = LpmTrie::<_, u32, u32>::new(&map).unwrap(); let ipaddr = Ipv4Addr::new(8, 8, 8, 8); @@ -449,7 +438,6 @@ mod tests { obj: new_obj_map(), fd: Some(42), pinned: false, - btf_fd: None, }; let trie = LpmTrie::<_, u32, u32>::new(&map).unwrap(); let ipaddr = Ipv4Addr::new(8, 8, 8, 8); diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index fca42110..d4f2fac0 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -24,7 +24,7 @@ //! //! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?; //! let map_fd = intercept_egress.fd()?; -//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; +//! let mut prog: aya::WithBtfFd = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; //! prog.load()?; //! prog.attach(map_fd)?; //! @@ -42,7 +42,7 @@ use std::{ marker::PhantomData, mem, ops::Deref, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, path::Path, ptr, }; @@ -486,14 +486,13 @@ pub(crate) fn check_v_size(map: &MapData) -> Result<(), MapError> { pub struct MapData { pub(crate) obj: obj::Map, pub(crate) fd: Option, - pub(crate) btf_fd: Option, /// Indicates if this map has been pinned to bpffs pub pinned: bool, } impl MapData { /// Creates a new map with the provided `name` - pub fn create(&mut self, name: &str) -> Result { + pub fn create(&mut self, name: &str, btf_fd: Option) -> Result { if self.fd.is_some() { return Err(MapError::AlreadyCreated { name: name.into() }); } @@ -504,7 +503,7 @@ impl MapData { let kernel_version = KernelVersion::current().unwrap(); #[cfg(test)] let kernel_version = KernelVersion::new(0xff, 0xff, 0xff); - let fd = bpf_create_map(&c_name, &self.obj, self.btf_fd, kernel_version).map_err( + let fd = bpf_create_map(&c_name, &self.obj, btf_fd, kernel_version).map_err( |(code, io_error)| { if kernel_version < KernelVersion::new(5, 11, 0) { maybe_warn_rlimit(); @@ -568,7 +567,6 @@ impl MapData { Ok(MapData { obj: parse_map_info(info, PinningType::ByName), fd: Some(fd), - btf_fd: None, pinned: true, }) } @@ -587,7 +585,6 @@ impl MapData { Ok(MapData { obj: parse_map_info(info, PinningType::None), fd: Some(fd), - btf_fd: None, pinned: false, }) } @@ -639,7 +636,6 @@ impl Clone for MapData { MapData { obj: self.obj.clone(), fd: self.fd.map(|fd| unsafe { libc::dup(fd) }), - btf_fd: self.btf_fd, pinned: self.pinned, } } @@ -842,6 +838,8 @@ impl Deref for PerCpuValues { #[cfg(test)] mod tests { + use std::os::fd::BorrowedFd; + use assert_matches::assert_matches; use libc::EFAULT; @@ -876,7 +874,6 @@ mod tests { obj: new_obj_map(), fd: None, pinned: false, - btf_fd: None, } } @@ -891,9 +888,12 @@ mod tests { }); let mut map = new_map(); - assert_matches!(map.create("foo"), Ok(42)); + assert_matches!(map.create("foo", Option::::None), Ok(42)); assert_eq!(map.fd, Some(42)); - assert_matches!(map.create("foo"), Err(MapError::AlreadyCreated { .. })); + assert_matches!( + map.create("foo", Option::::None), + Err(MapError::AlreadyCreated { .. }) + ); } #[test] @@ -901,7 +901,7 @@ mod tests { override_syscall(|_| Err((-42, io::Error::from_raw_os_error(EFAULT)))); let mut map = new_map(); - let ret = map.create("foo"); + let ret = map.create("foo", Option::::None); assert_matches!(ret, Err(MapError::CreateError { .. })); if let Err(MapError::CreateError { name, diff --git a/aya/src/maps/sock/sock_hash.rs b/aya/src/maps/sock/sock_hash.rs index be78e386..360b0b38 100644 --- a/aya/src/maps/sock/sock_hash.rs +++ b/aya/src/maps/sock/sock_hash.rs @@ -49,7 +49,7 @@ use crate::{ /// let mut intercept_egress = SockHash::<_, u32>::try_from(bpf.map("INTERCEPT_EGRESS").unwrap())?; /// let map_fd = intercept_egress.fd()?; /// -/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(map_fd)?; /// diff --git a/aya/src/maps/sock/sock_map.rs b/aya/src/maps/sock/sock_map.rs index d34f658b..2e6b27e2 100644 --- a/aya/src/maps/sock/sock_map.rs +++ b/aya/src/maps/sock/sock_map.rs @@ -17,7 +17,7 @@ use crate::{ /// sockets. /// /// A `SockMap` can also be used to redirect packets to sockets contained by the -/// map using `bpf_redirect_map()`, `bpf_sk_redirect_map()` etc. +/// map using `bpf_redirect_map()`, `bpf_sk_redirect_map()` etc. /// /// # Minimum kernel version /// @@ -33,7 +33,7 @@ use crate::{ /// let intercept_ingress = SockMap::try_from(bpf.map("INTERCEPT_INGRESS").unwrap())?; /// let map_fd = intercept_ingress.fd()?; /// -/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(map_fd)?; /// diff --git a/aya/src/programs/cgroup_device.rs b/aya/src/programs/cgroup_device.rs index e3580b28..78a504ee 100644 --- a/aya/src/programs/cgroup_device.rs +++ b/aya/src/programs/cgroup_device.rs @@ -1,7 +1,7 @@ //! Cgroup device programs. -use crate::util::KernelVersion; -use std::os::fd::{AsRawFd, RawFd}; +use crate::{util::KernelVersion, WithBtfFd}; +use std::os::fd::{AsFd, AsRawFd, RawFd}; use crate::{ generated::{bpf_attach_type::BPF_CGROUP_DEVICE, bpf_prog_type::BPF_PROG_TYPE_CGROUP_DEVICE}, @@ -40,7 +40,7 @@ use crate::{ /// use aya::programs::CgroupDevice; /// /// let cgroup = std::fs::File::open("/sys/fs/cgroup/unified")?; -/// let program: &mut CgroupDevice = bpf.program_mut("cgroup_dev").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("cgroup_dev").unwrap().try_into()?; /// program.load()?; /// program.attach(cgroup)?; /// # Ok::<(), Error>(()) @@ -51,10 +51,17 @@ pub struct CgroupDevice { pub(crate) data: ProgramData, } +impl<'p> WithBtfFd<'p, CgroupDevice> { + /// Loads the program inside the kernel. + pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + impl CgroupDevice { /// Loads the program inside the kernel - pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_CGROUP_DEVICE, &mut self.data) + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_CGROUP_DEVICE, &mut self.data, btf_fd) } /// Attaches the program to the given cgroup. diff --git a/aya/src/programs/cgroup_skb.rs b/aya/src/programs/cgroup_skb.rs index f67b56fe..6ce5aca7 100644 --- a/aya/src/programs/cgroup_skb.rs +++ b/aya/src/programs/cgroup_skb.rs @@ -1,9 +1,9 @@ //! Cgroup skb programs. -use crate::util::KernelVersion; +use crate::{util::KernelVersion, WithBtfFd}; use std::{ hash::Hash, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, path::Path, }; @@ -50,7 +50,7 @@ use crate::{ /// use aya::programs::{CgroupSkb, CgroupSkbAttachType}; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let egress: &mut CgroupSkb = bpf.program_mut("egress_filter").unwrap().try_into()?; +/// let mut egress: aya::WithBtfFd = bpf.program_mut("egress_filter").unwrap().try_into()?; /// egress.load()?; /// egress.attach(file, CgroupSkbAttachType::Egress)?; /// # Ok::<(), Error>(()) @@ -62,16 +62,23 @@ pub struct CgroupSkb { pub(crate) expected_attach_type: Option, } -impl CgroupSkb { +impl<'p> WithBtfFd<'p, CgroupSkb> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + +impl CgroupSkb { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { self.data.expected_attach_type = self.expected_attach_type .map(|attach_type| match attach_type { CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS, CgroupSkbAttachType::Egress => BPF_CGROUP_INET_EGRESS, }); - load_program(BPF_PROG_TYPE_CGROUP_SKB, &mut self.data) + load_program(BPF_PROG_TYPE_CGROUP_SKB, &mut self.data, btf_fd) } /// Returns the expected attach type of the program. diff --git a/aya/src/programs/cgroup_sock.rs b/aya/src/programs/cgroup_sock.rs index 9d66f9aa..4288e64b 100644 --- a/aya/src/programs/cgroup_sock.rs +++ b/aya/src/programs/cgroup_sock.rs @@ -2,10 +2,10 @@ pub use aya_obj::programs::CgroupSockAttachType; -use crate::util::KernelVersion; +use crate::{util::KernelVersion, WithBtfFd}; use std::{ hash::Hash, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, path::Path, }; @@ -48,7 +48,7 @@ use crate::{ /// use aya::programs::{CgroupSock, CgroupSockAttachType}; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let bind: &mut CgroupSock = bpf.program_mut("bind").unwrap().try_into()?; +/// let mut bind: aya::WithBtfFd = bpf.program_mut("bind").unwrap().try_into()?; /// bind.load()?; /// bind.attach(file)?; /// # Ok::<(), Error>(()) @@ -60,11 +60,18 @@ pub struct CgroupSock { pub(crate) attach_type: CgroupSockAttachType, } -impl CgroupSock { +impl<'p> WithBtfFd<'p, CgroupSock> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + +impl CgroupSock { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(self.attach_type.into()); - load_program(BPF_PROG_TYPE_CGROUP_SOCK, &mut self.data) + load_program(BPF_PROG_TYPE_CGROUP_SOCK, &mut self.data, btf_fd) } /// Attaches the program to the given cgroup. diff --git a/aya/src/programs/cgroup_sock_addr.rs b/aya/src/programs/cgroup_sock_addr.rs index 045a40d2..c51110f2 100644 --- a/aya/src/programs/cgroup_sock_addr.rs +++ b/aya/src/programs/cgroup_sock_addr.rs @@ -2,10 +2,10 @@ pub use aya_obj::programs::CgroupSockAddrAttachType; -use crate::util::KernelVersion; +use crate::{util::KernelVersion, WithBtfFd}; use std::{ hash::Hash, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, path::Path, }; @@ -49,7 +49,7 @@ use crate::{ /// use aya::programs::{CgroupSockAddr, CgroupSockAddrAttachType}; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let egress: &mut CgroupSockAddr = bpf.program_mut("connect4").unwrap().try_into()?; +/// let mut egress: aya::WithBtfFd = bpf.program_mut("connect4").unwrap().try_into()?; /// egress.load()?; /// egress.attach(file)?; /// # Ok::<(), Error>(()) @@ -61,11 +61,18 @@ pub struct CgroupSockAddr { pub(crate) attach_type: CgroupSockAddrAttachType, } -impl CgroupSockAddr { +impl<'p> WithBtfFd<'p, CgroupSockAddr> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + +impl CgroupSockAddr { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(self.attach_type.into()); - load_program(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, &mut self.data) + load_program(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, &mut self.data, btf_fd) } /// Attaches the program to the given cgroup. diff --git a/aya/src/programs/cgroup_sockopt.rs b/aya/src/programs/cgroup_sockopt.rs index 95b89dd7..7b4dbb3a 100644 --- a/aya/src/programs/cgroup_sockopt.rs +++ b/aya/src/programs/cgroup_sockopt.rs @@ -2,10 +2,10 @@ pub use aya_obj::programs::CgroupSockoptAttachType; -use crate::util::KernelVersion; +use crate::{util::KernelVersion, WithBtfFd}; use std::{ hash::Hash, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, path::Path, }; @@ -46,7 +46,7 @@ use crate::{ /// use aya::programs::CgroupSockopt; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let program: &mut CgroupSockopt = bpf.program_mut("cgroup_sockopt").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("cgroup_sockopt").unwrap().try_into()?; /// program.load()?; /// program.attach(file)?; /// # Ok::<(), Error>(()) @@ -58,11 +58,18 @@ pub struct CgroupSockopt { pub(crate) attach_type: CgroupSockoptAttachType, } -impl CgroupSockopt { +impl<'p> WithBtfFd<'p, CgroupSockopt> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + +impl CgroupSockopt { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(self.attach_type.into()); - load_program(BPF_PROG_TYPE_CGROUP_SOCKOPT, &mut self.data) + load_program(BPF_PROG_TYPE_CGROUP_SOCKOPT, &mut self.data, btf_fd) } /// Attaches the program to the given cgroup. diff --git a/aya/src/programs/cgroup_sysctl.rs b/aya/src/programs/cgroup_sysctl.rs index 3cd20195..2990c1d5 100644 --- a/aya/src/programs/cgroup_sysctl.rs +++ b/aya/src/programs/cgroup_sysctl.rs @@ -1,9 +1,9 @@ //! Cgroup sysctl programs. -use crate::util::KernelVersion; +use crate::{util::KernelVersion, WithBtfFd}; use std::{ hash::Hash, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, }; use crate::{ @@ -42,7 +42,7 @@ use crate::{ /// use aya::programs::CgroupSysctl; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let program: &mut CgroupSysctl = bpf.program_mut("cgroup_sysctl").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("cgroup_sysctl").unwrap().try_into()?; /// program.load()?; /// program.attach(file)?; /// # Ok::<(), Error>(()) @@ -53,10 +53,17 @@ pub struct CgroupSysctl { pub(crate) data: ProgramData, } -impl CgroupSysctl { +impl<'p> WithBtfFd<'p, CgroupSysctl> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_CGROUP_SYSCTL, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl CgroupSysctl { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_CGROUP_SYSCTL, &mut self.data, btf_fd) } /// Attaches the program to the given cgroup. diff --git a/aya/src/programs/extension.rs b/aya/src/programs/extension.rs index 682d14ad..0dbe3aeb 100644 --- a/aya/src/programs/extension.rs +++ b/aya/src/programs/extension.rs @@ -1,5 +1,5 @@ //! Extension programs. -use std::os::fd::{AsRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, RawFd}; use thiserror::Error; use object::Endianness; @@ -11,7 +11,7 @@ use crate::{ define_link_wrapper, load_program, FdLink, FdLinkId, ProgramData, ProgramError, ProgramFd, }, sys::{self, bpf_link_create}, - Btf, + Btf, WithBtfFd, }; /// The type returned when loading or attaching an [`Extension`] fails. @@ -37,12 +37,12 @@ pub enum ExtensionError { /// use aya::{BpfLoader, programs::{Xdp, XdpFlags, Extension}}; /// /// let mut bpf = BpfLoader::new().extension("extension").load_file("app.o")?; -/// let prog: &mut Xdp = bpf.program_mut("main").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("main").unwrap().try_into()?; /// prog.load()?; /// prog.attach("eth0", XdpFlags::default())?; /// /// let prog_fd = prog.fd().unwrap(); -/// let ext: &mut Extension = bpf.program_mut("extension").unwrap().try_into()?; +/// let mut ext: aya::WithBtfFd = bpf.program_mut("extension").unwrap().try_into()?; /// ext.load(prog_fd, "function_to_replace")?; /// ext.attach()?; /// Ok::<(), aya::BpfError>(()) @@ -53,6 +53,13 @@ pub struct Extension { pub(crate) data: ProgramData, } +impl<'p> WithBtfFd<'p, Extension> { + /// Loads the program inside the kernel. + pub fn load(&mut self, program: ProgramFd, func_name: &str) -> Result<(), ProgramError> { + self.program.load(program, func_name, self.btf_fd) + } +} + impl Extension { /// Loads the extension inside the kernel. /// @@ -68,14 +75,19 @@ impl Extension { /// The extension code will be loaded but inactive until it's attached. /// There are no restrictions on what functions may be replaced, so you could replace /// the main entry point of your program with an extension. - pub fn load(&mut self, program: ProgramFd, func_name: &str) -> Result<(), ProgramError> { + pub fn load( + &mut self, + program: ProgramFd, + func_name: &str, + btf_fd: Option, + ) -> Result<(), ProgramError> { let target_prog_fd = program.as_raw_fd(); - let (btf_fd, btf_id) = get_btf_info(target_prog_fd, func_name)?; + let (prog_btf_fd, prog_btf_id) = get_btf_info(target_prog_fd, func_name)?; - self.data.attach_btf_obj_fd = Some(btf_fd as u32); + self.data.attach_btf_obj_fd = Some(prog_btf_fd as u32); self.data.attach_prog_fd = Some(target_prog_fd); - self.data.attach_btf_id = Some(btf_id); - load_program(BPF_PROG_TYPE_EXT, &mut self.data) + self.data.attach_btf_id = Some(prog_btf_id); + load_program(BPF_PROG_TYPE_EXT, &mut self.data, btf_fd) } /// Attaches the extension. diff --git a/aya/src/programs/fentry.rs b/aya/src/programs/fentry.rs index 8f59061a..adaa130f 100644 --- a/aya/src/programs/fentry.rs +++ b/aya/src/programs/fentry.rs @@ -1,5 +1,7 @@ //! Fentry programs. +use std::os::fd::AsFd; + use crate::{ generated::{bpf_attach_type::BPF_TRACE_FENTRY, bpf_prog_type::BPF_PROG_TYPE_TRACING}, obj::btf::{Btf, BtfKind}, @@ -7,6 +9,7 @@ use crate::{ define_link_wrapper, load_program, utils::attach_raw_tracepoint, FdLink, FdLinkId, ProgramData, ProgramError, }, + WithBtfFd, }; /// A program that can be attached to the entry point of (almost) any kernel @@ -37,7 +40,7 @@ use crate::{ /// use aya::{Bpf, programs::FEntry, BtfError, Btf}; /// /// let btf = Btf::from_sys_fs()?; -/// let program: &mut FEntry = bpf.program_mut("filename_lookup").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("filename_lookup").unwrap().try_into()?; /// program.load("filename_lookup", &btf)?; /// program.attach()?; /// # Ok::<(), Error>(()) @@ -49,16 +52,28 @@ pub struct FEntry { pub(crate) data: ProgramData, } +impl<'p> WithBtfFd<'p, FEntry> { + /// Loads the program inside the kernel. + pub fn load(&mut self, fn_name: &str, btf: &Btf) -> Result<(), ProgramError> { + self.program.load(fn_name, btf, self.btf_fd) + } +} + impl FEntry { /// Loads the program inside the kernel. /// /// Loads the program so it's executed when the kernel function `fn_name` /// is entered. The `btf` argument must contain the BTF info for the /// running kernel. - pub fn load(&mut self, fn_name: &str, btf: &Btf) -> Result<(), ProgramError> { + pub fn load( + &mut self, + fn_name: &str, + btf: &Btf, + btf_fd: Option, + ) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(BPF_TRACE_FENTRY); self.data.attach_btf_id = Some(btf.id_by_type_name_kind(fn_name, BtfKind::Func)?); - load_program(BPF_PROG_TYPE_TRACING, &mut self.data) + load_program(BPF_PROG_TYPE_TRACING, &mut self.data, btf_fd) } /// Attaches the program. diff --git a/aya/src/programs/fexit.rs b/aya/src/programs/fexit.rs index ba2e1f1b..50213a5a 100644 --- a/aya/src/programs/fexit.rs +++ b/aya/src/programs/fexit.rs @@ -1,5 +1,7 @@ //! Fexit programs. +use std::os::fd::AsFd; + use crate::{ generated::{bpf_attach_type::BPF_TRACE_FEXIT, bpf_prog_type::BPF_PROG_TYPE_TRACING}, obj::btf::{Btf, BtfKind}, @@ -7,6 +9,7 @@ use crate::{ define_link_wrapper, load_program, utils::attach_raw_tracepoint, FdLink, FdLinkId, ProgramData, ProgramError, }, + WithBtfFd, }; /// A program that can be attached to the exit point of (almost) anny kernel @@ -37,7 +40,7 @@ use crate::{ /// use aya::{Bpf, programs::FExit, BtfError, Btf}; /// /// let btf = Btf::from_sys_fs()?; -/// let program: &mut FExit = bpf.program_mut("filename_lookup").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("filename_lookup").unwrap().try_into()?; /// program.load("filename_lookup", &btf)?; /// program.attach()?; /// # Ok::<(), Error>(()) @@ -49,16 +52,28 @@ pub struct FExit { pub(crate) data: ProgramData, } +impl<'p> WithBtfFd<'p, FExit> { + /// Loads the program inside the kernel. + pub fn load(&mut self, fn_name: &str, btf: &Btf) -> Result<(), ProgramError> { + self.program.load(fn_name, btf, self.btf_fd) + } +} + impl FExit { /// Loads the program inside the kernel. /// /// Loads the program so it's executed when the kernel function `fn_name` /// is exited. The `btf` argument must contain the BTF info for the running /// kernel. - pub fn load(&mut self, fn_name: &str, btf: &Btf) -> Result<(), ProgramError> { + pub fn load( + &mut self, + fn_name: &str, + btf: &Btf, + btf_fd: Option, + ) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(BPF_TRACE_FEXIT); self.data.attach_btf_id = Some(btf.id_by_type_name_kind(fn_name, BtfKind::Func)?); - load_program(BPF_PROG_TYPE_TRACING, &mut self.data) + load_program(BPF_PROG_TYPE_TRACING, &mut self.data, btf_fd) } /// Attaches the program. diff --git a/aya/src/programs/kprobe.rs b/aya/src/programs/kprobe.rs index a61f084f..0509238b 100644 --- a/aya/src/programs/kprobe.rs +++ b/aya/src/programs/kprobe.rs @@ -1,5 +1,5 @@ //! Kernel space probes. -use std::{io, path::Path}; +use std::{io, os::fd::AsFd, path::Path}; use thiserror::Error; use crate::{ @@ -11,7 +11,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, }, sys::bpf_link_get_info_by_fd, - VerifierLogLevel, + VerifierLogLevel, WithBtfFd, }; /// A kernel probe. @@ -32,7 +32,7 @@ use crate::{ /// # let mut bpf = Bpf::load_file("ebpf_programs.o")?; /// use aya::{Bpf, programs::KProbe}; /// -/// let program: &mut KProbe = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; /// program.load()?; /// program.attach("try_to_wake_up", 0)?; /// # Ok::<(), aya::BpfError>(()) @@ -44,10 +44,17 @@ pub struct KProbe { pub(crate) kind: ProbeKind, } -impl KProbe { +impl<'p> WithBtfFd<'p, KProbe> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl KProbe { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_KPROBE, &mut self.data, btf_fd) } /// Returns `KProbe` if the program is a `kprobe`, or `KRetProbe` if the diff --git a/aya/src/programs/links.rs b/aya/src/programs/links.rs index debe7b49..4052449d 100644 --- a/aya/src/programs/links.rs +++ b/aya/src/programs/links.rs @@ -97,7 +97,7 @@ pub struct FdLinkId(pub(crate) RawFd); /// # let mut bpf = Bpf::load_file("ebpf_programs.o")?; /// use aya::{Bpf, programs::{links::FdLink, KProbe}}; /// -/// let program: &mut KProbe = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; /// program.load()?; /// let link_id = program.attach("try_to_wake_up", 0)?; /// let link = program.take_link(link_id).unwrap(); @@ -138,7 +138,7 @@ impl FdLink { /// # Program(#[from] aya::programs::ProgramError) /// # } /// # let mut bpf = aya::Bpf::load(&[])?; - /// # let prog: &mut Extension = bpf.program_mut("example").unwrap().try_into()?; + /// # let mut prog: aya::WithBtfFd = bpf.program_mut("example").unwrap().try_into()?; /// let link_id = prog.attach()?; /// let owned_link = prog.take_link(link_id)?; /// let fd_link: FdLink = owned_link.into(); diff --git a/aya/src/programs/lirc_mode2.rs b/aya/src/programs/lirc_mode2.rs index ce40eaaa..2361955d 100644 --- a/aya/src/programs/lirc_mode2.rs +++ b/aya/src/programs/lirc_mode2.rs @@ -1,10 +1,11 @@ //! Lirc programs. -use std::os::fd::{AsRawFd, IntoRawFd as _, RawFd}; +use std::os::fd::{AsFd, AsRawFd, IntoRawFd as _, RawFd}; use crate::{ generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2}, programs::{load_program, query, Link, ProgramData, ProgramError, ProgramInfo}, sys::{bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd}, + WithBtfFd, }; use libc::{close, dup}; @@ -40,7 +41,7 @@ use libc::{close, dup}; /// /// let file = File::open("/dev/lirc0")?; /// let mut bpf = aya::Bpf::load_file("imon_rsc.o")?; -/// let decoder: &mut LircMode2 = bpf.program_mut("imon_rsc").unwrap().try_into().unwrap(); +/// let mut decoder: aya::WithBtfFd = bpf.program_mut("imon_rsc").unwrap().try_into().unwrap(); /// decoder.load()?; /// decoder.attach(file)?; /// # Ok::<(), Error>(()) @@ -51,10 +52,17 @@ pub struct LircMode2 { pub(crate) data: ProgramData, } -impl LircMode2 { +impl<'p> WithBtfFd<'p, LircMode2> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_LIRC_MODE2, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl LircMode2 { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_LIRC_MODE2, &mut self.data, btf_fd) } /// Attaches the program to the given lirc device. diff --git a/aya/src/programs/lsm.rs b/aya/src/programs/lsm.rs index 3a455707..d1c409ab 100644 --- a/aya/src/programs/lsm.rs +++ b/aya/src/programs/lsm.rs @@ -1,5 +1,7 @@ //! LSM probes. +use std::os::fd::AsFd; + use crate::{ generated::{bpf_attach_type::BPF_LSM_MAC, bpf_prog_type::BPF_PROG_TYPE_LSM}, obj::btf::{Btf, BtfKind}, @@ -7,6 +9,7 @@ use crate::{ define_link_wrapper, load_program, utils::attach_raw_tracepoint, FdLink, FdLinkId, ProgramData, ProgramError, }, + WithBtfFd, }; /// A program that attaches to Linux LSM hooks. Used to implement security policy and @@ -39,7 +42,7 @@ use crate::{ /// use aya::{Bpf, programs::Lsm, BtfError, Btf}; /// /// let btf = Btf::from_sys_fs()?; -/// let program: &mut Lsm = bpf.program_mut("lsm_prog").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("lsm_prog").unwrap().try_into()?; /// program.load("security_bprm_exec", &btf)?; /// program.attach()?; /// # Ok::<(), LsmError>(()) @@ -52,6 +55,13 @@ pub struct Lsm { pub(crate) data: ProgramData, } +impl<'p> WithBtfFd<'p, Lsm> { + /// Loads the program inside the kernel. + pub fn load(&mut self, lsm_hook_name: &str, btf: &Btf) -> Result<(), ProgramError> { + self.program.load(lsm_hook_name, btf, self.btf_fd) + } +} + impl Lsm { /// Loads the program inside the kernel. /// @@ -59,12 +69,17 @@ impl Lsm { /// /// * `lsm_hook_name` - full name of the LSM hook that the program should /// be attached to - pub fn load(&mut self, lsm_hook_name: &str, btf: &Btf) -> Result<(), ProgramError> { + pub fn load( + &mut self, + lsm_hook_name: &str, + btf: &Btf, + btf_fd: Option, + ) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(BPF_LSM_MAC); let type_name = format!("bpf_lsm_{lsm_hook_name}"); self.data.attach_btf_id = Some(btf.id_by_type_name_kind(type_name.as_str(), BtfKind::Func)?); - load_program(BPF_PROG_TYPE_LSM, &mut self.data) + load_program(BPF_PROG_TYPE_LSM, &mut self.data, btf_fd) } /// Attaches the program. diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index f868dfc8..46bbf7d7 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -18,7 +18,7 @@ //! //! let mut bpf = Bpf::load_file("ebpf_programs.o")?; //! // intercept_wakeups is the name of the program we want to load -//! let program: &mut KProbe = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; +//! let mut program: aya::WithBtfFd = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; //! program.load()?; //! // intercept_wakeups will be called every time try_to_wake_up() is called //! // inside the kernel @@ -69,7 +69,7 @@ use libc::ENOSPC; use std::{ ffi::CString, io, - os::fd::{AsRawFd, IntoRawFd as _, RawFd}, + os::fd::{AsFd, AsRawFd, IntoRawFd as _, RawFd}, path::{Path, PathBuf}, }; use thiserror::Error; @@ -413,7 +413,6 @@ pub(crate) struct ProgramData { pub(crate) attach_btf_obj_fd: Option, pub(crate) attach_btf_id: Option, pub(crate) attach_prog_fd: Option, - pub(crate) btf_fd: Option, pub(crate) verifier_log_level: VerifierLogLevel, pub(crate) path: Option, pub(crate) flags: u32, @@ -423,7 +422,6 @@ impl ProgramData { pub(crate) fn new( name: Option, obj: (obj::Program, obj::Function), - btf_fd: Option, verifier_log_level: VerifierLogLevel, ) -> ProgramData { ProgramData { @@ -435,7 +433,6 @@ impl ProgramData { attach_btf_obj_fd: None, attach_btf_id: None, attach_prog_fd: None, - btf_fd, verifier_log_level, path: None, flags: 0, @@ -475,7 +472,6 @@ impl ProgramData { attach_btf_obj_fd, attach_btf_id, attach_prog_fd: None, - btf_fd: None, verifier_log_level, path: Some(path.to_path_buf()), flags: 0, @@ -546,6 +542,7 @@ fn pin_program>(data: &ProgramData, path: P) -> Resul fn load_program( prog_type: bpf_prog_type, data: &mut ProgramData, + btf_fd: Option, ) -> Result<(), ProgramError> { let ProgramData { name, @@ -556,7 +553,6 @@ fn load_program( attach_btf_obj_fd, attach_btf_id, attach_prog_fd, - btf_fd, verifier_log_level, path: _, flags, @@ -613,7 +609,7 @@ fn load_program( license, kernel_version: target_kernel_version, expected_attach_type: *expected_attach_type, - prog_btf_fd: *btf_fd, + prog_btf_fd: btf_fd.as_ref().map(|f| f.as_fd()), attach_btf_obj_fd: *attach_btf_obj_fd, attach_btf_id: *attach_btf_id, attach_prog_fd: *attach_prog_fd, @@ -885,6 +881,17 @@ macro_rules! impl_try_from_program { } } } + + impl<'a> TryFrom<$crate::WithBtfFd<'a, Program>> for $crate::bpf::WithBtfFd<'a, $ty> { + type Error = ProgramError; + + fn try_from(program: $crate::WithBtfFd<'a, Program>) -> Result<$crate::WithBtfFd<'a, $ty>, ProgramError> { + Ok($crate::bpf::WithBtfFd { + program: program.program.try_into()?, + btf_fd: program.btf_fd + }) + } + } )+ } } diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index 5de7eeef..9e0fb12b 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -1,5 +1,7 @@ //! Perf event programs. +use std::os::fd::AsFd; + pub use crate::generated::{ perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, }; @@ -20,6 +22,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, }, sys::{bpf_link_get_info_by_fd, perf_event_open}, + WithBtfFd, }; /// The type of perf event @@ -105,7 +108,7 @@ pub enum PerfEventScope { /// perf_sw_ids::PERF_COUNT_SW_CPU_CLOCK, PerfEvent, PerfEventScope, PerfTypeId, SamplePolicy, /// }; /// -/// let prog: &mut PerfEvent = bpf.program_mut("observe_cpu_clock").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("observe_cpu_clock").unwrap().try_into()?; /// prog.load()?; /// /// for cpu in online_cpus()? { @@ -124,10 +127,17 @@ pub struct PerfEvent { pub(crate) data: ProgramData, } -impl PerfEvent { +impl<'p> WithBtfFd<'p, PerfEvent> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_PERF_EVENT, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl PerfEvent { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_PERF_EVENT, &mut self.data, btf_fd) } /// Attaches to the given perf event. diff --git a/aya/src/programs/raw_trace_point.rs b/aya/src/programs/raw_trace_point.rs index af451e59..f1c3654c 100644 --- a/aya/src/programs/raw_trace_point.rs +++ b/aya/src/programs/raw_trace_point.rs @@ -1,5 +1,5 @@ //! Raw tracepoints. -use std::ffi::CString; +use std::{ffi::CString, os::fd::AsFd}; use crate::{ generated::bpf_prog_type::BPF_PROG_TYPE_RAW_TRACEPOINT, @@ -7,6 +7,7 @@ use crate::{ define_link_wrapper, load_program, utils::attach_raw_tracepoint, FdLink, FdLinkId, ProgramData, ProgramError, }, + WithBtfFd, }; /// A program that can be attached at a pre-defined kernel trace point, but also @@ -27,7 +28,7 @@ use crate::{ /// # let mut bpf = Bpf::load_file("ebpf_programs.o")?; /// use aya::{Bpf, programs::RawTracePoint}; /// -/// let program: &mut RawTracePoint = bpf.program_mut("sys_enter").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("sys_enter").unwrap().try_into()?; /// program.load()?; /// program.attach("sys_enter")?; /// # Ok::<(), aya::BpfError>(()) @@ -38,10 +39,17 @@ pub struct RawTracePoint { pub(crate) data: ProgramData, } -impl RawTracePoint { +impl<'p> WithBtfFd<'p, RawTracePoint> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_RAW_TRACEPOINT, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl RawTracePoint { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_RAW_TRACEPOINT, &mut self.data, btf_fd) } /// Attaches the program to the given tracepoint. diff --git a/aya/src/programs/sk_lookup.rs b/aya/src/programs/sk_lookup.rs index 27d60b8f..837b9c17 100644 --- a/aya/src/programs/sk_lookup.rs +++ b/aya/src/programs/sk_lookup.rs @@ -1,9 +1,10 @@ -use std::os::fd::{AsRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, RawFd}; use crate::{ generated::{bpf_attach_type::BPF_SK_LOOKUP, bpf_prog_type::BPF_PROG_TYPE_SK_LOOKUP}, programs::{define_link_wrapper, load_program, FdLinkId, ProgramData, ProgramError}, sys::bpf_link_create, + WithBtfFd, }; use super::links::FdLink; @@ -39,7 +40,7 @@ use super::links::FdLink; /// use aya::programs::SkLookup; /// /// let file = File::open("/var/run/netns/test")?; -/// let program: &mut SkLookup = bpf.program_mut("sk_lookup").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("sk_lookup").unwrap().try_into()?; /// program.load()?; /// program.attach(file)?; /// # Ok::<(), Error>(()) @@ -50,11 +51,18 @@ pub struct SkLookup { pub(crate) data: ProgramData, } -impl SkLookup { +impl<'p> WithBtfFd<'p, SkLookup> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + +impl SkLookup { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(BPF_SK_LOOKUP); - load_program(BPF_PROG_TYPE_SK_LOOKUP, &mut self.data) + load_program(BPF_PROG_TYPE_SK_LOOKUP, &mut self.data, btf_fd) } /// Attaches the program to the given network namespace. diff --git a/aya/src/programs/sk_msg.rs b/aya/src/programs/sk_msg.rs index fc6202ba..c5fdaac4 100644 --- a/aya/src/programs/sk_msg.rs +++ b/aya/src/programs/sk_msg.rs @@ -1,6 +1,6 @@ //! Skmsg programs. -use std::os::fd::AsRawFd; +use std::os::fd::{AsFd, AsRawFd}; use crate::{ generated::{bpf_attach_type::BPF_SK_MSG_VERDICT, bpf_prog_type::BPF_PROG_TYPE_SK_MSG}, @@ -10,6 +10,7 @@ use crate::{ ProgramError, }, sys::bpf_prog_attach, + WithBtfFd, }; /// A program used to intercept messages sent with `sendmsg()`/`sendfile()`. @@ -46,7 +47,7 @@ use crate::{ /// let intercept_egress: SockHash<_, u32> = bpf.map("INTERCEPT_EGRESS").unwrap().try_into()?; /// let map_fd = intercept_egress.fd()?; /// -/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(map_fd)?; /// @@ -69,10 +70,17 @@ pub struct SkMsg { pub(crate) data: ProgramData, } -impl SkMsg { +impl<'p> WithBtfFd<'p, SkMsg> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SK_MSG, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl SkMsg { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SK_MSG, &mut self.data, btf_fd) } /// Attaches the program to the given sockmap. diff --git a/aya/src/programs/sk_skb.rs b/aya/src/programs/sk_skb.rs index 162d74d0..f23707cc 100644 --- a/aya/src/programs/sk_skb.rs +++ b/aya/src/programs/sk_skb.rs @@ -1,6 +1,9 @@ //! Skskb programs. -use std::{os::fd::AsRawFd, path::Path}; +use std::{ + os::fd::{AsFd, AsRawFd}, + path::Path, +}; use crate::{ generated::{ @@ -13,7 +16,7 @@ use crate::{ ProgramError, }, sys::bpf_prog_attach, - VerifierLogLevel, + VerifierLogLevel, WithBtfFd, }; /// The kind of [`SkSkb`] program. @@ -45,7 +48,7 @@ pub enum SkSkbKind { /// let intercept_ingress: SockMap<_> = bpf.map("INTERCEPT_INGRESS").unwrap().try_into()?; /// let map_fd = intercept_ingress.fd()?; /// -/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(map_fd)?; /// @@ -62,10 +65,17 @@ pub struct SkSkb { pub(crate) kind: SkSkbKind, } -impl SkSkb { +impl<'p> WithBtfFd<'p, SkSkb> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SK_SKB, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl SkSkb { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SK_SKB, &mut self.data, btf_fd) } /// Attaches the program to the given socket map. diff --git a/aya/src/programs/sock_ops.rs b/aya/src/programs/sock_ops.rs index fe8dccc0..847c68f1 100644 --- a/aya/src/programs/sock_ops.rs +++ b/aya/src/programs/sock_ops.rs @@ -1,5 +1,5 @@ //! Socket option programs. -use std::os::fd::AsRawFd; +use std::os::fd::{AsFd, AsRawFd}; use crate::{ generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS}, @@ -8,6 +8,7 @@ use crate::{ ProgramError, }, sys::bpf_prog_attach, + WithBtfFd, }; /// A program used to work with sockets. @@ -39,7 +40,7 @@ use crate::{ /// use aya::programs::SockOps; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let prog: &mut SockOps = bpf.program_mut("intercept_active_sockets").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("intercept_active_sockets").unwrap().try_into()?; /// prog.load()?; /// prog.attach(file)?; /// # Ok::<(), Error>(()) @@ -49,10 +50,17 @@ pub struct SockOps { pub(crate) data: ProgramData, } -impl SockOps { +impl<'p> WithBtfFd<'p, SockOps> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SOCK_OPS, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl SockOps { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SOCK_OPS, &mut self.data, btf_fd) } /// Attaches the program to the given cgroup. diff --git a/aya/src/programs/socket_filter.rs b/aya/src/programs/socket_filter.rs index 5ff9a301..41daa799 100644 --- a/aya/src/programs/socket_filter.rs +++ b/aya/src/programs/socket_filter.rs @@ -2,13 +2,14 @@ use libc::{setsockopt, SOL_SOCKET}; use std::{ io, mem, - os::fd::{AsRawFd, RawFd}, + os::fd::{AsFd, AsRawFd, RawFd}, }; use thiserror::Error; use crate::{ generated::{bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER, SO_ATTACH_BPF, SO_DETACH_BPF}, programs::{load_program, Link, ProgramData, ProgramError}, + WithBtfFd, }; /// The type returned when attaching a [`SocketFilter`] fails. @@ -52,7 +53,7 @@ pub enum SocketFilterError { /// use aya::programs::SocketFilter; /// /// let mut client = TcpStream::connect("127.0.0.1:1234")?; -/// let prog: &mut SocketFilter = bpf.program_mut("filter_packets").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("filter_packets").unwrap().try_into()?; /// prog.load()?; /// prog.attach(client.as_raw_fd())?; /// # Ok::<(), Error>(()) @@ -63,10 +64,17 @@ pub struct SocketFilter { pub(crate) data: ProgramData, } -impl SocketFilter { +impl<'p> WithBtfFd<'p, SocketFilter> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SOCKET_FILTER, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl SocketFilter { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SOCKET_FILTER, &mut self.data, btf_fd) } /// Attaches the filter on the given socket. diff --git a/aya/src/programs/tc.rs b/aya/src/programs/tc.rs index fad633a3..63b7e49f 100644 --- a/aya/src/programs/tc.rs +++ b/aya/src/programs/tc.rs @@ -4,6 +4,7 @@ use thiserror::Error; use std::{ ffi::{CStr, CString}, io, + os::fd::AsFd, path::Path, }; @@ -17,7 +18,7 @@ use crate::{ netlink_qdisc_detach, }, util::{ifindex_from_ifname, tc_handler_make}, - VerifierLogLevel, + VerifierLogLevel, WithBtfFd, }; /// Traffic control attach type. @@ -63,7 +64,7 @@ pub enum TcAttachType { /// // attached /// tc::qdisc_add_clsact("eth0")?; /// -/// let prog: &mut SchedClassifier = bpf.program_mut("redirect_ingress").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("redirect_ingress").unwrap().try_into()?; /// prog.load()?; /// prog.attach("eth0", TcAttachType::Ingress)?; /// @@ -112,10 +113,17 @@ pub struct TcOptions { pub handle: u32, } -impl SchedClassifier { +impl<'p> WithBtfFd<'p, SchedClassifier> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl SchedClassifier { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data, btf_fd) } /// Attaches the program to the given `interface` using the default options. diff --git a/aya/src/programs/tp_btf.rs b/aya/src/programs/tp_btf.rs index eb419ab1..92025b88 100644 --- a/aya/src/programs/tp_btf.rs +++ b/aya/src/programs/tp_btf.rs @@ -1,5 +1,7 @@ //! BTF-enabled raw tracepoints. +use std::os::fd::AsFd; + use crate::{ generated::{bpf_attach_type::BPF_TRACE_RAW_TP, bpf_prog_type::BPF_PROG_TYPE_TRACING}, obj::btf::{Btf, BtfKind}, @@ -7,6 +9,7 @@ use crate::{ define_link_wrapper, load_program, utils::attach_raw_tracepoint, FdLink, FdLinkId, ProgramData, ProgramError, }, + WithBtfFd, }; /// Marks a function as a [BTF-enabled raw tracepoint][1] eBPF program that can be attached at @@ -36,7 +39,7 @@ use crate::{ /// use aya::{Bpf, programs::BtfTracePoint, BtfError, Btf}; /// /// let btf = Btf::from_sys_fs()?; -/// let program: &mut BtfTracePoint = bpf.program_mut("sched_process_fork").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("sched_process_fork").unwrap().try_into()?; /// program.load("sched_process_fork", &btf)?; /// program.attach()?; /// # Ok::<(), Error>(()) @@ -50,6 +53,13 @@ pub struct BtfTracePoint { pub(crate) data: ProgramData, } +impl<'p> WithBtfFd<'p, BtfTracePoint> { + /// Loads the program inside the kernel. + pub fn load(&mut self, tracepoint: &str, btf: &Btf) -> Result<(), ProgramError> { + self.program.load(tracepoint, btf, self.btf_fd) + } +} + impl BtfTracePoint { /// Loads the program inside the kernel. /// @@ -57,12 +67,17 @@ impl BtfTracePoint { /// /// * `tracepoint` - full name of the tracepoint that we should attach to /// * `btf` - btf information for the target system - pub fn load(&mut self, tracepoint: &str, btf: &Btf) -> Result<(), ProgramError> { + pub fn load( + &mut self, + tracepoint: &str, + btf: &Btf, + btf_fd: Option, + ) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(BPF_TRACE_RAW_TP); let type_name = format!("btf_trace_{tracepoint}"); self.data.attach_btf_id = Some(btf.id_by_type_name_kind(type_name.as_str(), BtfKind::Typedef)?); - load_program(BPF_PROG_TYPE_TRACING, &mut self.data) + load_program(BPF_PROG_TYPE_TRACING, &mut self.data, btf_fd) } /// Attaches the program. diff --git a/aya/src/programs/trace_point.rs b/aya/src/programs/trace_point.rs index b23594b7..82462103 100644 --- a/aya/src/programs/trace_point.rs +++ b/aya/src/programs/trace_point.rs @@ -1,5 +1,5 @@ //! Tracepoint programs. -use std::{fs, io, path::Path}; +use std::{fs, io, os::fd::AsFd, path::Path}; use thiserror::Error; use crate::{ @@ -11,6 +11,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, }, sys::{bpf_link_get_info_by_fd, perf_event_open_trace_point}, + WithBtfFd, }; /// The type returned when attaching a [`TracePoint`] fails. @@ -54,7 +55,7 @@ pub enum TracePointError { /// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::programs::TracePoint; /// -/// let prog: &mut TracePoint = bpf.program_mut("trace_context_switch").unwrap().try_into()?; +/// let mut prog: aya::WithBtfFd = bpf.program_mut("trace_context_switch").unwrap().try_into()?; /// prog.load()?; /// prog.attach("sched", "sched_switch")?; /// # Ok::<(), Error>(()) @@ -65,10 +66,17 @@ pub struct TracePoint { pub(crate) data: ProgramData, } -impl TracePoint { +impl<'p> WithBtfFd<'p, TracePoint> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_TRACEPOINT, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl TracePoint { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_TRACEPOINT, &mut self.data, btf_fd) } /// Attaches to a given trace point. diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs index bab82d4b..5f8e558c 100644 --- a/aya/src/programs/uprobe.rs +++ b/aya/src/programs/uprobe.rs @@ -7,7 +7,7 @@ use std::{ fs, io::{self, BufRead, Cursor, Read}, mem, - os::raw::c_char, + os::{fd::AsFd, raw::c_char}, path::{Path, PathBuf}, sync::Arc, }; @@ -22,7 +22,7 @@ use crate::{ FdLink, LinkError, ProgramData, ProgramError, }, sys::bpf_link_get_info_by_fd, - VerifierLogLevel, + VerifierLogLevel, WithBtfFd, }; const LD_SO_CACHE_FILE: &str = "/etc/ld.so.cache"; @@ -48,10 +48,17 @@ pub struct UProbe { pub(crate) kind: ProbeKind, } -impl UProbe { +impl<'p> WithBtfFd<'p, UProbe> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { - load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) + self.program.load(self.btf_fd) + } +} + +impl UProbe { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { + load_program(BPF_PROG_TYPE_KPROBE, &mut self.data, btf_fd) } /// Returns `UProbe` if the program is a `uprobe`, or `URetProbe` if the diff --git a/aya/src/programs/xdp.rs b/aya/src/programs/xdp.rs index 9372b281..993c4ae0 100644 --- a/aya/src/programs/xdp.rs +++ b/aya/src/programs/xdp.rs @@ -1,9 +1,15 @@ //! eXpress Data Path (XDP) programs. -use crate::util::KernelVersion; +use crate::{util::KernelVersion, WithBtfFd}; use bitflags; use libc::if_nametoindex; -use std::{convert::TryFrom, ffi::CString, hash::Hash, io, mem, os::fd::RawFd}; +use std::{ + convert::TryFrom, + ffi::CString, + hash::Hash, + io, mem, + os::fd::{AsFd, RawFd}, +}; use thiserror::Error; use crate::{ @@ -66,7 +72,7 @@ bitflags! { /// # let mut bpf = Bpf::load_file("ebpf_programs.o")?; /// use aya::{Bpf, programs::{Xdp, XdpFlags}}; /// -/// let program: &mut Xdp = bpf.program_mut("intercept_packets").unwrap().try_into()?; +/// let mut program: aya::WithBtfFd = bpf.program_mut("intercept_packets").unwrap().try_into()?; /// program.attach("eth0", XdpFlags::default())?; /// # Ok::<(), aya::BpfError>(()) /// ``` @@ -76,11 +82,18 @@ pub struct Xdp { pub(crate) data: ProgramData, } -impl Xdp { +impl<'f> WithBtfFd<'f, Xdp> { /// Loads the program inside the kernel. pub fn load(&mut self) -> Result<(), ProgramError> { + self.program.load(self.btf_fd) + } +} + +impl Xdp { + /// Loads the program inside the kernel. + pub fn load(&mut self, btf_fd: Option) -> Result<(), ProgramError> { self.data.expected_attach_type = Some(bpf_attach_type::BPF_XDP); - load_program(BPF_PROG_TYPE_XDP, &mut self.data) + load_program(BPF_PROG_TYPE_XDP, &mut self.data, btf_fd) } /// Attaches the program to the given `interface`. diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index 5a26c57f..1b0c9a17 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -3,7 +3,7 @@ use std::{ ffi::{CStr, CString}, io, mem::{self, MaybeUninit}, - os::fd::{FromRawFd as _, OwnedFd, RawFd}, + os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd as _, OwnedFd, RawFd}, slice, }; @@ -35,7 +35,7 @@ use crate::{ pub(crate) fn bpf_create_map( name: &CStr, def: &obj::Map, - btf_fd: Option, + btf_fd: Option, kernel_version: KernelVersion, ) -> SysResult { let mut attr = unsafe { mem::zeroed::() }; @@ -75,7 +75,7 @@ pub(crate) fn bpf_create_map( _ => { u.btf_key_type_id = m.def.btf_key_type_id; u.btf_value_type_id = m.def.btf_value_type_id; - u.btf_fd = btf_fd.unwrap_or_default() as u32; + u.btf_fd = btf_fd.map(|fd| fd.as_fd().as_raw_fd()).unwrap_or_default() as u32; } } } @@ -115,7 +115,7 @@ pub(crate) struct BpfLoadProgramAttrs<'a> { pub(crate) license: &'a CStr, pub(crate) kernel_version: u32, pub(crate) expected_attach_type: Option, - pub(crate) prog_btf_fd: Option, + pub(crate) prog_btf_fd: Option>, pub(crate) attach_btf_obj_fd: Option, pub(crate) attach_btf_id: Option, pub(crate) attach_prog_fd: Option, @@ -161,7 +161,7 @@ pub(crate) fn bpf_load_program( let func_info_buf = aya_attr.func_info.func_info_bytes(); if let Some(btf_fd) = aya_attr.prog_btf_fd { - u.prog_btf_fd = btf_fd as u32; + u.prog_btf_fd = btf_fd.as_raw_fd() as u32; if aya_attr.line_info_rec_size > 0 { u.line_info = line_info_buf.as_ptr() as *const _ as u64; u.line_info_cnt = aya_attr.line_info.len() as u32; @@ -561,7 +561,7 @@ pub(crate) fn bpf_load_btf( raw_btf: &[u8], log_buf: &mut [u8], verifier_log_level: VerifierLogLevel, -) -> SysResult { +) -> SysResult { let mut attr = unsafe { mem::zeroed::() }; let u = unsafe { &mut attr.__bindgen_anon_7 }; u.btf = raw_btf.as_ptr() as *const _ as u64; @@ -571,7 +571,9 @@ pub(crate) fn bpf_load_btf( u.btf_log_buf = log_buf.as_mut_ptr() as u64; u.btf_log_size = log_buf.len() as u32; } - sys_bpf(bpf_cmd::BPF_BTF_LOAD, &attr) + let raw_fd = sys_bpf(bpf_cmd::BPF_BTF_LOAD, &attr)? as RawFd; + // SAFETY: BPF_BTF_LOAD returns a newly created file descriptor + Ok(unsafe { OwnedFd::from_raw_fd(raw_fd) }) } pub(crate) fn bpf_btf_get_fd_by_id(id: u32) -> Result { @@ -711,10 +713,9 @@ pub(crate) fn is_bpf_global_data_supported() -> bool { }), fd: None, pinned: false, - btf_fd: None, }; - if let Ok(map_fd) = map_data.create("aya_global") { + if let Ok(map_fd) = map_data.create("aya_global", Option::::None) { insns[0].imm = map_fd; let gpl = b"GPL\0"; diff --git a/test/integration-test/src/tests/bpf_probe_read.rs b/test/integration-test/src/tests/bpf_probe_read.rs index 22c3e9b1..cd6a8d8f 100644 --- a/test/integration-test/src/tests/bpf_probe_read.rs +++ b/test/integration-test/src/tests/bpf_probe_read.rs @@ -1,4 +1,4 @@ -use aya::{maps::Array, programs::UProbe, Bpf}; +use aya::{maps::Array, programs::UProbe, Bpf, WithBtfFd}; const RESULT_BUF_LEN: usize = 1024; @@ -104,8 +104,7 @@ fn result_bytes(bpf: &Bpf) -> Vec { fn load_and_attach_uprobe(prog_name: &str, func_name: &str, bytes: &[u8]) -> Bpf { let mut bpf = Bpf::load(bytes).unwrap(); - - let prog: &mut UProbe = bpf.program_mut(prog_name).unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut(prog_name).unwrap().try_into().unwrap(); prog.load().unwrap(); prog.attach(Some(func_name), 0, "/proc/self/exe", None) diff --git a/test/integration-test/src/tests/btf_relocations.rs b/test/integration-test/src/tests/btf_relocations.rs index 75f36223..2a286885 100644 --- a/test/integration-test/src/tests/btf_relocations.rs +++ b/test/integration-test/src/tests/btf_relocations.rs @@ -5,7 +5,9 @@ use std::{ time::Duration, }; -use aya::{maps::Array, programs::TracePoint, util::KernelVersion, BpfLoader, Btf, Endianness}; +use aya::{ + maps::Array, programs::TracePoint, util::KernelVersion, BpfLoader, Btf, Endianness, WithBtfFd, +}; // In the tests below we often use values like 0xAAAAAAAA or -0x7AAAAAAA. Those values have no // special meaning, they just have "nice" bit patterns that can be helpful while debugging. @@ -384,7 +386,7 @@ impl RelocationTestRunner { loader.btf(None); } let mut bpf = loader.load(&self.ebpf).context("Loading eBPF failed")?; - let program: &mut TracePoint = bpf + let mut program: WithBtfFd = bpf .program_mut("bpf_prog") .context("bpf_prog not found")? .try_into() diff --git a/test/integration-test/src/tests/load.rs b/test/integration-test/src/tests/load.rs index 8958ae59..92ea99c6 100644 --- a/test/integration-test/src/tests/load.rs +++ b/test/integration-test/src/tests/load.rs @@ -7,7 +7,7 @@ use aya::{ loaded_programs, KProbe, TracePoint, UProbe, Xdp, XdpFlags, }, util::KernelVersion, - Bpf, + Bpf, WithBtfFd, }; const MAX_RETRIES: u32 = 100; @@ -16,7 +16,7 @@ const RETRY_DURATION_MS: u64 = 10; #[test] fn long_name() { let mut bpf = Bpf::load(crate::NAME_TEST).unwrap(); - let name_prog: &mut Xdp = bpf + let mut name_prog: WithBtfFd = bpf .program_mut("ihaveaverylongname") .unwrap() .try_into() @@ -36,7 +36,8 @@ fn multiple_btf_maps() { let map_1: Array<_, u64> = bpf.take_map("map_1").unwrap().try_into().unwrap(); let map_2: Array<_, u64> = bpf.take_map("map_2").unwrap().try_into().unwrap(); - let prog: &mut TracePoint = bpf.program_mut("tracepoint").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = + bpf.program_mut("tracepoint").unwrap().try_into().unwrap(); prog.load().unwrap(); prog.attach("sched", "sched_switch").unwrap(); @@ -110,7 +111,7 @@ macro_rules! assert_loaded { #[test] fn unload_xdp() { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut Xdp = bpf.program_mut("test_xdp").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("test_xdp").unwrap().try_into().unwrap(); prog.load().unwrap(); assert_loaded!("test_xdp", true); let link = prog.attach("lo", XdpFlags::default()).unwrap(); @@ -135,7 +136,7 @@ fn unload_xdp() { #[test] fn unload_kprobe() { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut KProbe = bpf.program_mut("test_kprobe").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("test_kprobe").unwrap().try_into().unwrap(); prog.load().unwrap(); assert_loaded!("test_kprobe", true); let link = prog.attach("try_to_wake_up", 0).unwrap(); @@ -160,7 +161,7 @@ fn unload_kprobe() { #[test] fn basic_tracepoint() { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut TracePoint = bpf + let mut prog: WithBtfFd = bpf .program_mut("test_tracepoint") .unwrap() .try_into() @@ -191,7 +192,7 @@ fn basic_tracepoint() { #[test] fn basic_uprobe() { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut UProbe = bpf.program_mut("test_uprobe").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("test_uprobe").unwrap().try_into().unwrap(); prog.load().unwrap(); assert_loaded!("test_uprobe", true); @@ -224,7 +225,7 @@ fn pin_link() { } let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut Xdp = bpf.program_mut("test_xdp").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("test_xdp").unwrap().try_into().unwrap(); prog.load().unwrap(); let link_id = prog.attach("lo", XdpFlags::default()).unwrap(); let link = prog.take_link(link_id).unwrap(); @@ -257,7 +258,7 @@ fn pin_lifecycle() { // 1. Load Program and Pin { let mut bpf = Bpf::load(crate::PASS).unwrap(); - let prog: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("pass").unwrap().try_into().unwrap(); prog.load().unwrap(); prog.pin("/sys/fs/bpf/aya-xdp-test-prog").unwrap(); } @@ -291,7 +292,7 @@ fn pin_lifecycle() { // 4. Load a new version of the program, unpin link, and atomically replace old program { let mut bpf = Bpf::load(crate::PASS).unwrap(); - let prog: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("pass").unwrap().try_into().unwrap(); prog.load().unwrap(); let link = PinnedLink::from_pin("/sys/fs/bpf/aya-xdp-test-lo") @@ -311,7 +312,7 @@ fn pin_lifecycle_tracepoint() { // 1. Load Program and Pin { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut TracePoint = bpf + let mut prog: WithBtfFd = bpf .program_mut("test_tracepoint") .unwrap() .try_into() @@ -365,7 +366,8 @@ fn pin_lifecycle_kprobe() { // 1. Load Program and Pin { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut KProbe = bpf.program_mut("test_kprobe").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = + bpf.program_mut("test_kprobe").unwrap().try_into().unwrap(); prog.load().unwrap(); prog.pin("/sys/fs/bpf/aya-kprobe-test-prog").unwrap(); } @@ -423,7 +425,8 @@ fn pin_lifecycle_uprobe() { // 1. Load Program and Pin { let mut bpf = Bpf::load(crate::TEST).unwrap(); - let prog: &mut UProbe = bpf.program_mut("test_uprobe").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = + bpf.program_mut("test_uprobe").unwrap().try_into().unwrap(); prog.load().unwrap(); prog.pin("/sys/fs/bpf/aya-uprobe-test-prog").unwrap(); } diff --git a/test/integration-test/src/tests/log.rs b/test/integration-test/src/tests/log.rs index 8645762b..f62e0bea 100644 --- a/test/integration-test/src/tests/log.rs +++ b/test/integration-test/src/tests/log.rs @@ -3,7 +3,7 @@ use std::{ sync::{Arc, Mutex}, }; -use aya::{programs::UProbe, Bpf}; +use aya::{programs::UProbe, Bpf, WithBtfFd}; use aya_log::BpfLogger; use log::{Level, Log, Record}; @@ -60,7 +60,7 @@ async fn log() { .unwrap(); } - let prog: &mut UProbe = bpf.program_mut("test_log").unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut("test_log").unwrap().try_into().unwrap(); prog.load().unwrap(); prog.attach(Some("trigger_ebpf_program"), 0, "/proc/self/exe", None) .unwrap(); diff --git a/test/integration-test/src/tests/relocations.rs b/test/integration-test/src/tests/relocations.rs index 1b550e9f..d8636fac 100644 --- a/test/integration-test/src/tests/relocations.rs +++ b/test/integration-test/src/tests/relocations.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use aya::{programs::UProbe, Bpf}; +use aya::{programs::UProbe, Bpf, WithBtfFd}; #[test] fn relocations() { @@ -32,8 +32,7 @@ fn text_64_64_reloc() { fn load_and_attach(name: &str, bytes: &[u8]) -> Bpf { let mut bpf = Bpf::load(bytes).unwrap(); - - let prog: &mut UProbe = bpf.program_mut(name).unwrap().try_into().unwrap(); + let mut prog: WithBtfFd = bpf.program_mut(name).unwrap().try_into().unwrap(); prog.load().unwrap(); prog.attach( diff --git a/test/integration-test/src/tests/smoke.rs b/test/integration-test/src/tests/smoke.rs index 8b09ac92..bc055f27 100644 --- a/test/integration-test/src/tests/smoke.rs +++ b/test/integration-test/src/tests/smoke.rs @@ -1,7 +1,7 @@ use aya::{ programs::{Extension, Xdp, XdpFlags}, util::KernelVersion, - Bpf, BpfLoader, + Bpf, BpfLoader, WithBtfFd, }; #[test] @@ -13,7 +13,7 @@ fn xdp() { } let mut bpf = Bpf::load(crate::PASS).unwrap(); - let dispatcher: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap(); + let mut dispatcher: WithBtfFd = bpf.program_mut("pass").unwrap().try_into().unwrap(); dispatcher.load().unwrap(); dispatcher.attach("lo", XdpFlags::default()).unwrap(); } @@ -26,11 +26,11 @@ fn extension() { return; } let mut bpf = Bpf::load(crate::MAIN).unwrap(); - let pass: &mut Xdp = bpf.program_mut("pass").unwrap().try_into().unwrap(); + let mut pass: WithBtfFd = bpf.program_mut("pass").unwrap().try_into().unwrap(); pass.load().unwrap(); pass.attach("lo", XdpFlags::default()).unwrap(); let mut bpf = BpfLoader::new().extension("drop").load(crate::EXT).unwrap(); - let drop_: &mut Extension = bpf.program_mut("drop").unwrap().try_into().unwrap(); + let mut drop_: WithBtfFd = bpf.program_mut("drop").unwrap().try_into().unwrap(); drop_.load(pass.fd().unwrap(), "xdp_pass").unwrap(); }