use std::{
borrow::{Borrow, BorrowMut},
os::fd::{AsFd, AsRawFd, RawFd},
};
use crate::{
maps::{check_bounds, check_kv_size, MapData, MapError},
sys::{bpf_map_update_elem, SyscallError},
};
#[doc(alias = "BPF_MAP_TYPE_XSKMAP")]
pub struct XskMap<T> {
pub(crate) inner: T,
}
impl<T: Borrow<MapData>> XskMap<T> {
pub(crate) fn new(map: T) -> Result<Self, MapError> {
let data = map.borrow();
check_kv_size::<u32, RawFd>(data)?;
Ok(Self { inner: map })
}
pub fn len(&self) -> u32 {
self.inner.borrow().obj.max_entries()
}
}
impl<T: BorrowMut<MapData>> XskMap<T> {
pub fn set(&mut self, index: u32, socket_fd: impl AsRawFd, flags: u64) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
check_bounds(data, index)?;
let fd = data.fd().as_fd();
bpf_map_update_elem(fd, Some(&index), &socket_fd.as_raw_fd(), flags).map_err(
|(_, io_error)| SyscallError {
call: "bpf_map_update_elem",
io_error,
},
)?;
Ok(())
}
}