aya/maps: support TryFrom for LRU hash maps

The macro to implement TryFrom for MapData didn't have the ability to
specify that more than one variant of MapData can be valid for a single
map implementation. Support for new syntax was added to the macro so that
the implementation can succeed for both valid variants in the HashMap
and PerCpuHashMap impl.

Fixes #636
pull/774/head
Andrew Werner 1 year ago
parent 792f467d40
commit 172859c66b

@ -108,43 +108,22 @@ mod tests {
use libc::{EFAULT, ENOENT}; use libc::{EFAULT, ENOENT};
use crate::{ use crate::{
bpf_map_def,
generated::{ generated::{
bpf_attr, bpf_cmd, bpf_attr, bpf_cmd,
bpf_map_type::{BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_LRU_HASH}, bpf_map_type::{BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_LRU_HASH},
}, },
maps::{Map, MapData}, maps::Map,
obj::{self, maps::LegacyMap, BpfSectionKind}, obj,
sys::{override_syscall, SysResult, Syscall}, sys::{override_syscall, SysResult, Syscall},
}; };
use super::*; use super::{
super::test_utils::{self, new_map},
*,
};
fn new_obj_map() -> obj::Map { fn new_obj_map() -> obj::Map {
obj::Map::Legacy(LegacyMap { test_utils::new_obj_map(BPF_MAP_TYPE_HASH)
def: bpf_map_def {
map_type: BPF_MAP_TYPE_HASH as u32,
key_size: 4,
value_size: 4,
max_entries: 1024,
..Default::default()
},
section_index: 0,
section_kind: BpfSectionKind::Maps,
data: Vec::new(),
symbol_index: None,
})
}
fn new_map(obj: obj::Map) -> MapData {
override_syscall(|call| match call {
Syscall::Bpf {
cmd: bpf_cmd::BPF_MAP_CREATE,
..
} => Ok(1337),
call => panic!("unexpected syscall {:?}", call),
});
MapData::create(obj, "foo", None).unwrap()
} }
fn sys_error(value: i32) -> SysResult<c_long> { fn sys_error(value: i32) -> SysResult<c_long> {
@ -213,21 +192,10 @@ mod tests {
#[test] #[test]
fn test_try_from_ok_lru() { fn test_try_from_ok_lru() {
let map = new_map(obj::Map::Legacy(LegacyMap { let map_data = || new_map(test_utils::new_obj_map(BPF_MAP_TYPE_LRU_HASH));
def: bpf_map_def { let map = Map::HashMap(map_data());
map_type: BPF_MAP_TYPE_LRU_HASH as u32, assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok());
key_size: 4, let map = Map::LruHashMap(map_data());
value_size: 4,
max_entries: 1024,
..Default::default()
},
section_index: 0,
section_kind: BpfSectionKind::Maps,
symbol_index: None,
data: Vec::new(),
}));
let map = Map::HashMap(map);
assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok()) assert!(HashMap::<_, u32, u32>::try_from(&map).is_ok())
} }

@ -41,3 +41,41 @@ pub(crate) fn remove<K: Pod>(map: &MapData, key: &K) -> Result<(), MapError> {
.into() .into()
}) })
} }
#[cfg(test)]
mod test_utils {
use crate::{
bpf_map_def,
generated::{bpf_cmd, bpf_map_type},
maps::MapData,
obj::{self, maps::LegacyMap, BpfSectionKind},
sys::{override_syscall, Syscall},
};
pub(super) fn new_map(obj: obj::Map) -> MapData {
override_syscall(|call| match call {
Syscall::Bpf {
cmd: bpf_cmd::BPF_MAP_CREATE,
..
} => Ok(1337),
call => panic!("unexpected syscall {:?}", call),
});
MapData::create(obj, "foo", None).unwrap()
}
pub(super) fn new_obj_map(map_type: bpf_map_type) -> obj::Map {
obj::Map::Legacy(LegacyMap {
def: bpf_map_def {
map_type: map_type as u32,
key_size: 4,
value_size: 4,
max_entries: 1024,
..Default::default()
},
section_index: 0,
section_kind: BpfSectionKind::Maps,
data: Vec::new(),
symbol_index: None,
})
}
}

