Skip to content

Commit

Permalink
Merge pull request #757 from aya-rs/attach-fd-owned
Browse files Browse the repository at this point in the history
programs: `ProgramData::attach_prog_fd` is owned
  • Loading branch information
tamird authored Aug 15, 2023
2 parents befa55e + 3d68fa3 commit c7b5cd5
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 117 deletions.
17 changes: 11 additions & 6 deletions aya/src/programs/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub enum ExtensionError {
/// let prog_fd = prog.fd().unwrap();
/// let prog_fd = prog_fd.try_clone().unwrap();
/// let ext: &mut Extension = bpf.program_mut("extension").unwrap().try_into()?;
/// ext.load(&prog_fd, "function_to_replace")?;
/// ext.load(prog_fd, "function_to_replace")?;
/// ext.attach()?;
/// Ok::<(), aya::BpfError>(())
/// ```
Expand All @@ -69,12 +69,11 @@ impl Extension {
/// The extension code will be loaded but inactive until it's attached.
/// There are no restrictions on what functions may be replaced, so you could replace
/// the main entry point of your program with an extension.
pub fn load(&mut self, program: &ProgramFd, func_name: &str) -> Result<(), ProgramError> {
let target_prog_fd = program.as_fd();
let (btf_fd, btf_id) = get_btf_info(target_prog_fd, func_name)?;
pub fn load(&mut self, program: ProgramFd, func_name: &str) -> Result<(), ProgramError> {
let (btf_fd, btf_id) = get_btf_info(program.as_fd(), func_name)?;

self.data.attach_btf_obj_fd = Some(btf_fd);
self.data.attach_prog_fd = Some(target_prog_fd.as_raw_fd());
self.data.attach_prog_fd = Some(program);
self.data.attach_btf_id = Some(btf_id);
load_program(BPF_PROG_TYPE_EXT, &mut self.data)
}
Expand All @@ -90,7 +89,13 @@ impl Extension {
let prog_fd = self.fd()?;
let prog_fd = prog_fd.as_fd();
let prog_fd = prog_fd.as_raw_fd();
let target_fd = self.data.attach_prog_fd.ok_or(ProgramError::NotLoaded)?;
let target_fd = self
.data
.attach_prog_fd
.as_ref()
.ok_or(ProgramError::NotLoaded)?;
let target_fd = target_fd.as_fd();
let target_fd = target_fd.as_raw_fd();
let btf_id = self.data.attach_btf_id.ok_or(ProgramError::NotLoaded)?;
// the attach type must be set as 0, which is bpf_attach_type::BPF_CGROUP_INET_INGRESS
let link_fd = bpf_link_create(prog_fd, target_fd, BPF_CGROUP_INET_INGRESS, Some(btf_id), 0)
Expand Down
7 changes: 3 additions & 4 deletions aya/src/programs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ use std::{
ffi::CString,
io,
num::NonZeroU32,
os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd},
os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd},
path::{Path, PathBuf},
sync::Arc,
time::{Duration, SystemTime},
Expand Down Expand Up @@ -382,7 +382,6 @@ impl Program {
/// Returns the file descriptor of a program.
///
/// Can be used to add a program to a [`crate::maps::ProgramArray`] or attach an [`Extension`] program.
/// Can be converted to [`RawFd`] using [`AsRawFd`].
pub fn fd(&self) -> Result<&ProgramFd, ProgramError> {
match self {
Program::KProbe(p) => p.fd(),
Expand Down Expand Up @@ -422,7 +421,7 @@ pub(crate) struct ProgramData<T: Link> {
pub(crate) expected_attach_type: Option<bpf_attach_type>,
pub(crate) attach_btf_obj_fd: Option<OwnedFd>,
pub(crate) attach_btf_id: Option<u32>,
pub(crate) attach_prog_fd: Option<RawFd>,
pub(crate) attach_prog_fd: Option<ProgramFd>,
pub(crate) btf_fd: Option<Arc<OwnedFd>>,
pub(crate) verifier_log_level: VerifierLogLevel,
pub(crate) path: Option<PathBuf>,
Expand Down Expand Up @@ -613,7 +612,7 @@ fn load_program<T: Link>(
prog_btf_fd: btf_fd.as_ref().map(|f| f.as_fd()),
attach_btf_obj_fd: attach_btf_obj_fd.as_ref().map(|fd| fd.as_fd()),
attach_btf_id: *attach_btf_id,
attach_prog_fd: *attach_prog_fd,
attach_prog_fd: attach_prog_fd.as_ref().map(|fd| fd.as_fd()),
func_info_rec_size: *func_info_rec_size,
func_info: func_info.clone(),
line_info_rec_size: *line_info_rec_size,
Expand Down
73 changes: 25 additions & 48 deletions aya/src/sys/bpf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use std::{
ffi::{CStr, CString},
io, iter,
mem::{self, MaybeUninit},
os::fd::{AsRawFd as _, BorrowedFd, FromRawFd as _, OwnedFd, RawFd},
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, FromRawFd as _, OwnedFd, RawFd},
slice,
};

use crate::util::KernelVersion;
use libc::{c_char, c_long, close, ENOENT, ENOSPC};
use libc::{c_char, c_long, ENOENT, ENOSPC};
use obj::{
btf::{BtfEnum64, Enum64},
maps::{bpf_map_def, LegacyMap},
Expand Down Expand Up @@ -120,7 +120,7 @@ pub(crate) struct BpfLoadProgramAttrs<'a> {
pub(crate) prog_btf_fd: Option<BorrowedFd<'a>>,
pub(crate) attach_btf_obj_fd: Option<BorrowedFd<'a>>,
pub(crate) attach_btf_id: Option<u32>,
pub(crate) attach_prog_fd: Option<RawFd>,
pub(crate) attach_prog_fd: Option<BorrowedFd<'a>>,
pub(crate) func_info_rec_size: usize,
pub(crate) func_info: FuncSecInfo,
pub(crate) line_info_rec_size: usize,
Expand Down Expand Up @@ -184,14 +184,13 @@ pub(crate) fn bpf_load_program(
u.__bindgen_anon_1.attach_btf_obj_fd = v.as_raw_fd() as _;
}
if let Some(v) = aya_attr.attach_prog_fd {
u.__bindgen_anon_1.attach_prog_fd = v as u32;
u.__bindgen_anon_1.attach_prog_fd = v.as_raw_fd() as u32;
}

if let Some(v) = aya_attr.attach_btf_id {
u.attach_btf_id = v;
}
// SAFETY: BPF_PROG_LOAD returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) }
bpf_prog_load(&mut attr)
}

fn lookup<K: Pod, V: Pod>(
Expand Down Expand Up @@ -633,14 +632,7 @@ pub(crate) fn is_prog_name_supported() -> bool {
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER as u32;

match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
Ok(v) => {
let fd = v as RawFd;
unsafe { close(fd) };
true
}
Err(_) => false,
}
bpf_prog_load(&mut attr).is_ok()
}

pub(crate) fn is_probe_read_kernel_supported() -> bool {
Expand All @@ -664,14 +656,7 @@ pub(crate) fn is_probe_read_kernel_supported() -> bool {
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32;

match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
Ok(v) => {
let fd = v as RawFd;
unsafe { close(fd) };
true
}
Err(_) => false,
}
bpf_prog_load(&mut attr).is_ok()
}

pub(crate) fn is_perf_link_supported() -> bool {
Expand All @@ -691,18 +676,18 @@ pub(crate) fn is_perf_link_supported() -> bool {
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32;

if let Ok(fd) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
if let Err((_, e)) =
if let Ok(fd) = bpf_prog_load(&mut attr) {
let fd = fd.as_fd();
let fd = fd.as_raw_fd();
matches!(
// Uses an invalid target FD so we get EBADF if supported.
bpf_link_create(fd as i32, -1, bpf_attach_type::BPF_PERF_EVENT, None, 0)
{
bpf_link_create(fd, -1, bpf_attach_type::BPF_PERF_EVENT, None, 0),
// Returns EINVAL if unsupported. EBADF if supported.
let res = e.raw_os_error() == Some(libc::EBADF);
unsafe { libc::close(fd as i32) };
return res;
}
Err((_, e)) if e.raw_os_error() == Some(libc::EBADF),
)
} else {
false
}
false
}

pub(crate) fn is_bpf_global_data_supported() -> bool {
Expand Down Expand Up @@ -746,16 +731,10 @@ pub(crate) fn is_bpf_global_data_supported() -> bool {
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER as u32;

if let Ok(v) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
let fd = v as RawFd;

unsafe { close(fd) };

return true;
}
bpf_prog_load(&mut attr).is_ok()
} else {
false
}

false
}

pub(crate) fn is_bpf_cookie_supported() -> bool {
Expand All @@ -775,14 +754,7 @@ pub(crate) fn is_bpf_cookie_supported() -> bool {
u.insns = insns.as_ptr() as u64;
u.prog_type = bpf_prog_type::BPF_PROG_TYPE_KPROBE as u32;

match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &mut attr) {
Ok(v) => {
let fd = v as RawFd;
unsafe { close(fd) };
true
}
Err(_) => false,
}
bpf_prog_load(&mut attr).is_ok()
}

pub(crate) fn is_btf_supported() -> bool {
Expand Down Expand Up @@ -941,6 +913,11 @@ pub(crate) fn is_btf_type_tag_supported() -> bool {
bpf_load_btf(btf_bytes.as_slice(), &mut [], Default::default()).is_ok()
}

fn bpf_prog_load(attr: &mut bpf_attr) -> SysResult<OwnedFd> {
// SAFETY: BPF_PROG_LOAD returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_PROG_LOAD, attr) }
}

fn sys_bpf(cmd: bpf_cmd, attr: &mut bpf_attr) -> SysResult<c_long> {
syscall(Syscall::Bpf { cmd, attr })
}
Expand Down
4 changes: 3 additions & 1 deletion test/integration-test/src/tests/smoke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ fn extension() {
.load(crate::EXT)
.unwrap();
let drop_: &mut Extension = bpf.program_mut("xdp_drop").unwrap().try_into().unwrap();
drop_.load(pass.fd().unwrap(), "xdp_pass").unwrap();
drop_
.load(pass.fd().unwrap().try_clone().unwrap(), "xdp_pass")
.unwrap();
}

#[test]
Expand Down
2 changes: 0 additions & 2 deletions xtask/public-api/aya-log.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ impl core::marker::Sync for aya_log::Error
impl core::marker::Unpin for aya_log::Error
impl !core::panic::unwind_safe::RefUnwindSafe for aya_log::Error
impl !core::panic::unwind_safe::UnwindSafe for aya_log::Error
impl<E> core::any::Provider for aya_log::Error where E: core::error::Error + core::marker::Sized
pub fn aya_log::Error::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_log::Error where U: core::convert::From<T>
pub fn aya_log::Error::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_log::Error where U: core::convert::Into<T>
Expand Down
14 changes: 0 additions & 14 deletions xtask/public-api/aya-obj.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ impl core::marker::Sync for aya_obj::btf::BtfError
impl core::marker::Unpin for aya_obj::btf::BtfError
impl !core::panic::unwind_safe::RefUnwindSafe for aya_obj::btf::BtfError
impl !core::panic::unwind_safe::UnwindSafe for aya_obj::btf::BtfError
impl<E> core::any::Provider for aya_obj::btf::BtfError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::btf::BtfError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::btf::BtfError where U: core::convert::From<T>
pub fn aya_obj::btf::BtfError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::btf::BtfError where U: core::convert::Into<T>
Expand Down Expand Up @@ -557,8 +555,6 @@ impl core::marker::Sync for aya_obj::btf::BtfRelocationError
impl core::marker::Unpin for aya_obj::btf::BtfRelocationError
impl !core::panic::unwind_safe::RefUnwindSafe for aya_obj::btf::BtfRelocationError
impl !core::panic::unwind_safe::UnwindSafe for aya_obj::btf::BtfRelocationError
impl<E> core::any::Provider for aya_obj::btf::BtfRelocationError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::btf::BtfRelocationError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::btf::BtfRelocationError where U: core::convert::From<T>
pub fn aya_obj::btf::BtfRelocationError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::btf::BtfRelocationError where U: core::convert::Into<T>
Expand Down Expand Up @@ -5459,8 +5455,6 @@ impl core::marker::Sync for aya_obj::maps::PinningError
impl core::marker::Unpin for aya_obj::maps::PinningError
impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::maps::PinningError
impl core::panic::unwind_safe::UnwindSafe for aya_obj::maps::PinningError
impl<E> core::any::Provider for aya_obj::maps::PinningError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::maps::PinningError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::maps::PinningError where U: core::convert::From<T>
pub fn aya_obj::maps::PinningError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::maps::PinningError where U: core::convert::Into<T>
Expand Down Expand Up @@ -5798,8 +5792,6 @@ impl core::marker::Sync for aya_obj::ParseError
impl core::marker::Unpin for aya_obj::ParseError
impl !core::panic::unwind_safe::RefUnwindSafe for aya_obj::ParseError
impl !core::panic::unwind_safe::UnwindSafe for aya_obj::ParseError
impl<E> core::any::Provider for aya_obj::ParseError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::ParseError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::ParseError where U: core::convert::From<T>
pub fn aya_obj::ParseError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::ParseError where U: core::convert::Into<T>
Expand Down Expand Up @@ -6321,8 +6313,6 @@ impl core::marker::Sync for aya_obj::relocation::RelocationError
impl core::marker::Unpin for aya_obj::relocation::RelocationError
impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::relocation::RelocationError
impl core::panic::unwind_safe::UnwindSafe for aya_obj::relocation::RelocationError
impl<E> core::any::Provider for aya_obj::relocation::RelocationError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::relocation::RelocationError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::relocation::RelocationError where U: core::convert::From<T>
pub fn aya_obj::relocation::RelocationError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::relocation::RelocationError where U: core::convert::Into<T>
Expand Down Expand Up @@ -6353,8 +6343,6 @@ impl core::marker::Sync for aya_obj::relocation::BpfRelocationError
impl core::marker::Unpin for aya_obj::relocation::BpfRelocationError
impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::relocation::BpfRelocationError
impl core::panic::unwind_safe::UnwindSafe for aya_obj::relocation::BpfRelocationError
impl<E> core::any::Provider for aya_obj::relocation::BpfRelocationError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::relocation::BpfRelocationError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::relocation::BpfRelocationError where U: core::convert::From<T>
pub fn aya_obj::relocation::BpfRelocationError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::relocation::BpfRelocationError where U: core::convert::Into<T>
Expand Down Expand Up @@ -6519,8 +6507,6 @@ impl core::marker::Sync for aya_obj::ParseError
impl core::marker::Unpin for aya_obj::ParseError
impl !core::panic::unwind_safe::RefUnwindSafe for aya_obj::ParseError
impl !core::panic::unwind_safe::UnwindSafe for aya_obj::ParseError
impl<E> core::any::Provider for aya_obj::ParseError where E: core::error::Error + core::marker::Sized
pub fn aya_obj::ParseError::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_obj::ParseError where U: core::convert::From<T>
pub fn aya_obj::ParseError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::ParseError where U: core::convert::Into<T>
Expand Down
2 changes: 0 additions & 2 deletions xtask/public-api/aya-tool.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ impl core::marker::Sync for aya_tool::generate::Error
impl core::marker::Unpin for aya_tool::generate::Error
impl !core::panic::unwind_safe::RefUnwindSafe for aya_tool::generate::Error
impl !core::panic::unwind_safe::UnwindSafe for aya_tool::generate::Error
impl<E> core::any::Provider for aya_tool::generate::Error where E: core::error::Error + core::marker::Sized
pub fn aya_tool::generate::Error::provide<'a>(&'a self, demand: &mut core::any::Demand<'a>)
impl<T, U> core::convert::Into<U> for aya_tool::generate::Error where U: core::convert::From<T>
pub fn aya_tool::generate::Error::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_tool::generate::Error where U: core::convert::Into<T>
Expand Down
Loading

0 comments on commit c7b5cd5

Please sign in to comment.