aya: encode bpf(2) contract

Per man 2 bpf:

> RETURN VALUE
>   For a successful call, the return value depends on the operation:
>
>   BPF_MAP_CREATE
>     The new file descriptor associated with the eBPF map.
>
>   BPF_PROG_LOAD
>     The new file descriptor associated with the eBPF program.
>
>   All other commands
>     Zero.
>
>   On error, -1 is returned, and errno is set to indicate the error.

Bake this into our syscalls so we stop using `_` so much which can hide
information loss.
reviewable/pr1194/r1
Tamir Duberstein 2 weeks ago
parent 2d782606fe
commit f6df60fa70

@ -1131,7 +1131,7 @@ fn load_btf(
let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| { let (ret, verifier_log) = retry_with_verifier_logs(10, |logger| {
bpf_load_btf(raw_btf.as_slice(), logger, verifier_log_level) bpf_load_btf(raw_btf.as_slice(), logger, verifier_log_level)
}); });
ret.map_err(|(_, io_error)| BtfError::LoadError { ret.map_err(|io_error| BtfError::LoadError {
io_error, io_error,
verifier_log, verifier_log,
}) })

@ -64,11 +64,10 @@ impl<T: Borrow<MapData>, V: Pod> Array<T, V> {
check_bounds(data, *index)?; check_bounds(data, *index)?;
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
let value = let value = bpf_map_lookup_elem(fd, index, flags).map_err(|io_error| SyscallError {
bpf_map_lookup_elem(fd, index, flags).map_err(|(_, io_error)| SyscallError { call: "bpf_map_lookup_elem",
call: "bpf_map_lookup_elem", io_error,
io_error, })?;
})?;
value.ok_or(MapError::KeyNotFound) value.ok_or(MapError::KeyNotFound)
} }
@ -90,7 +89,7 @@ impl<T: BorrowMut<MapData>, V: Pod> Array<T, V> {
let data = self.inner.borrow_mut(); let data = self.inner.borrow_mut();
check_bounds(data, index)?; check_bounds(data, index)?;
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
bpf_map_update_elem(fd, Some(&index), value.borrow(), flags).map_err(|(_, io_error)| { bpf_map_update_elem(fd, Some(&index), value.borrow(), flags).map_err(|io_error| {
SyscallError { SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,

@ -83,12 +83,11 @@ impl<T: Borrow<MapData>, V: Pod> PerCpuArray<T, V> {
check_bounds(data, *index)?; check_bounds(data, *index)?;
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
let value = bpf_map_lookup_elem_per_cpu(fd, index, flags).map_err(|(_, io_error)| { let value =
SyscallError { bpf_map_lookup_elem_per_cpu(fd, index, flags).map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
} })?;
})?;
value.ok_or(MapError::KeyNotFound) value.ok_or(MapError::KeyNotFound)
} }
@ -111,7 +110,7 @@ impl<T: BorrowMut<MapData>, V: Pod> PerCpuArray<T, V> {
check_bounds(data, index)?; check_bounds(data, index)?;
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
bpf_map_update_elem_per_cpu(fd, &index, &values, flags).map_err(|(_, io_error)| { bpf_map_update_elem_per_cpu(fd, &index, &values, flags).map_err(|io_error| {
SyscallError { SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,

@ -78,13 +78,12 @@ impl<T: BorrowMut<MapData>> ProgramArray<T> {
let prog_fd = program.as_fd(); let prog_fd = program.as_fd();
let prog_fd = prog_fd.as_raw_fd(); let prog_fd = prog_fd.as_raw_fd();
bpf_map_update_elem(fd, Some(&index), &prog_fd, flags).map_err(|(_, io_error)| { bpf_map_update_elem(fd, Some(&index), &prog_fd, flags)
SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
} })
})?; .map_err(Into::into)
Ok(())
} }
/// Clears the value at index in the jump table. /// Clears the value at index in the jump table.
@ -97,13 +96,10 @@ impl<T: BorrowMut<MapData>> ProgramArray<T> {
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
bpf_map_delete_elem(fd, index) bpf_map_delete_elem(fd, index)
.map(|_| ()) .map_err(|io_error| SyscallError {
.map_err(|(_, io_error)| { call: "bpf_map_delete_elem",
SyscallError { io_error,
call: "bpf_map_delete_elem",
io_error,
}
.into()
}) })
.map_err(Into::into)
} }
} }

@ -56,13 +56,15 @@ impl<T: Borrow<MapData>, V: Pod> BloomFilter<T, V> {
pub fn contains(&self, mut value: &V, flags: u64) -> Result<(), MapError> { pub fn contains(&self, mut value: &V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
bpf_map_lookup_elem_ptr::<u32, _>(fd, None, &mut value, flags) match bpf_map_lookup_elem_ptr::<u32, _>(fd, None, &mut value, flags).map_err(
.map_err(|(_, io_error)| SyscallError { |io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})? },
.ok_or(MapError::ElementNotFound)?; )? {
Ok(()) None => Err(MapError::ElementNotFound),
Some(()) => Ok(()),
}
} }
} }
@ -70,11 +72,12 @@ impl<T: BorrowMut<MapData>, V: Pod> BloomFilter<T, V> {
/// Inserts a value into the map. /// Inserts a value into the map.
pub fn insert(&mut self, value: impl Borrow<V>, flags: u64) -> Result<(), MapError> { pub fn insert(&mut self, value: impl Borrow<V>, flags: u64) -> Result<(), MapError> {
let fd = self.inner.borrow_mut().fd().as_fd(); let fd = self.inner.borrow_mut().fd().as_fd();
bpf_map_push_elem(fd, value.borrow(), flags).map_err(|(_, io_error)| SyscallError { bpf_map_push_elem(fd, value.borrow(), flags)
call: "bpf_map_push_elem", .map_err(|io_error| SyscallError {
io_error, call: "bpf_map_push_elem",
})?; io_error,
Ok(()) })
.map_err(Into::into)
} }
} }
@ -166,7 +169,7 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM, cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM,
.. ..
} => Ok(1), } => Ok(0),
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });

