Skip to content

Commit

Permalink
feat(aya): Return error messages from netlink
Browse files Browse the repository at this point in the history
This returns error strings from netlink since they are more informative
than the raw os error. For example:

"Device or Resource Busy" vs. "XDP program already attached".

Signed-off-by: Dave Tucker <[email protected]>
  • Loading branch information
dave-tucker committed Jan 31, 2025
1 parent 2f757b2 commit f503df1
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 70 deletions.
7 changes: 6 additions & 1 deletion aya/src/programs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down
43 changes: 23 additions & 20 deletions aya/src/programs/tc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -88,12 +89,16 @@ pub struct SchedClassifier {
#[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,
},
#[error(transparent)]
NetlinkError(#[from] NetlinkError),

/// the provided string contains a nul byte
#[error(transparent)]
NulError(#[from] std::ffi::NulError),

#[error(transparent)]
/// an IO error occurred
IoError(#[from] io::Error),
/// the clsact qdisc is already attached
#[error("the clsact qdisc is already attached")]
AlreadyAttached,
Expand Down Expand Up @@ -209,8 +214,7 @@ impl SchedClassifier {
attach_type: TcAttachType,
options: TcAttachOptions,
) -> Result<SchedClassifierLinkId, 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)?;
self.do_attach(if_index, attach_type, options, true)
}

Expand Down Expand Up @@ -281,7 +285,7 @@ impl SchedClassifier {
create,
)
}
.map_err(|io_error| TcError::NetlinkError { io_error })?;
.map_err(TcError::NetlinkError)?;

self.data
.links
Expand Down Expand Up @@ -343,8 +347,7 @@ impl SchedClassifier {
interface: &str,
attach_type: TcAttachType,
) -> Result<(u64, Vec<ProgramInfo>), 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),
Expand Down Expand Up @@ -393,7 +396,7 @@ impl Link for NlLink {
self.handle,
)
}
.map_err(|io_error| TcError::NetlinkError { io_error })?;
.map_err(ProgramError::NetlinkError)?;
Ok(())
}
}
Expand Down Expand Up @@ -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.
Expand All @@ -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)
}

Expand All @@ -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 {
Expand Down
9 changes: 4 additions & 5 deletions aya/src/programs/xdp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
use std::{
ffi::CString,
hash::Hash,
io,
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd},
path::Path,
};
Expand All @@ -23,7 +22,7 @@ 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,
Expand All @@ -37,7 +36,7 @@ pub enum XdpError {
NetlinkError {
/// the [`io::Error`] from the netlink call
#[source]
io_error: io::Error,
nl_err: NetlinkError,
},
}

Expand Down Expand Up @@ -162,7 +161,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(|nl_err| XdpError::NetlinkError { nl_err })?;

let prog_fd = prog_fd.as_raw_fd();
self.data
Expand Down Expand Up @@ -224,7 +223,7 @@ impl Xdp {
Some(old_prog_fd),
replace_flags.bits(),
)
.map_err(|io_error| XdpError::NetlinkError { io_error })?;
.map_err(|nl_err| XdpError::NetlinkError { nl_err })?;
}

let prog_fd = prog_fd.as_raw_fd();
Expand Down
Loading

0 comments on commit f503df1

Please sign in to comment.