From 0edc13b4d4b87809b41b1a14101962a7defba65e Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Mon, 25 Sep 2023 00:33:17 +0200 Subject: [PATCH] bpf: add a shared try_redirect_map function for XDP maps --- bpf/aya-bpf/src/maps/xdp/cpu_map.rs | 14 ++++---------- bpf/aya-bpf/src/maps/xdp/dev_map.rs | 15 +++++---------- bpf/aya-bpf/src/maps/xdp/dev_map_hash.rs | 17 +++++------------ bpf/aya-bpf/src/maps/xdp/mod.rs | 24 ++++++++++++++++++++++++ bpf/aya-bpf/src/maps/xdp/xsk_map.rs | 15 +++++---------- xtask/public-api/aya-bpf.txt | 4 ++-- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/bpf/aya-bpf/src/maps/xdp/cpu_map.rs b/bpf/aya-bpf/src/maps/xdp/cpu_map.rs index 0179382c..133be94b 100644 --- a/bpf/aya-bpf/src/maps/xdp/cpu_map.rs +++ b/bpf/aya-bpf/src/maps/xdp/cpu_map.rs @@ -1,13 +1,14 @@ use core::{cell::UnsafeCell, mem}; -use aya_bpf_bindings::bindings::{bpf_cpumap_val, xdp_action::XDP_REDIRECT}; +use aya_bpf_bindings::bindings::bpf_cpumap_val; use crate::{ bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_CPUMAP}, - helpers::bpf_redirect_map, maps::PinningType, }; +use super::try_redirect_map; + /// An array of available CPUs. /// /// XDP programs can use this map to redirect packets to a target CPU for processing. @@ -114,13 +115,6 @@ impl CpuMap { /// ``` #[inline(always)] pub fn redirect(&self, index: u32, flags: u64) -> Result { - let ret = unsafe { bpf_redirect_map(self.def.get() as *mut _, index.into(), flags) }; - match ret.unsigned_abs() as u32 { - XDP_REDIRECT => Ok(XDP_REDIRECT), - // Return XDP_REDIRECT on success, or the value of the two lower bits of the flags - // argument on error. Thus I have no idea why it returns a long (i64) instead of - // something saner, hence the unsigned_abs. - ret => Err(ret), - } + try_redirect_map(&self.def, index, flags) } } diff --git a/bpf/aya-bpf/src/maps/xdp/dev_map.rs b/bpf/aya-bpf/src/maps/xdp/dev_map.rs index 6142d151..cfa44cb3 100644 --- a/bpf/aya-bpf/src/maps/xdp/dev_map.rs +++ b/bpf/aya-bpf/src/maps/xdp/dev_map.rs @@ -1,14 +1,16 @@ use core::{cell::UnsafeCell, mem, num::NonZeroU32, ptr::NonNull}; -use aya_bpf_bindings::bindings::{bpf_devmap_val, xdp_action::XDP_REDIRECT}; +use aya_bpf_bindings::bindings::bpf_devmap_val; use aya_bpf_cty::c_void; use crate::{ bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_DEVMAP}, - helpers::{bpf_map_lookup_elem, bpf_redirect_map}, + helpers::bpf_map_lookup_elem, maps::PinningType, }; +use super::try_redirect_map; + /// An array of network devices. /// /// XDP programs can use this map to redirect packets to other network deviecs. @@ -139,14 +141,7 @@ impl DevMap { /// ``` #[inline(always)] pub fn redirect(&self, index: u32, flags: u64) -> Result { - let ret = unsafe { bpf_redirect_map(self.def.get() as *mut _, index.into(), flags) }; - match ret.unsigned_abs() as u32 { - XDP_REDIRECT => Ok(XDP_REDIRECT), - // Return XDP_REDIRECT on success, or the value of the two lower bits of the flags - // argument on error. Thus I have no idea why it returns a long (i64) instead of - // something saner, hence the unsigned_abs. - ret => Err(ret), - } + try_redirect_map(&self.def, index, flags) } } diff --git a/bpf/aya-bpf/src/maps/xdp/dev_map_hash.rs b/bpf/aya-bpf/src/maps/xdp/dev_map_hash.rs index eb65b105..cbec50bb 100644 --- a/bpf/aya-bpf/src/maps/xdp/dev_map_hash.rs +++ b/bpf/aya-bpf/src/maps/xdp/dev_map_hash.rs @@ -1,15 +1,15 @@ use core::{cell::UnsafeCell, mem, num::NonZeroU32, ptr::NonNull}; -use aya_bpf_bindings::bindings::{bpf_devmap_val, xdp_action::XDP_REDIRECT}; +use aya_bpf_bindings::bindings::bpf_devmap_val; use aya_bpf_cty::c_void; use crate::{ bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH}, - helpers::{bpf_map_lookup_elem, bpf_redirect_map}, + helpers::bpf_map_lookup_elem, maps::PinningType, }; -use super::dev_map::DevMapValue; +use super::{dev_map::DevMapValue, try_redirect_map}; /// A map of network devices. /// @@ -140,14 +140,7 @@ impl DevMapHash { /// } /// ``` #[inline(always)] - pub fn redirect(&self, index: u32, flags: u64) -> Result { - let ret = unsafe { bpf_redirect_map(self.def.get() as *mut _, index.into(), flags) }; - match ret.unsigned_abs() as u32 { - XDP_REDIRECT => Ok(XDP_REDIRECT), - // Return XDP_REDIRECT on success, or the value of the two lower bits of the flags - // argument on error. Thus I have no idea why it returns a long (i64) instead of - // something saner, hence the unsigned_abs. - ret => Err(ret), - } + pub fn redirect(&self, key: u32, flags: u64) -> Result { + try_redirect_map(&self.def, key, flags) } } diff --git a/bpf/aya-bpf/src/maps/xdp/mod.rs b/bpf/aya-bpf/src/maps/xdp/mod.rs index b7ced7b5..5c8df0e5 100644 --- a/bpf/aya-bpf/src/maps/xdp/mod.rs +++ b/bpf/aya-bpf/src/maps/xdp/mod.rs @@ -3,7 +3,31 @@ mod dev_map; mod dev_map_hash; mod xsk_map; +use core::cell::UnsafeCell; + +use aya_bpf_bindings::{ + bindings::{bpf_map_def, xdp_action::XDP_REDIRECT}, + helpers::bpf_redirect_map, +}; pub use cpu_map::CpuMap; pub use dev_map::DevMap; pub use dev_map_hash::DevMapHash; pub use xsk_map::XskMap; + +/// Wrapper aroung the `bpf_redirect_map` function. +/// +/// # Return value +/// +/// - `Ok(XDP_REDIRECT)` on success. +/// - `Err(_)` of the lowest two bits of `flags` on failure. +#[inline(always)] +fn try_redirect_map(def: &UnsafeCell, key: u32, flags: u64) -> Result { + // Return XDP_REDIRECT on success, or the value of the two lower bits of the flags argument on + // error. Thus I have no idea why it returns a long (i64) instead of something saner, hence the + // unsigned_abs. + let ret = unsafe { bpf_redirect_map(def.get() as *mut _, key.into(), flags) }; + match ret.unsigned_abs() as u32 { + XDP_REDIRECT => Ok(XDP_REDIRECT), + ret => Err(ret), + } +} diff --git a/bpf/aya-bpf/src/maps/xdp/xsk_map.rs b/bpf/aya-bpf/src/maps/xdp/xsk_map.rs index f4546edb..455dfc84 100644 --- a/bpf/aya-bpf/src/maps/xdp/xsk_map.rs +++ b/bpf/aya-bpf/src/maps/xdp/xsk_map.rs @@ -1,14 +1,16 @@ use core::{cell::UnsafeCell, mem, ptr::NonNull}; -use aya_bpf_bindings::bindings::{bpf_xdp_sock, xdp_action::XDP_REDIRECT}; +use aya_bpf_bindings::bindings::bpf_xdp_sock; use aya_bpf_cty::c_void; use crate::{ bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_XSKMAP}, - helpers::{bpf_map_lookup_elem, bpf_redirect_map}, + helpers::bpf_map_lookup_elem, maps::PinningType, }; +use super::try_redirect_map; + /// An array of AF_XDP sockets. /// /// XDP programs can use this map to redirect packets to a target AF_XDP socket using the @@ -157,13 +159,6 @@ impl XskMap { /// ``` #[inline(always)] pub fn redirect(&self, index: u32, flags: u64) -> Result { - let ret = unsafe { bpf_redirect_map(self.def.get() as *mut _, index.into(), flags) }; - match ret.unsigned_abs() as u32 { - XDP_REDIRECT => Ok(XDP_REDIRECT), - // Return XDP_REDIRECT on success, or the value of the two lower bits of the flags - // argument on error. Thus I have no idea why it returns a long (i64) instead of - // something saner, hence the unsigned_abs. - ret => Err(ret), - } + try_redirect_map(&self.def, index, flags) } } diff --git a/xtask/public-api/aya-bpf.txt b/xtask/public-api/aya-bpf.txt index 4121839f..e221d2cc 100644 --- a/xtask/public-api/aya-bpf.txt +++ b/xtask/public-api/aya-bpf.txt @@ -621,7 +621,7 @@ pub fn aya_bpf::maps::DevMap::from(t: T) -> T impl aya_bpf::maps::DevMapHash pub fn aya_bpf::maps::DevMapHash::get(&self, key: u32) -> core::option::Option pub const fn aya_bpf::maps::DevMapHash::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMapHash -pub fn aya_bpf::maps::DevMapHash::redirect(&self, index: u32, flags: u64) -> core::result::Result +pub fn aya_bpf::maps::DevMapHash::redirect(&self, key: u32, flags: u64) -> core::result::Result pub const fn aya_bpf::maps::DevMapHash::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMapHash impl core::marker::Sync for aya_bpf::maps::DevMapHash impl core::marker::Send for aya_bpf::maps::DevMapHash @@ -783,7 +783,7 @@ pub fn aya_bpf::maps::DevMap::from(t: T) -> T impl aya_bpf::maps::DevMapHash pub fn aya_bpf::maps::DevMapHash::get(&self, key: u32) -> core::option::Option pub const fn aya_bpf::maps::DevMapHash::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMapHash -pub fn aya_bpf::maps::DevMapHash::redirect(&self, index: u32, flags: u64) -> core::result::Result +pub fn aya_bpf::maps::DevMapHash::redirect(&self, key: u32, flags: u64) -> core::result::Result pub const fn aya_bpf::maps::DevMapHash::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMapHash impl core::marker::Sync for aya_bpf::maps::DevMapHash impl core::marker::Send for aya_bpf::maps::DevMapHash