@ -54,7 +54,7 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> HashMap<T, K, V> {
/// Returns a copy of the value associated with the key. /// Returns a copy of the value associated with the key.
pub fn get(&self, key: &K, flags: u64) -> Result<V, MapError> { pub fn get(&self, key: &K, flags: u64) -> Result<V, MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| SyscallError { let value = bpf_map_lookup_elem(fd, key, flags).map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})?; })?;
@ -220,7 +220,7 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM, cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM,
.. ..
} => Ok(1), } => Ok(0),
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
@ -236,7 +236,7 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM, cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM,
.. ..
} => Ok(1), } => Ok(0),
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
@ -265,7 +265,7 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_DELETE_ELEM, cmd: bpf_cmd::BPF_MAP_DELETE_ELEM,
.. ..
} => Ok(1), } => Ok(0),
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
@ -306,14 +306,16 @@ mod tests {
} }
} }
fn set_next_key<T: Copy>(attr: &bpf_attr, next: T) { fn set_next_key<T: Copy>(attr: &bpf_attr, next: T) -> SysResult<c_long> {
let key = unsafe { attr.__bindgen_anon_2.__bindgen_anon_1.next_key } as *const T as *mut T; let key = unsafe { attr.__bindgen_anon_2.__bindgen_anon_1.next_key } as *const T as *mut T;
unsafe { *key = next }; unsafe { *key = next };
Ok(0)
} }
fn set_ret<T: Copy>(attr: &bpf_attr, ret: T) { fn set_ret<T: Copy>(attr: &bpf_attr, ret: T) -> SysResult<c_long> {
let value = unsafe { attr.__bindgen_anon_2.__bindgen_anon_1.value } as *const T as *mut T; let value = unsafe { attr.__bindgen_anon_2.__bindgen_anon_1.value } as *const T as *mut T;
unsafe { *value = ret }; unsafe { *value = ret };
Ok(0)
} }
#[test] #[test]
@ -336,11 +338,9 @@ mod tests {
None => set_next_key(attr, 10), None => set_next_key(attr, 10),
Some(10) => set_next_key(attr, 20), Some(10) => set_next_key(attr, 20),
Some(20) => set_next_key(attr, 30), Some(20) => set_next_key(attr, 30),
Some(30) => return sys_error(ENOENT), Some(30) => sys_error(ENOENT),
Some(_) => return sys_error(EFAULT), Some(_) => sys_error(EFAULT),
}; }
Ok(1)
} }
fn lookup_elem(attr: &bpf_attr) -> SysResult<c_long> { fn lookup_elem(attr: &bpf_attr) -> SysResult<c_long> {
@ -348,11 +348,9 @@ mod tests {
Some(10) => set_ret(attr, 100), Some(10) => set_ret(attr, 100),
Some(20) => set_ret(attr, 200), Some(20) => set_ret(attr, 200),
Some(30) => set_ret(attr, 300), Some(30) => set_ret(attr, 300),
Some(_) => return sys_error(ENOENT), Some(_) => sys_error(ENOENT),
None => return sys_error(EFAULT), None => sys_error(EFAULT),
}; }
Ok(1)
} }
#[test] #[test]
@ -380,15 +378,11 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_GET_NEXT_KEY, cmd: bpf_cmd::BPF_MAP_GET_NEXT_KEY,
attr, attr,
} => { } => match bpf_key(attr) {
match bpf_key(attr) { None => set_next_key(attr, 10),
None => set_next_key(attr, 10), Some(10) => set_next_key(attr, 20),
Some(10) => set_next_key(attr, 20), Some(_) => sys_error(EFAULT),
Some(_) => return sys_error(EFAULT), },
};
Ok(1)
}
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); let hm = HashMap::<_, u32, u32>::new(&map).unwrap();
@ -436,17 +430,13 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_LOOKUP_ELEM, cmd: bpf_cmd::BPF_MAP_LOOKUP_ELEM,
attr, attr,
} => { } => match bpf_key(attr) {
match bpf_key(attr) { Some(10) => set_ret(attr, 100),
Some(10) => set_ret(attr, 100), Some(20) => sys_error(ENOENT),
Some(20) => return sys_error(ENOENT), Some(30) => set_ret(attr, 300),
Some(30) => set_ret(attr, 300), Some(_) => sys_error(ENOENT),
Some(_) => return sys_error(ENOENT), None => sys_error(EFAULT),
None => return sys_error(EFAULT), },
};
Ok(1)
}
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); let hm = HashMap::<_, u32, u32>::new(&map).unwrap();
@ -462,17 +452,13 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_GET_NEXT_KEY, cmd: bpf_cmd::BPF_MAP_GET_NEXT_KEY,
attr, attr,
} => { } => match bpf_key(attr) {
match bpf_key(attr) { None => set_next_key(attr, 10),
None => set_next_key(attr, 10), Some(10) => set_next_key(attr, 20),
Some(10) => set_next_key(attr, 20), Some(20) => sys_error(EFAULT),
Some(20) => return sys_error(EFAULT), Some(30) => sys_error(ENOENT),
Some(30) => return sys_error(ENOENT), Some(i) => panic!("invalid key {}", i),
Some(i) => panic!("invalid key {}", i), },
};
Ok(1)
}
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_LOOKUP_ELEM, cmd: bpf_cmd::BPF_MAP_LOOKUP_ELEM,
attr, attr,
@ -505,17 +491,13 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_LOOKUP_ELEM, cmd: bpf_cmd::BPF_MAP_LOOKUP_ELEM,
attr, attr,
} => { } => match bpf_key(attr) {
match bpf_key(attr) { Some(10) => set_ret(attr, 100),
Some(10) => set_ret(attr, 100), Some(20) => sys_error(EFAULT),
Some(20) => return sys_error(EFAULT), Some(30) => set_ret(attr, 300),
Some(30) => set_ret(attr, 300), Some(_) => sys_error(ENOENT),
Some(_) => return sys_error(ENOENT), None => sys_error(EFAULT),
None => return sys_error(EFAULT), },
};
Ok(1)
}
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
let hm = HashMap::<_, u32, u32>::new(&map).unwrap(); let hm = HashMap::<_, u32, u32>::new(&map).unwrap();

@ -23,23 +23,20 @@ pub(crate) fn insert<K: Pod, V: Pod>(
flags: u64, flags: u64,
) -> Result<(), MapError> { ) -> Result<(), MapError> {
let fd = map.fd().as_fd(); let fd = map.fd().as_fd();
bpf_map_update_elem(fd, Some(key), value, flags).map_err(|(_, io_error)| SyscallError { bpf_map_update_elem(fd, Some(key), value, flags)
call: "bpf_map_update_elem", .map_err(|io_error| SyscallError {
io_error, call: "bpf_map_update_elem",
})?; io_error,
})
Ok(()) .map_err(Into::into)
} }
pub(crate) fn remove<K: Pod>(map: &MapData, key: &K) -> Result<(), MapError> { pub(crate) fn remove<K: Pod>(map: &MapData, key: &K) -> Result<(), MapError> {
let fd = map.fd().as_fd(); let fd = map.fd().as_fd();
bpf_map_delete_elem(fd, key) bpf_map_delete_elem(fd, key)
.map(|_| ()) .map_err(|io_error| SyscallError {
.map_err(|(_, io_error)| { call: "bpf_map_delete_elem",
SyscallError { io_error,
call: "bpf_map_delete_elem",
io_error,
}
.into()
}) })
.map_err(Into::into)
} }

@ -64,7 +64,7 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
pub fn get(&self, key: &K, flags: u64) -> Result<PerCpuValues<V>, MapError> { pub fn get(&self, key: &K, flags: u64) -> Result<PerCpuValues<V>, MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
let values = let values =
bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|(_, io_error)| SyscallError { bpf_map_lookup_elem_per_cpu(fd, key, flags).map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})?; })?;
@ -121,14 +121,12 @@ impl<T: BorrowMut<MapData>, K: Pod, V: Pod> PerCpuHashMap<T, K, V> {
flags: u64, flags: u64,
) -> Result<(), MapError> { ) -> Result<(), MapError> {
let fd = self.inner.borrow_mut().fd().as_fd(); let fd = self.inner.borrow_mut().fd().as_fd();
bpf_map_update_elem_per_cpu(fd, key.borrow(), &values, flags).map_err( bpf_map_update_elem_per_cpu(fd, key.borrow(), &values, flags)
|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
}, })
)?; .map_err(Into::into)
Ok(())
} }
/// Removes a key from the map. /// Removes a key from the map.

@ -121,7 +121,7 @@ impl MapInfo {
// TODO: avoid this unwrap by adding a new error variant. // TODO: avoid this unwrap by adding a new error variant.
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap(); let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
})?; })?;

@ -127,7 +127,7 @@ impl<T: Borrow<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
/// Returns a copy of the value associated with the longest prefix matching key in the LpmTrie. /// 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> { pub fn get(&self, key: &Key<K>, flags: u64) -> Result<V, MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| SyscallError { let value = bpf_map_lookup_elem(fd, key, flags).map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})?; })?;
@ -156,14 +156,12 @@ impl<T: BorrowMut<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
flags: u64, flags: u64,
) -> Result<(), MapError> { ) -> Result<(), MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
bpf_map_update_elem(fd, Some(key), value.borrow(), flags).map_err(|(_, io_error)| { bpf_map_update_elem(fd, Some(key), value.borrow(), flags)
SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
} })
})?; .map_err(Into::into)
Ok(())
} }
/// Removes an element from the map. /// Removes an element from the map.
@ -172,14 +170,11 @@ impl<T: BorrowMut<MapData>, K: Pod, V: Pod> LpmTrie<T, K, V> {
pub fn remove(&mut self, key: &Key<K>) -> Result<(), MapError> { pub fn remove(&mut self, key: &Key<K>) -> Result<(), MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
bpf_map_delete_elem(fd, key) bpf_map_delete_elem(fd, key)
.map(|_| ()) .map_err(|io_error| SyscallError {
.map_err(|(_, io_error)| { call: "bpf_map_delete_elem",
SyscallError { io_error,
call: "bpf_map_delete_elem",
io_error,
}
.into()
}) })
.map_err(Into::into)
} }
} }
@ -297,7 +292,7 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM, cmd: bpf_cmd::BPF_MAP_UPDATE_ELEM,
.. ..
} => Ok(1), } => Ok(0),
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });
@ -330,7 +325,7 @@ mod tests {
Syscall::Ebpf { Syscall::Ebpf {
cmd: bpf_cmd::BPF_MAP_DELETE_ELEM, cmd: bpf_cmd::BPF_MAP_DELETE_ELEM,
.. ..
} => Ok(1), } => Ok(0),
_ => sys_error(EFAULT), _ => sys_error(EFAULT),
}); });

