diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index c580b299..0ae2bf61 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -2,6 +2,7 @@ use std::{ borrow::Cow, collections::HashMap, error::Error, + ffi::CString, fs, io, os::{raw::c_int, unix::io::RawFd}, path::{Path, PathBuf}, @@ -191,8 +192,8 @@ impl<'a> BpfLoader<'a> { obj.relocate_btf(btf)?; } - let mut maps = Vec::new(); - for (_, mut obj) in obj.maps.drain() { + let mut maps = HashMap::new(); + for (name, mut obj) in obj.maps.drain() { if obj.def.map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 && obj.def.max_entries == 0 { obj.def.max_entries = possible_cpus() @@ -214,21 +215,21 @@ impl<'a> BpfLoader<'a> { None => return Err(BpfError::NoPinPath), }; // try to open map in case it's already pinned - match map.from_pinned(path) { + match map.from_pinned(&name, path) { Ok(fd) => { map.pinned = true; fd as RawFd } Err(_) => { - let fd = map.create()?; - map.pin(path)?; + let fd = map.create(&name)?; + map.pin(&name, path)?; fd } } } - PinningType::None => map.create()?, + PinningType::None => map.create(&name)?, }; - if !map.obj.data.is_empty() && map.obj.name != ".bss" { + if !map.obj.data.is_empty() && name != ".bss" { bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data.as_mut_ptr(), 0).map_err( |(code, io_error)| MapError::SyscallError { call: "bpf_map_update_elem".to_owned(), @@ -237,27 +238,25 @@ impl<'a> BpfLoader<'a> { }, )?; } - maps.push(map); + maps.insert(name, map); } - obj.relocate_maps(maps.as_slice())?; + obj.relocate_maps(maps.iter().map(|(name, map)| (name.as_str(), map)))?; obj.relocate_calls()?; let programs = obj .programs .drain() .map(|(name, obj)| { - let section = obj.section.clone(); let data = ProgramData { obj, - name: name.clone(), fd: None, links: Vec::new(), expected_attach_type: None, attach_btf_obj_fd: None, attach_btf_id: None, }; - let program = match section { + let program = match &data.obj.section { ProgramSection::KProbe { .. } => Program::KProbe(KProbe { data, kind: ProbeKind::KProbe, @@ -290,7 +289,13 @@ impl<'a> BpfLoader<'a> { }), ProgramSection::SockOps { .. } => Program::SockOps(SockOps { data }), ProgramSection::SchedClassifier { .. } => { - Program::SchedClassifier(SchedClassifier { data }) + Program::SchedClassifier(SchedClassifier { + data, + name: unsafe { + CString::from_vec_unchecked(Vec::from(name.clone())) + .into_boxed_c_str() + }, + }) } ProgramSection::CgroupSkbIngress { .. } => Program::CgroupSkb(CgroupSkb { data, @@ -314,13 +319,11 @@ impl<'a> BpfLoader<'a> { (name, program) }) .collect(); - Ok(Bpf { - maps: maps - .drain(..) - .map(|map| (map.obj.name.clone(), MapLock::new(map))) - .collect(), - programs, - }) + let maps = maps + .drain() + .map(|(name, map)| (name, MapLock::new(map))) + .collect(); + Ok(Bpf { maps, programs }) } } @@ -468,24 +471,16 @@ impl Bpf { /// For more details on programs and their usage, see the [programs module /// documentation](crate::programs). /// - /// # Errors - /// - /// Returns [`ProgramError::NotFound`] if the program does not exist. - /// /// # Examples /// /// ```no_run /// # let bpf = aya::Bpf::load(&[])?; - /// let program = bpf.program("SSL_read")?; + /// let program = bpf.program("SSL_read").unwrap(); /// println!("program SSL_read is of type {:?}", program.prog_type()); /// # Ok::<(), aya::BpfError>(()) /// ``` - pub fn program(&self, name: &str) -> Result<&Program, ProgramError> { - self.programs - .get(name) - .ok_or_else(|| ProgramError::NotFound { - name: name.to_owned(), - }) + pub fn program(&self, name: &str) -> Option<&Program> { + self.programs.get(name) } /// Returns a mutable reference to the program with the given name. @@ -493,10 +488,6 @@ impl Bpf { /// Used to get a program before loading and attaching it. For more details on programs and /// their usage, see the [programs module documentation](crate::programs). /// - /// # Errors - /// - /// Returns [`ProgramError::NotFound`] if the program does not exist. - /// /// # Examples /// /// ```no_run @@ -504,17 +495,13 @@ impl Bpf { /// use aya::programs::UProbe; /// use std::convert::TryInto; /// - /// let program: &mut UProbe = bpf.program_mut("SSL_read")?.try_into()?; + /// let program: &mut UProbe = 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) -> Result<&mut Program, ProgramError> { - self.programs - .get_mut(name) - .ok_or_else(|| ProgramError::NotFound { - name: name.to_owned(), - }) + pub fn program_mut(&mut self, name: &str) -> Option<&mut Program> { + self.programs.get_mut(name) } /// An iterator over all the programs. @@ -522,17 +509,17 @@ impl Bpf { /// # Examples /// ```no_run /// # let bpf = aya::Bpf::load(&[])?; - /// for program in bpf.programs() { + /// for (name, program) in bpf.programs() { /// println!( /// "found program `{}` of type `{:?}`", - /// program.name(), + /// name, /// program.prog_type() /// ); /// } /// # Ok::<(), aya::BpfError>(()) /// ``` - pub fn programs(&self) -> impl Iterator { - self.programs.values() + pub fn programs(&self) -> impl Iterator { + self.programs.iter().map(|(s, p)| (s.as_str(), p)) } /// An iterator mutably referencing all of the programs. @@ -542,13 +529,13 @@ impl Bpf { /// # use std::path::Path; /// # let mut bpf = aya::Bpf::load(&[])?; /// # let pin_path = Path::new("/tmp/pin_path"); - /// for program in bpf.programs_mut() { + /// for (_, program) in bpf.programs_mut() { /// program.pin(pin_path)?; /// } /// # Ok::<(), aya::BpfError>(()) /// ``` - pub fn programs_mut(&mut self) -> impl Iterator { - self.programs.values_mut() + pub fn programs_mut(&mut self) -> impl Iterator { + self.programs.iter_mut().map(|(s, p)| (s.as_str(), p)) } } diff --git a/aya/src/maps/array/program_array.rs b/aya/src/maps/array/program_array.rs index 9b2ae51d..6f939ed4 100644 --- a/aya/src/maps/array/program_array.rs +++ b/aya/src/maps/array/program_array.rs @@ -32,9 +32,9 @@ use crate::{ /// use std::convert::{TryFrom, TryInto}; /// /// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?; -/// let prog_0: &CgroupSkb = bpf.program("example_prog_0")?.try_into()?; -/// let prog_1: &CgroupSkb = bpf.program("example_prog_1")?.try_into()?; -/// let prog_2: &CgroupSkb = bpf.program("example_prog_2")?.try_into()?; +/// let prog_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?; +/// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?; +/// let prog_2: &CgroupSkb = bpf.program("example_prog_2").unwrap().try_into()?; /// /// let flags = 0; /// diff --git a/aya/src/maps/hash_map/hash_map.rs b/aya/src/maps/hash_map/hash_map.rs index fc841f34..e38eac52 100644 --- a/aya/src/maps/hash_map/hash_map.rs +++ b/aya/src/maps/hash_map/hash_map.rs @@ -158,9 +158,8 @@ mod tests { use super::*; - fn new_obj_map(name: &str) -> obj::Map { + fn new_obj_map() -> obj::Map { obj::Map { - name: name.to_string(), def: bpf_map_def { map_type: BPF_MAP_TYPE_HASH as u32, key_size: 4, @@ -180,7 +179,7 @@ mod tests { #[test] fn test_wrong_key_size() { let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: None, pinned: false, }; @@ -196,7 +195,7 @@ mod tests { #[test] fn test_wrong_value_size() { let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: None, pinned: false, }; @@ -213,7 +212,6 @@ mod tests { fn test_try_from_wrong_map() { let map = Map { obj: obj::Map { - name: "TEST".to_string(), def: bpf_map_def { map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32, key_size: 4, @@ -237,7 +235,7 @@ mod tests { #[test] fn test_new_not_created() { let mut map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: None, pinned: false, }; @@ -251,7 +249,7 @@ mod tests { #[test] fn test_new_ok() { let mut map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -262,7 +260,7 @@ mod tests { #[test] fn test_try_from_ok() { let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -273,7 +271,6 @@ mod tests { fn test_try_from_ok_lru() { let map = Map { obj: obj::Map { - name: "TEST".to_string(), def: bpf_map_def { map_type: BPF_MAP_TYPE_LRU_HASH as u32, key_size: 4, @@ -296,7 +293,7 @@ mod tests { override_syscall(|_| sys_error(EFAULT)); let mut map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -319,7 +316,7 @@ mod tests { }); let mut map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -333,7 +330,7 @@ mod tests { override_syscall(|_| sys_error(EFAULT)); let mut map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -356,7 +353,7 @@ mod tests { }); let mut map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -369,7 +366,7 @@ mod tests { fn test_get_syscall_error() { override_syscall(|_| sys_error(EFAULT)); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -391,7 +388,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -430,7 +427,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -474,7 +471,7 @@ mod tests { }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -502,7 +499,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -532,7 +529,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -565,7 +562,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -599,7 +596,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; @@ -639,7 +636,7 @@ mod tests { _ => sys_error(EFAULT), }); let map = Map { - obj: new_obj_map("TEST"), + obj: new_obj_map(), fd: Some(42), pinned: false, }; diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index d99375b7..74a1c4d6 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -21,7 +21,7 @@ //! use aya::programs::SkMsg; //! //! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; -//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet")?.try_into()?; +//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; //! prog.load()?; //! prog.attach(&intercept_egress)?; //! # Ok::<(), aya::BpfError>(()) @@ -79,8 +79,8 @@ pub enum MapError { #[error("invalid map path `{error}`")] InvalidPinPath { error: String }, - #[error("the map `{name}` has not been created")] - NotCreated { name: String }, + #[error("the map has not been created")] + NotCreated, #[error("the map `{name}` has already been created")] AlreadyCreated { name: String }, @@ -148,18 +148,16 @@ pub struct Map { } impl Map { - pub fn create(&mut self) -> Result { - let name = self.obj.name.clone(); + pub fn create(&mut self, name: &str) -> Result { if self.fd.is_some() { - return Err(MapError::AlreadyCreated { name }); + return Err(MapError::AlreadyCreated { name: name.into() }); } - let c_name = - CString::new(name.clone()).map_err(|_| MapError::InvalidName { name: name.clone() })?; + let c_name = CString::new(name).map_err(|_| MapError::InvalidName { name: name.into() })?; let fd = bpf_create_map(&c_name, &self.obj.def).map_err(|(code, io_error)| { MapError::CreateError { - name, + name: name.into(), code, io_error, } @@ -170,12 +168,15 @@ impl Map { Ok(fd) } - pub(crate) fn from_pinned>(&mut self, path: P) -> Result { - let name = self.obj.name.clone(); + pub(crate) fn from_pinned>( + &mut self, + name: &str, + path: P, + ) -> Result { if self.fd.is_some() { - return Err(MapError::AlreadyCreated { name }); + return Err(MapError::AlreadyCreated { name: name.into() }); } - let map_path = path.as_ref().join(self.name()); + let map_path = path.as_ref().join(name); let path_string = match CString::new(map_path.to_str().unwrap()) { Ok(s) => s, Err(e) => { @@ -185,7 +186,7 @@ impl Map { } }; let fd = bpf_get_object(&path_string).map_err(|(code, io_error)| MapError::PinError { - name, + name: name.into(), code, io_error, })? as RawFd; @@ -195,27 +196,19 @@ impl Map { Ok(fd) } - pub fn name(&self) -> &str { - &self.obj.name - } - pub fn map_type(&self) -> Result { bpf_map_type::try_from(self.obj.def.map_type) } pub(crate) fn fd_or_err(&self) -> Result { - self.fd.ok_or_else(|| MapError::NotCreated { - name: self.obj.name.clone(), - }) + self.fd.ok_or(MapError::NotCreated) } - pub(crate) fn pin>(&mut self, path: P) -> Result<(), MapError> { + pub(crate) fn pin>(&mut self, name: &str, path: P) -> Result<(), MapError> { if self.pinned { - return Err(MapError::AlreadyPinned { - name: self.name().to_string(), - }); + return Err(MapError::AlreadyPinned { name: name.into() }); } - let map_path = path.as_ref().join(self.name()); + let map_path = path.as_ref().join(name); let fd = self.fd_or_err()?; let path_string = CString::new(map_path.to_string_lossy().into_owned()).map_err(|e| { MapError::InvalidPinPath { @@ -492,9 +485,8 @@ mod tests { use super::*; - fn new_obj_map(name: &str) -> obj::Map { + fn new_obj_map() -> obj::Map { obj::Map { - name: name.to_string(), def: bpf_map_def { map_type: BPF_MAP_TYPE_HASH as u32, key_size: 4, @@ -507,9 +499,9 @@ mod tests { } } - fn new_map(name: &str) -> Map { + fn new_map() -> Map { Map { - obj: new_obj_map(name), + obj: new_obj_map(), fd: None, pinned: false, } @@ -525,18 +517,21 @@ mod tests { _ => Err((-1, io::Error::from_raw_os_error(EFAULT))), }); - let mut map = new_map("foo"); - assert!(matches!(map.create(), Ok(42))); + let mut map = new_map(); + assert!(matches!(map.create("foo"), Ok(42))); assert_eq!(map.fd, Some(42)); - assert!(matches!(map.create(), Err(MapError::AlreadyCreated { .. }))); + assert!(matches!( + map.create("foo"), + Err(MapError::AlreadyCreated { .. }) + )); } #[test] fn test_create_failed() { override_syscall(|_| Err((-42, io::Error::from_raw_os_error(EFAULT)))); - let mut map = new_map("foo"); - let ret = map.create(); + let mut map = new_map(); + let ret = map.create("foo"); 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 7e06173c..fa7914dd 100644 --- a/aya/src/maps/sock/sock_hash.rs +++ b/aya/src/maps/sock/sock_hash.rs @@ -50,7 +50,7 @@ use crate::{ /// use aya::programs::SkMsg; /// /// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; -/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet")?.try_into()?; +/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_egress)?; /// diff --git a/aya/src/maps/sock/sock_map.rs b/aya/src/maps/sock/sock_map.rs index d39f449c..13a46b1e 100644 --- a/aya/src/maps/sock/sock_map.rs +++ b/aya/src/maps/sock/sock_map.rs @@ -35,7 +35,7 @@ use crate::{ /// use aya::programs::SkSkb; /// /// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?; -/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet")?.try_into()?; +/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_ingress)?; /// # Ok::<(), aya::BpfError>(()) diff --git a/aya/src/obj/mod.rs b/aya/src/obj/mod.rs index 810cc83b..ec4c2da8 100644 --- a/aya/src/obj/mod.rs +++ b/aya/src/obj/mod.rs @@ -44,7 +44,6 @@ pub struct Object { #[derive(Debug, Clone)] pub struct Map { - pub(crate) name: String, pub(crate) def: bpf_map_def, pub(crate) section_index: usize, pub(crate) data: Vec, @@ -530,7 +529,6 @@ fn parse_map(section: &Section, name: &str) -> Result { Ok(Map { section_index: section.index.0, - name: name.to_string(), def, data, }) @@ -785,7 +783,6 @@ mod tests { ), Ok(Map { section_index: 0, - name, def: bpf_map_def { map_type: 1, key_size: 2, @@ -796,7 +793,7 @@ mod tests { pinning: PinningType::None, }, data - }) if name == "foo" && data.is_empty() + }) if data.is_empty() )) } @@ -813,7 +810,6 @@ mod tests { ), Ok(Map { section_index: 0, - name, def: bpf_map_def { map_type: _map_type, key_size: 4, @@ -824,7 +820,7 @@ mod tests { pinning: PinningType::None, }, data - }) if name == ".bss" && data == map_data && value_size == map_data.len() as u32 + }) if data == map_data && value_size == map_data.len() as u32 )) } diff --git a/aya/src/obj/relocation.rs b/aya/src/obj/relocation.rs index d170e868..bc70f9b6 100644 --- a/aya/src/obj/relocation.rs +++ b/aya/src/obj/relocation.rs @@ -61,10 +61,12 @@ pub(crate) struct Symbol { } impl Object { - pub fn relocate_maps(&mut self, maps: &[Map]) -> Result<(), BpfError> { + pub fn relocate_maps<'a>( + &'a mut self, + maps: impl Iterator, + ) -> Result<(), BpfError> { let maps_by_section = maps - .iter() - .map(|map| (map.obj.section_index, map)) + .map(|(name, map)| (map.obj.section_index, (name, map))) .collect::>(); let functions = self @@ -110,7 +112,7 @@ impl Object { fn relocate_maps<'a, I: Iterator>( fun: &mut Function, relocations: I, - maps_by_section: &HashMap, + maps_by_section: &HashMap, symbol_table: &HashMap, ) -> Result<(), RelocationError> { let section_offset = fun.section_offset; @@ -152,7 +154,7 @@ fn relocate_maps<'a, I: Iterator>( None => continue, }; - let map = + let (name, map) = maps_by_section .get(§ion_index.0) .ok_or(RelocationError::SectionNotFound { @@ -162,7 +164,7 @@ fn relocate_maps<'a, I: Iterator>( })?; let map_fd = map.fd.ok_or_else(|| RelocationError::MapNotCreated { - name: map.obj.name.clone(), + name: (*name).into(), section_index: section_index.0, })?; diff --git a/aya/src/programs/cgroup_skb.rs b/aya/src/programs/cgroup_skb.rs index 6b798ad1..9aff1295 100644 --- a/aya/src/programs/cgroup_skb.rs +++ b/aya/src/programs/cgroup_skb.rs @@ -43,7 +43,7 @@ use super::FdLink; /// use aya::programs::{CgroupSkb, CgroupSkbAttachType}; /// /// let file = File::open("/sys/fs/cgroup/unified")?; -/// let egress: &mut CgroupSkb = bpf.program_mut("egress_filter")?.try_into()?; +/// let egress: &mut CgroupSkb = bpf.program_mut("egress_filter").unwrap().try_into()?; /// egress.load()?; /// egress.attach(file, CgroupSkbAttachType::Egress)?; /// # Ok::<(), Error>(()) @@ -63,11 +63,6 @@ impl CgroupSkb { load_program(BPF_PROG_TYPE_CGROUP_SKB, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Returns the expected attach type of the program. /// /// [`CgroupSkb`] programs can specify the expected attach type in their ELF diff --git a/aya/src/programs/kprobe.rs b/aya/src/programs/kprobe.rs index 9dddf6f8..ca7cc963 100644 --- a/aya/src/programs/kprobe.rs +++ b/aya/src/programs/kprobe.rs @@ -30,7 +30,7 @@ use crate::{ /// use aya::{Bpf, programs::KProbe}; /// use std::convert::TryInto; /// -/// let program: &mut KProbe = bpf.program_mut("intercept_wakeups")?.try_into()?; +/// let program: &mut KProbe = bpf.program_mut("intercept_wakeups").unwrap().try_into()?; /// program.load()?; /// program.attach("try_to_wake_up", 0)?; /// # Ok::<(), aya::BpfError>(()) @@ -50,11 +50,6 @@ impl KProbe { load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Returns `KProbe` if the program is a `kprobe`, or `KRetProbe` if the /// program is a `kretprobe`. pub fn kind(&self) -> ProbeKind { diff --git a/aya/src/programs/lirc_mode2.rs b/aya/src/programs/lirc_mode2.rs index 06d4cd8a..25f30b53 100644 --- a/aya/src/programs/lirc_mode2.rs +++ b/aya/src/programs/lirc_mode2.rs @@ -40,7 +40,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")?.try_into().unwrap(); +/// let decoder: &mut LircMode2 = bpf.program_mut("imon_rsc").unwrap().try_into().unwrap(); /// decoder.load()?; /// decoder.attach(file)?; /// # Ok::<(), Error>(()) @@ -59,11 +59,6 @@ impl LircMode2 { load_program(BPF_PROG_TYPE_LIRC_MODE2, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given lirc device. pub fn attach(&mut self, lircdev: T) -> Result { let prog_fd = self.data.fd_or_err()?; diff --git a/aya/src/programs/lsm.rs b/aya/src/programs/lsm.rs index 5d7f4cc6..ef057d9b 100644 --- a/aya/src/programs/lsm.rs +++ b/aya/src/programs/lsm.rs @@ -43,7 +43,7 @@ use crate::{ /// use std::convert::TryInto; /// /// let btf = Btf::from_sys_fs()?; -/// let program: &mut Lsm = bpf.program_mut("lsm_prog")?.try_into()?; +/// let program: &mut Lsm = bpf.program_mut("lsm_prog").unwrap().try_into()?; /// program.load("security_bprm_exec", &btf)?; /// program.attach()?; /// # Ok::<(), LsmError>(()) @@ -83,11 +83,6 @@ impl Lsm { load_program(BPF_PROG_TYPE_LSM, &mut self.data).map_err(LsmLoadError::from) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program. pub fn attach(&mut self) -> Result { attach_btf_id(&mut self.data) diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 4964aa66..2b8f2416 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -19,7 +19,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")?.try_into()?; +//! let program: &mut KProbe = 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 @@ -95,10 +95,6 @@ use crate::{ /// Error type returned when working with programs. #[derive(Debug, Error)] pub enum ProgramError { - /// The program could not be found in the object code. - #[error("program `{name}` not found")] - NotFound { name: String }, - /// The program is already loaded. #[error("the program is already loaded")] AlreadyLoaded, @@ -240,11 +236,6 @@ impl Program { } } - /// Returns the name of the program. - pub fn name(&self) -> &str { - &self.data().name - } - /// Pin the program to the provided path pub fn pin>(&mut self, path: P) -> Result<(), ProgramError> { self.data_mut().pin(path) @@ -293,7 +284,6 @@ impl Program { #[derive(Debug)] pub(crate) struct ProgramData { - pub(crate) name: String, pub(crate) obj: obj::Program, pub(crate) fd: Option, pub(crate) links: Vec>>, diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index 209e2ddc..d7c0a95d 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -66,7 +66,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")?.try_into()?; +/// let prog: &mut PerfEvent = bpf.program_mut("observe_cpu_clock").unwrap().try_into()?; /// prog.load()?; /// /// for cpu in online_cpus()? { diff --git a/aya/src/programs/raw_trace_point.rs b/aya/src/programs/raw_trace_point.rs index 2ca95826..81b0e393 100644 --- a/aya/src/programs/raw_trace_point.rs +++ b/aya/src/programs/raw_trace_point.rs @@ -26,7 +26,7 @@ use crate::{ /// use aya::{Bpf, programs::RawTracePoint}; /// use std::convert::TryInto; /// -/// let program: &mut RawTracePoint = bpf.program_mut("sys_enter")?.try_into()?; +/// let program: &mut RawTracePoint = bpf.program_mut("sys_enter").unwrap().try_into()?; /// program.load()?; /// program.attach("sys_enter")?; /// # Ok::<(), aya::BpfError>(()) @@ -45,11 +45,6 @@ impl RawTracePoint { load_program(BPF_PROG_TYPE_RAW_TRACEPOINT, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given tracepoint. pub fn attach(&mut self, tp_name: &str) -> Result { let prog_fd = self.data.fd_or_err()?; diff --git a/aya/src/programs/sk_msg.rs b/aya/src/programs/sk_msg.rs index 9298a478..fcb50926 100644 --- a/aya/src/programs/sk_msg.rs +++ b/aya/src/programs/sk_msg.rs @@ -38,7 +38,7 @@ use crate::{ /// use aya::programs::SkMsg; /// /// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; -/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet")?.try_into()?; +/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_egress)?; /// @@ -67,11 +67,6 @@ impl SkMsg { load_program(BPF_PROG_TYPE_SK_MSG, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given sockmap. pub fn attach(&mut self, map: &dyn SocketMap) -> Result { let prog_fd = self.data.fd_or_err()?; diff --git a/aya/src/programs/sk_skb.rs b/aya/src/programs/sk_skb.rs index 6ab8a0fb..bd07534f 100644 --- a/aya/src/programs/sk_skb.rs +++ b/aya/src/programs/sk_skb.rs @@ -34,7 +34,7 @@ pub enum SkSkbKind { /// use aya::programs::SkSkb; /// /// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?; -/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet")?.try_into()?; +/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_ingress)?; /// # Ok::<(), aya::BpfError>(()) @@ -58,11 +58,6 @@ impl SkSkb { load_program(BPF_PROG_TYPE_SK_SKB, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given socket map. pub fn attach(&mut self, map: &dyn SocketMap) -> Result { let prog_fd = self.data.fd_or_err()?; diff --git a/aya/src/programs/sock_ops.rs b/aya/src/programs/sock_ops.rs index 5852c4d7..579dafc3 100644 --- a/aya/src/programs/sock_ops.rs +++ b/aya/src/programs/sock_ops.rs @@ -36,7 +36,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")?.try_into()?; +/// let prog: &mut SockOps = bpf.program_mut("intercept_active_sockets").unwrap().try_into()?; /// prog.load()?; /// prog.attach(file)?; /// # Ok::<(), Error>(()) @@ -54,11 +54,6 @@ impl SockOps { load_program(BPF_PROG_TYPE_SOCK_OPS, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given cgroup. pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; diff --git a/aya/src/programs/socket_filter.rs b/aya/src/programs/socket_filter.rs index 1509b22b..883ed5d2 100644 --- a/aya/src/programs/socket_filter.rs +++ b/aya/src/programs/socket_filter.rs @@ -51,7 +51,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")?.try_into()?; +/// let prog: &mut SocketFilter = bpf.program_mut("filter_packets").unwrap().try_into()?; /// prog.load()?; /// prog.attach(client.as_raw_fd())?; /// # Ok::<(), Error>(()) diff --git a/aya/src/programs/tc.rs b/aya/src/programs/tc.rs index 4d16e0d4..7094c04a 100644 --- a/aya/src/programs/tc.rs +++ b/aya/src/programs/tc.rs @@ -1,7 +1,11 @@ //! Network traffic control programs. use thiserror::Error; -use std::{ffi::CString, io, os::unix::io::RawFd}; +use std::{ + ffi::{CStr, CString}, + io, + os::unix::io::RawFd, +}; use crate::{ generated::{ @@ -59,7 +63,7 @@ pub enum TcAttachType { /// // attached /// tc::qdisc_add_clsact("eth0")?; /// -/// let prog: &mut SchedClassifier = bpf.program_mut("redirect_ingress")?.try_into()?; +/// let prog: &mut SchedClassifier = bpf.program_mut("redirect_ingress").unwrap().try_into()?; /// prog.load()?; /// prog.attach("eth0", TcAttachType::Ingress)?; /// @@ -69,6 +73,7 @@ pub enum TcAttachType { #[doc(alias = "BPF_PROG_TYPE_SCHED_CLS")] pub struct SchedClassifier { pub(crate) data: ProgramData, + pub(crate) name: Box, } #[derive(Debug, Error)] @@ -108,11 +113,6 @@ impl SchedClassifier { load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given `interface`. /// /// # Errors @@ -129,9 +129,8 @@ impl SchedClassifier { let prog_fd = self.data.fd_or_err()?; let if_index = ifindex_from_ifname(interface) .map_err(|io_error| TcError::NetlinkError { io_error })?; - let name = CString::new(self.name()).unwrap(); let priority = - unsafe { netlink_qdisc_attach(if_index as i32, &attach_type, prog_fd, &name) } + unsafe { netlink_qdisc_attach(if_index as i32, &attach_type, prog_fd, &self.name) } .map_err(|io_error| TcError::NetlinkError { io_error })?; Ok(self.data.link(TcLink { @@ -181,13 +180,33 @@ pub fn qdisc_detach_program( if_name: &str, attach_type: TcAttachType, name: &str, +) -> Result<(), io::Error> { + let cstr = CString::new(name)?; + qdisc_detach_program_fast(if_name, attach_type, &cstr) +} + +/// Detaches the programs with the given name as a C string. +/// Unlike qdisc_detach_program, this function does not allocate an additional +/// CString to. +/// +/// # Errors +/// +/// Returns [`io::ErrorKind::NotFound`] to indicate that no programs with the +/// given name were found, so nothing was detached. Other error kinds indicate +/// an actual failure while detaching a program. +fn qdisc_detach_program_fast( + if_name: &str, + attach_type: TcAttachType, + name: &CStr, ) -> Result<(), io::Error> { let if_index = ifindex_from_ifname(if_name)? as i32; - let c_name = CString::new(name).unwrap(); - let prios = unsafe { netlink_find_filter_with_name(if_index, attach_type, &c_name)? }; + let prios = unsafe { netlink_find_filter_with_name(if_index, attach_type, name)? }; if prios.is_empty() { - return Err(io::Error::new(io::ErrorKind::NotFound, name.to_string())); + return Err(io::Error::new( + io::ErrorKind::NotFound, + name.to_string_lossy(), + )); } for prio in prios { diff --git a/aya/src/programs/tp_btf.rs b/aya/src/programs/tp_btf.rs index 7c16db0c..966414df 100644 --- a/aya/src/programs/tp_btf.rs +++ b/aya/src/programs/tp_btf.rs @@ -40,7 +40,7 @@ use crate::{ /// use std::convert::TryInto; /// /// let btf = Btf::from_sys_fs()?; -/// let program: &mut BtfTracePoint = bpf.program_mut("sched_process_fork")?.try_into()?; +/// let program: &mut BtfTracePoint = bpf.program_mut("sched_process_fork").unwrap().try_into()?; /// program.load("sched_process_fork", &btf)?; /// program.attach()?; /// # Ok::<(), Error>(()) @@ -81,11 +81,6 @@ impl BtfTracePoint { load_program(BPF_PROG_TYPE_TRACING, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program. pub fn attach(&mut self) -> Result { let prog_fd = self.data.fd_or_err()?; diff --git a/aya/src/programs/trace_point.rs b/aya/src/programs/trace_point.rs index 844be0b9..59fa145c 100644 --- a/aya/src/programs/trace_point.rs +++ b/aya/src/programs/trace_point.rs @@ -44,7 +44,7 @@ pub enum TracePointError { /// use std::convert::TryInto; /// use aya::programs::TracePoint; /// -/// let prog: &mut TracePoint = bpf.program_mut("trace_context_switch")?.try_into()?; +/// let prog: &mut TracePoint = bpf.program_mut("trace_context_switch").unwrap().try_into()?; /// prog.load()?; /// prog.attach("sched", "sched_switch")?; /// # Ok::<(), Error>(()) diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs index 2444be86..ed699f9f 100644 --- a/aya/src/programs/uprobe.rs +++ b/aya/src/programs/uprobe.rs @@ -52,11 +52,6 @@ impl UProbe { load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Returns `UProbe` if the program is a `uprobe`, or `URetProbe` if the /// program is a `uretprobe`. pub fn kind(&self) -> ProbeKind { diff --git a/aya/src/programs/xdp.rs b/aya/src/programs/xdp.rs index 31a595c1..3cb75856 100644 --- a/aya/src/programs/xdp.rs +++ b/aya/src/programs/xdp.rs @@ -57,7 +57,7 @@ bitflags! { /// use aya::{Bpf, programs::{Xdp, XdpFlags}}; /// use std::convert::TryInto; /// -/// let program: &mut Xdp = bpf.program_mut("intercept_packets")?.try_into()?; +/// let program: &mut Xdp = bpf.program_mut("intercept_packets").unwrap().try_into()?; /// program.attach("eth0", XdpFlags::default())?; /// # Ok::<(), aya::BpfError>(()) /// ``` @@ -75,11 +75,6 @@ impl Xdp { load_program(BPF_PROG_TYPE_XDP, &mut self.data) } - /// Returns the name of the program. - pub fn name(&self) -> String { - self.data.name.to_string() - } - /// Attaches the program to the given `interface`. /// /// # Errors