feat(netlink): Refactors to use netlink-socket2

Migrates netlink implementation to use netlink-socket2 and netlink-bindings crates, replacing neli crate for improved socket handling. Removes unused dependencies.
This commit is contained in:
Nils Andreas Svee committed 2026-02-21 23:10:48 +07:00
1 parent e2962222b7
commit 986b649a37
4 files changed
+97 -465

No files matched your search

Generated
+24 -228
View File
@@ -72,32 +72,6 @@ version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
[[package]]
name = "bytemuck"
version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.2.56"
@@ -154,7 +128,7 @@ dependencies = [
"ansi_term",
"atty",
"bitflags 1.3.2",
"strsim 0.8.0",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
@@ -178,41 +152,6 @@ dependencies = [
"libc",
]
[[package]]
name = "darling"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim 0.11.1",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "deranged"
version = "0.5.7"
@@ -222,43 +161,6 @@ dependencies = [
"powerfmt",
]
[[package]]
name = "derive_builder"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "derive_builder_macro"
version = "0.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [
"derive_builder_core",
"syn",
]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "env_logger"
version = "0.8.4"
@@ -294,12 +196,6 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.5"
@@ -320,18 +216,6 @@ dependencies = [
"wasip3",
]
[[package]]
name = "getset"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cf0fc11e47561d47397154977bc219f4cf809b2974facc3ccb3b89e2436f912"
dependencies = [
"proc-macro-error2",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "glob"
version = "0.3.3"
@@ -388,12 +272,6 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "indexmap"
version = "2.13.0"
@@ -462,21 +340,23 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]]
name = "lock_api"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "maybe-async"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "memchr"
version = "2.8.0"
@@ -484,32 +364,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "neli"
version = "0.7.4"
name = "netlink-bindings"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22f9786d56d972959e1408b6a93be6af13b9c1392036c5c1fafa08a1b0c6ee87"
dependencies = [
"bitflags 2.11.0",
"byteorder",
"derive_builder",
"getset",
"libc",
"log",
"neli-proc-macros",
"parking_lot",
]
checksum = "e639b3a966932d8ab55cfc1e606e5421aef3d30a2610284535b854f11f6e4b44"
[[package]]
name = "neli-proc-macros"
version = "0.2.2"
name = "netlink-socket2"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d8d08c6e98f20a62417478ebf7be8e1425ec9acecc6f63e22da633f6b71609"
checksum = "ffef37f26cf649b9f473ccc00fa52d419511225a7b3a2093bf16dc8673ab9cf1"
dependencies = [
"either",
"proc-macro2",
"quote",
"serde",
"syn",
"libc",
"maybe-async",
"netlink-bindings",
]
[[package]]
@@ -528,29 +396,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
[[package]]
name = "parking_lot"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-link",
]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
@@ -573,28 +418,6 @@ dependencies = [
"syn",
]
[[package]]
name = "proc-macro-error-attr2"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "proc-macro-error2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.106"
@@ -636,15 +459,6 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
[[package]]
name = "redox_syscall"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags 2.11.0",
]
[[package]]
name = "regex"
version = "1.12.3"
@@ -704,12 +518,6 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "semver"
version = "1.0.27"
@@ -723,7 +531,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
@@ -765,12 +572,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "socket2"
version = "0.6.2"
@@ -786,10 +587,11 @@ name = "sqm-autorate-rust"
version = "0.2.0"
dependencies = [
"anyhow",
"bytemuck",
"icmp-socket",
"libc",
"log",
"neli",
"netlink-bindings",
"netlink-socket2",
"rand",
"rust-uci",
"rustix",
@@ -803,12 +605,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.117"
+3 -2
View File
@@ -20,13 +20,14 @@ strip = "symbols"
[dependencies]
anyhow = "1.0"
bytemuck = { version = "1.25.0", features = ["derive"] }
icmp-socket = "0.4.0"
neli = "0.7"
netlink-bindings = { version = "0.2", features = ["rt-link", "tc"] }
netlink-socket2 = "0.2"
rand = "0.10"
rustix = { version = "1.1", features = ["fs", "thread", "time"] }
rust-uci = { version = "0.1", optional = true }
thiserror = "2.0"
libc = "0.2"
[dependencies.log]
features = ["std"]
+68 -231
View File
@@ -1,31 +1,23 @@
use bytemuck::AnyBitPattern;
use bytemuck::checked::{CheckedCastError, try_from_bytes};
use neli::consts::nl::NlmF;
use neli::consts::rtnl::{Arphrd, Iff, Ifla, RtAddrFamily, Rtm, Tca};
use neli::consts::socket::NlFamily;
use neli::err::{RouterError, SerError};
use neli::nl::{NlPayload, Nlmsghdr};
use neli::router::synchronous::NlRouter;
use neli::rtnl::{Ifinfomsg, IfinfomsgBuilder, RtattrBuilder, Tcmsg, TcmsgBuilder};
use neli::types::{Buffer, RtBuffer};
use neli::utils::Groups;
use std::io;
use std::str::Utf8Error;
use netlink_bindings::{rt_link, tc};
use netlink_socket2::NetlinkSocket;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum NetlinkError {
#[error("Couldn't deserialize to struct: {0}")]
Deserialization(CheckedCastError),
#[error("Couldn't find intreface `{0}`")]
#[error("Couldn't find interface `{0}`")]
InterfaceNotFound(String),
#[error("Netlink interface error")]
NlInterfaceError(#[from] RouterError<Rtm, Ifinfomsg>),
#[error("Netlink error: {0}")]
Netlink(#[from] io::Error),
#[error("Netlink reply error: {0}")]
Reply(#[from] netlink_socket2::ReplyError),
#[error("Something went wrong while finding qdisc")]
NlQdiscError(#[from] RouterError<Rtm, Tcmsg>),
NlQdiscError(String),
#[error("Couldn't find CAKE qdisc on interface `{0}`")]
NoQdiscFound(String),
@@ -33,150 +25,49 @@ pub enum NetlinkError {
#[error("Couldn't find interface statistics: `{0}`")]
NoInterfaceStatsFound(String),
#[error("Couldn't open Netlink socket")]
OpenSocket(#[from] io::Error),
#[error("Serialization error")]
Serialization(#[from] SerError),
#[error("Error happened while parsing UTF-8 string")]
Utf8Error(#[from] Utf8Error),
#[error("Invalid Rtm type (expected {expected:?}, found {found:?})")]
WrongType { expected: Rtm, found: Rtm },
#[error("Invalid reply type")]
InvalidReply,
}
#[derive(Clone, Copy, Debug)]
pub struct Qdisc {
ifindex: i32,
parent: u32,
}
#[derive(AnyBitPattern, Copy, Clone, Default, Debug)]
#[repr(C)]
pub struct RtnlLinkStats64 {
pub rx_packets: u64,
pub tx_packets: u64,
pub rx_bytes: u64,
pub tx_bytes: u64,
pub rx_errors: u64,
pub tx_errors: u64,
pub rx_dropped: u64,
pub tx_dropped: u64,
pub multicast: u64,
pub collisions: u64,
pub rx_length_errors: u64,
pub rx_over_errors: u64,
pub rx_crc_errors: u64,
pub rx_frame_errors: u64,
pub rx_fifo_errors: u64,
pub rx_missed_errors: u64,
pub tx_aborted_errors: u64,
pub tx_carrier_errors: u64,
pub tx_fifo_errors: u64,
pub tx_heartbeat_errors: u64,
pub tx_window_errors: u64,
pub rx_compressed: u64,
pub tx_compressed: u64,
pub rx_nohandler: u64,
}
pub enum TcaCake {
BaseRate64 = 2,
pub ifindex: i32,
pub parent: u32,
}
pub struct Netlink {}
impl Netlink {
fn nl_interface_get(
socket: &NlRouter,
ifname: &str,
) -> Result<neli::router::synchronous::NlRouterReceiverHandle<Rtm, Ifinfomsg>, NetlinkError>
{
let mut attrs = RtBuffer::new();
const RTEXT_FILTER_VF: i32 = 1 << 0;
let attr_ifname = RtattrBuilder::default()
.rta_type(Ifla::Ifname)
.rta_payload(ifname)
.build()
.unwrap();
let attr_ext_mask = RtattrBuilder::default()
.rta_type(Ifla::ExtMask)
.rta_payload(RTEXT_FILTER_VF)
.build()
.unwrap();
attrs.push(attr_ifname);
attrs.push(attr_ext_mask);
let if_msg = IfinfomsgBuilder::default()
.ifi_family(RtAddrFamily::Unspecified)
.ifi_type(Arphrd::None)
.ifi_index(-1)
.ifi_flags(Iff::empty())
.ifi_change(Iff::empty())
.rtattrs(attrs)
.build()
.unwrap();
let recv = socket.send::<_, _, Rtm, Ifinfomsg>(
Rtm::Getlink,
NlmF::REQUEST | NlmF::ACK,
NlPayload::Payload(if_msg),
)?;
Ok(recv)
}
pub fn find_interface(ifname: &str) -> Result<i32, NetlinkError> {
let (socket, _) = NlRouter::connect(NlFamily::Route, None, Groups::empty()).unwrap();
let mut socket = NetlinkSocket::new();
let recv = Self::nl_interface_get(&socket, ifname)?;
let mut request = rt_link::Request::new()
.op_getlink_do_request(&Default::default());
request.encode().push_ifname_bytes(ifname.as_bytes());
for response in recv {
let header: Nlmsghdr<Rtm, Ifinfomsg> = response?;
if header.nl_type() != &Rtm::Newlink {
return Err(NetlinkError::WrongType {
expected: Rtm::Newlink,
found: *header.nl_type(),
});
let mut iter = socket.request(&request)?;
let (header, _) = iter.recv_one()?;
Ok(header.ifi_index())
}
if let NlPayload::Payload(p) = header.nl_payload() {
return Ok(*p.ifi_index());
}
}
pub fn get_interface_stats(ifname: &str) -> Result<(u64, u64), NetlinkError> {
let mut socket = NetlinkSocket::new();
// we shouldn't reach here
Err(NetlinkError::InterfaceNotFound(ifname.to_string()))
}
let mut request = rt_link::Request::new()
.op_getlink_do_request(&Default::default());
request.encode()
.push_ifname_bytes(ifname.as_bytes())
.push_ext_mask(1 /* RTEXT_FILTER_VF */);
pub fn get_interface_stats(ifname: &str) -> Result<RtnlLinkStats64, NetlinkError> {
let (socket, _) = NlRouter::connect(NlFamily::Route, None, Groups::empty()).unwrap();
let recv = Self::nl_interface_get(&socket, ifname)?;
for response in recv {
let header: Nlmsghdr<Rtm, Ifinfomsg> = response?;
if header.nl_type() != &Rtm::Newlink {
return Err(NetlinkError::WrongType {
expected: Rtm::Newlink,
found: *header.nl_type(),
});
}
if let NlPayload::Payload(p) = header.nl_payload() {
for attr in p.rtattrs().iter() {
if attr.rta_type() == &Ifla::Stats64 {
let buf = attr.rta_payload().as_ref();
let stats: &RtnlLinkStats64 = try_from_bytes::<RtnlLinkStats64>(buf)
.map_err(|e| NetlinkError::Deserialization(e))?;
return Ok(stats.clone());
}
let mut iter = socket.request(&request)?;
while let Some(reply) = iter.recv() {
let (_, attrs) = reply?;
for attr in attrs {
if let Ok(rt_link::OpGetlinkDoReply::Stats64(stats)) = attr {
return Ok((stats.rx_bytes(), stats.tx_bytes()));
}
}
}
@@ -185,56 +76,31 @@ impl Netlink {
}
pub fn qdisc_from_ifindex(ifindex: i32) -> Result<Qdisc, NetlinkError> {
let (socket, _) = NlRouter::connect(NlFamily::Route, None, Groups::empty()).unwrap();
let tc_msg = TcmsgBuilder::default()
.tcm_family(u8::from(RtAddrFamily::Unspecified))
.tcm_ifindex(ifindex)
.tcm_handle(0)
.tcm_parent(0)
.tcm_info(0)
.rtattrs(RtBuffer::new())
.build()
.unwrap();
let mut socket = NetlinkSocket::new();
let header = tc::PushTcmsg::new();
let request = tc::Request::new().op_getqdisc_dump_request(&header);
let recv = socket.send::<_, _, Rtm, Tcmsg>(
Rtm::Getqdisc,
NlmF::REQUEST | NlmF::DUMP,
NlPayload::Payload(tc_msg),
)?;
let mut iter = socket.request(&request)?;
while let Some(reply) = iter.recv() {
let (header, attrs) = reply?;
for response in recv {
let header: Nlmsghdr<Rtm, Tcmsg> = response?;
if header.ifindex() == ifindex {
let mut is_cake = false;
for attr in attrs {
if let Ok(tc::OpGetqdiscDumpReply::Kind(kind)) = attr {
if kind.to_str().map_err(|_| NetlinkError::NlQdiscError("Invalid UTF-8".to_string()))? == "cake" {
is_cake = true;
break;
}
}
}
if let NlPayload::Payload(p) = header.nl_payload() {
if header.nl_type() != &Rtm::Newqdisc {
return Err(NetlinkError::WrongType {
expected: Rtm::Newqdisc,
found: *header.nl_type(),
if is_cake {
return Ok(Qdisc {
ifindex,
parent: header.parent(),
});
}
if *p.tcm_ifindex() == ifindex {
let mut _type = "";
for attr in p.rtattrs().iter() {
if attr.rta_type() == &Tca::Kind {
let buff = attr.rta_payload().as_ref();
_type = std::str::from_utf8(buff)?.trim_end_matches('\0');
// Null terminator is valid UTF-8, but breaks comparison, so we remove it
}
}
let type_to_look_for = "cake";
if _type.eq(type_to_look_for) {
let qdisc = Qdisc {
ifindex: *p.tcm_ifindex() as i32,
parent: *p.tcm_parent(),
};
return Ok(qdisc);
}
}
}
}
@@ -247,53 +113,24 @@ impl Netlink {
}
pub fn set_qdisc_rate(qdisc: Qdisc, bandwidth_kbit: u64) -> Result<(), NetlinkError> {
let (socket, _) = NlRouter::connect(NlFamily::Route, None, Groups::empty()).unwrap();
let mut socket = NetlinkSocket::new();
let bandwidth = bandwidth_kbit * 1000 / 8;
let mut attrs = RtBuffer::new();
let mut header = tc::PushTcmsg::new();
header.set_ifindex(qdisc.ifindex);
header.set_parent(qdisc.parent);
let attr_type = RtattrBuilder::default()
.rta_type(Tca::Kind)
.rta_payload("cake")
.build()
.unwrap();
let attr_options = RtattrBuilder::default()
.rta_type(Tca::Options)
.rta_payload(Buffer::from(Vec::new()))
.build()
.unwrap()
.nest(
&RtattrBuilder::default()
.rta_type(TcaCake::BaseRate64 as u16)
.rta_payload(bandwidth)
.build()
.unwrap(),
)?;
let mut request = tc::Request::new()
.set_change()
.op_newqdisc_do_request(&header);
request.encode()
.push_kind(c"cake")
.nested_options_cake()
.push_base_rate64(bandwidth)
.end_nested();
attrs.push(attr_type);
attrs.push(attr_options);
let tc_msg = TcmsgBuilder::default()
.tcm_family(u8::from(RtAddrFamily::Unspecified))
.tcm_ifindex(qdisc.ifindex)
.tcm_handle(0)
.tcm_parent(qdisc.parent)
.tcm_info(0)
.rtattrs(attrs)
.build()
.unwrap();
let recv = socket
.send::<_, _, Rtm, Tcmsg>(
Rtm::Newqdisc,
NlmF::REQUEST | NlmF::ACK,
NlPayload::Payload(tc_msg),
)
.map_err(|e| NetlinkError::NlQdiscError(e))?;
for msg in recv {
let _ = msg?;
}
let mut iter = socket.request(&request)?;
iter.recv_ack()?;
Ok(())
}
+2 -4
View File
@@ -62,10 +62,8 @@ fn get_interface_stats(
down_direction: StatsDirection,
up_direction: StatsDirection,
) -> Result<(i128, i128), RatecontrolError> {
let down_stats = Netlink::get_interface_stats(config.download_interface.as_str())?;
let up_stats = Netlink::get_interface_stats(config.upload_interface.as_str())?;
let (down_rx, down_tx) = (down_stats.rx_bytes, down_stats.tx_bytes);
let (up_rx, up_tx) = (up_stats.rx_bytes, up_stats.tx_bytes);
let (down_rx, down_tx) = Netlink::get_interface_stats(config.download_interface.as_str())?;
let (up_rx, up_tx) = Netlink::get_interface_stats(config.upload_interface.as_str())?;
let rx_bytes = match down_direction {
StatsDirection::RX => down_rx,