Browse Source

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 <[email protected]>
Dave Tucker 2 years ago
parent
commit
b4413322e3
2 changed files with 58 additions and 60 deletions
  1. 11 9
      aya/src/maps/array/program_array.rs
  2. 47 51
      aya/src/programs/mod.rs

+ 11 - 9
aya/src/maps/array/program_array.rs

@@ -4,7 +4,7 @@ use std::{
     convert::TryFrom,
     mem,
     ops::{Deref, DerefMut},
-    os::unix::prelude::RawFd,
+    os::unix::prelude::{AsRawFd, RawFd},
 };
 
 use crate::{
@@ -26,26 +26,28 @@ use crate::{
 ///
 /// # Examples
 /// ```no_run
-/// # let bpf = aya::Bpf::load(&[])?;
+/// # let mut bpf = aya::Bpf::load(&[])?;
 /// use aya::maps::ProgramArray;
-/// use aya::programs::{CgroupSkb, ProgramFd};
+/// use aya::programs::CgroupSkb;
 /// use std::convert::{TryFrom, TryInto};
 ///
 /// 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_fd =  prog_0.fd().unwrap();
 /// 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_fd = prog_2.fd().unwrap();
 /// let flags = 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
-/// 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
-/// prog_array.set(2, prog_2, flags);
+/// prog_array.set(2, prog_2_fd, flags);
 /// # Ok::<(), aya::BpfError>(())
 /// ```
 #[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
     /// 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()?;
         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)| {
             MapError::SyscallError {

+ 47 - 51
aya/src/programs/mod.rs

@@ -214,10 +214,14 @@ pub enum ProgramError {
     },
 }
 
-/// Allows the Fd of a loaded [`Program`] to be retrieved
-pub trait ProgramFd {
-    /// Returns the [`RawFd`] of the program if it has been loaded, or `None`
-    fn fd(&self) -> Option<RawFd>;
+/// A [`Program`] file descriptor.
+#[derive(Copy, Clone)]
+pub struct ProgramFd(RawFd);
+
+impl AsRawFd for ProgramFd {
+    fn as_raw_fd(&self) -> RawFd {
+        self.0
+    }
 }
 
 /// eBPF program type.
@@ -359,6 +363,38 @@ impl Program {
             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 {
@@ -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 {
     ($($struct_name:ident),+ $(,)?) => {
         $(
@@ -634,25 +634,20 @@ impl_program_unload!(
     CgroupSock,
 );
 
-macro_rules! impl_program_fd {
+macro_rules! impl_fd {
     ($($struct_name:ident),+ $(,)?) => {
         $(
-            impl ProgramFd for $struct_name {
-                fn fd(&self) -> Option<RawFd> {
-                    self.data.fd
-                }
-            }
-
-            impl ProgramFd for &mut $struct_name {
-                fn fd(&self) -> Option<RawFd> {
-                    self.data.fd
+            impl $struct_name {
+                /// Returns the file descriptor of this Program.
+                pub fn fd(&self) -> Option<ProgramFd> {
+                    self.data.fd.map(|fd| ProgramFd(fd))
                 }
             }
         )+
     }
 }
 
-impl_program_fd!(
+impl_fd!(
     KProbe,
     UProbe,
     TracePoint,
@@ -674,6 +669,7 @@ impl_program_fd!(
     Extension,
     CgroupSockAddr,
     SkLookup,
+    SockOps,
     CgroupSock,
 );