SQUASH: respond to review comments

Signed-off-by: astoycos <astoycos@gmail.com>
reviewable/pr921/r7
astoycos 2 months ago committed by Andre Fredette
parent 9d3af47152
commit 613bbdba62

@ -98,7 +98,6 @@ tokio = { version = "1.24.0", default-features = false }
which = { version = "6.0.0", default-features = false } which = { version = "6.0.0", default-features = false }
xdpilone = { version = "1.0.5", default-features = false } xdpilone = { version = "1.0.5", default-features = false }
xtask = { path = "xtask", default-features = false } xtask = { path = "xtask", default-features = false }
chrono = { version = "0.4" }
[profile.dev] [profile.dev]
panic = "abort" panic = "abort"

@ -77,7 +77,6 @@ impl CgroupDevice {
BPF_CGROUP_DEVICE, BPF_CGROUP_DEVICE,
None, None,
mode.into(), mode.into(),
Some(0),
None, None,
None, None,
) )

@ -105,7 +105,6 @@ impl CgroupSkb {
attach_type, attach_type,
None, None,
mode.into(), mode.into(),
Some(0),
None, None,
None, None,
) )

@ -83,7 +83,6 @@ impl CgroupSock {
attach_type, attach_type,
None, None,
mode.into(), mode.into(),
Some(0),
None, None,
None, None,
) )

@ -84,7 +84,6 @@ impl CgroupSockAddr {
attach_type, attach_type,
None, None,
mode.into(), mode.into(),
Some(0),
None, None,
None, None,
) )

@ -81,7 +81,6 @@ impl CgroupSockopt {
attach_type, attach_type,
None, None,
mode.into(), mode.into(),
Some(0),
None, None,
None, None,
) )

@ -76,7 +76,6 @@ impl CgroupSysctl {
BPF_CGROUP_SYSCTL, BPF_CGROUP_SYSCTL,
None, None,
mode.into(), mode.into(),
Some(0),
None, None,
None, None,
) )

