aya: remove Rc<RefCell<dyn Link>> usage in BPF program links.

This is a breaking change which transfers all ownership of a link to an
eBPF program to the caller return value of the "attach" functions. This
eliminates the overhead of Rc<RefCell<dyn Link>>, as well as prevents the
links section of ProgramData from growing without bound as programs are
attached and detached.
pull/123/head
Thia Wyrod 3 years ago
parent 07a6016ebb
commit d80892cbf2
No known key found for this signature in database
GPG Key ID: 55D3AB7E5658CA0C

@ -251,7 +251,6 @@ impl<'a> BpfLoader<'a> {
let data = ProgramData {
obj,
fd: None,
links: Vec::new(),
expected_attach_type: None,
attach_btf_obj_fd: None,
attach_btf_id: None,

@ -11,3 +11,9 @@ pub use sock_map::SockMap;
pub trait SocketMap {
fn fd_or_err(&self) -> Result<RawFd, MapError>;
}
impl<'a, S: SocketMap> SocketMap for &'a S {
fn fd_or_err(&self) -> Result<RawFd, MapError> {
(*self).fd_or_err()
}
}

@ -5,12 +5,10 @@ use crate::{
bpf_attach_type::{BPF_CGROUP_INET_EGRESS, BPF_CGROUP_INET_INGRESS},
bpf_prog_type::BPF_PROG_TYPE_CGROUP_SKB,
},
programs::{load_program, LinkRef, ProgAttachLink, ProgramData, ProgramError},
programs::{load_program, FdLink, OwnedLink, ProgAttachLink, ProgramData, ProgramError},
sys::{bpf_link_create, bpf_prog_attach, kernel_version},
};
use super::FdLink;
/// A program used to inspect or filter network activity for a given cgroup.
///
/// [`CgroupSkb`] programs can be used to inspect or filter network activity
@ -78,7 +76,7 @@ impl CgroupSkb {
&mut self,
cgroup: T,
attach_type: CgroupSkbAttachType,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd();
@ -95,7 +93,7 @@ impl CgroupSkb {
io_error,
}
})? as RawFd;
Ok(self.data.link(FdLink { fd: Some(link_fd) }))
Ok(FdLink { fd: Some(link_fd) }.into())
} else {
bpf_prog_attach(prog_fd, cgroup_fd, attach_type).map_err(|(_, io_error)| {
ProgramError::SyscallError {
@ -104,9 +102,7 @@ impl CgroupSkb {
}
})?;
Ok(self
.data
.link(ProgAttachLink::new(prog_fd, cgroup_fd, attach_type)))
Ok(ProgAttachLink::new(prog_fd, cgroup_fd, attach_type).into())
}
}
}

@ -7,7 +7,7 @@ use crate::{
programs::{
load_program,
probe::{attach, ProbeKind},
LinkRef, ProgramData, ProgramError,
OwnedLink, ProgramData, ProgramError,
},
};
@ -65,7 +65,7 @@ impl KProbe {
/// If the program is a `kprobe`, it is attached to the *start* address of the target function.
/// Conversely if the program is a `kretprobe`, it is attached to the return address of the
/// target function.
pub fn attach(&mut self, fn_name: &str, offset: u64) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self, fn_name: &str, offset: u64) -> Result<OwnedLink, ProgramError> {
attach(&mut self.data, self.kind, fn_name, offset, None)
}
}

@ -2,7 +2,7 @@ use std::os::unix::prelude::{AsRawFd, RawFd};
use crate::{
generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2},
programs::{load_program, query, Link, LinkRef, ProgramData, ProgramError, ProgramInfo},
programs::{load_program, query, Link, OwnedLink, ProgramData, ProgramError, ProgramInfo},
sys::{bpf_obj_get_info_by_fd, bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id},
};
@ -60,7 +60,7 @@ impl LircMode2 {
}
/// Attaches the program to the given lirc device.
pub fn attach<T: AsRawFd>(&mut self, lircdev: T) -> Result<LinkRef, ProgramError> {
pub fn attach<T: AsRawFd>(&mut self, lircdev: T) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let lircdev_fd = lircdev.as_raw_fd();
@ -71,7 +71,7 @@ impl LircMode2 {
}
})?;
Ok(self.data.link(LircLink::new(prog_fd, lircdev_fd)))
Ok(LircLink::new(prog_fd, lircdev_fd).into())
}
/// Queries the lirc device for attached programs.

