use std::{
borrow::{Borrow, BorrowMut},
os::fd::{AsRawFd, RawFd},
};
use crate::maps::{
MapData, MapError, MapKeys, check_bounds, check_kv_size, hash_map, sock::SockMapFd,
};
#[doc(alias = "BPF_MAP_TYPE_SOCKMAP")]
pub struct SockMap<T> {
pub(crate) inner: T,
}
impl<T: Borrow<MapData>> SockMap<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 indices(&self) -> MapKeys<'_, u32> {
MapKeys::new(self.inner.borrow())
}
pub fn fd(&self) -> &SockMapFd {
let fd = self.inner.borrow().fd();
unsafe { std::mem::transmute(fd) }
}
}
impl<T: BorrowMut<MapData>> SockMap<T> {
pub fn set<I: AsRawFd>(&mut self, index: u32, socket: &I, flags: u64) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
check_bounds(data, index)?;
hash_map::insert(data, &index, &socket.as_raw_fd(), flags)
}
pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
check_bounds(data, *index)?;
hash_map::remove(data, index)
}
}