@ -49,7 +49,7 @@
//! implement the [Pod] trait. //! implement the [Pod] trait.
use std::{ use std::{
borrow::Borrow, borrow::Borrow,
ffi::{c_long, CString}, ffi::CString,
fmt, io, fmt, io,
marker::PhantomData, marker::PhantomData,
mem, mem,
@ -123,12 +123,10 @@ pub enum MapError {
}, },
/// Failed to create map /// Failed to create map
#[error("failed to create map `{name}` with code {code}")] #[error("failed to create map `{name}`")]
CreateError { CreateError {
/// Map name /// Map name
name: String, name: String,
/// Error code
code: c_long,
#[source] #[source]
/// Original io::Error /// Original io::Error
io_error: io::Error, io_error: io::Error,
@ -584,18 +582,16 @@ impl MapData {
let kernel_version = KernelVersion::current().unwrap(); let kernel_version = KernelVersion::current().unwrap();
#[cfg(test)] #[cfg(test)]
let kernel_version = KernelVersion::new(0xff, 0xff, 0xff); let kernel_version = KernelVersion::new(0xff, 0xff, 0xff);
let fd = let fd = bpf_create_map(&c_name, &obj, btf_fd, kernel_version).map_err(|io_error| {
bpf_create_map(&c_name, &obj, btf_fd, kernel_version).map_err(|(code, io_error)| { if kernel_version < KernelVersion::new(5, 11, 0) {
if kernel_version < KernelVersion::new(5, 11, 0) { maybe_warn_rlimit();
maybe_warn_rlimit(); }
}
MapError::CreateError { MapError::CreateError {
name: name.into(), name: name.into(),
code, io_error,
io_error, }
} })?;
})?;
Ok(Self { Ok(Self {
obj, obj,
fd: MapFd::from_fd(fd), fd: MapFd::from_fd(fd),
@ -621,7 +617,7 @@ impl MapData {
}); });
} }
}; };
match bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { match bpf_get_object(&path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
}) { }) {
@ -644,7 +640,7 @@ impl MapData {
let Self { obj, fd } = self; let Self { obj, fd } = self;
if !obj.data().is_empty() { if !obj.data().is_empty() {
bpf_map_update_elem_ptr(fd.as_fd(), &0 as *const _, obj.data_mut().as_mut_ptr(), 0) bpf_map_update_elem_ptr(fd.as_fd(), &0 as *const _, obj.data_mut().as_mut_ptr(), 0)
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
}) })
@ -652,7 +648,7 @@ impl MapData {
} }
if obj.section_kind() == EbpfSectionKind::Rodata { if obj.section_kind() == EbpfSectionKind::Rodata {
bpf_map_freeze(fd.as_fd()) bpf_map_freeze(fd.as_fd())
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_freeze", call: "bpf_map_freeze",
io_error, io_error,
}) })
@ -675,7 +671,7 @@ impl MapData {
}, },
})?; })?;
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
})?; })?;
@ -742,7 +738,7 @@ impl MapData {
error, error,
} }
})?; })?;
bpf_pin_object(fd.as_fd(), &path_string).map_err(|(_, io_error)| SyscallError { bpf_pin_object(fd.as_fd(), &path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_PIN", call: "BPF_OBJ_PIN",
io_error, io_error,
})?; })?;
@ -801,11 +797,10 @@ impl<K: Pod> Iterator for MapKeys<'_, K> {
} }
let fd = self.map.fd().as_fd(); let fd = self.map.fd().as_fd();
let key = let key = bpf_map_get_next_key(fd, self.key.as_ref()).map_err(|io_error| SyscallError {
bpf_map_get_next_key(fd, self.key.as_ref()).map_err(|(_, io_error)| SyscallError { call: "bpf_map_get_next_key",
call: "bpf_map_get_next_key", io_error,
io_error, });
});
match key { match key {
Err(err) => { Err(err) => {
self.err = true; self.err = true;
@ -1305,13 +1300,12 @@ mod tests {
#[test] #[test]
fn test_create_failed() { fn test_create_failed() {
override_syscall(|_| Err((-42, io::Error::from_raw_os_error(EFAULT)))); override_syscall(|_| Err((-1, io::Error::from_raw_os_error(EFAULT))));
assert_matches!( assert_matches!(
MapData::create(new_obj_map(), "foo", None), MapData::create(new_obj_map(), "foo", None),
Err(MapError::CreateError { name, code, io_error }) => { Err(MapError::CreateError { name, io_error }) => {
assert_eq!(name, "foo"); assert_eq!(name, "foo");
assert_eq!(code, -42);
assert_eq!(io_error.raw_os_error(), Some(EFAULT)); assert_eq!(io_error.raw_os_error(), Some(EFAULT));
} }
); );

@ -199,8 +199,7 @@ impl<T: BorrowMut<MapData>> PerfEventArray<T> {
let map_data: &MapData = self.map.deref().borrow(); let map_data: &MapData = self.map.deref().borrow();
let map_fd = map_data.fd().as_fd(); let map_fd = map_data.fd().as_fd();
let buf = PerfBuffer::open(index, self.page_size, page_count.unwrap_or(2))?; let buf = PerfBuffer::open(index, self.page_size, page_count.unwrap_or(2))?;
bpf_map_update_elem(map_fd, Some(&index), &buf.as_fd().as_raw_fd(), 0) bpf_map_update_elem(map_fd, Some(&index), &buf.as_fd().as_raw_fd(), 0)?;
.map_err(|(_, io_error)| io_error)?;
Ok(PerfEventArrayBuffer { Ok(PerfEventArrayBuffer {
buf, buf,

@ -63,12 +63,13 @@ impl<T: BorrowMut<MapData>, V: Pod> Queue<T, V> {
pub fn pop(&mut self, flags: u64) -> Result<V, MapError> { pub fn pop(&mut self, flags: u64) -> Result<V, MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err( let value =
|(_, io_error)| SyscallError { bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(|io_error| {
call: "bpf_map_lookup_and_delete_elem", SyscallError {
io_error, call: "bpf_map_lookup_and_delete_elem",
}, io_error,
)?; }
})?;
value.ok_or(MapError::ElementNotFound) value.ok_or(MapError::ElementNotFound)
} }
@ -79,10 +80,11 @@ impl<T: BorrowMut<MapData>, V: Pod> Queue<T, V> {
/// [`MapError::SyscallError`] if `bpf_map_update_elem` fails. /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
pub fn push(&mut self, value: impl Borrow<V>, flags: u64) -> Result<(), MapError> { pub fn push(&mut self, value: impl Borrow<V>, flags: u64) -> Result<(), MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
bpf_map_push_elem(fd, value.borrow(), flags).map_err(|(_, io_error)| SyscallError { bpf_map_push_elem(fd, value.borrow(), flags)
call: "bpf_map_push_elem", .map_err(|io_error| SyscallError {
io_error, call: "bpf_map_push_elem",
})?; io_error,
Ok(()) })
.map_err(Into::into)
} }
} }

@ -83,7 +83,7 @@ impl<T: Borrow<MapData>, K: Pod> SockHash<T, K> {
/// Returns the fd of the socket stored at the given key. /// Returns the fd of the socket stored at the given key.
pub fn get(&self, key: &K, flags: u64) -> Result<RawFd, MapError> { pub fn get(&self, key: &K, flags: u64) -> Result<RawFd, MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(_, io_error)| SyscallError { let value = bpf_map_lookup_elem(fd, key, flags).map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})?; })?;

@ -87,13 +87,12 @@ impl<T: BorrowMut<MapData>> SockMap<T> {
let data = self.inner.borrow_mut(); let data = self.inner.borrow_mut();
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
check_bounds(data, index)?; check_bounds(data, index)?;
bpf_map_update_elem(fd, Some(&index), &socket.as_raw_fd(), flags).map_err( bpf_map_update_elem(fd, Some(&index), &socket.as_raw_fd(), flags)
|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
}, })
)?; .map_err(Into::into)
Ok(())
} }
/// Removes the socket stored at `index` from the map. /// Removes the socket stored at `index` from the map.
@ -102,13 +101,10 @@ impl<T: BorrowMut<MapData>> SockMap<T> {
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
check_bounds(data, *index)?; check_bounds(data, *index)?;
bpf_map_delete_elem(fd, index) bpf_map_delete_elem(fd, index)
.map(|_| ()) .map_err(|io_error| SyscallError {
.map_err(|(_, io_error)| { call: "bpf_map_delete_elem",
SyscallError { io_error,
call: "bpf_map_delete_elem",
io_error,
}
.into()
}) })
.map_err(Into::into)
} }
} }

@ -63,12 +63,13 @@ impl<T: BorrowMut<MapData>, V: Pod> Stack<T, V> {
pub fn pop(&mut self, flags: u64) -> Result<V, MapError> { pub fn pop(&mut self, flags: u64) -> Result<V, MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
let value = bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err( let value =
|(_, io_error)| SyscallError { bpf_map_lookup_and_delete_elem::<u32, _>(fd, None, flags).map_err(|io_error| {
call: "bpf_map_lookup_and_delete_elem", SyscallError {
io_error, call: "bpf_map_lookup_and_delete_elem",
}, io_error,
)?; }
})?;
value.ok_or(MapError::ElementNotFound) value.ok_or(MapError::ElementNotFound)
} }
@ -79,12 +80,11 @@ impl<T: BorrowMut<MapData>, V: Pod> Stack<T, V> {
/// [`MapError::SyscallError`] if `bpf_map_update_elem` fails. /// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
pub fn push(&mut self, value: impl Borrow<V>, flags: u64) -> Result<(), MapError> { pub fn push(&mut self, value: impl Borrow<V>, flags: u64) -> Result<(), MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
bpf_map_update_elem(fd, None::<&u32>, value.borrow(), flags).map_err(|(_, io_error)| { bpf_map_update_elem(fd, None::<&u32>, value.borrow(), flags)
SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
} })
})?; .map_err(Into::into)
Ok(())
} }
} }

