From ede3e91014075de01af02da624cad99861da2dad Mon Sep 17 00:00:00 2001 From: Tuetuopay Date: Sat, 5 Aug 2023 00:15:37 +0200 Subject: [PATCH] aya: Update XDP maps implementations Map impls changed since this was first written. Fixes: 2b726c8 ("aya: Implement XDP Map Types") --- aya/src/bpf.rs | 4 + aya/src/maps/mod.rs | 18 ++++- aya/src/maps/xdp/cpu_map.rs | 111 +++++++++++++-------------- aya/src/maps/xdp/dev_map.rs | 112 ++++++++++++--------------- aya/src/maps/xdp/dev_map_hash.rs | 127 +++++++++++++------------------ aya/src/maps/xdp/xsk_map.rs | 87 +++++---------------- 6 files changed, 197 insertions(+), 262 deletions(-) diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index a5fb9273..999271ec 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -707,6 +707,10 @@ fn parse_map(data: (String, MapData)) -> Result<(String, Map), BpfError> { BPF_MAP_TYPE_STACK => Map::Stack(map), BPF_MAP_TYPE_STACK_TRACE => Map::StackTraceMap(map), BPF_MAP_TYPE_QUEUE => Map::Queue(map), + BPF_MAP_TYPE_CPUMAP => Map::CpuMap(map), + BPF_MAP_TYPE_DEVMAP => Map::DevMap(map), + BPF_MAP_TYPE_DEVMAP_HASH => Map::DevMapHash(map), + BPF_MAP_TYPE_XSKMAP => Map::XskMap(map), m => { warn!("The map {name} is of type {:#?} which is currently unsupported in Aya, use `allow_unsupported_maps()` to load it anyways", m); Map::Unsupported(map) diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index 190d8c67..2f7c556f 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -97,7 +97,7 @@ pub use queue::Queue; pub use sock::{SockHash, SockMap}; pub use stack::Stack; pub use stack_trace::StackTraceMap; -pub use xdp::XskMap; +pub use xdp::{CpuMap, DevMap, DevMapHash, XskMap}; #[derive(Error, Debug)] /// Errors occuring from working with Maps @@ -267,6 +267,14 @@ pub enum Map { StackTraceMap(MapData), /// A [`Queue`] map Queue(MapData), + /// A [`CpuMap`] map + CpuMap(MapData), + /// A [`DevMap`] map + DevMap(MapData), + /// A [`DevMapHash`] map + DevMapHash(MapData), + /// A [`XskMap`] map + XskMap(MapData), /// An unsupported map type Unsupported(MapData), } @@ -290,6 +298,10 @@ impl Map { Self::Stack(map) => map.obj.map_type(), Self::StackTraceMap(map) => map.obj.map_type(), Self::Queue(map) => map.obj.map_type(), + Self::CpuMap(map) => map.obj.map_type(), + Self::DevMap(map) => map.obj.map_type(), + Self::DevMapHash(map) => map.obj.map_type(), + Self::XskMap(map) => map.obj.map_type(), Self::Unsupported(map) => map.obj.map_type(), } } @@ -349,6 +361,10 @@ impl_try_from_map!(() { SockMap, PerfEventArray, StackTraceMap, + CpuMap, + DevMap, + DevMapHash, + XskMap, }); #[cfg(any(feature = "async_tokio", feature = "async_std"))] diff --git a/aya/src/maps/xdp/cpu_map.rs b/aya/src/maps/xdp/cpu_map.rs index 2b6ba3cb..cb6fbe45 100644 --- a/aya/src/maps/xdp/cpu_map.rs +++ b/aya/src/maps/xdp/cpu_map.rs @@ -1,15 +1,10 @@ //! An array of available CPUs. -use std::{ - convert::TryFrom, - mem, - ops::{Deref, DerefMut}, -}; +use std::borrow::{Borrow, BorrowMut}; use crate::{ - generated::bpf_map_type::BPF_MAP_TYPE_CPUMAP, - maps::{Map, MapError, MapRef, MapRefMut}, - sys::bpf_map_update_elem, + maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError}, + sys::{bpf_map_lookup_elem, bpf_map_update_elem, SyscallError}, }; /// An array of available CPUs. @@ -19,15 +14,18 @@ use crate::{ /// /// # Minimum kernel version /// -/// The minimum kernel version required to use this feature is 4.2. +/// The minimum kernel version required to use this feature is 4.15. /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let elf_bytes = &[]; /// use aya::maps::xdp::CpuMap; -/// use std::convert::{TryFrom, TryInto}; /// -/// let mut cpumap = CpuMap::try_from(bpf.map_mut("CPUS")?)?; +/// let mut bpf = aya::BpfLoader::new() +/// .set_max_entries("CPUS", aya::util::nr_cpus().unwrap() as u32) +/// .load(elf_bytes) +/// .unwrap(); +/// let mut cpumap = CpuMap::try_from(bpf.map_mut("CPUS").unwrap())?; /// let flags = 0; /// let queue_size = 2048; /// for i in 0u32..8u32 { @@ -37,52 +35,51 @@ use crate::{ /// # Ok::<(), aya::BpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_CPUMAP")] -pub struct CpuMap> { +pub struct CpuMap { inner: T, } -impl> CpuMap { - fn new(map: T) -> Result, MapError> { - let map_type = map.obj.def.map_type; - if map_type != BPF_MAP_TYPE_CPUMAP as u32 { - return Err(MapError::InvalidMapType { - map_type: map_type as u32, - }); - } - let expected = mem::size_of::(); - let size = map.obj.def.key_size as usize; - if size != expected { - return Err(MapError::InvalidKeySize { size, expected }); - } - - let expected = mem::size_of::(); - let size = map.obj.def.value_size as usize; - if size != expected { - return Err(MapError::InvalidValueSize { size, expected }); - } - let _fd = map.fd_or_err()?; +impl> CpuMap { + pub(crate) fn new(map: T) -> Result { + let data = map.borrow(); + check_kv_size::(data)?; - Ok(CpuMap { inner: map }) + Ok(Self { inner: map }) } /// Returns the number of elements in the array. /// /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side. pub fn len(&self) -> u32 { - self.inner.obj.def.max_entries + self.inner.borrow().obj.max_entries() } - fn check_bounds(&self, index: u32) -> Result<(), MapError> { - let max_entries = self.inner.obj.def.max_entries; - if index >= self.inner.obj.def.max_entries { - Err(MapError::OutOfBounds { index, max_entries }) - } else { - Ok(()) - } + /// Returns the value stored at the given index. + /// + /// # Errors + /// + /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] + /// if `bpf_map_lookup_elem` fails. + pub fn get(&self, index: u32, flags: u64) -> Result { + let data = self.inner.borrow(); + check_bounds(data, index)?; + let fd = data.fd().as_fd(); + + let value = + bpf_map_lookup_elem(fd, &index, flags).map_err(|(_, io_error)| SyscallError { + call: "bpf_map_lookup_elem", + io_error, + })?; + value.ok_or(MapError::KeyNotFound) + } + + /// An iterator over the elements of the map. + pub fn iter(&self) -> impl Iterator> + '_ { + (0..self.len()).map(move |i| self.get(i, 0)) } } -impl + DerefMut> CpuMap { +impl> CpuMap { /// Sets the value of the element at the given index. /// /// # Errors @@ -90,12 +87,12 @@ impl + DerefMut> CpuMap { /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] /// if `bpf_map_update_elem` fails. pub fn set(&mut self, index: u32, value: u32, flags: u64) -> Result<(), MapError> { - let fd = self.inner.fd_or_err()?; - self.check_bounds(index)?; - bpf_map_update_elem(fd, &index, &value, flags).map_err(|(code, io_error)| { - MapError::SyscallError { - call: "bpf_map_update_elem".to_owned(), - code, + let data = self.inner.borrow_mut(); + check_bounds(data, index)?; + let fd = data.fd().as_fd(); + bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(_, io_error)| { + SyscallError { + call: "bpf_map_update_elem", io_error, } })?; @@ -103,18 +100,12 @@ impl + DerefMut> CpuMap { } } -impl TryFrom for CpuMap { - type Error = MapError; - - fn try_from(a: MapRef) -> Result, MapError> { - CpuMap::new(a) +impl> IterableMap for CpuMap { + fn map(&self) -> &MapData { + self.inner.borrow() } -} - -impl TryFrom for CpuMap { - type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { - CpuMap::new(a) + fn get(&self, key: &u32) -> Result { + self.get(*key, 0) } } diff --git a/aya/src/maps/xdp/dev_map.rs b/aya/src/maps/xdp/dev_map.rs index 365a5b1e..b8fad587 100644 --- a/aya/src/maps/xdp/dev_map.rs +++ b/aya/src/maps/xdp/dev_map.rs @@ -1,15 +1,10 @@ //! An array of network devices. -use std::{ - convert::TryFrom, - mem, - ops::{Deref, DerefMut}, -}; +use std::borrow::{Borrow, BorrowMut}; use crate::{ - generated::bpf_map_type::BPF_MAP_TYPE_DEVMAP, - maps::{Map, MapError, MapRef, MapRefMut}, - sys::bpf_map_update_elem, + maps::{check_bounds, check_kv_size, IterableMap, MapData, MapError}, + sys::{bpf_map_lookup_elem, bpf_map_update_elem, SyscallError}, }; /// An array of network devices. @@ -19,67 +14,66 @@ use crate::{ /// /// # Minimum kernel version /// -/// The minimum kernel version required to use this feature is 4.2. +/// The minimum kernel version required to use this feature is 4.14. /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::xdp::DevMap; -/// use std::convert::{TryFrom, TryInto}; /// -/// let mut devmap = DevMap::try_from(bpf.map_mut("IFACES")?)?; -/// let ifindex = 32u32; -/// devmap.set(ifindex, ifindex, 0); +/// let mut devmap = DevMap::try_from(bpf.map_mut("IFACES").unwrap())?; +/// let source = 32u32; +/// let dest = 42u32; +/// devmap.set(source, dest, 0); /// /// # Ok::<(), aya::BpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_DEVMAP")] -pub struct DevMap> { +pub struct DevMap { inner: T, } -impl> DevMap { - fn new(map: T) -> Result, MapError> { - let map_type = map.obj.def.map_type; - if map_type != BPF_MAP_TYPE_DEVMAP as u32 { - return Err(MapError::InvalidMapType { - map_type: map_type as u32, - }); - } - let expected = mem::size_of::(); - let size = map.obj.def.key_size as usize; - if size != expected { - return Err(MapError::InvalidKeySize { size, expected }); - } - - let expected = mem::size_of::(); - let size = map.obj.def.value_size as usize; - if size != expected { - return Err(MapError::InvalidValueSize { size, expected }); - } - let _fd = map.fd_or_err()?; +impl> DevMap { + pub(crate) fn new(map: T) -> Result { + let data = map.borrow(); + check_kv_size::(data)?; - Ok(DevMap { inner: map }) + Ok(Self { inner: map }) } /// Returns the number of elements in the array. /// /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side. pub fn len(&self) -> u32 { - self.inner.obj.def.max_entries + self.inner.borrow().obj.max_entries() } - fn check_bounds(&self, index: u32) -> Result<(), MapError> { - let max_entries = self.inner.obj.def.max_entries; - if index >= self.inner.obj.def.max_entries { - Err(MapError::OutOfBounds { index, max_entries }) - } else { - Ok(()) - } + /// Returns the value stored at the given index. + /// + /// # Errors + /// + /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] + /// if `bpf_map_lookup_elem` fails. + pub fn get(&self, index: u32, flags: u64) -> Result { + let data = self.inner.borrow(); + check_bounds(data, index)?; + let fd = data.fd().as_fd(); + + let value = + bpf_map_lookup_elem(fd, &index, flags).map_err(|(_, io_error)| SyscallError { + call: "bpf_map_lookup_elem", + io_error, + })?; + value.ok_or(MapError::KeyNotFound) + } + + /// An iterator over the elements of the array. + pub fn iter(&self) -> impl Iterator> + '_ { + (0..self.len()).map(move |i| self.get(i, 0)) } } -impl + DerefMut> DevMap { +impl> DevMap { /// Sets the value of the element at the given index. /// /// # Errors @@ -87,12 +81,12 @@ impl + DerefMut> DevMap { /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] /// if `bpf_map_update_elem` fails. pub fn set(&mut self, index: u32, value: u32, flags: u64) -> Result<(), MapError> { - let fd = self.inner.fd_or_err()?; - self.check_bounds(index)?; - bpf_map_update_elem(fd, &index, &value, flags).map_err(|(code, io_error)| { - MapError::SyscallError { - call: "bpf_map_update_elem".to_owned(), - code, + let data = self.inner.borrow_mut(); + check_bounds(data, index)?; + let fd = data.fd().as_fd(); + bpf_map_update_elem(fd, Some(&index), &value, flags).map_err(|(_, io_error)| { + SyscallError { + call: "bpf_map_update_elem", io_error, } })?; @@ -100,18 +94,12 @@ impl + DerefMut> DevMap { } } -impl TryFrom for DevMap { - type Error = MapError; - - fn try_from(a: MapRef) -> Result, MapError> { - DevMap::new(a) +impl> IterableMap for DevMap { + fn map(&self) -> &MapData { + self.inner.borrow() } -} - -impl TryFrom for DevMap { - type Error = MapError; - fn try_from(a: MapRefMut) -> Result, MapError> { - DevMap::new(a) + fn get(&self, key: &u32) -> Result { + self.get(*key, 0) } } diff --git a/aya/src/maps/xdp/dev_map_hash.rs b/aya/src/maps/xdp/dev_map_hash.rs index 4cf16762..47eed67d 100644 --- a/aya/src/maps/xdp/dev_map_hash.rs +++ b/aya/src/maps/xdp/dev_map_hash.rs @@ -1,118 +1,99 @@ -//! An array of network devices. +//! An hashmap of network devices. -use std::{ - convert::TryFrom, - mem, - ops::{Deref, DerefMut}, -}; +use std::borrow::{Borrow, BorrowMut}; use crate::{ - generated::bpf_map_type::BPF_MAP_TYPE_DEVMAP_HASH, - maps::{Map, MapError, MapRef, MapRefMut}, - sys::bpf_map_update_elem, + maps::{check_kv_size, hash_map, IterableMap, MapData, MapError, MapIter, MapKeys}, + sys::{bpf_map_lookup_elem, SyscallError}, }; -/// An array of network devices. +/// An hashmap of network devices. /// /// XDP programs can use this map to redirect to other network /// devices. /// /// # Minimum kernel version /// -/// The minimum kernel version required to use this feature is 4.2. +/// The minimum kernel version required to use this feature is 5.4. /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// use aya::maps::xdp::DevMapHash; -/// use std::convert::{TryFrom, TryInto}; /// -/// let mut devmap = DevMapHash::try_from(bpf.map_mut("IFACES")?)?; +/// let mut devmap = DevMapHash::try_from(bpf.map_mut("IFACES").unwrap())?; /// let flags = 0; /// let ifindex = 32u32; -/// devmap.set(ifindex, ifindex, flags); +/// devmap.insert(ifindex, ifindex, flags); /// /// # Ok::<(), aya::BpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_DEVMAP_HASH")] -pub struct DevMapHash> { +pub struct DevMapHash { inner: T, } -impl> DevMapHash { - fn new(map: T) -> Result, MapError> { - let map_type = map.obj.def.map_type; - if map_type != BPF_MAP_TYPE_DEVMAP_HASH as u32 { - return Err(MapError::InvalidMapType { - map_type: map_type as u32, - }); - } - let expected = mem::size_of::(); - let size = map.obj.def.key_size as usize; - if size != expected { - return Err(MapError::InvalidKeySize { size, expected }); - } - - let expected = mem::size_of::(); - let size = map.obj.def.value_size as usize; - if size != expected { - return Err(MapError::InvalidValueSize { size, expected }); - } - let _fd = map.fd_or_err()?; +impl> DevMapHash { + pub(crate) fn new(map: T) -> Result { + let data = map.borrow(); + check_kv_size::(data)?; - Ok(DevMapHash { inner: map }) + Ok(Self { inner: map }) } - /// Returns the number of elements in the array. + /// Returns the value stored at the given index. + /// + /// # Errors /// - /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side. - pub fn len(&self) -> u32 { - self.inner.obj.def.max_entries + /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] + /// if `bpf_map_lookup_elem` fails. + pub fn get(&self, index: u32, flags: u64) -> Result { + let fd = self.inner.borrow().fd().as_fd(); + let value = + bpf_map_lookup_elem(fd, &index, flags).map_err(|(_, io_error)| SyscallError { + call: "bpf_map_lookup_elem", + io_error, + })?; + value.ok_or(MapError::KeyNotFound) + } + + /// An iterator over the elements of the devmap in arbitrary order. + pub fn iter(&self) -> MapIter<'_, u32, u32, Self> { + MapIter::new(self) } - fn check_bounds(&self, index: u32) -> Result<(), MapError> { - let max_entries = self.inner.obj.def.max_entries; - if index >= self.inner.obj.def.max_entries { - Err(MapError::OutOfBounds { index, max_entries }) - } else { - Ok(()) - } + /// An iterator visiting all keys in arbitrary order. + pub fn keys(&self) -> MapKeys<'_, u32> { + MapKeys::new(self.inner.borrow()) } } -impl + DerefMut> DevMapHash { - /// Sets the value of the element at the given index. +impl> DevMapHash { + /// Inserts a value in the map. /// /// # Errors /// - /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] - /// if `bpf_map_update_elem` fails. - pub fn set(&mut self, index: u32, value: u32, flags: u64) -> Result<(), MapError> { - let fd = self.inner.fd_or_err()?; - self.check_bounds(index)?; - bpf_map_update_elem(fd, &index, &value, flags).map_err(|(code, io_error)| { - MapError::SyscallError { - call: "bpf_map_update_elem".to_owned(), - code, - io_error, - } - })?; - Ok(()) + /// Returns [`MapError::SyscallError`] if `bpf_map_update_elem` fails. + pub fn insert(&mut self, index: u32, value: u32, flags: u64) -> Result<(), MapError> { + hash_map::insert(self.inner.borrow_mut(), &index, &value, flags) } -} - -impl TryFrom for DevMapHash { - type Error = MapError; - fn try_from(a: MapRef) -> Result, MapError> { - DevMapHash::new(a) + /// Remove a value from the map. + /// + /// # Errors + /// + /// Returns [`MapError::SyscallError`] if `bpf_map_delete_elem` fails. + pub fn remove(&mut self, key: u32) -> Result<(), MapError> { + hash_map::remove(self.inner.borrow_mut(), &key) } } -impl TryFrom for DevMapHash { - type Error = MapError; +impl> IterableMap for DevMapHash { + fn map(&self) -> &MapData { + self.inner.borrow() + } - fn try_from(a: MapRefMut) -> Result, MapError> { - DevMapHash::new(a) + fn get(&self, key: &u32) -> Result { + self.get(*key, 0) } } diff --git a/aya/src/maps/xdp/xsk_map.rs b/aya/src/maps/xdp/xsk_map.rs index 239c908c..133173c0 100644 --- a/aya/src/maps/xdp/xsk_map.rs +++ b/aya/src/maps/xdp/xsk_map.rs @@ -1,16 +1,13 @@ //! An array of AF_XDP sockets. use std::{ - convert::TryFrom, - mem, - ops::{Deref, DerefMut}, - os::unix::prelude::{AsRawFd, RawFd}, + borrow::{Borrow, BorrowMut}, + os::fd::{AsFd, AsRawFd, RawFd}, }; use crate::{ - generated::bpf_map_type::BPF_MAP_TYPE_XSKMAP, - maps::{Map, MapError, MapRef, MapRefMut}, - sys::bpf_map_update_elem, + maps::{check_bounds, check_kv_size, MapData, MapError}, + sys::{bpf_map_update_elem, SyscallError}, }; /// An array of AF_XDP sockets. @@ -20,67 +17,41 @@ use crate::{ /// /// # Minimum kernel version /// -/// The minimum kernel version required to use this feature is 4.2. +/// The minimum kernel version required to use this feature is 4.18. /// /// # Examples /// ```no_run -/// # let bpf = aya::Bpf::load(&[])?; +/// # let mut bpf = aya::Bpf::load(&[])?; /// # let socket_fd = 1; /// use aya::maps::XskMap; -/// use std::convert::{TryFrom, TryInto}; /// -/// let mut xskmap = XskMap::try_from(bpf.map_mut("SOCKETS")?)?; +/// let mut xskmap = XskMap::try_from(bpf.map_mut("SOCKETS").unwrap())?; /// // socket_fd is the RawFd of an AF_XDP socket /// xskmap.set(0, socket_fd, 0); /// # Ok::<(), aya::BpfError>(()) /// ``` #[doc(alias = "BPF_MAP_TYPE_XSKMAP")] -pub struct XskMap> { +pub struct XskMap { inner: T, } -impl> XskMap { - fn new(map: T) -> Result, MapError> { - let map_type = map.obj.def.map_type; - if map_type != BPF_MAP_TYPE_XSKMAP as u32 { - return Err(MapError::InvalidMapType { - map_type: map_type as u32, - }); - } - let expected = mem::size_of::(); - let size = map.obj.def.key_size as usize; - if size != expected { - return Err(MapError::InvalidKeySize { size, expected }); - } +impl> XskMap { + pub(crate) fn new(map: T) -> Result { + let data = map.borrow(); + check_kv_size::(data)?; - let expected = mem::size_of::(); - let size = map.obj.def.value_size as usize; - if size != expected { - return Err(MapError::InvalidValueSize { size, expected }); - } - let _fd = map.fd_or_err()?; - - Ok(XskMap { inner: map }) + Ok(Self { inner: map }) } /// Returns the number of elements in the array. /// /// This corresponds to the value of `bpf_map_def::max_entries` on the eBPF side. pub fn len(&self) -> u32 { - self.inner.obj.def.max_entries - } - - fn check_bounds(&self, index: u32) -> Result<(), MapError> { - let max_entries = self.inner.obj.def.max_entries; - if index >= self.inner.obj.def.max_entries { - Err(MapError::OutOfBounds { index, max_entries }) - } else { - Ok(()) - } + self.inner.borrow().obj.max_entries() } } -impl + DerefMut> XskMap { +impl> XskMap { /// Sets the value of the element at the given index. /// /// # Errors @@ -88,31 +59,15 @@ impl + DerefMut> XskMap { /// Returns [`MapError::OutOfBounds`] if `index` is out of bounds, [`MapError::SyscallError`] /// if `bpf_map_update_elem` fails. pub fn set(&mut self, index: u32, value: V, flags: u64) -> Result<(), MapError> { - let fd = self.inner.fd_or_err()?; - self.check_bounds(index)?; - bpf_map_update_elem(fd, &index, &value.as_raw_fd(), flags).map_err( - |(code, io_error)| MapError::SyscallError { - call: "bpf_map_update_elem".to_owned(), - code, + let data = self.inner.borrow_mut(); + check_bounds(data, index)?; + let fd = data.fd().as_fd(); + bpf_map_update_elem(fd, Some(&index), &value.as_raw_fd(), flags).map_err( + |(_, io_error)| SyscallError { + call: "bpf_map_update_elem", io_error, }, )?; Ok(()) } } - -impl TryFrom for XskMap { - type Error = MapError; - - fn try_from(a: MapRef) -> Result, MapError> { - XskMap::new(a) - } -} - -impl TryFrom for XskMap { - type Error = MapError; - - fn try_from(a: MapRefMut) -> Result, MapError> { - XskMap::new(a) - } -}