More doc fixes

pull/1/head
Alessandro Decina 3 years ago
parent 28158e6028
commit 6c7df27bd0

@ -46,11 +46,13 @@ impl MapLock {
}
}
/// A borrowed reference to a BPF map.
pub struct MapRef {
_lock: Arc<RwLock<Map>>,
guard: RwLockReadGuard<'static, Map>,
}
/// A mutable borrowed reference to a BPF map.
pub struct MapRefMut {
_lock: Arc<RwLock<Map>>,
guard: RwLockWriteGuard<'static, Map>,

@ -117,6 +117,7 @@ pub enum MapError {
BorrowMutError { name: String },
}
/// A generic handle to a BPF map.
#[derive(Debug)]
pub struct Map {
pub(crate) obj: obj::Map,

@ -1,3 +1,4 @@
//! A FIFO queue.
use std::{
convert::TryFrom,
marker::PhantomData,

@ -1,3 +1,4 @@
//! Socket maps.
mod sock_hash;
mod sock_map;

@ -14,22 +14,48 @@ use crate::{
Pod,
};
/// A hash map that can be shared between eBPF programs and user space.
/// A hash map of TCP or UDP sockets.
///
/// It is required that both keys and values implement the [`Pod`] trait.
/// A `SockHash` is used to store TCP or UDP sockets. eBPF programs can then be
/// attached to the map to inspect, filter or redirect network buffers on those
/// sockets.
///
/// A `SockHash` can also be used to redirect packets to sockets contained by the
/// map using `bpf_redirect_map()`, `bpf_sk_redirect_hash()` etc.
///
/// # Example
///
/// ```no_run
/// # let bpf = aya::Bpf::load(&[], None)?;
/// ##[derive(Debug, thiserror::Error)]
/// # enum Error {
/// # #[error(transparent)]
/// # IO(#[from] std::io::Error),
/// # #[error(transparent)]
/// # Map(#[from] aya::maps::MapError),
/// # #[error(transparent)]
/// # Program(#[from] aya::programs::ProgramError),
/// # #[error(transparent)]
/// # Bpf(#[from] aya::BpfError)
/// # }
/// # let mut bpf = aya::Bpf::load(&[], None)?;
/// use std::convert::{TryFrom, TryInto};
/// use std::io::Write;
/// use std::net::TcpStream;
/// use std::os::unix::io::AsRawFd;
/// use aya::maps::SockHash;
/// use std::convert::TryFrom;
/// use aya::programs::SkMsg;
///
/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?;
/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet")?.try_into()?;
/// prog.load()?;
/// prog.attach(&intercept_egress)?;
///
/// const CONFIG_KEY_NUM_RETRIES: u8 = 1;
/// let mut client = TcpStream::connect("127.0.0.1:1234")?;
/// intercept_egress.insert(1234, client.as_raw_fd(), 0)?;
///
/// let mut hm = SockHash::try_from(bpf.map_mut("CONFIG")?)?;
/// hm.insert(CONFIG_KEY_NUM_RETRIES, 3, 0 /* flags */);
/// # Ok::<(), aya::BpfError>(())
/// // the write will be intercepted
/// client.write_all(b"foo")?;
/// # Ok::<(), Error>(())
/// ```
#[doc(alias = "BPF_MAP_TYPE_SOCKHASH")]
pub struct SockHash<T: Deref<Target = Map>, K> {
@ -56,8 +82,8 @@ impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
})
}
/// Returns a copy of the value associated with the key.
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<u32, MapError> {
/// Returns the fd of the socket stored at the given key.
pub unsafe fn get(&self, key: &K, flags: u64) -> Result<RawFd, MapError> {
let fd = self.inner.deref().fd_or_err()?;
let value = bpf_map_lookup_elem(fd, key, flags).map_err(|(code, io_error)| {
MapError::SyscallError {
@ -71,7 +97,7 @@ impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
/// An iterator visiting all key-value pairs in arbitrary order. The
/// iterator item type is `Result<(K, V), MapError>`.
pub unsafe fn iter(&self) -> MapIter<'_, K, u32> {
pub unsafe fn iter(&self) -> MapIter<'_, K, RawFd> {
MapIter::new(self)
}
@ -83,23 +109,23 @@ impl<T: Deref<Target = Map>, K: Pod> SockHash<T, K> {
}
impl<T: DerefMut<Target = Map>, K: Pod> SockHash<T, K> {
/// Inserts a key-value pair into the map.
/// Inserts a socket under the given key.
pub fn insert<I: AsRawFd>(&mut self, key: K, value: I, flags: u64) -> Result<(), MapError> {
hash_map::insert(&mut self.inner, key, value.as_raw_fd(), flags)
}
/// Removes a key from the map.
/// Removes a socket from the map.
pub fn remove(&mut self, key: &K) -> Result<(), MapError> {
hash_map::remove(&mut self.inner, key)
}
}
impl<T: Deref<Target = Map>, K: Pod> IterableMap<K, u32> for SockHash<T, K> {
impl<T: Deref<Target = Map>, K: Pod> IterableMap<K, RawFd> for SockHash<T, K> {
fn map(&self) -> &Map {
&self.inner
}
unsafe fn get(&self, key: &K) -> Result<u32, MapError> {
unsafe fn get(&self, key: &K) -> Result<RawFd, MapError> {
SockHash::get(self, key, 0)
}
}

@ -13,14 +13,29 @@ use crate::{
sys::{bpf_map_delete_elem, bpf_map_update_elem},
};
/// An array of TCP or UDP sock objects. Primarly used for doing socket redirect with eBPF helpers.
/// An array of TCP or UDP sockets.
///
/// A sock map can have two eBPF programs attached: one to parse packets and one to provide a
/// redirect decision on packets. Whenever a sock object is added to the map, the map's programs
/// are automatically attached to the socket.
/// A `SockMap` is used to store TCP or UDP sockets. eBPF programs can then be
/// attached to the map to inspect, filter or redirect network buffers on those
/// sockets.
///
/// A `SockMap` can also be used to redirect packets to sockets contained by the
/// map using `bpf_redirect_map()`, `bpf_sk_redirect_map()` etc.
///
/// # Example
///
/// ```no_run
/// # let mut bpf = aya::Bpf::load(&[], None)?;
/// use std::convert::{TryFrom, TryInto};
/// use aya::maps::SockMap;
/// use aya::programs::SkMsg;
///
/// let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?;
/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet")?.try_into()?;
/// prog.load()?;
/// prog.attach(&intercept_egress)?;
/// # Ok::<(), aya::BpfError>(())
/// ```
pub struct SockMap<T: Deref<Target = Map>> {
pub(crate) inner: T,
}
@ -66,10 +81,7 @@ impl<T: Deref<Target = Map>> SockMap<T> {
}
impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
/// Stores a TCP socket into the map.
///
/// eBPF programs can then pass `index` to the `bpf_sk_redirect_map()` helper to redirect
/// packets to the corresponding socket.
/// Stores a socket into the map.
pub fn set<I: AsRawFd>(&mut self, index: u32, socket: &I, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(index)?;
@ -83,7 +95,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> SockMap<T> {
Ok(())
}
/// Removes the TCP socket stored at `index` from the map.
/// Removes the socket stored at `index` from the map.
pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
self.check_bounds(*index)?;

@ -1,3 +1,4 @@
//! A LIFO stack.
use std::{
convert::TryFrom,
marker::PhantomData,
@ -13,6 +14,19 @@ use crate::{
};
/// A LIFO stack.
///
/// # Example
/// ```no_run
/// # let bpf = aya::Bpf::load(&[], None)?;
/// use aya::maps::Stack;
/// use std::convert::TryFrom;
///
/// let mut stack = Stack::try_from(bpf.map_mut("STACK")?)?;
/// stack.push(42, 0)?;
/// stack.push(43, 0)?;
/// assert_eq!(stack.pop(0)?, 43);
/// # Ok::<(), aya::BpfError>(())
/// ```
pub struct Stack<T: Deref<Target = Map>, V: Pod> {
inner: T,
_v: PhantomData<V>,
@ -78,19 +92,6 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>, V: Pod> Stack<T, V> {
/// # Errors
///
/// [`MapError::SyscallError`] if `bpf_map_update_elem` fails.
///
/// # Example
/// ```no_run
/// # let bpf = aya::Bpf::load(&[], None)?;
/// use aya::maps::Stack;
/// use std::convert::TryFrom;
///
/// let mut stack = Stack::try_from(bpf.map_mut("ARRAY")?)?;
/// stack.push(42, 0)?;
/// stack.push(43, 0)?;
/// assert_eq!(stack.pop(0)?, 43);
/// # Ok::<(), aya::BpfError>(())
/// ```
pub fn push(&mut self, value: V, flags: u64) -> Result<(), MapError> {
let fd = self.inner.fd_or_err()?;
bpf_map_update_elem(fd, &0, &value, flags).map_err(|(code, io_error)| {

@ -14,6 +14,15 @@ pub enum SkSkbKind {
StreamVerdict,
}
/// A socket buffer program.
///
/// Socket buffer programs are attached to [socket maps], and can be used to
/// inspect, redirect or filter packet. See [SockMap] and [SockHash] for more
/// info and examples.
///
/// [socket maps]: crate::maps::sock
/// [SockMap]: crate::maps::SockMap
/// [SockHash]: crate::maps::SockHash
#[derive(Debug)]
pub struct SkSkb {
pub(crate) data: ProgramData,
@ -33,7 +42,7 @@ impl SkSkb {
self.data.name.to_string()
}
/// Attaches the program to the given sockmap.
/// Attaches the program to the given socket map.
pub fn attach(&mut self, map: &dyn SocketMap) -> Result<LinkRef, ProgramError> {
let prog_fd = self.data.fd_or_err()?;
let map_fd = map.fd_or_err()?;

Loading…
Cancel
Save