aya: support loading a map by fd

This adds support to loading maps by fd similarly to the way programs
can be loaded by fd.
pull/676/merge
Adam Preuss 1 year ago committed by Alessandro Decina
parent 68ba02002f
commit 36420d9297

@ -68,8 +68,9 @@ use crate::{
obj::{self, parse_map_info, BpfSectionKind}, obj::{self, parse_map_info, BpfSectionKind},
pin::PinError, pin::PinError,
sys::{ sys::{
bpf_create_map, bpf_get_object, bpf_map_freeze, bpf_map_get_info_by_fd, bpf_create_map, bpf_get_object, bpf_map_freeze, bpf_map_get_fd_by_id,
bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, SyscallError, bpf_map_get_info_by_fd, bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object,
SyscallError,
}, },
util::{nr_cpus, KernelVersion}, util::{nr_cpus, KernelVersion},
PinningType, Pod, PinningType, Pod,
@ -648,6 +649,13 @@ impl MapData {
}) })
} }
/// Loads a map from a map id.
pub fn from_id(id: u32) -> Result<Self, MapError> {
bpf_map_get_fd_by_id(id)
.map_err(MapError::from)
.and_then(Self::from_fd)
}
/// Loads a map from a file descriptor. /// Loads a map from a file descriptor.
/// ///
/// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`](crate::maps::MapData::from_pin). /// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`](crate::maps::MapData::from_pin).
@ -935,6 +943,38 @@ mod tests {
}) })
} }
#[test]
fn test_from_map_id() {
override_syscall(|call| match call {
Syscall::Bpf {
cmd: bpf_cmd::BPF_MAP_GET_FD_BY_ID,
attr,
} => {
assert_eq!(
unsafe { attr.__bindgen_anon_6.__bindgen_anon_1.map_id },
1234
);
Ok(42)
}
Syscall::Bpf {
cmd: bpf_cmd::BPF_OBJ_GET_INFO_BY_FD,
attr,
} => {
assert_eq!(unsafe { attr.info.bpf_fd }, 42);
Ok(0)
}
_ => Err((-1, io::Error::from_raw_os_error(EFAULT))),
});
assert_matches!(
MapData::from_id(1234),
Ok(MapData {
obj: _,
fd,
}) => assert_eq!(fd.as_fd().as_raw_fd(), 42)
);
}
#[test] #[test]
fn test_create() { fn test_create() {
override_syscall(|call| match call { override_syscall(|call| match call {

@ -550,6 +550,21 @@ pub(crate) fn bpf_prog_get_info_by_fd(
}) })
} }
pub(crate) fn bpf_map_get_fd_by_id(map_id: u32) -> Result<OwnedFd, SyscallError> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.__bindgen_anon_6.__bindgen_anon_1.map_id = map_id;
// SAFETY: BPF_MAP_GET_FD_BY_ID returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_MAP_GET_FD_BY_ID, &mut attr) }.map_err(|(code, io_error)| {
assert_eq!(code, -1);
SyscallError {
call: "bpf_map_get_fd_by_id",
io_error,
}
})
}
pub(crate) fn bpf_map_get_info_by_fd(fd: BorrowedFd<'_>) -> Result<bpf_map_info, SyscallError> { pub(crate) fn bpf_map_get_info_by_fd(fd: BorrowedFd<'_>) -> Result<bpf_map_info, SyscallError> {
bpf_obj_get_info_by_fd(fd, |_| {}) bpf_obj_get_info_by_fd(fd, |_| {})
} }

@ -1686,6 +1686,7 @@ impl aya::maps::MapData
pub fn aya::maps::MapData::create(obj: aya_obj::maps::Map, name: &str, btf_fd: core::option::Option<std::os::fd::owned::BorrowedFd<'_>>) -> core::result::Result<Self, aya::maps::MapError> pub fn aya::maps::MapData::create(obj: aya_obj::maps::Map, name: &str, btf_fd: core::option::Option<std::os::fd::owned::BorrowedFd<'_>>) -> core::result::Result<Self, aya::maps::MapError>
pub fn aya::maps::MapData::fd(&self) -> &aya::maps::MapFd pub fn aya::maps::MapData::fd(&self) -> &aya::maps::MapFd
pub fn aya::maps::MapData::from_fd(fd: std::os::fd::owned::OwnedFd) -> core::result::Result<Self, aya::maps::MapError> pub fn aya::maps::MapData::from_fd(fd: std::os::fd::owned::OwnedFd) -> core::result::Result<Self, aya::maps::MapError>
pub fn aya::maps::MapData::from_id(id: u32) -> core::result::Result<Self, aya::maps::MapError>
pub fn aya::maps::MapData::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::maps::MapError> pub fn aya::maps::MapData::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::maps::MapError>
pub fn aya::maps::MapData::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> pub fn aya::maps::MapData::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
impl core::fmt::Debug for aya::maps::MapData impl core::fmt::Debug for aya::maps::MapData

Loading…
Cancel
Save