Merge pull request #527 from Tuetuopay/xdpmaps

Implement XDP map types
pull/793/head
Alessandro Decina 1 year ago committed by GitHub
commit 7f9ce062f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -128,6 +128,28 @@ pub fn sk_msg(attrs: TokenStream, item: TokenStream) -> TokenStream {
}
}
/// Marks a function as an eBPF XDP program that can be attached to a network interface.
///
/// On some NIC drivers, XDP probes are compatible with jumbo frames through the use of
/// multi-buffer packets. Programs can opt-in this support by passing the `frags` argument.
///
/// XDP programs can also be chained through the use of CPU maps and dev maps, but must opt-in
/// with the `map = "cpumap"` or `map = "devmap"` arguments.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.8.
///
/// # Examples
///
/// ```no_run
/// use aya_bpf::{bindings::xdp_action::XDP_PASS, macros::xdp, programs::XdpContext};
///
/// #[xdp(frags)]
/// pub fn xdp(ctx: XdpContext) -> u32 {
/// XDP_PASS
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn xdp(attrs: TokenStream, item: TokenStream) -> TokenStream {

@ -1,31 +1,52 @@
use std::borrow::Cow;
use proc_macro2::TokenStream;
use quote::quote;
use syn::{ItemFn, Result};
use syn::{Error, ItemFn, Result};
use crate::args::{err_on_unknown_args, pop_bool_arg, Args};
use crate::args::{err_on_unknown_args, pop_bool_arg, pop_string_arg, Args};
pub(crate) struct Xdp {
item: ItemFn,
frags: bool,
map: Option<XdpMap>,
}
#[derive(Clone, Copy)]
pub(crate) enum XdpMap {
CpuMap,
DevMap,
}
impl Xdp {
pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result<Xdp> {
let item = syn::parse2(item)?;
let mut args: Args = syn::parse2(attrs)?;
let frags = pop_bool_arg(&mut args, "frags");
let map = match pop_string_arg(&mut args, "map").as_deref() {
Some("cpumap") => Some(XdpMap::CpuMap),
Some("devmap") => Some(XdpMap::DevMap),
Some(name) => {
return Err(Error::new_spanned(
"map",
format!("Invalid value. Expected 'cpumap' or 'devmap', found '{name}'"),
))
}
None => None,
};
err_on_unknown_args(&args)?;
Ok(Xdp { item, frags })
Ok(Xdp { item, frags, map })
}
pub(crate) fn expand(&self) -> Result<TokenStream> {
let section_name: Cow<'_, _> = if self.frags {
"xdp.frags".into()
} else {
"xdp".into()
let mut section_name = vec![if self.frags { "xdp.frags" } else { "xdp" }];
match self.map {
Some(XdpMap::CpuMap) => section_name.push("cpumap"),
Some(XdpMap::DevMap) => section_name.push("devmap"),
None => (),
};
let section_name = section_name.join("/");
let fn_vis = &self.item.vis;
let fn_name = self.item.sig.ident.clone();
let item = &self.item;
@ -97,4 +118,122 @@ mod tests {
};
assert_eq!(expected.to_string(), expanded.to_string());
}
#[test]
fn test_xdp_cpumap() {
let prog = Xdp::parse(
parse_quote! { map = "cpumap" },
parse_quote! {
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp/cpumap"]
fn prog(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
return prog(::aya_bpf::programs::XdpContext::new(ctx));
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
}
};
assert_eq!(expected.to_string(), expanded.to_string());
}
#[test]
fn test_xdp_devmap() {
let prog = Xdp::parse(
parse_quote! { map = "devmap" },
parse_quote! {
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp/devmap"]
fn prog(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
return prog(::aya_bpf::programs::XdpContext::new(ctx));
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
}
};
assert_eq!(expected.to_string(), expanded.to_string());
}
#[test]
#[should_panic(expected = "Invalid value. Expected 'cpumap' or 'devmap', found 'badmap'")]
fn test_xdp_bad_map() {
Xdp::parse(
parse_quote! { map = "badmap" },
parse_quote! {
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
},
)
.unwrap();
}
#[test]
fn test_xdp_frags_cpumap() {
let prog = Xdp::parse(
parse_quote! { frags, map = "cpumap" },
parse_quote! {
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp.frags/cpumap"]
fn prog(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
return prog(::aya_bpf::programs::XdpContext::new(ctx));
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
}
};
assert_eq!(expected.to_string(), expanded.to_string());
}
#[test]
fn test_xdp_frags_devmap() {
let prog = Xdp::parse(
parse_quote! { frags, map = "devmap" },
parse_quote! {
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
},
)
.unwrap();
let expanded = prog.expand().unwrap();
let expected = quote! {
#[no_mangle]
#[link_section = "xdp.frags/devmap"]
fn prog(ctx: *mut ::aya_bpf::bindings::xdp_md) -> u32 {
return prog(::aya_bpf::programs::XdpContext::new(ctx));
fn prog(ctx: &mut ::aya_bpf::programs::XdpContext) -> i32 {
0
}
}
};
assert_eq!(expected.to_string(), expanded.to_string());
}
}

@ -176,6 +176,14 @@ impl Map {
}
}
/// Set the value size in bytes
pub fn set_value_size(&mut self, size: u32) {
match self {
Map::Legacy(m) => m.def.value_size = size,
Map::Btf(m) => m.def.value_size = size,
}
}
/// Returns the max entry number
pub fn max_entries(&self) -> u32 {
match self {

@ -19,6 +19,7 @@ use crate::{
btf::BtfFeatures,
generated::{BPF_CALL, BPF_JMP, BPF_K},
maps::{BtfMap, LegacyMap, Map, MINIMUM_MAP_SIZE},
programs::XdpAttachType,
relocation::*,
util::HashMap,
};
@ -47,17 +48,22 @@ pub struct Features {
bpf_perf_link: bool,
bpf_global_data: bool,
bpf_cookie: bool,
cpumap_prog_id: bool,
devmap_prog_id: bool,
btf: Option<BtfFeatures>,
}
impl Features {
#[doc(hidden)]
#[allow(clippy::too_many_arguments)]
pub fn new(
bpf_name: bool,
bpf_probe_read_kernel: bool,
bpf_perf_link: bool,
bpf_global_data: bool,
bpf_cookie: bool,
cpumap_prog_id: bool,
devmap_prog_id: bool,
btf: Option<BtfFeatures>,
) -> Self {
Self {
@ -66,6 +72,8 @@ impl Features {
bpf_perf_link,
bpf_global_data,
bpf_cookie,
cpumap_prog_id,
devmap_prog_id,
btf,
}
}
@ -95,6 +103,16 @@ impl Features {
self.bpf_cookie
}
/// Returns whether XDP CPU Maps support chained program IDs.
pub fn cpumap_prog_id(&self) -> bool {
self.cpumap_prog_id
}
/// Returns whether XDP Device Maps support chained program IDs.
pub fn devmap_prog_id(&self) -> bool {
self.devmap_prog_id
}
/// If BTF is supported, returns which BTF features are supported.
pub fn btf(&self) -> Option<&BtfFeatures> {
self.btf.as_ref()
@ -204,8 +222,6 @@ pub struct Function {
/// - `struct_ops+`
/// - `fmod_ret+`, `fmod_ret.s+`
/// - `iter+`, `iter.s+`
/// - `xdp.frags/cpumap`, `xdp/cpumap`
/// - `xdp.frags/devmap`, `xdp/devmap`
#[derive(Debug, Clone)]
#[allow(missing_docs)]
pub enum ProgramSection {
@ -221,6 +237,7 @@ pub enum ProgramSection {
SocketFilter,
Xdp {
frags: bool,
attach_type: XdpAttachType,
},
SkMsg,
SkSkbStreamParser,
@ -283,8 +300,19 @@ impl FromStr for ProgramSection {
"uprobe.s" => UProbe { sleepable: true },
"uretprobe" => URetProbe { sleepable: false },
"uretprobe.s" => URetProbe { sleepable: true },
"xdp" => Xdp { frags: false },
"xdp.frags" => Xdp { frags: true },
"xdp" | "xdp.frags" => Xdp {
frags: kind == "xdp.frags",
attach_type: match pieces.next() {
None => XdpAttachType::Interface,
Some("cpumap") => XdpAttachType::CpuMap,
Some("devmap") => XdpAttachType::DevMap,
Some(_) => {
return Err(ParseError::InvalidProgramSection {
section: section.to_owned(),
})
}
},
},
"tp_btf" => BtfTracePoint,
"tracepoint" | "tp" => TracePoint,
"socket" => SocketFilter,
@ -2012,7 +2040,7 @@ mod tests {
assert_matches!(
obj.parse_section(fake_section(
BpfSectionKind::Program,
"xdp/foo",
"xdp",
bytes_of(&fake_ins()),
None
)),
@ -2035,7 +2063,7 @@ mod tests {
assert_matches!(
obj.parse_section(fake_section(
BpfSectionKind::Program,
"xdp.frags/foo",
"xdp.frags",
bytes_of(&fake_ins()),
None
)),

@ -3,7 +3,9 @@
pub mod cgroup_sock;
pub mod cgroup_sock_addr;
pub mod cgroup_sockopt;
pub mod xdp;
pub use cgroup_sock::CgroupSockAttachType;
pub use cgroup_sock_addr::CgroupSockAddrAttachType;
pub use cgroup_sockopt::CgroupSockoptAttachType;
pub use xdp::XdpAttachType;

@ -0,0 +1,24 @@
//! XDP programs.
use crate::generated::bpf_attach_type;
/// Defines where to attach an `XDP` program.
#[derive(Copy, Clone, Debug)]
pub enum XdpAttachType {
/// Attach to a network interface.
Interface,
/// Attach to a cpumap. Requires kernel 5.9 or later.
CpuMap,
/// Attach to a devmap. Requires kernel 5.8 or later.
DevMap,
}
impl From<XdpAttachType> for bpf_attach_type {
fn from(value: XdpAttachType) -> Self {
match value {
XdpAttachType::Interface => bpf_attach_type::BPF_XDP,
XdpAttachType::CpuMap => bpf_attach_type::BPF_XDP_CPUMAP,
XdpAttachType::DevMap => bpf_attach_type::BPF_XDP_DEVMAP,
}
}
}

@ -12,6 +12,7 @@ edition = "2021"
rust-version = "1.66"
[dependencies]
assert_matches = { workspace = true }
async-io = { workspace = true, optional = true }
aya-obj = { workspace = true, features = ["std"] }
bitflags = { workspace = true }
@ -28,7 +29,6 @@ thiserror = { workspace = true }
tokio = { workspace = true, features = ["rt"], optional = true }
[dev-dependencies]
assert_matches = { workspace = true }
tempfile = { workspace = true }
[features]

@ -40,7 +40,8 @@ use crate::{
is_btf_datasec_supported, is_btf_decl_tag_supported, is_btf_enum64_supported,
is_btf_float_supported, is_btf_func_global_supported, is_btf_func_supported,
is_btf_supported, is_btf_type_tag_supported, is_perf_link_supported,
is_probe_read_kernel_supported, is_prog_name_supported, retry_with_verifier_logs,
is_probe_read_kernel_supported, is_prog_id_supported, is_prog_name_supported,
retry_with_verifier_logs,
},
util::{bytes_of, bytes_of_slice, possible_cpus, POSSIBLE_CPUS},
};
@ -93,6 +94,8 @@ fn detect_features() -> Features {
is_perf_link_supported(),
is_bpf_global_data_supported(),
is_bpf_cookie_supported(),
is_prog_id_supported(BPF_MAP_TYPE_CPUMAP),
is_prog_id_supported(BPF_MAP_TYPE_DEVMAP),
btf,
);
debug!("BPF Feature Detection: {:#?}", f);
@ -412,7 +415,10 @@ impl<'a> BpfLoader<'a> {
| ProgramSection::URetProbe { sleepable: _ }
| ProgramSection::TracePoint
| ProgramSection::SocketFilter
| ProgramSection::Xdp { frags: _ }
| ProgramSection::Xdp {
frags: _,
attach_type: _,
}
| ProgramSection::SkMsg
| ProgramSection::SkSkbStreamParser
| ProgramSection::SkSkbStreamVerdict
@ -473,6 +479,15 @@ impl<'a> BpfLoader<'a> {
}
}
}
match obj.map_type().try_into() {
Ok(BPF_MAP_TYPE_CPUMAP) => {
obj.set_value_size(if FEATURES.cpumap_prog_id() { 8 } else { 4 })
}
Ok(BPF_MAP_TYPE_DEVMAP | BPF_MAP_TYPE_DEVMAP_HASH) => {
obj.set_value_size(if FEATURES.devmap_prog_id() { 8 } else { 4 })
}
_ => (),
}
let btf_fd = btf_fd.as_deref().map(|fd| fd.as_fd());
let mut map = match obj.pinning() {
PinningType::None => MapData::create(obj, &name, btf_fd)?,
@ -556,13 +571,18 @@ impl<'a> BpfLoader<'a> {
ProgramSection::SocketFilter => Program::SocketFilter(SocketFilter {
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
}),
ProgramSection::Xdp { frags, .. } => {
ProgramSection::Xdp {
frags, attach_type, ..
} => {
let mut data =
ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level);
if *frags {
data.flags = BPF_F_XDP_HAS_FRAGS;
}
Program::Xdp(Xdp { data })
Program::Xdp(Xdp {
data,
attach_type: *attach_type,
})
}
ProgramSection::SkMsg => Program::SkMsg(SkMsg {
data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level),
@ -707,6 +727,10 @@ fn parse_map(data: (String, MapData)) -> Result<(String, Map), BpfError> {
BPF_MAP_TYPE_STACK => Map::Stack(map),
BPF_MAP_TYPE_STACK_TRACE => Map::StackTraceMap(map),
BPF_MAP_TYPE_QUEUE => Map::Queue(map),
BPF_MAP_TYPE_CPUMAP => Map::CpuMap(map),
BPF_MAP_TYPE_DEVMAP => Map::DevMap(map),
BPF_MAP_TYPE_DEVMAP_HASH => Map::DevMapHash(map),
BPF_MAP_TYPE_XSKMAP => Map::XskMap(map),
m => {
warn!("The map {name} is of type {:#?} which is currently unsupported in Aya, use `allow_unsupported_maps()` to load it anyways", m);
Map::Unsupported(map)

@ -83,6 +83,7 @@ pub mod queue;
pub mod sock;
pub mod stack;
pub mod stack_trace;
pub mod xdp;
pub use array::{Array, PerCpuArray, ProgramArray};
pub use bloom_filter::BloomFilter;
@ -96,6 +97,7 @@ pub use queue::Queue;
pub use sock::{SockHash, SockMap};
pub use stack::Stack;
pub use stack_trace::StackTraceMap;
pub use xdp::{CpuMap, DevMap, DevMapHash, XskMap};
#[derive(Error, Debug)]
/// Errors occuring from working with Maps
@ -179,6 +181,10 @@ pub enum MapError {
error: PinError,
},
/// Program IDs are not supported
#[error("program ids are not supported by the current kernel")]
ProgIdNotSupported,
/// Unsupported Map type
#[error("Unsupported map type found {map_type}")]
Unsupported {
@ -235,37 +241,45 @@ fn maybe_warn_rlimit() {
/// eBPF map types.
#[derive(Debug)]
pub enum Map {
/// A [`Array`] map
/// An [`Array`] map.
Array(MapData),
/// A [`PerCpuArray`] map
/// A [`PerCpuArray`] map.
PerCpuArray(MapData),
/// A [`ProgramArray`] map
/// A [`ProgramArray`] map.
ProgramArray(MapData),
/// A [`HashMap`] map
/// A [`HashMap`] map.
HashMap(MapData),
/// A [`PerCpuHashMap`] map
/// A [`PerCpuHashMap`] map.
PerCpuHashMap(MapData),
/// A [`HashMap`] map that uses a LRU eviction policy.
LruHashMap(MapData),
/// A [`PerCpuHashMap`] map that uses a LRU eviction policy.
PerCpuLruHashMap(MapData),
/// A [`PerfEventArray`] map
/// A [`PerfEventArray`] map.
PerfEventArray(MapData),
/// A [`SockMap`] map
/// A [`SockMap`] map.
SockMap(MapData),
/// A [`SockHash`] map
/// A [`SockHash`] map.
SockHash(MapData),
/// A [`BloomFilter`] map
/// A [`BloomFilter`] map.
BloomFilter(MapData),
/// A [`LpmTrie`] map
/// A [`LpmTrie`] map.
LpmTrie(MapData),
/// A [`Stack`] map
/// A [`Stack`] map.
Stack(MapData),
/// A [`StackTraceMap`] map
/// A [`StackTraceMap`] map.
StackTraceMap(MapData),
/// A [`Queue`] map
/// A [`Queue`] map.
Queue(MapData),
/// An unsupported map type
/// A [`CpuMap`] map.
CpuMap(MapData),
/// A [`DevMap`] map.
DevMap(MapData),
/// A [`DevMapHash`] map.
DevMapHash(MapData),
/// A [`XskMap`] map.
XskMap(MapData),
/// An unsupported map type.
Unsupported(MapData),
}
@ -288,6 +302,10 @@ impl Map {
Self::Stack(map) => map.obj.map_type(),
Self::StackTraceMap(map) => map.obj.map_type(),
Self::Queue(map) => map.obj.map_type(),
Self::CpuMap(map) => map.obj.map_type(),
Self::DevMap(map) => map.obj.map_type(),
Self::DevMapHash(map) => map.obj.map_type(),
Self::XskMap(map) => map.obj.map_type(),
Self::Unsupported(map) => map.obj.map_type(),
}
}
@ -347,6 +365,10 @@ impl_try_from_map!(() {
SockMap,
PerfEventArray,
StackTraceMap,
CpuMap,
DevMap,
DevMapHash,
XskMap,
});
#[cfg(any(feature = "async_tokio", feature = "async_std"))]

@ -0,0 +1,195 @@
//! An array of available CPUs.
use std::{
borrow::{Borrow, BorrowMut},
num::NonZeroU32,
os::fd::{AsFd, AsRawFd},
};
use aya_obj::generated::bpf_cpumap_val;
use crate::{
maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError},
programs::ProgramFd,
sys::{bpf_map_lookup_elem, bpf_map_update_elem, SyscallError},
Pod, FEATURES,
};
use super::XdpMapError;
/// An array of available CPUs.
///
/// XDP programs can use this map to redirect packets to a target
/// CPU for processing.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.15.
///
/// # Examples
/// ```no_run
/// # 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", 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 0..ncpus {
/// cpumap.set(i, queue_size, None, flags);
/// }
///
/// # Ok::<(), aya::BpfError>(())
/// ```
///
/// # See also
///
/// Kernel documentation: <https://docs.kernel.org/next/bpf/map_cpumap.html>
#[doc(alias = "BPF_MAP_TYPE_CPUMAP")]
pub struct CpuMap<T> {
inner: T,
}
impl<T: Borrow<MapData>> CpuMap<T> {
pub(crate) fn new(map: T) -> Result<Self, MapError> {
let data = map.borrow();
if FEATURES.cpumap_prog_id() {
check_kv_size::<u32, bpf_cpumap_val>(data)?;
} else {
check_kv_size::<u32, u32>(data)?;
}
Ok(Self { inner: map })
}
/// Returns the number of elements in the array.
///
/// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
pub fn len(&self) -> u32 {
self.inner.borrow().obj.max_entries()
}
/// Returns the queue size and optional program for a given CPU index.
///
/// # Errors
///
/// Returns [`MapError::OutOfBounds`] if `cpu_index` is out of bounds,
/// [`MapError::SyscallError`] if `bpf_map_lookup_elem` fails.
pub fn get(&self, cpu_index: u32, flags: u64) -> Result<CpuMapValue, MapError> {
let data = self.inner.borrow();
check_bounds(data, cpu_index)?;
let fd = data.fd().as_fd();
let value = if FEATURES.cpumap_prog_id() {
bpf_map_lookup_elem::<_, bpf_cpumap_val>(fd, &cpu_index, flags).map(|value| {
value.map(|value| CpuMapValue {
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 }),
})
})
} else {
bpf_map_lookup_elem::<_, u32>(fd, &cpu_index, flags).map(|value| {
value.map(|qsize| CpuMapValue {
queue_size: qsize,
prog_id: None,
})
})
};
value
.map_err(|(_, io_error)| SyscallError {
call: "bpf_map_lookup_elem",
io_error,
})?
.ok_or(MapError::KeyNotFound)
}
/// An iterator over the elements of the map.
pub fn iter(&self) -> impl Iterator<Item = Result<CpuMapValue, MapError>> + '_ {
(0..self.len()).map(move |i| self.get(i, 0))
}
}
impl<T: BorrowMut<MapData>> CpuMap<T> {
/// Sets the queue size at the given CPU index, and optionally a chained program.
///
/// When sending the packet to the CPU at the given index, the kernel will queue up to
/// `queue_size` packets before dropping them.
///
/// 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.
///
/// The chained program must be loaded with the `BPF_XDP_CPUMAP` attach type. When using
/// `aya-ebpf`, that means XDP programs that specify the `map = "cpumap"` argument. See the
/// kernel-space `aya_ebpf::xdp` for more information.
///
/// # Errors
///
/// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
/// 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<(), 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 mut value = unsafe { std::mem::zeroed::<bpf_cpumap_val>() };
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(XdpMapError::ChainedProgramNotSupported);
}
bpf_map_update_elem(fd, Some(&cpu_index), &queue_size, flags)
};
res.map_err(|(_, io_error)| {
MapError::from(SyscallError {
call: "bpf_map_update_elem",
io_error,
})
})?;
Ok(())
}
}
impl<T: Borrow<MapData>> IterableMap<u32, CpuMapValue> for CpuMap<T> {
fn map(&self) -> &MapData {
self.inner.borrow()
}
fn get(&self, key: &u32) -> Result<CpuMapValue, MapError> {
self.get(*key, 0)
}
}
unsafe impl Pod for bpf_cpumap_val {}
#[derive(Clone, Copy, Debug)]
/// The value of a CPU map.
pub struct CpuMapValue {
/// Size of the for the CPU.
pub queue_size: u32,
/// Chained XDP program ID.
pub prog_id: Option<NonZeroU32>,
}

@ -0,0 +1,187 @@
//! An array of network devices.
use std::{
borrow::{Borrow, BorrowMut},
num::NonZeroU32,
os::fd::{AsFd, AsRawFd},
};
use aya_obj::generated::bpf_devmap_val;
use crate::{
maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError},
programs::ProgramFd,
sys::{bpf_map_lookup_elem, bpf_map_update_elem, SyscallError},
Pod, FEATURES,
};
use super::XdpMapError;
/// An array of network devices.
///
/// XDP programs can use this map to redirect to other network
/// devices.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.14.
///
/// # Examples
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[])?;
/// use aya::maps::xdp::DevMap;
///
/// let mut devmap = DevMap::try_from(bpf.map_mut("IFACES").unwrap())?;
/// // 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: <https://docs.kernel.org/next/bpf/map_devmap.html>
#[doc(alias = "BPF_MAP_TYPE_DEVMAP")]
pub struct DevMap<T> {
inner: T,
}
impl<T: Borrow<MapData>> DevMap<T> {
pub(crate) fn new(map: T) -> Result<Self, MapError> {
let data = map.borrow();
if FEATURES.devmap_prog_id() {
check_kv_size::<u32, bpf_devmap_val>(data)?;
} else {
check_kv_size::<u32, u32>(data)?;
}
Ok(Self { inner: map })
}
/// Returns the number of elements in the array.
///
/// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
pub fn len(&self) -> u32 {
self.inner.borrow().obj.max_entries()
}
/// Returns the target interface index and optional program at a given index.
///
/// # Errors
///
/// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
/// if `bpf_map_lookup_elem` fails.
pub fn get(&self, index: u32, flags: u64) -> Result<DevMapValue, MapError> {
let data = self.inner.borrow();
check_bounds(data, index)?;
let fd = data.fd().as_fd();
let value = if FEATURES.devmap_prog_id() {
bpf_map_lookup_elem::<_, bpf_devmap_val>(fd, &index, flags).map(|value| {
value.map(|value| DevMapValue {
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 }),
})
})
} else {
bpf_map_lookup_elem::<_, u32>(fd, &index, flags).map(|value| {
value.map(|ifindex| DevMapValue {
if_index: ifindex,
prog_id: None,
})
})
};
value
.map_err(|(_, io_error)| SyscallError {
call: "bpf_map_lookup_elem",
io_error,
})?
.ok_or(MapError::KeyNotFound)
}
/// An iterator over the elements of the array.
pub fn iter(&self) -> impl Iterator<Item = Result<DevMapValue, MapError>> + '_ {
(0..self.len()).map(move |i| self.get(i, 0))
}
}
impl<T: BorrowMut<MapData>> DevMap<T> {
/// Sets the target interface index at index, and optionally a chained program.
///
/// When redirecting using `index`, packets will be transmitted by the interface with
/// `target_if_index`.
///
/// 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.
///
/// The chained program must be loaded with the `BPF_XDP_DEVMAP` attach type. When using
/// `aya-ebpf`, that means XDP programs that specify the `map = "devmap"` argument. See the
/// kernel-space `aya_ebpf::xdp` for more information.
///
/// # 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 chained programs and one is provided.
pub fn set(
&mut self,
index: u32,
target_if_index: u32,
program: Option<&ProgramFd>,
flags: u64,
) -> 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 mut value = unsafe { std::mem::zeroed::<bpf_devmap_val>() };
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(XdpMapError::ChainedProgramNotSupported);
}
bpf_map_update_elem(fd, Some(&index), &target_if_index, flags)
};
res.map_err(|(_, io_error)| {
MapError::from(SyscallError {
call: "bpf_map_update_elem",
io_error,
})
})?;
Ok(())
}
}
impl<T: Borrow<MapData>> IterableMap<u32, DevMapValue> for DevMap<T> {
fn map(&self) -> &MapData {
self.inner.borrow()
}
fn get(&self, key: &u32) -> Result<DevMapValue, MapError> {
self.get(*key, 0)
}
}
unsafe impl Pod for bpf_devmap_val {}
#[derive(Clone, Copy, Debug)]
/// The value of a device map.
pub struct DevMapValue {
/// Target interface index to redirect to.
pub if_index: u32,
/// Chained XDP program ID.
pub prog_id: Option<NonZeroU32>,
}

@ -0,0 +1,168 @@
//! An hashmap of network devices.
use std::{
borrow::{Borrow, BorrowMut},
num::NonZeroU32,
os::fd::{AsFd, AsRawFd},
};
use aya_obj::generated::bpf_devmap_val;
use crate::{
maps::{check_kv_size, hash_map, IterableMap, MapData, MapError, MapIter, MapKeys},
programs::ProgramFd,
sys::{bpf_map_lookup_elem, SyscallError},
FEATURES,
};
use super::{dev_map::DevMapValue, XdpMapError};
/// An hashmap of network devices.
///
/// XDP programs can use this map to redirect to other network
/// devices.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 5.4.
///
/// # Examples
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[])?;
/// use aya::maps::xdp::DevMapHash;
///
/// let mut devmap = DevMapHash::try_from(bpf.map_mut("IFACES").unwrap())?;
/// // 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: <https://docs.kernel.org/next/bpf/map_devmap.html>
#[doc(alias = "BPF_MAP_TYPE_DEVMAP_HASH")]
pub struct DevMapHash<T> {
inner: T,
}
impl<T: Borrow<MapData>> DevMapHash<T> {
pub(crate) fn new(map: T) -> Result<Self, MapError> {
let data = map.borrow();
if FEATURES.devmap_prog_id() {
check_kv_size::<u32, bpf_devmap_val>(data)?;
} else {
check_kv_size::<u32, u32>(data)?;
}
Ok(Self { inner: map })
}
/// Returns the target interface index and optional program for a given key.
///
/// # Errors
///
/// Returns [`MapError::SyscallError`] if `bpf_map_lookup_elem` fails.
pub fn get(&self, key: u32, flags: u64) -> Result<DevMapValue, MapError> {
let fd = self.inner.borrow().fd().as_fd();
let value = if FEATURES.devmap_prog_id() {
bpf_map_lookup_elem::<_, bpf_devmap_val>(fd, &key, flags).map(|value| {
value.map(|value| DevMapValue {
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 }),
})
})
} else {
bpf_map_lookup_elem::<_, u32>(fd, &key, flags).map(|value| {
value.map(|ifindex| DevMapValue {
if_index: ifindex,
prog_id: None,
})
})
};
value
.map_err(|(_, io_error)| SyscallError {
call: "bpf_map_lookup_elem",
io_error,
})?
.ok_or(MapError::KeyNotFound)
}
/// An iterator over the elements of the devmap in arbitrary order.
pub fn iter(&self) -> MapIter<'_, u32, DevMapValue, Self> {
MapIter::new(self)
}
/// An iterator visiting all keys in arbitrary order.
pub fn keys(&self) -> MapKeys<'_, u32> {
MapKeys::new(self.inner.borrow())
}
}
impl<T: BorrowMut<MapData>> DevMapHash<T> {
/// Inserts an ifindex and optionally a chained program in the map.
///
/// When redirecting using `key`, packets will be transmitted by the interface with `ifindex`.
///
/// 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.
///
/// The chained program must be loaded with the `BPF_XDP_DEVMAP` attach type. When using
/// `aya-ebpf`, that means XDP programs that specify the `map = "devmap"` argument. See the
/// kernel-space `aya_ebpf::xdp` for more information.
///
/// # Errors
///
/// Returns [`MapError::SyscallError`] if `bpf_map_update_elem` fails,
/// [`MapError::ProgIdNotSupported`] if the kernel does not support chained programs and one is
/// provided.
pub fn insert(
&mut self,
key: u32,
target_if_index: u32,
program: Option<&ProgramFd>,
flags: u64,
) -> Result<(), XdpMapError> {
if FEATURES.devmap_prog_id() {
let mut value = unsafe { std::mem::zeroed::<bpf_devmap_val>() };
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(XdpMapError::ChainedProgramNotSupported);
}
hash_map::insert(self.inner.borrow_mut(), &key, &target_if_index, flags)?;
}
Ok(())
}
/// Removes a value from the map.
///
/// # Errors
///
/// Returns [`MapError::SyscallError`] if `bpf_map_delete_elem` fails.
pub fn remove(&mut self, key: u32) -> Result<(), MapError> {
hash_map::remove(self.inner.borrow_mut(), &key)
}
}
impl<T: Borrow<MapData>> IterableMap<u32, DevMapValue> for DevMapHash<T> {
fn map(&self) -> &MapData {
self.inner.borrow()
}
fn get(&self, key: &u32) -> Result<DevMapValue, MapError> {
self.get(*key, 0)
}
}