@ -6,7 +6,7 @@ use thiserror::Error;
use crate::{
generated::{bpf_attach_type::BPF_LSM_MAC, bpf_prog_type::BPF_PROG_TYPE_LSM},
obj::btf::{Btf, BtfError, BtfKind},
programs::{load_program, FdLink, LinkRef, ProgramData, ProgramError},
programs::{load_program, FdLink, OwnedLink, ProgramData, ProgramError},
sys::bpf_raw_tracepoint_open,
};
@ -84,13 +84,13 @@ impl Lsm {
}
/// Attaches the program.
pub fn attach(&mut self) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self) -> Result<OwnedLink, ProgramError> {
attach_btf_id(&mut self.data)
}
}
/// Common logic for all BPF program types that attach to a BTF id.
pub(crate) fn attach_btf_id(program_data: &mut ProgramData) -> Result<LinkRef, ProgramError> {
pub(crate) fn attach_btf_id(program_data: &mut ProgramData) -> Result<OwnedLink, ProgramError> {
let prog_fd = program_data.fd_or_err()?;
// Attaching LSM programs doesn't require providing attach name. LSM
@ -102,5 +102,5 @@ pub(crate) fn attach_btf_id(program_data: &mut ProgramData) -> Result<LinkRef, P
}
})? as RawFd;
Ok(program_data.link(FdLink { fd: Some(pfd) }))
Ok(FdLink { fd: Some(pfd) }.into())
}

