@ -137,7 +137,8 @@ pub struct EbpfLoader<'a> {
extensions : HashSet < & ' a str > ,
verifier_log_level : VerifierLogLevel ,
allow_unsupported_maps : bool ,
deactivate_maps : HashSet < bpf_map_type > ,
ignore_maps_by_type : HashSet < bpf_map_type > ,
ignore_maps_by_name : & ' a [ & ' a str ] ,
}
/// Builder style API for advanced loading of eBPF programs.
@ -176,7 +177,8 @@ impl<'a> EbpfLoader<'a> {
extensions : HashSet ::new ( ) ,
verifier_log_level : VerifierLogLevel ::default ( ) ,
allow_unsupported_maps : false ,
deactivate_maps : HashSet ::new ( ) ,
ignore_maps_by_type : HashSet ::new ( ) ,
ignore_maps_by_name : & [ ] ,
}
}
@ -229,9 +231,10 @@ impl<'a> EbpfLoader<'a> {
/// Allows programs containing unsupported maps for the current kernel to be loaded
/// by skipping map creation and relocation before loading.
///
/// This is useful when you have a single program containing e.g. a `RingBuf`
/// This is useful when you have a single ebpf program containing e.g. a `RingBuf`
/// and a `PerfEventArray` and you decide which one to use before loading the bytecode.
/// Can be used with `.set_global()` to signal if the map is supported.
///
/// Must be used with `.set_global()` to signal if the map is supported in the ebpf program.
///
/// # Example
///
@ -240,16 +243,44 @@ impl<'a> EbpfLoader<'a> {
/// use aya_obj::generated::bpf_map_type;
/// use std::collections::HashSet;
///
/// let ringbuf_supported = 0;
/// let mut set = HashSet::new();
/// set.insert(bpf_map_type::BPF_MAP_TYPE_RINGBUF);
/// let ebpf = EbpfLoader::new()
/// .deactivate_maps(set)
/// .ignore_maps_by_type(set)
/// .set_global("RINGBUF_SUPPORTED", &ringbuf_supported, true)
/// .load_file("file.o")?;
/// # Ok::<(), aya::EbpfError>(())
/// ```
///
pub fn ignore_maps_by_type ( & mut self , set : HashSet < bpf_map_type > ) -> & mut Self {
self . ignore_maps_by_type = set ;
self
}
/// Allows programs containing unsupported maps for the current kernel to be loaded
/// by skipping map creation and relocation before loading.
///
/// This is useful when you have a single ebpf program containing e.g. a `RingBuf`
/// and a `PerfEventArray` and you decide which one to use before loading the bytecode.
///
/// Must be used with `.set_global()` to signal if the map is supported in the ebpf program.
///
/// # Example
///
/// ```no_run
/// use aya::EbpfLoader;
///
/// let ringbuf_supported = 0;
/// let ebpf = EbpfLoader::new()
/// .ignore_maps_by_name(&["RINGBUF"])
/// .set_global("RINGBUF_SUPPORTED", &ringbuf_supported, true)
/// .load_file("file.o")?;
/// # Ok::<(), aya::EbpfError>(())
/// ```
///
pub fn deactivate_maps ( & mut self , set : HashSet < bpf_map_type > ) -> & mut Self {
self . deactivate_maps = set ;
pub fn ignore_maps_by_name( & mut self , name : & ' a [ & ' a str ] ) -> & mut Self {
self . ignore_maps_by_name = name ;
self
}
@ -423,7 +454,8 @@ impl<'a> EbpfLoader<'a> {
extensions ,
verifier_log_level ,
allow_unsupported_maps ,
deactivate_maps ,
ignore_maps_by_type ,
ignore_maps_by_name ,
} = self ;
let mut obj = Object ::parse ( data ) ? ;
obj . patch_map_data ( globals . clone ( ) ) ? ;
@ -499,7 +531,7 @@ impl<'a> EbpfLoader<'a> {
}
let map_type : bpf_map_type = obj . map_type ( ) . try_into ( ) . map_err ( MapError ::from ) ? ;
if deactivate_maps. contains ( & map_type ) {
if ignore_maps_by_type. contains ( & map_type ) | | ignore_maps_by_name . contains ( & name . as_str ( ) ) {
ignored_maps . insert ( name , obj ) ;
// ignore map creation. The map is saved in `ignored_maps` and filtered out
// in `relocate_maps()` later on