@ -146,3 +146,30 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> IterableMap<K, PerCpuValues<V>>
Self::get(self, key, 0) Self::get(self, key, 0)
} }
} }
#[cfg(test)]
mod tests {
use crate::{
generated::bpf_map_type::{BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_HASH},
maps::Map,
};
use super::{super::test_utils, *};
#[test]
fn test_try_from_ok() {
let map = Map::PerCpuHashMap(test_utils::new_map(test_utils::new_obj_map(
BPF_MAP_TYPE_PERCPU_HASH,
)));
assert!(PerCpuHashMap::<_, u32, u32>::try_from(&map).is_ok())
}
#[test]
fn test_try_from_ok_lru() {
let map_data =
|| test_utils::new_map(test_utils::new_obj_map(BPF_MAP_TYPE_LRU_PERCPU_HASH));
let map = Map::PerCpuHashMap(map_data());
assert!(PerCpuHashMap::<_, u32, u32>::try_from(&map).is_ok());
let map = Map::PerCpuLruHashMap(map_data());
assert!(PerCpuHashMap::<_, u32, u32>::try_from(&map).is_ok())
}
}

@ -291,9 +291,9 @@ macro_rules! impl_try_from_map {
// rather than the repeated idents used later because the macro language does not allow one // rather than the repeated idents used later because the macro language does not allow one
// repetition to be pasted inside another. // repetition to be pasted inside another.
($ty_param:tt { ($ty_param:tt {
$($ty:ident $(from $variant:ident)?),+ $(,)? $($ty:ident $(from $($variant:ident)|+)?),+ $(,)?
}) => { }) => {
$(impl_try_from_map!(<$ty_param> $ty $(from $variant)?);)+ $(impl_try_from_map!(<$ty_param> $ty $(from $($variant)|+)?);)+
}; };
// Add the "from $variant" using $ty as the default if it is missing. // Add the "from $variant" using $ty as the default if it is missing.
(<$ty_param:tt> $ty:ident) => { (<$ty_param:tt> $ty:ident) => {
@ -301,17 +301,17 @@ macro_rules! impl_try_from_map {
}; };
// Dispatch for each of the lifetimes. // Dispatch for each of the lifetimes.
( (
<($($ty_param:ident),*)> $ty:ident from $variant:ident <($($ty_param:ident),*)> $ty:ident from $($variant:ident)|+
) => { ) => {
impl_try_from_map!(<'a> ($($ty_param),*) $ty from $variant); impl_try_from_map!(<'a> ($($ty_param),*) $ty from $($variant)|+);
impl_try_from_map!(<'a mut> ($($ty_param),*) $ty from $variant); impl_try_from_map!(<'a mut> ($($ty_param),*) $ty from $($variant)|+);
impl_try_from_map!(<> ($($ty_param),*) $ty from $variant); impl_try_from_map!(<> ($($ty_param),*) $ty from $($variant)|+);
}; };
// An individual impl. // An individual impl.
( (
<$($l:lifetime $($m:ident)?)?> <$($l:lifetime $($m:ident)?)?>
($($ty_param:ident),*) ($($ty_param:ident),*)
$ty:ident from $variant:ident $ty:ident from $($variant:ident)|+
) => { ) => {
impl<$($l,)? $($ty_param: Pod),*> TryFrom<$(&$l $($m)?)? Map> impl<$($l,)? $($ty_param: Pod),*> TryFrom<$(&$l $($m)?)? Map>
for $ty<$(&$l $($m)?)? MapData, $($ty_param),*> for $ty<$(&$l $($m)?)? MapData, $($ty_param),*>
@ -320,7 +320,7 @@ macro_rules! impl_try_from_map {
fn try_from(map: $(&$l $($m)?)? Map) -> Result<Self, Self::Error> { fn try_from(map: $(&$l $($m)?)? Map) -> Result<Self, Self::Error> {
match map { match map {
Map::$variant(map_data) => Self::new(map_data), $(Map::$variant(map_data) => Self::new(map_data),)+
map => Err(MapError::InvalidMapType { map => Err(MapError::InvalidMapType {
map_type: map.map_type() map_type: map.map_type()
}), }),
@ -353,8 +353,8 @@ impl_try_from_map!((V) {
}); });
impl_try_from_map!((K, V) { impl_try_from_map!((K, V) {
HashMap, HashMap from HashMap|LruHashMap,
PerCpuHashMap, PerCpuHashMap from PerCpuHashMap|PerCpuLruHashMap,
LpmTrie, LpmTrie,
}); });

Loading…
Cancel
Save