@ -113,7 +113,7 @@ impl<T: Borrow<MapData>> StackTraceMap<T> {
let mut frames = vec![0; self.max_stack_depth]; let mut frames = vec![0; self.max_stack_depth];
bpf_map_lookup_elem_ptr(fd, Some(stack_id), frames.as_mut_ptr(), flags) bpf_map_lookup_elem_ptr(fd, Some(stack_id), frames.as_mut_ptr(), flags)
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})? })?
@ -168,14 +168,11 @@ impl<T: BorrowMut<MapData>> StackTraceMap<T> {
pub fn remove(&mut self, stack_id: &u32) -> Result<(), MapError> { pub fn remove(&mut self, stack_id: &u32) -> Result<(), MapError> {
let fd = self.inner.borrow().fd().as_fd(); let fd = self.inner.borrow().fd().as_fd();
bpf_map_delete_elem(fd, stack_id) bpf_map_delete_elem(fd, stack_id)
.map(|_| ()) .map_err(|io_error| SyscallError {
.map_err(|(_, io_error)| { call: "bpf_map_delete_elem",
SyscallError { io_error,
call: "bpf_map_delete_elem",
io_error,
}
.into()
}) })
.map_err(Into::into)
} }
} }

@ -103,7 +103,7 @@ impl<T: Borrow<MapData>> CpuMap<T> {
}) })
}; };
value value
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})? })?
@ -163,13 +163,13 @@ impl<T: BorrowMut<MapData>> CpuMap<T> {
bpf_map_update_elem(fd, Some(&cpu_index), &queue_size, flags) bpf_map_update_elem(fd, Some(&cpu_index), &queue_size, flags)
}; };
res.map_err(|(_, io_error)| { res.map_err(|io_error| {
MapError::from(SyscallError { MapError::from(SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
}) })
})?; })
Ok(()) .map_err(Into::into)
} }
} }

@ -94,7 +94,7 @@ impl<T: Borrow<MapData>> DevMap<T> {
}) })
}; };
value value
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})? })?
@ -154,13 +154,13 @@ impl<T: BorrowMut<MapData>> DevMap<T> {
bpf_map_update_elem(fd, Some(&index), &target_if_index, flags) bpf_map_update_elem(fd, Some(&index), &target_if_index, flags)
}; };
res.map_err(|(_, io_error)| { res.map_err(|io_error| {
MapError::from(SyscallError { MapError::from(SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
}) })
})?; })
Ok(()) .map_err(Into::into)
} }
} }

@ -84,7 +84,7 @@ impl<T: Borrow<MapData>> DevMapHash<T> {
}) })
}; };
value value
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_lookup_elem", call: "bpf_map_lookup_elem",
io_error, io_error,
})? })?

@ -70,12 +70,11 @@ impl<T: BorrowMut<MapData>> XskMap<T> {
let data = self.inner.borrow_mut(); let data = self.inner.borrow_mut();
check_bounds(data, index)?; check_bounds(data, index)?;
let fd = data.fd().as_fd(); let fd = data.fd().as_fd();
bpf_map_update_elem(fd, Some(&index), &socket_fd.as_raw_fd(), flags).map_err( bpf_map_update_elem(fd, Some(&index), &socket_fd.as_raw_fd(), flags)
|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_map_update_elem", call: "bpf_map_update_elem",
io_error, io_error,
}, })
)?; .map_err(Into::into)
Ok(())
} }
} }

