Skip to content

Commit

Permalink
Merge pull request #747 from aya-rs/helpers
Browse files Browse the repository at this point in the history
sys: add map_ids to bpf_prog_get_info_by_fd
  • Loading branch information
tamird committed Aug 10, 2023
2 parents 68bf881 + 5ac1862 commit 5bc922a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 53 deletions.
37 changes: 12 additions & 25 deletions aya/src/programs/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,44 +151,31 @@ impl Extension {
/// with the name `func_name` within that BTF object.
fn get_btf_info(prog_fd: i32, func_name: &str) -> Result<(RawFd, u32), ProgramError> {
// retrieve program information
let info = sys::bpf_prog_get_info_by_fd(prog_fd)?;
let info = sys::bpf_prog_get_info_by_fd(prog_fd, &mut [])?;

// btf_id refers to the ID of the program btf that was loaded with bpf(BPF_BTF_LOAD)
if info.btf_id == 0 {
return Err(ProgramError::ExtensionError(ExtensionError::NoBTF));
}

// the bpf fd of the BTF object
let btf_fd = sys::bpf_btf_get_fd_by_id(info.btf_id).map_err(|io_error| SyscallError {
call: "bpf_btf_get_fd_by_id",
io_error,
})?;
let btf_fd = sys::bpf_btf_get_fd_by_id(info.btf_id)?;

// we need to read the btf bytes into a buffer but we don't know the size ahead of time.
// assume 4kb. if this is too small we can resize based on the size obtained in the response.
let mut buf = vec![0u8; 4096];
let btf_info = match sys::btf_obj_get_info_by_fd(btf_fd, &buf) {
Ok(info) => {
if info.btf_size > buf.len() as u32 {
buf.resize(info.btf_size as usize, 0u8);
let btf_info =
sys::btf_obj_get_info_by_fd(btf_fd, &buf).map_err(|io_error| SyscallError {
call: "bpf_prog_get_info_by_fd",
io_error,
})?;
Ok(btf_info)
} else {
Ok(info)
}
loop {
let info = sys::btf_obj_get_info_by_fd(btf_fd, &mut buf)?;
let btf_size = info.btf_size as usize;
if btf_size > buf.len() {
buf.resize(btf_size, 0u8);
continue;
}
Err(io_error) => Err(SyscallError {
call: "bpf_prog_get_info_by_fd",
io_error,
}),
}?;
buf.truncate(btf_size);
break;
}

let btf = Btf::parse(&buf[0..btf_info.btf_size as usize], Endianness::default())
.map_err(ProgramError::Btf)?;
let btf = Btf::parse(&buf, Endianness::default()).map_err(ProgramError::Btf)?;

let btf_id = btf
.id_by_type_name_kind(func_name, BtfKind::Func)
Expand Down
2 changes: 1 addition & 1 deletion aya/src/programs/lirc_mode2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl LircLink {

/// Get ProgramInfo from this link
pub fn info(&self) -> Result<ProgramInfo, ProgramError> {
bpf_prog_get_info_by_fd(self.prog_fd)
bpf_prog_get_info_by_fd(self.prog_fd, &mut [])
.map(ProgramInfo)
.map_err(Into::into)
}
Expand Down
6 changes: 3 additions & 3 deletions aya/src/programs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ impl<T: Link> ProgramData<T> {
io_error,
})?;

let info = bpf_prog_get_info_by_fd(fd.as_raw_fd())?;
let info = bpf_prog_get_info_by_fd(fd.as_raw_fd(), &mut [])?;
let name = ProgramInfo(info).name_as_str().map(|s| s.to_string());
ProgramData::from_bpf_prog_info(name, fd, path.as_ref(), info, verifier_log_level)
}
Expand Down Expand Up @@ -955,7 +955,7 @@ impl ProgramInfo {
io_error,
})?;

let info = bpf_prog_get_info_by_fd(fd.as_raw_fd())?;
let info = bpf_prog_get_info_by_fd(fd.as_raw_fd(), &mut [])?;
Ok(ProgramInfo(info))
}
}
Expand Down Expand Up @@ -991,7 +991,7 @@ pub fn loaded_programs() -> impl Iterator<Item = Result<ProgramInfo, ProgramErro
})
.map(|fd| {
let fd = fd?;
bpf_prog_get_info_by_fd(fd.as_raw_fd())
bpf_prog_get_info_by_fd(fd.as_raw_fd(), &mut [])
})
.map(|result| result.map(ProgramInfo).map_err(Into::into))
}
Expand Down
50 changes: 26 additions & 24 deletions aya/src/sys/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,14 @@ pub(crate) fn bpf_prog_get_fd_by_id(prog_id: u32) -> Result<OwnedFd, SyscallErro
})
}

