Also use BorrowedFd in SockMapFd

reviewable/pr614/r5
Andrés Medina 2 years ago
parent 9f5b205993
commit 18ea23fff8

@ -24,9 +24,10 @@
//! //!
//! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?; //! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?;
//! let map_fd = intercept_egress.fd()?; //! let map_fd = intercept_egress.fd()?;
//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; //! // TODO (AM) figure out lifetimes
//! prog.load()?; //! // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
//! prog.attach(map_fd)?; //! // prog.load()?;
//! // prog.attach(map_fd)?;
//! //!
//! # Ok::<(), aya::BpfError>(()) //! # Ok::<(), aya::BpfError>(())
//! ``` //! ```

@ -1,13 +1,16 @@
use std::{ use std::{
ffi::c_void, ffi::c_void,
io, mem, io, mem,
os::unix::io::{AsRawFd, RawFd}, os::{
fd::OwnedFd,
unix::io::{AsRawFd, RawFd},
},
ptr, slice, ptr, slice,
sync::atomic::{self, AtomicPtr, Ordering}, sync::atomic::{self, AtomicPtr, Ordering},
}; };
use bytes::BytesMut; use bytes::BytesMut;
use libc::{c_int, close, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE}; use libc::{c_int, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE};
use thiserror::Error; use thiserror::Error;
use crate::{ use crate::{
@ -87,7 +90,7 @@ pub(crate) struct PerfBuffer {
buf: AtomicPtr<perf_event_mmap_page>, buf: AtomicPtr<perf_event_mmap_page>,
size: usize, size: usize,
page_size: usize, page_size: usize,
fd: RawFd, fd: OwnedFd,
} }
impl PerfBuffer { impl PerfBuffer {
@ -101,8 +104,7 @@ impl PerfBuffer {
} }
let fd = perf_event_open_bpf(cpu_id as i32) let fd = perf_event_open_bpf(cpu_id as i32)
.map_err(|(_, io_error)| PerfBufferError::OpenError { io_error })? .map_err(|(_, io_error)| PerfBufferError::OpenError { io_error })?;
as RawFd;
let size = page_size * page_count; let size = page_size * page_count;
let buf = unsafe { let buf = unsafe {
mmap( mmap(
@ -110,7 +112,8 @@ impl PerfBuffer {
size + page_size, size + page_size,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_SHARED, MAP_SHARED,
fd, // TODO (AM)
fd.as_raw_fd(),
0, 0,
) )
}; };
@ -127,7 +130,8 @@ impl PerfBuffer {
page_size, page_size,
}; };
perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) // TODO (AM)
perf_event_ioctl(perf_buf.fd.as_raw_fd(), PERF_EVENT_IOC_ENABLE, 0)
.map_err(|(_, io_error)| PerfBufferError::PerfEventEnableError { io_error })?; .map_err(|(_, io_error)| PerfBufferError::PerfEventEnableError { io_error })?;
Ok(perf_buf) Ok(perf_buf)
@ -260,19 +264,19 @@ impl PerfBuffer {
impl AsRawFd for PerfBuffer { impl AsRawFd for PerfBuffer {
fn as_raw_fd(&self) -> RawFd { fn as_raw_fd(&self) -> RawFd {
self.fd self.fd.as_raw_fd()
} }
} }
impl Drop for PerfBuffer { impl Drop for PerfBuffer {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
let _ = perf_event_ioctl(self.fd, PERF_EVENT_IOC_DISABLE, 0); // TODO (AM)
let _ = perf_event_ioctl(self.fd.as_raw_fd(), PERF_EVENT_IOC_DISABLE, 0);
munmap( munmap(
self.buf.load(Ordering::SeqCst) as *mut c_void, self.buf.load(Ordering::SeqCst) as *mut c_void,
self.size + self.page_size, self.size + self.page_size,
); );
close(self.fd);
} }
} }
} }

@ -5,14 +5,23 @@ mod sock_map;
pub use sock_hash::SockHash; pub use sock_hash::SockHash;
pub use sock_map::SockMap; pub use sock_map::SockMap;
use std::os::unix::io::{AsRawFd, RawFd}; use std::os::{
fd::{AsFd, BorrowedFd},
unix::io::{AsRawFd, RawFd},
};
/// A socket map file descriptor. /// A socket map file descriptor.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct SockMapFd(RawFd); pub struct SockMapFd<'f>(BorrowedFd<'f>);
impl AsRawFd for SockMapFd { impl AsRawFd for SockMapFd<'_> {
fn as_raw_fd(&self) -> RawFd { fn as_raw_fd(&self) -> RawFd {
self.0 self.0.as_raw_fd()
}
}
impl AsFd for SockMapFd<'_> {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
} }
} }

