pub mod prelude;
mod devmap;
pub use devmap::DevMap;
use crate::bindings::*;
use crate::maps::{PerfMap as PerfMapBase, PerfMapFlags};
use crate::net::{NetworkBuffer, NetworkResult};
pub type XdpResult = NetworkResult<XdpAction>;
#[repr(u32)]
pub enum XdpAction {
Aborted = xdp_action_XDP_ABORTED,
Drop = xdp_action_XDP_DROP,
Pass = xdp_action_XDP_PASS,
Tx = xdp_action_XDP_TX,
Redirect = xdp_action_XDP_REDIRECT,
}
#[derive(Clone)]
pub struct XdpContext {
pub ctx: *mut xdp_md,
}
impl XdpContext {
#[inline]
pub fn inner(&self) -> *mut xdp_md {
self.ctx
}
}
impl NetworkBuffer for XdpContext {
fn data_start(&self) -> usize {
unsafe { (*self.ctx).data as usize }
}
fn data_end(&self) -> usize {
unsafe { (*self.ctx).data_end as usize }
}
}
#[repr(C)]
pub struct MapData<T> {
data: T,
offset: u32,
size: u32,
payload: [u8; 0],
}
impl<T> MapData<T> {
pub fn new(data: T) -> Self {
MapData::<T>::with_payload(data, 0, 0)
}
pub fn with_payload(data: T, offset: u32, size: u32) -> Self {
Self {
data,
payload: [],
offset,
size,
}
}
}
#[repr(transparent)]
pub struct PerfMap<T>(PerfMapBase<MapData<T>>);
impl<T> PerfMap<T> {
pub const fn with_max_entries(max_entries: u32) -> Self {
Self(PerfMapBase::with_max_entries(max_entries))
}
#[inline]
pub fn insert(&mut self, ctx: &XdpContext, data: &MapData<T>) {
let size = data.size;
self.0
.insert_with_flags(ctx.inner(), data, PerfMapFlags::with_xdp_size(size))
}
#[inline]
pub fn insert_with_flags(
&mut self,
ctx: &XdpContext,
data: &MapData<T>,
mut flags: PerfMapFlags,
) {
flags.xdp_size = data.size;
self.0.insert_with_flags(ctx.inner(), data, flags)
}
}