diff --git a/aya/src/programs/links.rs b/aya/src/programs/links.rs index 129d5952..18773584 100644 --- a/aya/src/programs/links.rs +++ b/aya/src/programs/links.rs @@ -14,7 +14,7 @@ use crate::{ generated::bpf_attach_type, pin::PinError, programs::ProgramError, - sys::{bpf_pin_object, bpf_prog_detach}, + sys::{bpf_get_object, bpf_pin_object, bpf_prog_detach}, }; /// A Link. @@ -162,6 +162,12 @@ impl Drop for FdLink { } } +impl From for FdLink { + fn from(p: PinnedLink) -> Self { + p.inner + } +} + /// A pinned file descriptor link. /// /// This link has been pinned to the BPF filesystem. On drop, the file descriptor that backs @@ -181,6 +187,18 @@ impl PinnedLink { } } + /// Creates a [`PinnedLink`] from a valid path on bpffs + pub fn from_path>(path: P) -> Result { + let path_string = CString::new(path.as_ref().to_string_lossy().to_string()).unwrap(); + let fd = + bpf_get_object(&path_string).map_err(|(code, io_error)| LinkError::SyscallError { + call: "BPF_OBJ_GET".to_string(), + code, + io_error, + })? as RawFd; + Ok(PinnedLink::new(path.as_ref().to_path_buf(), fd)) + } + /// Removes the pinned link from the filesystem and returns an [`FdLink`]. pub fn unpin(self) -> Result { std::fs::remove_file(self.path)?; @@ -272,6 +290,17 @@ pub enum LinkError { /// Invalid link. #[error("Invalid link")] InvalidLink, + /// Syscall failed. + #[error("the `{call}` syscall failed with code {code}")] + SyscallError { + /// Syscall Name. + call: String, + /// Error code. + code: libc::c_long, + #[source] + /// Original io::Error. + io_error: io::Error, + }, } #[cfg(test)] diff --git a/aya/src/programs/xdp.rs b/aya/src/programs/xdp.rs index 875a9f04..6aa715eb 100644 --- a/aya/src/programs/xdp.rs +++ b/aya/src/programs/xdp.rs @@ -250,6 +250,12 @@ impl TryFrom for FdLink { } } +impl From for XdpLink { + fn from(fd_link: FdLink) -> Self { + XdpLink(XdpLinkInner::FdLink(fd_link)) + } +} + define_link_wrapper!( /// The link used by [Xdp] programs. XdpLink,