@ -105,7 +105,6 @@ impl Extension {
0, 0,
None, None,
None, None,
None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",
@ -145,7 +144,6 @@ impl Extension {
0, 0,
None, None,
None, None,
None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",

@ -15,7 +15,7 @@ use crate::{
BPF_F_ID, BPF_F_LINK, BPF_F_REPLACE, BPF_F_ID, BPF_F_LINK, BPF_F_REPLACE,
}, },
pin::PinError, pin::PinError,
programs::{MprogLink, MprogProgram, ProgramError, ProgramFd, ProgramId}, programs::{MultiProgLink, MultiProgProgram, ProgramError, ProgramFd, ProgramId},
sys::{bpf_get_object, bpf_pin_object, bpf_prog_attach, bpf_prog_detach, SyscallError}, sys::{bpf_get_object, bpf_pin_object, bpf_prog_attach, bpf_prog_detach, SyscallError},
}; };
@ -409,6 +409,12 @@ impl LinkId {
} }
} }
#[derive(Debug)]
pub(crate) enum LinkRef {
Id(u32),
Fd(RawFd),
}
bitflags::bitflags! { bitflags::bitflags! {
/// Flags which are use to build a set of MprogOptions. /// Flags which are use to build a set of MprogOptions.
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
@ -426,7 +432,7 @@ bitflags::bitflags! {
/// ///
/// # Minimum kernel version /// # Minimum kernel version
/// ///
/// The minimum kernel version required to use this feature is 6.6. /// The minimum kernel version required to use this feature is 6.6.0.
/// ///
/// # Example /// # Example
/// ///
@ -443,8 +449,7 @@ bitflags::bitflags! {
/// ``` /// ```
#[derive(Debug)] #[derive(Debug)]
pub struct LinkOrder { pub struct LinkOrder {
pub(crate) id: Option<u32>, pub(crate) link_ref: LinkRef,
pub(crate) fd: Option<RawFd>,
pub(crate) expected_revision: Option<u64>, pub(crate) expected_revision: Option<u64>,
pub(crate) flags: MprogFlags, pub(crate) flags: MprogFlags,
} }
@ -453,8 +458,7 @@ pub struct LinkOrder {
impl Default for LinkOrder { impl Default for LinkOrder {
fn default() -> Self { fn default() -> Self {
Self { Self {
id: Some(0), link_ref: LinkRef::Fd(0),
fd: None,
flags: MprogFlags::AFTER, flags: MprogFlags::AFTER,
expected_revision: None, expected_revision: None,
} }
@ -465,8 +469,7 @@ impl LinkOrder {
/// Ensure the link is created before all other links at a given attachment point. /// Ensure the link is created before all other links at a given attachment point.
pub fn first() -> Self { pub fn first() -> Self {
Self { Self {
id: Some(0), link_ref: LinkRef::Id(0),
fd: None,
flags: MprogFlags::BEFORE, flags: MprogFlags::BEFORE,
expected_revision: None, expected_revision: None,
} }
@ -475,28 +478,25 @@ impl LinkOrder {
/// Ensure the link is created after all other links for a given attachment point. /// Ensure the link is created after all other links for a given attachment point.
pub fn last() -> Self { pub fn last() -> Self {
Self { Self {
id: Some(0), link_ref: LinkRef::Id(0),
fd: None,
flags: MprogFlags::AFTER, flags: MprogFlags::AFTER,
expected_revision: None, expected_revision: None,
} }
} }
/// Ensure the link is created before the specified aya-owned link for a given attachment point. /// Ensure the link is created before the specified aya-owned link for a given attachment point.
pub fn before_link<L: MprogLink>(link: &L) -> Result<Self, LinkError> { pub fn before_link<L: MultiProgLink>(link: &L) -> Result<Self, LinkError> {
Ok(Self { Ok(Self {
id: None, link_ref: LinkRef::Fd(link.fd()?.as_raw_fd()),
fd: Some(link.fd()?.as_raw_fd()),
flags: MprogFlags::BEFORE | MprogFlags::LINK, flags: MprogFlags::BEFORE | MprogFlags::LINK,
expected_revision: None, expected_revision: None,
}) })
} }
/// Ensure the link is created after the specified aya-owned link for a given attachment point. /// Ensure the link is created after the specified aya-owned link for a given attachment point.
pub fn after_link<L: MprogLink>(link: &L) -> Result<Self, LinkError> { pub fn after_link<L: MultiProgLink>(link: &L) -> Result<Self, LinkError> {
Ok(Self { Ok(Self {
id: None, link_ref: LinkRef::Fd(link.fd()?.as_raw_fd()),
fd: Some(link.fd()?.as_raw_fd()),
flags: MprogFlags::AFTER | MprogFlags::LINK, flags: MprogFlags::AFTER | MprogFlags::LINK,
expected_revision: None, expected_revision: None,
}) })
@ -505,8 +505,7 @@ impl LinkOrder {
/// Ensure the link is created before a link specified by its kernel id for a given attachment point. /// Ensure the link is created before a link specified by its kernel id for a given attachment point.
pub fn before_link_id(id: LinkId) -> Result<Self, LinkError> { pub fn before_link_id(id: LinkId) -> Result<Self, LinkError> {
Ok(Self { Ok(Self {
id: Some(id.0), link_ref: LinkRef::Id(id.0),
fd: None,
flags: MprogFlags::BEFORE | MprogFlags::LINK | MprogFlags::ID, flags: MprogFlags::BEFORE | MprogFlags::LINK | MprogFlags::ID,
expected_revision: None, expected_revision: None,
}) })
@ -515,28 +514,25 @@ impl LinkOrder {
/// Ensure the link is created after a link specified by its kernel id for a given attachment point. /// Ensure the link is created after a link specified by its kernel id for a given attachment point.
pub fn after_link_id(id: LinkId) -> Result<Self, LinkError> { pub fn after_link_id(id: LinkId) -> Result<Self, LinkError> {
Ok(Self { Ok(Self {
id: Some(id.0), link_ref: LinkRef::Id(id.0),
fd: None,
flags: MprogFlags::AFTER | MprogFlags::LINK | MprogFlags::ID, flags: MprogFlags::AFTER | MprogFlags::LINK | MprogFlags::ID,
expected_revision: None, expected_revision: None,
}) })
} }
/// Ensure the link is created before the specified aya-owned program for a given attachment point. /// Ensure the link is created before the specified aya-owned program for a given attachment point.
pub fn before_program<P: MprogProgram>(program: &P) -> Result<Self, ProgramError> { pub fn before_program<P: MultiProgProgram>(program: &P) -> Result<Self, ProgramError> {
Ok(Self { Ok(Self {
id: None, link_ref: LinkRef::Fd(program.fd()?.as_raw_fd()),
fd: Some(program.fd()?.as_raw_fd()),
flags: MprogFlags::BEFORE, flags: MprogFlags::BEFORE,
expected_revision: None, expected_revision: None,
}) })
} }
/// Ensure the link is created after the specified aya-owned program for a given attachment point. /// Ensure the link is created after the specified aya-owned program for a given attachment point.
pub fn after_program<P: MprogProgram>(program: &P) -> Result<Self, ProgramError> { pub fn after_program<P: MultiProgProgram>(program: &P) -> Result<Self, ProgramError> {
Ok(Self { Ok(Self {
id: None, link_ref: LinkRef::Fd(program.fd()?.as_raw_fd()),
fd: Some(program.fd()?.as_raw_fd()),
flags: MprogFlags::AFTER, flags: MprogFlags::AFTER,
expected_revision: None, expected_revision: None,
}) })
@ -545,8 +541,7 @@ impl LinkOrder {
/// Ensure the link is created before a program specified by its kernel id for a given attachment point. /// Ensure the link is created before a program specified by its kernel id for a given attachment point.
pub fn before_program_id(id: ProgramId) -> Self { pub fn before_program_id(id: ProgramId) -> Self {
Self { Self {
id: Some(id.0), link_ref: LinkRef::Id(id.0),
fd: None,
flags: MprogFlags::BEFORE | MprogFlags::ID, flags: MprogFlags::BEFORE | MprogFlags::ID,
expected_revision: None, expected_revision: None,
} }
@ -555,8 +550,7 @@ impl LinkOrder {
/// Ensure the link is created after a program specified by its kernel id for a given attachment point. /// Ensure the link is created after a program specified by its kernel id for a given attachment point.
pub fn after_program_id(id: ProgramId) -> Self { pub fn after_program_id(id: ProgramId) -> Self {
Self { Self {
id: Some(id.0), link_ref: LinkRef::Id(id.0),
fd: None,
flags: MprogFlags::AFTER | MprogFlags::ID, flags: MprogFlags::AFTER | MprogFlags::ID,
expected_revision: None, expected_revision: None,
} }

@ -816,17 +816,17 @@ impl_fd!(
/// ///
/// # Minimum kernel version /// # Minimum kernel version
/// ///
/// The minimum kernel version required to use this feature is 6.6. /// The minimum kernel version required to use this feature is 6.6.0.
pub trait MprogProgram { pub trait MultiProgProgram {
/// Returns a borrowed reference to the file descriptor of a given /// Returns a borrowed reference to the file descriptor of a given
/// [`Program`] which has support for the kernel's generic multi-prog API. /// [`Program`] which has support for the kernel's generic multi-prog API.
fn fd(&self) -> Result<BorrowedFd<'_>, ProgramError>; fn fd(&self) -> Result<BorrowedFd<'_>, ProgramError>;
} }
macro_rules! impl_mprog_fd { macro_rules! impl_multiprog_fd {
($($struct_name:ident),+ $(,)?) => { ($($struct_name:ident),+ $(,)?) => {
$( $(
impl MprogProgram for $struct_name { impl MultiProgProgram for $struct_name {
/// Returns the a borrowed reference file descriptor of this Program. /// Returns the a borrowed reference file descriptor of this Program.
fn fd(&self) -> Result<BorrowedFd<'_>, ProgramError> { fn fd(&self) -> Result<BorrowedFd<'_>, ProgramError> {
Ok(self.fd()?.as_fd()) Ok(self.fd()?.as_fd())
@ -836,24 +836,23 @@ macro_rules! impl_mprog_fd {
} }
} }
impl_mprog_fd!(SchedClassifier,); impl_multiprog_fd!(SchedClassifier);
/// Defines which [`Link`]s support the kernel's /// Defines the [Link] types which support the kernel's [generic multi-prog API](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=053c8e1f235dc3f69d13375b32f4209228e1cb96).
/// generic multi-prog API.
/// ///
/// # Minimum kernel version /// # Minimum kernel version
/// ///
/// The minimum kernel version required to use this feature is 6.6. /// The minimum kernel version required to use this feature is 6.6.0.
pub trait MprogLink { pub trait MultiProgLink {
/// Returns a borrowed reference to the file descriptor of a given /// Returns a borrowed reference to the file descriptor of a given
/// [`Link`] which has support for the kernel's generic multi-prog API. /// [`Link`] which has support for the kernel's generic multi-prog API.
fn fd(&self) -> Result<BorrowedFd<'_>, LinkError>; fn fd(&self) -> Result<BorrowedFd<'_>, LinkError>;
} }
macro_rules! impl_mproglink_fd { macro_rules! impl_multiproglink_fd {
($($struct_name:ident),+ $(,)?) => { ($($struct_name:ident),+ $(,)?) => {
$( $(
impl MprogLink for $struct_name { impl MultiProgLink for $struct_name {
/// Returns the a borrowed reference file descriptor of this Program. /// Returns the a borrowed reference file descriptor of this Program.
fn fd(&self) -> Result<BorrowedFd<'_>, LinkError> { fn fd(&self) -> Result<BorrowedFd<'_>, LinkError> {
let link: &FdLink = self.try_into()?; let link: &FdLink = self.try_into()?;
@ -864,7 +863,7 @@ macro_rules! impl_mproglink_fd {
} }
} }
impl_mproglink_fd!(SchedClassifierLink); impl_multiproglink_fd!(SchedClassifierLink);
macro_rules! impl_program_pin{ macro_rules! impl_program_pin{
($($struct_name:ident),+ $(,)?) => { ($($struct_name:ident),+ $(,)?) => {

@ -83,7 +83,6 @@ pub(crate) fn perf_attach(
0, 0,
None, None,
None, None,
None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",

@ -73,7 +73,6 @@ impl SkLookup {
0, 0,
None, None,
None, None,
None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",

@ -98,11 +98,11 @@ pub enum TcError {
#[error("the clsact qdisc is already attached")] #[error("the clsact qdisc is already attached")]
AlreadyAttached, AlreadyAttached,
/// tcx links can only be attached to ingress or egress /// tcx links can only be attached to ingress or egress
#[error("tcx links can only be attached to ingress or egress")] #[error("tcx links can only be attached to ingress or egress, custom attachment: {0} is not supported")]
InvalidTcxAttach, InvalidTcxAttach(u32),
/// program was loaded via tcx not netlink /// program was loaded via tcx not netlink
#[error("program was loaded via tcx not netlink")] #[error("program was loaded via tcx not netlink")]
InvalidTcLink, InvalidLink,
} }
impl TcAttachType { impl TcAttachType {
@ -118,33 +118,23 @@ impl TcAttachType {
match self { match self {
Self::Ingress => Ok(BPF_TCX_INGRESS), Self::Ingress => Ok(BPF_TCX_INGRESS),
Self::Egress => Ok(BPF_TCX_EGRESS), Self::Egress => Ok(BPF_TCX_EGRESS),
Self::Custom(_) => Err(TcError::InvalidTcxAttach), Self::Custom(i) => Err(TcError::InvalidTcxAttach(i.to_owned())),
} }
} }
} }
/// Options for a SchedClassifier attach operation. The options vary based on /// Options for a SchedClassifier attach operation.
/// what is supported by the current kernel. Kernels older than 6.6 must utilize ///
/// netlink for attachements, while newer kernels can utilize the modern TCX eBPF /// The options vary based on what is supported by the current kernel. Kernels
/// link type which support's the kernel's mprog ordering api. /// older than 6.6.0 must utilize netlink for attachments, while newer kernels
/// can utilize the modern TCX eBPF link type which support's the kernel's
/// multi-prog api.
#[derive(Debug)]
pub enum TcAttachOptions { pub enum TcAttachOptions {
/// Netlink attach options. /// Netlink attach options.
NlOptions(NlOptions), Netlink(NlOptions),
/// Tcx attach options. /// Tcx attach options.
TCXOptions(LinkOrder), TcxOrder(LinkOrder),
}
impl TcAttachOptions {
/// Create a new set of tcx attach options with a specified link ordering
pub fn tcxoptions(order: LinkOrder) -> Self {
Self::TCXOptions(order)
}
/// Create a new set of netlink attach options with a specified priority and
/// handle.
pub fn nloptions(nl: NlOptions) -> Self {
Self::NlOptions(nl)
}
} }
/// Options for SchedClassifier attach via netlink /// Options for SchedClassifier attach via netlink
@ -164,17 +154,22 @@ impl SchedClassifier {
load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data) load_program(BPF_PROG_TYPE_SCHED_CLS, &mut self.data)
} }
/// Attaches the program to the given `interface` using the TCX link /// Attaches the program to the given `interface`.
/// API in the first position by default, revert to the legacy netlink API otherwise. ///
/// For fine-grain control over link ordering use [`SchedClassifier::attach_with_options`]. /// On kernels >= 6.6.0, it will attempt to use the TCX interface and attach as
/// the first program. On older kernels, it will fallback to using the
/// legacy netlink interface.
///
/// For finer grained control over link ordering use [`SchedClassifier::attach_with_options`].
/// ///
/// The returned value can be used to detach, see [SchedClassifier::detach]. /// The returned value can be used to detach, see [SchedClassifier::detach].
/// ///
/// # Errors /// # Errors
/// ///
/// [`TcError::NetlinkError`] is returned if attaching via netlink fails. A /// When attaching fails, [`ProgramError::SyscallError`] is returned for
/// common cause of failure is not having added the `clsact` qdisc to the given /// kernels `>= 6.6.0`, and instead [`TcError::NetlinkError`] is returned for
/// interface, see [`qdisc_add_clsact`] /// older kernels. A common cause of netlink attachment failure is not having added
/// the `clsact` qdisc to the given interface, see [`qdisc_add_clsact`]
/// ///
pub fn attach( pub fn attach(
&mut self, &mut self,
@ -182,18 +177,18 @@ impl SchedClassifier {
attach_type: TcAttachType, attach_type: TcAttachType,
) -> Result<SchedClassifierLinkId, ProgramError> { ) -> Result<SchedClassifierLinkId, ProgramError> {
if KernelVersion::current().unwrap() >= KernelVersion::new(6, 6, 0) { if KernelVersion::current().unwrap() >= KernelVersion::new(6, 6, 0) {
debug!("attaching schedClassifier program via txc link API"); debug!("attaching schedClassifier program via tcx link API");
self.attach_with_options( self.attach_with_options(
interface, interface,
attach_type, attach_type,
TcAttachOptions::TCXOptions(LinkOrder::default()), TcAttachOptions::TcxOrder(LinkOrder::default()),
) )
} else { } else {
debug!("attaching SchedClassifier program via netlink API"); debug!("attaching SchedClassifier program via netlink API");
self.attach_with_options( self.attach_with_options(
interface, interface,
attach_type, attach_type,
TcAttachOptions::NlOptions(NlOptions::default()), TcAttachOptions::Netlink(NlOptions::default()),
) )
} }
} }
@ -254,7 +249,7 @@ impl SchedClassifier {
}) => self.do_attach( }) => self.do_attach(
if_index, if_index,
attach_type, attach_type,
TcAttachOptions::NlOptions(NlOptions { priority, handle }), TcAttachOptions::Netlink(NlOptions { priority, handle }),
false, false,
), ),
} }
@ -271,7 +266,7 @@ impl SchedClassifier {
let prog_fd = prog_fd.as_fd(); let prog_fd = prog_fd.as_fd();
match options { match options {
TcAttachOptions::NlOptions(options) => { TcAttachOptions::Netlink(options) => {
let name = self.data.name.as_deref().unwrap_or_default(); let name = self.data.name.as_deref().unwrap_or_default();
// TODO: avoid this unwrap by adding a new error variant. // TODO: avoid this unwrap by adding a new error variant.
let name = CString::new(name).unwrap(); let name = CString::new(name).unwrap();
@ -297,16 +292,15 @@ impl SchedClassifier {
handle, handle,
}))) })))
} }
TcAttachOptions::TCXOptions(options) => { TcAttachOptions::TcxOrder(options) => {
let link_fd = bpf_link_create( let link_fd = bpf_link_create(
prog_fd, prog_fd,
LinkTarget::IfIndex(if_index), LinkTarget::IfIndex(if_index),
attach_type.tcx_attach()?, attach_type.tcx_attach()?,
None, None,
options.flags.bits(), options.flags.bits(),
options.id, Some(&options.link_ref),
options.fd, options.expected_revision,
None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_mprog_attach", call: "bpf_mprog_attach",
@ -512,7 +506,7 @@ impl SchedClassifierLink {
if let TcLinkInner::NlLink(n) = self.inner() { if let TcLinkInner::NlLink(n) = self.inner() {
Ok(n.attach_type) Ok(n.attach_type)
} else { } else {
Err(TcError::InvalidTcLink.into()) Err(TcError::InvalidLink.into())
} }
} }
@ -521,7 +515,7 @@ impl SchedClassifierLink {
if let TcLinkInner::NlLink(n) = self.inner() { if let TcLinkInner::NlLink(n) = self.inner() {
Ok(n.priority) Ok(n.priority)
} else { } else {
Err(TcError::InvalidTcLink.into()) Err(TcError::InvalidLink.into())
} }
} }
@ -530,7 +524,7 @@ impl SchedClassifierLink {
if let TcLinkInner::NlLink(n) = self.inner() { if let TcLinkInner::NlLink(n) = self.inner() {
Ok(n.handle) Ok(n.handle)
} else { } else {
Err(TcError::InvalidTcLink.into()) Err(TcError::InvalidLink.into())
} }
} }
} }

@ -152,7 +152,6 @@ impl Xdp {
flags.bits(), flags.bits(),
None, None,
None, None,
None,
) )
.map_err(|(_, io_error)| SyscallError { .map_err(|(_, io_error)| SyscallError {
call: "bpf_link_create", call: "bpf_link_create",

@ -30,6 +30,7 @@ use crate::{
}, },
copy_instructions, copy_instructions,
}, },
programs::links::LinkRef,
sys::{syscall, SysResult, Syscall, SyscallError}, sys::{syscall, SysResult, Syscall, SyscallError},
util::KernelVersion, util::KernelVersion,
Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN, FEATURES, Btf, Pod, VerifierLogLevel, BPF_OBJ_NAME_LEN, FEATURES,
@ -379,15 +380,13 @@ pub(crate) enum LinkTarget<'f> {
} }
// since kernel 5.7 // since kernel 5.7
#[allow(clippy::too_many_arguments)]
pub(crate) fn bpf_link_create( pub(crate) fn bpf_link_create(
prog_fd: BorrowedFd<'_>, prog_fd: BorrowedFd<'_>,
target: LinkTarget<'_>, target: LinkTarget<'_>,
attach_type: bpf_attach_type, attach_type: bpf_attach_type,
btf_id: Option<u32>, btf_id: Option<u32>,
flags: u32, flags: u32,
relative_id: Option<u32>, link_ref: Option<&LinkRef>,
relative_fd: Option<RawFd>,
expected_revision: Option<u64>, expected_revision: Option<u64>,
) -> SysResult<crate::MockableFd> { ) -> SysResult<crate::MockableFd> {
let mut attr = unsafe { mem::zeroed::<bpf_attr>() }; let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
@ -415,20 +414,20 @@ pub(crate) fn bpf_link_create(
attr.link_create.__bindgen_anon_3.tcx.expected_revision = expected_revision; attr.link_create.__bindgen_anon_3.tcx.expected_revision = expected_revision;
} }
match (relative_fd, relative_id) { match link_ref {
(Some(fd), None) => { Some(LinkRef::Fd(fd)) => {
attr.link_create attr.link_create
.__bindgen_anon_3 .__bindgen_anon_3
.tcx .tcx
.__bindgen_anon_1 .__bindgen_anon_1
.relative_fd = fd as u32; .relative_fd = fd.to_owned() as u32;
} }
(None, Some(id)) => { Some(LinkRef::Id(id)) => {
attr.link_create attr.link_create
.__bindgen_anon_3 .__bindgen_anon_3
.tcx .tcx
.__bindgen_anon_1 .__bindgen_anon_1
.relative_id = id; .relative_id = id.to_owned();
} }
_ => {} _ => {}
}; };
@ -855,7 +854,7 @@ pub(crate) fn is_perf_link_supported() -> bool {
let fd = fd.as_fd(); let fd = fd.as_fd();
matches!( matches!(
// Uses an invalid target FD so we get EBADF if supported. // Uses an invalid target FD so we get EBADF if supported.
bpf_link_create(fd, LinkTarget::IfIndex(u32::MAX), bpf_attach_type::BPF_PERF_EVENT, None, 0, None, None, None), bpf_link_create(fd, LinkTarget::IfIndex(u32::MAX), bpf_attach_type::BPF_PERF_EVENT, None, 0, None, None),
// Returns EINVAL if unsupported. EBADF if supported. // Returns EINVAL if unsupported. EBADF if supported.
Err((_, e)) if e.raw_os_error() == Some(libc::EBADF), Err((_, e)) if e.raw_os_error() == Some(libc::EBADF),
) )

@ -19,7 +19,6 @@ use network_types::{
static ORDER: i32 = 0; static ORDER: i32 = 0;
// Gives us raw pointers to a specific offset in the packet // Gives us raw pointers to a specific offset in the packet
#[inline(always)]
unsafe fn ptr_at<T>(ctx: &TcContext, offset: usize) -> Result<*mut T, i64> { unsafe fn ptr_at<T>(ctx: &TcContext, offset: usize) -> Result<*mut T, i64> {
let start = ctx.data(); let start = ctx.data();
let end = ctx.data_end(); let end = ctx.data_end();

@ -27,8 +27,6 @@ test-case = { workspace = true }
test-log = { workspace = true, features = ["log"] } test-log = { workspace = true, features = ["log"] }
tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] } tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] }
xdpilone = { workspace = true } xdpilone = { workspace = true }
chrono = { workspace = true }
[build-dependencies] [build-dependencies]
cargo_metadata = { workspace = true } cargo_metadata = { workspace = true }
# TODO(https://github.com/rust-lang/cargo/issues/12375): this should be an artifact dependency, but # TODO(https://github.com/rust-lang/cargo/issues/12375): this should be an artifact dependency, but

@ -1,11 +1,11 @@
use std::{ use std::{
borrow::Cow, borrow::Cow,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Instant,
}; };
use aya::{programs::UProbe, Ebpf}; use aya::{programs::UProbe, Ebpf};
use aya_log::EbpfLogger; use aya_log::EbpfLogger;
use chrono::{DateTime, Utc};
use log::{Level, Log, Record}; use log::{Level, Log, Record};
use test_log::test; use test_log::test;
@ -37,7 +37,7 @@ pub(crate) struct CapturedLog<'a> {
pub(crate) body: Cow<'a, str>, pub(crate) body: Cow<'a, str>,
pub(crate) level: Level, pub(crate) level: Level,
pub(crate) target: Cow<'a, str>, pub(crate) target: Cow<'a, str>,
pub(crate) timestamp: Option<DateTime<Utc>>, pub(crate) timestamp: Option<Instant>,
} }
#[test(tokio::test)] #[test(tokio::test)]

@ -1,7 +1,7 @@
use std::{ use std::{
net::UdpSocket, net::UdpSocket,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
time::Duration, time::{Duration, Instant},
}; };
use aya::{ use aya::{
@ -10,7 +10,6 @@ use aya::{
Ebpf, EbpfLoader, Ebpf, EbpfLoader,
}; };
use aya_log::EbpfLogger; use aya_log::EbpfLogger;
use chrono::Utc;
use log::{debug, Record}; use log::{debug, Record};
use test_log::test; use test_log::test;
@ -30,7 +29,7 @@ fn setup_logs(loader: &mut Ebpf, logs: &Arc<Mutex<Vec<CapturedLog<'static>>>>) {
body: format!("{}", record.args()).into(), body: format!("{}", record.args()).into(),
level: record.level(), level: record.level(),
target: record.target().to_string().into(), target: record.target().to_string().into(),
timestamp: Some(Utc::now()), timestamp: Some(Instant::now()),
}); });
}, },
}, },
@ -105,15 +104,23 @@ async fn tcx_ordering() {
.unwrap(); .unwrap();
prog3.load().unwrap(); prog3.load().unwrap();
// Test LinkOrder::first() // Test LinkOrder::first() and LinkOrder::set_expected_revision()
let options = TcAttachOptions::tcxoptions(LinkOrder::first()); let mut order: LinkOrder = LinkOrder::last();
order.set_expected_revision(u64::MAX);
let options = TcAttachOptions::TcxOrder(order);
let result = prog0.attach_with_options("lo", TcAttachType::Ingress, options);
assert!(result.is_err());
let mut order: LinkOrder = LinkOrder::last();
order.set_expected_revision(0);
let options = TcAttachOptions::TcxOrder(order);
prog0 prog0
.attach_with_options("lo", TcAttachType::Ingress, options) .attach_with_options("lo", TcAttachType::Ingress, options)
.unwrap(); .unwrap();
// Test LinkOrder::after_program() // Test LinkOrder::after_program()
let order = LinkOrder::after_program(prog0).unwrap(); let order = LinkOrder::after_program(prog0).unwrap();
let options = TcAttachOptions::tcxoptions(order); let options = TcAttachOptions::TcxOrder(order);
let prog1_link_id = prog1 let prog1_link_id = prog1
.attach_with_options("lo", TcAttachType::Ingress, options) .attach_with_options("lo", TcAttachType::Ingress, options)
.unwrap(); .unwrap();
@ -122,13 +129,13 @@ async fn tcx_ordering() {
// Test LinkOrder::after_link() // Test LinkOrder::after_link()
let order = LinkOrder::after_link(&prog1_link).unwrap(); let order = LinkOrder::after_link(&prog1_link).unwrap();
let options = TcAttachOptions::tcxoptions(order); let options = TcAttachOptions::TcxOrder(order);
prog2 prog2
.attach_with_options("lo", TcAttachType::Ingress, options) .attach_with_options("lo", TcAttachType::Ingress, options)
.unwrap(); .unwrap();
// Test LinkOrder::last() // Test LinkOrder::last()
let options = TcAttachOptions::tcxoptions(LinkOrder::last()); let options = TcAttachOptions::TcxOrder(LinkOrder::last());
prog3 prog3
.attach_with_options("lo", TcAttachType::Ingress, options) .attach_with_options("lo", TcAttachType::Ingress, options)
.unwrap(); .unwrap();
@ -139,7 +146,7 @@ async fn tcx_ordering() {
let addr = sock.local_addr().unwrap(); let addr = sock.local_addr().unwrap();
sock.set_read_timeout(Some(Duration::from_secs(60))) sock.set_read_timeout(Some(Duration::from_secs(60)))
.unwrap(); .unwrap();
// We only need to send data since we're attaching tx programs to the ingress hook // We only need to send data since we're attaching tcx programs to the ingress hook
sock.send_to(PAYLOAD.as_bytes(), addr).unwrap(); sock.send_to(PAYLOAD.as_bytes(), addr).unwrap();
// Allow logs to populate // Allow logs to populate

@ -4045,13 +4045,13 @@ impl<T> core::convert::From<T> for aya::programs::links::LinkId
pub fn aya::programs::links::LinkId::from(t: T) -> T pub fn aya::programs::links::LinkId::from(t: T) -> T
pub struct aya::programs::links::LinkOrder pub struct aya::programs::links::LinkOrder
impl aya::programs::links::LinkOrder impl aya::programs::links::LinkOrder
pub fn aya::programs::links::LinkOrder::after_link<L: aya::programs::MprogLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::after_link<L: aya::programs::MultiProgLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::after_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::after_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::after_program<P: aya::programs::MprogProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError> pub fn aya::programs::links::LinkOrder::after_program<P: aya::programs::MultiProgProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::links::LinkOrder::after_program_id(id: aya::programs::ProgramId) -> Self pub fn aya::programs::links::LinkOrder::after_program_id(id: aya::programs::ProgramId) -> Self
pub fn aya::programs::links::LinkOrder::before_link<L: aya::programs::MprogLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::before_link<L: aya::programs::MultiProgLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::before_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::before_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::before_program<P: aya::programs::MprogProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError> pub fn aya::programs::links::LinkOrder::before_program<P: aya::programs::MultiProgProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::links::LinkOrder::before_program_id(id: aya::programs::ProgramId) -> Self pub fn aya::programs::links::LinkOrder::before_program_id(id: aya::programs::ProgramId) -> Self
pub fn aya::programs::links::LinkOrder::first() -> Self pub fn aya::programs::links::LinkOrder::first() -> Self
pub fn aya::programs::links::LinkOrder::last() -> Self pub fn aya::programs::links::LinkOrder::last() -> Self
@ -5624,11 +5624,10 @@ impl<T> core::convert::From<T> for aya::programs::socket_filter::SocketFilterLin
pub fn aya::programs::socket_filter::SocketFilterLinkId::from(t: T) -> T pub fn aya::programs::socket_filter::SocketFilterLinkId::from(t: T) -> T
pub mod aya::programs::tc pub mod aya::programs::tc
pub enum aya::programs::tc::TcAttachOptions pub enum aya::programs::tc::TcAttachOptions
pub aya::programs::tc::TcAttachOptions::NlOptions(aya::programs::tc::NlOptions) pub aya::programs::tc::TcAttachOptions::Netlink(aya::programs::tc::NlOptions)
pub aya::programs::tc::TcAttachOptions::TCXOptions(aya::programs::links::LinkOrder) pub aya::programs::tc::TcAttachOptions::TcxOrder(aya::programs::links::LinkOrder)
impl aya::programs::tc::TcAttachOptions impl core::fmt::Debug for aya::programs::tc::TcAttachOptions
pub fn aya::programs::tc::TcAttachOptions::nloptions(nl: aya::programs::tc::NlOptions) -> Self pub fn aya::programs::tc::TcAttachOptions::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
pub fn aya::programs::tc::TcAttachOptions::tcxoptions(order: aya::programs::links::LinkOrder) -> Self
impl core::marker::Freeze for aya::programs::tc::TcAttachOptions impl core::marker::Freeze for aya::programs::tc::TcAttachOptions
impl core::marker::Send for aya::programs::tc::TcAttachOptions impl core::marker::Send for aya::programs::tc::TcAttachOptions
impl core::marker::Sync for aya::programs::tc::TcAttachOptions impl core::marker::Sync for aya::programs::tc::TcAttachOptions
@ -5700,8 +5699,8 @@ impl<T> core::convert::From<T> for aya::programs::tc::TcAttachType
pub fn aya::programs::tc::TcAttachType::from(t: T) -> T pub fn aya::programs::tc::TcAttachType::from(t: T) -> T
pub enum aya::programs::tc::TcError pub enum aya::programs::tc::TcError
pub aya::programs::tc::TcError::AlreadyAttached pub aya::programs::tc::TcError::AlreadyAttached
pub aya::programs::tc::TcError::InvalidTcLink pub aya::programs::tc::TcError::InvalidLink
pub aya::programs::tc::TcError::InvalidTcxAttach pub aya::programs::tc::TcError::InvalidTcxAttach(u32)
pub aya::programs::tc::TcError::NetlinkError pub aya::programs::tc::TcError::NetlinkError
pub aya::programs::tc::TcError::NetlinkError::io_error: std::io::error::Error pub aya::programs::tc::TcError::NetlinkError::io_error: std::io::error::Error
impl core::convert::From<aya::programs::tc::TcError> for aya::programs::ProgramError impl core::convert::From<aya::programs::tc::TcError> for aya::programs::ProgramError
@ -5793,7 +5792,7 @@ pub fn aya::programs::tc::SchedClassifier::pin<P: core::convert::AsRef<std::path
pub fn aya::programs::tc::SchedClassifier::unpin(self) -> core::result::Result<(), std::io::error::Error> pub fn aya::programs::tc::SchedClassifier::unpin(self) -> core::result::Result<(), std::io::error::Error>
impl aya::programs::tc::SchedClassifier impl aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifier::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
impl aya::programs::MprogProgram for aya::programs::tc::SchedClassifier impl aya::programs::MultiProgProgram for aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError>
impl core::fmt::Debug for aya::programs::tc::SchedClassifier impl core::fmt::Debug for aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn aya::programs::tc::SchedClassifier::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
@ -5833,7 +5832,7 @@ pub fn aya::programs::tc::SchedClassifierLink::attach_type(&self) -> core::resul
pub fn aya::programs::tc::SchedClassifierLink::attached(if_name: &str, attach_type: aya::programs::tc::TcAttachType, priority: u16, handle: u32) -> core::result::Result<Self, std::io::error::Error> pub fn aya::programs::tc::SchedClassifierLink::attached(if_name: &str, attach_type: aya::programs::tc::TcAttachType, priority: u16, handle: u32) -> core::result::Result<Self, std::io::error::Error>
pub fn aya::programs::tc::SchedClassifierLink::handle(&self) -> core::result::Result<u32, aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifierLink::handle(&self) -> core::result::Result<u32, aya::programs::ProgramError>
pub fn aya::programs::tc::SchedClassifierLink::priority(&self) -> core::result::Result<u16, aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifierLink::priority(&self) -> core::result::Result<u16, aya::programs::ProgramError>
impl aya::programs::MprogLink for aya::programs::tc::SchedClassifierLink impl aya::programs::MultiProgLink for aya::programs::tc::SchedClassifierLink
pub fn aya::programs::tc::SchedClassifierLink::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::links::LinkError> pub fn aya::programs::tc::SchedClassifierLink::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::links::LinkError>
impl aya::programs::links::Link for aya::programs::tc::SchedClassifierLink impl aya::programs::links::Link for aya::programs::tc::SchedClassifierLink
pub type aya::programs::tc::SchedClassifierLink::Id = aya::programs::tc::SchedClassifierLinkId pub type aya::programs::tc::SchedClassifierLink::Id = aya::programs::tc::SchedClassifierLinkId
@ -7396,8 +7395,8 @@ impl<T> core::convert::From<T> for aya::programs::tc::TcAttachType
pub fn aya::programs::tc::TcAttachType::from(t: T) -> T pub fn aya::programs::tc::TcAttachType::from(t: T) -> T
pub enum aya::programs::TcError pub enum aya::programs::TcError
pub aya::programs::TcError::AlreadyAttached pub aya::programs::TcError::AlreadyAttached
pub aya::programs::TcError::InvalidTcLink pub aya::programs::TcError::InvalidLink
pub aya::programs::TcError::InvalidTcxAttach pub aya::programs::TcError::InvalidTcxAttach(u32)
pub aya::programs::TcError::NetlinkError pub aya::programs::TcError::NetlinkError
pub aya::programs::TcError::NetlinkError::io_error: std::io::error::Error pub aya::programs::TcError::NetlinkError::io_error: std::io::error::Error
impl core::convert::From<aya::programs::tc::TcError> for aya::programs::ProgramError impl core::convert::From<aya::programs::tc::TcError> for aya::programs::ProgramError
@ -8086,13 +8085,13 @@ impl<T> core::convert::From<T> for aya::programs::kprobe::KProbe
pub fn aya::programs::kprobe::KProbe::from(t: T) -> T pub fn aya::programs::kprobe::KProbe::from(t: T) -> T
pub struct aya::programs::LinkOrder pub struct aya::programs::LinkOrder
impl aya::programs::links::LinkOrder impl aya::programs::links::LinkOrder
pub fn aya::programs::links::LinkOrder::after_link<L: aya::programs::MprogLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::after_link<L: aya::programs::MultiProgLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::after_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::after_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::after_program<P: aya::programs::MprogProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError> pub fn aya::programs::links::LinkOrder::after_program<P: aya::programs::MultiProgProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::links::LinkOrder::after_program_id(id: aya::programs::ProgramId) -> Self pub fn aya::programs::links::LinkOrder::after_program_id(id: aya::programs::ProgramId) -> Self
pub fn aya::programs::links::LinkOrder::before_link<L: aya::programs::MprogLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::before_link<L: aya::programs::MultiProgLink>(link: &L) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::before_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError> pub fn aya::programs::links::LinkOrder::before_link_id(id: aya::programs::links::LinkId) -> core::result::Result<Self, aya::programs::links::LinkError>
pub fn aya::programs::links::LinkOrder::before_program<P: aya::programs::MprogProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError> pub fn aya::programs::links::LinkOrder::before_program<P: aya::programs::MultiProgProgram>(program: &P) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::links::LinkOrder::before_program_id(id: aya::programs::ProgramId) -> Self pub fn aya::programs::links::LinkOrder::before_program_id(id: aya::programs::ProgramId) -> Self
pub fn aya::programs::links::LinkOrder::first() -> Self pub fn aya::programs::links::LinkOrder::first() -> Self
pub fn aya::programs::links::LinkOrder::last() -> Self pub fn aya::programs::links::LinkOrder::last() -> Self
@ -8436,7 +8435,7 @@ pub fn aya::programs::tc::SchedClassifier::pin<P: core::convert::AsRef<std::path
pub fn aya::programs::tc::SchedClassifier::unpin(self) -> core::result::Result<(), std::io::error::Error> pub fn aya::programs::tc::SchedClassifier::unpin(self) -> core::result::Result<(), std::io::error::Error>
impl aya::programs::tc::SchedClassifier impl aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifier::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
impl aya::programs::MprogProgram for aya::programs::tc::SchedClassifier impl aya::programs::MultiProgProgram for aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError>
impl core::fmt::Debug for aya::programs::tc::SchedClassifier impl core::fmt::Debug for aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn aya::programs::tc::SchedClassifier::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
@ -9087,13 +9086,13 @@ impl aya::programs::links::Link for aya::programs::xdp::XdpLink
pub type aya::programs::xdp::XdpLink::Id = aya::programs::xdp::XdpLinkId pub type aya::programs::xdp::XdpLink::Id = aya::programs::xdp::XdpLinkId
pub fn aya::programs::xdp::XdpLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::xdp::XdpLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::XdpLink::id(&self) -> Self::Id pub fn aya::programs::xdp::XdpLink::id(&self) -> Self::Id
pub trait aya::programs::MprogLink pub trait aya::programs::MultiProgLink
pub fn aya::programs::MprogLink::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::links::LinkError> pub fn aya::programs::MultiProgLink::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::links::LinkError>
impl aya::programs::MprogLink for aya::programs::tc::SchedClassifierLink impl aya::programs::MultiProgLink for aya::programs::tc::SchedClassifierLink
pub fn aya::programs::tc::SchedClassifierLink::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::links::LinkError> pub fn aya::programs::tc::SchedClassifierLink::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::links::LinkError>
pub trait aya::programs::MprogProgram pub trait aya::programs::MultiProgProgram
pub fn aya::programs::MprogProgram::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError> pub fn aya::programs::MultiProgProgram::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError>
impl aya::programs::MprogProgram for aya::programs::tc::SchedClassifier impl aya::programs::MultiProgProgram for aya::programs::tc::SchedClassifier
pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError> pub fn aya::programs::tc::SchedClassifier::fd(&self) -> core::result::Result<std::os::fd::owned::BorrowedFd<'_>, aya::programs::ProgramError>
pub fn aya::programs::loaded_programs() -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>> pub fn aya::programs::loaded_programs() -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>>
pub mod aya::sys pub mod aya::sys

Loading…
Cancel
Save