@ -49,9 +49,10 @@ use crate::{
/// let mut intercept_egress = SockHash::<_, u32>::try_from(bpf.map("INTERCEPT_EGRESS").unwrap())?; /// let mut intercept_egress = SockHash::<_, u32>::try_from(bpf.map("INTERCEPT_EGRESS").unwrap())?;
/// let map_fd = intercept_egress.fd()?; /// let map_fd = intercept_egress.fd()?;
/// ///
/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// // TODO (AM) : figure out lifetimes
/// prog.load()?; /// // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
/// prog.attach(map_fd)?; /// // prog.load()?;
/// // prog.attach(map_fd)?;
/// ///
/// let mut client = TcpStream::connect("127.0.0.1:1234")?; /// let mut client = TcpStream::connect("127.0.0.1:1234")?;
/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?; /// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?;
@ -108,9 +109,8 @@ impl<T: Borrow<MapData>, K: Pod> SockHash<T, K> {
/// ///
/// The returned file descriptor can be used to attach programs that work with /// The returned file descriptor can be used to attach programs that work with
/// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb). /// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb).
pub fn fd(&self) -> Result<SockMapFd, MapError> { pub fn fd(&self) -> Result<SockMapFd<'_>, MapError> {
// TODO (AM) Ok(SockMapFd(self.inner.borrow().fd_or_err()?))
Ok(SockMapFd(self.inner.borrow().fd_or_err()?.as_raw_fd()))
} }
} }

@ -33,9 +33,10 @@ use crate::{
/// let intercept_ingress = SockMap::try_from(bpf.map("INTERCEPT_INGRESS").unwrap())?; /// let intercept_ingress = SockMap::try_from(bpf.map("INTERCEPT_INGRESS").unwrap())?;
/// let map_fd = intercept_ingress.fd()?; /// let map_fd = intercept_ingress.fd()?;
/// ///
/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// // TODO (AM): figure out lifetimes
/// prog.load()?; /// // let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
/// prog.attach(map_fd)?; /// // prog.load()?;
/// // prog.attach(map_fd)?;
/// ///
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
@ -64,9 +65,8 @@ impl<T: Borrow<MapData>> SockMap<T> {
/// ///
/// The returned file descriptor can be used to attach programs that work with /// The returned file descriptor can be used to attach programs that work with
/// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb). /// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb).
pub fn fd(&self) -> Result<SockMapFd, MapError> { pub fn fd(&self) -> Result<SockMapFd<'_>, MapError> {
// TODO (AM) Ok(SockMapFd(self.inner.borrow().fd_or_err()?))
Ok(SockMapFd(self.inner.borrow().fd_or_err()?.as_raw_fd()))
} }
} }

@ -1,5 +1,5 @@
//! Cgroup device programs. //! Cgroup device programs.
use std::os::fd::AsRawFd; use std::os::{fd::AsFd, unix::prelude::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},
@ -58,18 +58,19 @@ impl CgroupDevice {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [CgroupDevice::detach] /// The returned value can be used to detach, see [CgroupDevice::detach]
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<CgroupDeviceLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupDeviceLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
let k_ver = kernel_version().unwrap(); let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) { if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, None, 0).map_err( // TODO (AM)
|(_, io_error)| ProgramError::SyscallError { let link_fd =
bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), BPF_CGROUP_DEVICE, None, 0)
.map_err(|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
}, })?;
)?;
self.data self.data
.links .links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd( .insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd(
@ -86,7 +87,11 @@ impl CgroupDevice {
.links .links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach( .insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach(
// TODO (AM) // TODO (AM)
ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, BPF_CGROUP_DEVICE), ProgAttachLink::new(
prog_fd.as_raw_fd(),
cgroup_fd.try_clone_to_owned()?,
BPF_CGROUP_DEVICE,
),
))) )))
} }
} }

@ -1,5 +1,9 @@
//! Cgroup skb programs. //! Cgroup skb programs.
use std::{hash::Hash, os::fd::AsRawFd, path::Path}; use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
path::Path,
};
use crate::{ use crate::{
generated::{ generated::{
@ -80,13 +84,13 @@ impl CgroupSkb {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [CgroupSkb::detach]. /// The returned value can be used to detach, see [CgroupSkb::detach].
pub fn attach<T: AsRawFd>( pub fn attach<T: AsFd>(
&mut self, &mut self,
cgroup: T, cgroup: T,
attach_type: CgroupSkbAttachType, attach_type: CgroupSkbAttachType,
) -> Result<CgroupSkbLinkId, ProgramError> { ) -> Result<CgroupSkbLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = match attach_type { let attach_type = match attach_type {
CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS, CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS,
@ -94,12 +98,12 @@ impl CgroupSkb {
}; };
let k_ver = kernel_version().unwrap(); let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) { if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( // TODO (AM)
|(_, io_error)| ProgramError::SyscallError { let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0)
.map_err(|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
}, })?;
)?;
self.data self.data
.links .links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new( .insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new(
@ -117,7 +121,11 @@ impl CgroupSkb {
.links .links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach( .insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach(
// TODO (AM) // TODO (AM)
ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, attach_type), ProgAttachLink::new(
prog_fd.as_raw_fd(),
cgroup_fd.try_clone_to_owned()?,
attach_type,
),
))) )))
} }
} }