@ -0,0 +1,25 @@
//! XDP maps.
mod cpu_map;
mod dev_map;
mod dev_map_hash;
mod xsk_map;
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),
}

@ -0,0 +1,81 @@
//! An array of AF_XDP sockets.
use std::{
borrow::{Borrow, BorrowMut},
os::fd::{AsFd, AsRawFd, RawFd},
};
use crate::{
maps::{check_bounds, check_kv_size, MapData, MapError},
sys::{bpf_map_update_elem, SyscallError},
};
/// An array of AF_XDP sockets.
///
/// XDP programs can use this map to redirect packets to a target
/// AF_XDP socket using the `XDP_REDIRECT` action.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.18.
///
/// # Examples
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[])?;
/// # let socket_fd = 1;
/// use aya::maps::XskMap;
///
/// let mut xskmap = XskMap::try_from(bpf.map_mut("SOCKETS").unwrap())?;
/// // socket_fd is the RawFd of an AF_XDP socket
/// xskmap.set(0, socket_fd, 0);
/// # Ok::<(), aya::BpfError>(())
/// ```
///
/// # See also
///
/// Kernel documentation: <https://docs.kernel.org/next/bpf/map_xskmap.html>
#[doc(alias = "BPF_MAP_TYPE_XSKMAP")]
pub struct XskMap<T> {
inner: T,
}
impl<T: Borrow<MapData>> XskMap<T> {
pub(crate) fn new(map: T) -> Result<Self, MapError> {
let data = map.borrow();
check_kv_size::<u32, RawFd>(data)?;
Ok(Self { inner: map })
}
/// Returns the number of elements in the array.
///
/// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side.
pub fn len(&self) -> u32 {
self.inner.borrow().obj.max_entries()
}
}
impl<T: BorrowMut<MapData>> XskMap<T> {
/// Sets the `AF_XDP` socket at a given index.
///
/// When redirecting a packet, the `AF_XDP` socket at `index` will recieve the packet. Note
/// that it will do so only if the socket is bound to the same queue the packet was recieved
/// on.
///
/// # Errors
///
/// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
/// if `bpf_map_update_elem` fails.
pub fn set(&mut self, index: u32, socket_fd: impl AsRawFd, flags: u64) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
check_bounds(data, index)?;
let fd = data.fd().as_fd();
bpf_map_update_elem(fd, Some(&index), &socket_fd.as_raw_fd(), flags).map_err(
|(_, io_error)| SyscallError {
call: "bpf_map_update_elem",
io_error,
},
)?;
Ok(())
}
}

