From f961cbb3d43693e21a9c633d8b581c8a24fa7055 Mon Sep 17 00:00:00 2001 From: Dave Tucker Date: Tue, 6 Sep 2022 13:18:18 +0000 Subject: [PATCH] aya: Replace From for XdpLink with TryFrom Signed-off-by: Dave Tucker --- aya/src/programs/xdp.rs | 25 +++++++++++++++++++++---- aya/src/sys/bpf.rs | 41 +++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 20 deletions(-) diff --git a/aya/src/programs/xdp.rs b/aya/src/programs/xdp.rs index 6aa715eb..a979bc08 100644 --- a/aya/src/programs/xdp.rs +++ b/aya/src/programs/xdp.rs @@ -7,6 +7,7 @@ use thiserror::Error; use crate::{ generated::{ bpf_attach_type::{self, BPF_XDP}, + bpf_link_type, 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, @@ -14,7 +15,10 @@ use crate::{ programs::{ define_link_wrapper, load_program, FdLink, Link, LinkError, ProgramData, ProgramError, }, - sys::{bpf_link_create, bpf_link_update, kernel_version, netlink_set_xdp_fd}, + sys::{ + bpf_link_create, bpf_link_get_info_by_fd, bpf_link_update, kernel_version, + netlink_set_xdp_fd, + }, }; /// The type returned when attaching an [`Xdp`] program fails on kernels `< 5.9`. @@ -250,9 +254,22 @@ impl TryFrom for FdLink { } } -impl From for XdpLink { - fn from(fd_link: FdLink) -> Self { - XdpLink(XdpLinkInner::FdLink(fd_link)) +impl TryFrom for XdpLink { + type Error = LinkError; + + fn try_from(fd_link: FdLink) -> Result { + // unwrap of fd_link.fd will not panic since it's only None when being dropped. + let info = bpf_link_get_info_by_fd(fd_link.fd.unwrap()).map_err(|io_error| { + LinkError::SyscallError { + call: "BPF_OBJ_GET_INFO_BY_FD".to_string(), + code: 0, + io_error, + } + })?; + if info.type_ == (bpf_link_type::BPF_LINK_TYPE_XDP as u32) { + return Ok(XdpLink(XdpLinkInner::FdLink(fd_link))); + } + Err(LinkError::InvalidLink) } } diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index 37ba219a..1e0010ea 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -1,16 +1,3 @@ -use crate::{ - generated::BPF_F_REPLACE, - obj::{ - btf::{ - BtfParam, BtfType, DataSec, DataSecEntry, DeclTag, Float, Func, FuncLinkage, FuncProto, - Int, IntEncoding, Ptr, TypeTag, Var, VarLinkage, - }, - copy_instructions, - }, - Btf, -}; -use libc::{c_char, c_long, close, ENOENT, ENOSPC}; - use std::{ cmp::{self, min}, ffi::{CStr, CString}, @@ -20,18 +7,25 @@ use std::{ slice, }; +use libc::{c_char, c_long, close, ENOENT, ENOSPC}; + use crate::{ generated::{ - bpf_attach_type, bpf_attr, bpf_btf_info, bpf_cmd, bpf_insn, bpf_prog_info, bpf_prog_type, + bpf_attach_type, bpf_attr, bpf_btf_info, bpf_cmd, bpf_insn, bpf_link_info, bpf_prog_info, + bpf_prog_type, BPF_F_REPLACE, }, maps::PerCpuValues, obj::{ self, - btf::{FuncSecInfo, LineSecInfo}, + btf::{ + BtfParam, BtfType, DataSec, DataSecEntry, DeclTag, Float, Func, FuncLinkage, FuncProto, + FuncSecInfo, Int, IntEncoding, LineSecInfo, Ptr, TypeTag, Var, VarLinkage, + }, + copy_instructions, }, sys::{kernel_version, syscall, SysResult, Syscall}, util::VerifierLog, - Pod, BPF_OBJ_NAME_LEN, + Btf, Pod, BPF_OBJ_NAME_LEN, }; pub(crate) fn bpf_create_map(name: &CStr, def: &obj::Map, btf_fd: Option) -> SysResult { @@ -457,6 +451,21 @@ pub(crate) fn bpf_prog_get_info_by_fd(prog_fd: RawFd) -> Result Result { + let mut attr = unsafe { mem::zeroed::() }; + // info gets entirely populated by the kernel + let info = unsafe { MaybeUninit::zeroed().assume_init() }; + + attr.info.bpf_fd = link_fd as u32; + attr.info.info = &info as *const _ as u64; + attr.info.info_len = mem::size_of::() as u32; + + match sys_bpf(bpf_cmd::BPF_OBJ_GET_INFO_BY_FD, &attr) { + Ok(_) => Ok(info), + Err((_, err)) => Err(err), + } +} + pub(crate) fn btf_obj_get_info_by_fd( prog_fd: RawFd, buf: &mut [u8],