@ -56,19 +56,18 @@ mod xdp;
use libc::{close, dup, ENOSPC};
use std::{
cell::RefCell,
cmp,
convert::TryFrom,
ffi::{CStr, CString},
io,
os::unix::io::{AsRawFd, RawFd},
path::Path,
rc::Rc,
};
use thiserror::Error;
pub use cgroup_skb::{CgroupSkb, CgroupSkbAttachType};
pub use kprobe::{KProbe, KProbeError};
use lirc_mode2::LircLink;
pub use lirc_mode2::LircMode2;
pub use lsm::{Lsm, LsmLoadError};
use perf_attach::*;
@ -78,11 +77,14 @@ pub use raw_trace_point::RawTracePoint;
pub use sk_msg::SkMsg;
pub use sk_skb::{SkSkb, SkSkbKind};
pub use sock_ops::SockOps;
use socket_filter::SocketFilterLink;
pub use socket_filter::{SocketFilter, SocketFilterError};
use tc::TcLink;
pub use tc::{SchedClassifier, TcAttachType, TcError};
pub use tp_btf::{BtfTracePoint, BtfTracePointError};
pub use trace_point::{TracePoint, TracePointError};
pub use uprobe::{UProbe, UProbeError};
use xdp::NlLink;
pub use xdp::{Xdp, XdpError, XdpFlags};
use crate::{
@ -286,7 +288,6 @@ impl Program {
pub(crate) struct ProgramData {
pub(crate) obj: obj::Program,
pub(crate) fd: Option<RawFd>,
pub(crate) links: Vec<Rc<RefCell<dyn Link>>>,
pub(crate) expected_attach_type: Option<bpf_attach_type>,
pub(crate) attach_btf_obj_fd: Option<u32>,
pub(crate) attach_btf_id: Option<u32>,
@ -297,12 +298,6 @@ impl ProgramData {
self.fd.ok_or(ProgramError::NotLoaded)
}
pub fn link<T: Link + 'static>(&mut self, link: T) -> LinkRef {
let link: Rc<RefCell<dyn Link>> = Rc::new(RefCell::new(link));
self.links.push(Rc::clone(&link));
LinkRef::new(link)
}
pub fn pin<P: AsRef<Path>>(&mut self, path: P) -> Result<(), ProgramError> {
let fd = self.fd_or_err()?;
let path_string =
@ -479,28 +474,140 @@ pub(crate) fn query<T: AsRawFd>(
}
/// Detach an attached program.
pub trait Link: std::fmt::Debug {
pub trait Link {
fn detach(&mut self) -> Result<(), ProgramError>;
}
/// The return type of `program.attach(...)`.
///
/// [`LinkRef`] implements the [`Link`] trait and can be used to detach a
/// [`OwnedLink`] implements the [`Link`] trait and can be used to detach a
/// program.
/// An eBPF program's lifetime is directly connected to the OwnedLink's; it must
/// be in scope for as long as one wants the program to remain attached. When
/// dropped, OwnedLink will detach the program.
#[derive(Debug)]
pub struct LinkRef {
inner: Rc<RefCell<dyn Link>>,
pub struct OwnedLink {
pub(crate) inner: OwnedLinkImpl,
}
impl Link for OwnedLink {
fn detach(&mut self) -> Result<(), ProgramError> {
self.inner.detach()
}
}
impl From<OwnedLinkImpl> for OwnedLink {
fn from(inner: OwnedLinkImpl) -> Self {
Self { inner }
}
}
impl From<FdLink> for OwnedLink {
fn from(l: FdLink) -> Self {
Self { inner: l.into() }
}
}
impl From<LircLink> for OwnedLink {
fn from(l: LircLink) -> Self {
Self { inner: l.into() }
}
}
impl From<NlLink> for OwnedLink {
fn from(l: NlLink) -> Self {
Self { inner: l.into() }
}
}
impl From<PerfLink> for OwnedLink {
fn from(l: PerfLink) -> Self {
Self { inner: l.into() }
}
}
impl From<ProgAttachLink> for OwnedLink {
fn from(l: ProgAttachLink) -> Self {
Self { inner: l.into() }
}
}
impl From<SocketFilterLink> for OwnedLink {
fn from(l: SocketFilterLink) -> Self {
Self { inner: l.into() }
}
}
impl LinkRef {
fn new(link: Rc<RefCell<dyn Link>>) -> LinkRef {
LinkRef { inner: link }
impl From<TcLink> for OwnedLink {
fn from(l: TcLink) -> Self {
Self { inner: l.into() }
}
}
impl Link for LinkRef {
#[derive(Debug)]
pub(crate) enum OwnedLinkImpl {
Fd(FdLink),
Lirc(LircLink),
Nl(NlLink),
Perf(PerfLink),
ProgAttach(ProgAttachLink),
SocketFilter(SocketFilterLink),
Tc(TcLink),
}
impl Link for OwnedLinkImpl {
fn detach(&mut self) -> Result<(), ProgramError> {
self.inner.borrow_mut().detach()
match self {
Self::Fd(link) => link.detach(),
Self::Lirc(link) => link.detach(),
Self::Nl(link) => link.detach(),
Self::Perf(link) => link.detach(),
Self::ProgAttach(link) => link.detach(),
Self::SocketFilter(link) => link.detach(),
Self::Tc(link) => link.detach(),
}
}
}
impl From<FdLink> for OwnedLinkImpl {
fn from(l: FdLink) -> Self {
Self::Fd(l)
}
}
impl From<LircLink> for OwnedLinkImpl {
fn from(l: LircLink) -> Self {
Self::Lirc(l)
}
}
impl From<NlLink> for OwnedLinkImpl {
fn from(l: NlLink) -> Self {
Self::Nl(l)
}
}
impl From<PerfLink> for OwnedLinkImpl {
fn from(l: PerfLink) -> Self {
Self::Perf(l)
}
}
impl From<ProgAttachLink> for OwnedLinkImpl {
fn from(l: ProgAttachLink) -> Self {
Self::ProgAttach(l)
}
}
impl From<SocketFilterLink> for OwnedLinkImpl {
fn from(l: SocketFilterLink) -> Self {
Self::SocketFilter(l)
}
}
impl From<TcLink> for OwnedLinkImpl {
fn from(l: TcLink) -> Self {
Self::Tc(l)
}
}
@ -527,7 +634,7 @@ impl Drop for FdLink {
}
#[derive(Debug)]
struct ProgAttachLink {
pub(crate) struct ProgAttachLink {
prog_fd: Option<RawFd>,
target_fd: Option<RawFd>,
attach_type: bpf_attach_type,

@ -7,10 +7,10 @@ use crate::{
PERF_EVENT_IOC_DISABLE, PERF_EVENT_IOC_ENABLE, PERF_EVENT_IOC_SET_BPF,
};
use super::{Link, LinkRef, ProgramData, ProgramError};
use super::{Link, OwnedLink, ProgramData, ProgramError};
#[derive(Debug)]
struct PerfLink {
pub(crate) struct PerfLink {
perf_fd: Option<RawFd>,
probe_kind: Option<ProbeKind>,
event_alias: Option<String>,
@ -41,7 +41,7 @@ impl Drop for PerfLink {
}
}
pub(crate) fn perf_attach(data: &mut ProgramData, fd: RawFd) -> Result<LinkRef, ProgramError> {
pub(crate) fn perf_attach(data: &mut ProgramData, fd: RawFd) -> Result<OwnedLink, ProgramError> {
perf_attach_either(data, fd, None, None)
}
@ -50,7 +50,7 @@ pub(crate) fn perf_attach_debugfs(
fd: RawFd,
probe_kind: ProbeKind,
event_alias: String,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
perf_attach_either(data, fd, Some(probe_kind), Some(event_alias))
}
@ -59,7 +59,7 @@ fn perf_attach_either(
fd: RawFd,
probe_kind: Option<ProbeKind>,
event_alias: Option<String>,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
let prog_fd = data.fd_or_err()?;
perf_event_ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd).map_err(|(_, io_error)| {
ProgramError::SyscallError {
@ -74,9 +74,10 @@ fn perf_attach_either(
}
})?;
Ok(data.link(PerfLink {
Ok(PerfLink {
perf_fd: Some(fd),
probe_kind,
event_alias,
}))
}
.into())
}

@ -10,7 +10,7 @@ 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,
};
use super::{load_program, perf_attach, LinkRef, ProgramData, ProgramError};
use super::{load_program, perf_attach, OwnedLink, ProgramData, ProgramError};
#[repr(u32)]
#[derive(Debug, Clone)]
@ -104,7 +104,7 @@ impl PerfEvent {
config: u64,
scope: PerfEventScope,
sample_policy: SamplePolicy,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
let (sample_period, sample_frequency) = match sample_policy {
SamplePolicy::Period(period) => (period, None),
SamplePolicy::Frequency(frequency) => (0, Some(frequency)),

@ -8,7 +8,7 @@ use std::{
use crate::{
programs::{
kprobe::KProbeError, perf_attach, perf_attach_debugfs,
trace_point::read_sys_fs_trace_point_id, uprobe::UProbeError, LinkRef, ProgramData,
trace_point::read_sys_fs_trace_point_id, uprobe::UProbeError, OwnedLink, ProgramData,
ProgramError,
},
sys::{kernel_version, perf_event_open_probe, perf_event_open_trace_point},
@ -41,7 +41,7 @@ pub(crate) fn attach(
fn_name: &str,
offset: u64,
pid: Option<pid_t>,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
// https://github.com/torvalds/linux/commit/e12f03d7031a977356e3d7b75a68c2185ff8d155
// Use debugfs to create probe
let k_ver = kernel_version().unwrap();

@ -3,7 +3,7 @@ use std::{ffi::CString, os::unix::io::RawFd};
use crate::{
generated::bpf_prog_type::BPF_PROG_TYPE_RAW_TRACEPOINT,
programs::{load_program, FdLink, LinkRef, ProgramData, ProgramError},
programs::{load_program, FdLink, OwnedLink, ProgramData, ProgramError},
sys::bpf_raw_tracepoint_open,
};
@ -46,7 +46,7 @@ impl RawTracePoint {
}
/// Attaches the program to the given tracepoint.
pub fn attach(&mut self, tp_name: &str) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self, tp_name: &str) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let name = CString::new(tp_name).unwrap();
@ -57,6 +57,6 @@ impl RawTracePoint {
}
})? as RawFd;
Ok(self.data.link(FdLink { fd: Some(pfd) }))
Ok(FdLink { fd: Some(pfd) }.into())
}
}

@ -1,7 +1,7 @@
use crate::{
generated::{bpf_attach_type::BPF_SK_MSG_VERDICT, bpf_prog_type::BPF_PROG_TYPE_SK_MSG},
maps::sock::SocketMap,
programs::{load_program, LinkRef, ProgAttachLink, ProgramData, ProgramError},
programs::{load_program, OwnedLink, ProgAttachLink, ProgramData, ProgramError},
sys::bpf_prog_attach,
};
@ -68,7 +68,7 @@ impl SkMsg {
}
/// Attaches the program to the given sockmap.
pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self, map: impl SocketMap) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let map_fd = map.fd_or_err()?;
@ -78,8 +78,6 @@ impl SkMsg {
io_error,
}
})?;
Ok(self
.data
.link(ProgAttachLink::new(prog_fd, map_fd, BPF_SK_MSG_VERDICT)))
Ok(ProgAttachLink::new(prog_fd, map_fd, BPF_SK_MSG_VERDICT).into())
}
}

@ -4,7 +4,7 @@ use crate::{
bpf_prog_type::BPF_PROG_TYPE_SK_SKB,
},
maps::sock::SocketMap,
programs::{load_program, LinkRef, ProgAttachLink, ProgramData, ProgramError},
programs::{load_program, OwnedLink, ProgAttachLink, ProgramData, ProgramError},
sys::bpf_prog_attach,
};
@ -59,7 +59,7 @@ impl SkSkb {
}
/// Attaches the program to the given socket map.
pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self, map: impl SocketMap) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let map_fd = map.fd_or_err()?;
@ -73,8 +73,6 @@ impl SkSkb {
io_error,
}
})?;
Ok(self
.data
.link(ProgAttachLink::new(prog_fd, map_fd, attach_type)))
Ok(ProgAttachLink::new(prog_fd, map_fd, attach_type).into())
}
}