@ -879,7 +879,6 @@ macro_rules! impl_from_pin {
impl_from_pin!(
TracePoint,
SocketFilter,
Xdp,
SkMsg,
CgroupSysctl,
LircMode2,

@ -12,18 +12,21 @@ use std::{
hash::Hash,
io,
os::fd::{AsFd as _, AsRawFd as _, BorrowedFd, RawFd},
path::Path,
};
use thiserror::Error;
use crate::{
generated::{
bpf_attach_type, bpf_link_type, bpf_prog_type, XDP_FLAGS_DRV_MODE, XDP_FLAGS_HW_MODE,
XDP_FLAGS_REPLACE, XDP_FLAGS_SKB_MODE, XDP_FLAGS_UPDATE_IF_NOEXIST,
bpf_link_type, bpf_prog_type, XDP_FLAGS_DRV_MODE, XDP_FLAGS_HW_MODE, XDP_FLAGS_REPLACE,
XDP_FLAGS_SKB_MODE, XDP_FLAGS_UPDATE_IF_NOEXIST,
},
obj::programs::XdpAttachType,
programs::{
define_link_wrapper, load_program, FdLink, Link, LinkError, ProgramData, ProgramError,
},
sys::{bpf_link_create, bpf_link_get_info_by_fd, bpf_link_update, netlink_set_xdp_fd},
VerifierLogLevel,
};
/// The type returned when attaching an [`Xdp`] program fails on kernels `< 5.9`.
@ -80,12 +83,13 @@ bitflags::bitflags! {
#[doc(alias = "BPF_PROG_TYPE_XDP")]
pub struct Xdp {
pub(crate) data: ProgramData<XdpLink>,
pub(crate) attach_type: XdpAttachType,
}
impl Xdp {
/// Loads the program inside the kernel.
pub fn load(&mut self) -> Result<(), ProgramError> {
self.data.expected_attach_type = Some(bpf_attach_type::BPF_XDP);
self.data.expected_attach_type = Some(self.attach_type.into());
load_program(bpf_prog_type::BPF_PROG_TYPE_XDP, &mut self.data)
}
@ -133,10 +137,18 @@ impl Xdp {
let prog_fd = prog_fd.as_fd();
if KernelVersion::current().unwrap() >= KernelVersion::new(5, 9, 0) {
// Unwrap safety: the function starts with `self.fd()?` that will succeed if and only
// if the program has been loaded, i.e. there is an fd. We get one by:
// - Using `Xdp::from_pin` that sets `expected_attach_type`
// - Calling `Xdp::attach` that sets `expected_attach_type`, as geting an `Xdp`
// instance trhough `Xdp:try_from(Program)` does not set any fd.
// So, in all cases where we have an fd, we have an expected_attach_type. Thus, if we
// reach this point, expected_attach_type is guaranteed to be Some(_).
let attach_type = self.data.expected_attach_type.unwrap();
let link_fd = bpf_link_create(
prog_fd,
LinkTarget::IfIndex(if_index),
bpf_attach_type::BPF_XDP,
attach_type,
None,
flags.bits(),
)
@ -163,6 +175,21 @@ impl Xdp {
}
}
/// Creates a program from a pinned entry on a bpffs.
///
/// Existing links will not be populated. To work with existing links you should use [`crate::programs::links::PinnedLink`].
///
/// On drop, any managed links are detached and the program is unloaded. This will not result in
/// the program being unloaded from the kernel if it is still pinned.
pub fn from_pin<P: AsRef<Path>>(
path: P,
attach_type: XdpAttachType,
) -> Result<Self, ProgramError> {
let mut data = ProgramData::from_pinned_path(path, VerifierLogLevel::default())?;
data.expected_attach_type = Some(attach_type.into());
Ok(Self { data, attach_type })
}
/// Detaches the program.
///
/// See [Xdp::attach].

@ -8,6 +8,7 @@ use std::{
};
use crate::util::KernelVersion;
use assert_matches::assert_matches;
use libc::{c_char, c_long, ENOENT, ENOSPC};
use obj::{
btf::{BtfEnum64, Enum64},
@ -793,6 +794,28 @@ pub(crate) fn is_bpf_cookie_supported() -> bool {
bpf_prog_load(&mut attr).is_ok()
}
/// Tests whether CpuMap, DevMap and DevMapHash support program ids
pub(crate) fn is_prog_id_supported(map_type: bpf_map_type) -> bool {
assert_matches!(
map_type,
bpf_map_type::BPF_MAP_TYPE_CPUMAP
| bpf_map_type::BPF_MAP_TYPE_DEVMAP
| bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH
);
let mut attr = unsafe { mem::zeroed::<bpf_attr>() };
let u = unsafe { &mut attr.__bindgen_anon_1 };
u.map_type = map_type as u32;
u.key_size = 4;
u.value_size = 8; // 4 for CPU ID, 8 for CPU ID + prog ID
u.max_entries = 1;
u.map_flags = 0;
// SAFETY: BPF_MAP_CREATE returns a new file descriptor.
unsafe { fd_sys_bpf(bpf_cmd::BPF_MAP_CREATE, &mut attr) }.is_ok()
}
pub(crate) fn is_btf_supported() -> bool {
let mut btf = Btf::new();
let name_offset = btf.add_string("int");
@ -1072,4 +1095,28 @@ mod tests {
let supported = is_perf_link_supported();
assert!(!supported);
}
#[test]
fn test_prog_id_supported() {
override_syscall(|_call| Ok(42));
// Ensure that the three map types we can check are accepted
let supported = is_prog_id_supported(bpf_map_type::BPF_MAP_TYPE_CPUMAP);
assert!(supported);
let supported = is_prog_id_supported(bpf_map_type::BPF_MAP_TYPE_DEVMAP);
assert!(supported);
let supported = is_prog_id_supported(bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH);
assert!(supported);
override_syscall(|_call| Err((-1, io::Error::from_raw_os_error(EINVAL))));
let supported = is_prog_id_supported(bpf_map_type::BPF_MAP_TYPE_CPUMAP);
assert!(!supported);
}
#[test]
#[should_panic = "assertion failed: `BPF_MAP_TYPE_HASH` does not match `bpf_map_type::BPF_MAP_TYPE_CPUMAP | bpf_map_type::BPF_MAP_TYPE_DEVMAP |
bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH`"]
fn test_prog_id_supported_reject_types() {
is_prog_id_supported(bpf_map_type::BPF_MAP_TYPE_HASH);
}
}

@ -17,6 +17,7 @@ pub mod sock_hash;
pub mod sock_map;
pub mod stack;
pub mod stack_trace;
pub mod xdp;
pub use array::Array;
pub use bloom_filter::BloomFilter;
@ -30,3 +31,4 @@ pub use sock_hash::SockHash;
pub use sock_map::SockMap;
pub use stack::Stack;
pub use stack_trace::StackTrace;
pub use xdp::{CpuMap, DevMap, DevMapHash, XskMap};

@ -0,0 +1,120 @@
use core::{cell::UnsafeCell, mem};
use aya_bpf_bindings::bindings::bpf_cpumap_val;
use crate::{
bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_CPUMAP},
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.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.15.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::CpuMap, programs::XdpContext};
///
/// #[map]
/// static MAP: CpuMap = CpuMap::with_max_entries(8, 0);
///
/// #[xdp]
/// fn xdp(_ctx: XdpContext) -> i32 {
/// // Redirect to CPU 7 or drop packet if no entry found.
/// MAP.redirect(7, xdp_action::XDP_DROP as u64)
/// }
/// ```
#[repr(transparent)]
pub struct CpuMap {
def: UnsafeCell<bpf_map_def>,
}
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. `max_entries` can be set to zero here, and updated by userspace
/// at runtime. Refer to the userspace documentation for more information.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::CpuMap};
///
/// #[map]
/// static MAP: CpuMap = CpuMap::with_max_entries(8, 0);
/// ```
pub const fn with_max_entries(max_entries: u32, flags: u32) -> CpuMap {
CpuMap {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_CPUMAP,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<bpf_cpumap_val>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::None as u32,
}),
}
}
/// Creates a [`CpuMap`] with a set maximum number of elements that can be pinned to the BPF
/// File System (bpffs).
///
/// See [`CpuMap::with_max_entries`] for more information.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::CpuMap};
///
/// #[map]
/// static MAP: CpuMap = CpuMap::pinned(8, 0);
/// ```
pub const fn pinned(max_entries: u32, flags: u32) -> CpuMap {
CpuMap {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_CPUMAP,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<bpf_cpumap_val>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::ByName as u32,
}),
}
}
/// Redirects the current packet on the CPU at `index`.
///
/// The lower two bits of `flags` are used for the return code if the map lookup fails, which
/// can be used as the XDP program's return code if a CPU cannot be found.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::CpuMap, programs::XdpContext};
///
/// #[map]
/// static MAP: CpuMap = CpuMap::with_max_entries(8, 0);
///
/// #[xdp]
/// fn xdp(_ctx: XdpContext) -> u32 {
/// // Redirect to CPU 7 or drop packet if no entry found.
/// MAP.redirect(7, 0).unwrap_or(xdp_action::XDP_DROP)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, index: u32, flags: u64) -> Result<u32, u32> {
try_redirect_map(&self.def, index, flags)
}
}

@ -0,0 +1,155 @@
use core::{cell::UnsafeCell, mem, num::NonZeroU32, ptr::NonNull};
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,
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.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.14.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::DevMap, programs::XdpContext};
///
/// #[map]
/// static MAP: DevMap = DevMap::with_max_entries(1, 0);
///
/// #[xdp]
/// fn xdp(_ctx: XdpContext) -> i32 {
/// MAP.redirect(0, xdp_action::XDP_PASS as u64)
/// }
/// ```
#[repr(transparent)]
pub struct DevMap {
def: UnsafeCell<bpf_map_def>,
}
unsafe impl Sync for DevMap {}
impl DevMap {
/// Creates a [`DevMap`] with a set maximum number of elements.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::DevMap};
///
/// #[map]
/// static MAP: DevMap = DevMap::with_max_entries(8, 0);
/// ```
pub const fn with_max_entries(max_entries: u32, flags: u32) -> DevMap {
DevMap {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_DEVMAP,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<bpf_devmap_val>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::None as u32,
}),
}
}
/// Creates a [`DevMap`] with a set maximum number of elements that can be pinned to the BPF
/// File System (bpffs).
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::DevMap};
///
/// #[map]
/// static MAP: DevMap = DevMap::pinned(8, 0);
/// ```
pub const fn pinned(max_entries: u32, flags: u32) -> DevMap {
DevMap {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_DEVMAP,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<bpf_devmap_val>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::ByName as u32,
}),
}
}
/// Retrieves the interface index at `index` in the array.
///
/// To actually redirect a packet, see [`DevMap::redirect`].
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::DevMap};
///
/// #[map]
/// static MAP: DevMap = DevMap::with_max_entries(1, 0);
///
/// let target_if_index = MAP.get(0).target_if_index;
///
/// // redirect to if_index
/// ```
#[inline(always)]
pub fn get(&self, index: u32) -> Option<DevMapValue> {
unsafe {
let value = bpf_map_lookup_elem(
self.def.get() as *mut _,
&index as *const _ as *const c_void,
);
NonNull::new(value as *mut bpf_devmap_val).map(|p| DevMapValue {
if_index: p.as_ref().ifindex,
// SAFETY: map writes use fd, map reads use id.
// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/bpf.h#L6136
prog_id: NonZeroU32::new(p.as_ref().bpf_prog.id),
})
}
}
/// Redirects the current packet on the interface at `index`.
///
/// The lower two bits of `flags` are used for the return code if the map lookup fails, which
/// can be used as the XDP program's return code if a CPU cannot be found.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::DevMap, programs::XdpContext};
///
/// #[map]
/// static MAP: DevMap = DevMap::with_max_entries(8, 0);
///
/// #[xdp]
/// fn xdp(_ctx: XdpContext) -> u32 {
/// MAP.redirect(7, 0).unwrap_or(xdp_action::XDP_DROP)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, index: u32, flags: u64) -> Result<u32, u32> {
try_redirect_map(&self.def, index, flags)
}
}
#[derive(Clone, Copy)]
/// The value of a device map.
pub struct DevMapValue {
/// Target interface index to redirect to.
pub if_index: u32,
/// Chained XDP program ID.
pub prog_id: Option<NonZeroU32>,
}

