From 64b611ee37b542035ad98112674039ba45b4db9d Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Mon, 18 Sep 2023 16:16:27 +0200 Subject: [PATCH] aya, bpf: misc fixes following review comments --- aya-bpf-macros/src/lib.rs | 9 +--- aya-bpf-macros/src/xdp.rs | 2 +- aya-obj/src/obj.rs | 8 ---- aya/src/bpf.rs | 6 +-- aya/src/maps/xdp/cpu_map.rs | 67 ++++++++++++++------------ aya/src/maps/xdp/dev_map.rs | 73 +++++++++++++++-------------- aya/src/maps/xdp/dev_map_hash.rs | 68 ++++++++++++++------------- aya/src/maps/xdp/mod.rs | 15 ++++++ aya/src/maps/xdp/xsk_map.rs | 4 ++ bpf/aya-bpf/src/maps/xdp/cpu_map.rs | 6 +-- 10 files changed, 136 insertions(+), 122 deletions(-) diff --git a/aya-bpf-macros/src/lib.rs b/aya-bpf-macros/src/lib.rs index bdac27950..f29b725fe 100644 --- a/aya-bpf-macros/src/lib.rs +++ b/aya-bpf-macros/src/lib.rs @@ -147,14 +147,7 @@ pub fn sk_msg(attrs: TokenStream, item: TokenStream) -> TokenStream { /// /// #[xdp(frags)] /// pub fn xdp(ctx: XdpContext) -> u32 { -/// match unsafe { try_xdp(ctx) } { -/// Ok(ret) => ret, -/// Err(ret) => ret, -/// } -/// } -/// -/// unsafe fn try_xdp(_ctx: XdpContext) -> Result { -/// Ok(XDP_PASS) +/// XDP_PASS /// } /// ``` #[proc_macro_error] diff --git a/aya-bpf-macros/src/xdp.rs b/aya-bpf-macros/src/xdp.rs index e8e9b6e60..baaf57468 100644 --- a/aya-bpf-macros/src/xdp.rs +++ b/aya-bpf-macros/src/xdp.rs @@ -28,7 +28,7 @@ impl Xdp { Some(name) => { return Err(Error::new_spanned( "map", - format!("invalid value. expected 'cpumap' or 'devmap', found '{name}'"), + format!("Invalid value. Expected 'cpumap' or 'devmap', found '{name}'"), )) } None => None, diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index 6909a229d..38221f966 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -50,7 +50,6 @@ pub struct Features { bpf_cookie: bool, cpumap_prog_id: bool, devmap_prog_id: bool, - devmap_hash_prog_id: bool, btf: Option, } @@ -65,7 +64,6 @@ impl Features { bpf_cookie: bool, cpumap_prog_id: bool, devmap_prog_id: bool, - devmap_hash_prog_id: bool, btf: Option, ) -> Self { Self { @@ -76,7 +74,6 @@ impl Features { bpf_cookie, cpumap_prog_id, devmap_prog_id, - devmap_hash_prog_id, btf, } } @@ -116,11 +113,6 @@ impl Features { self.devmap_prog_id } - /// Returns whether XDP Hash Device Maps support chained program IDs. - pub fn devmap_hash_prog_id(&self) -> bool { - self.devmap_hash_prog_id - } - /// If BTF is supported, returns which BTF features are supported. pub fn btf(&self) -> Option<&BtfFeatures> { self.btf.as_ref() diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 181d971fb..2272bc524 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -96,7 +96,6 @@ fn detect_features() -> Features { is_bpf_cookie_supported(), is_prog_id_supported(BPF_MAP_TYPE_CPUMAP), is_prog_id_supported(BPF_MAP_TYPE_DEVMAP), - is_prog_id_supported(BPF_MAP_TYPE_DEVMAP_HASH), btf, ); debug!("BPF Feature Detection: {:#?}", f); @@ -484,12 +483,9 @@ impl<'a> BpfLoader<'a> { Ok(BPF_MAP_TYPE_CPUMAP) => { obj.set_value_size(if FEATURES.cpumap_prog_id() { 8 } else { 4 }) } - Ok(BPF_MAP_TYPE_DEVMAP) => { + Ok(BPF_MAP_TYPE_DEVMAP | BPF_MAP_TYPE_DEVMAP_HASH) => { obj.set_value_size(if FEATURES.devmap_prog_id() { 8 } else { 4 }) } - Ok(BPF_MAP_TYPE_DEVMAP_HASH) => { - obj.set_value_size(if FEATURES.devmap_hash_prog_id() { 8 } else { 4 }) - } _ => (), } let btf_fd = btf_fd.as_deref().map(|fd| fd.as_fd()); diff --git a/aya/src/maps/xdp/cpu_map.rs b/aya/src/maps/xdp/cpu_map.rs index e63491630..d21f711cc 100644 --- a/aya/src/maps/xdp/cpu_map.rs +++ b/aya/src/maps/xdp/cpu_map.rs @@ -6,7 +6,7 @@ use std::{ os::fd::{AsFd, AsRawFd}, }; -use aya_obj::generated::{bpf_cpumap_val, bpf_cpumap_val__bindgen_ty_1}; +use aya_obj::generated::bpf_cpumap_val; use crate::{ maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError}, @@ -15,6 +15,8 @@ use crate::{ Pod, FEATURES, }; +use super::XdpMapError; + /// An array of available CPUs. /// /// XDP programs can use this map to redirect packets to a target @@ -29,19 +31,24 @@ use crate::{ /// # let elf_bytes = &[]; /// use aya::maps::xdp::CpuMap; /// +/// let ncpus = aya::util::nr_cpus().unwrap() as u32; /// let mut bpf = aya::BpfLoader::new() -/// .set_max_entries("CPUS", aya::util::nr_cpus().unwrap() as u32) +/// .set_max_entries("CPUS", ncpus) /// .load(elf_bytes) /// .unwrap(); /// let mut cpumap = CpuMap::try_from(bpf.map_mut("CPUS").unwrap())?; /// let flags = 0; /// let queue_size = 2048; -/// for i in 0u32..8u32 { +/// for i in 0..ncpus { /// cpumap.set(i, queue_size, None, flags); /// } /// /// # Ok::<(), aya::BpfError>(()) /// ``` +/// +/// # See also +/// +/// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_CPUMAP")] pub struct CpuMap { inner: T, @@ -67,7 +74,7 @@ impl> CpuMap { self.inner.borrow().obj.max_entries() } - /// Returns the queue size and possible program for a given CPU index. + /// Returns the queue size and optional program for a given CPU index. /// /// # Errors /// @@ -81,7 +88,7 @@ impl> CpuMap { let value = if FEATURES.cpumap_prog_id() { bpf_map_lookup_elem::<_, bpf_cpumap_val>(fd, &cpu_index, flags).map(|value| { value.map(|value| CpuMapValue { - qsize: value.qsize, + queue_size: value.qsize, // SAFETY: map writes use fd, map reads use id. // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/include/uapi/linux/bpf.h#L6241 prog_id: NonZeroU32::new(unsafe { value.bpf_prog.id }), @@ -90,7 +97,7 @@ impl> CpuMap { } else { bpf_map_lookup_elem::<_, u32>(fd, &cpu_index, flags).map(|value| { value.map(|qsize| CpuMapValue { - qsize, + queue_size: qsize, prog_id: None, }) }) @@ -115,52 +122,52 @@ impl> CpuMap { /// When sending the packet to the CPU at the given index, the kernel will queue up to /// `queue_size` packets before dropping them. /// - /// Another XDP program can be passed in that will be run on the target CPU, instead of the CPU - /// that receives the packets. This allows to perform minimal computations on CPUs that - /// directly handle packets from a NIC's RX queues, and perform possibly heavier ones in other, - /// less busy CPUs. + /// Starting from Linux kernel 5.9, another XDP program can be passed in that will be run on the + /// target CPU, instead of the CPU that receives the packets. This allows to perform minimal + /// computations on CPUs that directly handle packets from a NIC's RX queues, and perform + /// possibly heavier ones in other, less busy CPUs. /// - /// Note that only XDP programs with the `map = "cpumap"` argument can be passed. See the - /// kernel-space `aya_bpf::xdp` for more information. + /// Note that, when using `aya-ebpf`, only XDP programs with the `map = "cpumap"` argument can + /// be passed. See the kernel-space `aya_ebpf::xdp` for more information. Otherwise, the + /// program must be loaded with the `BPF_XDP_CPUMAP` attach type. /// /// # Errors /// /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] - /// if `bpf_map_update_elem` fails, [`MapError::ProgIdNotSupported`] if the kernel does not - /// support program ids and one is provided. + /// if `bpf_map_update_elem` fails, [`XdpMapError::ChainedProgramNotSupported`] if the kernel + /// does not support chained programs and one is provided. pub fn set( &mut self, cpu_index: u32, queue_size: u32, program: Option<&ProgramFd>, flags: u64, - ) -> Result<(), MapError> { + ) -> Result<(), XdpMapError> { let data = self.inner.borrow_mut(); check_bounds(data, cpu_index)?; let fd = data.fd().as_fd(); let res = if FEATURES.cpumap_prog_id() { - let value = bpf_cpumap_val { - qsize: queue_size, - bpf_prog: bpf_cpumap_val__bindgen_ty_1 { - // Default is valid as the kernel will only consider fd > 0: - // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/cpumap.c#L466 - fd: program - .map(|prog| prog.as_fd().as_raw_fd()) - .unwrap_or_default(), - }, - }; + let mut value = unsafe { std::mem::zeroed::() }; + value.qsize = queue_size; + // Default is valid as the kernel will only consider fd > 0: + // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/cpumap.c#L466 + value.bpf_prog.fd = program + .map(|prog| prog.as_fd().as_raw_fd()) + .unwrap_or_default(); bpf_map_update_elem(fd, Some(&cpu_index), &value, flags) } else { if program.is_some() { - return Err(MapError::ProgIdNotSupported); + return Err(XdpMapError::ChainedProgramNotSupported); } bpf_map_update_elem(fd, Some(&cpu_index), &queue_size, flags) }; - res.map_err(|(_, io_error)| SyscallError { - call: "bpf_map_update_elem", - io_error, + res.map_err(|(_, io_error)| { + MapError::from(SyscallError { + call: "bpf_map_update_elem", + io_error, + }) })?; Ok(()) } @@ -180,6 +187,6 @@ unsafe impl Pod for bpf_cpumap_val {} #[derive(Clone, Copy, Debug)] pub struct CpuMapValue { - pub qsize: u32, + pub queue_size: u32, pub prog_id: Option, } diff --git a/aya/src/maps/xdp/dev_map.rs b/aya/src/maps/xdp/dev_map.rs index df43461c6..adbefbda2 100644 --- a/aya/src/maps/xdp/dev_map.rs +++ b/aya/src/maps/xdp/dev_map.rs @@ -6,7 +6,7 @@ use std::{ os::fd::{AsFd, AsRawFd}, }; -use aya_obj::generated::{bpf_devmap_val, bpf_devmap_val__bindgen_ty_1}; +use aya_obj::generated::bpf_devmap_val; use crate::{ maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError}, @@ -15,6 +15,8 @@ use crate::{ Pod, FEATURES, }; +use super::XdpMapError; + /// An array of network devices. /// /// XDP programs can use this map to redirect to other network @@ -30,12 +32,15 @@ use crate::{ /// use aya::maps::xdp::DevMap; /// /// let mut devmap = DevMap::try_from(bpf.map_mut("IFACES").unwrap())?; -/// let source = 32u32; -/// let dest = 42u32; -/// devmap.set(source, dest, None, 0); +/// // Lookups at index 2 will redirect packets to interface with index 3 (e.g. eth1) +/// devmap.set(2, 3, None, 0); /// /// # Ok::<(), aya::BpfError>(()) /// ``` +/// +/// # See also +/// +/// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_DEVMAP")] pub struct DevMap { inner: T, @@ -61,7 +66,7 @@ impl> DevMap { self.inner.borrow().obj.max_entries() } - /// Returns the target ifindex and possible program at a given index. + /// Returns the target interface index and optional program at a given index. /// /// # Errors /// @@ -75,7 +80,7 @@ impl> DevMap { let value = if FEATURES.devmap_prog_id() { bpf_map_lookup_elem::<_, bpf_devmap_val>(fd, &index, flags).map(|value| { value.map(|value| DevMapValue { - ifindex: value.ifindex, + if_index: value.ifindex, // SAFETY: map writes use fd, map reads use id. // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/include/uapi/linux/bpf.h#L6228 prog_id: NonZeroU32::new(unsafe { value.bpf_prog.id }), @@ -84,7 +89,7 @@ impl> DevMap { } else { bpf_map_lookup_elem::<_, u32>(fd, &index, flags).map(|value| { value.map(|ifindex| DevMapValue { - ifindex, + if_index: ifindex, prog_id: None, }) }) @@ -104,57 +109,57 @@ impl> DevMap { } impl> DevMap { - /// Sets the target ifindex at index, and optionally a chained program. + /// Sets the target interface index at index, and optionally a chained program. /// /// When redirecting using `index`, packets will be transmitted by the interface with - /// `ifindex`. + /// `target_if_index`. /// - /// Another XDP program can be passed in that will be run before actual transmission. It can be - /// used to modify the packet before transmission with NIC specific data (MAC address update, - /// checksum computations, etc) or other purposes. + /// Starting from Linux kernel 5.8, another XDP program can be passed in that will be run before + /// actual transmission. It can be used to modify the packet before transmission with NIC + /// specific data (MAC address update, checksum computations, etc) or other purposes. /// - /// Note that only XDP programs with the `map = "devmap"` argument can be passed. See the - /// kernel-space `aya_bpf::xdp` for more information. + /// Note that, when using `aya-ebpf`, only XDP programs with the `map = "devmap"` argument can + /// be passed. See the kernel-space `aya_ebpf::xdp` for more information. Otherwise, the + /// program must be loaded with the `BPF_XDP_DEVMAP` attach type. /// /// # Errors /// /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] /// if `bpf_map_update_elem` fails, [`MapError::ProgIdNotSupported`] if the kernel does not - /// support program ids and one is provided. + /// support chained programs and one is provided. pub fn set( &mut self, index: u32, - ifindex: u32, + target_if_index: u32, program: Option<&ProgramFd>, flags: u64, - ) -> Result<(), MapError> { + ) -> Result<(), XdpMapError> { let data = self.inner.borrow_mut(); check_bounds(data, index)?; let fd = data.fd().as_fd(); let res = if FEATURES.devmap_prog_id() { - let value = bpf_devmap_val { - ifindex, - bpf_prog: bpf_devmap_val__bindgen_ty_1 { - // Default is valid as the kernel will only consider fd > 0: - // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L866 - // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L918 - fd: program - .map(|prog| prog.as_fd().as_raw_fd()) - .unwrap_or_default(), - }, - }; + let mut value = unsafe { std::mem::zeroed::() }; + value.ifindex = target_if_index; + // Default is valid as the kernel will only consider fd > 0: + // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L866 + // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L918 + value.bpf_prog.fd = program + .map(|prog| prog.as_fd().as_raw_fd()) + .unwrap_or_default(); bpf_map_update_elem(fd, Some(&index), &value, flags) } else { if program.is_some() { - return Err(MapError::ProgIdNotSupported); + return Err(XdpMapError::ChainedProgramNotSupported); } - bpf_map_update_elem(fd, Some(&index), &ifindex, flags) + bpf_map_update_elem(fd, Some(&index), &target_if_index, flags) }; - res.map_err(|(_, io_error)| SyscallError { - call: "bpf_map_update_elem", - io_error, + res.map_err(|(_, io_error)| { + MapError::from(SyscallError { + call: "bpf_map_update_elem", + io_error, + }) })?; Ok(()) } @@ -174,6 +179,6 @@ unsafe impl Pod for bpf_devmap_val {} #[derive(Clone, Copy, Debug)] pub struct DevMapValue { - pub ifindex: u32, + pub if_index: u32, pub prog_id: Option, } diff --git a/aya/src/maps/xdp/dev_map_hash.rs b/aya/src/maps/xdp/dev_map_hash.rs index 8311a29b2..fcd184c50 100644 --- a/aya/src/maps/xdp/dev_map_hash.rs +++ b/aya/src/maps/xdp/dev_map_hash.rs @@ -6,7 +6,7 @@ use std::{ os::fd::{AsFd, AsRawFd}, }; -use aya_obj::generated::{bpf_devmap_val, bpf_devmap_val__bindgen_ty_1}; +use aya_obj::generated::bpf_devmap_val; use crate::{ maps::{check_kv_size, hash_map, IterableMap, MapData, MapError, MapIter, MapKeys}, @@ -15,7 +15,7 @@ use crate::{ FEATURES, }; -use super::dev_map::DevMapValue; +use super::{dev_map::DevMapValue, XdpMapError}; /// An hashmap of network devices. /// @@ -32,12 +32,15 @@ use super::dev_map::DevMapValue; /// use aya::maps::xdp::DevMapHash; /// /// let mut devmap = DevMapHash::try_from(bpf.map_mut("IFACES").unwrap())?; -/// let flags = 0; -/// let ifindex = 32u32; -/// devmap.insert(ifindex, ifindex, None, flags); +/// // Lookups with key 2 will redirect packets to interface with index 3 (e.g. eth1) +/// devmap.insert(2, 3, None, 0); /// /// # Ok::<(), aya::BpfError>(()) /// ``` +/// +/// # See also +/// +/// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_DEVMAP_HASH")] pub struct DevMapHash { inner: T, @@ -47,7 +50,7 @@ impl> DevMapHash { pub(crate) fn new(map: T) -> Result { let data = map.borrow(); - if FEATURES.devmap_hash_prog_id() { + if FEATURES.devmap_prog_id() { check_kv_size::(data)?; } else { check_kv_size::(data)?; @@ -56,7 +59,7 @@ impl> DevMapHash { Ok(Self { inner: map }) } - /// Returns the target ifindex and possible program for a given key. + /// Returns the target interface index and optional program for a given key. /// /// # Errors /// @@ -64,10 +67,10 @@ impl> DevMapHash { pub fn get(&self, key: u32, flags: u64) -> Result { let fd = self.inner.borrow().fd().as_fd(); - let value = if FEATURES.devmap_hash_prog_id() { + let value = if FEATURES.devmap_prog_id() { bpf_map_lookup_elem::<_, bpf_devmap_val>(fd, &key, flags).map(|value| { value.map(|value| DevMapValue { - ifindex: value.ifindex, + if_index: value.ifindex, // SAFETY: map writes use fd, map reads use id. // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/include/uapi/linux/bpf.h#L6228 prog_id: NonZeroU32::new(unsafe { value.bpf_prog.id }), @@ -76,7 +79,7 @@ impl> DevMapHash { } else { bpf_map_lookup_elem::<_, u32>(fd, &key, flags).map(|value| { value.map(|ifindex| DevMapValue { - ifindex, + if_index: ifindex, prog_id: None, }) }) @@ -105,44 +108,43 @@ impl> DevMapHash { /// /// When redirecting using `key`, packets will be transmitted by the interface with `ifindex`. /// - /// Another XDP program can be passed in that will be run before actual transmission. It can be - /// used to modify the packet before transmission with NIC specific data (MAC address update, - /// checksum computations, etc) or other purposes. + /// Starting from Linux kernel 5.8, another XDP program can be passed in that will be run before + /// actual transmission. It can be used to modify the packet before transmission with NIC + /// specific data (MAC address update, checksum computations, etc) or other purposes. /// - /// Note that only XDP programs with the `map = "devmap"` argument can be passed. See the - /// kernel-space `aya_bpf::xdp` for more information. + /// Note that, when using `aya-ebpf`, only XDP programs with the `map = "devmap"` argument can + /// be passed. See the kernel-space `aya_ebpf::xdp` for more information. Otherwise, the + /// program must be loaded with the `BPF_XDP_DEVMAP` attach type. /// /// # Errors /// /// Returns [`MapError::SyscallError`] if `bpf_map_update_elem` fails, - /// [`MapError::ProgIdNotSupported`] if the kernel does not support program ids and one is + /// [`MapError::ProgIdNotSupported`] if the kernel does not support chained programs and one is /// provided. pub fn insert( &mut self, key: u32, - ifindex: u32, + target_if_index: u32, program: Option<&ProgramFd>, flags: u64, - ) -> Result<(), MapError> { - if FEATURES.devmap_hash_prog_id() { - let value = bpf_devmap_val { - ifindex, - bpf_prog: bpf_devmap_val__bindgen_ty_1 { - // Default is valid as the kernel will only consider fd > 0: - // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L866 - // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L918 - fd: program - .map(|prog| prog.as_fd().as_raw_fd()) - .unwrap_or_default(), - }, - }; - hash_map::insert(self.inner.borrow_mut(), &key, &value, flags) + ) -> Result<(), XdpMapError> { + if FEATURES.devmap_prog_id() { + let mut value = unsafe { std::mem::zeroed::() }; + value.ifindex = target_if_index; + // Default is valid as the kernel will only consider fd > 0: + // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L866 + // https://github.com/torvalds/linux/blob/2dde18cd1d8fac735875f2e4987f11817cc0bc2c/kernel/bpf/devmap.c#L918 + value.bpf_prog.fd = program + .map(|prog| prog.as_fd().as_raw_fd()) + .unwrap_or_default(); + hash_map::insert(self.inner.borrow_mut(), &key, &value, flags)?; } else { if program.is_some() { - return Err(MapError::ProgIdNotSupported); + return Err(XdpMapError::ChainedProgramNotSupported); } - hash_map::insert(self.inner.borrow_mut(), &key, &ifindex, flags) + hash_map::insert(self.inner.borrow_mut(), &key, &target_if_index, flags)?; } + Ok(()) } /// Removes a value from the map. diff --git a/aya/src/maps/xdp/mod.rs b/aya/src/maps/xdp/mod.rs index 6120dc909..c4ca1c7c8 100644 --- a/aya/src/maps/xdp/mod.rs +++ b/aya/src/maps/xdp/mod.rs @@ -8,3 +8,18 @@ pub use cpu_map::CpuMap; pub use dev_map::DevMap; pub use dev_map_hash::DevMapHash; pub use xsk_map::XskMap; + +use super::MapError; +use thiserror::Error; + +#[derive(Error, Debug)] +/// Errors occuring from working with XDP Maps +pub enum XdpMapError { + /// Chained programs are not supported. + #[error("chained programs are not supported by the current kernel")] + ChainedProgramNotSupported, + + /// Map operation failed + #[error(transparent)] + MapError(#[from] MapError), +} diff --git a/aya/src/maps/xdp/xsk_map.rs b/aya/src/maps/xdp/xsk_map.rs index 99477dbdb..5382ae4c9 100644 --- a/aya/src/maps/xdp/xsk_map.rs +++ b/aya/src/maps/xdp/xsk_map.rs @@ -30,6 +30,10 @@ use crate::{ /// xskmap.set(0, socket_fd, 0); /// # Ok::<(), aya::BpfError>(()) /// ``` +/// +/// # See also +/// +/// Kernel documentation: #[doc(alias = "BPF_MAP_TYPE_XSKMAP")] pub struct XskMap { inner: T, diff --git a/bpf/aya-bpf/src/maps/xdp/cpu_map.rs b/bpf/aya-bpf/src/maps/xdp/cpu_map.rs index df1a32d21..d14f5047a 100644 --- a/bpf/aya-bpf/src/maps/xdp/cpu_map.rs +++ b/bpf/aya-bpf/src/maps/xdp/cpu_map.rs @@ -40,9 +40,9 @@ unsafe impl Sync for CpuMap {} impl CpuMap { /// Creates a [`CpuMap`] with a set maximum number of elements. /// - /// In a CPU Map, an entry represents a CPU core. Thus there should be as many entries as there - /// are CPU cores on the system. It can be set to zero here, and updated by userspace at - /// runtime. Refer to the userspace documentation for more information. + /// In a CPU map, an entry represents a CPU core. Thus there should be as many entries as there + /// are CPU cores on the system. `max_entries` can be set to zero here, and updated by userspace + /// at runtime. Refer to the userspace documentation for more information. /// /// # Examples ///