|
|
@ -21,30 +21,30 @@ pub struct ProgramArray<T: Deref<Target = Map>> {
|
|
|
|
|
|
|
|
|
|
|
|
impl<T: Deref<Target = Map>> ProgramArray<T> {
|
|
|
|
impl<T: Deref<Target = Map>> ProgramArray<T> {
|
|
|
|
pub fn new(map: T) -> Result<ProgramArray<T>, MapError> {
|
|
|
|
pub fn new(map: T) -> Result<ProgramArray<T>, MapError> {
|
|
|
|
let inner = map.deref();
|
|
|
|
let map_type = map.obj.def.map_type;
|
|
|
|
let map_type = inner.obj.def.map_type;
|
|
|
|
|
|
|
|
if map_type != BPF_MAP_TYPE_PROG_ARRAY {
|
|
|
|
if map_type != BPF_MAP_TYPE_PROG_ARRAY {
|
|
|
|
return Err(MapError::InvalidMapType {
|
|
|
|
return Err(MapError::InvalidMapType {
|
|
|
|
map_type: map_type as u32,
|
|
|
|
map_type: map_type as u32,
|
|
|
|
})?;
|
|
|
|
})?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let expected = mem::size_of::<RawFd>();
|
|
|
|
let expected = mem::size_of::<RawFd>();
|
|
|
|
let size = inner.obj.def.key_size as usize;
|
|
|
|
let size = map.obj.def.key_size as usize;
|
|
|
|
if size != expected {
|
|
|
|
if size != expected {
|
|
|
|
return Err(MapError::InvalidKeySize { size, expected });
|
|
|
|
return Err(MapError::InvalidKeySize { size, expected });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let expected = mem::size_of::<RawFd>();
|
|
|
|
let expected = mem::size_of::<RawFd>();
|
|
|
|
let size = inner.obj.def.value_size as usize;
|
|
|
|
let size = map.obj.def.value_size as usize;
|
|
|
|
if size != expected {
|
|
|
|
if size != expected {
|
|
|
|
return Err(MapError::InvalidValueSize { size, expected });
|
|
|
|
return Err(MapError::InvalidValueSize { size, expected });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let _fd = map.fd_or_err()?;
|
|
|
|
|
|
|
|
|
|
|
|
Ok(ProgramArray { inner: map })
|
|
|
|
Ok(ProgramArray { inner: map })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn get(&self, key: &u32, flags: u64) -> Result<Option<RawFd>, MapError> {
|
|
|
|
pub unsafe fn get(&self, key: &u32, flags: u64) -> Result<Option<RawFd>, MapError> {
|
|
|
|
let fd = self.inner.deref().fd_or_err()?;
|
|
|
|
let fd = self.inner.fd_or_err()?;
|
|
|
|
let fd = bpf_map_lookup_elem(fd, key, flags)
|
|
|
|
let fd = bpf_map_lookup_elem(fd, key, flags)
|
|
|
|
.map_err(|(code, io_error)| MapError::LookupElementError { code, io_error })?;
|
|
|
|
.map_err(|(code, io_error)| MapError::LookupElementError { code, io_error })?;
|
|
|
|
Ok(fd)
|
|
|
|
Ok(fd)
|
|
|
@ -59,8 +59,8 @@ impl<T: Deref<Target = Map>> ProgramArray<T> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn check_bounds(&self, index: u32) -> Result<(), MapError> {
|
|
|
|
fn check_bounds(&self, index: u32) -> Result<(), MapError> {
|
|
|
|
let max_entries = self.inner.deref().obj.def.max_entries;
|
|
|
|
let max_entries = self.inner.obj.def.max_entries;
|
|
|
|
if index >= self.inner.deref().obj.def.max_entries {
|
|
|
|
if index >= self.inner.obj.def.max_entries {
|
|
|
|
Err(MapError::OutOfBounds { index, max_entries })
|
|
|
|
Err(MapError::OutOfBounds { index, max_entries })
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Ok(())
|
|
|
|
Ok(())
|
|
|
@ -75,7 +75,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
|
|
|
|
program: &dyn ProgramFd,
|
|
|
|
program: &dyn ProgramFd,
|
|
|
|
flags: u64,
|
|
|
|
flags: u64,
|
|
|
|
) -> Result<(), MapError> {
|
|
|
|
) -> Result<(), MapError> {
|
|
|
|
let fd = self.inner.deref().fd_or_err()?;
|
|
|
|
let fd = self.inner.fd_or_err()?;
|
|
|
|
self.check_bounds(index)?;
|
|
|
|
self.check_bounds(index)?;
|
|
|
|
let prog_fd = program.fd().ok_or(MapError::ProgramNotLoaded)?;
|
|
|
|
let prog_fd = program.fd().ok_or(MapError::ProgramNotLoaded)?;
|
|
|
|
|
|
|
|
|
|
|
@ -85,14 +85,14 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub unsafe fn pop(&mut self, index: &u32) -> Result<Option<RawFd>, MapError> {
|
|
|
|
pub unsafe fn pop(&mut self, index: &u32) -> Result<Option<RawFd>, MapError> {
|
|
|
|
let fd = self.inner.deref().fd_or_err()?;
|
|
|
|
let fd = self.inner.fd_or_err()?;
|
|
|
|
self.check_bounds(*index)?;
|
|
|
|
self.check_bounds(*index)?;
|
|
|
|
bpf_map_lookup_and_delete_elem(fd, index)
|
|
|
|
bpf_map_lookup_and_delete_elem(fd, index)
|
|
|
|
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementError { code, io_error })
|
|
|
|
.map_err(|(code, io_error)| MapError::LookupAndDeleteElementError { code, io_error })
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn remove(&mut self, index: &u32) -> Result<(), MapError> {
|
|
|
|
pub fn remove(&mut self, index: &u32) -> Result<(), MapError> {
|
|
|
|
let fd = self.inner.deref().fd_or_err()?;
|
|
|
|
let fd = self.inner.fd_or_err()?;
|
|
|
|
self.check_bounds(*index)?;
|
|
|
|
self.check_bounds(*index)?;
|
|
|
|
bpf_map_delete_elem(fd, index)
|
|
|
|
bpf_map_delete_elem(fd, index)
|
|
|
|
.map(|_| ())
|
|
|
|
.map(|_| ())
|
|
|
@ -102,7 +102,7 @@ impl<T: Deref<Target = Map> + DerefMut<Target = Map>> ProgramArray<T> {
|
|
|
|
|
|
|
|
|
|
|
|
impl<T: Deref<Target = Map>> IterableMap<u32, RawFd> for ProgramArray<T> {
|
|
|
|
impl<T: Deref<Target = Map>> IterableMap<u32, RawFd> for ProgramArray<T> {
|
|
|
|
fn fd(&self) -> Result<RawFd, MapError> {
|
|
|
|
fn fd(&self) -> Result<RawFd, MapError> {
|
|
|
|
self.inner.deref().fd_or_err()
|
|
|
|
self.inner.fd_or_err()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsafe fn get(&self, index: &u32) -> Result<Option<RawFd>, MapError> {
|
|
|
|
unsafe fn get(&self, index: &u32) -> Result<Option<RawFd>, MapError> {
|
|
|
|