@ -1,7 +1,11 @@
//! Cgroup socket programs. //! Cgroup socket programs.
pub use aya_obj::programs::CgroupSockAttachType; pub use aya_obj::programs::CgroupSockAttachType;
use std::{hash::Hash, os::fd::AsRawFd, path::Path}; use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
path::Path,
};
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK,
@ -63,18 +67,18 @@ impl CgroupSock {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [CgroupSock::detach]. /// The returned value can be used to detach, see [CgroupSock::detach].
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<CgroupSockLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSockLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap(); let attach_type = self.data.expected_attach_type.unwrap();
let k_ver = kernel_version().unwrap(); let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) { if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( // TODO (AM)
|(_, io_error)| ProgramError::SyscallError { let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0)
.map_err(|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
}, })?;
)?;
self.data self.data
.links .links
.insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new( .insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new(
@ -92,7 +96,11 @@ impl CgroupSock {
.links .links
.insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach( .insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach(
// TODO (AM) // TODO (AM)
ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, attach_type), ProgAttachLink::new(
prog_fd.as_raw_fd(),
cgroup_fd.try_clone_to_owned()?,
attach_type,
),
))) )))
} }
} }

@ -1,7 +1,11 @@
//! Cgroup socket address programs. //! Cgroup socket address programs.
pub use aya_obj::programs::CgroupSockAddrAttachType; pub use aya_obj::programs::CgroupSockAddrAttachType;
use std::{hash::Hash, os::fd::AsRawFd, path::Path}; use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
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,
@ -64,18 +68,17 @@ impl CgroupSockAddr {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [CgroupSockAddr::detach]. /// The returned value can be used to detach, see [CgroupSockAddr::detach].
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<CgroupSockAddrLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSockAddrLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap(); let attach_type = self.data.expected_attach_type.unwrap();
let k_ver = kernel_version().unwrap(); let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) { if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0)
|(_, io_error)| ProgramError::SyscallError { .map_err(|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
}, })?;
)?;
self.data self.data
.links .links
.insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd( .insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd(
@ -93,7 +96,7 @@ impl CgroupSockAddr {
CgroupSockAddrLinkInner::ProgAttach(ProgAttachLink::new( CgroupSockAddrLinkInner::ProgAttach(ProgAttachLink::new(
// TODO (AM) // TODO (AM)
prog_fd.as_raw_fd(), prog_fd.as_raw_fd(),
cgroup_fd, cgroup_fd.try_clone_to_owned()?,
attach_type, attach_type,
)), )),
)) ))

@ -1,7 +1,11 @@
//! Cgroup socket option programs. //! Cgroup socket option programs.
pub use aya_obj::programs::CgroupSockoptAttachType; pub use aya_obj::programs::CgroupSockoptAttachType;
use std::{hash::Hash, os::fd::AsRawFd, path::Path}; use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
path::Path,
};
use crate::{ use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT, generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT,
@ -61,18 +65,18 @@ impl CgroupSockopt {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [CgroupSockopt::detach]. /// The returned value can be used to detach, see [CgroupSockopt::detach].
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<CgroupSockoptLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSockoptLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap(); let attach_type = self.data.expected_attach_type.unwrap();
let k_ver = kernel_version().unwrap(); let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) { if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( // TODO (AM)
|(_, io_error)| ProgramError::SyscallError { let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0)
.map_err(|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
}, })?;
)?;
self.data self.data
.links .links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd( .insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd(
@ -90,7 +94,11 @@ impl CgroupSockopt {
.links .links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach( .insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach(
// TODO (AM) // TODO (AM)
ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, attach_type), ProgAttachLink::new(
prog_fd.as_raw_fd(),
cgroup_fd.try_clone_to_owned()?,
attach_type,
),
))) )))
} }
} }

@ -1,5 +1,8 @@
//! Cgroup sysctl programs. //! Cgroup sysctl programs.
use std::{hash::Hash, os::fd::AsRawFd}; use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
};
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},
@ -57,18 +60,19 @@ impl CgroupSysctl {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [CgroupSysctl::detach]. /// The returned value can be used to detach, see [CgroupSysctl::detach].
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<CgroupSysctlLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<CgroupSysctlLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
let k_ver = kernel_version().unwrap(); let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) { if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, None, 0).map_err( // TODO (AM)
|(_, io_error)| ProgramError::SyscallError { let link_fd =
bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), BPF_CGROUP_SYSCTL, None, 0)
.map_err(|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
}, })?;
)?;
self.data self.data
.links .links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd( .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(
@ -86,7 +90,11 @@ impl CgroupSysctl {
.links .links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach( .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach(
// TODO (AM) // TODO (AM)
ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, BPF_CGROUP_SYSCTL), ProgAttachLink::new(
prog_fd.as_raw_fd(),
cgroup_fd.try_clone_to_owned()?,
BPF_CGROUP_SYSCTL,
),
))) )))
} }
} }

