diff --git a/aya/Cargo.toml b/aya/Cargo.toml index 735d892d..b4d9a932 100644 --- a/aya/Cargo.toml +++ b/aya/Cargo.toml @@ -17,7 +17,6 @@ object = { version = "0.27", default-features = false, features = ["std", "read_ bitflags = "1.2.1" bytes = "1" lazy_static = "1" -parking_lot = { version = "0.11.1", features = ["send_guard"] } futures = { version = "0.3.12", optional = true, default-features = false, features = ["std"] } tokio = { version = "1.2.0", features = ["macros", "rt", "rt-multi-thread", "net"], optional = true } async-std = { version = "1.9.0", optional = true } diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 0ae2bf61..e5bc42ec 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -1,6 +1,6 @@ use std::{ borrow::Cow, - collections::HashMap, + collections::{hash_map::Entry, HashMap}, error::Error, ffi::CString, fs, io, @@ -15,7 +15,7 @@ use crate::{ bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, AYA_PERF_EVENT_IOC_DISABLE, AYA_PERF_EVENT_IOC_ENABLE, AYA_PERF_EVENT_IOC_SET_BPF, }, - maps::{Map, MapError, MapLock, MapRef, MapRefMut}, + maps::{Map, MapError}, obj::{ btf::{Btf, BtfError}, Object, ParseError, ProgramSection, @@ -319,10 +319,6 @@ impl<'a> BpfLoader<'a> { (name, program) }) .collect(); - let maps = maps - .drain() - .map(|(name, map)| (name, MapLock::new(map))) - .collect(); Ok(Bpf { maps, programs }) } } @@ -336,7 +332,7 @@ impl<'a> Default for BpfLoader<'a> { /// The main entry point into the library, used to work with eBPF programs and maps. #[derive(Debug)] pub struct Bpf { - maps: HashMap, + maps: HashMap, programs: HashMap, } @@ -395,47 +391,50 @@ impl Bpf { /// /// For more details and examples on maps and their usage, see the [maps module /// documentation][crate::maps]. + pub fn map(&self, name: &str) -> Option<&Map> { + self.maps.get(name) + } + + /// Returns a mutable reference to the map with the given name. /// - /// # Errors + /// The returned type is mostly opaque. In order to do anything useful with it you need to + /// convert it to a [typed map](crate::maps). /// - /// Returns [`MapError::MapNotFound`] 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 { - self.maps - .get(name) - .ok_or_else(|| MapError::MapNotFound { - name: name.to_owned(), - }) - .and_then(|lock| { - lock.try_read().map_err(|_| MapError::BorrowError { - name: name.to_owned(), - }) - }) + /// For more details and examples on maps and their usage, see the [maps module + /// documentation][crate::maps]. + pub fn map_mut(&mut self, name: &str) -> Option<&mut Map> { + self.maps.get_mut(name) } - /// Returns a mutable reference to the map with the given name. + /// Take ownership of the map with the given name. Useful when intending to maintain frequent + /// access to a map without repeatedly incurring the cost of converting it into a + /// [typed map](crate::maps). /// /// The returned type is mostly opaque. In order to do anything useful with it you need to /// convert it to a [typed map](crate::maps). /// /// For more details and examples on maps and their usage, see the [maps module /// documentation][crate::maps]. + pub fn take_map(&mut self, name: &str) -> Option<(String, Map)> { + self.maps.remove_entry(name) + } + + /// Return ownership of the map with the given name. This is the dual of [take_map](Self::take_map). + /// + /// For more details and examples on maps and their usage, see the [maps module + /// documentation][crate::maps]. /// /// # Errors /// - /// Returns [`MapError::MapNotFound`] 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 { - self.maps - .get(name) - .ok_or_else(|| MapError::MapNotFound { - name: name.to_owned(), - }) - .and_then(|lock| { - lock.try_write().map_err(|_| MapError::BorrowError { - name: name.to_owned(), - }) - }) + /// Returns [`MapError::Occupied`] if a map already exists at the given name. + pub fn return_map(&mut self, name: String, map: Map) -> Result<(), MapError> { + match self.maps.entry(name) { + Entry::Vacant(vacant) => { + vacant.insert(map); + Ok(()) + } + Entry::Occupied(_) => Err(MapError::Occupied), + } } /// An iterator over all the maps. @@ -447,23 +446,16 @@ impl Bpf { /// println!( /// "found map `{}` of type `{:?}`", /// name, - /// map?.map_type().unwrap() + /// map.map_type().unwrap() /// ); /// } /// # Ok::<(), aya::BpfError>(()) /// ``` - pub fn maps(&self) -> impl Iterator)> { - let ret = self.maps.iter().map(|(name, lock)| { - ( - name.as_str(), - lock.try_read() - .map_err(|_| MapError::BorrowError { name: name.clone() }), - ) - }); - ret + pub fn maps(&self) -> impl Iterator { + self.maps.iter().map(|(s, m)| (s.as_str(), m)) } - /// Returns a reference to the program with the given name. + /// Returns a reference to the program with the given name if it exists. /// /// You can use this to inspect a program and its properties. To load and attach a program, use /// [program_mut](Self::program_mut) instead. @@ -483,7 +475,7 @@ impl Bpf { self.programs.get(name) } - /// Returns a mutable reference to the program with the given name. + /// Returns a mutable reference to the program with the given name if it exists. /// /// 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). @@ -504,7 +496,7 @@ impl Bpf { self.programs.get_mut(name) } - /// An iterator over all the programs. + /// An iterator over all of the programs. /// /// # Examples /// ```no_run diff --git a/aya/src/maps/array/array.rs b/aya/src/maps/array/array.rs index 6b41cc5d..a79b9f8d 100644 --- a/aya/src/maps/array/array.rs +++ b/aya/src/maps/array/array.rs @@ -7,7 +7,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_ARRAY, - maps::{IterableMap, Map, MapError, MapRef, MapRefMut}, + maps::{IterableMap, Map, MapError}, sys::{bpf_map_lookup_elem, bpf_map_update_elem}, Pod, }; @@ -23,11 +23,11 @@ use crate::{ /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::Array; /// use std::convert::TryFrom; /// -/// let mut array = Array::try_from(bpf.map_mut("ARRAY")?)?; +/// let mut array = Array::try_from(bpf.map_mut("ARRAY").unwrap())?; /// array.set(1, 42, 0)?; /// assert_eq!(array.get(&1, 0)?, 42); /// # Ok::<(), aya::BpfError>(()) @@ -139,18 +139,18 @@ impl, V: Pod> IterableMap for Array { } } -impl TryFrom for Array { +impl<'a, V: Pod> TryFrom<&'a Map> for Array<&'a Map, V> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { Array::new(a) } } -impl TryFrom for Array { +impl<'a, V: Pod> TryFrom<&'a mut Map> for Array<&'a mut Map, V> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { Array::new(a) } } diff --git a/aya/src/maps/array/per_cpu_array.rs b/aya/src/maps/array/per_cpu_array.rs index 099778e8..3c29120d 100644 --- a/aya/src/maps/array/per_cpu_array.rs +++ b/aya/src/maps/array/per_cpu_array.rs @@ -7,7 +7,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_PERCPU_ARRAY, - maps::{IterableMap, Map, MapError, MapRef, MapRefMut, PerCpuValues}, + maps::{IterableMap, Map, MapError, PerCpuValues}, sys::{bpf_map_lookup_elem_per_cpu, bpf_map_update_elem_per_cpu}, Pod, }; @@ -32,12 +32,12 @@ use crate::{ /// # #[error(transparent)] /// # Bpf(#[from] aya::BpfError) /// # } -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::{PerCpuArray, PerCpuValues}; /// use aya::util::nr_cpus; /// use std::convert::TryFrom; /// -/// let mut array = PerCpuArray::try_from(bpf.map_mut("ARRAY")?)?; +/// let mut array = PerCpuArray::try_from(bpf.map_mut("ARRAY").unwrap())?; /// /// // set array[1] = 42 for all cpus /// let nr_cpus = nr_cpus()?; @@ -158,18 +158,18 @@ impl, V: Pod> IterableMap> for PerCp } } -impl TryFrom for PerCpuArray { +impl<'a, V: Pod> TryFrom<&'a Map> for PerCpuArray<&'a Map, V> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { PerCpuArray::new(a) } } -impl TryFrom for PerCpuArray { +impl<'a, V: Pod> TryFrom<&'a mut Map> for PerCpuArray<&'a mut Map, V> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { PerCpuArray::new(a) } } diff --git a/aya/src/maps/array/program_array.rs b/aya/src/maps/array/program_array.rs index 3a3f7d02..04a075c9 100644 --- a/aya/src/maps/array/program_array.rs +++ b/aya/src/maps/array/program_array.rs @@ -9,7 +9,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_PROG_ARRAY, - maps::{Map, MapError, MapKeys, MapRef, MapRefMut}, + maps::{Map, MapError, MapKeys}, programs::ProgramFd, sys::{bpf_map_delete_elem, bpf_map_update_elem}, }; @@ -26,12 +26,13 @@ use crate::{ /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::ProgramArray; /// use aya::programs::{CgroupSkb, ProgramFd}; /// use std::convert::{TryFrom, TryInto}; /// -/// let mut prog_array = ProgramArray::try_from(bpf.map_mut("JUMP_TABLE")?)?; +/// let (name, mut map) = bpf.take_map("JUMP_TABLE").unwrap(); +/// let mut prog_array = ProgramArray::try_from(&mut map)?; /// let prog_0: &CgroupSkb = bpf.program("example_prog_0").unwrap().try_into()?; /// let prog_1: &CgroupSkb = bpf.program("example_prog_1").unwrap().try_into()?; /// let prog_2: &CgroupSkb = bpf.program("example_prog_2").unwrap().try_into()?; @@ -46,6 +47,8 @@ use crate::{ /// /// // bpf_tail_call(ctx, JUMP_TABLE, 2) will jump to prog_2 /// prog_array.set(2, prog_2, flags); +/// +/// bpf.return_map(name, map)?; /// # Ok::<(), aya::BpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_PROG_ARRAY")] @@ -130,18 +133,18 @@ impl + DerefMut> ProgramArray { } } -impl TryFrom for ProgramArray { +impl<'a> TryFrom<&'a Map> for ProgramArray<&'a Map> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { ProgramArray::new(a) } } -impl TryFrom for ProgramArray { +impl<'a> TryFrom<&'a mut Map> for ProgramArray<&'a mut Map> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { ProgramArray::new(a) } } diff --git a/aya/src/maps/hash_map/hash_map.rs b/aya/src/maps/hash_map/hash_map.rs index 9567fd6c..3f500bdf 100644 --- a/aya/src/maps/hash_map/hash_map.rs +++ b/aya/src/maps/hash_map/hash_map.rs @@ -6,7 +6,7 @@ use std::{ use crate::{ generated::bpf_map_type::{BPF_MAP_TYPE_HASH, BPF_MAP_TYPE_LRU_HASH}, - maps::{hash_map, IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut}, + maps::{hash_map, IterableMap, Map, MapError, MapIter, MapKeys}, sys::bpf_map_lookup_elem, Pod, }; @@ -20,11 +20,11 @@ use crate::{ /// # Examples /// /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::HashMap; /// use std::convert::TryFrom; /// -/// let mut redirect_ports = HashMap::try_from(bpf.map_mut("REDIRECT_PORTS")?)?; +/// let mut redirect_ports = HashMap::try_from(bpf.map_mut("REDIRECT_PORTS").unwrap())?; /// /// // redirect port 80 to 8080 /// redirect_ports.insert(80, 8080, 0); @@ -108,22 +108,6 @@ impl, K: Pod, V: Pod> IterableMap for HashMap TryFrom for HashMap { - type Error = MapError; - - fn try_from(a: MapRef) -> Result, MapError> { - HashMap::new(a) - } -} - -impl TryFrom for HashMap { - type Error = MapError; - - fn try_from(a: MapRefMut) -> Result, MapError> { - HashMap::new(a) - } -} - impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for HashMap<&'a Map, K, V> { type Error = MapError; diff --git a/aya/src/maps/hash_map/per_cpu_hash_map.rs b/aya/src/maps/hash_map/per_cpu_hash_map.rs index 77eb76a2..3490898a 100644 --- a/aya/src/maps/hash_map/per_cpu_hash_map.rs +++ b/aya/src/maps/hash_map/per_cpu_hash_map.rs @@ -7,9 +7,7 @@ use std::{ use crate::{ generated::bpf_map_type::{BPF_MAP_TYPE_LRU_PERCPU_HASH, BPF_MAP_TYPE_PERCPU_HASH}, - maps::{ - hash_map, IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut, PerCpuValues, - }, + maps::{hash_map, IterableMap, Map, MapError, MapIter, MapKeys, PerCpuValues}, sys::{bpf_map_lookup_elem_per_cpu, bpf_map_update_elem_per_cpu}, Pod, }; @@ -27,14 +25,14 @@ use crate::{ /// # Examples /// /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::PerCpuHashMap; /// use std::convert::TryFrom; /// /// const CPU_IDS: u8 = 1; /// const WAKEUPS: u8 = 2; /// -/// let mut hm = PerCpuHashMap::<_, u8, u32>::try_from(bpf.map("COUNTERS")?)?; +/// let mut hm = PerCpuHashMap::<_, u8, u32>::try_from(bpf.map("COUNTERS").unwrap())?; /// let cpu_ids = unsafe { hm.get(&CPU_IDS, 0)? }; /// let wakeups = unsafe { hm.get(&WAKEUPS, 0)? }; /// for (cpu_id, wakeups) in cpu_ids.iter().zip(wakeups.iter()) { @@ -113,14 +111,14 @@ impl, K: Pod, V: Pod> PerCpuHashMap { /// # #[error(transparent)] /// # Bpf(#[from] aya::BpfError) /// # } - /// # let bpf = aya::Bpf::load(&[])?; + /// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::{PerCpuHashMap, PerCpuValues}; /// use aya::util::nr_cpus; /// use std::convert::TryFrom; /// /// const RETRIES: u8 = 1; /// - /// let mut hm = PerCpuHashMap::<_, u8, u32>::try_from(bpf.map_mut("PER_CPU_STORAGE")?)?; + /// let mut hm = PerCpuHashMap::<_, u8, u32>::try_from(bpf.map_mut("PER_CPU_STORAGE").unwrap())?; /// hm.insert( /// RETRIES, /// PerCpuValues::try_from(vec![3u32; nr_cpus()?])?, @@ -159,22 +157,6 @@ impl, K: Pod, V: Pod> IterableMap> } } -impl TryFrom for PerCpuHashMap { - type Error = MapError; - - fn try_from(a: MapRef) -> Result, MapError> { - PerCpuHashMap::new(a) - } -} - -impl TryFrom for PerCpuHashMap { - type Error = MapError; - - fn try_from(a: MapRefMut) -> Result, MapError> { - PerCpuHashMap::new(a) - } -} - impl<'a, K: Pod, V: Pod> TryFrom<&'a Map> for PerCpuHashMap<&'a Map, K, V> { type Error = MapError; diff --git a/aya/src/maps/map_lock.rs b/aya/src/maps/map_lock.rs deleted file mode 100644 index 7a693173..00000000 --- a/aya/src/maps/map_lock.rs +++ /dev/null @@ -1,81 +0,0 @@ -use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -use std::{ - mem, - ops::{Deref, DerefMut}, - sync::Arc, -}; - -use crate::maps::Map; - -pub(crate) struct MapLockError; - -/* FIXME: write a full RwLock implementation that doesn't use borrowing guards - * so that try_read() and try_write() don't have to use the ugly lifetime - * extension hack */ - -#[derive(Debug)] -pub(crate) struct MapLock { - inner: Arc>, -} - -impl MapLock { - pub(crate) fn new(map: Map) -> MapLock { - MapLock { - inner: Arc::new(RwLock::new(map)), - } - } - - pub(crate) fn try_read(&self) -> Result { - let lock: Option> = - unsafe { mem::transmute(self.inner.try_read()) }; - lock.map(|guard| MapRef { - _lock: self.inner.clone(), - guard, - }) - .ok_or(MapLockError) - } - - pub(crate) fn try_write(&self) -> Result { - let lock: Option> = - unsafe { mem::transmute(self.inner.try_write()) }; - lock.map(|guard| MapRefMut { - _lock: self.inner.clone(), - guard, - }) - .ok_or(MapLockError) - } -} - -/// A borrowed reference to a BPF map. -pub struct MapRef { - _lock: Arc>, - guard: RwLockReadGuard<'static, Map>, -} - -/// A mutable borrowed reference to a BPF map. -pub struct MapRefMut { - _lock: Arc>, - guard: RwLockWriteGuard<'static, Map>, -} - -impl Deref for MapRef { - type Target = Map; - - fn deref(&self) -> &Map { - &*self.guard - } -} - -impl Deref for MapRefMut { - type Target = Map; - - fn deref(&self) -> &Map { - &*self.guard - } -} - -impl DerefMut for MapRefMut { - fn deref_mut(&mut self) -> &mut Map { - &mut *self.guard - } -} diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index 46e3889f..91af28a7 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -11,7 +11,7 @@ //! //! The eBPF API includes many map types each supporting different operations. //! [`Bpf::map`](crate::Bpf::map) and [`Bpf::map_mut`](crate::Bpf::map_mut) always return the -//! opaque [`MapRef`] and [`MapRefMut`] types respectively. Those two types can be converted to +//! opaque &Map and &mut Map types respectively. Those two types can be converted to //! *typed maps* using the [`TryFrom`](std::convert::TryFrom) trait. For example: //! //! ```no_run @@ -20,10 +20,12 @@ //! use aya::maps::SockMap; //! use aya::programs::SkMsg; //! -//! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; +//! let (name, mut map) = bpf.take_map("INTERCEPT_EGRESS").unwrap(); +//! let intercept_egress = SockMap::try_from(&mut map)?; //! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; //! prog.load()?; //! prog.attach(&intercept_egress)?; +//! bpf.return_map(name, map)?; //! # Ok::<(), aya::BpfError>(()) //! ``` //! @@ -46,8 +48,6 @@ use crate::{ Pod, }; -mod map_lock; - pub mod array; pub mod hash_map; pub mod perf; @@ -58,7 +58,6 @@ pub mod stack_trace; pub use array::{Array, PerCpuArray, ProgramArray}; pub use hash_map::{HashMap, PerCpuHashMap}; -pub use map_lock::*; pub use perf::PerfEventArray; pub use queue::Queue; pub use sock::{SockHash, SockMap}; @@ -67,8 +66,8 @@ pub use stack_trace::StackTraceMap; #[derive(Error, Debug)] pub enum MapError { - #[error("map `{name}` not found ")] - MapNotFound { name: String }, + #[error("map already exists")] + Occupied, #[error("invalid map type {map_type}")] InvalidMapType { map_type: u32 }, @@ -129,12 +128,6 @@ pub enum MapError { #[source] io_error: io::Error, }, - - #[error("map `{name}` is borrowed mutably")] - BorrowError { name: String }, - - #[error("map `{name}` is already borrowed")] - BorrowMutError { name: String }, } /// A generic handle to a BPF map. diff --git a/aya/src/maps/perf/async_perf_event_array.rs b/aya/src/maps/perf/async_perf_event_array.rs index fdea6db5..664cbdb4 100644 --- a/aya/src/maps/perf/async_perf_event_array.rs +++ b/aya/src/maps/perf/async_perf_event_array.rs @@ -13,7 +13,7 @@ use tokio::io::unix::AsyncFd; use crate::maps::{ perf::{Events, PerfBufferError, PerfEventArray, PerfEventArrayBuffer}, - Map, MapError, MapRefMut, + Map, MapError, }; /// A `Future` based map that can be used to receive events from eBPF programs using the linux @@ -198,10 +198,10 @@ impl> AsyncPerfEventArrayBuffer { } } -impl TryFrom for AsyncPerfEventArray { +impl<'a> TryFrom<&'a mut Map> for AsyncPerfEventArray<&'a mut Map> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { AsyncPerfEventArray::new(a) } } diff --git a/aya/src/maps/perf/perf_event_array.rs b/aya/src/maps/perf/perf_event_array.rs index 9695ea60..0803954f 100644 --- a/aya/src/maps/perf/perf_event_array.rs +++ b/aya/src/maps/perf/perf_event_array.rs @@ -15,7 +15,7 @@ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, maps::{ perf::{Events, PerfBuffer, PerfBufferError}, - Map, MapError, MapRefMut, + Map, MapError, }, sys::bpf_map_update_elem, }; @@ -109,13 +109,13 @@ impl> AsRawFd for PerfEventArrayBuffer { /// # #[error(transparent)] /// # PerfBuf(#[from] aya::maps::perf::PerfBufferError), /// # } -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::PerfEventArray; /// use aya::util::online_cpus; /// use std::convert::{TryFrom, TryInto}; /// use bytes::BytesMut; /// -/// let mut perf_array = PerfEventArray::try_from(bpf.map_mut("EVENTS")?)?; +/// let mut perf_array = PerfEventArray::try_from(bpf.map_mut("EVENTS").unwrap())?; /// /// // eBPF programs are going to write to the EVENTS perf array, using the id of the CPU they're /// // running on as the array index. @@ -205,10 +205,10 @@ impl> PerfEventArray { } } -impl TryFrom for PerfEventArray { +impl<'a> TryFrom<&'a mut Map> for PerfEventArray<&'a mut Map> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { PerfEventArray::new(a) } } diff --git a/aya/src/maps/queue.rs b/aya/src/maps/queue.rs index a6257807..83f60709 100644 --- a/aya/src/maps/queue.rs +++ b/aya/src/maps/queue.rs @@ -8,7 +8,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_QUEUE, - maps::{Map, MapError, MapRef, MapRefMut}, + maps::{Map, MapError}, sys::{bpf_map_lookup_and_delete_elem, bpf_map_push_elem}, Pod, }; @@ -21,11 +21,11 @@ use crate::{ /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::Queue; /// use std::convert::TryFrom; /// -/// let mut queue = Queue::try_from(bpf.map_mut("ARRAY")?)?; +/// let mut queue = Queue::try_from(bpf.map_mut("ARRAY").unwrap())?; /// queue.push(42, 0)?; /// queue.push(43, 0)?; /// assert_eq!(queue.pop(0)?, 42); @@ -110,18 +110,18 @@ impl + DerefMut, V: Pod> Queue { } } -impl TryFrom for Queue { +impl<'a, V: Pod> TryFrom<&'a Map> for Queue<&'a Map, V> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { Queue::new(a) } } -impl TryFrom for Queue { +impl<'a, V: Pod> TryFrom<&'a mut Map> for Queue<&'a mut Map, V> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { Queue::new(a) } } diff --git a/aya/src/maps/sock/sock_hash.rs b/aya/src/maps/sock/sock_hash.rs index d71e9f84..51d95b3a 100644 --- a/aya/src/maps/sock/sock_hash.rs +++ b/aya/src/maps/sock/sock_hash.rs @@ -7,9 +7,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_SOCKHASH, - maps::{ - hash_map, sock::SocketMap, IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut, - }, + maps::{hash_map, sock::SocketMap, IterableMap, Map, MapError, MapIter, MapKeys}, sys::bpf_map_lookup_elem, Pod, }; @@ -49,13 +47,15 @@ use crate::{ /// use aya::maps::SockHash; /// use aya::programs::SkMsg; /// -/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; +/// let (name, mut map) = bpf.take_map("INTERCEPT_EGRESS").unwrap(); +/// let mut intercept_egress = SockHash::try_from(&mut map)?; /// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_egress)?; /// /// let mut client = TcpStream::connect("127.0.0.1:1234")?; /// intercept_egress.insert(1234, client.as_raw_fd(), 0)?; +/// bpf.return_map(name, map)?; /// /// // the write will be intercepted /// client.write_all(b"foo")?; @@ -140,18 +140,18 @@ impl, K: Pod> SocketMap for SockHash { } } -impl TryFrom for SockHash { +impl<'a, K: Pod> TryFrom<&'a Map> for SockHash<&'a Map, K> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { SockHash::new(a) } } -impl TryFrom for SockHash { +impl<'a, K: Pod> TryFrom<&'a mut Map> for SockHash<&'a mut Map, K> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { SockHash::new(a) } } diff --git a/aya/src/maps/sock/sock_map.rs b/aya/src/maps/sock/sock_map.rs index 13a46b1e..2f1c3f9f 100644 --- a/aya/src/maps/sock/sock_map.rs +++ b/aya/src/maps/sock/sock_map.rs @@ -9,7 +9,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_SOCKMAP, - maps::{sock::SocketMap, Map, MapError, MapKeys, MapRef, MapRefMut}, + maps::{sock::SocketMap, Map, MapError, MapKeys}, sys::{bpf_map_delete_elem, bpf_map_update_elem}, }; @@ -34,10 +34,12 @@ use crate::{ /// use aya::maps::SockMap; /// use aya::programs::SkSkb; /// -/// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?; +/// let (name, mut map) = bpf.take_map("INTERCEPT_EGRESS").unwrap(); +/// let intercept_ingress = SockMap::try_from(&mut map)?; /// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_ingress)?; +/// bpf.return_map(name, map)?; /// # Ok::<(), aya::BpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_SOCKMAP")] @@ -120,18 +122,18 @@ impl + DerefMut> SocketMap for SockMap { } } -impl TryFrom for SockMap { +impl<'a> TryFrom<&'a Map> for SockMap<&'a Map> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { SockMap::new(a) } } -impl TryFrom for SockMap { +impl<'a> TryFrom<&'a mut Map> for SockMap<&'a mut Map> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { SockMap::new(a) } } diff --git a/aya/src/maps/stack.rs b/aya/src/maps/stack.rs index c8f36083..e13dfa34 100644 --- a/aya/src/maps/stack.rs +++ b/aya/src/maps/stack.rs @@ -8,7 +8,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_STACK, - maps::{Map, MapError, MapRef, MapRefMut}, + maps::{Map, MapError}, sys::{bpf_map_lookup_and_delete_elem, bpf_map_update_elem}, Pod, }; @@ -21,11 +21,11 @@ use crate::{ /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::Stack; /// use std::convert::TryFrom; /// -/// let mut stack = Stack::try_from(bpf.map_mut("STACK")?)?; +/// let mut stack = Stack::try_from(bpf.map_mut("STACK").unwrap())?; /// stack.push(42, 0)?; /// stack.push(43, 0)?; /// assert_eq!(stack.pop(0)?, 43); @@ -110,18 +110,18 @@ impl + DerefMut, V: Pod> Stack { } } -impl TryFrom for Stack { +impl<'a, V: Pod> TryFrom<&'a Map> for Stack<&'a Map, V> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { Stack::new(a) } } -impl TryFrom for Stack { +impl<'a, V: Pod> TryFrom<&'a mut Map> for Stack<&'a mut Map, V> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { Stack::new(a) } } diff --git a/aya/src/maps/stack_trace.rs b/aya/src/maps/stack_trace.rs index 6a24b8fc..f2490bb0 100644 --- a/aya/src/maps/stack_trace.rs +++ b/aya/src/maps/stack_trace.rs @@ -7,7 +7,7 @@ use std::{ use crate::{ generated::bpf_map_type::BPF_MAP_TYPE_STACK_TRACE, - maps::{IterableMap, Map, MapError, MapIter, MapKeys, MapRef, MapRefMut}, + maps::{IterableMap, Map, MapError, MapIter, MapKeys}, sys::bpf_map_lookup_elem_ptr, }; @@ -39,7 +39,7 @@ use crate::{ /// use aya::util::kernel_symbols; /// use std::convert::TryFrom; /// -/// let mut stack_traces = StackTraceMap::try_from(bpf.map("STACK_TRACES")?)?; +/// let mut stack_traces = StackTraceMap::try_from(bpf.map("STACK_TRACES").unwrap())?; /// // load kernel symbols from /proc/kallsyms /// let ksyms = kernel_symbols()?; /// @@ -161,18 +161,18 @@ impl> IterableMap for StackTraceMap { } } -impl TryFrom for StackTraceMap { +impl<'a> TryFrom<&'a Map> for StackTraceMap<&'a Map> { type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { + fn try_from(a: &'a Map) -> Result, MapError> { StackTraceMap::new(a) } } -impl TryFrom for StackTraceMap { +impl<'a> TryFrom<&'a mut Map> for StackTraceMap<&'a mut Map> { type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { + fn try_from(a: &'a mut Map) -> Result, MapError> { StackTraceMap::new(a) } } diff --git a/aya/src/programs/sk_msg.rs b/aya/src/programs/sk_msg.rs index fcb50926..4f60aa0a 100644 --- a/aya/src/programs/sk_msg.rs +++ b/aya/src/programs/sk_msg.rs @@ -37,7 +37,8 @@ use crate::{ /// use aya::maps::SockHash; /// use aya::programs::SkMsg; /// -/// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS")?)?; +/// let (name, mut map) = bpf.take_map("INTERCEPT_EGRESS").unwrap(); +/// let mut intercept_egress = SockHash::try_from(&mut map)?; /// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_egress)?; @@ -47,6 +48,7 @@ use crate::{ /// /// // the write will be intercepted /// client.write_all(b"foo")?; +/// bpf.return_map(name, map)?; /// # Ok::<(), Error>(()) /// ``` /// diff --git a/aya/src/programs/sk_skb.rs b/aya/src/programs/sk_skb.rs index bd07534f..6b8a7e52 100644 --- a/aya/src/programs/sk_skb.rs +++ b/aya/src/programs/sk_skb.rs @@ -33,10 +33,12 @@ pub enum SkSkbKind { /// use aya::maps::SockMap; /// use aya::programs::SkSkb; /// -/// let intercept_ingress = SockMap::try_from(bpf.map_mut("INTERCEPT_INGRESS")?)?; +/// let (name, mut map) = bpf.take_map("INTERCEPT_EGRESS").unwrap(); +/// let intercept_ingress = SockMap::try_from(&mut map)?; /// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; /// prog.load()?; /// prog.attach(&intercept_ingress)?; +/// bpf.return_map(name, map)?; /// # Ok::<(), aya::BpfError>(()) /// ``` ///