Browse Source

More doc fixes

Alessandro Decina 3 years ago
parent
commit
6c7df27bd0

+ 2 - 0
aya/src/maps/map_lock.rs

@@ -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>,

+ 1 - 0
aya/src/maps/mod.rs

@@ -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 - 0
aya/src/maps/queue.rs

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

+ 1 - 0
aya/src/maps/sock/mod.rs

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

+ 41 - 15
aya/src/maps/sock/sock_hash.rs

@@ -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)
     }
 }

+ 21 - 9
aya/src/maps/sock/sock_map.rs

@@ -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)?;

+ 14 - 13
aya/src/maps/stack.rs

@@ -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)| {

+ 10 - 1
aya/src/programs/sk_skb.rs

@@ -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()?;