@ -81,7 +81,7 @@ impl CgroupDevice {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -107,7 +107,7 @@ impl CgroupSkb {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -84,7 +84,7 @@ impl CgroupSock {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -85,7 +85,7 @@ impl CgroupSockAddr {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -82,7 +82,7 @@ impl CgroupSockopt {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -80,7 +80,7 @@ impl CgroupSysctl {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -106,7 +106,7 @@ impl Extension {
0, 0,
Some(BpfLinkCreateArgs::TargetBtfId(btf_id)), Some(BpfLinkCreateArgs::TargetBtfId(btf_id)),
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;
@ -143,7 +143,7 @@ impl Extension {
0, 0,
Some(BpfLinkCreateArgs::TargetBtfId(btf_id)), Some(BpfLinkCreateArgs::TargetBtfId(btf_id)),
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -214,7 +214,7 @@ impl ProgramInfo {
// TODO: avoid this unwrap by adding a new error variant. // TODO: avoid this unwrap by adding a new error variant.
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap(); let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
})?; })?;

@ -76,7 +76,7 @@ impl Iter {
let prog_fd = self.fd()?; let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let link_fd = bpf_link_create(prog_fd, LinkTarget::Iter, BPF_TRACE_ITER, 0, None).map_err( let link_fd = bpf_link_create(prog_fd, LinkTarget::Iter, BPF_TRACE_ITER, 0, None).map_err(
|(_, io_error)| SyscallError { |io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
@ -140,10 +140,10 @@ impl IterLink {
/// outputs of the iterator program. /// outputs of the iterator program.
pub fn into_file(self) -> Result<File, LinkError> { pub fn into_file(self) -> Result<File, LinkError> {
if let PerfLinkInner::FdLink(fd) = self.into_inner() { if let PerfLinkInner::FdLink(fd) = self.into_inner() {
let fd = bpf_create_iter(fd.fd.as_fd()).map_err(|(_, error)| { let fd = bpf_create_iter(fd.fd.as_fd()).map_err(|io_error| {
LinkError::SyscallError(SyscallError { LinkError::SyscallError(SyscallError {
call: "bpf_iter_create", call: "bpf_iter_create",
io_error: error, io_error,
}) })
})?; })?;
Ok(fd.into_inner().into()) Ok(fd.into_inner().into())

@ -183,7 +183,7 @@ impl FdLink {
error, error,
} }
})?; })?;
bpf_pin_object(self.fd.as_fd(), &path_string).map_err(|(_, io_error)| SyscallError { bpf_pin_object(self.fd.as_fd(), &path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_PIN", call: "BPF_OBJ_PIN",
io_error, io_error,
})?; })?;
@ -238,7 +238,7 @@ impl PinnedLink {
// TODO: avoid this unwrap by adding a new error variant. // TODO: avoid this unwrap by adding a new error variant.
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap(); let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| { let fd = bpf_get_object(&path_string).map_err(|io_error| {
LinkError::SyscallError(SyscallError { LinkError::SyscallError(SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,

@ -569,7 +569,7 @@ impl<T: Link> ProgramData<T> {
// TODO: avoid this unwrap by adding a new error variant. // TODO: avoid this unwrap by adding a new error variant.
let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap(); let path_string = CString::new(path.as_ref().as_os_str().as_bytes()).unwrap();
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|io_error| SyscallError {
call: "bpf_obj_get", call: "bpf_obj_get",
io_error, io_error,
})?; })?;
@ -610,7 +610,7 @@ fn pin_program<T: Link, P: AsRef<Path>>(data: &ProgramData<T>, path: P) -> Resul
path: path.into(), path: path.into(),
error, error,
})?; })?;
bpf_pin_object(fd.as_fd(), &path_string).map_err(|(_, io_error)| SyscallError { bpf_pin_object(fd.as_fd(), &path_string).map_err(|io_error| SyscallError {
call: "BPF_OBJ_PIN", call: "BPF_OBJ_PIN",
io_error, io_error,
})?; })?;
@ -701,7 +701,7 @@ fn load_program<T: Link>(
*fd = Some(ProgramFd(prog_fd)); *fd = Some(ProgramFd(prog_fd));
Ok(()) Ok(())
} }
Err((_, io_error)) => Err(ProgramError::LoadError { Err(io_error) => Err(ProgramError::LoadError {
io_error, io_error,
verifier_log, verifier_log,
}), }),
@ -734,7 +734,7 @@ pub(crate) fn query(
prog_ids.resize(prog_cnt as usize, 0); prog_ids.resize(prog_cnt as usize, 0);
return Ok((revision, prog_ids)); return Ok((revision, prog_ids));
} }
Err((_, io_error)) => { Err(io_error) => {
if retries == 0 && io_error.raw_os_error() == Some(ENOSPC) { if retries == 0 && io_error.raw_os_error() == Some(ENOSPC) {
prog_ids.resize(prog_cnt as usize, 0); prog_ids.resize(prog_cnt as usize, 0);
retries += 1; retries += 1;

@ -98,7 +98,7 @@ pub(crate) fn perf_attach(
0, 0,
cookie.map(|bpf_cookie| BpfLinkCreateArgs::PerfEvent { bpf_cookie }), cookie.map(|bpf_cookie| BpfLinkCreateArgs::PerfEvent { bpf_cookie }),
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -176,13 +176,12 @@ fn create_as_probe(
_ => None, _ => None,
}; };
perf_event_open_probe(perf_ty, ret_bit, fn_name, offset, pid).map_err(|(_code, io_error)| { perf_event_open_probe(perf_ty, ret_bit, fn_name, offset, pid)
SyscallError { .map_err(|(_code, io_error)| SyscallError {
call: "perf_event_open", call: "perf_event_open",
io_error, io_error,
} })
.into() .map_err(Into::into)
})
} }
fn create_as_trace_point( fn create_as_trace_point(

@ -67,7 +67,7 @@ impl SkLookup {
let netns_fd = netns.as_fd(); let netns_fd = netns.as_fd();
let link_fd = bpf_link_create(prog_fd, LinkTarget::Fd(netns_fd), BPF_SK_LOOKUP, 0, None) let link_fd = bpf_link_create(prog_fd, LinkTarget::Fd(netns_fd), BPF_SK_LOOKUP, 0, None)
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -79,7 +79,7 @@ impl SockOps {
mode.into(), mode.into(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;

@ -232,7 +232,7 @@ impl SchedClassifier {
let fd = link.fd; let fd = link.fd;
let link_fd = fd.as_fd(); let link_fd = fd.as_fd();
bpf_link_update(link_fd.as_fd(), prog_fd, None, 0).map_err(|(_, io_error)| { bpf_link_update(link_fd.as_fd(), prog_fd, None, 0).map_err(|io_error| {
SyscallError { SyscallError {
call: "bpf_link_update", call: "bpf_link_update",
io_error, io_error,
@ -304,7 +304,7 @@ impl SchedClassifier {
options.flags.bits(), options.flags.bits(),
Some(BpfLinkCreateArgs::Tcx(&options.link_ref)), Some(BpfLinkCreateArgs::Tcx(&options.link_ref)),
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_mprog_attach", call: "bpf_mprog_attach",
io_error, io_error,
})?; })?;

@ -21,11 +21,10 @@ pub(crate) fn attach_raw_tracepoint<T: Link + From<FdLink>>(
) -> Result<T::Id, ProgramError> { ) -> Result<T::Id, ProgramError> {
let prog_fd = program_data.fd()?; let prog_fd = program_data.fd()?;
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
let pfd = let pfd = bpf_raw_tracepoint_open(tp_name, prog_fd).map_err(|io_error| SyscallError {
bpf_raw_tracepoint_open(tp_name, prog_fd).map_err(|(_code, io_error)| SyscallError { call: "bpf_raw_tracepoint_open",
call: "bpf_raw_tracepoint_open", io_error,
io_error, })?;
})?;
program_data.links.insert(FdLink::new(pfd).into()) program_data.links.insert(FdLink::new(pfd).into())
} }

@ -149,7 +149,7 @@ impl Xdp {
flags.bits(), flags.bits(),
None, None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|io_error| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})?; })?;
@ -196,7 +196,7 @@ impl Xdp {
match link.into_inner() { match link.into_inner() {
XdpLinkInner::FdLink(fd_link) => { XdpLinkInner::FdLink(fd_link) => {
let link_fd = fd_link.fd; let link_fd = fd_link.fd;
bpf_link_update(link_fd.as_fd(), prog_fd, None, 0).map_err(|(_, io_error)| { bpf_link_update(link_fd.as_fd(), prog_fd, None, 0).map_err(|io_error| {
SyscallError { SyscallError {
call: "bpf_link_update", call: "bpf_link_update",
io_error, io_error,

@ -27,12 +27,12 @@ use libc::{ENOENT, ENOSPC};
use crate::{ use crate::{
maps::{MapData, PerCpuValues}, maps::{MapData, PerCpuValues},
programs::links::LinkRef, programs::links::LinkRef,
sys::{syscall, SysResult, Syscall, SyscallError}, sys::{syscall, Syscall, SyscallError},
util::KernelVersion, util::KernelVersion,
Btf, Pod, VerifierLogLevel, FEATURES, Btf, Pod, VerifierLogLevel, FEATURES,
}; };
pub(crate) fn bpf_create_iter(link_fd: BorrowedFd<'_>) -> SysResult<crate::MockableFd> { pub(crate) fn bpf_create_iter(link_fd: BorrowedFd<'_>) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.iter_create }; let u = unsafe { &mut attr.iter_create };
@ -47,7 +47,7 @@ pub(crate) fn bpf_create_map(
def: &aya_obj::Map, def: &aya_obj::Map,
btf_fd: Option<BorrowedFd<'_>>, btf_fd: Option<BorrowedFd<'_>>,
kernel_version: KernelVersion, kernel_version: KernelVersion,
) -> SysResult<crate::MockableFd> { ) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_1 }; let u = unsafe { &mut attr.__bindgen_anon_1 };
@ -105,16 +105,16 @@ pub(crate) fn bpf_create_map(
unsafe { fd_sys_bpf(bpf_cmd::BPF_MAP_CREATE, &mut attr) } unsafe { fd_sys_bpf(bpf_cmd::BPF_MAP_CREATE, &mut attr) }
} }
pub(crate) fn bpf_pin_object(fd: BorrowedFd<'_>, path: &CStr) -> SysResult<c_long> { pub(crate) fn bpf_pin_object(fd: BorrowedFd<'_>, path: &CStr) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_4 }; let u = unsafe { &mut attr.__bindgen_anon_4 };
u.bpf_fd = fd.as_raw_fd() as u32; u.bpf_fd = fd.as_raw_fd() as u32;
u.pathname = path.as_ptr() as u64; u.pathname = path.as_ptr() as u64;
sys_bpf(bpf_cmd::BPF_OBJ_PIN, &mut attr) unit_sys_bpf(bpf_cmd::BPF_OBJ_PIN, &mut attr)
} }
/// Introduced in kernel v4.4. /// Introduced in kernel v4.4.
pub(crate) fn bpf_get_object(path: &CStr) -> SysResult<crate::MockableFd> { pub(crate) fn bpf_get_object(path: &CStr) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_4 }; let u = unsafe { &mut attr.__bindgen_anon_4 };
u.pathname = path.as_ptr() as u64; u.pathname = path.as_ptr() as u64;
@ -144,7 +144,7 @@ pub(crate) fn bpf_load_program(
aya_attr: &EbpfLoadProgramAttrs<'_>, aya_attr: &EbpfLoadProgramAttrs<'_>,
log_buf: &mut [u8], log_buf: &mut [u8],
verifier_log_level: VerifierLogLevel, verifier_log_level: VerifierLogLevel,
) -> SysResult<crate::MockableFd> { ) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_3 }; let u = unsafe { &mut attr.__bindgen_anon_3 };
@ -207,7 +207,7 @@ fn lookup<K: Pod, V: Pod>(
key: Option<&K>, key: Option<&K>,
flags: u64, flags: u64,
cmd: bpf_cmd, cmd: bpf_cmd,
) -> SysResult<Option<V>> { ) -> io::Result<Option<V>> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let mut value = MaybeUninit::zeroed(); let mut value = MaybeUninit::zeroed();
@ -219,9 +219,9 @@ fn lookup<K: Pod, V: Pod>(
u.__bindgen_anon_1.value = &mut value as *mut _ as u64; u.__bindgen_anon_1.value = &mut value as *mut _ as u64;
u.flags = flags; u.flags = flags;
match sys_bpf(cmd, &mut attr) { match unit_sys_bpf(cmd, &mut attr) {
Ok(_) => Ok(Some(unsafe { value.assume_init() })), Ok(_) => Ok(Some(unsafe { value.assume_init() })),
Err((_, io_error)) if io_error.raw_os_error() == Some(ENOENT) => Ok(None), Err(io_error) if io_error.raw_os_error() == Some(ENOENT) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -230,7 +230,7 @@ pub(crate) fn bpf_map_lookup_elem<K: Pod, V: Pod>(
fd: BorrowedFd<'_>, fd: BorrowedFd<'_>,
key: &K, key: &K,
flags: u64, flags: u64,
) -> SysResult<Option<V>> { ) -> io::Result<Option<V>> {
lookup(fd, Some(key), flags, bpf_cmd::BPF_MAP_LOOKUP_ELEM) lookup(fd, Some(key), flags, bpf_cmd::BPF_MAP_LOOKUP_ELEM)
} }
@ -238,7 +238,7 @@ pub(crate) fn bpf_map_lookup_and_delete_elem<K: Pod, V: Pod>(
fd: BorrowedFd<'_>, fd: BorrowedFd<'_>,
key: Option<&K>, key: Option<&K>,
flags: u64, flags: u64,
) -> SysResult<Option<V>> { ) -> io::Result<Option<V>> {
lookup(fd, key, flags, bpf_cmd::BPF_MAP_LOOKUP_AND_DELETE_ELEM) lookup(fd, key, flags, bpf_cmd::BPF_MAP_LOOKUP_AND_DELETE_ELEM)
} }
@ -246,11 +246,11 @@ pub(crate) fn bpf_map_lookup_elem_per_cpu<K: Pod, V: Pod>(
fd: BorrowedFd<'_>, fd: BorrowedFd<'_>,
key: &K, key: &K,
flags: u64, flags: u64,
) -> SysResult<Option<PerCpuValues<V>>> { ) -> io::Result<Option<PerCpuValues<V>>> {
let mut mem = PerCpuValues::<V>::alloc_kernel_mem().map_err(|io_error| (-1, io_error))?; let mut mem = PerCpuValues::<V>::alloc_kernel_mem()?;
match bpf_map_lookup_elem_ptr(fd, Some(key), mem.as_mut_ptr(), flags) { match bpf_map_lookup_elem_ptr(fd, Some(key), mem.as_mut_ptr(), flags) {
Ok(v) => Ok(v.map(|()| unsafe { PerCpuValues::from_kernel_mem(mem) })), Ok(v) => Ok(v.map(|()| unsafe { PerCpuValues::from_kernel_mem(mem) })),
Err((_, io_error)) if io_error.raw_os_error() == Some(ENOENT) => Ok(None), Err(io_error) if io_error.raw_os_error() == Some(ENOENT) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -260,7 +260,7 @@ pub(crate) fn bpf_map_lookup_elem_ptr<K: Pod, V>(
key: Option<&K>, key: Option<&K>,
value: *mut V, value: *mut V,
flags: u64, flags: u64,
) -> SysResult<Option<()>> { ) -> io::Result<Option<()>> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_2 }; let u = unsafe { &mut attr.__bindgen_anon_2 };
@ -271,9 +271,9 @@ pub(crate) fn bpf_map_lookup_elem_ptr<K: Pod, V>(
u.__bindgen_anon_1.value = value as u64; u.__bindgen_anon_1.value = value as u64;
u.flags = flags; u.flags = flags;
match sys_bpf(bpf_cmd::BPF_MAP_LOOKUP_ELEM, &mut attr) { match unit_sys_bpf(bpf_cmd::BPF_MAP_LOOKUP_ELEM, &mut attr) {
Ok(_) => Ok(Some(())), Ok(_) => Ok(Some(())),
Err((_, io_error)) if io_error.raw_os_error() == Some(ENOENT) => Ok(None), Err(io_error) if io_error.raw_os_error() == Some(ENOENT) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
@ -283,7 +283,7 @@ pub(crate) fn bpf_map_update_elem<K: Pod, V: Pod>(
key: Option<&K>, key: Option<&K>,
value: &V, value: &V,
flags: u64, flags: u64,
) -> SysResult<c_long> { ) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_2 }; let u = unsafe { &mut attr.__bindgen_anon_2 };
@ -294,14 +294,14 @@ pub(crate) fn bpf_map_update_elem<K: Pod, V: Pod>(
u.__bindgen_anon_1.value = value as *const _ as u64; u.__bindgen_anon_1.value = value as *const _ as u64;
u.flags = flags; u.flags = flags;
sys_bpf(bpf_cmd::BPF_MAP_UPDATE_ELEM, &mut attr) unit_sys_bpf(bpf_cmd::BPF_MAP_UPDATE_ELEM, &mut attr)
} }
pub(crate) fn bpf_map_push_elem<V: Pod>( pub(crate) fn bpf_map_push_elem<V: Pod>(
fd: BorrowedFd<'_>, fd: BorrowedFd<'_>,
value: &V, value: &V,
flags: u64, flags: u64,
) -> SysResult<c_long> { ) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_2 }; let u = unsafe { &mut attr.__bindgen_anon_2 };
@ -309,7 +309,7 @@ pub(crate) fn bpf_map_push_elem<V: Pod>(
u.__bindgen_anon_1.value = value as *const _ as u64; u.__bindgen_anon_1.value = value as *const _ as u64;
u.flags = flags; u.flags = flags;
sys_bpf(bpf_cmd::BPF_MAP_UPDATE_ELEM, &mut attr) unit_sys_bpf(bpf_cmd::BPF_MAP_UPDATE_ELEM, &mut attr)
} }
pub(crate) fn bpf_map_update_elem_ptr<K, V>( pub(crate) fn bpf_map_update_elem_ptr<K, V>(
@ -317,7 +317,7 @@ pub(crate) fn bpf_map_update_elem_ptr<K, V>(
key: *const K, key: *const K,
value: *mut V, value: *mut V,
flags: u64, flags: u64,
) -> SysResult<c_long> { ) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_2 }; let u = unsafe { &mut attr.__bindgen_anon_2 };
@ -326,7 +326,7 @@ pub(crate) fn bpf_map_update_elem_ptr<K, V>(
u.__bindgen_anon_1.value = value as u64; u.__bindgen_anon_1.value = value as u64;
u.flags = flags; u.flags = flags;
sys_bpf(bpf_cmd::BPF_MAP_UPDATE_ELEM, &mut attr) unit_sys_bpf(bpf_cmd::BPF_MAP_UPDATE_ELEM, &mut attr)
} }
pub(crate) fn bpf_map_update_elem_per_cpu<K: Pod, V: Pod>( pub(crate) fn bpf_map_update_elem_per_cpu<K: Pod, V: Pod>(
@ -334,25 +334,25 @@ pub(crate) fn bpf_map_update_elem_per_cpu<K: Pod, V: Pod>(
key: &K, key: &K,
values: &PerCpuValues<V>, values: &PerCpuValues<V>,
flags: u64, flags: u64,
) -> SysResult<c_long> { ) -> io::Result<()> {
let mut mem = values.build_kernel_mem().map_err(|e| (-1, e))?; let mut mem = values.build_kernel_mem()?;
bpf_map_update_elem_ptr(fd, key, mem.as_mut_ptr(), flags) bpf_map_update_elem_ptr(fd, key, mem.as_mut_ptr(), flags)
} }
pub(crate) fn bpf_map_delete_elem<K: Pod>(fd: BorrowedFd<'_>, key: &K) -> SysResult<c_long> { pub(crate) fn bpf_map_delete_elem<K: Pod>(fd: BorrowedFd<'_>, key: &K) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_2 }; let u = unsafe { &mut attr.__bindgen_anon_2 };
u.map_fd = fd.as_raw_fd() as u32; u.map_fd = fd.as_raw_fd() as u32;
u.key = key as *const _ as u64; u.key = key as *const _ as u64;
sys_bpf(bpf_cmd::BPF_MAP_DELETE_ELEM, &mut attr) unit_sys_bpf(bpf_cmd::BPF_MAP_DELETE_ELEM, &mut attr)
} }
pub(crate) fn bpf_map_get_next_key<K: Pod>( pub(crate) fn bpf_map_get_next_key<K: Pod>(
fd: BorrowedFd<'_>, fd: BorrowedFd<'_>,
key: Option<&K>, key: Option<&K>,
) -> SysResult<Option<K>> { ) -> io::Result<Option<K>> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let mut next_key = MaybeUninit::uninit(); let mut next_key = MaybeUninit::uninit();
@ -363,19 +363,19 @@ pub(crate) fn bpf_map_get_next_key<K: Pod>(
} }
u.__bindgen_anon_1.next_key = &mut next_key as *mut _ as u64; u.__bindgen_anon_1.next_key = &mut next_key as *mut _ as u64;
match sys_bpf(bpf_cmd::BPF_MAP_GET_NEXT_KEY, &mut attr) { match unit_sys_bpf(bpf_cmd::BPF_MAP_GET_NEXT_KEY, &mut attr) {
Ok(_) => Ok(Some(unsafe { next_key.assume_init() })), Ok(_) => Ok(Some(unsafe { next_key.assume_init() })),
Err((_, io_error)) if io_error.raw_os_error() == Some(ENOENT) => Ok(None), Err(io_error) if io_error.raw_os_error() == Some(ENOENT) => Ok(None),
Err(e) => Err(e), Err(e) => Err(e),
} }
} }
// since kernel 5.2 // since kernel 5.2
pub(crate) fn bpf_map_freeze(fd: BorrowedFd<'_>) -> SysResult<c_long> { pub(crate) fn bpf_map_freeze(fd: BorrowedFd<'_>) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_2 }; let u = unsafe { &mut attr.__bindgen_anon_2 };
u.map_fd = fd.as_raw_fd() as u32; u.map_fd = fd.as_raw_fd() as u32;
sys_bpf(bpf_cmd::BPF_MAP_FREEZE, &mut attr) unit_sys_bpf(bpf_cmd::BPF_MAP_FREEZE, &mut attr)
} }
pub(crate) enum LinkTarget<'f> { pub(crate) enum LinkTarget<'f> {
@ -400,7 +400,7 @@ pub(crate) fn bpf_link_create(
attach_type: bpf_attach_type, attach_type: bpf_attach_type,
flags: u32, flags: u32,
args: Option<BpfLinkCreateArgs<'_>>, args: Option<BpfLinkCreateArgs<'_>>,
) -> SysResult<crate::MockableFd> { ) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.link_create.__bindgen_anon_1.prog_fd = prog_fd.as_raw_fd() as u32; attr.link_create.__bindgen_anon_1.prog_fd = prog_fd.as_raw_fd() as u32;
@ -458,7 +458,7 @@ pub(crate) fn bpf_link_update(
new_prog_fd: BorrowedFd<'_>, new_prog_fd: BorrowedFd<'_>,
old_prog_fd: Option<RawFd>, old_prog_fd: Option<RawFd>,
flags: u32, flags: u32,
) -> SysResult<c_long> { ) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.link_update.link_fd = link_fd.as_raw_fd() as u32; attr.link_update.link_fd = link_fd.as_raw_fd() as u32;
@ -470,7 +470,7 @@ pub(crate) fn bpf_link_update(
attr.link_update.flags = flags; attr.link_update.flags = flags;
} }
sys_bpf(bpf_cmd::BPF_LINK_UPDATE, &mut attr) unit_sys_bpf(bpf_cmd::BPF_LINK_UPDATE, &mut attr)
} }
pub(crate) fn bpf_prog_attach( pub(crate) fn bpf_prog_attach(
@ -486,15 +486,10 @@ pub(crate) fn bpf_prog_attach(
attr.__bindgen_anon_5.attach_type = attach_type as u32; attr.__bindgen_anon_5.attach_type = attach_type as u32;
attr.__bindgen_anon_5.attach_flags = flags; attr.__bindgen_anon_5.attach_flags = flags;
let ret = sys_bpf(bpf_cmd::BPF_PROG_ATTACH, &mut attr).map_err(|(code, io_error)| { unit_sys_bpf(bpf_cmd::BPF_PROG_ATTACH, &mut attr).map_err(|io_error| SyscallError {
assert_eq!(code, -1); call: "bpf_prog_attach",
SyscallError { io_error,
call: "bpf_prog_attach", })
io_error,
}
})?;
assert_eq!(ret, 0);
Ok(())
} }
pub(crate) fn bpf_prog_detach( pub(crate) fn bpf_prog_detach(
@ -508,15 +503,10 @@ pub(crate) fn bpf_prog_detach(
attr.__bindgen_anon_5.__bindgen_anon_1.target_fd = target_fd.as_raw_fd() as u32; attr.__bindgen_anon_5.__bindgen_anon_1.target_fd = target_fd.as_raw_fd() as u32;
attr.__bindgen_anon_5.attach_type = attach_type as u32; attr.__bindgen_anon_5.attach_type = attach_type as u32;
let ret = sys_bpf(bpf_cmd::BPF_PROG_DETACH, &mut attr).map_err(|(code, io_error)| { unit_sys_bpf(bpf_cmd::BPF_PROG_DETACH, &mut attr).map_err(|io_error| SyscallError {
assert_eq!(code, -1); call: "bpf_prog_detach",
SyscallError { io_error,
call: "bpf_prog_detach", })
io_error,
}
})?;
assert_eq!(ret, 0);
Ok(())
} }
#[derive(Debug)] #[derive(Debug)]
@ -533,7 +523,7 @@ pub(crate) fn bpf_prog_query(
prog_ids: &mut [u32], prog_ids: &mut [u32],
prog_cnt: &mut u32, prog_cnt: &mut u32,
revision: &mut u64, revision: &mut u64,
) -> SysResult<c_long> { ) -> io::Result<()> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
match target { match target {
@ -548,7 +538,7 @@ pub(crate) fn bpf_prog_query(
attr.query.query_flags = query_flags; attr.query.query_flags = query_flags;
attr.query.__bindgen_anon_2.prog_cnt = prog_ids.len() as u32; attr.query.__bindgen_anon_2.prog_cnt = prog_ids.len() as u32;
attr.query.prog_ids = prog_ids.as_mut_ptr() as u64; attr.query.prog_ids = prog_ids.as_mut_ptr() as u64;
let ret = sys_bpf(bpf_cmd::BPF_PROG_QUERY, &mut attr); let ret = unit_sys_bpf(bpf_cmd::BPF_PROG_QUERY, &mut attr);
*prog_cnt = unsafe { attr.query.__bindgen_anon_2.prog_cnt }; *prog_cnt = unsafe { attr.query.__bindgen_anon_2.prog_cnt };
*revision = unsafe { attr.query.revision }; *revision = unsafe { attr.query.revision };
@ -566,8 +556,7 @@ pub(crate) fn bpf_prog_get_fd_by_id(prog_id: u32) -> Result<crate::MockableFd, S
attr.__bindgen_anon_6.__bindgen_anon_1.prog_id = prog_id; attr.__bindgen_anon_6.__bindgen_anon_1.prog_id = prog_id;
// SAFETY: BPF_PROG_GET_FD_BY_ID returns a new file descriptor. // SAFETY: BPF_PROG_GET_FD_BY_ID returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_GET_FD_BY_ID, &mut attr) }.map_err(|(code, io_error)| { unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_GET_FD_BY_ID, &mut attr) }.map_err(|io_error| {
assert_eq!(code, -1);
SyscallError { SyscallError {
call: "bpf_prog_get_fd_by_id", call: "bpf_prog_get_fd_by_id",
io_error, io_error,
@ -589,18 +578,12 @@ fn bpf_obj_get_info_by_fd<T, F: FnOnce(&mut T)>(
attr.info.info = &info as *const _ as u64; attr.info.info = &info as *const _ as u64;
attr.info.info_len = mem::size_of_val(&info) as u32; attr.info.info_len = mem::size_of_val(&info) as u32;
match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &mut attr) { match unit_sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &mut attr) {
Ok(code) => { Ok(()) => Ok(info),
assert_eq!(code, 0); Err(io_error) => Err(SyscallError {
Ok(info) call: "bpf_obj_get_info_by_fd",
} io_error,
Err((code, io_error)) => { }),
assert_eq!(code, -1);
Err(SyscallError {
call: "bpf_obj_get_info_by_fd",
io_error,
})
}
} }
} }
@ -626,8 +609,7 @@ pub(crate) fn bpf_map_get_fd_by_id(map_id: u32) -> Result<crate::MockableFd, Sys
attr.__bindgen_anon_6.__bindgen_anon_1.map_id = map_id; attr.__bindgen_anon_6.__bindgen_anon_1.map_id = map_id;
// SAFETY: BPF_MAP_GET_FD_BY_ID returns a new file descriptor. // 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)| { unsafe { fd_sys_bpf(bpf_cmd::BPF_MAP_GET_FD_BY_ID, &mut attr) }.map_err(|io_error| {
assert_eq!(code, -1);
SyscallError { SyscallError {
call: "bpf_map_get_fd_by_id", call: "bpf_map_get_fd_by_id",
io_error, io_error,
@ -644,8 +626,7 @@ pub(crate) fn bpf_link_get_fd_by_id(link_id: u32) -> Result<crate::MockableFd, S
attr.__bindgen_anon_6.__bindgen_anon_1.link_id = link_id; attr.__bindgen_anon_6.__bindgen_anon_1.link_id = link_id;
// SAFETY: BPF_LINK_GET_FD_BY_ID returns a new file descriptor. // SAFETY: BPF_LINK_GET_FD_BY_ID returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_LINK_GET_FD_BY_ID, &mut attr) }.map_err(|(code, io_error)| { unsafe { fd_sys_bpf(bpf_cmd::BPF_LINK_GET_FD_BY_ID, &mut attr) }.map_err(|io_error| {
assert_eq!(code, -1);
SyscallError { SyscallError {
call: "bpf_link_get_fd_by_id", call: "bpf_link_get_fd_by_id",
io_error, io_error,
@ -670,7 +651,7 @@ pub(crate) fn btf_obj_get_info_by_fd(
pub(crate) fn bpf_raw_tracepoint_open( pub(crate) fn bpf_raw_tracepoint_open(
name: Option<&CStr>, name: Option<&CStr>,
prog_fd: BorrowedFd<'_>, prog_fd: BorrowedFd<'_>,
) -> SysResult<crate::MockableFd> { ) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.raw_tracepoint.name = match name { attr.raw_tracepoint.name = match name {
@ -687,7 +668,7 @@ pub(crate) fn bpf_load_btf(
raw_btf: &[u8], raw_btf: &[u8],
log_buf: &mut [u8], log_buf: &mut [u8],
verifier_log_level: VerifierLogLevel, verifier_log_level: VerifierLogLevel,
) -> SysResult<crate::MockableFd> { ) -> io::Result<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_7 }; let u = unsafe { &mut attr.__bindgen_anon_7 };
u.btf = raw_btf.as_ptr() as *const _ as u64; u.btf = raw_btf.as_ptr() as *const _ as u64;
@ -702,15 +683,12 @@ pub(crate) fn bpf_load_btf(
} }
// SAFETY: only use for bpf_cmd that return a new file descriptor on success. // SAFETY: only use for bpf_cmd that return a new file descriptor on success.
unsafe fn fd_sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> SysResult<crate::MockableFd> { unsafe fn fd_sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> io::Result<crate::MockableFd> {
let fd = sys_bpf(cmd, attr)?; let fd = sys_bpf(cmd, attr)?;
let fd = fd.try_into().map_err(|_| { let fd = fd.try_into().map_err(|std::num::TryFromIntError { .. }| {
( io::Error::new(
fd, io::ErrorKind::InvalidData,
io::Error::new( format!("{cmd:?}: invalid fd returned: {fd}"),
io::ErrorKind::InvalidData,
format!("{cmd:?}: invalid fd returned: {fd}"),
),
) )
})?; })?;
Ok(crate::MockableFd::from_raw_fd(fd)) Ok(crate::MockableFd::from_raw_fd(fd))
@ -721,8 +699,7 @@ pub(crate) fn bpf_btf_get_fd_by_id(id: u32) -> Result<crate::MockableFd, Syscall
attr.__bindgen_anon_6.__bindgen_anon_1.btf_id = id; attr.__bindgen_anon_6.__bindgen_anon_1.btf_id = id;
// SAFETY: BPF_BTF_GET_FD_BY_ID returns a new file descriptor. // SAFETY: BPF_BTF_GET_FD_BY_ID returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_BTF_GET_FD_BY_ID, &mut attr) }.map_err(|(code, io_error)| { unsafe { fd_sys_bpf(bpf_cmd::BPF_BTF_GET_FD_BY_ID, &mut attr) }.map_err(|io_error| {
assert_eq!(code, -1);
SyscallError { SyscallError {
call: "bpf_btf_get_fd_by_id", call: "bpf_btf_get_fd_by_id",
io_error, io_error,
@ -842,7 +819,7 @@ pub(crate) fn is_perf_link_supported() -> bool {
None, None,
); );
// Returns EINVAL if unsupported. EBADF if supported. // Returns EINVAL if unsupported. EBADF if supported.
matches!(link, Err((_, e)) if e.raw_os_error() == Some(libc::EBADF)) matches!(link, Err(err) if err.raw_os_error() == Some(libc::EBADF))
} else { } else {
false false
} }
@ -1098,13 +1075,20 @@ pub(crate) fn is_btf_type_tag_supported() -> bool {
bpf_load_btf(btf_bytes.as_slice(), &mut [], Default::default()).is_ok() bpf_load_btf(btf_bytes.as_slice(), &mut [], Default::default()).is_ok()
} }
fn bpf_prog_load(attr: &mut bpf_attr) -> SysResult<crate::MockableFd> { fn bpf_prog_load(attr: &mut bpf_attr) -> io::Result<crate::MockableFd> {
// SAFETY: BPF_PROG_LOAD returns a new file descriptor. // SAFETY: BPF_PROG_LOAD returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_LOAD, attr) } unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_LOAD, attr) }
} }
fn sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> SysResult<c_long> { fn sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> io::Result<c_long> {
syscall(Syscall::Ebpf { cmd, attr }) syscall(Syscall::Ebpf { cmd, attr }).map_err(|(code, io_error)| {
assert_eq!(code, -1);
io_error
})
}
fn unit_sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> io::Result<()> {
sys_bpf(cmd, attr).map(|code| assert_eq!(code, 0))
} }
fn bpf_obj_get_next_id( fn bpf_obj_get_next_id(
@ -1115,13 +1099,9 @@ fn bpf_obj_get_next_id(
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_6 }; let u = unsafe { &mut attr.__bindgen_anon_6 };
u.__bindgen_anon_1.start_id = id; u.__bindgen_anon_1.start_id = id;
match sys_bpf(cmd, &mut attr) { match unit_sys_bpf(cmd, &mut attr) {
Ok(code) => { Ok(()) => Ok(Some(unsafe { attr.__bindgen_anon_6.next_id })),
assert_eq!(code, 0); Err(io_error) => {
Ok(Some(unsafe { attr.__bindgen_anon_6.next_id }))
}
Err((code, io_error)) => {
assert_eq!(code, -1);
if io_error.raw_os_error() == Some(ENOENT) { if io_error.raw_os_error() == Some(ENOENT) {
Ok(None) Ok(None)
} else { } else {
@ -1174,18 +1154,16 @@ pub(crate) fn bpf_enable_stats(
attr.enable_stats.type_ = stats_type as u32; attr.enable_stats.type_ = stats_type as u32;
// SAFETY: BPF_ENABLE_STATS returns a new file descriptor. // SAFETY: BPF_ENABLE_STATS returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_ENABLE_STATS, &mut attr) }.map_err(|(_, io_error)| { unsafe { fd_sys_bpf(bpf_cmd::BPF_ENABLE_STATS, &mut attr) }.map_err(|io_error| SyscallError {
SyscallError { call: "bpf_enable_stats",
call: "bpf_enable_stats", io_error,
io_error,
}
}) })
} }
pub(crate) fn retry_with_verifier_logs<T>( pub(crate) fn retry_with_verifier_logs<T>(
max_retries: usize, max_retries: usize,
f: impl Fn(&mut [u8]) -> SysResult<T>, f: impl Fn(&mut [u8]) -> io::Result<T>,
) -> (SysResult<T>, VerifierLog) { ) -> (io::Result<T>, VerifierLog) {
const MIN_LOG_BUF_SIZE: usize = 1024 * 10; const MIN_LOG_BUF_SIZE: usize = 1024 * 10;
const MAX_LOG_BUF_SIZE: usize = (u32::MAX >> 8) as usize; const MAX_LOG_BUF_SIZE: usize = (u32::MAX >> 8) as usize;
@ -1194,7 +1172,7 @@ pub(crate) fn retry_with_verifier_logs<T>(
loop { loop {
let ret = f(log_buf.as_mut_slice()); let ret = f(log_buf.as_mut_slice());
if retries != max_retries { if retries != max_retries {
if let Err((_, io_error)) = &ret { if let Err(io_error) = &ret {
if retries == 0 || io_error.raw_os_error() == Some(ENOSPC) { if retries == 0 || io_error.raw_os_error() == Some(ENOSPC) {
let len = (log_buf.capacity() * 10).clamp(MIN_LOG_BUF_SIZE, MAX_LOG_BUF_SIZE); let len = (log_buf.capacity() * 10).clamp(MIN_LOG_BUF_SIZE, MAX_LOG_BUF_SIZE);
log_buf.resize(len, 0); log_buf.resize(len, 0);

@ -1336,7 +1336,6 @@ impl<T> core::convert::From<T> for aya::maps::Map
pub fn aya::maps::Map::from(t: T) -> T pub fn aya::maps::Map::from(t: T) -> T
pub enum aya::maps::MapError pub enum aya::maps::MapError
pub aya::maps::MapError::CreateError pub aya::maps::MapError::CreateError
pub aya::maps::MapError::CreateError::code: core::ffi::primitives::c_long
pub aya::maps::MapError::CreateError::io_error: std::io::error::Error pub aya::maps::MapError::CreateError::io_error: std::io::error::Error
pub aya::maps::MapError::CreateError::name: alloc::string::String pub aya::maps::MapError::CreateError::name: alloc::string::String
pub aya::maps::MapError::ElementNotFound pub aya::maps::MapError::ElementNotFound

Loading…
Cancel
Save