diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index 22372339..835f53d3 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -123,7 +123,8 @@ use crate::{ sys::{ bpf_btf_get_fd_by_id, bpf_get_object, bpf_link_get_fd_by_id, bpf_link_get_info_by_fd, bpf_load_program, bpf_pin_object, bpf_prog_get_fd_by_id, bpf_prog_query, iter_link_ids, - retry_with_verifier_logs, EbpfLoadProgramAttrs, ProgQueryTarget, SyscallError, + retry_with_verifier_logs, EbpfLoadProgramAttrs, NetlinkError, ProgQueryTarget, + SyscallError, }, util::KernelVersion, VerifierLogLevel, @@ -223,6 +224,10 @@ pub enum ProgramError { /// Providing an attach cookie is not supported. #[error("providing an attach cookie is not supported")] AttachCookieNotSupported, + + /// An error occurred while working with Netlink. + #[error(transparent)] + NetlinkError(#[from] NetlinkError), } /// A [`Program`] file descriptor. diff --git a/aya/src/programs/tc.rs b/aya/src/programs/tc.rs index 252795bd..fe407e00 100644 --- a/aya/src/programs/tc.rs +++ b/aya/src/programs/tc.rs @@ -23,7 +23,8 @@ use crate::{ sys::{ bpf_link_create, bpf_link_get_info_by_fd, bpf_link_update, bpf_prog_get_fd_by_id, netlink_find_filter_with_name, netlink_qdisc_add_clsact, netlink_qdisc_attach, - netlink_qdisc_detach, BpfLinkCreateArgs, LinkTarget, ProgQueryTarget, SyscallError, + netlink_qdisc_detach, BpfLinkCreateArgs, LinkTarget, NetlinkError, ProgQueryTarget, + SyscallError, }, util::{ifindex_from_ifname, tc_handler_make, KernelVersion}, VerifierLogLevel, @@ -63,6 +64,8 @@ pub enum TcAttachType { /// # #[error(transparent)] /// # Program(#[from] aya::programs::ProgramError), /// # #[error(transparent)] +/// # Tc(#[from] aya::programs::tc::TcError), +/// # #[error(transparent)] /// # Ebpf(#[from] aya::EbpfError) /// # } /// # let mut bpf = aya::Ebpf::load(&[])?; @@ -87,20 +90,22 @@ pub struct SchedClassifier { /// Errors from TC programs #[derive(Debug, Error)] pub enum TcError { - /// netlink error while attaching ebpf program - #[error("netlink error while attaching ebpf program to tc")] - NetlinkError { - /// the [`io::Error`] from the netlink call - #[source] - io_error: io::Error, - }, - /// the clsact qdisc is already attached + /// a netlink error occurred. + #[error(transparent)] + NetlinkError(#[from] NetlinkError), + /// the provided string contains a nul byte. + #[error(transparent)] + NulError(#[from] std::ffi::NulError), + /// an IO error occurred. + #[error(transparent)] + IoError(#[from] io::Error), + /// the clsact qdisc is already attached. #[error("the clsact qdisc is already attached")] AlreadyAttached, - /// tcx links can only be attached to ingress or egress, custom attachment is not supported + /// tcx links can only be attached to ingress or egress, custom attachment is not supported. #[error("tcx links can only be attached to ingress or egress, custom attachment: {0} is not supported")] InvalidTcxAttach(u32), - /// operation not supported for programs loaded via tcx + /// operation not supported for programs loaded via tcx. #[error("operation not supported for programs loaded via tcx")] InvalidLinkOperation, } @@ -209,8 +214,7 @@ impl SchedClassifier { attach_type: TcAttachType, options: TcAttachOptions, ) -> Result { - let if_index = ifindex_from_ifname(interface) - .map_err(|io_error| TcError::NetlinkError { io_error })?; + let if_index = ifindex_from_ifname(interface).map_err(TcError::IoError)?; self.do_attach(if_index, attach_type, options, true) } @@ -281,7 +285,7 @@ impl SchedClassifier { create, ) } - .map_err(|io_error| TcError::NetlinkError { io_error })?; + .map_err(TcError::NetlinkError)?; self.data .links @@ -343,8 +347,7 @@ impl SchedClassifier { interface: &str, attach_type: TcAttachType, ) -> Result<(u64, Vec), ProgramError> { - let if_index = ifindex_from_ifname(interface) - .map_err(|io_error| TcError::NetlinkError { io_error })?; + let if_index = ifindex_from_ifname(interface).map_err(TcError::IoError)?; let (revision, prog_ids) = query( ProgQueryTarget::IfIndex(if_index), @@ -393,7 +396,7 @@ impl Link for NlLink { self.handle, ) } - .map_err(|io_error| TcError::NetlinkError { io_error })?; + .map_err(ProgramError::NetlinkError)?; Ok(()) } } @@ -557,9 +560,9 @@ impl SchedClassifierLink { /// /// The `clsact` qdisc must be added to an interface before [`SchedClassifier`] /// programs can be attached. -pub fn qdisc_add_clsact(if_name: &str) -> Result<(), io::Error> { +pub fn qdisc_add_clsact(if_name: &str) -> Result<(), TcError> { let if_index = ifindex_from_ifname(if_name)?; - unsafe { netlink_qdisc_add_clsact(if_index as i32) } + unsafe { netlink_qdisc_add_clsact(if_index as i32).map_err(TcError::NetlinkError) } } /// Detaches the programs with the given name. @@ -573,8 +576,8 @@ pub fn qdisc_detach_program( if_name: &str, attach_type: TcAttachType, name: &str, -) -> Result<(), io::Error> { - let cstr = CString::new(name)?; +) -> Result<(), TcError> { + let cstr = CString::new(name).map_err(TcError::NulError)?; qdisc_detach_program_fast(if_name, attach_type, &cstr) } @@ -591,15 +594,15 @@ fn qdisc_detach_program_fast( if_name: &str, attach_type: TcAttachType, name: &CStr, -) -> Result<(), io::Error> { +) -> Result<(), TcError> { let if_index = ifindex_from_ifname(if_name)? as i32; let filter_info = unsafe { netlink_find_filter_with_name(if_index, attach_type, name)? }; if filter_info.is_empty() { - return Err(io::Error::new( + return Err(TcError::IoError(io::Error::new( io::ErrorKind::NotFound, name.to_string_lossy(), - )); + ))); } for (prio, handle) in filter_info { diff --git a/aya/src/programs/xdp.rs b/aya/src/programs/xdp.rs index acff7950..633614ff 100644 --- a/aya/src/programs/xdp.rs +++ b/aya/src/programs/xdp.rs @@ -3,7 +3,6 @@ use std::{ ffi::CString, hash::Hash, - io, os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd}, path::Path, }; @@ -23,22 +22,18 @@ use crate::{ }, sys::{ bpf_link_create, bpf_link_get_info_by_fd, bpf_link_update, netlink_set_xdp_fd, LinkTarget, - SyscallError, + NetlinkError, SyscallError, }, util::KernelVersion, VerifierLogLevel, }; -/// The type returned when attaching an [`Xdp`] program fails on kernels `< 5.9`. +/// An error that occurred while working with an XDP program. #[derive(Debug, Error)] pub enum XdpError { - /// netlink error while attaching XDP program - #[error("netlink error while attaching XDP program")] - NetlinkError { - /// the [`io::Error`] from the netlink call - #[source] - io_error: io::Error, - }, + /// A netlink error occurred. + #[error(transparent)] + NetlinkError(#[from] NetlinkError), } bitflags::bitflags! { @@ -162,7 +157,7 @@ impl Xdp { } else { let if_index = if_index as i32; unsafe { netlink_set_xdp_fd(if_index, Some(prog_fd), None, flags.bits()) } - .map_err(|io_error| XdpError::NetlinkError { io_error })?; + .map_err(XdpError::NetlinkError)?; let prog_fd = prog_fd.as_raw_fd(); self.data @@ -224,7 +219,7 @@ impl Xdp { Some(old_prog_fd), replace_flags.bits(), ) - .map_err(|io_error| XdpError::NetlinkError { io_error })?; + .map_err(XdpError::NetlinkError)?; } let prog_fd = prog_fd.as_raw_fd(); diff --git a/aya/src/sys/netlink.rs b/aya/src/sys/netlink.rs index 11b99471..899a7132 100644 --- a/aya/src/sys/netlink.rs +++ b/aya/src/sys/netlink.rs @@ -8,18 +8,19 @@ use std::{ use libc::{ getsockname, nlattr, nlmsgerr, nlmsghdr, recv, send, setsockopt, sockaddr_nl, socket, - AF_NETLINK, AF_UNSPEC, ETH_P_ALL, IFF_UP, IFLA_XDP, NETLINK_EXT_ACK, NETLINK_ROUTE, - NLA_ALIGNTO, NLA_F_NESTED, NLA_TYPE_MASK, NLMSG_DONE, NLMSG_ERROR, NLM_F_ACK, NLM_F_CREATE, - NLM_F_DUMP, NLM_F_ECHO, NLM_F_EXCL, NLM_F_MULTI, NLM_F_REQUEST, RTM_DELTFILTER, RTM_GETTFILTER, - RTM_NEWQDISC, RTM_NEWTFILTER, RTM_SETLINK, SOCK_RAW, SOL_NETLINK, + AF_NETLINK, AF_UNSPEC, ETH_P_ALL, IFF_UP, IFLA_XDP, NETLINK_CAP_ACK, NETLINK_EXT_ACK, + NETLINK_ROUTE, NLA_ALIGNTO, NLA_F_NESTED, NLA_TYPE_MASK, NLMSG_DONE, NLMSG_ERROR, NLM_F_ACK, + NLM_F_CREATE, NLM_F_DUMP, NLM_F_ECHO, NLM_F_EXCL, NLM_F_MULTI, NLM_F_REQUEST, RTM_DELTFILTER, + RTM_GETTFILTER, RTM_NEWQDISC, RTM_NEWTFILTER, RTM_SETLINK, SOCK_RAW, SOL_NETLINK, }; use thiserror::Error; use crate::{ generated::{ - ifinfomsg, tcmsg, IFLA_XDP_EXPECTED_FD, IFLA_XDP_FD, IFLA_XDP_FLAGS, NLMSG_ALIGNTO, - TCA_BPF_FD, TCA_BPF_FLAGS, TCA_BPF_FLAG_ACT_DIRECT, TCA_BPF_NAME, TCA_KIND, TCA_OPTIONS, - TC_H_CLSACT, TC_H_INGRESS, TC_H_MAJ_MASK, TC_H_UNSPEC, XDP_FLAGS_REPLACE, + ifinfomsg, nlmsgerr_attrs::NLMSGERR_ATTR_MSG, tcmsg, IFLA_XDP_EXPECTED_FD, IFLA_XDP_FD, + IFLA_XDP_FLAGS, NLMSG_ALIGNTO, TCA_BPF_FD, TCA_BPF_FLAGS, TCA_BPF_FLAG_ACT_DIRECT, + TCA_BPF_NAME, TCA_KIND, TCA_OPTIONS, TC_H_CLSACT, TC_H_INGRESS, TC_H_MAJ_MASK, TC_H_UNSPEC, + XDP_FLAGS_REPLACE, }, programs::TcAttachType, util::tc_handler_make, @@ -27,6 +28,28 @@ use crate::{ const NLA_HDR_LEN: usize = align_to(mem::size_of::(), NLA_ALIGNTO as usize); +/// A private error type for internal use in this module. +#[derive(Error, Debug)] +pub(crate) enum NetlinkErrorInternal { + #[error("netlink error: {message}")] + Error { + message: String, + #[source] + source: io::Error, + }, + #[error(transparent)] + IoError(#[from] io::Error), + #[error(transparent)] + NulError(#[from] std::ffi::NulError), + #[error(transparent)] + NlAttrError(#[from] NlAttrError), +} + +/// An error occurred during a netlink operation. +#[derive(Error, Debug)] +#[error(transparent)] +pub struct NetlinkError(#[from] NetlinkErrorInternal); + // Safety: marking this as unsafe overall because of all the pointer math required to comply with // netlink alignments pub(crate) unsafe fn netlink_set_xdp_fd( @@ -34,7 +57,7 @@ pub(crate) unsafe fn netlink_set_xdp_fd( fd: Option>, old_fd: Option>, flags: u32, -) -> Result<(), io::Error> { +) -> Result<(), NetlinkError> { let sock = NetlinkSocket::open()?; // Safety: Request is POD so this is safe @@ -54,33 +77,39 @@ pub(crate) unsafe fn netlink_set_xdp_fd( // write the attrs let attrs_buf = request_attributes(&mut req, nlmsg_len); let mut attrs = NestedAttrs::new(attrs_buf, IFLA_XDP); - attrs.write_attr( - IFLA_XDP_FD as u16, - fd.map(|fd| fd.as_raw_fd()).unwrap_or(-1), - )?; + attrs + .write_attr( + IFLA_XDP_FD as u16, + fd.map(|fd| fd.as_raw_fd()).unwrap_or(-1), + ) + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; if flags > 0 { - attrs.write_attr(IFLA_XDP_FLAGS as u16, flags)?; + attrs + .write_attr(IFLA_XDP_FLAGS as u16, flags) + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; } if flags & XDP_FLAGS_REPLACE != 0 { - attrs.write_attr( - IFLA_XDP_EXPECTED_FD as u16, - old_fd.map(|fd| fd.as_raw_fd()).unwrap(), - )?; + attrs + .write_attr( + IFLA_XDP_EXPECTED_FD as u16, + old_fd.map(|fd| fd.as_raw_fd()).unwrap(), + ) + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; } - let nla_len = attrs.finish()?; + let nla_len = attrs + .finish() + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; req.header.nlmsg_len += align_to(nla_len, NLA_ALIGNTO as usize) as u32; sock.send(&bytes_of(&req)[..req.header.nlmsg_len as usize])?; - sock.recv()?; - Ok(()) } -pub(crate) unsafe fn netlink_qdisc_add_clsact(if_index: i32) -> Result<(), io::Error> { +pub(crate) unsafe fn netlink_qdisc_add_clsact(if_index: i32) -> Result<(), NetlinkError> { let sock = NetlinkSocket::open()?; let mut req = mem::zeroed::(); @@ -101,7 +130,8 @@ pub(crate) unsafe fn netlink_qdisc_add_clsact(if_index: i32) -> Result<(), io::E // add the TCA_KIND attribute let attrs_buf = request_attributes(&mut req, nlmsg_len); - let attr_len = write_attr_bytes(attrs_buf, 0, TCA_KIND as u16, b"clsact\0")?; + let attr_len = write_attr_bytes(attrs_buf, 0, TCA_KIND as u16, b"clsact\0") + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; req.header.nlmsg_len += align_to(attr_len, NLA_ALIGNTO as usize) as u32; sock.send(&bytes_of(&req)[..req.header.nlmsg_len as usize])?; @@ -118,7 +148,7 @@ pub(crate) unsafe fn netlink_qdisc_attach( priority: u16, handle: u32, create: bool, -) -> Result<(u16, u32), io::Error> { +) -> Result<(u16, u32), NetlinkError> { let sock = NetlinkSocket::open()?; let mut req = mem::zeroed::(); @@ -152,15 +182,24 @@ pub(crate) unsafe fn netlink_qdisc_attach( let attrs_buf = request_attributes(&mut req, nlmsg_len); // add TCA_KIND - let kind_len = write_attr_bytes(attrs_buf, 0, TCA_KIND as u16, b"bpf\0")?; + let kind_len = write_attr_bytes(attrs_buf, 0, TCA_KIND as u16, b"bpf\0") + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; // add TCA_OPTIONS which includes TCA_BPF_FD, TCA_BPF_NAME and TCA_BPF_FLAGS let mut options = NestedAttrs::new(&mut attrs_buf[kind_len..], TCA_OPTIONS as u16); - options.write_attr(TCA_BPF_FD as u16, prog_fd)?; - options.write_attr_bytes(TCA_BPF_NAME as u16, prog_name.to_bytes_with_nul())?; + options + .write_attr(TCA_BPF_FD as u16, prog_fd) + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; + options + .write_attr_bytes(TCA_BPF_NAME as u16, prog_name.to_bytes_with_nul()) + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; let flags: u32 = TCA_BPF_FLAG_ACT_DIRECT; - options.write_attr(TCA_BPF_FLAGS as u16, flags)?; - let options_len = options.finish()?; + options + .write_attr(TCA_BPF_FLAGS as u16, flags) + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; + let options_len = options + .finish() + .map_err(|e| NetlinkError(NetlinkErrorInternal::IoError(e)))?; req.header.nlmsg_len += align_to(kind_len + options_len, NLA_ALIGNTO as usize) as u32; sock.send(&bytes_of(&req)[..req.header.nlmsg_len as usize])?; @@ -176,10 +215,10 @@ pub(crate) unsafe fn netlink_qdisc_attach( None => { // if sock.recv() succeeds we should never get here unless there's a // bug in the kernel - return Err(io::Error::new( + return Err(NetlinkError(NetlinkErrorInternal::IoError(io::Error::new( io::ErrorKind::Other, "no RTM_NEWTFILTER reply received, this is a bug.", - )); + )))); } }; @@ -192,7 +231,7 @@ pub(crate) unsafe fn netlink_qdisc_detach( attach_type: &TcAttachType, priority: u16, handle: u32, -) -> Result<(), io::Error> { +) -> Result<(), NetlinkError> { let sock = NetlinkSocket::open()?; let mut req = mem::zeroed::(); @@ -222,7 +261,7 @@ pub(crate) unsafe fn netlink_find_filter_with_name( if_index: i32, attach_type: TcAttachType, name: &CStr, -) -> Result, io::Error> { +) -> Result, NetlinkError> { let mut req = mem::zeroed::(); let nlmsg_len = mem::size_of::() + mem::size_of::(); @@ -249,10 +288,12 @@ pub(crate) unsafe fn netlink_find_filter_with_name( let tc_msg = ptr::read_unaligned(msg.data.as_ptr() as *const tcmsg); let priority = (tc_msg.tcm_info >> 16) as u16; - let attrs = parse_attrs(&msg.data[mem::size_of::()..])?; + let attrs = parse_attrs(&msg.data[mem::size_of::()..]) + .map_err(|e| NetlinkError(NetlinkErrorInternal::NlAttrError(e)))?; if let Some(opts) = attrs.get(&(TCA_OPTIONS as u16)) { - let opts = parse_attrs(opts.data)?; + let opts = parse_attrs(opts.data) + .map_err(|e| NetlinkError(NetlinkErrorInternal::NlAttrError(e)))?; if let Some(f_name) = opts.get(&(TCA_BPF_NAME as u16)) { if let Ok(f_name) = CStr::from_bytes_with_nul(f_name.data) { if name == f_name { @@ -267,7 +308,7 @@ pub(crate) unsafe fn netlink_find_filter_with_name( } #[doc(hidden)] -pub unsafe fn netlink_set_link_up(if_index: i32) -> Result<(), io::Error> { +pub unsafe fn netlink_set_link_up(if_index: i32) -> Result<(), NetlinkError> { let sock = NetlinkSocket::open()?; // Safety: Request is POD so this is safe @@ -312,11 +353,11 @@ struct NetlinkSocket { } impl NetlinkSocket { - fn open() -> Result { + fn open() -> Result { // Safety: libc wrapper let sock = unsafe { socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) }; if sock < 0 { - return Err(io::Error::last_os_error()); + return Err(NetlinkErrorInternal::IoError(io::Error::last_os_error())); } // SAFETY: `socket` returns a file descriptor. let sock = unsafe { crate::MockableFd::from_raw_fd(sock) }; @@ -324,13 +365,29 @@ impl NetlinkSocket { let enable = 1i32; // Safety: libc wrapper unsafe { - setsockopt( + // Set NETLINK_EXT_ACK to get extended attributes. + if setsockopt( sock.as_raw_fd(), SOL_NETLINK, NETLINK_EXT_ACK, &enable as *const _ as *const _, mem::size_of::() as u32, - ) + ) < 0 + { + return Err(NetlinkErrorInternal::IoError(io::Error::last_os_error())); + }; + + // Set NETLINK_CAP_ACK to avoid getting copies of request payload. + if setsockopt( + sock.as_raw_fd(), + SOL_NETLINK, + NETLINK_CAP_ACK, + &enable as *const _ as *const _, + mem::size_of::() as u32, + ) < 0 + { + return Err(NetlinkErrorInternal::IoError(io::Error::last_os_error())); + }; }; // Safety: sockaddr_nl is POD so this is safe @@ -346,7 +403,7 @@ impl NetlinkSocket { ) } < 0 { - return Err(io::Error::last_os_error()); + return Err(NetlinkErrorInternal::IoError(io::Error::last_os_error())); } Ok(Self { @@ -355,7 +412,7 @@ impl NetlinkSocket { }) } - fn send(&self, msg: &[u8]) -> Result<(), io::Error> { + fn send(&self, msg: &[u8]) -> Result<(), NetlinkErrorInternal> { if unsafe { send( self.sock.as_raw_fd(), @@ -365,12 +422,12 @@ impl NetlinkSocket { ) } < 0 { - return Err(io::Error::last_os_error()); + return Err(NetlinkErrorInternal::IoError(io::Error::last_os_error())); } Ok(()) } - fn recv(&self) -> Result, io::Error> { + fn recv(&self) -> Result, NetlinkErrorInternal> { let mut buf = [0u8; 4096]; let mut messages = Vec::new(); let mut multipart = true; @@ -386,7 +443,7 @@ impl NetlinkSocket { ) }; if len < 0 { - return Err(io::Error::last_os_error()); + return Err(NetlinkErrorInternal::IoError(io::Error::last_os_error())); } if len == 0 { break; @@ -405,7 +462,22 @@ impl NetlinkSocket { // this is an ACK continue; } - return Err(io::Error::from_raw_os_error(-err.error)); + let attrs = parse_attrs(&message.data)?; + let err_msg = attrs.get(&(NLMSGERR_ATTR_MSG as u16)).and_then(|msg| { + CStr::from_bytes_with_nul(msg.data) + .ok() + .map(|s| s.to_string_lossy().into_owned()) + }); + let e = match err_msg { + Some(err_msg) => NetlinkErrorInternal::Error { + message: err_msg, + source: io::Error::from_raw_os_error(-err.error), + }, + None => NetlinkErrorInternal::IoError(io::Error::from_raw_os_error( + -err.error, + )), + }; + return Err(e); } NLMSG_DONE => break 'out, _ => messages.push(message), @@ -444,7 +516,7 @@ impl NetlinkMessage { return Err(io::Error::new(io::ErrorKind::Other, "need more data")); } - let (data, error) = if header.nlmsg_type == NLMSG_ERROR as u16 { + let (rest, error) = if header.nlmsg_type == NLMSG_ERROR as u16 { if data_offset + mem::size_of::() > buf.len() { return Err(io::Error::new( io::ErrorKind::Other, @@ -452,19 +524,19 @@ impl NetlinkMessage { )); } ( - Vec::new(), + &buf[data_offset + mem::size_of::()..msg_len], // Safety: nlmsgerr is POD so read is safe Some(unsafe { ptr::read_unaligned(buf[data_offset..].as_ptr() as *const nlmsgerr) }), ) } else { - (buf[data_offset..msg_len].to_vec(), None) + (&buf[data_offset..msg_len], None) }; Ok(Self { header, - data, + data: rest.to_vec(), error, }) } @@ -628,7 +700,7 @@ struct NlAttr<'a> { } #[derive(Debug, Error, PartialEq, Eq)] -enum NlAttrError { +pub(crate) enum NlAttrError { #[error("invalid buffer size `{size}`, expected `{expected}`")] InvalidBufferLength { size: usize, expected: usize }, diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 3c8367b7..cd2886d8 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -6060,10 +6060,15 @@ pub enum aya::programs::tc::TcError pub aya::programs::tc::TcError::AlreadyAttached pub aya::programs::tc::TcError::InvalidLinkOperation pub aya::programs::tc::TcError::InvalidTcxAttach(u32) -pub aya::programs::tc::TcError::NetlinkError -pub aya::programs::tc::TcError::NetlinkError::io_error: std::io::error::Error +pub aya::programs::tc::TcError::IoError(std::io::error::Error) +pub aya::programs::tc::TcError::NetlinkError(aya::sys::netlink::NetlinkError) +pub aya::programs::tc::TcError::NulError(alloc::ffi::c_str::NulError) +impl core::convert::From for aya::programs::tc::TcError +pub fn aya::programs::tc::TcError::from(source: alloc::ffi::c_str::NulError) -> Self impl core::convert::From for aya::programs::ProgramError pub fn aya::programs::ProgramError::from(source: aya::programs::tc::TcError) -> Self +impl core::convert::From for aya::programs::tc::TcError +pub fn aya::programs::tc::TcError::from(source: std::io::error::Error) -> Self impl core::error::Error for aya::programs::tc::TcError pub fn aya::programs::tc::TcError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> impl core::fmt::Debug for aya::programs::tc::TcError @@ -6276,8 +6281,8 @@ impl core::borrow::BorrowMut for aya::programs::tc::SchedClassifierLinkId pub fn aya::programs::tc::SchedClassifierLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::tc::SchedClassifierLinkId pub fn aya::programs::tc::SchedClassifierLinkId::from(t: T) -> T -pub fn aya::programs::tc::qdisc_add_clsact(if_name: &str) -> core::result::Result<(), std::io::error::Error> -pub fn aya::programs::tc::qdisc_detach_program(if_name: &str, attach_type: aya::programs::tc::TcAttachType, name: &str) -> core::result::Result<(), std::io::error::Error> +pub fn aya::programs::tc::qdisc_add_clsact(if_name: &str) -> core::result::Result<(), aya::programs::tc::TcError> +pub fn aya::programs::tc::qdisc_detach_program(if_name: &str, attach_type: aya::programs::tc::TcAttachType, name: &str) -> core::result::Result<(), aya::programs::tc::TcError> pub mod aya::programs::tp_btf pub struct aya::programs::tp_btf::BtfTracePoint impl aya::programs::tp_btf::BtfTracePoint @@ -6783,8 +6788,7 @@ impl core::convert::From for aya::programs::uprobe::UProbeLinkId pub fn aya::programs::uprobe::UProbeLinkId::from(t: T) -> T pub mod aya::programs::xdp pub enum aya::programs::xdp::XdpError -pub aya::programs::xdp::XdpError::NetlinkError -pub aya::programs::xdp::XdpError::NetlinkError::io_error: std::io::error::Error +pub aya::programs::xdp::XdpError::NetlinkError(aya::sys::netlink::NetlinkError) impl core::convert::From for aya::programs::ProgramError pub fn aya::programs::ProgramError::from(source: aya::programs::xdp::XdpError) -> Self impl core::error::Error for aya::programs::xdp::XdpError @@ -7548,6 +7552,7 @@ pub aya::programs::ProgramError::LoadError pub aya::programs::ProgramError::LoadError::io_error: std::io::error::Error pub aya::programs::ProgramError::LoadError::verifier_log: aya_obj::VerifierLog pub aya::programs::ProgramError::MapError(aya::maps::MapError) +pub aya::programs::ProgramError::NetlinkError(aya::sys::netlink::NetlinkError) pub aya::programs::ProgramError::NotAttached pub aya::programs::ProgramError::NotLoaded pub aya::programs::ProgramError::SocketFilterError(aya::programs::socket_filter::SocketFilterError) @@ -7841,10 +7846,15 @@ pub enum aya::programs::TcError pub aya::programs::TcError::AlreadyAttached pub aya::programs::TcError::InvalidLinkOperation pub aya::programs::TcError::InvalidTcxAttach(u32) -pub aya::programs::TcError::NetlinkError -pub aya::programs::TcError::NetlinkError::io_error: std::io::error::Error +pub aya::programs::TcError::IoError(std::io::error::Error) +pub aya::programs::TcError::NetlinkError(aya::sys::netlink::NetlinkError) +pub aya::programs::TcError::NulError(alloc::ffi::c_str::NulError) +impl core::convert::From for aya::programs::tc::TcError +pub fn aya::programs::tc::TcError::from(source: alloc::ffi::c_str::NulError) -> Self impl core::convert::From for aya::programs::ProgramError pub fn aya::programs::ProgramError::from(source: aya::programs::tc::TcError) -> Self +impl core::convert::From for aya::programs::tc::TcError +pub fn aya::programs::tc::TcError::from(source: std::io::error::Error) -> Self impl core::error::Error for aya::programs::tc::TcError pub fn aya::programs::tc::TcError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> impl core::fmt::Debug for aya::programs::tc::TcError @@ -7955,8 +7965,7 @@ pub fn aya::programs::uprobe::UProbeError::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::uprobe::UProbeError pub fn aya::programs::uprobe::UProbeError::from(t: T) -> T pub enum aya::programs::XdpError -pub aya::programs::XdpError::NetlinkError -pub aya::programs::XdpError::NetlinkError::io_error: std::io::error::Error +pub aya::programs::XdpError::NetlinkError(aya::sys::netlink::NetlinkError) impl core::convert::From for aya::programs::ProgramError pub fn aya::programs::ProgramError::from(source: aya::programs::xdp::XdpError) -> Self impl core::error::Error for aya::programs::xdp::XdpError