aya: eliminate name duplication in maps and programs.

Map and ProgramData objects had unnecessarily cloned strings for their
names, despite them being just as easily available to external users via
bpf.maps() and bpf.programs().
pull/120/head
Thia Wyrod 3 years ago
parent 98b36b23bc
commit f56dd0a70b
No known key found for this signature in database
GPG Key ID: 55D3AB7E5658CA0C

@ -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