mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
Port map_txq_config_base_setup from C to Rust
The previous C function was pretty simple, it'd been left as C for fast porting. It's now a safe (other than the syscall, which is properly wrapped) Rust function.
This commit is contained in:
@@ -246,70 +246,3 @@ int tc_attach_ingress(int ifindex, bool verbose, struct lqos_kern *obj)
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
/*******************************/
|
||||
|
||||
static inline unsigned int bpf_num_possible_cpus(void)
|
||||
{
|
||||
static const char *fcpu = "/sys/devices/system/cpu/possible";
|
||||
unsigned int start, end, possible_cpus = 0;
|
||||
char buff[128];
|
||||
FILE *fp;
|
||||
int n;
|
||||
|
||||
fp = fopen(fcpu, "r");
|
||||
if (!fp) {
|
||||
printf("Failed to open %s: '%s'!\n", fcpu, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (fgets(buff, sizeof(buff), fp)) {
|
||||
n = sscanf(buff, "%u-%u", &start, &end);
|
||||
if (n == 0) {
|
||||
printf("Failed to retrieve # possible CPUs!\n");
|
||||
exit(1);
|
||||
} else if (n == 1) {
|
||||
end = start;
|
||||
}
|
||||
possible_cpus = start == 0 ? end + 1 : 0;
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return possible_cpus;
|
||||
}
|
||||
|
||||
struct txq_config {
|
||||
/* lookup key: __u32 cpu; */
|
||||
__u16 queue_mapping;
|
||||
__u16 htb_major;
|
||||
};
|
||||
|
||||
bool map_txq_config_base_setup(int map_fd) {
|
||||
unsigned int possible_cpus = bpf_num_possible_cpus();
|
||||
struct txq_config txq_cfg;
|
||||
__u32 cpu;
|
||||
int err;
|
||||
|
||||
if (map_fd < 0) {
|
||||
fprintf(stderr, "ERR: (bad map_fd:%d) "
|
||||
"cannot proceed without access to txq_config map\n",
|
||||
map_fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (cpu = 0; cpu < possible_cpus; cpu++) {
|
||||
txq_cfg.queue_mapping = cpu + 1;
|
||||
txq_cfg.htb_major = cpu + 1;
|
||||
|
||||
err = bpf_map_update_elem(map_fd, &cpu, &txq_cfg, 0);
|
||||
if (err) {
|
||||
fprintf(stderr,
|
||||
"ERR: %s() updating cpu-key:%d err(%d):%s\n",
|
||||
__func__, cpu, errno, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -8,5 +8,4 @@ extern int tc_detach_egress(int ifindex, bool verbose, bool flush_hook, const ch
|
||||
extern int tc_attach_ingress(int ifindex, bool verbose, struct lqos_kern *obj);
|
||||
extern int tc_detach_ingress(int ifindex, bool verbose, bool flush_hook, const char * ifname);
|
||||
extern __u64 max_tracker_ips();
|
||||
extern bool map_txq_config_base_setup(int map_fd);
|
||||
extern void do_not_print();
|
||||
@@ -2,8 +2,7 @@ use anyhow::{Error, Result};
|
||||
use libbpf_sys::{bpf_map_update_elem, bpf_obj_get};
|
||||
use log::info;
|
||||
use std::{ffi::CString, os::raw::c_void};
|
||||
|
||||
use crate::num_possible_cpus;
|
||||
use crate::{num_possible_cpus, linux::map_txq_config_base_setup};
|
||||
|
||||
//* Provides an interface for querying the number of CPUs eBPF can
|
||||
//* see, and marking CPUs as available. Currently marks ALL eBPF
|
||||
@@ -72,14 +71,7 @@ impl CpuMapping {
|
||||
}
|
||||
|
||||
pub(crate) fn setup_base_txq_config(&self) -> Result<()> {
|
||||
use crate::lqos_kernel::bpf::map_txq_config_base_setup;
|
||||
// Should we shell out to the C and do it the easy way?
|
||||
let result = unsafe { map_txq_config_base_setup(self.fd_txq_config) };
|
||||
if !result {
|
||||
Err(Error::msg("Unable to setup TXQ map"))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
Ok(map_txq_config_base_setup(self.fd_txq_config)?)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
//! Ports of C code that is very Linux specific.
|
||||
|
||||
mod possible_cpus;
|
||||
pub use possible_cpus::num_possible_cpus;
|
||||
mod txq_base_setup;
|
||||
pub use possible_cpus::num_possible_cpus;
|
||||
pub(crate) use txq_base_setup::*;
|
||||
51
src/rust/lqos_sys/src/linux/txq_base_setup.rs
Normal file
51
src/rust/lqos_sys/src/linux/txq_base_setup.rs
Normal file
@@ -0,0 +1,51 @@
|
||||
use std::ffi::c_void;
|
||||
use libbpf_sys::bpf_map_update_elem;
|
||||
use log::error;
|
||||
use thiserror::Error;
|
||||
use crate::num_possible_cpus;
|
||||
|
||||
#[derive(Default)]
|
||||
#[repr(C)]
|
||||
struct TxqConfig {
|
||||
/* lookup key: __u32 cpu; */
|
||||
queue_mapping: u16,
|
||||
htb_major: u16,
|
||||
}
|
||||
|
||||
pub fn map_txq_config_base_setup(map_fd: i32) -> Result<(), MapTxqConfigError> {
|
||||
let possible_cpus = num_possible_cpus().map_err(|_| MapTxqConfigError::NumCpusError)?;
|
||||
if map_fd < 0 {
|
||||
error!("ERR: (bad map_fd:{map_fd}) cannot proceed without access to txq_config map");
|
||||
return Err(MapTxqConfigError::BadMapFd);
|
||||
}
|
||||
|
||||
let mut txq_cfg = TxqConfig::default();
|
||||
for cpu in 0 .. possible_cpus {
|
||||
let cpu_u16: u16 = cpu as u16;
|
||||
txq_cfg.queue_mapping = cpu_u16 + 1;
|
||||
txq_cfg.htb_major = cpu_u16 + 1;
|
||||
|
||||
let key_ptr: *const u32 = &cpu;
|
||||
let val_ptr: *const TxqConfig = &txq_cfg;
|
||||
|
||||
let err = unsafe {
|
||||
bpf_map_update_elem(map_fd, key_ptr as *const c_void, val_ptr as *mut c_void, 0)
|
||||
};
|
||||
if err != 0 {
|
||||
error!("Unable to update TXQ map");
|
||||
return Err(MapTxqConfigError::BpfMapUpdateFail);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MapTxqConfigError {
|
||||
#[error("Unable to determine number of CPUs")]
|
||||
NumCpusError,
|
||||
#[error("Bad Mapped File Descriptor")]
|
||||
BadMapFd,
|
||||
#[error("Unable to insert into map")]
|
||||
BpfMapUpdateFail,
|
||||
}
|
||||
Reference in New Issue
Block a user