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 map_fd = intercept_egress.fd()?;
//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
//! prog.load()?;
//! prog.attach(map_fd)?;
//! // TODO (AM) figure out lifetimes
//! // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
//! // prog.load()?;
//! // prog.attach(map_fd)?;
//!
//! # Ok::<(), aya::BpfError>(())
//! ```

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

@ -5,14 +5,23 @@ mod sock_map;
pub use sock_hash::SockHash;
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.
#[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 {
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 map_fd = intercept_egress.fd()?;
///
/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
/// prog.load()?;
/// prog.attach(map_fd)?;
/// // TODO (AM) : figure out lifetimes
/// // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
/// // prog.load()?;
/// // prog.attach(map_fd)?;
///
/// let mut client = TcpStream::connect("127.0.0.1:1234")?;
/// 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
/// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb).
pub fn fd(&self) -> Result<SockMapFd, MapError> {
// TODO (AM)
Ok(SockMapFd(self.inner.borrow().fd_or_err()?.as_raw_fd()))
pub fn fd(&self) -> Result<SockMapFd<'_>, MapError> {
Ok(SockMapFd(self.inner.borrow().fd_or_err()?))
}
}

@ -33,9 +33,10 @@ use crate::{
/// let intercept_ingress = SockMap::try_from(bpf.map("INTERCEPT_INGRESS").unwrap())?;
/// let map_fd = intercept_ingress.fd()?;
///
/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
/// prog.load()?;
/// prog.attach(map_fd)?;
/// // TODO (AM): figure out lifetimes
/// // let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?;
/// // prog.load()?;
/// // prog.attach(map_fd)?;
///
/// # 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
/// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb).
pub fn fd(&self) -> Result<SockMapFd, MapError> {
// TODO (AM)
Ok(SockMapFd(self.inner.borrow().fd_or_err()?.as_raw_fd()))
pub fn fd(&self) -> Result<SockMapFd<'_>, MapError> {
Ok(SockMapFd(self.inner.borrow().fd_or_err()?))
}
}

