aya: tweak docs

pull/1/head
Alessandro Decina 4 years ago
parent f464279740
commit ad6d0596ab

@ -6,23 +6,28 @@
//!
//! Aya is an eBPF library built with a focus on operability and developer experience. It does not
//! rely on [libbpf](https://github.com/libbpf/libbpf) nor [bcc](https://github.com/iovisor/bcc) -
//! it's built from the ground up purely in Rust, using the Linux system call interface directly to
//! load and interact with programs. When linked with musl and in conjunction with BTF, it provides
//! a true [compile once, run everywhere solution](https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html).
//! it's built from the ground up purely in Rust, using only the [libc](https://crates.io/libc)
//! crate to execute syscalls. With BTF support and when linked with musl, it offers a true
//! [compile once, run everywhere
//! solution](https://facebookmicrosites.github.io/bpf/blog/2020/02/19/bpf-portability-and-co-re.html),
//! where one self-contained binary can be deployed on many linux distributions
//! and kernel versions.
//!
//! Some of the major features provided include:
//!
//! * Support for the BPF Type Format (BTF), which is transparently enabled when
//! supported by the target kernel.
//! * Support for global data maps, which means that eBPF programs can make use of global
//! data and variables. This is especially useful when the eBPF code itself is written
//! in Rust, and makes use of byte literals and other initializers that result
//! in global data being created.
//! supported by the target kernel. This allows eBPF programs compiled against
//! one kernel version to run on different kernel versions without the need to
//! recompile.
//! * Support for global data maps, which allows eBPF programs to make use of global data and
//! variables. This is especially useful when the eBPF code itself is written in Rust, and makes
//! use of byte literals and other initializers that get place in global data sections.
//! * Support for function calls, so eBPF programs can call other functions and are not
//! forced to inline everything.
//! * Async support with both [tokio](https://docs.rs/tokio) and [async-std](https://docs.rs/async-std).
//! * Easy to deploy and fast to build: aya doesn't require kernel headers nor a
//! C toolchain and a release build completes in a matter of seconds.
//! * Easy to deploy and fast to build: aya doesn't require a kernel build or
//! compiled headers, and not even a C toolchain; a release build completes in a matter
//! of seconds.
//!
//! # Minimum kernel version
//!

@ -77,7 +77,7 @@ impl<T: Deref<Target = Map>, V: Pod> Array<T, V> {
/// An iterator over the elements of the array. The iterator item type is `Result<V,
/// MapError>`.
pub unsafe fn iter<'coll>(&'coll self) -> impl Iterator<Item = Result<V, MapError>> + 'coll {
pub unsafe fn iter<'a>(&'a self) -> impl Iterator<Item = Result<V, MapError>> + 'a {
(0..self.len()).map(move |i| self.get(&i, 0))
}

