Merge pull request #387 from astoycos/map-from-prog

Load static maps
pull/391/head
Dave Tucker 2 years ago committed by GitHub
commit eb26a6b116
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -443,7 +443,7 @@ impl<'a> BpfLoader<'a> {
Err(_) => {
let fd = map.create(&name)?;
map.pin(&name, path).map_err(|error| MapError::PinError {
name: name.to_string(),
name: Some(name.to_string()),
error,
})?;
fd
@ -454,16 +454,14 @@ impl<'a> BpfLoader<'a> {
};
if !map.obj.data().is_empty() && map.obj.kind() != MapKind::Bss {
bpf_map_update_elem_ptr(fd, &0 as *const _, map.obj.data_mut().as_mut_ptr(), 0)
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
})?;
}
if map.obj.kind() == MapKind::Rodata {
bpf_map_freeze(fd).map_err(|(code, io_error)| MapError::SyscallError {
bpf_map_freeze(fd).map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_freeze".to_owned(),
code,
io_error,
})?;
}

@ -80,10 +80,9 @@ impl<T: Deref<Target = Map>, V: Pod> Array<T, V> {
self.check_bounds(*index)?;
let fd = self.inner.fd_or_err()?;
let value = bpf_map_lookup_elem(fd, index, flags).map_err(|(code, io_error)| {
let value = bpf_map_lookup_elem(fd, index, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
@ -116,10 +115,9 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Array<T, V> {
pub fn set(&mut self, index: u32, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?;
bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(code, io_error)| {
bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;

@ -99,10 +99,9 @@ impl<T: Deref<Target = Map>, V: Pod> PerCpuArray<T, V> {
self.check_bounds(*index)?;
let fd = self.inner.fd_or_err()?;
let value = bpf_map_lookup_elem_per_cpu(fd, index, flags).map_err(|(code, io_error)| {
let value = bpf_map_lookup_elem_per_cpu(fd, index, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
@ -135,10 +134,9 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> PerCpuArray<T, V>
pub fn set(&mut self, index: u32, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?;
bpf_map_update_elem_per_cpu(fd, &index, &values, flags).map_err(|(code, io_error)| {
bpf_map_update_elem_per_cpu(fd, &index, &values, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;

@ -103,10 +103,9 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
self.check_bounds(index)?;
let prog_fd = program.as_raw_fd();
bpf_map_update_elem(fd, Some(&index), &prog_fd, flags).map_err(|(code, io_error)| {
bpf_map_update_elem(fd, Some(&index), &prog_fd, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
@ -122,9 +121,8 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
self.check_bounds(*index)?;
bpf_map_delete_elem(fd, index)
.map(|_| ())
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_delete_elem".to_owned(),
code,
io_error,
})
}

@ -68,9 +68,8 @@ impl<T: Deref<Target = Map>, V: Pod> BloomFilter<T, V> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_lookup_elem_ptr::<u32, _>(fd, None, &mut value, flags)
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
})?
.ok_or(MapError::ElementNotFound)?;
@ -80,12 +79,9 @@ impl<T: Deref<Target = Map>, V: Pod> BloomFilter<T, V> {
/// Inserts a value into the map.
pub fn insert(&self, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_push_elem(fd, &value, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
bpf_map_push_elem(fd, &value, flags).map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_push_elem".to_owned(),
code,
io_error,
}
})?;
Ok(())
}
@ -254,7 +250,7 @@ mod tests {
assert!(matches!(
bloom_filter.insert(1, 0),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_push_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_push_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -292,7 +288,7 @@ mod tests {
assert!(matches!(
bloom_filter.contains(&1, 0),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}

@ -61,10 +61,9 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> HashMap<T, K, V> {
/// Returns a copy of the value associated with the key.
pub fn get(&self, key: &K, flags: u64) -> Result<V, MapError> {
let fd = self.inner.deref().fd_or_err()?;
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
@ -313,7 +312,7 @@ mod tests {
assert!(matches!(
hm.insert(1, 42, 0),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_update_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_update_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -352,7 +351,7 @@ mod tests {
assert!(matches!(
hm.remove(&1),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_delete_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_delete_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -390,7 +389,7 @@ mod tests {
assert!(matches!(
hm.get(&1, 0),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}

@ -29,10 +29,9 @@ pub(crate) fn check_kv_size<K, V>(map: &Map) -> Result<(), MapError> {
pub(crate) fn insert<K, V>(map: &mut Map, key: K, value: V, flags: u64) -> Result<(), MapError> {
let fd = map.fd_or_err()?;
bpf_map_update_elem(fd, Some(&key), &value, flags).map_err(|(code, io_error)| {
bpf_map_update_elem(fd, Some(&key), &value, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
@ -44,9 +43,8 @@ pub(crate) fn remove<K>(map: &mut Map, key: &K) -> Result<(), MapError> {
let fd = map.fd_or_err()?;
bpf_map_delete_elem(fd, key)
.map(|_| ())
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_delete_elem".to_owned(),
code,
io_error,
})
}

@ -73,10 +73,9 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
/// Returns a slice of values - one for each CPU - associated with the key.
pub fn get(&self, key: &K, flags: u64) -> Result<PerCpuValues<V>, MapError> {
let fd = self.inner.deref().fd_or_err()?;
let values = bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(code, io_error)| {
let values = bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
@ -127,10 +126,9 @@ impl<T: DerefMut<Target = Map>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
/// ```
pub fn insert(&mut self, key: K, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
bpf_map_update_elem_per_cpu(fd, &key, &values, flags).map_err(|(code, io_error)| {
bpf_map_update_elem_per_cpu(fd, &key, &values, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;

@ -129,10 +129,9 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
/// Returns a copy of the value associated with the longest prefix matching key in the LpmTrie.
pub fn get(&self, key: &Key<K>, flags: u64) -> Result<V, MapError> {
let fd = self.inner.deref().fd_or_err()?;
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;
@ -142,10 +141,9 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
/// Inserts a key value pair into the map.
pub fn insert(&self, key: &Key<K>, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_update_elem(fd, Some(key), &value, flags).map_err(|(code, io_error)| {
bpf_map_update_elem(fd, Some(key), &value, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;
@ -160,9 +158,8 @@ impl<T: Deref<Target = Map>, K: Pod, V: Pod> LpmTrie<T, K, V> {
let fd = self.inner.deref().fd_or_err()?;
bpf_map_delete_elem(fd, key)
.map(|_| ())
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_delete_elem".to_owned(),
code,
io_error,
})
}
@ -360,7 +357,7 @@ mod tests {
let key = Key::new(16, u32::from(ipaddr).to_be());
assert!(matches!(
trie.insert(&key, 1, 0),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_update_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_update_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -402,7 +399,7 @@ mod tests {
let key = Key::new(16, u32::from(ipaddr).to_be());
assert!(matches!(
trie.remove(&key),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_delete_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_delete_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}
@ -443,7 +440,7 @@ mod tests {
assert!(matches!(
trie.get(&key, 0),
Err(MapError::SyscallError { call, code: -1, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
Err(MapError::SyscallError { call, io_error }) if call == "bpf_map_lookup_elem" && io_error.raw_os_error() == Some(EFAULT)
));
}

@ -50,7 +50,10 @@ use crate::{
generated::bpf_map_type,
obj,
pin::PinError,
sys::{bpf_create_map, bpf_get_object, bpf_map_get_next_key, bpf_pin_object, kernel_version},
sys::{
bpf_create_map, bpf_get_object, bpf_map_get_info_by_fd, bpf_map_get_next_key,
bpf_pin_object, kernel_version,
},
util::nr_cpus,
Pod,
};
@ -163,13 +166,10 @@ pub enum MapError {
ProgramNotLoaded,
/// Syscall failed
#[error("the `{call}` syscall failed with code {code}")]
#[error("the `{call}` syscall failed")]
SyscallError {
/// Syscall Name
call: String,
/// Error code
code: libc::c_long,
#[source]
/// Original io::Error
io_error: io::Error,
},
@ -189,10 +189,10 @@ pub enum MapError {
},
/// Could not pin map by name
#[error("map `{name}` requested pinning by name. pinning failed")]
#[error("map `{name:?}` requested pinning by name. pinning failed")]
PinError {
/// The map name
name: String,
name: Option<String>,
/// The reason for the failure
#[source]
error: PinError,
@ -292,10 +292,8 @@ impl Map {
}
let map_path = path.as_ref().join(name);
let path_string = CString::new(map_path.to_str().unwrap()).unwrap();
let fd =
bpf_get_object(&path_string).map_err(|(code, io_error)| MapError::SyscallError {
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| MapError::SyscallError {
call: "BPF_OBJ_GET".to_string(),
code,
io_error,
})? as RawFd;
@ -304,6 +302,55 @@ impl Map {
Ok(fd)
}
/// Loads a map from a pinned path in bpffs.
pub fn from_pinned<P: AsRef<Path>>(path: P) -> Result<Map, MapError> {
let path_string =
CString::new(path.as_ref().to_string_lossy().into_owned()).map_err(|e| {
MapError::PinError {
name: None,
error: PinError::InvalidPinPath {
error: e.to_string(),
},
}
})?;
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| MapError::SyscallError {
call: "BPF_OBJ_GET".to_owned(),
io_error,
})? as RawFd;
let info = bpf_map_get_info_by_fd(fd).map_err(|io_error| MapError::SyscallError {
call: "BPF_MAP_GET_INFO_BY_FD".to_owned(),
io_error,
})?;
Ok(Map {
obj: obj::parse_map_info(info, crate::PinningType::ByName),
fd: Some(fd),
btf_fd: None,
pinned: true,
})
}
/// Loads a map from a [`RawFd`].
///
/// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pinned`].
/// This API is intended for cases where you have received a valid BPF FD from some other means.
/// For example, you received an FD over Unix Domain Socket.
pub fn from_fd(fd: RawFd) -> Result<Map, MapError> {
let info = bpf_map_get_info_by_fd(fd).map_err(|io_error| MapError::SyscallError {
call: "BPF_OBJ_GET".to_owned(),
io_error,
})?;
Ok(Map {
obj: obj::parse_map_info(info, crate::PinningType::None),
fd: Some(fd),
btf_fd: None,
pinned: false,
})
}
/// Returns the [`bpf_map_type`] of this map
pub fn map_type(&self) -> Result<bpf_map_type, MapError> {
bpf_map_type::try_from(self.obj.map_type())
@ -402,11 +449,10 @@ impl<K: Pod> Iterator for MapKeys<'_, K> {
self.key = None;
None
}
Err((code, io_error)) => {
Err((_, io_error)) => {
self.err = true;
Some(Err(MapError::SyscallError {
call: "bpf_map_get_next_key".to_owned(),
code,
io_error,
}))
}

@ -81,9 +81,8 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Queue<T, V> {
let fd = self.inner.fd_or_err()?;
let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(
|(code, io_error)| MapError::SyscallError {
|(_, io_error)| MapError::SyscallError {
call: "bpf_map_lookup_and_delete_elem".to_owned(),
code,
io_error,
},
)?;
@ -97,12 +96,9 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Queue<T, V> {
/// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
bpf_map_push_elem(fd, &value, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
bpf_map_push_elem(fd, &value, flags).map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_push_elem".to_owned(),
code,
io_error,
}
})?;
Ok(())
}

@ -87,10 +87,9 @@ impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
/// Returns the fd of the socket stored at the given key.
pub fn get(&self, key: &K, flags: u64) -> Result<RawFd, MapError> {
let fd = self.inner.deref().fd_or_err()?;
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
}
})?;

@ -89,9 +89,8 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?;
bpf_map_update_elem(fd, Some(&index), &socket.as_raw_fd(), flags).map_err(
|(code, io_error)| MapError::SyscallError {
|(_, io_error)| MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
},
)?;
@ -104,9 +103,8 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
self.check_bounds(*index)?;
bpf_map_delete_elem(fd, index)
.map(|_| ())
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_delete_elem".to_owned(),
code,
io_error,
})
}

@ -81,9 +81,8 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
let fd = self.inner.fd_or_err()?;
let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(
|(code, io_error)| MapError::SyscallError {
|(_, io_error)| MapError::SyscallError {
call: "bpf_map_lookup_and_delete_elem".to_owned(),
code,
io_error,
},
)?;
@ -97,10 +96,9 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
/// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
bpf_map_update_elem(fd, None::<&u32>, &value, flags).map_err(|(code, io_error)| {
bpf_map_update_elem(fd, None::<&u32>, &value, flags).map_err(|(_, io_error)| {
MapError::SyscallError {
call: "bpf_map_update_elem".to_owned(),
code,
io_error,
}
})?;

@ -86,7 +86,6 @@ impl<T: Deref<Target = Map>> StackTraceMap<T> {
sysctl::<usize>("kernel/perf_event_max_stack").map_err(|io_error| {
MapError::SyscallError {
call: "sysctl".to_owned(),
code: -1,
io_error,
}
})?;
@ -113,9 +112,8 @@ impl<T: Deref<Target = Map>> StackTraceMap<T> {
let mut frames = vec![0; self.max_stack_depth];
bpf_map_lookup_elem_ptr(fd, Some(stack_id), frames.as_mut_ptr(), flags)
.map_err(|(code, io_error)| MapError::SyscallError {
.map_err(|(_, io_error)| MapError::SyscallError {
call: "bpf_map_lookup_elem".to_owned(),
code,
io_error,
})?
.ok_or(MapError::KeyNotFound)?;

@ -19,7 +19,7 @@ use relocation::*;
use crate::{
bpf_map_def,
generated::{bpf_insn, bpf_map_type::BPF_MAP_TYPE_ARRAY, BPF_F_RDONLY_PROG},
generated::{bpf_insn, bpf_map_info, bpf_map_type::BPF_MAP_TYPE_ARRAY, BPF_F_RDONLY_PROG},
obj::btf::{Btf, BtfError, BtfExt, BtfType},
programs::{CgroupSockAddrAttachType, CgroupSockAttachType, CgroupSockoptAttachType},
BpfError, BtfMapDef, PinningType,
@ -1305,6 +1305,45 @@ fn parse_btf_map_def(btf: &Btf, info: &DataSecEntry) -> Result<(String, BtfMapDe
Ok((map_name.to_string(), map_def))
}
pub(crate) fn parse_map_info(info: bpf_map_info, pinned: PinningType) -> Map {
if info.btf_key_type_id != 0 {
Map::Btf(BtfMap {
def: BtfMapDef {
map_type: info.type_,
key_size: info.key_size,
value_size: info.value_size,
max_entries: info.max_entries,
map_flags: info.map_flags,
pinning: pinned,
btf_key_type_id: info.btf_key_type_id,
btf_value_type_id: info.btf_value_type_id,
},
section_index: 0,
symbol_index: 0,
data: Vec::new(),
// We should never be loading the .bss or .data or .rodata FDs
kind: MapKind::Other,
})
} else {
Map::Legacy(LegacyMap {
def: bpf_map_def {
map_type: info.type_,
key_size: info.key_size,
value_size: info.value_size,
max_entries: info.max_entries,
map_flags: info.map_flags,
pinning: pinned,
id: info.id,
},
section_index: 0,
symbol_index: 0,
data: Vec::new(),
// We should never be loading the .bss or .data or .rodata FDs
kind: MapKind::Other,
})
}
}
pub(crate) fn copy_instructions(data: &[u8]) -> Result<Vec<bpf_insn>, ParseError> {
if data.len() % mem::size_of::<bpf_insn>() > 0 {
return Err(ParseError::InvalidProgramCode);

@ -175,7 +175,7 @@ fn get_btf_info(prog_fd: i32, func_name: &str) -> Result<(RawFd, u32), ProgramEr
let btf_info =
sys::btf_obj_get_info_by_fd(btf_fd, &mut buf).map_err(|io_error| {
ProgramError::SyscallError {
call: "btf_obj_get_info_by_fd".to_owned(),
call: "bpf_prog_get_info_by_fd".to_owned(),
io_error,
}
})?;
@ -185,7 +185,7 @@ fn get_btf_info(prog_fd: i32, func_name: &str) -> Result<(RawFd, u32), ProgramEr
}
}
Err(io_error) => Err(ProgramError::SyscallError {
call: "btf_obj_get_info_by_fd".to_owned(),
call: "bpf_prog_get_info_by_fd".to_owned(),
io_error,
}),
}?;

@ -11,8 +11,8 @@ use libc::{c_char, c_long, close, ENOENT, ENOSPC};
use crate::{
generated::{
bpf_attach_type, bpf_attr, bpf_btf_info, bpf_cmd, bpf_insn, bpf_link_info, bpf_prog_info,
bpf_prog_type, BPF_F_REPLACE,
bpf_attach_type, bpf_attr, bpf_btf_info, bpf_cmd, bpf_insn, bpf_link_info, bpf_map_info,
bpf_prog_info, bpf_prog_type, BPF_F_REPLACE,
},
maps::PerCpuValues,
obj::{
@ -439,14 +439,29 @@ pub(crate) fn bpf_prog_get_fd_by_id(prog_id: u32) -> Result<RawFd, io::Error> {
pub(crate) fn bpf_prog_get_info_by_fd(prog_fd: RawFd) -> Result<bpf_prog_info, io::Error> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
// info gets entirely populated by the kernel
let info = unsafe { MaybeUninit::zeroed().assume_init() };
let info = MaybeUninit::zeroed();
attr.info.bpf_fd = prog_fd as u32;
attr.info.info = &info as *const _ as u64;
attr.info.info_len = mem::size_of::<bpf_prog_info>() as u32;
match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &attr) {
Ok(_) => Ok(info),
Ok(_) => Ok(unsafe { info.assume_init() }),
Err((_, err)) => Err(err),
}
}
pub(crate) fn bpf_map_get_info_by_fd(prog_fd: RawFd) -> Result<bpf_map_info, io::Error> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
// info gets entirely populated by the kernel
let info = MaybeUninit::zeroed();
attr.info.bpf_fd = prog_fd as u32;
attr.info.info = info.as_ptr() as *const _ as u64;
attr.info.info_len = mem::size_of::<bpf_map_info>() as u32;
match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &attr) {
Ok(_) => Ok(unsafe { info.assume_init() }),
Err((_, err)) => Err(err),
}
}

Loading…
Cancel
Save