programs: make `loaded_programs` opaque

reviewable/pr712/r15
Tamir Duberstein 1 year ago
parent de8519a380
commit a0af7e0b2f
No known key found for this signature in database

@ -110,7 +110,7 @@ use crate::{
pin::PinError,
sys::{
bpf_btf_get_fd_by_id, bpf_get_object, bpf_load_program, bpf_pin_object,
bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd, bpf_prog_get_next_id, bpf_prog_query,
bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd, bpf_prog_query, iter_prog_ids,
retry_with_verifier_logs, BpfLoadProgramAttrs, SyscallError,
},
util::KernelVersion,
@ -971,56 +971,6 @@ impl ProgramInfo {
}
}
/// ProgramsIter is an Iterator over loaded eBPF programs.
pub struct ProgramsIter {
current: u32,
error: bool,
}
impl Iterator for ProgramsIter {
type Item = Result<ProgramInfo, ProgramError>;
fn next(&mut self) -> Option<Self::Item> {
if self.error {
return None;
}
let current = self.current;
match bpf_prog_get_next_id(current) {
Ok(Some(next)) => {
self.current = next;
Some(
bpf_prog_get_fd_by_id(next)
.map_err(|io_error| SyscallError {
call: "bpf_prog_get_fd_by_id",
io_error,
})
.and_then(|fd| {
bpf_prog_get_info_by_fd(fd.as_raw_fd())
.map_err(|io_error| SyscallError {
call: "bpf_prog_get_info_by_fd",
io_error,
})
.map(ProgramInfo)
})
.map_err(Into::into),
)
}
Ok(None) => None,
Err((_, io_error)) => {
// If getting the next program failed, we have to yield None in our next
// iteration to avoid an infinite loop.
self.error = true;
Some(Err(SyscallError {
call: "bpf_prog_get_fd_by_id",
io_error,
}
.into()))
}
}
}
}
/// Returns an iterator over all loaded bpf programs.
///
/// This differs from [`crate::Bpf::programs`] since it will return all programs
@ -1044,9 +994,21 @@ impl Iterator for ProgramsIter {
/// next program id, get the program fd, or the [`ProgramInfo`] fail. In cases where
/// iteration can't be performed, for example the caller does not have the necessary privileges,
/// a single item will be yielded containing the error that occurred.
pub fn loaded_programs() -> ProgramsIter {
ProgramsIter {
current: 0,
error: false,
}
pub fn loaded_programs() -> impl Iterator<Item = Result<ProgramInfo, ProgramError>> {
iter_prog_ids()
.map(|id| {
let id = id?;
bpf_prog_get_fd_by_id(id).map_err(|io_error| SyscallError {
call: "bpf_prog_get_fd_by_id",
io_error,
})
})
.map(|fd| {
let fd = fd?;
bpf_prog_get_info_by_fd(fd.as_raw_fd()).map_err(|io_error| SyscallError {
call: "bpf_prog_get_info_by_fd",
io_error,
})
})
.map(|result| result.map(ProgramInfo).map_err(Into::into))
}

@ -1,7 +1,7 @@
use std::{
cmp::{self, min},
ffi::{CStr, CString},
io,
io, iter,
mem::{self, MaybeUninit},
os::fd::{AsRawFd, BorrowedFd, FromRawFd as _, OwnedFd, RawFd},
slice,
@ -28,7 +28,7 @@ use crate::{
},
copy_instructions,
},
sys::{syscall, SysResult, Syscall},
sys::{syscall, SysResult, Syscall, SyscallError},
Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN,
};
@ -909,17 +909,44 @@ fn sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> SysResult<c_long> {
syscall(Syscall::Bpf { cmd, attr })
}
pub(crate) fn bpf_prog_get_next_id(id: u32) -> Result<Option<u32>, (c_long, io::Error)> {
fn bpf_prog_get_next_id(id: u32) -> Result<Option<u32>, SyscallError> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_6 };
u.__bindgen_anon_1.start_id = id;
match sys_bpf(bpf_cmd::BPF_PROG_GET_NEXT_ID, &mut attr) {
Ok(_) => Ok(Some(unsafe { attr.__bindgen_anon_6.next_id })),
Err((_, io_error)) if io_error.raw_os_error() == Some(ENOENT) => Ok(None),
Err(e) => Err(e),
Ok(code) => {
assert_eq!(code, 0);
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) {
Ok(None)
} else {
Err(SyscallError {
call: "bpf_prog_get_next_id",
io_error,
})
}
}
}
}
pub(crate) fn iter_prog_ids() -> impl Iterator<Item = Result<u32, SyscallError>> {
let mut current_id = Some(0);
iter::from_fn(move || {
let next_id = {
let current_id = current_id?;
bpf_prog_get_next_id(current_id).transpose()
};
current_id = next_id.as_ref().and_then(|next_id| match next_id {
Ok(next_id) => Some(*next_id),
Err(SyscallError { .. }) => None,
});
next_id
})
}
pub(crate) fn retry_with_verifier_logs<T>(
max_retries: usize,
f: impl Fn(&mut [u8]) -> SysResult<T>,

@ -6228,35 +6228,6 @@ impl<T> core::borrow::BorrowMut<T> for aya::programs::ProgramInfo where T: core:
pub fn aya::programs::ProgramInfo::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::programs::ProgramInfo
pub fn aya::programs::ProgramInfo::from(t: T) -> T
pub struct aya::programs::ProgramsIter
impl core::iter::traits::iterator::Iterator for aya::programs::ProgramsIter
pub type aya::programs::ProgramsIter::Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
pub fn aya::programs::ProgramsIter::next(&mut self) -> core::option::Option<Self::Item>
impl core::marker::Send for aya::programs::ProgramsIter
impl core::marker::Sync for aya::programs::ProgramsIter
impl core::marker::Unpin for aya::programs::ProgramsIter
impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::ProgramsIter
impl core::panic::unwind_safe::UnwindSafe for aya::programs::ProgramsIter
impl<I> core::iter::traits::collect::IntoIterator for aya::programs::ProgramsIter where I: core::iter::traits::iterator::Iterator
pub type aya::programs::ProgramsIter::IntoIter = I
pub type aya::programs::ProgramsIter::Item = <I as core::iter::traits::iterator::Iterator>::Item
pub fn aya::programs::ProgramsIter::into_iter(self) -> I
impl<T, U> core::convert::Into<U> for aya::programs::ProgramsIter where U: core::convert::From<T>
pub fn aya::programs::ProgramsIter::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::programs::ProgramsIter where U: core::convert::Into<T>
pub type aya::programs::ProgramsIter::Error = core::convert::Infallible
pub fn aya::programs::ProgramsIter::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::programs::ProgramsIter where U: core::convert::TryFrom<T>
pub type aya::programs::ProgramsIter::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::programs::ProgramsIter::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::programs::ProgramsIter where T: 'static + core::marker::Sized
pub fn aya::programs::ProgramsIter::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::programs::ProgramsIter where T: core::marker::Sized
pub fn aya::programs::ProgramsIter::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::programs::ProgramsIter where T: core::marker::Sized
pub fn aya::programs::ProgramsIter::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::programs::ProgramsIter
pub fn aya::programs::ProgramsIter::from(t: T) -> T
pub struct aya::programs::RawTracePoint
impl aya::programs::RawTracePoint
pub fn aya::programs::RawTracePoint::attach(&mut self, tp_name: &str) -> core::result::Result<RawTracePointLinkId, aya::programs::ProgramError>
@ -6919,7 +6890,7 @@ impl aya::programs::links::Link for aya::programs::xdp::XdpLink
pub type aya::programs::xdp::XdpLink::Id = aya::programs::xdp::XdpLinkId
pub fn aya::programs::xdp::XdpLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::XdpLink::id(&self) -> Self::Id
pub fn aya::programs::loaded_programs() -> aya::programs::ProgramsIter
pub fn aya::programs::loaded_programs() -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>>
pub mod aya::util
pub struct aya::util::KernelVersion
impl aya::util::KernelVersion
@ -7250,4 +7221,4 @@ impl aya::Pod for u8
impl<K: aya::Pod> aya::Pod for aya::maps::lpm_trie::Key<K>
impl<T: aya::Pod, const N: usize> aya::Pod for [T; N]
pub fn aya::features() -> &'static aya_obj::obj::Features
pub fn aya::loaded_programs() -> aya::programs::ProgramsIter
pub fn aya::loaded_programs() -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>>

Loading…
Cancel
Save