Skip to content

Commit

Permalink
bpf: add documentation for XDP maps
Browse files Browse the repository at this point in the history
  • Loading branch information
Tuetuopay committed Mar 2, 2023
1 parent c325332 commit d1c4b72
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 0 deletions.
68 changes: 68 additions & 0 deletions bpf/aya-bpf/src/maps/xdp/cpu_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@ use crate::{
maps::PinningType,
};

/// 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>,
Expand All @@ -16,6 +38,20 @@ pub struct CpuMap {
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. To dynamically set the entry count at runtime, refer to the
/// userspace documentation.
///
/// # 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 {
Expand All @@ -30,6 +66,19 @@ impl CpuMap {
}
}

/// 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 {
Expand All @@ -44,6 +93,25 @@ impl CpuMap {
}
}

/// 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) -> i32 {
/// // Redirect to CPU 7 or drop packet if no entry found.
/// MAP.redirect(7, xdp_action::XDP_DROP as u64)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, index: u32, flags: u64) -> u32 {
unsafe { bpf_redirect_map(self.def.get() as *mut _, index as u64, flags) as u32 }
Expand Down
76 changes: 76 additions & 0 deletions bpf/aya-bpf/src/maps/xdp/dev_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,27 @@ use crate::{
maps::PinningType,
};

/// 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>,
Expand All @@ -17,6 +38,16 @@ pub struct DevMap {
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 {
Expand All @@ -31,6 +62,17 @@ impl DevMap {
}
}

/// 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 {
Expand All @@ -45,6 +87,22 @@ impl DevMap {
}
}

/// 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 ifindex = MAP.get(0);
///
/// // redirect to ifindex
/// ```
#[inline(always)]
pub fn get(&self, index: u32) -> Option<bpf_devmap_val> {
unsafe {
Expand All @@ -56,6 +114,24 @@ impl DevMap {
}
}

/// 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) -> i32 {
/// MAP.redirect(7, xdp_action::XDP_PASS as u64)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, index: u32, flags: u64) -> u32 {
unsafe { bpf_redirect_map(self.def.get() as *mut _, index as u64, flags) as u32 }
Expand Down
78 changes: 78 additions & 0 deletions bpf/aya-bpf/src/maps/xdp/dev_map_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,29 @@ use crate::{
maps::PinningType,
};

/// 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>,
Expand All @@ -17,6 +40,16 @@ pub struct DevMapHash {
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 {
Expand All @@ -31,6 +64,17 @@ impl DevMapHash {
}
}

/// 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 {
Expand All @@ -45,6 +89,22 @@ impl DevMapHash {
}
}

/// 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 ifindex = MAP.get(42);
///
/// // redirect to ifindex
/// ```
#[inline(always)]
pub fn get(&self, key: u32) -> Option<bpf_devmap_val> {
unsafe {
Expand All @@ -54,6 +114,24 @@ impl DevMapHash {
}
}

/// 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) -> i32 {
/// MAP.redirect(7, xdp_action::XDP_PASS as u64)
/// }
/// ```
#[inline(always)]
pub fn redirect(&self, key: u32, flags: u64) -> u32 {
unsafe { bpf_redirect_map(self.def.get() as *mut _, key as u64, flags) as u32 }
Expand Down
Loading

0 comments on commit d1c4b72

Please sign in to comment.