@ -1,5 +1,5 @@
//! Cgroup device programs.
use std::os::fd::AsRawFd;
use std::os::{fd::AsFd, unix::prelude::AsRawFd};
use crate::{
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.
///
/// 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 cgroup_fd = cgroup.as_raw_fd();
let cgroup_fd = cgroup.as_fd();
let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, None, 0).map_err(
|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(),
io_error,
},
)?;
// TODO (AM)
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(),
io_error,
})?;
self.data
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd(
@ -86,7 +87,11 @@ impl CgroupDevice {
.links
.insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach(
// 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.
use std::{hash::Hash, os::fd::AsRawFd, path::Path};
use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
path::Path,
};
use crate::{
generated::{
@ -80,13 +84,13 @@ impl CgroupSkb {
/// Attaches the program to the given cgroup.
///
/// The returned value can be used to detach, see [CgroupSkb::detach].
pub fn attach<T: AsRawFd>(
pub fn attach<T: AsFd>(
&mut self,
cgroup: T,
attach_type: CgroupSkbAttachType,
) -> Result<CgroupSkbLinkId, ProgramError> {
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 {
CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS,
@ -94,12 +98,12 @@ impl CgroupSkb {
};
let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err(
|(_, io_error)| ProgramError::SyscallError {
// TODO (AM)
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(),
io_error,
},
)?;
})?;
self.data
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new(
@ -117,7 +121,11 @@ impl CgroupSkb {
.links
.insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach(
// 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.
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::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK,
@ -63,18 +67,18 @@ impl CgroupSock {
/// Attaches the program to the given cgroup.
///
/// 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 cgroup_fd = cgroup.as_raw_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap();
let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err(
|(_, io_error)| ProgramError::SyscallError {
// TODO (AM)
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(),
io_error,
},
)?;
})?;
self.data
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new(
@ -92,7 +96,11 @@ impl CgroupSock {
.links
.insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach(
// 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.
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::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
@ -64,18 +68,17 @@ impl CgroupSockAddr {
/// Attaches the program to the given cgroup.
///
/// 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 cgroup_fd = cgroup.as_raw_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap();
let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err(
|(_, 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(),
io_error,
},
)?;
})?;
self.data
.links
.insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd(
@ -93,7 +96,7 @@ impl CgroupSockAddr {
CgroupSockAddrLinkInner::ProgAttach(ProgAttachLink::new(
// TODO (AM)
prog_fd.as_raw_fd(),
cgroup_fd,
cgroup_fd.try_clone_to_owned()?,
attach_type,
)),
))

@ -1,7 +1,11 @@
//! Cgroup socket option programs.
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::{
generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT,
@ -61,18 +65,18 @@ impl CgroupSockopt {
/// Attaches the program to the given cgroup.
///
/// 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 cgroup_fd = cgroup.as_raw_fd();
let cgroup_fd = cgroup.as_fd();
let attach_type = self.data.expected_attach_type.unwrap();
let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err(
|(_, io_error)| ProgramError::SyscallError {
// TODO (AM)
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(),
io_error,
},
)?;
})?;
self.data
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd(
@ -90,7 +94,11 @@ impl CgroupSockopt {
.links
.insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach(
// 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.
use std::{hash::Hash, os::fd::AsRawFd};
use std::{
hash::Hash,
os::fd::{AsFd, AsRawFd},
};
use crate::{
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.
///
/// 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 cgroup_fd = cgroup.as_raw_fd();
let cgroup_fd = cgroup.as_fd();
let k_ver = kernel_version().unwrap();
if k_ver >= (5, 7, 0) {
let link_fd = bpf_link_create(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, None, 0).map_err(
|(_, io_error)| ProgramError::SyscallError {
call: "bpf_link_create".to_owned(),
io_error,
},
)?;
// TODO (AM)
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(),
io_error,
})?;
self.data
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd(
@ -86,7 +90,11 @@ impl CgroupSysctl {
.links
.insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach(
// 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.
use libc::{close, dup};
use thiserror::Error;
use std::{
@ -208,19 +207,19 @@ pub struct ProgAttachLinkId(RawFd, RawFd, bpf_attach_type);
#[derive(Debug)]
pub struct ProgAttachLink {
prog_fd: RawFd,
target_fd: RawFd,
target_fd: OwnedFd,
attach_type: bpf_attach_type,
}
impl ProgAttachLink {
pub(crate) fn new(
prog_fd: RawFd,
target_fd: RawFd,
target_fd: OwnedFd,
attach_type: bpf_attach_type,
) -> ProgAttachLink {
ProgAttachLink {
prog_fd,
target_fd: unsafe { dup(target_fd) },
target_fd,
attach_type,
}
}
@ -230,12 +229,13 @@ impl Link for ProgAttachLink {
type Id = ProgAttachLinkId;
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> {
let _ = bpf_prog_detach(self.prog_fd, self.target_fd, self.attach_type);
unsafe { close(self.target_fd) };
// TODO (AM)
let _ = bpf_prog_detach(self.prog_fd, self.target_fd.as_raw_fd(), self.attach_type);
Ok(())
}
}

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

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

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

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

@ -1,6 +1,6 @@
//! Skmsg programs.
use std::os::unix::io::AsRawFd;
use std::os::{fd::AsFd, unix::io::AsRawFd};
use crate::{
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 map_fd = intercept_egress.fd()?;
///
/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
/// prog.load()?;
/// prog.attach(map_fd)?;
/// // TODO (AM): Figure out lifetimes
/// // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?;
/// // prog.load()?;
/// // prog.attach(map_fd)?;
///
/// let mut client = TcpStream::connect("127.0.0.1:1234")?;
/// 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.
///
/// 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 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)| {
ProgramError::SyscallError {
@ -91,7 +92,7 @@ impl SkMsg {
self.data.links.insert(SkMsgLink::new(ProgAttachLink::new(
// TODO (AM)
prog_fd.as_raw_fd(),
map_fd,
map_fd.try_clone_to_owned()?,
BPF_SK_MSG_VERDICT,
)))
}

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

@ -1,5 +1,5 @@
//! Socket option programs.
use std::os::unix::io::AsRawFd;
use std::os::{fd::AsFd, unix::io::AsRawFd};
use crate::{
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.
///
/// 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 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)| {
ProgramError::SyscallError {
@ -71,7 +71,7 @@ impl SockOps {
// TODO (AM)
self.data.links.insert(SockOpsLink::new(ProgAttachLink::new(
prog_fd.as_raw_fd(),
cgroup_fd,
cgroup_fd.try_clone_to_owned()?,
BPF_CGROUP_SOCK_OPS,
)))
}

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

@ -421,13 +421,13 @@ pub(crate) fn bpf_link_update(
pub(crate) fn bpf_prog_attach(
prog_fd: BorrowedFd<'_>,
target_fd: RawFd,
target_fd: BorrowedFd<'_>,
attach_type: bpf_attach_type,
) -> SysResult {
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.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;
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};
@ -12,6 +16,8 @@ use crate::generated::{
use super::{syscall, SysResult, Syscall};
type Result = std::result::Result<OwnedFd, (libc::c_long, io::Error)>;
#[allow(clippy::too_many_arguments)]
pub(crate) fn perf_event_open(
perf_type: u32,
@ -22,7 +28,7 @@ pub(crate) fn perf_event_open(
sample_frequency: Option<u64>,
wakeup: bool,
flags: u32,
) -> SysResult {
) -> Result {
let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
attr.config = config;
@ -39,16 +45,19 @@ pub(crate) fn perf_event_open(
attr.__bindgen_anon_1.sample_period = sample_period;
}
syscall(Syscall::PerfEventOpen {
let fd = syscall(Syscall::PerfEventOpen {
attr,
pid,
cpu,
group: -1,
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_TYPE_SOFTWARE as u32,
PERF_COUNT_SW_BPF_OUTPUT as u64,
@ -67,7 +76,7 @@ pub(crate) fn perf_event_open_probe(
name: &str,
offset: u64,
pid: Option<pid_t>,
) -> SysResult {
) -> Result {
let mut attr = unsafe { mem::zeroed::<perf_event_attr>() };
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 pid = pid.unwrap_or(-1);
syscall(Syscall::PerfEventOpen {
let fd = syscall(Syscall::PerfEventOpen {
attr,
pid,
cpu,
group: -1,
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>() };
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 pid = pid.unwrap_or(-1);
syscall(Syscall::PerfEventOpen {
let fd = syscall(Syscall::PerfEventOpen {
attr,
pid,
cpu,
group: -1,
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 {

@ -14,8 +14,8 @@ macro_rules! read_str_bytes {
($fun:ident, $ptr:expr, $len:expr $(,)?) => {
let r = unsafe {
let Some(ptr) = RESULT.get_ptr_mut(0) else {
return;
};
return;
};
&mut *ptr
};

Loading…
Cancel
Save