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_PROG_TEST_RUN: i32 = 10;
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 ProgTestRunAttr {
pub prog_fd: u32,
pub retval: u32,
pub data_size_in: u32,
pub data_size_out: u32,
pub data_in: u64,
pub data_out: u64,
pub repeat: u32,
pub duration: u32,
pub ctx_size_in: u32,
pub ctx_size_out: u32,
pub ctx_in: u64,
pub ctx_out: u64,
pub flags: u32,
pub cpu: u32,
pub batch_size: u32,
pub _pad: u32,
}
const _: () = {
assert!(std::mem::size_of::<MapCreateAttr>() == 5 * 4);
assert!(std::mem::size_of::<MapElemAttr>() == 2 * 4 + 3 * 8);
assert!(std::mem::size_of::<ProgLoadAttr>() == 8 * 4 + 3 * 8 + 16);
assert!(std::mem::size_of::<ProgTestRunAttr>() == 12 * 4 + 4 * 8);
assert!(std::mem::size_of::<LinkCreateAttr>() == 4 * 4);
};
#[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}"))
}