aya: add some docs for the crate and `Bpf`

pull/1/head
Alessandro Decina 4 years ago
parent 563ce46118
commit 1bbbf616b6

@ -55,6 +55,7 @@ pub(crate) struct bpf_map_def {
pub(crate) map_flags: u32, pub(crate) map_flags: u32,
} }
/// Used to work with eBPF programs and maps.
#[derive(Debug)] #[derive(Debug)]
pub struct Bpf { pub struct Bpf {
maps: HashMap<String, MapLock>, maps: HashMap<String, MapLock>,
@ -62,6 +63,20 @@ pub struct Bpf {
} }
impl Bpf { impl Bpf {
/// Loads eBPF bytecode from a file.
///
/// Parses the given object code file and initializes the [maps](crate::maps) defined in it. If
/// the kernel supports [BTF](Btf) debug info, it is automatically loaded from
/// `/sys/kernel/btf/vmlinux`.
///
/// # Examples
///
/// ```no_run
/// use aya::Bpf;
///
/// let bpf = Bpf::load_file("file.o")?;
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn load_file<P: AsRef<Path>>(path: P) -> Result<Bpf, BpfError> { pub fn load_file<P: AsRef<Path>>(path: P) -> Result<Bpf, BpfError> {
let path = path.as_ref(); let path = path.as_ref();
Bpf::load( Bpf::load(
@ -73,6 +88,23 @@ impl Bpf {
) )
} }
/// Load eBPF bytecode.
///
/// Parses the object code contained in `data` and initializes the [maps](crate::maps) defined
/// in it. If `target_btf` is `Some` and `data` includes BTF debug info, [BTF](Btf) relocations
/// are applied as well.
///
/// # Examples
///
/// ```no_run
/// use aya::{Bpf, Btf};
/// use std::fs;
///
/// let data = fs::read("file.o").unwrap();
/// // load the BTF data from /sys/kernel/btf/vmlinux
/// let bpf = Bpf::load(&data, Some(Btf::from_sys_fs()?));
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn load(data: &[u8], target_btf: Option<Btf>) -> Result<Bpf, BpfError> { pub fn load(data: &[u8], target_btf: Option<Btf>) -> Result<Bpf, BpfError> {
let mut obj = Object::parse(data)?; let mut obj = Object::parse(data)?;
@ -155,6 +187,18 @@ impl Bpf {
}) })
} }
/// Returns a reference to the map with the given name.
///
/// The returned type is mostly opaque. In order to do anything useful with it you need to
/// convert it to a [concrete map type](crate::maps).
///
/// For more details and examples on maps and their usage, see the [maps module
/// documentation][crate::maps].
///
/// # Errors
///
/// Returns [`MapError::NotFound`] if the map does not exist. If the map is already borrowed
/// mutably with [map_mut](Self::map_mut) then [`MapError::BorrowError`] is returned.
pub fn map(&self, name: &str) -> Result<MapRef, MapError> { pub fn map(&self, name: &str) -> Result<MapRef, MapError> {
self.maps self.maps
.get(name) .get(name)
@ -168,6 +212,18 @@ impl Bpf {
}) })
} }
/// Returns a mutable reference to the map with the given name.
///
/// The returned type is mostly opaque. In order to do anything useful with it you need to
/// convert it to a [concrete map type](crate::maps).
///
/// For more details and examples on maps and their usage, see the [maps module
/// documentation][crate::maps].
///
/// # Errors
///
/// Returns [`MapError::NotFound`] if the map does not exist. If the map is already borrowed
/// mutably with [map_mut](Self::map_mut) then [`MapError::BorrowError`] is returned.
pub fn map_mut(&self, name: &str) -> Result<MapRefMut, MapError> { pub fn map_mut(&self, name: &str) -> Result<MapRefMut, MapError> {
self.maps self.maps
.get(name) .get(name)
@ -181,6 +237,20 @@ impl Bpf {
}) })
} }
/// An iterator over all the maps.
///
/// # Examples
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[], None)?;
/// for (name, map) in bpf.maps() {
/// println!(
/// "found map `{}` of type `{:?}`",
/// name,
/// map?.map_type().unwrap()
/// );
/// }
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn maps<'a>(&'a self) -> impl Iterator<Item = (&'a str, Result<MapRef, MapError>)> + 'a { pub fn maps<'a>(&'a self) -> impl Iterator<Item = (&'a str, Result<MapRef, MapError>)> + 'a {
let ret = self.maps.iter().map(|(name, lock)| { let ret = self.maps.iter().map(|(name, lock)| {
( (
@ -192,6 +262,26 @@ impl Bpf {
ret ret
} }
/// Returns a reference to the program with the given name.
///
/// You can use this to inspect a program and its properties. To load and attach a program, use
/// [program_mut](Self::program_mut) instead.
///
/// For more details on programs and their usage, see the [programs module
/// documentation](crate::programs).
///
/// # Errors
///
/// Returns [`ProgramError::NotFound`] if the program does not exist.
///
/// # Example
///
/// ```no_run
/// # let bpf = aya::Bpf::load(&[], None)?;
/// let program = bpf.program("SSL_read")?;
/// println!("program SSL_read is of type {:?}", program.prog_type());
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn program(&self, name: &str) -> Result<&Program, ProgramError> { pub fn program(&self, name: &str) -> Result<&Program, ProgramError> {
self.programs self.programs
.get(name) .get(name)
@ -200,6 +290,27 @@ impl Bpf {
}) })
} }
/// Returns a mutable reference to the program with the given name.
///
/// Used to get a program before loading and attaching it. For more details on programs and
/// their usage, see the [programs module documentation](crate::programs).
///
/// # Errors
///
/// Returns [`ProgramError::NotFound`] if the program does not exist.
///
/// # Example
///
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[], None)?;
/// use aya::programs::UProbe;
/// use std::convert::TryInto;
///
/// let program: &mut UProbe = bpf.program_mut("SSL_read")?.try_into()?;
/// program.load()?;
/// program.attach(Some("SSL_read"), 0, "libssl", None)?;
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn program_mut(&mut self, name: &str) -> Result<&mut Program, ProgramError> { pub fn program_mut(&mut self, name: &str) -> Result<&mut Program, ProgramError> {
self.programs self.programs
.get_mut(name) .get_mut(name)
@ -208,6 +319,20 @@ impl Bpf {
}) })
} }
/// An iterator over all the programs.
///
/// # Examples
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[], None)?;
/// for program in bpf.programs() {
/// println!(
/// "found program `{}` of type `{:?}`",
/// program.name(),
/// program.prog_type()
/// );
/// }
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn programs(&self) -> impl Iterator<Item = &Program> { pub fn programs(&self) -> impl Iterator<Item = &Program> {
self.programs.values() self.programs.values()
} }

@ -1,3 +1,33 @@
//! A library to work with eBPF programs.
//!
//! eBPF is a technology that allows running user-supplied programs inside the
//! Linux kernel. For more info see
//! [https://ebpf.io/what-is-ebpf](https://ebpf.io/what-is-ebpf).
//!
//! 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).
//!
//! 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.
//! * 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.
//!
//!
//! # Minimum kernel version
//!
//! Aya currently supports kernels version 5.4 (latest LTS) and newer.
#![deny(clippy::all)] #![deny(clippy::all)]
#[macro_use] #[macro_use]

Loading…
Cancel
Save