@ -16,6 +16,37 @@ use crate::{
///
/// The size of the array is defined on the eBPF side using the `bpf_map_def::max_entries` field.
/// All the entries are zero-initialized when the map is created.
///
/// # Example
/// ```no_run
/// # #[derive(thiserror::Error, Debug)]
/// # enum Error {
/// # #[error(transparent)]
/// # IO(#[from] std::io::Error),
/// # #[error(transparent)]
/// # Map(#[from] aya::maps::MapError),
/// # #[error(transparent)]
/// # Bpf(#[from] aya::BpfError)
/// # }
/// # let bpf = aya::Bpf::load(&[], None)?;
/// use aya::maps::{PerCpuArray, PerCpuValues};
/// use aya::util::nr_cpus;
/// use std::convert::TryFrom;
///
/// let mut array = PerCpuArray::try_from(bpf.map_mut("ARRAY")?)?;
///
/// // set array[1] = 42 for all cpus
/// let nr_cpus = nr_cpus()?;
/// array.set(1, PerCpuValues::try_from(vec![42u32; nr_cpus])?, 0)?;
///
/// // retrieve the values at index 1 for all cpus
/// let values = array.get(&1, 0)?;
/// assert_eq!(values.len(), nr_cpus);
/// for cpu_val in values.iter() {
/// assert_eq!(*cpu_val, 42u32);
/// }
/// # Ok::<(), Error>(())
/// ```
pub struct PerCpuArray<T: Deref<Target = Map>, V: Pod> {
inner: T,
_v: PhantomData<V>,
@ -77,9 +108,9 @@ impl<T: Deref<Target = Map>, V: Pod> PerCpuArray<T, V> {
/// An iterator over the elements of the array. The iterator item type is
/// `Result<PerCpuValues<V>, MapError>`.
pub unsafe fn iter<'coll>(
&'coll self,
) -> impl Iterator<Item = Result<PerCpuValues<V>, MapError>> + 'coll {
pub unsafe fn iter<'a>(
&'a self,
) -> impl Iterator<Item = Result<PerCpuValues<V>, MapError>> + 'a {
(0..self.len()).map(move |i| self.get(&i, 0))
}
@ -100,28 +131,6 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> PerCpuArray<T, V>
///
/// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`]
/// if `bpf_map_update_elem` fails.
///
/// # Example
/// ```no_run
/// # #[derive(thiserror::Error, Debug)]
/// # enum Error {
/// # #[error(transparent)]
/// # IO(#[from] std::io::Error),
/// # #[error(transparent)]
/// # Map(#[from] aya::maps::MapError),
/// # #[error(transparent)]
/// # Bpf(#[from] aya::BpfError)
/// # }
/// # let bpf = aya::Bpf::load(&[], None)?;
/// use aya::maps::{PerCpuArray, PerCpuValues};
/// use aya::util::nr_cpus;
/// use std::convert::TryFrom;
///
/// let mut array = PerCpuArray::try_from(bpf.map_mut("ARRAY")?)?;
/// array.set(1, PerCpuValues::try_from(vec![42u32; nr_cpus()?])?, 0)?;
/// assert_eq!(&**array.get(&1, 0)?, vec![42u32; nr_cpus()?].as_slice());
/// # Ok::<(), Error>(())
/// ```
pub fn set(&mut self, index: u32, values: PerCpuValues<V>, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?;

@ -16,8 +16,30 @@ use crate::{
/// An array of eBPF program file descriptors used as a jump table.
///
/// eBPF programs can jump to other programs calling `bpf_tail_call(prog_array, index)`. User space
/// programs can use [`ProgramArray`] to configure which programs correspond to which jump indexes.
/// eBPF programs can jump to other programs calling `bpf_tail_call(prog_array, index)`. You can
/// use [`ProgramArray`] to configure which programs correspond to which jump indexes.
///
/// # Example
/// ```no_run
/// # let bpf = aya::Bpf::load(&[], None)?;
/// use aya::maps::ProgramArray;
/// use aya::programs::KProbe;
/// use std::convert::{TryFrom, TryInto};
///
/// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?;
/// let prog_0: &KProbe = bpf.program("example_prog_0")?.try_into()?;
/// let prog_1: &KProbe = bpf.program("example_prog_1")?.try_into()?;
/// let prog_2: &KProbe = bpf.program("example_prog_2")?.try_into()?;
///
/// let flags = 0;
/// // bpf_tail_call(JUMP_TABLE, 0) will jump to prog_0
/// prog_array.set(0, prog_0, flags);
/// // bpf_tail_call(JUMP_TABLE, 0) will jump to prog_1
/// prog_array.set(1, prog_1, flags);
/// // bpf_tail_call(JUMP_TABLE, 0) will jump to prog_2
/// prog_array.set(2, prog_2, flags);
/// # Ok::<(), aya::BpfError>(())
/// ```
pub struct ProgramArray<T: Deref<Target = Map>> {
inner: T,
}
@ -67,19 +89,6 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
///
/// When an eBPF program calls `bpf_tail_call(prog_array, index)`, control
/// flow will jump to `program`.
///
/// # Example
/// ```no_run
/// # let bpf = aya::Bpf::load(&[], None)?;
/// use aya::maps::ProgramArray;
/// use aya::programs::KProbe;
/// use std::convert::{TryFrom, TryInto};
///
/// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?;
/// let prog: &KProbe = bpf.program("example_prog")?.try_into()?;
/// prog_array.set(0, prog, 0 /* flags */);
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn set(&mut self, index: u32, program: &dyn ProgramFd, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?;

@ -2,7 +2,6 @@ use std::{
convert::TryFrom,
marker::PhantomData,
ops::{Deref, DerefMut},
os::unix::io::RawFd,
};
use crate::{

@ -3,7 +3,6 @@ use std::{
convert::TryFrom,
marker::PhantomData,
ops::{Deref, DerefMut},
os::unix::io::RawFd,
};
use crate::{

@ -1,9 +1,9 @@
//! eBPF data structures used to exchange data with eBPF programs.
//! Data structures used to exchange data with eBPF programs.
//!
//! The eBPF platform provides data structures - maps in eBPF speak - that can be used by eBPF
//! programs and user-space to exchange data. When you call
//! [`Bpf::load_file`](crate::Bpf::load_file) or [`Bpf::load`](crate::Bpf::load), all the maps
//! defined in the code get initialized and can then be accessed using
//! defined in the eBPF code get initialized and can then be accessed using
//! [`Bpf::map`](crate::Bpf::map) and [`Bpf::map_mut`](crate::Bpf::map_mut).
//!
//! # Concrete map types

Loading…
Cancel
Save