@ -0,0 +1,146 @@
use core::{cell::UnsafeCell, mem, num::NonZeroU32, ptr::NonNull};
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,
maps::PinningType,
};
use super::{dev_map::DevMapValue, try_redirect_map};
/// A map of network devices.
///
/// XDP programs can use this map to redirect packets to other network devices. It is similar to
/// [`DevMap`](super::DevMap), but is an hash map rather than an array. Keys do not need to be
/// contiguous nor start at zero, but there is a hashing cost to every lookup.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 5.4.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::DevMapHash, programs::XdpContext};
///
/// #[map]
/// static MAP: DevMapHash = DevMapHash::with_max_entries(1, 0);
///
/// #[xdp]
/// fn xdp(_ctx: XdpContext) -> i32 {
/// MAP.redirect(42, xdp_action::XDP_PASS as u64)
/// }
/// ```
#[repr(transparent)]
pub struct DevMapHash {
def: UnsafeCell<bpf_map_def>,
}
unsafe impl Sync for DevMapHash {}
impl DevMapHash {
/// Creates a [`DevMapHash`] with a set maximum number of elements.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::DevMapHash};
///
/// #[map]
/// static MAP: DevMapHash = DevMapHash::with_max_entries(8, 0);
/// ```
pub const fn with_max_entries(max_entries: u32, flags: u32) -> DevMapHash {
DevMapHash {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_DEVMAP_HASH,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<bpf_devmap_val>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::None as u32,
}),
}
}
/// Creates a [`DevMapHash`] with a set maximum number of elements that can be pinned to the BPF
/// File System (bpffs).
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::DevMapHash};
///
/// #[map]
/// static MAP: DevMapHash = DevMapHash::pinned(8, 0);
/// ```
pub const fn pinned(max_entries: u32, flags: u32) -> DevMapHash {
DevMapHash {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_DEVMAP_HASH,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<bpf_devmap_val>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::ByName as u32,
}),
}
}
/// Retrieves the interface index with `key` in the map.
///
/// To actually redirect a packet, see [`DevMapHash::redirect`].
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::DevMapHash};
///
/// #[map]
/// static MAP: DevMapHash = DevMapHash::with_max_entries(1, 0);
///
/// let target_if_index = MAP.get(42).target_if_index;
///
/// // redirect to ifindex
/// ```
#[inline(always)]
pub fn get(&self, key: u32) -> Option<DevMapValue> {
unsafe {
let value =
bpf_map_lookup_elem(self.def.get() as *mut _, &key as *const _ as *const c_void);
NonNull::new(value as *mut bpf_devmap_val).map(|p| DevMapValue {
if_index: p.as_ref().ifindex,
// SAFETY: map writes use fd, map reads use id.
// https://elixir.bootlin.com/linux/v6.2/source/include/uapi/linux/bpf.h#L6136
prog_id: NonZeroU32::new(p.as_ref().bpf_prog.id),
})
}
}
/// Redirects the current packet on the interface at `key`.
///
/// The lower two bits of `flags` are used for the return code if the map lookup fails, which
/// can be used as the XDP program's return code if a CPU cannot be found.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::DevMapHash, programs::XdpContext};
///
/// #[map]
/// static MAP: DevMapHash = DevMapHash::with_max_entries(8, 0);
///
/// #[xdp]
/// fn xdp(_ctx: XdpContext) -> u32 {
/// MAP.redirect(7, 0).unwrap_or(xdp_action::XDP_DROP)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, key: u32, flags: u64) -> Result<u32, u32> {
try_redirect_map(&self.def, key, flags)
}
}

@ -0,0 +1,33 @@
mod cpu_map;
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<bpf_map_def>, key: u32, flags: u64) -> Result<u32, u32> {
// 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),
}
}

@ -0,0 +1,164 @@
use core::{cell::UnsafeCell, mem, ptr::NonNull};
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,
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
/// `XDP_REDIRECT` action.
///
/// # Minimum kernel version
///
/// The minimum kernel version required to use this feature is 4.18.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::XskMap, programs::XdpContext};
///
/// #[map]
/// static SOCKS: XskMap = XskMap::with_max_entries(8, 0);
///
/// #[xdp]
/// fn xdp(ctx, XdpContext) -> i32 {
/// let queue_id = unsafe { (*ctx.ctx).rx_queue_index };
/// MAP.redirect(queue_id, xdp_action::XDP_DROP as u64)
/// }
/// ```
///
/// # Queue management
///
/// Packets received on a RX queue can only be redirected to sockets bound on the same queue. Most
/// hardware NICs have multiple RX queue to spread the load across multiple CPU cores using RSS.
///
/// Three strategies are possible:
///
/// - Reduce the RX queue count to a single one. This option is great for development, but is
/// detrimental for performance as the single CPU core recieving packets will get overwhelmed.
/// Setting the queue count for a NIC can be achieved using `ethtool -L <ifname> combined 1`.
/// - Create a socket for every RX queue. Most modern NICs will have an RX queue per CPU thread, so
/// a socket per CPU thread is best for performance. To dynamically size the map depending on the
/// recieve queue count, see the userspace documentation of `CpuMap`.
/// - Create a single socket and use a [`CpuMap`](super::CpuMap) to redirect the packet to the
/// correct CPU core. This way, the packet is sent to another CPU, and a chained XDP program can
/// the redirect to the AF_XDP socket. Using a single socket simplifies the userspace code but
/// will not perform great unless not a lot of traffic is redirected to the socket. Regular
/// traffic however will not be impacted, contrary to reducing the queue count.
#[repr(transparent)]
pub struct XskMap {
def: UnsafeCell<bpf_map_def>,
}
unsafe impl Sync for XskMap {}
impl XskMap {
/// Creates a [`XskMap`] with a set maximum number of elements.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::XskMap};
///
/// #[map]
/// static SOCKS: XskMap::with_max_entries(8, 0);
/// ```
pub const fn with_max_entries(max_entries: u32, flags: u32) -> XskMap {
XskMap {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_XSKMAP,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<u32>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::None as u32,
}),
}
}
/// Creates a [`XskMap`] with a set maximum number of elements that can be pinned to the BPF
/// filesystem (bpffs).
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::XskMap};
///
/// #[map]
/// static SOCKS: XskMap::pinned(8, 0);
/// ```
pub const fn pinned(max_entries: u32, flags: u32) -> XskMap {
XskMap {
def: UnsafeCell::new(bpf_map_def {
type_: BPF_MAP_TYPE_XSKMAP,
key_size: mem::size_of::<u32>() as u32,
value_size: mem::size_of::<u32>() as u32,
max_entries,
map_flags: flags,
id: 0,
pinning: PinningType::ByName as u32,
}),
}
}
/// Retrieves the queue to which the socket is bound at `index` in the array.
///
/// To actually redirect a packet, see [`XskMap::redirect`].
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{macros::map, maps::XskMap};
///
/// #[map]
/// static SOCKS: XskMap = XskMap::with_max_entries(8, 0);
///
/// let queue_id = SOCKS.get(0);
/// ```
#[inline(always)]
pub fn get(&self, index: u32) -> Option<u32> {
unsafe {
let value = bpf_map_lookup_elem(
self.def.get() as *mut _,
&index as *const _ as *const c_void,
);
NonNull::new(value as *mut bpf_xdp_sock).map(|p| p.as_ref().queue_id)
}
}
/// Redirects the current packet to the AF_XDP socket at `index`.
///
/// The lower two bits of `flags` are used for the return code if the map lookup fails, which
/// can be used as the XDP program's return code if a matching socket cannot be found.
///
/// However, if the socket at `index` is bound to a RX queue which is not the current RX queue,
/// the packet will be dropped.
///
/// # Examples
///
/// ```rust,no_run
/// use aya_bpf::{bindings::xdp_action, macros::{map, xdp}, maps::XskMap, programs::XdpContext};
///
/// #[map]
/// static SOCKS: XskMap = XskMap::with_max_entries(8, 0);
///
/// #[xdp]
/// fn xdp(ctx, XdpContext) -> u32 {
/// let queue_id = unsafe { (*ctx.ctx).rx_queue_index };
/// MAP.redirect(queue_id, 0).unwrap_or(xdp_action::XDP_DROP)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, index: u32, flags: u64) -> Result<u32, u32> {
try_redirect_map(&self.def, index, flags)
}
}

@ -43,3 +43,11 @@ path = "src/bpf_probe_read.rs"
[[bin]]
name = "two_progs"
path = "src/two_progs.rs"
[[bin]]
name = "redirect"
path = "src/redirect.rs"
[[bin]]
name = "xdp_sec"
path = "src/xdp_sec.rs"

@ -0,0 +1,73 @@
#![no_std]
#![no_main]
use aya_bpf::{
bindings::xdp_action,
macros::{map, xdp},
maps::{Array, CpuMap, DevMap, DevMapHash, XskMap},
programs::XdpContext,
};
#[map]
static SOCKS: XskMap = XskMap::with_max_entries(1, 0);
#[map]
static DEVS: DevMap = DevMap::with_max_entries(1, 0);
#[map]
static DEVS_HASH: DevMapHash = DevMapHash::with_max_entries(1, 0);
#[map]
static CPUS: CpuMap = CpuMap::with_max_entries(1, 0);
/// Hits of a probe, used to test program chaining through CpuMap/DevMap.
/// The first slot counts how many times the "raw" xdp program got executed, while the second slot
/// counts how many times the map programs got executed.
/// This allows the test harness to assert that a specific step got executed.
#[map]
static mut HITS: Array<u32> = Array::with_max_entries(2, 0);
#[xdp]
pub fn redirect_sock(_ctx: XdpContext) -> u32 {
SOCKS.redirect(0, 0).unwrap_or(xdp_action::XDP_ABORTED)
}
#[xdp]
pub fn redirect_dev(_ctx: XdpContext) -> u32 {
inc_hit(0);
DEVS.redirect(0, 0).unwrap_or(xdp_action::XDP_ABORTED)
}
#[xdp]
pub fn redirect_dev_hash(_ctx: XdpContext) -> u32 {
inc_hit(0);
DEVS_HASH.redirect(10, 0).unwrap_or(xdp_action::XDP_ABORTED)
}
#[xdp]
pub fn redirect_cpu(_ctx: XdpContext) -> u32 {
inc_hit(0);
CPUS.redirect(0, 0).unwrap_or(xdp_action::XDP_ABORTED)
}
#[xdp(map = "cpumap")]
pub fn redirect_cpu_chain(_ctx: XdpContext) -> u32 {
inc_hit(1);
xdp_action::XDP_PASS
}
#[xdp(map = "devmap")]
pub fn redirect_dev_chain(_ctx: XdpContext) -> u32 {
inc_hit(1);
xdp_action::XDP_PASS
}
#[inline(always)]
fn inc_hit(index: u32) {
if let Some(hit) = unsafe { HITS.get_ptr_mut(index) } {
unsafe { *hit += 1 };
}
}
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}

