Merge pull request #520 from astoycos/unsupported-map

Add Unsupported Map type
pull/540/head
Alessandro Decina 1 year ago committed by GitHub
commit eb60d65613
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -13,7 +13,7 @@ use aya_obj::{
relocation::BpfRelocationError,
BpfSectionKind, Features,
};
use log::debug;
use log::{debug, warn};
use thiserror::Error;
use crate::{
@ -129,6 +129,7 @@ pub struct BpfLoader<'a> {
max_entries: HashMap<&'a str, u32>,
extensions: HashSet<&'a str>,
verifier_log_level: VerifierLogLevel,
allow_unsupported_maps: bool,
}
bitflags! {
@ -162,6 +163,7 @@ impl<'a> BpfLoader<'a> {
max_entries: HashMap::new(),
extensions: HashSet::new(),
verifier_log_level: VerifierLogLevel::default(),
allow_unsupported_maps: false,
}
}
@ -187,6 +189,30 @@ impl<'a> BpfLoader<'a> {
self
}
/// Allows programs containing unsupported maps to be loaded.
///
/// By default programs containing unsupported maps will fail to load. This
/// method can be used to configure the loader so that unsupported maps will
/// be loaded, but won't be accessible from userspace. Can be useful when
/// using unsupported maps that are only accessed from eBPF code and don't
/// require any userspace interaction.
///
/// # Example
///
/// ```no_run
/// use aya::BpfLoader;
///
/// let bpf = BpfLoader::new()
/// .allow_unsupported_maps()
/// .load_file("file.o")?;
/// # Ok::<(), aya::BpfError>(())
/// ```
///
pub fn allow_unsupported_maps(&mut self) -> &mut BpfLoader<'a> {
self.allow_unsupported_maps = true;
self
}
/// Sets the base directory path for pinned maps.
///
/// Pinned maps will be loaded from `path/MAP_NAME`.
@ -616,12 +642,21 @@ impl<'a> BpfLoader<'a> {
(name, program)
})
.collect();
let maps: Result<HashMap<String, Map>, BpfError> = maps.drain().map(parse_map).collect();
let maps = maps
.drain()
.map(parse_map)
.collect::<Result<HashMap<String, Map>, BpfError>>()?;
Ok(Bpf {
maps: maps?,
programs,
})
if !self.allow_unsupported_maps {
maps.iter().try_for_each(|(_, x)| match x {
Map::Unsupported(map) => Err(BpfError::MapError(MapError::Unsupported {
map_type: map.obj.map_type(),
})),
_ => Ok(()),
})?;
};
Ok(Bpf { maps, programs })
}
}
@ -633,25 +668,26 @@ fn parse_map(data: (String, MapData)) -> Result<(String, Map), BpfError> {
map_type: e.map_type,
})?;
let map = match map_type {
BPF_MAP_TYPE_ARRAY => Ok(Map::Array(map)),
BPF_MAP_TYPE_PERCPU_ARRAY => Ok(Map::PerCpuArray(map)),
BPF_MAP_TYPE_PROG_ARRAY => Ok(Map::ProgramArray(map)),
BPF_MAP_TYPE_HASH => Ok(Map::HashMap(map)),
BPF_MAP_TYPE_LRU_HASH => Ok(Map::LruHashMap(map)),
BPF_MAP_TYPE_PERCPU_HASH => Ok(Map::PerCpuHashMap(map)),
BPF_MAP_TYPE_LRU_PERCPU_HASH => Ok(Map::PerCpuLruHashMap(map)),
BPF_MAP_TYPE_PERF_EVENT_ARRAY => Ok(Map::PerfEventArray(map)),
BPF_MAP_TYPE_SOCKHASH => Ok(Map::SockHash(map)),
BPF_MAP_TYPE_SOCKMAP => Ok(Map::SockMap(map)),
BPF_MAP_TYPE_BLOOM_FILTER => Ok(Map::BloomFilter(map)),
BPF_MAP_TYPE_LPM_TRIE => Ok(Map::LpmTrie(map)),
BPF_MAP_TYPE_STACK => Ok(Map::Stack(map)),
BPF_MAP_TYPE_STACK_TRACE => Ok(Map::StackTraceMap(map)),
BPF_MAP_TYPE_QUEUE => Ok(Map::Queue(map)),
m => Err(BpfError::MapError(MapError::InvalidMapType {
map_type: m as u32,
})),
}?;
BPF_MAP_TYPE_ARRAY => Map::Array(map),
BPF_MAP_TYPE_PERCPU_ARRAY => Map::PerCpuArray(map),
BPF_MAP_TYPE_PROG_ARRAY => Map::ProgramArray(map),
BPF_MAP_TYPE_HASH => Map::HashMap(map),
BPF_MAP_TYPE_LRU_HASH => Map::LruHashMap(map),
BPF_MAP_TYPE_PERCPU_HASH => Map::PerCpuHashMap(map),
BPF_MAP_TYPE_LRU_PERCPU_HASH => Map::PerCpuLruHashMap(map),
BPF_MAP_TYPE_PERF_EVENT_ARRAY => Map::PerfEventArray(map),
BPF_MAP_TYPE_SOCKHASH => Map::SockHash(map),
BPF_MAP_TYPE_SOCKMAP => Map::SockMap(map),
BPF_MAP_TYPE_BLOOM_FILTER => Map::BloomFilter(map),
BPF_MAP_TYPE_LPM_TRIE => Map::LpmTrie(map),
BPF_MAP_TYPE_STACK => Map::Stack(map),
BPF_MAP_TYPE_STACK_TRACE => Map::StackTraceMap(map),
BPF_MAP_TYPE_QUEUE => Map::Queue(map),
m => {
warn!("The map {name} is of type {:#?} which is currently unsupported in Aya, use `allow_unsupported_maps()` to load it anyways", m);
Map::Unsupported(map)
}
};
Ok((name, map))
}

@ -183,6 +183,13 @@ pub enum MapError {
#[source]
error: PinError,
},
/// Unsupported Map type
#[error("Unsupported map type found {map_type}")]
Unsupported {
/// The map type
map_type: u32,
},
}
/// A map file descriptor.
@ -262,6 +269,8 @@ pub enum Map {
StackTraceMap(MapData),
/// A [`Queue`] map
Queue(MapData),
/// An unsupported map type
Unsupported(MapData),
}
impl Map {
@ -283,6 +292,7 @@ impl Map {
Map::Stack(map) => map.obj.map_type(),
Map::StackTraceMap(map) => map.obj.map_type(),
Map::Queue(map) => map.obj.map_type(),
Map::Unsupported(map) => map.obj.map_type(),
}
}
}

Loading…
Cancel
Save