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