@ -0,0 +1,26 @@
#![no_std]
#![no_main]
use aya_bpf::{bindings::xdp_action::XDP_PASS, macros::xdp, programs::XdpContext};
macro_rules! probe {
($name:ident, ($($arg:ident $(= $value:literal)?),*) ) => {
#[xdp($($arg $(= $value)?),*)]
pub fn $name(_ctx: XdpContext) -> u32 {
XDP_PASS
}
};
}
probe!(xdp_plain, ());
probe!(xdp_frags, (frags));
probe!(xdp_cpumap, (map = "cpumap"));
probe!(xdp_devmap, (map = "devmap"));
probe!(xdp_frags_cpumap, (frags, map = "cpumap"));
probe!(xdp_frags_devmap, (frags, map = "devmap"));
#[cfg(not(test))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}

@ -19,6 +19,8 @@ pub const RELOCATIONS: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "
pub const TWO_PROGS: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/two_progs"));
pub const BPF_PROBE_READ: &[u8] =
include_bytes_aligned!(concat!(env!("OUT_DIR"), "/bpf_probe_read"));
pub const REDIRECT: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/redirect"));
pub const XDP_SEC: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/xdp_sec"));
#[cfg(test)]
mod tests;

@ -6,3 +6,4 @@ mod log;
mod rbpf;
mod relocations;
mod smoke;
mod xdp;

