use std::{
borrow::{Borrow, BorrowMut},
os::fd::{AsFd as _, AsRawFd, RawFd},
};
use crate::{
maps::{MapData, MapError, MapKeys, check_bounds, check_kv_size},
sys::{SyscallError, bpf_map_delete_elem, bpf_map_update_elem},
};
#[doc(alias = "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY")]
pub struct ReusePortSockArray<T> {
pub(crate) inner: T,
}
impl<T: Borrow<MapData>> ReusePortSockArray<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())
}
}
impl<T: BorrowMut<MapData>> ReusePortSockArray<T> {
pub fn set<I: AsRawFd>(&mut self, index: u32, socket: &I, flags: u64) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
let fd = data.fd().as_fd();
check_bounds(data, index)?;
bpf_map_update_elem(fd, Some(&index), &socket.as_raw_fd(), flags)
.map_err(|io_error| SyscallError {
call: "bpf_map_update_elem",
io_error,
})
.map_err(Into::into)
}
pub fn clear_index(&mut self, index: &u32) -> Result<(), MapError> {
let data = self.inner.borrow_mut();
let fd = data.fd().as_fd();
check_bounds(data, *index)?;
bpf_map_delete_elem(fd, index)
.map_err(|io_error| SyscallError {
call: "bpf_map_delete_elem",
io_error,
})
.map_err(Into::into)
}
}