fn bpf_obj_get_info_by_fd<T>(fd: BorrowedFd<'_>) -> Result<T, SyscallError> {
fn bpf_obj_get_info_by_fd<T, F: FnOnce(&mut T)>(
fd: BorrowedFd<'_>,
init: F,
) -> Result<T, SyscallError> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
// info gets entirely populated by the kernel
let info = MaybeUninit::zeroed();
let mut info = unsafe { mem::zeroed() };

init(&mut info);

attr.info.bpf_fd = fd.as_raw_fd() as u32;
attr.info.info = &info as *const _ as u64;
Expand All @@ -489,7 +493,7 @@ fn bpf_obj_get_info_by_fd<T>(fd: BorrowedFd<'_>) -> Result<T, SyscallError> {
match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &mut attr) {
Ok(code) => {
assert_eq!(code, 0);
Ok(unsafe { info.assume_init() })
Ok(info)
}
Err((code, io_error)) => {
assert_eq!(code, -1);
Expand All @@ -501,13 +505,19 @@ fn bpf_obj_get_info_by_fd<T>(fd: BorrowedFd<'_>) -> Result<T, SyscallError> {
}
}

pub(crate) fn bpf_prog_get_info_by_fd(fd: RawFd) -> Result<bpf_prog_info, SyscallError> {
pub(crate) fn bpf_prog_get_info_by_fd(
fd: RawFd,
map_ids: &mut [u32],
) -> Result<bpf_prog_info, SyscallError> {
let fd = unsafe { BorrowedFd::borrow_raw(fd) };
bpf_obj_get_info_by_fd::<bpf_prog_info>(fd)
bpf_obj_get_info_by_fd(fd, |info: &mut bpf_prog_info| {
info.nr_map_ids = map_ids.len() as _;
info.map_ids = map_ids.as_mut_ptr() as _;
})
}

pub(crate) fn bpf_map_get_info_by_fd(fd: BorrowedFd<'_>) -> Result<bpf_map_info, SyscallError> {
bpf_obj_get_info_by_fd::<bpf_map_info>(fd)
bpf_obj_get_info_by_fd(fd, |_| {})
}

pub(crate) fn bpf_link_get_fd_by_id(link_id: u32) -> Result<OwnedFd, SyscallError> {
Expand All @@ -525,26 +535,18 @@ pub(crate) fn bpf_link_get_fd_by_id(link_id: u32) -> Result<OwnedFd, SyscallErro
}

pub(crate) fn bpf_link_get_info_by_fd(fd: BorrowedFd<'_>) -> Result<bpf_link_info, SyscallError> {
bpf_obj_get_info_by_fd::<bpf_link_info>(fd)
bpf_obj_get_info_by_fd(fd, |_| {})
}

pub(crate) fn btf_obj_get_info_by_fd(
prog_fd: RawFd,
buf: &[u8],
) -> Result<bpf_btf_info, io::Error> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let mut info = unsafe { mem::zeroed::<bpf_btf_info>() };
let buf_size = buf.len() as u32;
info.btf = buf.as_ptr() as u64;
info.btf_size = buf_size;
attr.info.bpf_fd = prog_fd as u32;
attr.info.info = &info as *const bpf_btf_info as u64;
attr.info.info_len = mem::size_of::<bpf_btf_info>() as u32;

match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &mut attr) {
Ok(_) => Ok(info),
Err((_, err)) => Err(err),
}
fd: RawFd,
buf: &mut [u8],
) -> Result<bpf_btf_info, SyscallError> {
let fd = unsafe { BorrowedFd::borrow_raw(fd) };
bpf_obj_get_info_by_fd(fd, |info: &mut bpf_btf_info| {
info.btf = buf.as_mut_ptr() as _;
info.btf_size = buf.len() as _;
})
}

pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> SysResult<OwnedFd> {
Expand Down

0 comments on commit 5bc922a

Please sign in to comment.