@ -13,6 +13,7 @@ use aya::{
util::KernelVersion,
Bpf,
};
use aya_obj::programs::XdpAttachType;
const MAX_RETRIES: usize = 100;
const RETRY_DURATION: Duration = Duration::from_millis(10);
@ -309,7 +310,7 @@ fn pin_lifecycle() {
// 2. Load program from bpffs but don't attach it
{
let _ = Xdp::from_pin("/sys/fs/bpf/aya-xdp-test-prog").unwrap();
let _ = Xdp::from_pin("/sys/fs/bpf/aya-xdp-test-prog", XdpAttachType::Interface).unwrap();
}
// should still be loaded since prog was pinned
@ -317,7 +318,8 @@ fn pin_lifecycle() {
// 3. Load program from bpffs and attach
{
let mut prog = Xdp::from_pin("/sys/fs/bpf/aya-xdp-test-prog").unwrap();
let mut prog =
Xdp::from_pin("/sys/fs/bpf/aya-xdp-test-prog", XdpAttachType::Interface).unwrap();
let link_id = prog.attach("lo", XdpFlags::default()).unwrap();
let link = prog.take_link(link_id).unwrap();
let fd_link: FdLink = link.try_into().unwrap();

@ -2,7 +2,7 @@ use core::{mem::size_of, ptr::null_mut, slice::from_raw_parts};
use std::collections::HashMap;
use assert_matches::assert_matches;
use aya_obj::{generated::bpf_insn, Object, ProgramSection};
use aya_obj::{generated::bpf_insn, programs::XdpAttachType, Object, ProgramSection};
#[test]
fn run_with_rbpf() {
@ -11,7 +11,10 @@ fn run_with_rbpf() {
assert_eq!(object.programs.len(), 1);
assert_matches!(
object.programs["pass"].section,
ProgramSection::Xdp { frags: true }
ProgramSection::Xdp {
frags: true,
attach_type: XdpAttachType::Interface
}
);
let instructions = &object

@ -0,0 +1,98 @@
use std::{net::UdpSocket, time::Duration};
use aya::{
maps::{Array, CpuMap},
programs::{Xdp, XdpFlags},
Bpf,
};
use object::{Object, ObjectSection, ObjectSymbol, SymbolSection};
use crate::utils::NetNsGuard;
#[test]
fn prog_sections() {
let obj_file = object::File::parse(crate::XDP_SEC).unwrap();
ensure_symbol(&obj_file, "xdp", "xdp_plain");
ensure_symbol(&obj_file, "xdp.frags", "xdp_frags");
ensure_symbol(&obj_file, "xdp/cpumap", "xdp_cpumap");
ensure_symbol(&obj_file, "xdp/devmap", "xdp_devmap");
ensure_symbol(&obj_file, "xdp.frags/cpumap", "xdp_frags_cpumap");
ensure_symbol(&obj_file, "xdp.frags/devmap", "xdp_frags_devmap");
}
#[track_caller]
fn ensure_symbol(obj_file: &object::File, sec_name: &str, sym_name: &str) {
let sec = obj_file.section_by_name(sec_name).unwrap_or_else(|| {
let secs = obj_file
.sections()
.flat_map(|sec| sec.name().ok().map(|name| name.to_owned()))
.collect::<Vec<_>>();
panic!("section {sec_name} not found. available sections: {secs:?}");
});
let sec = SymbolSection::Section(sec.index());
let syms = obj_file
.symbols()
.filter(|sym| sym.section() == sec)
.filter_map(|sym| sym.name().ok())
.collect::<Vec<_>>();
assert!(
syms.contains(&sym_name),
"symbol not found. available symbols in section: {syms:?}"
);
}
#[test]
fn map_load() {
let bpf = Bpf::load(crate::XDP_SEC).unwrap();
bpf.program("xdp_plain").unwrap();
bpf.program("xdp_frags").unwrap();
bpf.program("xdp_cpumap").unwrap();
bpf.program("xdp_devmap").unwrap();
bpf.program("xdp_frags_cpumap").unwrap();
bpf.program("xdp_frags_devmap").unwrap();
}
#[test]
fn cpumap_chain() {
let _netns = NetNsGuard::new();
let mut bpf = Bpf::load(crate::REDIRECT).unwrap();
// Load our cpumap and our canary map
let mut cpus: CpuMap<_> = bpf.take_map("CPUS").unwrap().try_into().unwrap();
let hits: Array<_, u32> = bpf.take_map("HITS").unwrap().try_into().unwrap();
let xdp_chain_fd = {
// Load the chained program to run on the target CPU
let xdp: &mut Xdp = bpf
.program_mut("redirect_cpu_chain")
.unwrap()
.try_into()
.unwrap();
xdp.load().unwrap();
xdp.fd().unwrap()
};
cpus.set(0, 2048, Some(xdp_chain_fd), 0).unwrap();
// Load the main program
let xdp: &mut Xdp = bpf.program_mut("redirect_cpu").unwrap().try_into().unwrap();
xdp.load().unwrap();
xdp.attach("lo", XdpFlags::default()).unwrap();
let sock = UdpSocket::bind("127.0.0.1:1777").unwrap();
sock.set_read_timeout(Some(Duration::from_millis(1)))
.unwrap();
sock.send_to(b"hello cpumap", "127.0.0.1:1777").unwrap();
// Read back the packet to ensure it wenth through the entire network stack, including our two
// probes.
let mut buf = vec![0u8; 1000];
let n = sock.recv(&mut buf).unwrap();
assert_eq!(&buf[..n], b"hello cpumap");
assert_eq!(hits.get(&0, 0).unwrap(), 1);
assert_eq!(hits.get(&1, 0).unwrap(), 1);
}

@ -563,6 +563,114 @@ impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::stack_trace::StackTrace wh
pub fn aya_bpf::maps::stack_trace::StackTrace::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::stack_trace::StackTrace
pub fn aya_bpf::maps::stack_trace::StackTrace::from(t: T) -> T
pub mod aya_bpf::maps::xdp
#[repr(transparent)] pub struct aya_bpf::maps::xdp::CpuMap
impl aya_bpf::maps::CpuMap
pub const fn aya_bpf::maps::CpuMap::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::CpuMap
pub fn aya_bpf::maps::CpuMap::redirect(&self, index: u32, flags: u64) -> core::result::Result<u32, u32>
pub const fn aya_bpf::maps::CpuMap::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::CpuMap
impl core::marker::Sync for aya_bpf::maps::CpuMap
impl core::marker::Send for aya_bpf::maps::CpuMap
impl core::marker::Unpin for aya_bpf::maps::CpuMap
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::CpuMap
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::CpuMap
impl<T, U> core::convert::Into<U> for aya_bpf::maps::CpuMap where U: core::convert::From<T>
pub fn aya_bpf::maps::CpuMap::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::CpuMap where U: core::convert::Into<T>
pub type aya_bpf::maps::CpuMap::Error = core::convert::Infallible
pub fn aya_bpf::maps::CpuMap::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::CpuMap where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::CpuMap::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::CpuMap::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::CpuMap where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::CpuMap::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::CpuMap where T: core::marker::Sized
pub fn aya_bpf::maps::CpuMap::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::CpuMap where T: core::marker::Sized
pub fn aya_bpf::maps::CpuMap::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::CpuMap
pub fn aya_bpf::maps::CpuMap::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::xdp::DevMap
impl aya_bpf::maps::DevMap
pub fn aya_bpf::maps::DevMap::get(&self, index: u32) -> core::option::Option<DevMapValue>
pub const fn aya_bpf::maps::DevMap::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMap
pub fn aya_bpf::maps::DevMap::redirect(&self, index: u32, flags: u64) -> core::result::Result<u32, u32>
pub const fn aya_bpf::maps::DevMap::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMap
impl core::marker::Sync for aya_bpf::maps::DevMap
impl core::marker::Send for aya_bpf::maps::DevMap
impl core::marker::Unpin for aya_bpf::maps::DevMap
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::DevMap
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::DevMap
impl<T, U> core::convert::Into<U> for aya_bpf::maps::DevMap where U: core::convert::From<T>
pub fn aya_bpf::maps::DevMap::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::DevMap where U: core::convert::Into<T>
pub type aya_bpf::maps::DevMap::Error = core::convert::Infallible
pub fn aya_bpf::maps::DevMap::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::DevMap where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::DevMap::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::DevMap::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::DevMap where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::DevMap::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::DevMap where T: core::marker::Sized
pub fn aya_bpf::maps::DevMap::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::DevMap where T: core::marker::Sized
pub fn aya_bpf::maps::DevMap::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::DevMap
pub fn aya_bpf::maps::DevMap::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::xdp::DevMapHash
impl aya_bpf::maps::DevMapHash
pub fn aya_bpf::maps::DevMapHash::get(&self, key: u32) -> core::option::Option<DevMapValue>
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, key: u32, flags: u64) -> core::result::Result<u32, u32>
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
impl core::marker::Unpin for aya_bpf::maps::DevMapHash
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::DevMapHash
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::DevMapHash
impl<T, U> core::convert::Into<U> for aya_bpf::maps::DevMapHash where U: core::convert::From<T>
pub fn aya_bpf::maps::DevMapHash::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::DevMapHash where U: core::convert::Into<T>
pub type aya_bpf::maps::DevMapHash::Error = core::convert::Infallible
pub fn aya_bpf::maps::DevMapHash::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::DevMapHash where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::DevMapHash::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::DevMapHash::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::DevMapHash where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::DevMapHash::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::DevMapHash where T: core::marker::Sized
pub fn aya_bpf::maps::DevMapHash::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::DevMapHash where T: core::marker::Sized
pub fn aya_bpf::maps::DevMapHash::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::DevMapHash
pub fn aya_bpf::maps::DevMapHash::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::xdp::XskMap
impl aya_bpf::maps::XskMap
pub fn aya_bpf::maps::XskMap::get(&self, index: u32) -> core::option::Option<u32>
pub const fn aya_bpf::maps::XskMap::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::XskMap
pub fn aya_bpf::maps::XskMap::redirect(&self, index: u32, flags: u64) -> core::result::Result<u32, u32>
pub const fn aya_bpf::maps::XskMap::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::XskMap
impl core::marker::Sync for aya_bpf::maps::XskMap
impl core::marker::Send for aya_bpf::maps::XskMap
impl core::marker::Unpin for aya_bpf::maps::XskMap
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::XskMap
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::XskMap
impl<T, U> core::convert::Into<U> for aya_bpf::maps::XskMap where U: core::convert::From<T>
pub fn aya_bpf::maps::XskMap::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::XskMap where U: core::convert::Into<T>
pub type aya_bpf::maps::XskMap::Error = core::convert::Infallible
pub fn aya_bpf::maps::XskMap::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::XskMap where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::XskMap::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::XskMap::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::XskMap where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::XskMap::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::XskMap where T: core::marker::Sized
pub fn aya_bpf::maps::XskMap::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::XskMap where T: core::marker::Sized
pub fn aya_bpf::maps::XskMap::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::XskMap
pub fn aya_bpf::maps::XskMap::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::Array<T>
impl<T> aya_bpf::maps::array::Array<T>
pub fn aya_bpf::maps::array::Array<T>::get(&self, index: u32) -> core::option::Option<&T>
@ -618,6 +726,86 @@ impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::bloom_filter::BloomFilter<
pub fn aya_bpf::maps::bloom_filter::BloomFilter<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::bloom_filter::BloomFilter<T>
pub fn aya_bpf::maps::bloom_filter::BloomFilter<T>::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::CpuMap
impl aya_bpf::maps::CpuMap
pub const fn aya_bpf::maps::CpuMap::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::CpuMap
pub fn aya_bpf::maps::CpuMap::redirect(&self, index: u32, flags: u64) -> core::result::Result<u32, u32>
pub const fn aya_bpf::maps::CpuMap::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::CpuMap
impl core::marker::Sync for aya_bpf::maps::CpuMap
impl core::marker::Send for aya_bpf::maps::CpuMap
impl core::marker::Unpin for aya_bpf::maps::CpuMap
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::CpuMap
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::CpuMap
impl<T, U> core::convert::Into<U> for aya_bpf::maps::CpuMap where U: core::convert::From<T>
pub fn aya_bpf::maps::CpuMap::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::CpuMap where U: core::convert::Into<T>
pub type aya_bpf::maps::CpuMap::Error = core::convert::Infallible
pub fn aya_bpf::maps::CpuMap::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::CpuMap where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::CpuMap::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::CpuMap::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::CpuMap where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::CpuMap::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::CpuMap where T: core::marker::Sized
pub fn aya_bpf::maps::CpuMap::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::CpuMap where T: core::marker::Sized
pub fn aya_bpf::maps::CpuMap::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::CpuMap
pub fn aya_bpf::maps::CpuMap::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::DevMap
impl aya_bpf::maps::DevMap
pub fn aya_bpf::maps::DevMap::get(&self, index: u32) -> core::option::Option<DevMapValue>
pub const fn aya_bpf::maps::DevMap::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMap
pub fn aya_bpf::maps::DevMap::redirect(&self, index: u32, flags: u64) -> core::result::Result<u32, u32>
pub const fn aya_bpf::maps::DevMap::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::DevMap
impl core::marker::Sync for aya_bpf::maps::DevMap
impl core::marker::Send for aya_bpf::maps::DevMap
impl core::marker::Unpin for aya_bpf::maps::DevMap
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::DevMap
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::DevMap
impl<T, U> core::convert::Into<U> for aya_bpf::maps::DevMap where U: core::convert::From<T>
pub fn aya_bpf::maps::DevMap::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::DevMap where U: core::convert::Into<T>
pub type aya_bpf::maps::DevMap::Error = core::convert::Infallible
pub fn aya_bpf::maps::DevMap::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::DevMap where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::DevMap::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::DevMap::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::DevMap where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::DevMap::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::DevMap where T: core::marker::Sized
pub fn aya_bpf::maps::DevMap::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::DevMap where T: core::marker::Sized
pub fn aya_bpf::maps::DevMap::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::DevMap
pub fn aya_bpf::maps::DevMap::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::DevMapHash
impl aya_bpf::maps::DevMapHash
pub fn aya_bpf::maps::DevMapHash::get(&self, key: u32) -> core::option::Option<DevMapValue>
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, key: u32, flags: u64) -> core::result::Result<u32, u32>
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
impl core::marker::Unpin for aya_bpf::maps::DevMapHash
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::DevMapHash
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::DevMapHash
impl<T, U> core::convert::Into<U> for aya_bpf::maps::DevMapHash where U: core::convert::From<T>
pub fn aya_bpf::maps::DevMapHash::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::DevMapHash where U: core::convert::Into<T>
pub type aya_bpf::maps::DevMapHash::Error = core::convert::Infallible
pub fn aya_bpf::maps::DevMapHash::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::DevMapHash where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::DevMapHash::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::DevMapHash::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::DevMapHash where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::DevMapHash::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::DevMapHash where T: core::marker::Sized
pub fn aya_bpf::maps::DevMapHash::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::DevMapHash where T: core::marker::Sized
pub fn aya_bpf::maps::DevMapHash::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::DevMapHash
pub fn aya_bpf::maps::DevMapHash::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::HashMap<K, V>
impl<K, V> aya_bpf::maps::hash_map::HashMap<K, V>
pub unsafe fn aya_bpf::maps::hash_map::HashMap<K, V>::get(&self, key: &K) -> core::option::Option<&V>
@ -1014,6 +1202,33 @@ impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::stack_trace::StackTrace wh
pub fn aya_bpf::maps::stack_trace::StackTrace::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::stack_trace::StackTrace
pub fn aya_bpf::maps::stack_trace::StackTrace::from(t: T) -> T
#[repr(transparent)] pub struct aya_bpf::maps::XskMap
impl aya_bpf::maps::XskMap
pub fn aya_bpf::maps::XskMap::get(&self, index: u32) -> core::option::Option<u32>
pub const fn aya_bpf::maps::XskMap::pinned(max_entries: u32, flags: u32) -> aya_bpf::maps::XskMap
pub fn aya_bpf::maps::XskMap::redirect(&self, index: u32, flags: u64) -> core::result::Result<u32, u32>
pub const fn aya_bpf::maps::XskMap::with_max_entries(max_entries: u32, flags: u32) -> aya_bpf::maps::XskMap
impl core::marker::Sync for aya_bpf::maps::XskMap
impl core::marker::Send for aya_bpf::maps::XskMap
impl core::marker::Unpin for aya_bpf::maps::XskMap
impl !core::panic::unwind_safe::RefUnwindSafe for aya_bpf::maps::XskMap
impl core::panic::unwind_safe::UnwindSafe for aya_bpf::maps::XskMap
impl<T, U> core::convert::Into<U> for aya_bpf::maps::XskMap where U: core::convert::From<T>
pub fn aya_bpf::maps::XskMap::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_bpf::maps::XskMap where U: core::convert::Into<T>
pub type aya_bpf::maps::XskMap::Error = core::convert::Infallible
pub fn aya_bpf::maps::XskMap::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_bpf::maps::XskMap where U: core::convert::TryFrom<T>
pub type aya_bpf::maps::XskMap::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_bpf::maps::XskMap::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya_bpf::maps::XskMap where T: 'static + core::marker::Sized
pub fn aya_bpf::maps::XskMap::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_bpf::maps::XskMap where T: core::marker::Sized
pub fn aya_bpf::maps::XskMap::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_bpf::maps::XskMap where T: core::marker::Sized
pub fn aya_bpf::maps::XskMap::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_bpf::maps::XskMap
pub fn aya_bpf::maps::XskMap::from(t: T) -> T
pub mod aya_bpf::programs
pub mod aya_bpf::programs::device
pub struct aya_bpf::programs::device::DeviceContext

@ -1342,6 +1342,8 @@ impl core::convert::From<aya_obj::programs::cgroup_sock_addr::CgroupSockAddrAtta
pub fn aya_obj::generated::bpf_attach_type::from(s: aya_obj::programs::cgroup_sock_addr::CgroupSockAddrAttachType) -> aya_obj::generated::bpf_attach_type
impl core::convert::From<aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType> for aya_obj::generated::bpf_attach_type
pub fn aya_obj::generated::bpf_attach_type::from(s: aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType) -> aya_obj::generated::bpf_attach_type
impl core::convert::From<aya_obj::programs::xdp::XdpAttachType> for aya_obj::generated::bpf_attach_type
pub fn aya_obj::generated::bpf_attach_type::from(value: aya_obj::programs::xdp::XdpAttachType) -> Self
impl core::clone::Clone for aya_obj::generated::bpf_attach_type
pub fn aya_obj::generated::bpf_attach_type::clone(&self) -> aya_obj::generated::bpf_attach_type
impl core::cmp::Eq for aya_obj::generated::bpf_attach_type
@ -5411,6 +5413,7 @@ pub fn aya_obj::maps::Map::pinning(&self) -> aya_obj::maps::PinningType
pub fn aya_obj::maps::Map::section_index(&self) -> usize
pub fn aya_obj::maps::Map::section_kind(&self) -> aya_obj::BpfSectionKind
pub fn aya_obj::maps::Map::set_max_entries(&mut self, v: u32)
pub fn aya_obj::maps::Map::set_value_size(&mut self, size: u32)
pub fn aya_obj::maps::Map::symbol_index(&self) -> core::option::Option<usize>
pub fn aya_obj::maps::Map::value_size(&self) -> u32
impl core::clone::Clone for aya_obj::maps::Map
@ -5848,6 +5851,7 @@ pub aya_obj::obj::ProgramSection::UProbe::sleepable: bool
pub aya_obj::obj::ProgramSection::URetProbe
pub aya_obj::obj::ProgramSection::URetProbe::sleepable: bool
pub aya_obj::obj::ProgramSection::Xdp
pub aya_obj::obj::ProgramSection::Xdp::attach_type: aya_obj::programs::xdp::XdpAttachType
pub aya_obj::obj::ProgramSection::Xdp::frags: bool
impl core::str::traits::FromStr for aya_obj::ProgramSection
pub type aya_obj::ProgramSection::Err = aya_obj::ParseError
@ -5889,6 +5893,8 @@ pub fn aya_obj::Features::bpf_name(&self) -> bool
pub fn aya_obj::Features::bpf_perf_link(&self) -> bool
pub fn aya_obj::Features::bpf_probe_read_kernel(&self) -> bool
pub fn aya_obj::Features::btf(&self) -> core::option::Option<&aya_obj::btf::BtfFeatures>
pub fn aya_obj::Features::cpumap_prog_id(&self) -> bool
pub fn aya_obj::Features::devmap_prog_id(&self) -> bool
impl core::default::Default for aya_obj::Features
pub fn aya_obj::Features::default() -> aya_obj::Features
impl core::fmt::Debug for aya_obj::Features
@ -6164,6 +6170,43 @@ impl<T> core::borrow::BorrowMut<T> for aya_obj::programs::cgroup_sockopt::Cgroup
pub fn aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType
pub fn aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType::from(t: T) -> T
pub mod aya_obj::programs::xdp
pub enum aya_obj::programs::xdp::XdpAttachType
pub aya_obj::programs::xdp::XdpAttachType::CpuMap
pub aya_obj::programs::xdp::XdpAttachType::DevMap
pub aya_obj::programs::xdp::XdpAttachType::Interface
impl core::convert::From<aya_obj::programs::xdp::XdpAttachType> for aya_obj::generated::bpf_attach_type
pub fn aya_obj::generated::bpf_attach_type::from(value: aya_obj::programs::xdp::XdpAttachType) -> Self
impl core::clone::Clone for aya_obj::programs::xdp::XdpAttachType
pub fn aya_obj::programs::xdp::XdpAttachType::clone(&self) -> aya_obj::programs::xdp::XdpAttachType
impl core::fmt::Debug for aya_obj::programs::xdp::XdpAttachType
pub fn aya_obj::programs::xdp::XdpAttachType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya_obj::programs::xdp::XdpAttachType
impl core::marker::Send for aya_obj::programs::xdp::XdpAttachType
impl core::marker::Sync for aya_obj::programs::xdp::XdpAttachType
impl core::marker::Unpin for aya_obj::programs::xdp::XdpAttachType
impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::programs::xdp::XdpAttachType
impl core::panic::unwind_safe::UnwindSafe for aya_obj::programs::xdp::XdpAttachType
impl<T, U> core::convert::Into<U> for aya_obj::programs::xdp::XdpAttachType where U: core::convert::From<T>
pub fn aya_obj::programs::xdp::XdpAttachType::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::programs::xdp::XdpAttachType where U: core::convert::Into<T>
pub type aya_obj::programs::xdp::XdpAttachType::Error = core::convert::Infallible
pub fn aya_obj::programs::xdp::XdpAttachType::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_obj::programs::xdp::XdpAttachType where U: core::convert::TryFrom<T>
pub type aya_obj::programs::xdp::XdpAttachType::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_obj::programs::xdp::XdpAttachType::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya_obj::programs::xdp::XdpAttachType where T: core::clone::Clone
pub type aya_obj::programs::xdp::XdpAttachType::Owned = T
pub fn aya_obj::programs::xdp::XdpAttachType::clone_into(&self, target: &mut T)
pub fn aya_obj::programs::xdp::XdpAttachType::to_owned(&self) -> T
impl<T> core::any::Any for aya_obj::programs::xdp::XdpAttachType where T: 'static + core::marker::Sized
pub fn aya_obj::programs::xdp::XdpAttachType::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_obj::programs::xdp::XdpAttachType where T: core::marker::Sized
pub fn aya_obj::programs::xdp::XdpAttachType::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_obj::programs::xdp::XdpAttachType where T: core::marker::Sized
pub fn aya_obj::programs::xdp::XdpAttachType::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_obj::programs::xdp::XdpAttachType
pub fn aya_obj::programs::xdp::XdpAttachType::from(t: T) -> T
pub enum aya_obj::programs::CgroupSockAddrAttachType
pub aya_obj::programs::CgroupSockAddrAttachType::Bind4
pub aya_obj::programs::CgroupSockAddrAttachType::Bind6
@ -6283,6 +6326,42 @@ impl<T> core::borrow::BorrowMut<T> for aya_obj::programs::cgroup_sockopt::Cgroup
pub fn aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType
pub fn aya_obj::programs::cgroup_sockopt::CgroupSockoptAttachType::from(t: T) -> T
pub enum aya_obj::programs::XdpAttachType
pub aya_obj::programs::XdpAttachType::CpuMap
pub aya_obj::programs::XdpAttachType::DevMap
pub aya_obj::programs::XdpAttachType::Interface
impl core::convert::From<aya_obj::programs::xdp::XdpAttachType> for aya_obj::generated::bpf_attach_type
pub fn aya_obj::generated::bpf_attach_type::from(value: aya_obj::programs::xdp::XdpAttachType) -> Self
impl core::clone::Clone for aya_obj::programs::xdp::XdpAttachType
pub fn aya_obj::programs::xdp::XdpAttachType::clone(&self) -> aya_obj::programs::xdp::XdpAttachType
impl core::fmt::Debug for aya_obj::programs::xdp::XdpAttachType
pub fn aya_obj::programs::xdp::XdpAttachType::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Copy for aya_obj::programs::xdp::XdpAttachType
impl core::marker::Send for aya_obj::programs::xdp::XdpAttachType
impl core::marker::Sync for aya_obj::programs::xdp::XdpAttachType
impl core::marker::Unpin for aya_obj::programs::xdp::XdpAttachType
impl core::panic::unwind_safe::RefUnwindSafe for aya_obj::programs::xdp::XdpAttachType
impl core::panic::unwind_safe::UnwindSafe for aya_obj::programs::xdp::XdpAttachType
impl<T, U> core::convert::Into<U> for aya_obj::programs::xdp::XdpAttachType where U: core::convert::From<T>
pub fn aya_obj::programs::xdp::XdpAttachType::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya_obj::programs::xdp::XdpAttachType where U: core::convert::Into<T>
pub type aya_obj::programs::xdp::XdpAttachType::Error = core::convert::Infallible
pub fn aya_obj::programs::xdp::XdpAttachType::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya_obj::programs::xdp::XdpAttachType where U: core::convert::TryFrom<T>
pub type aya_obj::programs::xdp::XdpAttachType::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya_obj::programs::xdp::XdpAttachType::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::borrow::ToOwned for aya_obj::programs::xdp::XdpAttachType where T: core::clone::Clone
pub type aya_obj::programs::xdp::XdpAttachType::Owned = T
pub fn aya_obj::programs::xdp::XdpAttachType::clone_into(&self, target: &mut T)
pub fn aya_obj::programs::xdp::XdpAttachType::to_owned(&self) -> T
impl<T> core::any::Any for aya_obj::programs::xdp::XdpAttachType where T: 'static + core::marker::Sized
pub fn aya_obj::programs::xdp::XdpAttachType::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya_obj::programs::xdp::XdpAttachType where T: core::marker::Sized
pub fn aya_obj::programs::xdp::XdpAttachType::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya_obj::programs::xdp::XdpAttachType where T: core::marker::Sized
pub fn aya_obj::programs::xdp::XdpAttachType::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya_obj::programs::xdp::XdpAttachType
pub fn aya_obj::programs::xdp::XdpAttachType::from(t: T) -> T
pub mod aya_obj::relocation
pub enum aya_obj::relocation::RelocationError
pub aya_obj::relocation::RelocationError::InvalidRelocationOffset
@ -6420,6 +6499,7 @@ pub fn aya_obj::maps::Map::pinning(&self) -> aya_obj::maps::PinningType
pub fn aya_obj::maps::Map::section_index(&self) -> usize
pub fn aya_obj::maps::Map::section_kind(&self) -> aya_obj::BpfSectionKind
pub fn aya_obj::maps::Map::set_max_entries(&mut self, v: u32)
pub fn aya_obj::maps::Map::set_value_size(&mut self, size: u32)
pub fn aya_obj::maps::Map::symbol_index(&self) -> core::option::Option<usize>
pub fn aya_obj::maps::Map::value_size(&self) -> u32
impl core::clone::Clone for aya_obj::maps::Map
@ -6560,6 +6640,7 @@ pub aya_obj::ProgramSection::UProbe::sleepable: bool
pub aya_obj::ProgramSection::URetProbe
pub aya_obj::ProgramSection::URetProbe::sleepable: bool
pub aya_obj::ProgramSection::Xdp
pub aya_obj::ProgramSection::Xdp::attach_type: aya_obj::programs::xdp::XdpAttachType
pub aya_obj::ProgramSection::Xdp::frags: bool
impl core::str::traits::FromStr for aya_obj::ProgramSection
pub type aya_obj::ProgramSection::Err = aya_obj::ParseError
@ -6601,6 +6682,8 @@ pub fn aya_obj::Features::bpf_name(&self) -> bool
pub fn aya_obj::Features::bpf_perf_link(&self) -> bool
pub fn aya_obj::Features::bpf_probe_read_kernel(&self) -> bool
pub fn aya_obj::Features::btf(&self) -> core::option::Option<&aya_obj::btf::BtfFeatures>
pub fn aya_obj::Features::cpumap_prog_id(&self) -> bool
pub fn aya_obj::Features::devmap_prog_id(&self) -> bool
impl core::default::Default for aya_obj::Features
pub fn aya_obj::Features::default() -> aya_obj::Features
impl core::fmt::Debug for aya_obj::Features

@ -795,9 +795,194 @@ impl<T> core::borrow::BorrowMut<T> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::from(t: T) -> T
pub mod aya::maps::xdp
pub enum aya::maps::xdp::XdpMapError
pub aya::maps::xdp::XdpMapError::ChainedProgramNotSupported
pub aya::maps::xdp::XdpMapError::MapError(aya::maps::MapError)
impl core::convert::From<aya::maps::MapError> for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::from(source: aya::maps::MapError) -> Self
impl core::error::Error for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
impl core::fmt::Display for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::fmt(&self, __formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::fmt::Debug for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
impl core::marker::Send for aya::maps::xdp::XdpMapError
impl core::marker::Sync for aya::maps::xdp::XdpMapError
impl core::marker::Unpin for aya::maps::xdp::XdpMapError
impl !core::panic::unwind_safe::RefUnwindSafe for aya::maps::xdp::XdpMapError
impl !core::panic::unwind_safe::UnwindSafe for aya::maps::xdp::XdpMapError
impl<T, U> core::convert::Into<U> for aya::maps::xdp::XdpMapError where U: core::convert::From<T>
pub fn aya::maps::xdp::XdpMapError::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::xdp::XdpMapError where U: core::convert::Into<T>
pub type aya::maps::xdp::XdpMapError::Error = core::convert::Infallible
pub fn aya::maps::xdp::XdpMapError::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::xdp::XdpMapError where U: core::convert::TryFrom<T>
pub type aya::maps::xdp::XdpMapError::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::xdp::XdpMapError::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> alloc::string::ToString for aya::maps::xdp::XdpMapError where T: core::fmt::Display + core::marker::Sized
pub fn aya::maps::xdp::XdpMapError::to_string(&self) -> alloc::string::String
impl<T> core::any::Any for aya::maps::xdp::XdpMapError where T: 'static + core::marker::Sized
pub fn aya::maps::xdp::XdpMapError::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::xdp::XdpMapError where T: core::marker::Sized
pub fn aya::maps::xdp::XdpMapError::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::xdp::XdpMapError where T: core::marker::Sized
pub fn aya::maps::xdp::XdpMapError::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::from(t: T) -> T
pub struct aya::maps::xdp::CpuMap<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::CpuMap<T>
pub fn aya::maps::CpuMap<T>::get(&self, cpu_index: u32, flags: u64) -> core::result::Result<CpuMapValue, aya::maps::MapError>
pub fn aya::maps::CpuMap<T>::iter(&self) -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<CpuMapValue, aya::maps::MapError>> + '_
pub fn aya::maps::CpuMap<T>::len(&self) -> u32
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::CpuMap<T>
pub fn aya::maps::CpuMap<T>::set(&mut self, cpu_index: u32, queue_size: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::CpuMap<aya::maps::MapData>
pub type aya::maps::CpuMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::CpuMap<&'a aya::maps::MapData>
pub type aya::maps::CpuMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::CpuMap<&'a mut aya::maps::MapData>
pub type aya::maps::CpuMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::CpuMap<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::CpuMap<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::CpuMap<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::CpuMap<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::CpuMap<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::CpuMap<T> where U: core::convert::From<T>
pub fn aya::maps::CpuMap<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::CpuMap<T> where U: core::convert::Into<T>
pub type aya::maps::CpuMap<T>::Error = core::convert::Infallible
pub fn aya::maps::CpuMap<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::CpuMap<T> where U: core::convert::TryFrom<T>
pub type aya::maps::CpuMap<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::CpuMap<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::CpuMap<T> where T: 'static + core::marker::Sized
pub fn aya::maps::CpuMap<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::CpuMap<T> where T: core::marker::Sized
pub fn aya::maps::CpuMap<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::CpuMap<T> where T: core::marker::Sized
pub fn aya::maps::CpuMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::CpuMap<T>
pub fn aya::maps::CpuMap<T>::from(t: T) -> T
pub struct aya::maps::xdp::DevMap<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::DevMap<T>
pub fn aya::maps::DevMap<T>::get(&self, index: u32, flags: u64) -> core::result::Result<DevMapValue, aya::maps::MapError>
pub fn aya::maps::DevMap<T>::iter(&self) -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<DevMapValue, aya::maps::MapError>> + '_
pub fn aya::maps::DevMap<T>::len(&self) -> u32
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::DevMap<T>
pub fn aya::maps::DevMap<T>::set(&mut self, index: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::DevMap<aya::maps::MapData>
pub type aya::maps::DevMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::DevMap<&'a aya::maps::MapData>
pub type aya::maps::DevMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::DevMap<&'a mut aya::maps::MapData>
pub type aya::maps::DevMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::DevMap<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::DevMap<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::DevMap<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::DevMap<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::DevMap<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::DevMap<T> where U: core::convert::From<T>
pub fn aya::maps::DevMap<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::DevMap<T> where U: core::convert::Into<T>
pub type aya::maps::DevMap<T>::Error = core::convert::Infallible
pub fn aya::maps::DevMap<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::DevMap<T> where U: core::convert::TryFrom<T>
pub type aya::maps::DevMap<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::DevMap<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::DevMap<T> where T: 'static + core::marker::Sized
pub fn aya::maps::DevMap<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::DevMap<T> where T: core::marker::Sized
pub fn aya::maps::DevMap<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::DevMap<T> where T: core::marker::Sized
pub fn aya::maps::DevMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::DevMap<T>
pub fn aya::maps::DevMap<T>::from(t: T) -> T
pub struct aya::maps::xdp::DevMapHash<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::DevMapHash<T>
pub fn aya::maps::DevMapHash<T>::get(&self, key: u32, flags: u64) -> core::result::Result<DevMapValue, aya::maps::MapError>
pub fn aya::maps::DevMapHash<T>::iter(&self) -> aya::maps::MapIter<'_, u32, DevMapValue, Self>
pub fn aya::maps::DevMapHash<T>::keys(&self) -> aya::maps::MapKeys<'_, u32>
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::DevMapHash<T>
pub fn aya::maps::DevMapHash<T>::insert(&mut self, key: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError>
pub fn aya::maps::DevMapHash<T>::remove(&mut self, key: u32) -> core::result::Result<(), aya::maps::MapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::DevMapHash<aya::maps::MapData>
pub type aya::maps::DevMapHash<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::DevMapHash<&'a aya::maps::MapData>
pub type aya::maps::DevMapHash<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::DevMapHash<&'a mut aya::maps::MapData>
pub type aya::maps::DevMapHash<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::DevMapHash<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::DevMapHash<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::DevMapHash<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::DevMapHash<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::DevMapHash<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::DevMapHash<T> where U: core::convert::From<T>
pub fn aya::maps::DevMapHash<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::DevMapHash<T> where U: core::convert::Into<T>
pub type aya::maps::DevMapHash<T>::Error = core::convert::Infallible
pub fn aya::maps::DevMapHash<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::DevMapHash<T> where U: core::convert::TryFrom<T>
pub type aya::maps::DevMapHash<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::DevMapHash<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::DevMapHash<T> where T: 'static + core::marker::Sized
pub fn aya::maps::DevMapHash<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::DevMapHash<T> where T: core::marker::Sized
pub fn aya::maps::DevMapHash<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::DevMapHash<T> where T: core::marker::Sized
pub fn aya::maps::DevMapHash<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::DevMapHash<T>
pub fn aya::maps::DevMapHash<T>::from(t: T) -> T
pub struct aya::maps::xdp::XskMap<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::XskMap<T>
pub fn aya::maps::XskMap<T>::len(&self) -> u32
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::XskMap<T>
pub fn aya::maps::XskMap<T>::set(&mut self, index: u32, socket_fd: impl std::os::fd::raw::AsRawFd, flags: u64) -> core::result::Result<(), aya::maps::MapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::XskMap<aya::maps::MapData>
pub type aya::maps::XskMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::XskMap<&'a aya::maps::MapData>
pub type aya::maps::XskMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::XskMap<&'a mut aya::maps::MapData>
pub type aya::maps::XskMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::XskMap<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::XskMap<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::XskMap<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::XskMap<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::XskMap<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::XskMap<T> where U: core::convert::From<T>
pub fn aya::maps::XskMap<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::XskMap<T> where U: core::convert::Into<T>
pub type aya::maps::XskMap<T>::Error = core::convert::Infallible
pub fn aya::maps::XskMap<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::XskMap<T> where U: core::convert::TryFrom<T>
pub type aya::maps::XskMap<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::XskMap<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::XskMap<T> where T: 'static + core::marker::Sized
pub fn aya::maps::XskMap<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::XskMap<T> where T: core::marker::Sized
pub fn aya::maps::XskMap<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::XskMap<T> where T: core::marker::Sized
pub fn aya::maps::XskMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::XskMap<T>
pub fn aya::maps::XskMap<T>::from(t: T) -> T
pub enum aya::maps::Map
pub aya::maps::Map::Array(aya::maps::MapData)
pub aya::maps::Map::BloomFilter(aya::maps::MapData)
pub aya::maps::Map::CpuMap(aya::maps::MapData)
pub aya::maps::Map::DevMap(aya::maps::MapData)
pub aya::maps::Map::DevMapHash(aya::maps::MapData)
pub aya::maps::Map::HashMap(aya::maps::MapData)
pub aya::maps::Map::LpmTrie(aya::maps::MapData)
pub aya::maps::Map::LruHashMap(aya::maps::MapData)
@ -812,12 +997,25 @@ pub aya::maps::Map::SockMap(aya::maps::MapData)
pub aya::maps::Map::Stack(aya::maps::MapData)
pub aya::maps::Map::StackTraceMap(aya::maps::MapData)
pub aya::maps::Map::Unsupported(aya::maps::MapData)
pub aya::maps::Map::XskMap(aya::maps::MapData)
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::CpuMap<aya::maps::MapData>
pub type aya::maps::CpuMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::DevMap<aya::maps::MapData>
pub type aya::maps::DevMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::DevMapHash<aya::maps::MapData>
pub type aya::maps::DevMapHash<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::ProgramArray<aya::maps::MapData>
pub type aya::maps::ProgramArray<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::ProgramArray<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::SockMap<aya::maps::MapData>
pub type aya::maps::SockMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::SockMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::XskMap<aya::maps::MapData>
pub type aya::maps::XskMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::perf::AsyncPerfEventArray<aya::maps::MapData>
pub type aya::maps::perf::AsyncPerfEventArray<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::perf::AsyncPerfEventArray<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
@ -881,12 +1079,24 @@ pub fn aya::maps::queue::Queue<&'a mut aya::maps::MapData, V>::try_from(map: &'a
impl<'a, V: aya::Pod> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::stack::Stack<&'a mut aya::maps::MapData, V>
pub type aya::maps::stack::Stack<&'a mut aya::maps::MapData, V>::Error = aya::maps::MapError
pub fn aya::maps::stack::Stack<&'a mut aya::maps::MapData, V>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::CpuMap<&'a aya::maps::MapData>
pub type aya::maps::CpuMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::DevMap<&'a aya::maps::MapData>
pub type aya::maps::DevMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::DevMapHash<&'a aya::maps::MapData>
pub type aya::maps::DevMapHash<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::ProgramArray<&'a aya::maps::MapData>
pub type aya::maps::ProgramArray<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::ProgramArray<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::SockMap<&'a aya::maps::MapData>
pub type aya::maps::SockMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::SockMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::XskMap<&'a aya::maps::MapData>
pub type aya::maps::XskMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::perf::AsyncPerfEventArray<&'a aya::maps::MapData>
pub type aya::maps::perf::AsyncPerfEventArray<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::perf::AsyncPerfEventArray<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
@ -896,12 +1106,24 @@ pub fn aya::maps::perf::PerfEventArray<&'a aya::maps::MapData>::try_from(map: &'
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::stack_trace::StackTraceMap<&'a aya::maps::MapData>
pub type aya::maps::stack_trace::StackTraceMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::stack_trace::StackTraceMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::CpuMap<&'a mut aya::maps::MapData>
pub type aya::maps::CpuMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::DevMap<&'a mut aya::maps::MapData>
pub type aya::maps::DevMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::DevMapHash<&'a mut aya::maps::MapData>
pub type aya::maps::DevMapHash<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::ProgramArray<&'a mut aya::maps::MapData>
pub type aya::maps::ProgramArray<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::ProgramArray<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::SockMap<&'a mut aya::maps::MapData>
pub type aya::maps::SockMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::SockMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::XskMap<&'a mut aya::maps::MapData>
pub type aya::maps::XskMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::perf::AsyncPerfEventArray<&'a mut aya::maps::MapData>
pub type aya::maps::perf::AsyncPerfEventArray<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::perf::AsyncPerfEventArray<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
@ -984,12 +1206,15 @@ pub aya::maps::MapError::OutOfBounds::max_entries: u32
pub aya::maps::MapError::PinError
pub aya::maps::MapError::PinError::error: aya::pin::PinError
pub aya::maps::MapError::PinError::name: core::option::Option<alloc::string::String>
pub aya::maps::MapError::ProgIdNotSupported
pub aya::maps::MapError::ProgramNotLoaded
pub aya::maps::MapError::SyscallError(crate::sys::SyscallError)
pub aya::maps::MapError::Unsupported
pub aya::maps::MapError::Unsupported::map_type: u32
impl core::convert::From<aya::maps::MapError> for aya::BpfError
pub fn aya::BpfError::from(source: aya::maps::MapError) -> Self
impl core::convert::From<aya::maps::MapError> for aya::maps::xdp::XdpMapError
pub fn aya::maps::xdp::XdpMapError::from(source: aya::maps::MapError) -> Self
impl core::convert::From<aya::maps::MapError> for aya::programs::ProgramError
pub fn aya::programs::ProgramError::from(source: aya::maps::MapError) -> Self
impl core::error::Error for aya::maps::MapError
@ -1131,6 +1356,118 @@ impl<T> core::borrow::BorrowMut<T> for aya::maps::bloom_filter::BloomFilter<T, V
pub fn aya::maps::bloom_filter::BloomFilter<T, V>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::bloom_filter::BloomFilter<T, V>
pub fn aya::maps::bloom_filter::BloomFilter<T, V>::from(t: T) -> T
pub struct aya::maps::CpuMap<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::CpuMap<T>
pub fn aya::maps::CpuMap<T>::get(&self, cpu_index: u32, flags: u64) -> core::result::Result<CpuMapValue, aya::maps::MapError>
pub fn aya::maps::CpuMap<T>::iter(&self) -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<CpuMapValue, aya::maps::MapError>> + '_
pub fn aya::maps::CpuMap<T>::len(&self) -> u32
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::CpuMap<T>
pub fn aya::maps::CpuMap<T>::set(&mut self, cpu_index: u32, queue_size: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::CpuMap<aya::maps::MapData>
pub type aya::maps::CpuMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::CpuMap<&'a aya::maps::MapData>
pub type aya::maps::CpuMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::CpuMap<&'a mut aya::maps::MapData>
pub type aya::maps::CpuMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::CpuMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::CpuMap<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::CpuMap<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::CpuMap<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::CpuMap<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::CpuMap<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::CpuMap<T> where U: core::convert::From<T>
pub fn aya::maps::CpuMap<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::CpuMap<T> where U: core::convert::Into<T>
pub type aya::maps::CpuMap<T>::Error = core::convert::Infallible
pub fn aya::maps::CpuMap<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::CpuMap<T> where U: core::convert::TryFrom<T>
pub type aya::maps::CpuMap<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::CpuMap<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::CpuMap<T> where T: 'static + core::marker::Sized
pub fn aya::maps::CpuMap<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::CpuMap<T> where T: core::marker::Sized
pub fn aya::maps::CpuMap<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::CpuMap<T> where T: core::marker::Sized
pub fn aya::maps::CpuMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::CpuMap<T>
pub fn aya::maps::CpuMap<T>::from(t: T) -> T
pub struct aya::maps::DevMap<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::DevMap<T>
pub fn aya::maps::DevMap<T>::get(&self, index: u32, flags: u64) -> core::result::Result<DevMapValue, aya::maps::MapError>
pub fn aya::maps::DevMap<T>::iter(&self) -> impl core::iter::traits::iterator::Iterator<Item = core::result::Result<DevMapValue, aya::maps::MapError>> + '_
pub fn aya::maps::DevMap<T>::len(&self) -> u32
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::DevMap<T>
pub fn aya::maps::DevMap<T>::set(&mut self, index: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::DevMap<aya::maps::MapData>
pub type aya::maps::DevMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::DevMap<&'a aya::maps::MapData>
pub type aya::maps::DevMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::DevMap<&'a mut aya::maps::MapData>
pub type aya::maps::DevMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::DevMap<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::DevMap<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::DevMap<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::DevMap<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::DevMap<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::DevMap<T> where U: core::convert::From<T>
pub fn aya::maps::DevMap<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::DevMap<T> where U: core::convert::Into<T>
pub type aya::maps::DevMap<T>::Error = core::convert::Infallible
pub fn aya::maps::DevMap<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::DevMap<T> where U: core::convert::TryFrom<T>
pub type aya::maps::DevMap<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::DevMap<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::DevMap<T> where T: 'static + core::marker::Sized
pub fn aya::maps::DevMap<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::DevMap<T> where T: core::marker::Sized
pub fn aya::maps::DevMap<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::DevMap<T> where T: core::marker::Sized
pub fn aya::maps::DevMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::DevMap<T>
pub fn aya::maps::DevMap<T>::from(t: T) -> T
pub struct aya::maps::DevMapHash<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::DevMapHash<T>
pub fn aya::maps::DevMapHash<T>::get(&self, key: u32, flags: u64) -> core::result::Result<DevMapValue, aya::maps::MapError>
pub fn aya::maps::DevMapHash<T>::iter(&self) -> aya::maps::MapIter<'_, u32, DevMapValue, Self>
pub fn aya::maps::DevMapHash<T>::keys(&self) -> aya::maps::MapKeys<'_, u32>
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::DevMapHash<T>
pub fn aya::maps::DevMapHash<T>::insert(&mut self, key: u32, target_if_index: u32, program: core::option::Option<&aya::programs::ProgramFd>, flags: u64) -> core::result::Result<(), aya::maps::xdp::XdpMapError>
pub fn aya::maps::DevMapHash<T>::remove(&mut self, key: u32) -> core::result::Result<(), aya::maps::MapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::DevMapHash<aya::maps::MapData>
pub type aya::maps::DevMapHash<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::DevMapHash<&'a aya::maps::MapData>
pub type aya::maps::DevMapHash<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::DevMapHash<&'a mut aya::maps::MapData>
pub type aya::maps::DevMapHash<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::DevMapHash<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::DevMapHash<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::DevMapHash<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::DevMapHash<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::DevMapHash<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::DevMapHash<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::DevMapHash<T> where U: core::convert::From<T>
pub fn aya::maps::DevMapHash<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::DevMapHash<T> where U: core::convert::Into<T>
pub type aya::maps::DevMapHash<T>::Error = core::convert::Infallible
pub fn aya::maps::DevMapHash<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::DevMapHash<T> where U: core::convert::TryFrom<T>
pub type aya::maps::DevMapHash<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::DevMapHash<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::DevMapHash<T> where T: 'static + core::marker::Sized
pub fn aya::maps::DevMapHash<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::DevMapHash<T> where T: core::marker::Sized
pub fn aya::maps::DevMapHash<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::DevMapHash<T> where T: core::marker::Sized
pub fn aya::maps::DevMapHash<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::DevMapHash<T>
pub fn aya::maps::DevMapHash<T>::from(t: T) -> T
pub struct aya::maps::HashMap<T, K, V>
impl<T: core::borrow::Borrow<aya::maps::MapData>, K: aya::Pod, V: aya::Pod> aya::maps::hash_map::HashMap<T, K, V>
pub fn aya::maps::hash_map::HashMap<T, K, V>::get(&self, key: &K, flags: u64) -> core::result::Result<V, aya::maps::MapError>
@ -1712,6 +2049,41 @@ impl<T> core::borrow::BorrowMut<T> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::stack_trace::StackTraceMap<T>
pub fn aya::maps::stack_trace::StackTraceMap<T>::from(t: T) -> T
pub struct aya::maps::XskMap<T>
impl<T: core::borrow::Borrow<aya::maps::MapData>> aya::maps::XskMap<T>
pub fn aya::maps::XskMap<T>::len(&self) -> u32
impl<T: core::borrow::BorrowMut<aya::maps::MapData>> aya::maps::XskMap<T>
pub fn aya::maps::XskMap<T>::set(&mut self, index: u32, socket_fd: impl std::os::fd::raw::AsRawFd, flags: u64) -> core::result::Result<(), aya::maps::MapError>
impl core::convert::TryFrom<aya::maps::Map> for aya::maps::XskMap<aya::maps::MapData>
pub type aya::maps::XskMap<aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<aya::maps::MapData>::try_from(map: aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a aya::maps::Map> for aya::maps::XskMap<&'a aya::maps::MapData>
pub type aya::maps::XskMap<&'a aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<&'a aya::maps::MapData>::try_from(map: &'a aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<'a> core::convert::TryFrom<&'a mut aya::maps::Map> for aya::maps::XskMap<&'a mut aya::maps::MapData>
pub type aya::maps::XskMap<&'a mut aya::maps::MapData>::Error = aya::maps::MapError
pub fn aya::maps::XskMap<&'a mut aya::maps::MapData>::try_from(map: &'a mut aya::maps::Map) -> core::result::Result<Self, Self::Error>
impl<T> core::marker::Send for aya::maps::XskMap<T> where T: core::marker::Send
impl<T> core::marker::Sync for aya::maps::XskMap<T> where T: core::marker::Sync
impl<T> core::marker::Unpin for aya::maps::XskMap<T> where T: core::marker::Unpin
impl<T> core::panic::unwind_safe::RefUnwindSafe for aya::maps::XskMap<T> where T: core::panic::unwind_safe::RefUnwindSafe
impl<T> core::panic::unwind_safe::UnwindSafe for aya::maps::XskMap<T> where T: core::panic::unwind_safe::UnwindSafe
impl<T, U> core::convert::Into<U> for aya::maps::XskMap<T> where U: core::convert::From<T>
pub fn aya::maps::XskMap<T>::into(self) -> U
impl<T, U> core::convert::TryFrom<U> for aya::maps::XskMap<T> where U: core::convert::Into<T>
pub type aya::maps::XskMap<T>::Error = core::convert::Infallible
pub fn aya::maps::XskMap<T>::try_from(value: U) -> core::result::Result<T, <T as core::convert::TryFrom<U>>::Error>
impl<T, U> core::convert::TryInto<U> for aya::maps::XskMap<T> where U: core::convert::TryFrom<T>
pub type aya::maps::XskMap<T>::Error = <U as core::convert::TryFrom<T>>::Error
pub fn aya::maps::XskMap<T>::try_into(self) -> core::result::Result<U, <U as core::convert::TryFrom<T>>::Error>
impl<T> core::any::Any for aya::maps::XskMap<T> where T: 'static + core::marker::Sized
pub fn aya::maps::XskMap<T>::type_id(&self) -> core::any::TypeId
impl<T> core::borrow::Borrow<T> for aya::maps::XskMap<T> where T: core::marker::Sized
pub fn aya::maps::XskMap<T>::borrow(&self) -> &T
impl<T> core::borrow::BorrowMut<T> for aya::maps::XskMap<T> where T: core::marker::Sized
pub fn aya::maps::XskMap<T>::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::maps::XskMap<T>
pub fn aya::maps::XskMap<T>::from(t: T) -> T
pub trait aya::maps::IterableMap<K: aya::Pod, V>
pub fn aya::maps::IterableMap::get(&self, key: &K) -> core::result::Result<V, aya::maps::MapError>
pub fn aya::maps::IterableMap::map(&self) -> &aya::maps::MapData
@ -4514,13 +4886,12 @@ pub fn aya::programs::xdp::Xdp::attach(&mut self, interface: &str, flags: aya::p
pub fn aya::programs::xdp::Xdp::attach_to_if_index(&mut self, if_index: u32, flags: aya::programs::xdp::XdpFlags) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::attach_to_link(&mut self, link: aya::programs::xdp::XdpLink) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::detach(&mut self, link_id: aya::programs::xdp::XdpLinkId) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::xdp::XdpAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::take_link(&mut self, link_id: aya::programs::xdp::XdpLinkId) -> core::result::Result<aya::programs::xdp::XdpLink, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@ -6681,13 +7052,12 @@ pub fn aya::programs::xdp::Xdp::attach(&mut self, interface: &str, flags: aya::p
pub fn aya::programs::xdp::Xdp::attach_to_if_index(&mut self, if_index: u32, flags: aya::programs::xdp::XdpFlags) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::attach_to_link(&mut self, link: aya::programs::xdp::XdpLink) -> core::result::Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::detach(&mut self, link_id: aya::programs::xdp::XdpLinkId) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P, attach_type: aya_obj::programs::xdp::XdpAttachType) -> core::result::Result<Self, aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::load(&mut self) -> core::result::Result<(), aya::programs::ProgramError>
pub fn aya::programs::xdp::Xdp::take_link(&mut self, link_id: aya::programs::xdp::XdpLinkId) -> core::result::Result<aya::programs::xdp::XdpLink, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::from_pin<P: core::convert::AsRef<std::path::Path>>(path: P) -> core::result::Result<Self, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::info(&self) -> core::result::Result<aya::programs::ProgramInfo, aya::programs::ProgramError>
impl aya::programs::xdp::Xdp
pub fn aya::programs::xdp::Xdp::pin<P: core::convert::AsRef<std::path::Path>>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError>
@ -7234,6 +7604,8 @@ pub fn aya::VerifierLogLevel::borrow_mut(&mut self) -> &mut T
impl<T> core::convert::From<T> for aya::VerifierLogLevel
pub fn aya::VerifierLogLevel::from(t: T) -> T
pub unsafe trait aya::Pod: core::marker::Copy + 'static
impl aya::Pod for aya_obj::generated::linux_bindings_x86_64::bpf_cpumap_val
impl aya::Pod for aya_obj::generated::linux_bindings_x86_64::bpf_devmap_val
impl aya::Pod for i128
impl aya::Pod for i16
impl aya::Pod for i32

Loading…
Cancel
Save