use std::ffi::CString;
use crate::ffi;
pub struct Eal {
_private: (),
}
impl Eal {
pub fn init(args: &[&str]) -> Result<Self, EalError> {
let mut c_args: Vec<CString> = Vec::with_capacity(args.len() + 1);
c_args.push(CString::new("melin-dpdk").expect("program name"));
for arg in args {
c_args.push(CString::new(*arg).map_err(|_| EalError::InvalidArg)?);
}
let mut c_ptrs: Vec<*mut libc::c_char> = c_args
.iter()
.map(|s| s.as_ptr() as *mut libc::c_char)
.collect();
let argc = c_ptrs.len() as libc::c_int;
let ret = unsafe { ffi::rte_eal_init(argc, c_ptrs.as_mut_ptr()) };
if ret < 0 {
return Err(EalError::InitFailed(ret));
}
tracing::info!(cores = ret, "DPDK EAL initialized");
Ok(Eal { _private: () })
}
pub fn port_count(&self) -> u16 {
unsafe { ffi::rte_eth_dev_count_avail() }
}
}
impl Drop for Eal {
fn drop(&mut self) {
unsafe {
ffi::rte_eal_cleanup();
}
tracing::info!("DPDK EAL cleaned up");
}
}
#[derive(Debug)]
pub enum EalError {
InvalidArg,
InitFailed(libc::c_int),
}
impl std::fmt::Display for EalError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EalError::InvalidArg => write!(f, "EAL argument contains null byte"),
EalError::InitFailed(code) => write!(f, "rte_eal_init failed with code {code}"),
}
}
}
impl std::error::Error for EalError {}