aya: Replace ProgramFd trait with struct

This removes the ProgramFd trait with a struct that wraps a RawFd.
Program::fd() has been implemented as well as fd() for each Program
Type. This allows for a better API than requiring the use of the
ProgramFd trait.

Signed-off-by: Dave Tucker <dave@dtucker.co.uk>
pull/282/head
Dave Tucker 2 years ago
parent fd52bfeadc
commit b4413322e3

@ -4,7 +4,7 @@ use std::{
convert::TryFrom, convert::TryFrom,
mem, mem,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
os::unix::prelude::RawFd, os::unix::prelude::{AsRawFd, RawFd},
}; };
use crate::{ use crate::{
@ -26,26 +26,28 @@ use crate::{
/// ///
/// # Examples /// # Examples
/// ```no_run /// ```no_run
/// # let bpf = aya::Bpf::load(&[])?; /// # let mut bpf = aya::Bpf::load(&[])?;
/// use aya::maps::ProgramArray; /// use aya::maps::ProgramArray;
/// use aya::programs::{CgroupSkb, ProgramFd}; /// use aya::programs::CgroupSkb;
/// use std::convert::{TryFrom, TryInto}; /// use std::convert::{TryFrom, TryInto};
/// ///
/// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?; /// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?;
/// let prog_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?; /// let prog_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?;
/// let prog_0_fd = prog_0.fd().unwrap();
/// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?; /// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?;
/// let prog_1_fd = prog_1.fd().unwrap();
/// let prog_2: &CgroupSkb = bpf.program("example_prog_2").unwrap().try_into()?; /// let prog_2: &CgroupSkb = bpf.program("example_prog_2").unwrap().try_into()?;
/// /// let prog_2_fd = prog_2.fd().unwrap();
/// let flags = 0; /// let flags = 0;
/// ///
/// // bpf_tail_call(ctx, JUMP_TABLE, 0) will jump to prog_0 /// // bpf_tail_call(ctx, JUMP_TABLE, 0) will jump to prog_0
/// prog_array.set(0, prog_0, flags); /// prog_array.set(0, prog_0_fd, flags);
/// ///
/// // bpf_tail_call(ctx, JUMP_TABLE, 1) will jump to prog_1 /// // bpf_tail_call(ctx, JUMP_TABLE, 1) will jump to prog_1
/// prog_array.set(1, prog_1, flags); /// prog_array.set(1, prog_1_fd, flags);
/// ///
/// // bpf_tail_call(ctx, JUMP_TABLE, 2) will jump to prog_2 /// // bpf_tail_call(ctx, JUMP_TABLE, 2) will jump to prog_2
/// prog_array.set(2, prog_2, flags); /// prog_array.set(2, prog_2_fd, flags);
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
#[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")] #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")]
@ -98,10 +100,10 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
/// ///
/// When an eBPF program calls `bpf_tail_call(ctx, prog_array, index)`, control /// When an eBPF program calls `bpf_tail_call(ctx, prog_array, index)`, control
/// flow will jump to `program`. /// flow will jump to `program`.
pub fn set(&mut self, index: u32, program: impl ProgramFd, flags: u64) -> Result<(), MapError> { pub fn set(&mut self, index: u32, program: ProgramFd, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?; let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?; self.check_bounds(index)?;
let prog_fd = program.fd().ok_or(MapError::ProgramNotLoaded)?; let prog_fd = program.as_raw_fd();
bpf_map_update_elem(fd, &index, &prog_fd, flags).map_err(|(code, io_error)| { bpf_map_update_elem(fd, &index, &prog_fd, flags).map_err(|(code, io_error)| {
MapError::SyscallError { MapError::SyscallError {

@ -214,10 +214,14 @@ pub enum ProgramError {
}, },
} }
/// Allows the Fd of a loaded [`Program`] to be retrieved /// A [`Program`] file descriptor.
pub trait ProgramFd { #[derive(Copy, Clone)]
/// Returns the [`RawFd`] of the program if it has been loaded, or `None` pub struct ProgramFd(RawFd);
fn fd(&self) -> Option<RawFd>;
impl AsRawFd for ProgramFd {
fn as_raw_fd(&self) -> RawFd {
self.0
}
} }
/// eBPF program type. /// eBPF program type.
@ -359,6 +363,38 @@ impl Program {
Program::CgroupSock(p) => p.unload(), Program::CgroupSock(p) => p.unload(),
} }
} }
/// 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) -> Option<ProgramFd> {
match self {
Program::KProbe(p) => p.fd(),
Program::UProbe(p) => p.fd(),
Program::TracePoint(p) => p.fd(),
Program::SocketFilter(p) => p.fd(),
Program::Xdp(p) => p.fd(),
Program::SkMsg(p) => p.fd(),
Program::SkSkb(p) => p.fd(),
Program::SockOps(p) => p.fd(),
Program::SchedClassifier(p) => p.fd(),
Program::CgroupSkb(p) => p.fd(),
Program::CgroupSysctl(p) => p.fd(),
Program::CgroupSockopt(p) => p.fd(),
Program::LircMode2(p) => p.fd(),
Program::PerfEvent(p) => p.fd(),
Program::RawTracePoint(p) => p.fd(),
Program::Lsm(p) => p.fd(),
Program::BtfTracePoint(p) => p.fd(),
Program::FEntry(p) => p.fd(),
Program::FExit(p) => p.fd(),
Program::Extension(p) => p.fd(),
Program::CgroupSockAddr(p) => p.fd(),
Program::SkLookup(p) => p.fd(),
Program::CgroupSock(p) => p.fd(),
}
}
} }
impl Drop for Program { impl Drop for Program {
@ -555,42 +591,6 @@ pub(crate) fn query<T: AsRawFd>(
} }
} }
impl ProgramFd for Program {
fn fd(&self) -> Option<RawFd> {
match self {
Program::KProbe(p) => p.data.fd,
Program::UProbe(p) => p.data.fd,
Program::TracePoint(p) => p.data.fd,
Program::SocketFilter(p) => p.data.fd,
Program::Xdp(p) => p.data.fd,
Program::SkMsg(p) => p.data.fd,
Program::SkSkb(p) => p.data.fd,
Program::SockOps(p) => p.data.fd,
Program::SchedClassifier(p) => p.data.fd,
Program::CgroupSkb(p) => p.data.fd,
Program::CgroupSysctl(p) => p.data.fd,
Program::CgroupSockopt(p) => p.data.fd,
Program::LircMode2(p) => p.data.fd,
Program::PerfEvent(p) => p.data.fd,
Program::RawTracePoint(p) => p.data.fd,
Program::Lsm(p) => p.data.fd,
Program::BtfTracePoint(p) => p.data.fd,
Program::FEntry(p) => p.data.fd,
Program::FExit(p) => p.data.fd,
Program::Extension(p) => p.data.fd,
Program::CgroupSockAddr(p) => p.data.fd,
Program::SkLookup(p) => p.data.fd,
Program::CgroupSock(p) => p.data.fd,
}
}
}
impl<'a, P: ProgramFd> ProgramFd for &'a P {
fn fd(&self) -> Option<RawFd> {
(*self).fd()
}
}
macro_rules! impl_program_unload { macro_rules! impl_program_unload {
($($struct_name:ident),+ $(,)?) => { ($($struct_name:ident),+ $(,)?) => {
$( $(
@ -634,25 +634,20 @@ impl_program_unload!(
CgroupSock, CgroupSock,
); );
macro_rules! impl_program_fd { macro_rules! impl_fd {
($($struct_name:ident),+ $(,)?) => { ($($struct_name:ident),+ $(,)?) => {
$( $(
impl ProgramFd for $struct_name { impl $struct_name {
fn fd(&self) -> Option<RawFd> { /// Returns the file descriptor of this Program.
self.data.fd pub fn fd(&self) -> Option<ProgramFd> {
} self.data.fd.map(|fd| ProgramFd(fd))
}
impl ProgramFd for &mut $struct_name {
fn fd(&self) -> Option<RawFd> {
self.data.fd
} }
} }
)+ )+
} }
} }
impl_program_fd!( impl_fd!(
KProbe, KProbe,
UProbe, UProbe,
TracePoint, TracePoint,
@ -674,6 +669,7 @@ impl_program_fd!(
Extension, Extension,
CgroupSockAddr, CgroupSockAddr,
SkLookup, SkLookup,
SockOps,
CgroupSock, CgroupSock,
); );

Loading…
Cancel
Save