Use Log and Env_log for output. Suppress kernel messages that confuse

people on startup.

Default to "warn" level of logging. You can override by setting
RUST_LOG to "info". (Environment variable)
This commit is contained in:
Herbert Wolverson
2023-01-16 16:03:14 +00:00
parent 6f49b2498a
commit 7548413165
9 changed files with 57 additions and 36 deletions

1
src/rust/Cargo.lock generated
View File

@@ -1260,6 +1260,7 @@ dependencies = [
"bindgen",
"byteorder",
"libbpf-sys",
"log",
"lqos_bus",
"lqos_config",
"nix",

View File

@@ -10,6 +10,7 @@ anyhow = "1"
byteorder = "1.4"
lqos_bus = { path = "../lqos_bus" }
lqos_config = { path = "../lqos_config" }
log = "0"
[build-dependencies]
bindgen = "0.53.1"

View File

@@ -1,6 +1,6 @@
use anyhow::Result;
use lqos_config::{BridgeInterface, BridgeVlan};
use log::info;
use crate::{bpf_map::BpfMap, lqos_kernel::interface_name_to_index};
#[repr(C)]
@@ -20,19 +20,18 @@ const INTERFACE_PATH: &str = "/sys/fs/bpf/bifrost_interface_map";
const VLAN_PATH: &str = "/sys/fs/bpf/bifrost_vlan_map";
pub(crate) fn clear_bifrost() -> Result<()> {
println!("Clearing bifrost maps");
info!("Clearing bifrost maps");
let mut interface_map = BpfMap::<u32, BifrostInterface>::from_path(INTERFACE_PATH)?;
let mut vlan_map = BpfMap::<u32, BifrostVlan>::from_path(VLAN_PATH)?;
println!("Clearing VLANs");
info!("Clearing VLANs");
vlan_map.clear_no_repeat()?;
println!("Clearing Interfaces");
info!("Clearing Interfaces");
interface_map.clear_no_repeat()?;
println!("Done");
Ok(())
}
pub(crate) fn map_interfaces(mappings: &[BridgeInterface]) -> Result<()> {
println!("Interface maps");
info!("Interface maps");
let mut interface_map = BpfMap::<u32, BifrostInterface>::from_path(INTERFACE_PATH)?;
for mapping in mappings.iter() {
// Key is the parent interface
@@ -46,13 +45,13 @@ pub(crate) fn map_interfaces(mappings: &[BridgeInterface]) -> Result<()> {
},
};
interface_map.insert(&mut from, &mut mapping)?;
println!("Mapped bifrost interface {}->{}", from, redirect_to);
info!("Mapped bifrost interface {}->{}", from, redirect_to);
}
Ok(())
}
pub(crate) fn map_vlans(mappings: &[BridgeVlan]) -> Result<()> {
println!("VLAN maps");
info!("VLAN maps");
let mut vlan_map = BpfMap::<u32, BifrostVlan>::from_path(VLAN_PATH)?;
for mapping in mappings.iter() {
let mut key: u32 = (interface_name_to_index(&mapping.parent)? << 16) | mapping.tag;
@@ -60,11 +59,11 @@ pub(crate) fn map_vlans(mappings: &[BridgeVlan]) -> Result<()> {
redirect_to: mapping.redirect_to,
};
vlan_map.insert(&mut key, &mut val)?;
println!(
info!(
"Mapped bifrost VLAN: {}:{} => {}",
mapping.parent, mapping.tag, mapping.redirect_to
);
println!("{key}");
info!("{key}");
}
Ok(())
}

View File

@@ -13,6 +13,15 @@ extern __u64 max_tracker_ips() {
return MAX_TRACKED_IPS;
}
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return 0;
}
void do_not_print() {
libbpf_set_print(libbpf_print_fn);
}
/////////////////////////////////////////////////////////////////////////////////////
// The following is derived from
// https://github.com/xdp-project/bpf-examples/blob/master/tc-policy/tc_txq_policy.c
@@ -37,7 +46,7 @@ int teardown_hook(int ifindex, const char * ifname, bool verbose)
* programs are also detached.
*/
err = bpf_tc_hook_destroy(&hook);
if (err)
if (err && verbose)
fprintf(stderr, "Couldn't remove clsact qdisc on %s\n", ifname);
if (verbose)
@@ -58,7 +67,7 @@ int tc_detach_egress(int ifindex, bool verbose, bool flush_hook, const char * if
/* Check what program we are removing */
err = bpf_tc_query(&hook, &opts_info);
if (err) {
if (err && verbose) {
fprintf(stderr, "No egress program to detach "
"for ifindex %d (err:%d)\n", ifindex, err);
return err;
@@ -71,7 +80,7 @@ int tc_detach_egress(int ifindex, bool verbose, bool flush_hook, const char * if
opts_info.prog_id = 0;
opts_info.flags = 0;
err = bpf_tc_detach(&hook, &opts_info);
if (err) {
if (err && verbose) {
fprintf(stderr, "Cannot detach TC-BPF program id:%d "
"for ifindex %d (err:%d)\n", opts_info.prog_id,
ifindex, err);
@@ -143,7 +152,7 @@ int teardown_hook_ingress(int ifindex, const char * ifname, bool verbose)
* programs are also detached.
*/
err = bpf_tc_hook_destroy(&hook);
if (err)
if (err && verbose)
fprintf(stderr, "Couldn't remove clsact qdisc on %s\n", ifname);
if (verbose)
@@ -164,7 +173,7 @@ int tc_detach_ingress(int ifindex, bool verbose, bool flush_hook, const char * i
/* Check what program we are removing */
err = bpf_tc_query(&hook, &opts_info);
if (err) {
if (err && verbose) {
fprintf(stderr, "No ingress program to detach "
"for ifindex %d (err:%d)\n", ifindex, err);
return err;
@@ -177,7 +186,7 @@ int tc_detach_ingress(int ifindex, bool verbose, bool flush_hook, const char * i
opts_info.prog_id = 0;
opts_info.flags = 0;
err = bpf_tc_detach(&hook, &opts_info);
if (err) {
if (err && verbose) {
fprintf(stderr, "Cannot detach TC-BPF program id:%d "
"for ifindex %d (err:%d)\n", opts_info.prog_id,
ifindex, err);

View File

@@ -8,4 +8,5 @@ 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 bool map_txq_config_base_setup(int map_fd);
extern void do_not_print();

View File

@@ -1,6 +1,7 @@
use anyhow::{Error, Result};
use libbpf_sys::{bpf_map_update_elem, bpf_obj_get, libbpf_num_possible_cpus};
use std::{ffi::CString, os::raw::c_void};
use log::info;
//* Provides an interface for querying the number of CPUs eBPF can
//* see, and marking CPUs as available. Currently marks ALL eBPF
@@ -37,7 +38,7 @@ impl CpuMapping {
let queue_size = 2048u32;
let val_ptr: *const u32 = &queue_size;
for cpu in 0..cpu_count {
println!("Mapping core #{cpu}");
info!("Mapping core #{cpu}");
// Insert into the cpu map
let cpu_ptr: *const u32 = &cpu;
let error = unsafe {
@@ -91,14 +92,14 @@ impl Drop for CpuMapping {
/// Emulates xd_setup from cpumap
pub(crate) fn xps_setup_default_disable(interface: &str) -> Result<()> {
use std::io::Write;
println!("xps_setup");
info!("xps_setup");
let queues = sorted_txq_xps_cpus(interface)?;
for (cpu, xps_cpu) in queues.iter().enumerate() {
let mask = cpu_to_mask_disabled(cpu);
let mut f = std::fs::OpenOptions::new().write(true).open(xps_cpu)?;
f.write_all(&mask.to_string().as_bytes())?;
f.flush()?;
println!("Mapped TX queue for CPU {cpu}");
info!("Mapped TX queue for CPU {cpu}");
}
Ok(())

View File

@@ -11,6 +11,7 @@ use libbpf_sys::{
};
use nix::libc::{geteuid, if_nametoindex};
use std::{ffi::CString, process::Command};
use log::{info, warn};
pub(crate) mod bpf {
#![allow(warnings, unused)]
@@ -44,7 +45,7 @@ pub fn interface_name_to_index(interface_name: &str) -> Result<u32> {
}
pub fn unload_xdp_from_interface(interface_name: &str) -> Result<()> {
println!("Unloading XDP/TC");
info!("Unloading XDP/TC");
check_root()?;
let interface_index = interface_name_to_index(interface_name)?.try_into()?;
unsafe {
@@ -54,14 +55,15 @@ pub fn unload_xdp_from_interface(interface_name: &str) -> Result<()> {
}
let interface_c = CString::new(interface_name)?;
let _ = bpf::tc_detach_egress(interface_index as i32, true, true, interface_c.as_ptr());
let _ = bpf::tc_detach_ingress(interface_index as i32, true, true, interface_c.as_ptr());
let _ = bpf::tc_detach_egress(interface_index as i32, false, true, interface_c.as_ptr());
let _ = bpf::tc_detach_ingress(interface_index as i32, false, true, interface_c.as_ptr());
}
Ok(())
}
fn set_strict_mode() -> Result<()> {
let err = unsafe { libbpf_set_strict_mode(LIBBPF_STRICT_ALL) };
unsafe { bpf::do_not_print(); }
if err != 0 {
Err(Error::msg("Unable to activate BPF Strict Mode"))
} else {
@@ -133,22 +135,24 @@ pub fn attach_xdp_and_tc_to_interface(
// extern int tc_detach_egress(int ifindex, bool verbose, bool flush_hook, char * ifname);
let interface_c = CString::new(interface_name)?;
let _ =
unsafe { bpf::tc_detach_egress(interface_index as i32, true, true, interface_c.as_ptr()) }; // Ignoring error, because it's ok to not have something to detach
unsafe { bpf::tc_detach_egress(interface_index as i32, false, true, interface_c.as_ptr()) }; // Ignoring error, because it's ok to not have something to detach
// Remove any previous entry
let r = Command::new("tc")
let _r = Command::new("tc")
.args(["qdisc", "del", "dev", interface_name, "clsact"])
.output()?;
println!("{}", String::from_utf8(r.stderr).unwrap());
// This message was worrying people, commented out.
//println!("{}", String::from_utf8(r.stderr).unwrap());
// Add the classifier
let r = Command::new("tc")
let _r= Command::new("tc")
.args(["filter", "add", "dev", interface_name, "clsact"])
.output()?;
println!("{}", String::from_utf8(r.stderr).unwrap());
// This message was worrying people, commented out.
//println!("{}", String::from_utf8(r.stderr).unwrap());
// Attach to the egress
let error = unsafe { bpf::tc_attach_egress(interface_index as i32, true, skeleton) };
let error = unsafe { bpf::tc_attach_egress(interface_index as i32, false, skeleton) };
if error != 0 {
return Err(Error::msg("Unable to attach TC to interface"));
}
@@ -159,6 +163,7 @@ pub fn attach_xdp_and_tc_to_interface(
if bridge.use_xdp_bridge {
// Enable "promiscuous" mode on interfaces
for mapping in bridge.interface_mapping.iter() {
info!("Enabling promiscuous mode on {}", &mapping.name);
std::process::Command::new("/bin/ip")
.args(["link", "set", &mapping.name, "promisc", "on"])
.output()?;
@@ -171,7 +176,7 @@ pub fn attach_xdp_and_tc_to_interface(
// Actually attach the TC ingress program
let error =
unsafe { bpf::tc_attach_ingress(interface_index as i32, true, skeleton) };
unsafe { bpf::tc_attach_ingress(interface_index as i32, false, skeleton) };
if error != 0 {
return Err(Error::msg("Unable to attach TC Ingress to interface"));
}
@@ -200,13 +205,13 @@ unsafe fn attach_xdp_best_available(interface_index: u32, prog_fd: i32) -> Resul
return Err(Error::msg("Unable to attach to interface"));
}
} else {
println!("Attached in SKB compatibility mode. (Not so fast)");
warn!("Attached in SKB compatibility mode. (Not so fast)");
}
} else {
println!("Attached in driver mode. (Fast)");
info!("Attached in driver mode. (Fast)");
}
} else {
println!("Attached in hardware accelerated mode. (Fastest)");
info!("Attached in hardware accelerated mode. (Fastest)");
}
Ok(())
}

View File

@@ -22,4 +22,4 @@ notify = { version = "5.0.0", default-features = false, feature=["macos_kqueue"]
env_logger = "0"
log = "0"
nix = "0"
rayon = "1"
rayon = "1"

View File

@@ -23,7 +23,11 @@ use tokio::{
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init(); // Configure log level with RUST_LOG environment variable
// Configure log level with RUST_LOG environment variable,
// defaulting to "info"
env_logger::init_from_env(
env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "warn")
);
info!("LibreQoS Daemon Starting");
let config = LibreQoSConfig::load()?;
tuning::tune_lqosd_from_config_file(&config)?;
@@ -80,7 +84,7 @@ async fn main() -> Result<()> {
// Main bus listen loop
let listener = TcpListener::bind(BUS_BIND_ADDRESS).await?;
info!("Listening on: {}", BUS_BIND_ADDRESS);
warn!("Listening on: {}", BUS_BIND_ADDRESS);
loop {
let (mut socket, _) = listener.accept().await?;
tokio::spawn(async move {