use std::io;
use crate::Result;
pub const BPF_MAP_CREATE: i32 = 0;
pub const BPF_MAP_LOOKUP_ELEM: i32 = 1;
pub const BPF_MAP_UPDATE_ELEM: i32 = 2;
pub const BPF_MAP_DELETE_ELEM: i32 = 3;
pub const BPF_PROG_LOAD: i32 = 5;
pub const BPF_LINK_CREATE: i32 = 28;
pub const BPF_PROG_TYPE_XDP: u32 = 6;
pub const BPF_ATTACH_TYPE_XDP: u32 = 37;
#[repr(C)]
#[derive(Default)]
pub struct MapCreateAttr {
pub map_type: u32,
pub key_size: u32,
pub value_size: u32,
pub max_entries: u32,
pub map_flags: u32,
}
#[repr(C)]
#[derive(Default)]
pub struct MapElemAttr {
pub map_fd: u32,
pub _pad: u32,
pub key: u64,
pub value: u64,
pub flags: u64,
}
#[repr(C)]
#[derive(Default)]
pub struct ProgLoadAttr {
pub prog_type: u32,
pub insn_cnt: u32,
pub insns: u64,
pub license: u64,
pub log_level: u32,
pub log_size: u32,
pub log_buf: u64,
pub kern_version: u32,
pub prog_flags: u32,
pub prog_name: [u8; 16],
pub prog_ifindex: u32,
pub expected_attach_type: u32,
}
#[repr(C)]
#[derive(Default)]
pub struct LinkCreateAttr {
pub prog_fd: u32,
pub target_ifindex: u32,
pub attach_type: u32,
pub flags: u32,
}
pub unsafe fn bpf(cmd: i32, attr: *mut libc::c_void, size: usize) -> Result<i32> {
let r = unsafe {
libc::syscall(
libc::SYS_bpf,
cmd as libc::c_long,
attr,
size as libc::c_long,
)
};
if r < 0 {
return Err(io::Error::last_os_error());
}
Ok(r as i32)
}
pub unsafe fn bpf_cmd<T>(cmd: i32, attr: &mut T) -> Result<i32> {
unsafe {
bpf(
cmd,
attr as *mut T as *mut libc::c_void,
std::mem::size_of::<T>(),
)
}
}
pub fn ctx_err(what: &str, e: io::Error) -> io::Error {
io::Error::new(e.kind(), format!("xdp: {what}: {e}"))
}