@ -2,7 +2,7 @@ use std::os::unix::io::AsRawFd;
use crate::{
generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS},
programs::{load_program, LinkRef, ProgAttachLink, ProgramData, ProgramError},
programs::{load_program, OwnedLink, ProgAttachLink, ProgramData, ProgramError},
sys::bpf_prog_attach,
};
@ -55,7 +55,7 @@ impl SockOps {
}
/// Attaches the program to the given cgroup.
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<LinkRef, ProgramError> {
pub fn attach<T: AsRawFd>(&mut self, cgroup: T) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let cgroup_fd = cgroup.as_raw_fd();
@ -65,8 +65,6 @@ impl SockOps {
io_error,
}
})?;
Ok(self
.data
.link(ProgAttachLink::new(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS)))
Ok(ProgAttachLink::new(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS).into())
}
}

@ -7,7 +7,7 @@ use thiserror::Error;
use crate::{
generated::{bpf_prog_type::BPF_PROG_TYPE_SOCKET_FILTER, SO_ATTACH_BPF, SO_DETACH_BPF},
programs::{load_program, Link, LinkRef, ProgramData, ProgramError},
programs::{load_program, Link, OwnedLink, ProgramData, ProgramError},
};
/// The type returned when attaching a [`SocketFilter`] fails.
@ -71,7 +71,7 @@ impl SocketFilter {
}
/// Attaches the filter on the given socket.
pub fn attach<T: AsRawFd>(&mut self, socket: T) -> Result<LinkRef, ProgramError> {
pub fn attach<T: AsRawFd>(&mut self, socket: T) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let socket = socket.as_raw_fd();
@ -91,15 +91,16 @@ impl SocketFilter {
.into());
}
Ok(self.data.link(SocketFilterLink {
Ok(SocketFilterLink {
socket,
prog_fd: Some(prog_fd),
}))
}
.into())
}
}
#[derive(Debug)]
struct SocketFilterLink {
pub(crate) struct SocketFilterLink {
socket: RawFd,
prog_fd: Option<RawFd>,
}

@ -11,7 +11,7 @@ use crate::{
generated::{
bpf_prog_type::BPF_PROG_TYPE_SCHED_CLS, TC_H_CLSACT, TC_H_MIN_EGRESS, TC_H_MIN_INGRESS,
},
programs::{load_program, Link, LinkRef, ProgramData, ProgramError},
programs::{load_program, Link, OwnedLink, ProgramData, ProgramError},
sys::{
netlink_find_filter_with_name, netlink_qdisc_add_clsact, netlink_qdisc_attach,
netlink_qdisc_detach,
@ -88,7 +88,7 @@ pub enum TcError {
}
#[derive(Debug)]
struct TcLink {
pub(crate) struct TcLink {
if_index: i32,
attach_type: TcAttachType,
prog_fd: Option<RawFd>,
@ -125,7 +125,7 @@ impl SchedClassifier {
&mut self,
interface: &str,
attach_type: TcAttachType,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let if_index = ifindex_from_ifname(interface)
.map_err(|io_error| TcError::NetlinkError { io_error })?;
@ -133,12 +133,13 @@ impl SchedClassifier {
unsafe { netlink_qdisc_attach(if_index as i32, &attach_type, prog_fd, &self.name) }
.map_err(|io_error| TcError::NetlinkError { io_error })?;
Ok(self.data.link(TcLink {
Ok(TcLink {
if_index: if_index as i32,
attach_type,
prog_fd: Some(prog_fd),
priority,
}))
}
.into())
}
}

@ -6,7 +6,7 @@ use thiserror::Error;
use crate::{
generated::{bpf_attach_type::BPF_TRACE_RAW_TP, bpf_prog_type::BPF_PROG_TYPE_TRACING},
obj::btf::{Btf, BtfError, BtfKind},
programs::{load_program, FdLink, LinkRef, ProgramData, ProgramError},
programs::{load_program, FdLink, OwnedLink, ProgramData, ProgramError},
sys::bpf_raw_tracepoint_open,
};
@ -82,7 +82,7 @@ impl BtfTracePoint {
}
/// Attaches the program.
pub fn attach(&mut self) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
// BTF programs specify their attach name at program load time
@ -93,6 +93,6 @@ impl BtfTracePoint {
}
})? as RawFd;
Ok(self.data.link(FdLink { fd: Some(pfd) }))
Ok(FdLink { fd: Some(pfd) }.into())
}
}

@ -3,7 +3,7 @@ use thiserror::Error;
use crate::{generated::bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT, sys::perf_event_open_trace_point};
use super::{load_program, perf_attach, LinkRef, ProgramData, ProgramError};
use super::{load_program, perf_attach, OwnedLink, ProgramData, ProgramError};
/// The type returned when attaching a [`TracePoint`] fails.
#[derive(Debug, Error)]
@ -67,7 +67,7 @@ impl TracePoint {
///
/// For a list of the available event categories and names, see
/// `/sys/kernel/debug/tracing/events`.
pub fn attach(&mut self, category: &str, name: &str) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self, category: &str, name: &str) -> Result<OwnedLink, ProgramError> {
let id = read_sys_fs_trace_point_id(category, name)?;
let fd = perf_event_open_trace_point(id, None).map_err(|(_code, io_error)| {
ProgramError::SyscallError {

@ -18,7 +18,7 @@ use crate::{
programs::{
load_program,
probe::{attach, ProbeKind},
LinkRef, ProgramData, ProgramError,
OwnedLink, ProgramData, ProgramError,
},
};
@ -78,7 +78,7 @@ impl UProbe {
offset: u64,
target: T,
pid: Option<pid_t>,
) -> Result<LinkRef, ProgramError> {
) -> Result<OwnedLink, ProgramError> {
let target = target.as_ref();
let target_str = &*target.as_os_str().to_string_lossy();

@ -8,7 +8,7 @@ use crate::{
bpf_attach_type::BPF_XDP, bpf_prog_type::BPF_PROG_TYPE_XDP, XDP_FLAGS_DRV_MODE,
XDP_FLAGS_HW_MODE, XDP_FLAGS_REPLACE, XDP_FLAGS_SKB_MODE, XDP_FLAGS_UPDATE_IF_NOEXIST,
},
programs::{load_program, FdLink, Link, LinkRef, ProgramData, ProgramError},
programs::{load_program, FdLink, Link, OwnedLink, ProgramData, ProgramError},
sys::{bpf_link_create, kernel_version, netlink_set_xdp_fd},
};
@ -86,7 +86,7 @@ impl Xdp {
/// kernels `>= 5.9.0`, and instead
/// [`XdpError::NetlinkError`] is returned for older
/// kernels.
pub fn attach(&mut self, interface: &str, flags: XdpFlags) -> Result<LinkRef, ProgramError> {
pub fn attach(&mut self, interface: &str, flags: XdpFlags) -> Result<OwnedLink, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let c_interface = CString::new(interface).unwrap();
@ -105,24 +105,23 @@ impl Xdp {
io_error,
},
)? as RawFd;
Ok(self
.data
.link(XdpLink::FdLink(FdLink { fd: Some(link_fd) })))
Ok(FdLink { fd: Some(link_fd) }.into())
} else {
unsafe { netlink_set_xdp_fd(if_index, prog_fd, None, flags.bits) }
.map_err(|io_error| XdpError::NetlinkError { io_error })?;
Ok(self.data.link(XdpLink::NlLink(NlLink {
Ok(NlLink {
if_index,
prog_fd: Some(prog_fd),
flags,
})))
}
.into())
}
}
}
#[derive(Debug)]
struct NlLink {
pub(crate) struct NlLink {
if_index: i32,
prog_fd: Option<RawFd>,
flags: XdpFlags,
@ -150,18 +149,3 @@ impl Drop for NlLink {
let _ = self.detach();
}
}
#[derive(Debug)]
enum XdpLink {
FdLink(FdLink),
NlLink(NlLink),
}
impl Link for XdpLink {
fn detach(&mut self) -> Result<(), ProgramError> {
match self {
XdpLink::FdLink(link) => link.detach(),
XdpLink::NlLink(link) => link.detach(),
}
}
}

Loading…
Cancel
Save