Merge pull request #120 from eero-thia/thia/dedup

aya: eliminate name duplication in maps and programs.
pull/118/head
Alessandro Decina 3 years ago committed by GitHub
commit 07a6016ebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2,6 +2,7 @@ use std::{
borrow::Cow, borrow::Cow,
collections::HashMap, collections::HashMap,
error::Error, error::Error,
ffi::CString,
fs, io, fs, io,
os::{raw::c_int, unix::io::RawFd}, os::{raw::c_int, unix::io::RawFd},
path::{Path, PathBuf}, path::{Path, PathBuf},
@ -191,8 +192,8 @@ impl<'a> BpfLoader<'a> {
obj.relocate_btf(btf)?; obj.relocate_btf(btf)?;
} }
let mut maps = Vec::new(); let mut maps = HashMap::new();
for (_, mut obj) in obj.maps.drain() { 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 if obj.def.map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32 && obj.def.max_entries == 0
{ {
obj.def.max_entries = possible_cpus() obj.def.max_entries = possible_cpus()
@ -214,21 +215,21 @@ impl<'a> BpfLoader<'a> {
None => return Err(BpfError::NoPinPath), None => return Err(BpfError::NoPinPath),
}; };
// try to open map in case it's already pinned // try to open map in case it's already pinned
match map.from_pinned(path) { match map.from_pinned(&name, path) {
Ok(fd) => { Ok(fd) => {
map.pinned = true; map.pinned = true;
fd as RawFd fd as RawFd
} }
Err(_) => { Err(_) => {
let fd = map.create()?; let fd = map.create(&name)?;
map.pin(path)?; map.pin(&name, path)?;
fd 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( bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data.as_mut_ptr(), 0).map_err(
|(code, io_error)| MapError::SyscallError { |(code, io_error)| MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(), 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()?; obj.relocate_calls()?;
let programs = obj let programs = obj
.programs .programs
.drain() .drain()
.map(|(name, obj)| { .map(|(name, obj)| {
let section = obj.section.clone();
let data = ProgramData { let data = ProgramData {
obj, obj,
name: name.clone(),
fd: None, fd: None,
links: Vec::new(), links: Vec::new(),
expected_attach_type: None, expected_attach_type: None,
attach_btf_obj_fd: None, attach_btf_obj_fd: None,
attach_btf_id: None, attach_btf_id: None,
}; };
let program = match section { let program = match &data.obj.section {
ProgramSection::KProbe { .. } => Program::KProbe(KProbe { ProgramSection::KProbe { .. } => Program::KProbe(KProbe {
data, data,
kind: ProbeKind::KProbe, kind: ProbeKind::KProbe,
@ -290,7 +289,13 @@ impl<'a> BpfLoader<'a> {
}), }),
ProgramSection::SockOps { .. } => Program::SockOps(SockOps { data }), ProgramSection::SockOps { .. } => Program::SockOps(SockOps { data }),
ProgramSection::SchedClassifier { .. } => { 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 { ProgramSection::CgroupSkbIngress { .. } => Program::CgroupSkb(CgroupSkb {
data, data,
@ -314,13 +319,11 @@ impl<'a> BpfLoader<'a> {
(name, program) (name, program)
}) })
.collect(); .collect();
Ok(Bpf { let maps = maps
maps: maps .drain()
.drain(..) .map(|(name, map)| (name, MapLock::new(map)))
.map(|map| (map.obj.name.clone(), MapLock::new(map))) .collect();
.collect(), Ok(Bpf { maps, programs })
programs,
})
} }
} }
@ -468,24 +471,16 @@ impl Bpf {
/// For more details on programs and their usage, see the [programs module /// For more details on programs and their usage, see the [programs module
/// documentation](crate::programs). /// documentation](crate::programs).
/// ///
/// # Errors
///
/// Returns [`ProgramError::NotFound`] if the program does not exist.
///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
/// # let bpf = aya::Bpf::load(&[])?; /// # 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()); /// println!("program SSL_read is of type {:?}", program.prog_type());
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
pub fn program(&self, name: &str) -> Result<&Program, ProgramError> { pub fn program(&self, name: &str) -> Option<&Program> {
self.programs self.programs.get(name)
.get(name)
.ok_or_else(|| ProgramError::NotFound {
name: name.to_owned(),
})
} }
/// Returns a mutable reference to the program with the given 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 /// 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). /// their usage, see the [programs module documentation](crate::programs).
/// ///
/// # Errors
///
/// Returns [`ProgramError::NotFound`] if the program does not exist.
///
/// # Examples /// # Examples
/// ///
/// ```no_run /// ```no_run
@ -504,17 +495,13 @@ impl Bpf {
/// use aya::programs::UProbe; /// use aya::programs::UProbe;
/// use std::convert::TryInto; /// 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.load()?;
/// program.attach(Some("SSL_read"), 0, "libssl", None)?; /// program.attach(Some("SSL_read"), 0, "libssl", None)?;
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
pub fn program_mut(&mut self, name: &str) -> Result<&mut Program, ProgramError> { pub fn program_mut(&mut self, name: &str) -> Option<&mut Program> {
self.programs self.programs.get_mut(name)
.get_mut(name)
.ok_or_else(|| ProgramError::NotFound {
name: name.to_owned(),
})
} }
/// An iterator over all the programs. /// An iterator over all the programs.
@ -522,17 +509,17 @@ impl Bpf {
/// # Examples /// # Examples
/// ```no_run /// ```no_run
/// # let bpf = aya::Bpf::load(&[])?; /// # let bpf = aya::Bpf::load(&[])?;
/// for program in bpf.programs() { /// for (name, program) in bpf.programs() {
/// println!( /// println!(
/// "found program `{}` of type `{:?}`", /// "found program `{}` of type `{:?}`",
/// program.name(), /// name,
/// program.prog_type() /// program.prog_type()
/// ); /// );
/// } /// }
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
pub fn programs(&self) -> impl Iterator<Item = &Program> { pub fn programs(&self) -> impl Iterator<Item = (&str, &Program)> {
self.programs.values() self.programs.iter().map(|(s, p)| (s.as_str(), p))
} }
/// An iterator mutably referencing all of the programs. /// An iterator mutably referencing all of the programs.
@ -542,13 +529,13 @@ impl Bpf {
/// # use std::path::Path; /// # use std::path::Path;
/// # let mut bpf = aya::Bpf::load(&[])?; /// # let mut bpf = aya::Bpf::load(&[])?;
/// # let pin_path = Path::new("/tmp/pin_path"); /// # let pin_path = Path::new("/tmp/pin_path");
/// for program in bpf.programs_mut() { /// for (_, program) in bpf.programs_mut() {
/// program.pin(pin_path)?; /// program.pin(pin_path)?;
/// } /// }
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
pub fn programs_mut(&mut self) -> impl Iterator<Item = &mut Program> { pub fn programs_mut(&mut self) -> impl Iterator<Item = (&str, &mut Program)> {
self.programs.values_mut() self.programs.iter_mut().map(|(s, p)| (s.as_str(), p))
} }
} }

@ -32,9 +32,9 @@ use crate::{
/// use std::convert::{TryFrom, TryInto}; /// use std::convert::{TryFrom, TryInto};
/// ///
/// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?; /// 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_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?;
/// let prog_1: &CgroupSkb = bpf.program("example_prog_1")?.try_into()?; /// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?;
/// let prog_2: &CgroupSkb = bpf.program("example_prog_2")?.try_into()?; /// let prog_2: &CgroupSkb = bpf.program("example_prog_2").unwrap().try_into()?;
/// ///
/// let flags = 0; /// let flags = 0;
/// ///

@ -158,9 +158,8 @@ mod tests {
use super::*; use super::*;
fn new_obj_map(name: &str) -> obj::Map { fn new_obj_map() -> obj::Map {
obj::Map { obj::Map {
name: name.to_string(),
def: bpf_map_def { def: bpf_map_def {
map_type: BPF_MAP_TYPE_HASH as u32, map_type: BPF_MAP_TYPE_HASH as u32,
key_size: 4, key_size: 4,
@ -180,7 +179,7 @@ mod tests {
#[test] #[test]
fn test_wrong_key_size() { fn test_wrong_key_size() {
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: None, fd: None,
pinned: false, pinned: false,
}; };
@ -196,7 +195,7 @@ mod tests {
#[test] #[test]
fn test_wrong_value_size() { fn test_wrong_value_size() {
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: None, fd: None,
pinned: false, pinned: false,
}; };
@ -213,7 +212,6 @@ mod tests {
fn test_try_from_wrong_map() { fn test_try_from_wrong_map() {
let map = Map { let map = Map {
obj: obj::Map { obj: obj::Map {
name: "TEST".to_string(),
def: bpf_map_def { def: bpf_map_def {
map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32, map_type: BPF_MAP_TYPE_PERF_EVENT_ARRAY as u32,
key_size: 4, key_size: 4,
@ -237,7 +235,7 @@ mod tests {
#[test] #[test]
fn test_new_not_created() { fn test_new_not_created() {
let mut map = Map { let mut map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: None, fd: None,
pinned: false, pinned: false,
}; };
@ -251,7 +249,7 @@ mod tests {
#[test] #[test]
fn test_new_ok() { fn test_new_ok() {
let mut map = Map { let mut map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -262,7 +260,7 @@ mod tests {
#[test] #[test]
fn test_try_from_ok() { fn test_try_from_ok() {
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -273,7 +271,6 @@ mod tests {
fn test_try_from_ok_lru() { fn test_try_from_ok_lru() {
let map = Map { let map = Map {
obj: obj::Map { obj: obj::Map {
name: "TEST".to_string(),
def: bpf_map_def { def: bpf_map_def {
map_type: BPF_MAP_TYPE_LRU_HASH as u32, map_type: BPF_MAP_TYPE_LRU_HASH as u32,
key_size: 4, key_size: 4,
@ -296,7 +293,7 @@ mod tests {
override_syscall(|_| sys_error(EFAULT)); override_syscall(|_| sys_error(EFAULT));
let mut map = Map { let mut map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -319,7 +316,7 @@ mod tests {
}); });
let mut map = Map { let mut map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -333,7 +330,7 @@ mod tests {
override_syscall(|_| sys_error(EFAULT)); override_syscall(|_| sys_error(EFAULT));
let mut map = Map { let mut map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -356,7 +353,7 @@ mod tests {
}); });
let mut map = Map { let mut map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -369,7 +366,7 @@ mod tests {
fn test_get_syscall_error() { fn test_get_syscall_error() {
override_syscall(|_| sys_error(EFAULT)); override_syscall(|_| sys_error(EFAULT));
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -391,7 +388,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -430,7 +427,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -474,7 +471,7 @@ mod tests {
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -502,7 +499,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -532,7 +529,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -565,7 +562,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -599,7 +596,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };
@ -639,7 +636,7 @@ mod tests {
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let map = Map { let map = Map {
obj: new_obj_map("TEST"), obj: new_obj_map(),
fd: Some(42), fd: Some(42),
pinned: false, pinned: false,
}; };

@ -21,7 +21,7 @@
//! use aya::programs::SkMsg; //! use aya::programs::SkMsg;
//! //!
//! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; //! 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.load()?;
//! prog.attach(&intercept_egress)?; //! prog.attach(&intercept_egress)?;
//! # Ok::<(), aya::BpfError>(()) //! # Ok::<(), aya::BpfError>(())
@ -79,8 +79,8 @@ pub enum MapError {
#[error("invalid map path `{error}`")] #[error("invalid map path `{error}`")]
InvalidPinPath { error: String }, InvalidPinPath { error: String },
#[error("the map `{name}` has not been created")] #[error("the map has not been created")]
NotCreated { name: String }, NotCreated,
#[error("the map `{name}` has already been created")] #[error("the map `{name}` has already been created")]
AlreadyCreated { name: String }, AlreadyCreated { name: String },
@ -148,18 +148,16 @@ pub struct Map {
} }
impl Map { impl Map {
pub fn create(&mut self) -> Result<RawFd, MapError> { pub fn create(&mut self, name: &str) -> Result<RawFd, MapError> {
let name = self.obj.name.clone();
if self.fd.is_some() { if self.fd.is_some() {
return Err(MapError::AlreadyCreated { name }); return Err(MapError::AlreadyCreated { name: name.into() });
} }
let c_name = let c_name = CString::new(name).map_err(|_| MapError::InvalidName { name: name.into() })?;
CString::new(name.clone()).map_err(|_| MapError::InvalidName { name: name.clone() })?;
let fd = bpf_create_map(&c_name, &self.obj.def).map_err(|(code, io_error)| { let fd = bpf_create_map(&c_name, &self.obj.def).map_err(|(code, io_error)| {
MapError::CreateError { MapError::CreateError {
name, name: name.into(),
code, code,
io_error, io_error,
} }
@ -170,12 +168,15 @@ impl Map {
Ok(fd) Ok(fd)
} }
pub(crate) fn from_pinned<P: AsRef<Path>>(&mut self, path: P) -> Result<RawFd, MapError> { pub(crate) fn from_pinned<P: AsRef<Path>>(
let name = self.obj.name.clone(); &mut self,
name: &str,
path: P,
) -> Result<RawFd, MapError> {
if self.fd.is_some() { 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()) { let path_string = match CString::new(map_path.to_str().unwrap()) {
Ok(s) => s, Ok(s) => s,
Err(e) => { Err(e) => {
@ -185,7 +186,7 @@ impl Map {
} }
}; };
let fd = bpf_get_object(&path_string).map_err(|(code, io_error)| MapError::PinError { let fd = bpf_get_object(&path_string).map_err(|(code, io_error)| MapError::PinError {
name, name: name.into(),
code, code,
io_error, io_error,
})? as RawFd; })? as RawFd;
@ -195,27 +196,19 @@ impl Map {
Ok(fd) Ok(fd)
} }
pub fn name(&self) -> &str {
&self.obj.name
}
pub fn map_type(&self) -> Result<bpf_map_type, MapError> { pub fn map_type(&self) -> Result<bpf_map_type, MapError> {
bpf_map_type::try_from(self.obj.def.map_type) bpf_map_type::try_from(self.obj.def.map_type)
} }
pub(crate) fn fd_or_err(&self) -> Result<RawFd, MapError> { pub(crate) fn fd_or_err(&self) -> Result<RawFd, MapError> {
self.fd.ok_or_else(|| MapError::NotCreated { self.fd.ok_or(MapError::NotCreated)
name: self.obj.name.clone(),
})
} }
pub(crate) fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), MapError> { pub(crate) fn pin<P: AsRef<Path>>(&mut self, name: &str, path: P) -> Result<(), MapError> {
if self.pinned { if self.pinned {
return Err(MapError::AlreadyPinned { return Err(MapError::AlreadyPinned { name: name.into() });
name: self.name().to_string(),
});
} }
let map_path = path.as_ref().join(self.name()); let map_path = path.as_ref().join(name);
let fd = self.fd_or_err()?; let fd = self.fd_or_err()?;
let path_string = CString::new(map_path.to_string_lossy().into_owned()).map_err(|e| { let path_string = CString::new(map_path.to_string_lossy().into_owned()).map_err(|e| {
MapError::InvalidPinPath { MapError::InvalidPinPath {
@ -492,9 +485,8 @@ mod tests {
use super::*; use super::*;
fn new_obj_map(name: &str) -> obj::Map { fn new_obj_map() -> obj::Map {
obj::Map { obj::Map {
name: name.to_string(),
def: bpf_map_def { def: bpf_map_def {
map_type: BPF_MAP_TYPE_HASH as u32, map_type: BPF_MAP_TYPE_HASH as u32,
key_size: 4, key_size: 4,
@ -507,9 +499,9 @@ mod tests {
} }
} }
fn new_map(name: &str) -> Map { fn new_map() -> Map {
Map { Map {
obj: new_obj_map(name), obj: new_obj_map(),
fd: None, fd: None,
pinned: false, pinned: false,
} }
@ -525,18 +517,21 @@ mod tests {
_ => Err((-1, io::Error::from_raw_os_error(EFAULT))), _ => Err((-1, io::Error::from_raw_os_error(EFAULT))),
}); });
let mut map = new_map("foo"); let mut map = new_map();
assert!(matches!(map.create(), Ok(42))); assert!(matches!(map.create("foo"), Ok(42)));
assert_eq!(map.fd, Some(42)); assert_eq!(map.fd, Some(42));
assert!(matches!(map.create(), Err(MapError::AlreadyCreated { .. }))); assert!(matches!(
map.create("foo"),
Err(MapError::AlreadyCreated { .. })
));
} }
#[test] #[test]
fn test_create_failed() { fn test_create_failed() {
override_syscall(|_| Err((-42, io::Error::from_raw_os_error(EFAULT)))); override_syscall(|_| Err((-42, io::Error::from_raw_os_error(EFAULT))));
let mut map = new_map("foo"); let mut map = new_map();
let ret = map.create(); let ret = map.create("foo");
assert!(matches!(ret, Err(MapError::CreateError { .. }))); assert!(matches!(ret, Err(MapError::CreateError { .. })));
if let Err(MapError::CreateError { if let Err(MapError::CreateError {
name, name,

@ -50,7 +50,7 @@ use crate::{
/// use aya::programs::SkMsg; /// use aya::programs::SkMsg;
/// ///
/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; /// 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.load()?;
/// prog.attach(&intercept_egress)?; /// prog.attach(&intercept_egress)?;
/// ///

@ -35,7 +35,7 @@ use crate::{
/// use aya::programs::SkSkb; /// use aya::programs::SkSkb;
/// ///
/// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?; /// 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.load()?;
/// prog.attach(&intercept_ingress)?; /// prog.attach(&intercept_ingress)?;
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())

@ -44,7 +44,6 @@ pub struct Object {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Map { pub struct Map {
pub(crate) name: String,
pub(crate) def: bpf_map_def, pub(crate) def: bpf_map_def,
pub(crate) section_index: usize, pub(crate) section_index: usize,
pub(crate) data: Vec<u8>, pub(crate) data: Vec<u8>,
@ -530,7 +529,6 @@ fn parse_map(section: &Section, name: &str) -> Result<Map, ParseError> {
Ok(Map { Ok(Map {
section_index: section.index.0, section_index: section.index.0,
name: name.to_string(),
def, def,
data, data,
}) })
@ -785,7 +783,6 @@ mod tests {
), ),
Ok(Map { Ok(Map {
section_index: 0, section_index: 0,
name,
def: bpf_map_def { def: bpf_map_def {
map_type: 1, map_type: 1,
key_size: 2, key_size: 2,
@ -796,7 +793,7 @@ mod tests {
pinning: PinningType::None, pinning: PinningType::None,
}, },
data data
}) if name == "foo" && data.is_empty() }) if data.is_empty()
)) ))
} }
@ -813,7 +810,6 @@ mod tests {
), ),
Ok(Map { Ok(Map {
section_index: 0, section_index: 0,
name,
def: bpf_map_def { def: bpf_map_def {
map_type: _map_type, map_type: _map_type,
key_size: 4, key_size: 4,
@ -824,7 +820,7 @@ mod tests {
pinning: PinningType::None, pinning: PinningType::None,
}, },
data 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
)) ))
} }

@ -61,10 +61,12 @@ pub(crate) struct Symbol {
} }
impl Object { impl Object {
pub fn relocate_maps(&mut self, maps: &[Map]) -> Result<(), BpfError> { pub fn relocate_maps<'a>(
&'a mut self,
maps: impl Iterator<Item = (&'a str, &'a Map)>,
) -> Result<(), BpfError> {
let maps_by_section = maps let maps_by_section = maps
.iter() .map(|(name, map)| (map.obj.section_index, (name, map)))
.map(|map| (map.obj.section_index, map))
.collect::<HashMap<_, _>>(); .collect::<HashMap<_, _>>();
let functions = self let functions = self
@ -110,7 +112,7 @@ impl Object {
fn relocate_maps<'a, I: Iterator<Item = &'a Relocation>>( fn relocate_maps<'a, I: Iterator<Item = &'a Relocation>>(
fun: &mut Function, fun: &mut Function,
relocations: I, relocations: I,
maps_by_section: &HashMap<usize, &Map>, maps_by_section: &HashMap<usize, (&str, &Map)>,
symbol_table: &HashMap<usize, Symbol>, symbol_table: &HashMap<usize, Symbol>,
) -> Result<(), RelocationError> { ) -> Result<(), RelocationError> {
let section_offset = fun.section_offset; let section_offset = fun.section_offset;
@ -152,7 +154,7 @@ fn relocate_maps<'a, I: Iterator<Item = &'a Relocation>>(
None => continue, None => continue,
}; };
let map = let (name, map) =
maps_by_section maps_by_section
.get(&section_index.0) .get(&section_index.0)
.ok_or(RelocationError::SectionNotFound { .ok_or(RelocationError::SectionNotFound {
@ -162,7 +164,7 @@ fn relocate_maps<'a, I: Iterator<Item = &'a Relocation>>(
})?; })?;
let map_fd = map.fd.ok_or_else(|| RelocationError::MapNotCreated { let map_fd = map.fd.ok_or_else(|| RelocationError::MapNotCreated {
name: map.obj.name.clone(), name: (*name).into(),
section_index: section_index.0, section_index: section_index.0,
})?; })?;

@ -43,7 +43,7 @@ use super::FdLink;
/// use aya::programs::{CgroupSkb, CgroupSkbAttachType}; /// use aya::programs::{CgroupSkb, CgroupSkbAttachType};
/// ///
/// let file = File::open("/sys/fs/cgroup/unified")?; /// 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.load()?;
/// egress.attach(file, CgroupSkbAttachType::Egress)?; /// egress.attach(file, CgroupSkbAttachType::Egress)?;
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())
@ -63,11 +63,6 @@ impl CgroupSkb {
load_program(BPF_PROG_TYPE_CGROUP_SKB, &mut self.data) 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. /// Returns the expected attach type of the program.
/// ///
/// [`CgroupSkb`] programs can specify the expected attach type in their ELF /// [`CgroupSkb`] programs can specify the expected attach type in their ELF

@ -30,7 +30,7 @@ use crate::{
/// use aya::{Bpf, programs::KProbe}; /// use aya::{Bpf, programs::KProbe};
/// use std::convert::TryInto; /// 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.load()?;
/// program.attach("try_to_wake_up", 0)?; /// program.attach("try_to_wake_up", 0)?;
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
@ -50,11 +50,6 @@ impl KProbe {
load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) 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 /// Returns `KProbe` if the program is a `kprobe`, or `KRetProbe` if the
/// program is a `kretprobe`. /// program is a `kretprobe`.
pub fn kind(&self) -> ProbeKind { pub fn kind(&self) -> ProbeKind {

@ -40,7 +40,7 @@ use libc::{close, dup};
/// ///
/// let file = File::open("/dev/lirc0")?; /// let file = File::open("/dev/lirc0")?;
/// let mut bpf = aya::Bpf::load_file("imon_rsc.o")?; /// 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.load()?;
/// decoder.attach(file)?; /// decoder.attach(file)?;
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())
@ -59,11 +59,6 @@ impl LircMode2 {
load_program(BPF_PROG_TYPE_LIRC_MODE2, &mut self.data) 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. /// Attaches the program to the given lirc device.
pub fn attach<T: AsRawFd>(&mut self, lircdev: T) -> Result<LinkRef, ProgramError> { pub fn attach<T: AsRawFd>(&mut self, lircdev: T) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;

@ -43,7 +43,7 @@ use crate::{
/// use std::convert::TryInto; /// use std::convert::TryInto;
/// ///
/// let btf = Btf::from_sys_fs()?; /// 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.load("security_bprm_exec", &btf)?;
/// program.attach()?; /// program.attach()?;
/// # Ok::<(), LsmError>(()) /// # Ok::<(), LsmError>(())
@ -83,11 +83,6 @@ impl Lsm {
load_program(BPF_PROG_TYPE_LSM, &mut self.data).map_err(LsmLoadError::from) 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. /// Attaches the program.
pub fn attach(&mut self) -> Result<LinkRef, ProgramError> { pub fn attach(&mut self) -> Result<LinkRef, ProgramError> {
attach_btf_id(&mut self.data) attach_btf_id(&mut self.data)

@ -19,7 +19,7 @@
//! //!
//! let mut bpf = Bpf::load_file("ebpf_programs.o")?; //! let mut bpf = Bpf::load_file("ebpf_programs.o")?;
//! // intercept_wakeups is the name of the program we want to load //! // 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()?; //! program.load()?;
//! // intercept_wakeups will be called every time try_to_wake_up() is called //! // intercept_wakeups will be called every time try_to_wake_up() is called
//! // inside the kernel //! // inside the kernel
@ -95,10 +95,6 @@ use crate::{
/// Error type returned when working with programs. /// Error type returned when working with programs.
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum ProgramError { 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. /// The program is already loaded.
#[error("the program is already loaded")] #[error("the program is already loaded")]
AlreadyLoaded, 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 /// Pin the program to the provided path
pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ProgramError> { pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ProgramError> {
self.data_mut().pin(path) self.data_mut().pin(path)
@ -293,7 +284,6 @@ impl Program {
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct ProgramData { pub(crate) struct ProgramData {
pub(crate) name: String,
pub(crate) obj: obj::Program, pub(crate) obj: obj::Program,
pub(crate) fd: Option<RawFd>, pub(crate) fd: Option<RawFd>,
pub(crate) links: Vec<Rc<RefCell<dyn Link>>>, pub(crate) links: Vec<Rc<RefCell<dyn Link>>>,

@ -66,7 +66,7 @@ pub enum PerfEventScope {
/// perf_sw_ids::PERF_COUNT_SW_CPU_CLOCK, PerfEvent, PerfEventScope, PerfTypeId, SamplePolicy, /// 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()?; /// prog.load()?;
/// ///
/// for cpu in online_cpus()? { /// for cpu in online_cpus()? {

@ -26,7 +26,7 @@ use crate::{
/// use aya::{Bpf, programs::RawTracePoint}; /// use aya::{Bpf, programs::RawTracePoint};
/// use std::convert::TryInto; /// 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.load()?;
/// program.attach("sys_enter")?; /// program.attach("sys_enter")?;
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
@ -45,11 +45,6 @@ impl RawTracePoint {
load_program(BPF_PROG_TYPE_RAW_TRACEPOINT, &mut self.data) 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. /// Attaches the program to the given tracepoint.
pub fn attach(&mut self, tp_name: &str) -> Result<LinkRef, ProgramError> { pub fn attach(&mut self, tp_name: &str) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;

@ -38,7 +38,7 @@ use crate::{
/// use aya::programs::SkMsg; /// use aya::programs::SkMsg;
/// ///
/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; /// 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.load()?;
/// prog.attach(&intercept_egress)?; /// prog.attach(&intercept_egress)?;
/// ///
@ -67,11 +67,6 @@ impl SkMsg {
load_program(BPF_PROG_TYPE_SK_MSG, &mut self.data) 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. /// Attaches the program to the given sockmap.
pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> { pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;

@ -34,7 +34,7 @@ pub enum SkSkbKind {
/// use aya::programs::SkSkb; /// use aya::programs::SkSkb;
/// ///
/// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?; /// 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.load()?;
/// prog.attach(&intercept_ingress)?; /// prog.attach(&intercept_ingress)?;
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
@ -58,11 +58,6 @@ impl SkSkb {
load_program(BPF_PROG_TYPE_SK_SKB, &mut self.data) 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. /// Attaches the program to the given socket map.
pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> { pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;

@ -36,7 +36,7 @@ use crate::{
/// use aya::programs::SockOps; /// use aya::programs::SockOps;
/// ///
/// let file = File::open("/sys/fs/cgroup/unified")?; /// 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.load()?;
/// prog.attach(file)?; /// prog.attach(file)?;
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())
@ -54,11 +54,6 @@ impl SockOps {
load_program(BPF_PROG_TYPE_SOCK_OPS, &mut self.data) 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. /// Attaches the program to the given cgroup.
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<LinkRef, ProgramError> { pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;

@ -51,7 +51,7 @@ pub enum SocketFilterError {
/// use aya::programs::SocketFilter; /// use aya::programs::SocketFilter;
/// ///
/// let mut client = TcpStream::connect("127.0.0.1:1234")?; /// 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.load()?;
/// prog.attach(client.as_raw_fd())?; /// prog.attach(client.as_raw_fd())?;
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())

@ -1,7 +1,11 @@
//! Network traffic control programs. //! Network traffic control programs.
use thiserror::Error; use thiserror::Error;
use std::{ffi::CString, io, os::unix::io::RawFd}; use std::{
ffi::{CStr, CString},
io,
os::unix::io::RawFd,
};
use crate::{ use crate::{
generated::{ generated::{
@ -59,7 +63,7 @@ pub enum TcAttachType {
/// // attached /// // attached
/// tc::qdisc_add_clsact("eth0")?; /// 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.load()?;
/// prog.attach("eth0", TcAttachType::Ingress)?; /// prog.attach("eth0", TcAttachType::Ingress)?;
/// ///
@ -69,6 +73,7 @@ pub enum TcAttachType {
#[doc(alias = "BPF_PROG_TYPE_SCHED_CLS")] #[doc(alias = "BPF_PROG_TYPE_SCHED_CLS")]
pub struct SchedClassifier { pub struct SchedClassifier {
pub(crate) data: ProgramData, pub(crate) data: ProgramData,
pub(crate) name: Box<CStr>,
} }
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -108,11 +113,6 @@ impl SchedClassifier {
load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) 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`. /// Attaches the program to the given `interface`.
/// ///
/// # Errors /// # Errors
@ -129,9 +129,8 @@ impl SchedClassifier {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let if_index = ifindex_from_ifname(interface) let if_index = ifindex_from_ifname(interface)
.map_err(|io_error| TcError::NetlinkError { io_error })?; .map_err(|io_error| TcError::NetlinkError { io_error })?;
let name = CString::new(self.name()).unwrap();
let priority = 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 })?; .map_err(|io_error| TcError::NetlinkError { io_error })?;
Ok(self.data.link(TcLink { Ok(self.data.link(TcLink {
@ -181,13 +180,33 @@ pub fn qdisc_detach_program(
if_name: &str, if_name: &str,
attach_type: TcAttachType, attach_type: TcAttachType,
name: &str, 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> { ) -> Result<(), io::Error> {
let if_index = ifindex_from_ifname(if_name)? as i32; 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() { 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 { for prio in prios {

@ -40,7 +40,7 @@ use crate::{
/// use std::convert::TryInto; /// use std::convert::TryInto;
/// ///
/// let btf = Btf::from_sys_fs()?; /// 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.load("sched_process_fork", &btf)?;
/// program.attach()?; /// program.attach()?;
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())
@ -81,11 +81,6 @@ impl BtfTracePoint {
load_program(BPF_PROG_TYPE_TRACING, &mut self.data) 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. /// Attaches the program.
pub fn attach(&mut self) -> Result<LinkRef, ProgramError> { pub fn attach(&mut self) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;

@ -44,7 +44,7 @@ pub enum TracePointError {
/// use std::convert::TryInto; /// use std::convert::TryInto;
/// use aya::programs::TracePoint; /// 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.load()?;
/// prog.attach("sched", "sched_switch")?; /// prog.attach("sched", "sched_switch")?;
/// # Ok::<(), Error>(()) /// # Ok::<(), Error>(())

@ -52,11 +52,6 @@ impl UProbe {
load_program(BPF_PROG_TYPE_KPROBE, &mut self.data) 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 /// Returns `UProbe` if the program is a `uprobe`, or `URetProbe` if the
/// program is a `uretprobe`. /// program is a `uretprobe`.
pub fn kind(&self) -> ProbeKind { pub fn kind(&self) -> ProbeKind {

@ -57,7 +57,7 @@ bitflags! {
/// use aya::{Bpf, programs::{Xdp, XdpFlags}}; /// use aya::{Bpf, programs::{Xdp, XdpFlags}};
/// use std::convert::TryInto; /// 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())?; /// program.attach("eth0", XdpFlags::default())?;
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
@ -75,11 +75,6 @@ impl Xdp {
load_program(BPF_PROG_TYPE_XDP, &mut self.data) 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`. /// Attaches the program to the given `interface`.
/// ///
/// # Errors /// # Errors

Loading…
Cancel
Save