aya: Use OwnedFd in FdLink.

reviewable/pr709/r3
Andrés Medina 1 year ago committed by Tamir Duberstein
parent e9153792f1
commit 8ebf0ac327
No known key found for this signature in database

@ -42,7 +42,7 @@ use std::{
marker::PhantomData, marker::PhantomData,
mem, mem,
ops::Deref, ops::Deref,
os::fd::{AsFd, AsRawFd, OwnedFd, RawFd}, os::fd::{AsFd as _, AsRawFd, IntoRawFd as _, OwnedFd, RawFd},
path::Path, path::Path,
ptr, ptr,
sync::Arc, sync::Arc,
@ -516,11 +516,9 @@ impl MapData {
code, code,
io_error, io_error,
} }
})? as RawFd; })?;
self.fd = Some(fd);
Ok(fd) Ok(*self.fd.insert(fd as RawFd))
} }
pub(crate) fn open_pinned<P: AsRef<Path>>( pub(crate) fn open_pinned<P: AsRef<Path>>(
@ -536,11 +534,9 @@ impl MapData {
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
})? as RawFd; })?;
self.fd = Some(fd);
Ok(fd) Ok(*self.fd.insert(fd.into_raw_fd()))
} }
/// Loads a map from a pinned path in bpffs. /// Loads a map from a pinned path in bpffs.
@ -558,29 +554,29 @@ impl MapData {
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
})? as RawFd; })?;
let info = bpf_map_get_info_by_fd(fd)?; let info = bpf_map_get_info_by_fd(fd.as_fd())?;
Ok(MapData { Ok(MapData {
obj: parse_map_info(info, PinningType::ByName), obj: parse_map_info(info, PinningType::ByName),
fd: Some(fd), fd: Some(fd.into_raw_fd()),
btf_fd: None, btf_fd: None,
pinned: true, pinned: true,
}) })
} }
/// Loads a map from a [`RawFd`]. /// Loads a map from a file descriptor.
/// ///
/// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`](crate::maps::MapData::from_pin). /// If loading from a BPF Filesystem (bpffs) you should use [`Map::from_pin`](crate::maps::MapData::from_pin).
/// This API is intended for cases where you have received a valid BPF FD from some other means. /// This API is intended for cases where you have received a valid BPF FD from some other means.
/// For example, you received an FD over Unix Domain Socket. /// For example, you received an FD over Unix Domain Socket.
pub fn from_fd(fd: RawFd) -> Result<MapData, MapError> { pub fn from_fd(fd: OwnedFd) -> Result<MapData, MapError> {
let info = bpf_map_get_info_by_fd(fd)?; let info = bpf_map_get_info_by_fd(fd.as_fd())?;
Ok(MapData { Ok(MapData {
obj: parse_map_info(info, PinningType::None), obj: parse_map_info(info, PinningType::None),
fd: Some(fd), fd: Some(fd.into_raw_fd()),
btf_fd: None, btf_fd: None,
pinned: false, pinned: false,
}) })

@ -1,7 +1,7 @@
//! Cgroup device programs. //! Cgroup device programs.
use crate::util::KernelVersion; use crate::util::KernelVersion;
use std::os::fd::{AsRawFd, RawFd}; use std::os::fd::AsRawFd;
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_CGROUP_DEVICE, bpf_prog_type::BPF_PROG_TYPE_CGROUP_DEVICE}, generated::{bpf_attach_type::BPF_CGROUP_DEVICE, bpf_prog_type::BPF_PROG_TYPE_CGROUP_DEVICE},
@ -70,7 +70,7 @@ impl CgroupDevice {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd( .insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd(

@ -1,11 +1,7 @@
//! Cgroup skb programs. //! Cgroup skb programs.
use crate::util::KernelVersion; use crate::util::KernelVersion;
use std::{ use std::{hash::Hash, os::fd::AsRawFd, path::Path};
hash::Hash,
os::fd::{AsRawFd, RawFd},
path::Path,
};
use crate::{ use crate::{
generated::{ generated::{
@ -105,7 +101,7 @@ impl CgroupSkb {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new( .insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new(

@ -3,11 +3,7 @@
pub use aya_obj::programs::CgroupSockAttachType; pub use aya_obj::programs::CgroupSockAttachType;
use crate::util::KernelVersion; use crate::util::KernelVersion;
use std::{ use std::{hash::Hash, os::fd::AsRawFd, path::Path};
hash::Hash,
os::fd::{AsRawFd, RawFd},
path::Path,
};
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK,
@ -80,7 +76,7 @@ impl CgroupSock {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new( .insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new(

@ -3,11 +3,7 @@
pub use aya_obj::programs::CgroupSockAddrAttachType; pub use aya_obj::programs::CgroupSockAddrAttachType;
use crate::util::KernelVersion; use crate::util::KernelVersion;
use std::{ use std::{hash::Hash, os::fd::AsRawFd, path::Path};
hash::Hash,
os::fd::{AsRawFd, RawFd},
path::Path,
};
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
@ -81,7 +77,7 @@ impl CgroupSockAddr {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd( .insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd(

@ -3,11 +3,7 @@
pub use aya_obj::programs::CgroupSockoptAttachType; pub use aya_obj::programs::CgroupSockoptAttachType;
use crate::util::KernelVersion; use crate::util::KernelVersion;
use std::{ use std::{hash::Hash, os::fd::AsRawFd, path::Path};
hash::Hash,
os::fd::{AsRawFd, RawFd},
path::Path,
};
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT,
@ -78,7 +74,7 @@ impl CgroupSockopt {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd( .insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd(

@ -1,10 +1,7 @@
//! Cgroup sysctl programs. //! Cgroup sysctl programs.
use crate::util::KernelVersion; use crate::util::KernelVersion;
use std::{ use std::{hash::Hash, os::fd::AsRawFd};
hash::Hash,
os::fd::{AsRawFd, RawFd},
};
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL}, generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL},
@ -72,7 +69,7 @@ impl CgroupSysctl {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd( .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(

@ -94,7 +94,7 @@ impl Extension {
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})? as RawFd; })?;
self.data self.data
.links .links
.insert(ExtensionLink::new(FdLink::new(link_fd))) .insert(ExtensionLink::new(FdLink::new(link_fd)))
@ -124,7 +124,7 @@ impl Extension {
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
})? as RawFd; })?;
self.data self.data
.links .links
.insert(ExtensionLink::new(FdLink::new(link_fd))) .insert(ExtensionLink::new(FdLink::new(link_fd)))

@ -1,5 +1,5 @@
//! Kernel space probes. //! Kernel space probes.
use std::{io, path::Path}; use std::{io, os::fd::AsFd as _, path::Path};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
@ -137,7 +137,7 @@ impl TryFrom<FdLink> for KProbeLink {
type Error = LinkError; type Error = LinkError;
fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> { fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> {
let info = bpf_link_get_info_by_fd(fd_link.fd)?; let info = bpf_link_get_info_by_fd(fd_link.fd.as_fd())?;
if info.type_ == (bpf_link_type::BPF_LINK_TYPE_KPROBE_MULTI as u32) { if info.type_ == (bpf_link_type::BPF_LINK_TYPE_KPROBE_MULTI as u32) {
return Ok(KProbeLink::new(PerfLinkInner::FdLink(fd_link))); return Ok(KProbeLink::new(PerfLinkInner::FdLink(fd_link)));
} }

@ -6,7 +6,7 @@ use std::{
collections::{hash_map::Entry, HashMap}, collections::{hash_map::Entry, HashMap},
ffi::CString, ffi::CString,
io, io,
os::fd::RawFd, os::fd::{AsRawFd as _, OwnedFd, RawFd},
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -108,11 +108,11 @@ pub struct FdLinkId(pub(crate) RawFd);
/// ``` /// ```
#[derive(Debug)] #[derive(Debug)]
pub struct FdLink { pub struct FdLink {
pub(crate) fd: RawFd, pub(crate) fd: OwnedFd,
} }
impl FdLink { impl FdLink {
pub(crate) fn new(fd: RawFd) -> FdLink { pub(crate) fn new(fd: OwnedFd) -> FdLink {
FdLink { fd } FdLink { fd }
} }
@ -152,9 +152,11 @@ impl FdLink {
error: e.to_string(), error: e.to_string(),
} }
})?; })?;
bpf_pin_object(self.fd, &path_string).map_err(|(_, io_error)| SyscallError { bpf_pin_object(self.fd.as_raw_fd(), &path_string).map_err(|(_, io_error)| {
call: "BPF_OBJ_PIN", SyscallError {
io_error, call: "BPF_OBJ_PIN",
io_error,
}
})?; })?;
Ok(PinnedLink::new(PathBuf::from(path.as_ref()), self)) Ok(PinnedLink::new(PathBuf::from(path.as_ref()), self))
} }
@ -164,7 +166,7 @@ impl Link for FdLink {
type Id = FdLinkId; type Id = FdLinkId;
fn id(&self) -> Self::Id { fn id(&self) -> Self::Id {
FdLinkId(self.fd) FdLinkId(self.fd.as_raw_fd())
} }
fn detach(self) -> Result<(), ProgramError> { fn detach(self) -> Result<(), ProgramError> {
@ -183,12 +185,6 @@ impl From<PinnedLink> for FdLink {
} }
} }
impl Drop for FdLink {
fn drop(&mut self) {
unsafe { close(self.fd) };
}
}
/// A pinned file descriptor link. /// A pinned file descriptor link.
/// ///
/// This link has been pinned to the BPF filesystem. On drop, the file descriptor that backs /// This link has been pinned to the BPF filesystem. On drop, the file descriptor that backs
@ -213,7 +209,7 @@ impl PinnedLink {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
}) })
})? as RawFd; })?;
Ok(PinnedLink::new( Ok(PinnedLink::new(
path.as_ref().to_path_buf(), path.as_ref().to_path_buf(),
FdLink::new(fd), FdLink::new(fd),
@ -346,7 +342,7 @@ pub enum LinkError {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use assert_matches::assert_matches; use assert_matches::assert_matches;
use std::{cell::RefCell, fs::File, mem, os::fd::AsRawFd, rc::Rc}; use std::{cell::RefCell, fs::File, rc::Rc};
use tempfile::tempdir; use tempfile::tempdir;
use crate::{programs::ProgramError, sys::override_syscall}; use crate::{programs::ProgramError, sys::override_syscall};
@ -484,10 +480,7 @@ mod tests {
fn test_pin() { fn test_pin() {
let dir = tempdir().unwrap(); let dir = tempdir().unwrap();
let f1 = File::create(dir.path().join("f1")).expect("unable to create file in tmpdir"); let f1 = File::create(dir.path().join("f1")).expect("unable to create file in tmpdir");
let fd_link = FdLink::new(f1.as_raw_fd()); let fd_link = FdLink::new(f1.into());
// leak the fd, it will get closed when our pinned link is dropped
mem::forget(f1);
// override syscall to allow for pin to happen in our tmpdir // override syscall to allow for pin to happen in our tmpdir
override_syscall(|_| Ok(0)); override_syscall(|_| Ok(0));

@ -440,7 +440,7 @@ impl<T: Link> ProgramData<T> {
pub(crate) fn from_bpf_prog_info( pub(crate) fn from_bpf_prog_info(
name: Option<String>, name: Option<String>,
fd: RawFd, fd: OwnedFd,
path: &Path, path: &Path,
info: bpf_prog_info, info: bpf_prog_info,
verifier_log_level: VerifierLogLevel, verifier_log_level: VerifierLogLevel,
@ -464,7 +464,7 @@ impl<T: Link> ProgramData<T> {
Ok(ProgramData { Ok(ProgramData {
name, name,
obj: None, obj: None,
fd: Some(fd), fd: Some(fd.into_raw_fd()),
links: LinkMap::new(), links: LinkMap::new(),
expected_attach_type: None, expected_attach_type: None,
attach_btf_obj_fd, attach_btf_obj_fd,
@ -486,9 +486,9 @@ impl<T: Link> ProgramData<T> {
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError {
call: "bpf_obj_get", call: "bpf_obj_get",
io_error, io_error,
})? as RawFd; })?;
let info = bpf_prog_get_info_by_fd(fd)?; let info = bpf_prog_get_info_by_fd(fd.as_raw_fd())?;
let name = ProgramInfo(info).name_as_str().map(|s| s.to_string()); 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) ProgramData::from_bpf_prog_info(name, fd, path.as_ref(), info, verifier_log_level)
} }
@ -953,13 +953,9 @@ impl ProgramInfo {
let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError { let fd = bpf_get_object(&path_string).map_err(|(_, io_error)| SyscallError {
call: "BPF_OBJ_GET", call: "BPF_OBJ_GET",
io_error, io_error,
})? as RawFd; })?;
let info = bpf_prog_get_info_by_fd(fd); let info = bpf_prog_get_info_by_fd(fd.as_raw_fd())?;
unsafe {
libc::close(fd);
}
let info = info?;
Ok(ProgramInfo(info)) Ok(ProgramInfo(info))
} }
} }
@ -1011,7 +1007,7 @@ pub fn loaded_links() -> impl Iterator<Item = Result<bpf_link_info, ProgramError
}) })
.map(|fd| { .map(|fd| {
let fd = fd?; let fd = fd?;
bpf_link_get_info_by_fd(fd.as_raw_fd()) bpf_link_get_info_by_fd(fd.as_fd())
}) })
.map(|result| result.map_err(Into::into)) .map(|result| result.map_err(Into::into))
} }

@ -77,7 +77,7 @@ pub(crate) fn perf_attach(prog_fd: RawFd, fd: OwnedFd) -> Result<PerfLinkInner,
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
Ok(PerfLinkInner::FdLink(FdLink::new(link_fd))) Ok(PerfLinkInner::FdLink(FdLink::new(link_fd)))
} else { } else {
perf_attach_either(prog_fd, fd, None) perf_attach_either(prog_fd, fd, None)

@ -1,5 +1,7 @@
//! Perf event programs. //! Perf event programs.
use std::os::fd::AsFd as _;
pub use crate::generated::{ pub use crate::generated::{
perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids, perf_hw_cache_id, perf_hw_cache_op_id, perf_hw_cache_op_result_id, perf_hw_id, perf_sw_ids,
}; };
@ -206,7 +208,7 @@ impl TryFrom<FdLink> for PerfEventLink {
type Error = LinkError; type Error = LinkError;
fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> { fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> {
let info = bpf_link_get_info_by_fd(fd_link.fd)?; let info = bpf_link_get_info_by_fd(fd_link.fd.as_fd())?;
if info.type_ == (bpf_link_type::BPF_LINK_TYPE_PERF_EVENT as u32) { if info.type_ == (bpf_link_type::BPF_LINK_TYPE_PERF_EVENT as u32) {
return Ok(PerfEventLink::new(PerfLinkInner::FdLink(fd_link))); return Ok(PerfEventLink::new(PerfLinkInner::FdLink(fd_link)));
} }

@ -1,4 +1,4 @@
use std::os::fd::{AsRawFd, RawFd}; use std::os::fd::AsRawFd;
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_SK_LOOKUP, bpf_prog_type::BPF_PROG_TYPE_SK_LOOKUP}, generated::{bpf_attach_type::BPF_SK_LOOKUP, bpf_prog_type::BPF_PROG_TYPE_SK_LOOKUP},
@ -69,7 +69,7 @@ impl SkLookup {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(SkLookupLink::new(FdLink::new(link_fd))) .insert(SkLookupLink::new(FdLink::new(link_fd)))

@ -1,5 +1,5 @@
//! Tracepoint programs. //! Tracepoint programs.
use std::{fs, io, path::Path}; use std::{fs, io, os::fd::AsFd as _, path::Path};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
@ -131,7 +131,7 @@ impl TryFrom<FdLink> for TracePointLink {
type Error = LinkError; type Error = LinkError;
fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> { fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> {
let info = bpf_link_get_info_by_fd(fd_link.fd)?; let info = bpf_link_get_info_by_fd(fd_link.fd.as_fd())?;
if info.type_ == (bpf_link_type::BPF_LINK_TYPE_TRACING as u32) { if info.type_ == (bpf_link_type::BPF_LINK_TYPE_TRACING as u32) {
return Ok(TracePointLink::new(PerfLinkInner::FdLink(fd_link))); return Ok(TracePointLink::new(PerfLinkInner::FdLink(fd_link)));
} }

@ -8,7 +8,7 @@ use std::{
fs, fs,
io::{self, BufRead, Cursor, Read}, io::{self, BufRead, Cursor, Read},
mem, mem,
os::raw::c_char, os::{fd::AsFd as _, raw::c_char},
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Arc, sync::Arc,
}; };
@ -202,7 +202,7 @@ impl TryFrom<FdLink> for UProbeLink {
type Error = LinkError; type Error = LinkError;
fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> { fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> {
let info = bpf_link_get_info_by_fd(fd_link.fd)?; let info = bpf_link_get_info_by_fd(fd_link.fd.as_fd())?;
if info.type_ == (bpf_link_type::BPF_LINK_TYPE_TRACING as u32) { if info.type_ == (bpf_link_type::BPF_LINK_TYPE_TRACING as u32) {
return Ok(UProbeLink::new(PerfLinkInner::FdLink(fd_link))); return Ok(UProbeLink::new(PerfLinkInner::FdLink(fd_link)));
} }

@ -1,5 +1,5 @@
//! Common functions shared between multiple eBPF program types. //! Common functions shared between multiple eBPF program types.
use std::{ffi::CStr, io, os::fd::RawFd, path::Path}; use std::{ffi::CStr, io, path::Path};
use crate::{ use crate::{
programs::{FdLink, Link, ProgramData, ProgramError}, programs::{FdLink, Link, ProgramData, ProgramError},
@ -17,7 +17,7 @@ pub(crate) fn attach_raw_tracepoint<T: Link + From<FdLink>>(
bpf_raw_tracepoint_open(tp_name, prog_fd).map_err(|(_code, io_error)| SyscallError { bpf_raw_tracepoint_open(tp_name, prog_fd).map_err(|(_code, io_error)| SyscallError {
call: "bpf_raw_tracepoint_open", call: "bpf_raw_tracepoint_open",
io_error, io_error,
})? as RawFd; })?;
program_data.links.insert(FdLink::new(pfd).into()) program_data.links.insert(FdLink::new(pfd).into())
} }

@ -3,7 +3,13 @@
use crate::{sys::SyscallError, util::KernelVersion}; use crate::{sys::SyscallError, util::KernelVersion};
use bitflags; use bitflags;
use libc::if_nametoindex; use libc::if_nametoindex;
use std::{convert::TryFrom, ffi::CString, hash::Hash, io, mem, os::fd::RawFd}; use std::{
convert::TryFrom,
ffi::CString,
hash::Hash,
io,
os::fd::{AsFd as _, RawFd},
};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
@ -131,7 +137,7 @@ impl Xdp {
call: "bpf_link_create", call: "bpf_link_create",
io_error, io_error,
}, },
)? as RawFd; )?;
self.data self.data
.links .links
.insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd)))) .insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd))))
@ -169,17 +175,16 @@ impl Xdp {
/// Ownership of the link will transfer to this program. /// Ownership of the link will transfer to this program.
pub fn attach_to_link(&mut self, link: XdpLink) -> Result<XdpLinkId, ProgramError> { pub fn attach_to_link(&mut self, link: XdpLink) -> Result<XdpLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
match link.inner() { match link.into_inner() {
XdpLinkInner::FdLink(fd_link) => { XdpLinkInner::FdLink(fd_link) => {
let link_fd = fd_link.fd; let link_fd = fd_link.fd;
bpf_link_update(link_fd, prog_fd, None, 0).map_err(|(_, io_error)| { bpf_link_update(link_fd.as_fd(), prog_fd, None, 0).map_err(|(_, io_error)| {
SyscallError { SyscallError {
call: "bpf_link_update", call: "bpf_link_update",
io_error, io_error,
} }
})?; })?;
// dispose of link and avoid detach on drop
mem::forget(link);
self.data self.data
.links .links
.insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd)))) .insert(XdpLink::new(XdpLinkInner::FdLink(FdLink::new(link_fd))))
@ -193,8 +198,7 @@ impl Xdp {
netlink_set_xdp_fd(if_index, prog_fd, Some(old_prog_fd), replace_flags.bits()) netlink_set_xdp_fd(if_index, prog_fd, Some(old_prog_fd), replace_flags.bits())
.map_err(|io_error| XdpError::NetlinkError { io_error })?; .map_err(|io_error| XdpError::NetlinkError { io_error })?;
} }
// dispose of link and avoid detach on drop
mem::forget(link);
self.data self.data
.links .links
.insert(XdpLink::new(XdpLinkInner::NlLink(NlLink { .insert(XdpLink::new(XdpLinkInner::NlLink(NlLink {
@ -279,7 +283,7 @@ impl TryFrom<FdLink> for XdpLink {
fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> { fn try_from(fd_link: FdLink) -> Result<Self, Self::Error> {
// unwrap of fd_link.fd will not panic since it's only None when being dropped. // unwrap of fd_link.fd will not panic since it's only None when being dropped.
let info = bpf_link_get_info_by_fd(fd_link.fd)?; let info = bpf_link_get_info_by_fd(fd_link.fd.as_fd())?;
if info.type_ == (bpf_link_type::BPF_LINK_TYPE_XDP as u32) { if info.type_ == (bpf_link_type::BPF_LINK_TYPE_XDP as u32) {
return Ok(XdpLink::new(XdpLinkInner::FdLink(fd_link))); return Ok(XdpLink::new(XdpLinkInner::FdLink(fd_link)));
} }

@ -101,11 +101,12 @@ pub(crate) fn bpf_pin_object(fd: RawFd, path: &CStr) -> SysResult<c_long> {
sys_bpf(bpf_cmd::BPF_OBJ_PIN, &mut attr) sys_bpf(bpf_cmd::BPF_OBJ_PIN, &mut attr)
} }
pub(crate) fn bpf_get_object(path: &CStr) -> SysResult<c_long> { pub(crate) fn bpf_get_object(path: &CStr) -> SysResult<OwnedFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_4 }; let u = unsafe { &mut attr.__bindgen_anon_4 };
u.pathname = path.as_ptr() as u64; u.pathname = path.as_ptr() as u64;
sys_bpf(bpf_cmd::BPF_OBJ_GET, &mut attr) // SAFETY: BPF_OBJ_GET returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_OBJ_GET, &mut attr) }
} }
pub(crate) struct BpfLoadProgramAttrs<'a> { pub(crate) struct BpfLoadProgramAttrs<'a> {
@ -370,7 +371,7 @@ pub(crate) fn bpf_link_create(
attach_type: bpf_attach_type, attach_type: bpf_attach_type,
btf_id: Option<u32>, btf_id: Option<u32>,
flags: u32, flags: u32,
) -> SysResult<c_long> { ) -> SysResult<OwnedFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.link_create.__bindgen_anon_1.prog_fd = prog_fd as u32; attr.link_create.__bindgen_anon_1.prog_fd = prog_fd as u32;
@ -381,19 +382,20 @@ pub(crate) fn bpf_link_create(
attr.link_create.__bindgen_anon_3.target_btf_id = btf_id; attr.link_create.__bindgen_anon_3.target_btf_id = btf_id;
} }
sys_bpf(bpf_cmd::BPF_LINK_CREATE, &mut attr) // SAFETY: BPF_LINK_CREATE returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_LINK_CREATE, &mut attr) }
} }
// since kernel 5.7 // since kernel 5.7
pub(crate) fn bpf_link_update( pub(crate) fn bpf_link_update(
link_fd: RawFd, link_fd: BorrowedFd<'_>,
new_prog_fd: RawFd, new_prog_fd: RawFd,
old_prog_fd: Option<RawFd>, old_prog_fd: Option<RawFd>,
flags: u32, flags: u32,
) -> SysResult<c_long> { ) -> SysResult<c_long> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.link_update.link_fd = link_fd as u32; attr.link_update.link_fd = link_fd.as_raw_fd() as u32;
attr.link_update.__bindgen_anon_1.new_prog_fd = new_prog_fd as u32; attr.link_update.__bindgen_anon_1.new_prog_fd = new_prog_fd as u32;
if let Some(fd) = old_prog_fd { if let Some(fd) = old_prog_fd {
attr.link_update.__bindgen_anon_2.old_prog_fd = fd as u32; attr.link_update.__bindgen_anon_2.old_prog_fd = fd as u32;
@ -503,8 +505,7 @@ pub(crate) fn bpf_prog_get_info_by_fd(fd: RawFd) -> Result<bpf_prog_info, Syscal
bpf_obj_get_info_by_fd::<bpf_prog_info>(fd) bpf_obj_get_info_by_fd::<bpf_prog_info>(fd)
} }
pub(crate) fn bpf_map_get_info_by_fd(fd: RawFd) -> Result<bpf_map_info, SyscallError> { pub(crate) fn bpf_map_get_info_by_fd(fd: BorrowedFd<'_>) -> Result<bpf_map_info, SyscallError> {
let fd = unsafe { BorrowedFd::borrow_raw(fd) };
bpf_obj_get_info_by_fd::<bpf_map_info>(fd) bpf_obj_get_info_by_fd::<bpf_map_info>(fd)
} }
@ -522,8 +523,7 @@ 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: RawFd) -> Result<bpf_link_info, SyscallError> { pub(crate) fn bpf_link_get_info_by_fd(fd: BorrowedFd<'_>) -> Result<bpf_link_info, SyscallError> {
let fd = unsafe { BorrowedFd::borrow_raw(fd) };
bpf_obj_get_info_by_fd::<bpf_link_info>(fd) bpf_obj_get_info_by_fd::<bpf_link_info>(fd)
} }
@ -546,7 +546,7 @@ pub(crate) fn btf_obj_get_info_by_fd(
} }
} }
pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> SysResult<c_long> { pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> SysResult<OwnedFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.raw_tracepoint.name = match name { attr.raw_tracepoint.name = match name {
@ -555,7 +555,8 @@ pub(crate) fn bpf_raw_tracepoint_open(name: Option<&CStr>, prog_fd: RawFd) -> Sy
}; };
attr.raw_tracepoint.prog_fd = prog_fd as u32; attr.raw_tracepoint.prog_fd = prog_fd as u32;
sys_bpf(bpf_cmd::BPF_RAW_TRACEPOINT_OPEN, &mut attr) // SAFETY: BPF_RAW_TRACEPOINT_OPEN returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_RAW_TRACEPOINT_OPEN, &mut attr) }
} }
pub(crate) fn bpf_load_btf( pub(crate) fn bpf_load_btf(

@ -1238,7 +1238,7 @@ pub aya::maps::MapData::pinned: bool
impl aya::maps::MapData impl aya::maps::MapData
pub fn aya::maps::MapData::create(&mut self, name: &str) -> core::result::Result<std::os::fd::raw::RawFd, aya::maps::MapError> pub fn aya::maps::MapData::create(&mut self, name: &str) -> core::result::Result<std::os::fd::raw::RawFd, aya::maps::MapError>
pub fn aya::maps::MapData::fd(&self) -> core::option::Option<aya::maps::MapFd> pub fn aya::maps::MapData::fd(&self) -> core::option::Option<aya::maps::MapFd>
pub fn aya::maps::MapData::from_fd(fd: std::os::fd::raw::RawFd) -> core::result::Result<aya::maps::MapData, aya::maps::MapError> pub fn aya::maps::MapData::from_fd(fd: std::os::fd::owned::OwnedFd) -> core::result::Result<aya::maps::MapData, aya::maps::MapError>
pub fn aya::maps::MapData::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<aya::maps::MapData, aya::maps::MapError> pub fn aya::maps::MapData::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<aya::maps::MapData, aya::maps::MapError>
impl core::clone::Clone for aya::maps::MapData impl core::clone::Clone for aya::maps::MapData
pub fn aya::maps::MapData::clone(&self) -> aya::maps::MapData pub fn aya::maps::MapData::clone(&self) -> aya::maps::MapData
@ -3099,8 +3099,6 @@ pub fn aya::programs::links::FdLink::try_from(value: aya::programs::uprobe::UPro
impl core::convert::TryFrom<aya::programs::xdp::XdpLink> for aya::programs::links::FdLink impl core::convert::TryFrom<aya::programs::xdp::XdpLink> for aya::programs::links::FdLink
pub type aya::programs::links::FdLink::Error = aya::programs::links::LinkError pub type aya::programs::links::FdLink::Error = aya::programs::links::LinkError
pub fn aya::programs::links::FdLink::try_from(value: aya::programs::xdp::XdpLink) -> core::result::Result<Self, Self::Error> pub fn aya::programs::links::FdLink::try_from(value: aya::programs::xdp::XdpLink) -> core::result::Result<Self, Self::Error>
impl core::ops::drop::Drop for aya::programs::links::FdLink
pub fn aya::programs::links::FdLink::drop(&mut self)
impl core::fmt::Debug for aya::programs::links::FdLink impl core::fmt::Debug for aya::programs::links::FdLink
pub fn aya::programs::links::FdLink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn aya::programs::links::FdLink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Send for aya::programs::links::FdLink impl core::marker::Send for aya::programs::links::FdLink

Loading…
Cancel
Save