@ -1,5 +1,4 @@
//! Program links. //! Program links.
use libc::{close, dup};
use thiserror::Error; use thiserror::Error;
use std::{ use std::{
@ -208,19 +207,19 @@ pub struct ProgAttachLinkId(RawFd, RawFd, bpf_attach_type);
#[derive(Debug)] #[derive(Debug)]
pub struct ProgAttachLink { pub struct ProgAttachLink {
prog_fd: RawFd, prog_fd: RawFd,
target_fd: RawFd, target_fd: OwnedFd,
attach_type: bpf_attach_type, attach_type: bpf_attach_type,
} }
impl ProgAttachLink { impl ProgAttachLink {
pub(crate) fn new( pub(crate) fn new(
prog_fd: RawFd, prog_fd: RawFd,
target_fd: RawFd, target_fd: OwnedFd,
attach_type: bpf_attach_type, attach_type: bpf_attach_type,
) -> ProgAttachLink { ) -> ProgAttachLink {
ProgAttachLink { ProgAttachLink {
prog_fd, prog_fd,
target_fd: unsafe { dup(target_fd) }, target_fd,
attach_type, attach_type,
} }
} }
@ -230,12 +229,13 @@ impl Link for ProgAttachLink {
type Id = ProgAttachLinkId; type Id = ProgAttachLinkId;
fn id(&self) -> Self::Id { fn id(&self) -> Self::Id {
ProgAttachLinkId(self.prog_fd, self.target_fd, self.attach_type) // TODO (AM)
ProgAttachLinkId(self.prog_fd, self.target_fd.as_raw_fd(), self.attach_type)
} }
fn detach(self) -> Result<(), ProgramError> { fn detach(self) -> Result<(), ProgramError> {
let _ = bpf_prog_detach(self.prog_fd, self.target_fd, self.attach_type); // TODO (AM)
unsafe { close(self.target_fd) }; let _ = bpf_prog_detach(self.prog_fd, self.target_fd.as_raw_fd(), self.attach_type);
Ok(()) Ok(())
} }
} }

@ -1,5 +1,5 @@
//! Lirc programs. //! Lirc programs.
use std::os::fd::{AsRawFd, RawFd}; use std::os::fd::{AsFd, AsRawFd, OwnedFd, RawFd};
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2}, generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2},
@ -7,8 +7,6 @@ use crate::{
sys::{bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd}, sys::{bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd},
}; };
use libc::{close, dup};
/// A program used to decode IR into key events for a lirc device. /// A program used to decode IR into key events for a lirc device.
/// ///
/// [`LircMode2`] programs can be used to inspect infrared pulses, spaces, /// [`LircMode2`] programs can be used to inspect infrared pulses, spaces,
@ -60,9 +58,9 @@ impl LircMode2 {
/// Attaches the program to the given lirc device. /// Attaches the program to the given lirc device.
/// ///
/// The returned value can be used to detach, see [LircMode2::detach]. /// The returned value can be used to detach, see [LircMode2::detach].
pub fn attach<T: AsRawFd>(&mut self, lircdev: T) -> Result<LircLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, lircdev: T) -> Result<LircLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let lircdev_fd = lircdev.as_raw_fd(); let lircdev_fd = lircdev.as_fd();
bpf_prog_attach(prog_fd, lircdev_fd, BPF_LIRC_MODE2).map_err(|(_, io_error)| { bpf_prog_attach(prog_fd, lircdev_fd, BPF_LIRC_MODE2).map_err(|(_, io_error)| {
ProgramError::SyscallError { ProgramError::SyscallError {
@ -72,9 +70,10 @@ impl LircMode2 {
})?; })?;
// TODO (AM) // TODO (AM)
self.data self.data.links.insert(LircLink::new(
.links prog_fd.as_raw_fd(),
.insert(LircLink::new(prog_fd.as_raw_fd(), lircdev_fd)) lircdev_fd.try_clone_to_owned()?,
))
} }
/// Detaches the program. /// Detaches the program.
@ -93,8 +92,9 @@ impl LircMode2 {
} }
/// Queries the lirc device for attached programs. /// Queries the lirc device for attached programs.
pub fn query<T: AsRawFd>(target_fd: T) -> Result<Vec<LircLink>, ProgramError> { pub fn query<T: AsFd>(target_fd: T) -> Result<Vec<LircLink>, ProgramError> {
let prog_ids = query(target_fd.as_raw_fd(), BPF_LIRC_MODE2, 0, &mut None)?; let target_fd = target_fd.as_fd();
let prog_ids = query(target_fd, BPF_LIRC_MODE2, 0, &mut None)?;
let mut prog_fds = Vec::with_capacity(prog_ids.len()); let mut prog_fds = Vec::with_capacity(prog_ids.len());
@ -107,10 +107,10 @@ impl LircMode2 {
prog_fds.push(fd as RawFd); prog_fds.push(fd as RawFd);
} }
Ok(prog_fds prog_fds
.into_iter() .into_iter()
.map(|prog_fd| LircLink::new(prog_fd, target_fd.as_raw_fd())) .map(|prog_fd| Ok(LircLink::new(prog_fd, target_fd.try_clone_to_owned()?)))
.collect()) .collect()
} }
} }
@ -122,15 +122,12 @@ pub struct LircLinkId(RawFd, RawFd);
/// An LircMode2 Link /// An LircMode2 Link
pub struct LircLink { pub struct LircLink {
prog_fd: RawFd, prog_fd: RawFd,
target_fd: RawFd, target_fd: OwnedFd,
} }
impl LircLink { impl LircLink {
pub(crate) fn new(prog_fd: RawFd, target_fd: RawFd) -> LircLink { pub(crate) fn new(prog_fd: RawFd, target_fd: OwnedFd) -> LircLink {
LircLink { LircLink { prog_fd, target_fd }
prog_fd,
target_fd: unsafe { dup(target_fd) },
}
} }
/// Get ProgramInfo from this link /// Get ProgramInfo from this link
@ -149,12 +146,13 @@ impl Link for LircLink {
type Id = LircLinkId; type Id = LircLinkId;
fn id(&self) -> Self::Id { fn id(&self) -> Self::Id {
LircLinkId(self.prog_fd, self.target_fd) // TODO (AM)
LircLinkId(self.prog_fd, self.target_fd.as_raw_fd())
} }
fn detach(self) -> Result<(), ProgramError> { fn detach(self) -> Result<(), ProgramError> {
let _ = bpf_prog_detach(self.prog_fd, self.target_fd, BPF_LIRC_MODE2); // TODO (AM)
unsafe { close(self.target_fd) }; let _ = bpf_prog_detach(self.prog_fd, self.target_fd.as_raw_fd(), BPF_LIRC_MODE2);
Ok(()) Ok(())
} }
} }

@ -1,7 +1,6 @@
//! Perf attach links. //! Perf attach links.
use libc::close;
use std::os::{ use std::os::{
fd::{AsRawFd, BorrowedFd}, fd::{AsRawFd, BorrowedFd, OwnedFd},
unix::io::RawFd, unix::io::RawFd,
}; };
@ -49,7 +48,7 @@ pub struct PerfLinkId(RawFd);
/// The attachment type of PerfEvent programs. /// The attachment type of PerfEvent programs.
#[derive(Debug)] #[derive(Debug)]
pub struct PerfLink { pub struct PerfLink {
perf_fd: RawFd, perf_fd: OwnedFd,
probe_kind: Option<ProbeKind>, probe_kind: Option<ProbeKind>,
event_alias: Option<String>, event_alias: Option<String>,
} }
@ -58,12 +57,13 @@ impl Link for PerfLink {
type Id = PerfLinkId; type Id = PerfLinkId;
fn id(&self) -> Self::Id { fn id(&self) -> Self::Id {
PerfLinkId(self.perf_fd) // TODO (AM)
PerfLinkId(self.perf_fd.as_raw_fd())
} }
fn detach(mut self) -> Result<(), ProgramError> { fn detach(mut self) -> Result<(), ProgramError> {
let _ = perf_event_ioctl(self.perf_fd, PERF_EVENT_IOC_DISABLE, 0); // TODO (AM)
unsafe { close(self.perf_fd) }; let _ = perf_event_ioctl(self.perf_fd.as_raw_fd(), PERF_EVENT_IOC_DISABLE, 0);
if let Some(probe_kind) = self.probe_kind.take() { if let Some(probe_kind) = self.probe_kind.take() {
if let Some(event_alias) = self.event_alias.take() { if let Some(event_alias) = self.event_alias.take() {
@ -77,16 +77,15 @@ impl Link for PerfLink {
pub(crate) fn perf_attach( pub(crate) fn perf_attach(
prog_fd: BorrowedFd<'_>, prog_fd: BorrowedFd<'_>,
fd: RawFd, fd: OwnedFd,
) -> Result<PerfLinkInner, ProgramError> { ) -> Result<PerfLinkInner, ProgramError> {
if FEATURES.bpf_perf_link() { if FEATURES.bpf_perf_link() {
let link_fd = let link_fd = bpf_link_create(prog_fd, fd.as_raw_fd(), BPF_PERF_EVENT, None, 0).map_err(
bpf_link_create(prog_fd, fd, BPF_PERF_EVENT, None, 0).map_err(|(_, io_error)| { |(_, io_error)| ProgramError::SyscallError {
ProgramError::SyscallError {
call: "bpf_link_create".to_owned(), call: "bpf_link_create".to_owned(),
io_error, io_error,
} },
})?; )?;
Ok(PerfLinkInner::FdLink(FdLink::new(link_fd))) Ok(PerfLinkInner::FdLink(FdLink::new(link_fd)))
} else { } else {
perf_attach_either(prog_fd, fd, None, None) perf_attach_either(prog_fd, fd, None, None)
@ -95,7 +94,7 @@ pub(crate) fn perf_attach(
pub(crate) fn perf_attach_debugfs( pub(crate) fn perf_attach_debugfs(
prog_fd: BorrowedFd<'_>, prog_fd: BorrowedFd<'_>,
fd: RawFd, fd: OwnedFd,
probe_kind: ProbeKind, probe_kind: ProbeKind,
event_alias: String, event_alias: String,
) -> Result<PerfLinkInner, ProgramError> { ) -> Result<PerfLinkInner, ProgramError> {
@ -104,17 +103,19 @@ pub(crate) fn perf_attach_debugfs(
fn perf_attach_either( fn perf_attach_either(
prog_fd: BorrowedFd<'_>, prog_fd: BorrowedFd<'_>,
fd: RawFd, fd: OwnedFd,
probe_kind: Option<ProbeKind>, probe_kind: Option<ProbeKind>,
event_alias: Option<String>, event_alias: Option<String>,
) -> Result<PerfLinkInner, ProgramError> { ) -> Result<PerfLinkInner, ProgramError> {
perf_event_ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd.as_raw_fd()).map_err( // TODO (AM)
perf_event_ioctl(fd.as_raw_fd(), PERF_EVENT_IOC_SET_BPF, prog_fd.as_raw_fd()).map_err(
|(_, io_error)| ProgramError::SyscallError { |(_, io_error)| ProgramError::SyscallError {
call: "PERF_EVENT_IOC_SET_BPF".to_owned(), call: "PERF_EVENT_IOC_SET_BPF".to_owned(),
io_error, io_error,
}, },
)?; )?;
perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| { // TODO (AM)
perf_event_ioctl(fd.as_raw_fd(), PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| {
ProgramError::SyscallError { ProgramError::SyscallError {
call: "PERF_EVENT_IOC_ENABLE".to_owned(), call: "PERF_EVENT_IOC_ENABLE".to_owned(),
io_error, io_error,

@ -167,7 +167,7 @@ impl PerfEvent {
.map_err(|(_code, io_error)| ProgramError::SyscallError { .map_err(|(_code, io_error)| ProgramError::SyscallError {
call: "perf_event_open".to_owned(), call: "perf_event_open".to_owned(),
io_error, io_error,
})? as i32; })?;
let link = perf_attach(self.data.fd_or_err()?, fd)?; let link = perf_attach(self.data.fd_or_err()?, fd)?;
self.data.links.insert(PerfEventLink::new(link)) self.data.links.insert(PerfEventLink::new(link))

@ -2,6 +2,7 @@ use libc::pid_t;
use std::{ use std::{
fs::{self, OpenOptions}, fs::{self, OpenOptions},
io::{self, Write}, io::{self, Write},
os::fd::OwnedFd,
path::Path, path::Path,
process, process,
sync::atomic::{AtomicUsize, Ordering}, sync::atomic::{AtomicUsize, Ordering},
@ -86,7 +87,7 @@ fn create_as_probe(
fn_name: &str, fn_name: &str,
offset: u64, offset: u64,
pid: Option<pid_t>, pid: Option<pid_t>,
) -> Result<i32, ProgramError> { ) -> Result<OwnedFd, ProgramError> {
use ProbeKind::*; use ProbeKind::*;
let perf_ty = match kind { let perf_ty = match kind {
@ -113,7 +114,7 @@ fn create_as_probe(
call: "perf_event_open".to_owned(), call: "perf_event_open".to_owned(),
io_error, io_error,
}, },
)? as i32; )?;
Ok(fd) Ok(fd)
} }
@ -123,7 +124,7 @@ fn create_as_trace_point(
name: &str, name: &str,
offset: u64, offset: u64,
pid: Option<pid_t>, pid: Option<pid_t>,
) -> Result<(i32, String), ProgramError> { ) -> Result<(OwnedFd, String), ProgramError> {
use ProbeKind::*; use ProbeKind::*;
let tracefs = find_tracefs_path()?; let tracefs = find_tracefs_path()?;
@ -142,7 +143,7 @@ fn create_as_trace_point(
call: "perf_event_open".to_owned(), call: "perf_event_open".to_owned(),
io_error, io_error,
} }
})? as i32; })?;
Ok((fd, event_alias)) Ok((fd, event_alias))
} }

@ -1,6 +1,6 @@
//! Skmsg programs. //! Skmsg programs.
use std::os::unix::io::AsRawFd; use std::os::{fd::AsFd, unix::io::AsRawFd};
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_SK_MSG_VERDICT, bpf_prog_type::BPF_PROG_TYPE_SK_MSG}, generated::{bpf_attach_type::BPF_SK_MSG_VERDICT, bpf_prog_type::BPF_PROG_TYPE_SK_MSG},
@ -46,9 +46,10 @@ use crate::{
/// let intercept_egress: SockHash<_, u32> = bpf.map("INTERCEPT_EGRESS").unwrap().try_into()?; /// let intercept_egress: SockHash<_, u32> = bpf.map("INTERCEPT_EGRESS").unwrap().try_into()?;
/// let map_fd = intercept_egress.fd()?; /// let map_fd = intercept_egress.fd()?;
/// ///
/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// // TODO (AM): Figure out lifetimes
/// prog.load()?; /// // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
/// prog.attach(map_fd)?; /// // prog.load()?;
/// // prog.attach(map_fd)?;
/// ///
/// let mut client = TcpStream::connect("127.0.0.1:1234")?; /// let mut client = TcpStream::connect("127.0.0.1:1234")?;
/// let mut intercept_egress: SockHash<_, u32> = bpf.map_mut("INTERCEPT_EGRESS").unwrap().try_into()?; /// let mut intercept_egress: SockHash<_, u32> = bpf.map_mut("INTERCEPT_EGRESS").unwrap().try_into()?;
@ -78,9 +79,9 @@ impl SkMsg {
/// Attaches the program to the given sockmap. /// Attaches the program to the given sockmap.
/// ///
/// The returned value can be used to detach, see [SkMsg::detach]. /// The returned value can be used to detach, see [SkMsg::detach].
pub fn attach(&mut self, map: SockMapFd) -> Result<SkMsgLinkId, ProgramError> { pub fn attach(&mut self, map: SockMapFd<'_>) -> Result<SkMsgLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let map_fd = map.as_raw_fd(); let map_fd = map.as_fd();
bpf_prog_attach(prog_fd, map_fd, BPF_SK_MSG_VERDICT).map_err(|(_, io_error)| { bpf_prog_attach(prog_fd, map_fd, BPF_SK_MSG_VERDICT).map_err(|(_, io_error)| {
ProgramError::SyscallError { ProgramError::SyscallError {
@ -91,7 +92,7 @@ impl SkMsg {
self.data.links.insert(SkMsgLink::new(ProgAttachLink::new( self.data.links.insert(SkMsgLink::new(ProgAttachLink::new(
// TODO (AM) // TODO (AM)
prog_fd.as_raw_fd(), prog_fd.as_raw_fd(),
map_fd, map_fd.try_clone_to_owned()?,
BPF_SK_MSG_VERDICT, BPF_SK_MSG_VERDICT,
))) )))
} }

@ -1,6 +1,9 @@
//! Skskb programs. //! Skskb programs.
use std::{os::unix::io::AsRawFd, path::Path}; use std::{
os::{fd::AsFd, unix::io::AsRawFd},
path::Path,
};
use crate::{ use crate::{
generated::{ generated::{
@ -44,9 +47,10 @@ pub enum SkSkbKind {
/// let intercept_ingress: SockMap<_> = bpf.map("INTERCEPT_INGRESS").unwrap().try_into()?; /// let intercept_ingress: SockMap<_> = bpf.map("INTERCEPT_INGRESS").unwrap().try_into()?;
/// let map_fd = intercept_ingress.fd()?; /// let map_fd = intercept_ingress.fd()?;
/// ///
/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// // TODO (AM): figure out lifetimes
/// prog.load()?; /// // let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
/// prog.attach(map_fd)?; /// // prog.load()?;
/// // prog.attach(map_fd)?;
/// ///
/// # Ok::<(), aya::BpfError>(()) /// # Ok::<(), aya::BpfError>(())
/// ``` /// ```
@ -70,9 +74,9 @@ impl SkSkb {
/// Attaches the program to the given socket map. /// Attaches the program to the given socket map.
/// ///
/// The returned value can be used to detach, see [SkSkb::detach]. /// The returned value can be used to detach, see [SkSkb::detach].
pub fn attach(&mut self, map: SockMapFd) -> Result<SkSkbLinkId, ProgramError> { pub fn attach(&mut self, map: SockMapFd<'_>) -> Result<SkSkbLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let map_fd = map.as_raw_fd(); let map_fd = map.as_fd();
let attach_type = match self.kind { let attach_type = match self.kind {
SkSkbKind::StreamParser => BPF_SK_SKB_STREAM_PARSER, SkSkbKind::StreamParser => BPF_SK_SKB_STREAM_PARSER,
@ -87,7 +91,7 @@ impl SkSkb {
// TODO (AM) // TODO (AM)
self.data.links.insert(SkSkbLink::new(ProgAttachLink::new( self.data.links.insert(SkSkbLink::new(ProgAttachLink::new(
prog_fd.as_raw_fd(), prog_fd.as_raw_fd(),
map_fd, map_fd.try_clone_to_owned()?,
attach_type, attach_type,
))) )))
} }

@ -1,5 +1,5 @@
//! Socket option programs. //! Socket option programs.
use std::os::unix::io::AsRawFd; use std::os::{fd::AsFd, unix::io::AsRawFd};
use crate::{ use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS}, generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS},
@ -58,9 +58,9 @@ impl SockOps {
/// Attaches the program to the given cgroup. /// Attaches the program to the given cgroup.
/// ///
/// The returned value can be used to detach, see [SockOps::detach]. /// The returned value can be used to detach, see [SockOps::detach].
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<SockOpsLinkId, ProgramError> { pub fn attach<T: AsFd>(&mut self, cgroup: T) -> Result<SockOpsLinkId, ProgramError> {
let prog_fd = self.data.fd_or_err()?; let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd(); let cgroup_fd = cgroup.as_fd();
bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS).map_err(|(_, io_error)| { bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS).map_err(|(_, io_error)| {
ProgramError::SyscallError { ProgramError::SyscallError {
@ -71,7 +71,7 @@ impl SockOps {
// TODO (AM) // TODO (AM)
self.data.links.insert(SockOpsLink::new(ProgAttachLink::new( self.data.links.insert(SockOpsLink::new(ProgAttachLink::new(
prog_fd.as_raw_fd(), prog_fd.as_raw_fd(),
cgroup_fd, cgroup_fd.try_clone_to_owned()?,
BPF_CGROUP_SOCK_OPS, BPF_CGROUP_SOCK_OPS,
))) )))
} }

@ -85,7 +85,7 @@ impl TracePoint {
call: "perf_event_open".to_owned(), call: "perf_event_open".to_owned(),
io_error, io_error,
} }
})? as i32; })?;
let link = perf_attach(self.data.fd_or_err()?, fd)?; let link = perf_attach(self.data.fd_or_err()?, fd)?;
self.data.links.insert(TracePointLink::new(link)) self.data.links.insert(TracePointLink::new(link))

@ -421,13 +421,13 @@ pub(crate) fn bpf_link_update(
pub(crate) fn bpf_prog_attach( pub(crate) fn bpf_prog_attach(
prog_fd: BorrowedFd<'_>, prog_fd: BorrowedFd<'_>,
target_fd: RawFd, target_fd: BorrowedFd<'_>,
attach_type: bpf_attach_type, attach_type: bpf_attach_type,
) -> SysResult { ) -> SysResult {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
attr.__bindgen_anon_5.attach_bpf_fd = prog_fd.as_raw_fd() as u32; attr.__bindgen_anon_5.attach_bpf_fd = prog_fd.as_raw_fd() as u32;
attr.__bindgen_anon_5.target_fd = target_fd as u32; attr.__bindgen_anon_5.target_fd = target_fd.as_raw_fd() as u32;
attr.__bindgen_anon_5.attach_type = attach_type as u32; attr.__bindgen_anon_5.attach_type = attach_type as u32;
sys_bpf(bpf_cmd::BPF_PROG_ATTACH, &attr) sys_bpf(bpf_cmd::BPF_PROG_ATTACH, &attr)

@ -1,4 +1,8 @@
use std::{ffi::CString, mem}; use std::{
ffi::CString,
io, mem,
os::fd::{FromRawFd, OwnedFd, RawFd},
};
use libc::{c_int, pid_t}; use libc::{c_int, pid_t};
@ -12,6 +16,8 @@ use crate::generated::{
use super::{syscall, SysResult, Syscall}; use super::{syscall, SysResult, Syscall};
type Result = std::result::Result<OwnedFd, (libc::c_long, io::Error)>;
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub(crate) fn perf_event_open( pub(crate) fn perf_event_open(
perf_type: u32, perf_type: u32,
@ -22,7 +28,7 @@ pub(crate) fn perf_event_open(
sample_frequency: Option<u64>, sample_frequency: Option<u64>,
wakeup: bool, wakeup: bool,
flags: u32, flags: u32,
) -> SysResult { ) -> Result {
let mut attr = unsafe { mem::zeroed::<perf_event_attr>() }; let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
attr.config = config; attr.config = config;
@ -39,16 +45,19 @@ pub(crate) fn perf_event_open(
attr.__bindgen_anon_1.sample_period = sample_period; attr.__bindgen_anon_1.sample_period = sample_period;
} }
syscall(Syscall::PerfEventOpen { let fd = syscall(Syscall::PerfEventOpen {
attr, attr,
pid, pid,
cpu, cpu,
group: -1, group: -1,
flags, flags,
}) })? as RawFd;
// SAFETY: perf_event_open returns new fd
Ok(unsafe { OwnedFd::from_raw_fd(fd) })
} }
pub(crate) fn perf_event_open_bpf(cpu: c_int) -> SysResult { pub(crate) fn perf_event_open_bpf(cpu: c_int) -> Result {
perf_event_open( perf_event_open(
PERF_TYPE_SOFTWARE as u32, PERF_TYPE_SOFTWARE as u32,
PERF_COUNT_SW_BPF_OUTPUT as u64, PERF_COUNT_SW_BPF_OUTPUT as u64,
@ -67,7 +76,7 @@ pub(crate) fn perf_event_open_probe(
name: &str, name: &str,
offset: u64, offset: u64,
pid: Option<pid_t>, pid: Option<pid_t>,
) -> SysResult { ) -> Result {
let mut attr = unsafe { mem::zeroed::<perf_event_attr>() }; let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
if let Some(ret_bit) = ret_bit { if let Some(ret_bit) = ret_bit {
@ -84,16 +93,19 @@ pub(crate) fn perf_event_open_probe(
let cpu = if pid.is_some() { -1 } else { 0 }; let cpu = if pid.is_some() { -1 } else { 0 };
let pid = pid.unwrap_or(-1); let pid = pid.unwrap_or(-1);
syscall(Syscall::PerfEventOpen { let fd = syscall(Syscall::PerfEventOpen {
attr, attr,
pid, pid,
cpu, cpu,
group: -1, group: -1,
flags: PERF_FLAG_FD_CLOEXEC, flags: PERF_FLAG_FD_CLOEXEC,
}) })? as RawFd;
// SAFETY: perf_event_open returns new fd
Ok(unsafe { OwnedFd::from_raw_fd(fd) })
} }
pub(crate) fn perf_event_open_trace_point(id: u32, pid: Option<pid_t>) -> SysResult { pub(crate) fn perf_event_open_trace_point(id: u32, pid: Option<pid_t>) -> Result {
let mut attr = unsafe { mem::zeroed::<perf_event_attr>() }; let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
attr.size = mem::size_of::<perf_event_attr>() as u32; attr.size = mem::size_of::<perf_event_attr>() as u32;
@ -103,13 +115,15 @@ pub(crate) fn perf_event_open_trace_point(id: u32, pid: Option<pid_t>) -> SysRes
let cpu = if pid.is_some() { -1 } else { 0 }; let cpu = if pid.is_some() { -1 } else { 0 };
let pid = pid.unwrap_or(-1); let pid = pid.unwrap_or(-1);
syscall(Syscall::PerfEventOpen { let fd = syscall(Syscall::PerfEventOpen {
attr, attr,
pid, pid,
cpu, cpu,
group: -1, group: -1,
flags: PERF_FLAG_FD_CLOEXEC, flags: PERF_FLAG_FD_CLOEXEC,
}) })? as RawFd;
// SAFETY: perf_event_open returns new fd
Ok(unsafe { OwnedFd::from_raw_fd(fd) })
} }
pub(crate) fn perf_event_ioctl(fd: c_int, request: c_int, arg: c_int) -> SysResult { pub(crate) fn perf_event_ioctl(fd: c_int, request: c_int, arg: c_int) -> SysResult {

Loading…
Cancel
Save