maps/xdp: improve XDP maps documentation

reviewable/pr527/r2
Tuetuopay 2 years ago
parent 7474b6b6a0
commit 545199a3da

@ -128,6 +128,35 @@ 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 = "true"` 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 = "true")]
/// pub fn xdp(ctx: XdpContext) -> u32 {
/// match unsafe { try_xdp(ctx) } {
/// Ok(ret) => ret,
/// Err(ret) => ret,
/// }
/// }
///
/// unsafe fn try_xdp(_ctx: XdpContext) -> Result<u32, u32> {
/// Ok(XDP_PASS)
/// }
/// ```
#[proc_macro_error]
#[proc_macro_attribute]
pub fn xdp(attrs: TokenStream, item: TokenStream) -> TokenStream {

@ -60,19 +60,19 @@ impl<T: Borrow<MapData>> CpuMap<T> {
self.inner.borrow().obj.max_entries()
}
/// Returns the value stored at the given index.
/// Returns the queue size and possible program for a given CPU 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<CpuMapValue, MapError> {
/// 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, index)?;
check_bounds(data, cpu_index)?;
let fd = data.fd;
let value =
bpf_map_lookup_elem(fd, &index, flags).map_err(|(_, io_error)| SyscallError {
bpf_map_lookup_elem(fd, &cpu_index, flags).map_err(|(_, io_error)| SyscallError {
call: "bpf_map_lookup_elem",
io_error,
})?;
@ -88,7 +88,18 @@ impl<T: Borrow<MapData>> CpuMap<T> {
}
impl<T: BorrowMut<MapData>> CpuMap<T> {
/// Sets the value of the element at the given index.
/// 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.
///
/// Another XDP program can be passed in that will be run on the target CPU, instead of the CPU
/// that receives the packets. This allows to perform minimal computations on CPUs that
/// directly handle packets from a NIC's RX queues, and perform possibly heavier ones in other,
/// less busy CPUs.
///
/// Note that only XDP programs with the `map = "cpumap"` argument can be passed. See the
/// kernel-space `aya_bpf::xdp` for more information.
///
/// # Errors
///
@ -96,22 +107,22 @@ impl<T: BorrowMut<MapData>> CpuMap<T> {
/// if `bpf_map_update_elem` fails.
pub fn set(
&mut self,
index: u32,
value: u32,
cpu_index: u32,
queue_size: u32,
program: Option<impl AsRawFd>,
flags: u64,
) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
check_bounds(data, index)?;
check_bounds(data, cpu_index)?;
let fd = data.fd;
let value = bpf_cpumap_val {
qsize: value,
qsize: queue_size,
bpf_prog: bpf_cpumap_val__bindgen_ty_1 {
fd: program.map(|prog| prog.as_raw_fd()).unwrap_or_default(),
},
};
bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(_, io_error)| {
bpf_map_update_elem(fd, Some(&cpu_index), &value, flags).map_err(|(_, io_error)| {
SyscallError {
call: "bpf_map_update_elem",
io_error,

@ -54,7 +54,7 @@ impl<T: Borrow<MapData>> DevMap<T> {
self.inner.borrow().obj.max_entries()
}
/// Returns the value stored at the given index.
/// Returns the target ifindex and possible program at a given index.
///
/// # Errors
///
@ -82,7 +82,17 @@ impl<T: Borrow<MapData>> DevMap<T> {
}
impl<T: BorrowMut<MapData>> DevMap<T> {
/// Sets the value of the element at the given index.
/// Sets the target ifindex at index, and optionally a chained program.
///
/// When redirecting using `index`, packets will be transmitted by the interface with
/// `ifindex`.
///
/// Another XDP program can be passed in that will be run before actual transmission. It can be
/// used to modify the packet before transmission with NIC specific data (MAC address update,
/// checksum computations, etc) or other purposes.
///
/// Note that only XDP programs with the `map = "devmap"` argument can be passed. See the
/// kernel-space `aya_bpf::xdp` for more information.
///
/// # Errors
///
@ -91,7 +101,7 @@ impl<T: BorrowMut<MapData>> DevMap<T> {
pub fn set(
&mut self,
index: u32,
value: u32,
ifindex: u32,
program: Option<impl AsRawFd>,
flags: u64,
) -> Result<(), MapError> {
@ -100,7 +110,7 @@ impl<T: BorrowMut<MapData>> DevMap<T> {
let fd = data.fd;
let value = bpf_devmap_val {
ifindex: value,
ifindex,
bpf_prog: bpf_devmap_val__bindgen_ty_1 {
fd: program.map(|prog| prog.as_raw_fd()).unwrap_or_default(),
},

@ -48,16 +48,14 @@ impl<T: Borrow<MapData>> DevMapHash<T> {
Ok(Self { inner: map })
}
/// Returns the value stored at the given index.
/// Returns the target ifindex and possible program for a given key.
///
/// # 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> {
/// 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;
let value =
bpf_map_lookup_elem(fd, &index, flags).map_err(|(_, io_error)| SyscallError {
let value = bpf_map_lookup_elem(fd, &key, flags).map_err(|(_, io_error)| SyscallError {
call: "bpf_map_lookup_elem",
io_error,
})?;
@ -66,7 +64,7 @@ impl<T: Borrow<MapData>> DevMapHash<T> {
}
/// An iterator over the elements of the devmap in arbitrary order. The iterator item type is
/// `Result<(u32, u32), MapError>`.
/// `Result<(u32, DevMapValue), MapError>`.
pub fn iter(&self) -> MapIter<'_, u32, DevMapValue, Self> {
MapIter::new(self)
}
@ -79,28 +77,37 @@ impl<T: Borrow<MapData>> DevMapHash<T> {
}
impl<T: BorrowMut<MapData>> DevMapHash<T> {
/// Inserts a value in the map.
/// Inserts an ifindex and optionally a chained program in the map.
///
/// When redirecting using `key`, packets will be transmitted by the interface with `ifindex`.
///
/// Another XDP program can be passed in that will be run before actual transmission. It can be
/// used to modify the packet before transmission with NIC specific data (MAC address update,
/// checksum computations, etc) or other purposes.
///
/// Note that only XDP programs with the `map = "devmap"` argument can be passed. See the
/// kernel-space `aya_bpf::xdp` for more information.
///
/// # Errors
///
/// Returns [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
pub fn insert(
&mut self,
index: u32,
value: u32,
key: u32,
ifindex: u32,
program: Option<impl AsRawFd>,
flags: u64,
) -> Result<(), MapError> {
let value = bpf_devmap_val {
ifindex: value,
ifindex,
bpf_prog: bpf_devmap_val__bindgen_ty_1 {
fd: program.map(|prog| prog.as_raw_fd()).unwrap_or_default(),
},
};
hash_map::insert(self.inner.borrow_mut(), &index, &value, flags)
hash_map::insert(self.inner.borrow_mut(), &key, &value, flags)
}
/// Remove a value from the map.
/// Removes a value from the map.
///
/// # Errors
///

@ -52,17 +52,21 @@ impl<T: Borrow<MapData>> XskMap<T> {
}
impl<T: BorrowMut<MapData>> XskMap<T> {
/// Sets the value of the element at the given index.
/// 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<V: AsRawFd>(&mut self, index: u32, value: V, flags: u64) -> Result<(), MapError> {
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;
bpf_map_update_elem(fd, Some(&index), &value.as_raw_fd(), flags).map_err(
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,

@ -41,8 +41,8 @@ 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.
/// are CPU cores on the system. It can be set to zero here, and updated by userspace at
/// runtime. Refer to the userspace documentation for more information.
///
/// # Examples
///

Loading…
Cancel
Save