From cdc06db34931bd82b6b9f5ae5210bda81e25cf4a Mon Sep 17 00:00:00 2001 From: ashon Date: Sun, 16 Feb 2025 15:04:05 +0900 Subject: [PATCH] Impl tc filter del command --- src/traffic_control/del_filter.rs | 82 +++++++++++++++++++++++++++++++ src/traffic_control/handle.rs | 9 +++- src/traffic_control/mod.rs | 2 + 3 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/traffic_control/del_filter.rs diff --git a/src/traffic_control/del_filter.rs b/src/traffic_control/del_filter.rs new file mode 100644 index 0000000..3d852b5 --- /dev/null +++ b/src/traffic_control/del_filter.rs @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: MIT + +use futures::stream::StreamExt; +use netlink_packet_core::{NetlinkMessage, NLM_F_REQUEST, NLM_F_ACK}; +use netlink_packet_route::{ + tc::{ + TcHandle, TcMessage, + }, + RouteNetlinkMessage, +}; + +use crate::{try_nl, Error, Handle}; + +#[derive(Debug, Clone)] +pub struct TrafficFilterDelRequest { + handle: Handle, + message: TcMessage, + flags: u16, +} + +impl TrafficFilterDelRequest { + pub(crate) fn new(handle: Handle, ifindex: i32) -> Self { + Self { + handle, + message: TcMessage::with_index(ifindex), + flags: NLM_F_REQUEST | NLM_F_ACK, + } + } + + /// Execute the request + pub async fn execute(self) -> Result<(), Error> { + let Self { + mut handle, + message, + flags, + } = self; + + let mut req = NetlinkMessage::from( + RouteNetlinkMessage::DelTrafficFilter(message), + ); + req.header.flags = flags; + + let mut response = handle.request(req)?; + if let Some(message) = response.next().await { + try_nl!(message); + } + + Ok(()) + } + + /// Set parent. + /// Equivalent to `[ root | ingress | egress | parent CLASSID ]` + /// command args. They are mutually exclusive. + pub fn parent(mut self, parent: u32) -> Self { + self.message.header.parent = parent.into(); + self + } + + /// Set parent to root. + pub fn root(mut self) -> Self { + self.message.header.parent = TcHandle::ROOT; + self + } + + /// Set parent to ingress. + pub fn ingress(mut self) -> Self { + self.message.header.parent = TcHandle { + major: 0xffff, + minor: TcHandle::MIN_INGRESS, + }; + self + } + + /// Set parent to egress. + pub fn egress(mut self) -> Self { + self.message.header.parent = TcHandle { + major: 0xffff, + minor: TcHandle::MIN_EGRESS, + }; + self + } +} diff --git a/src/traffic_control/handle.rs b/src/traffic_control/handle.rs index 80cb2a2..cde1650 100644 --- a/src/traffic_control/handle.rs +++ b/src/traffic_control/handle.rs @@ -2,7 +2,8 @@ use super::{ QDiscDelRequest, QDiscGetRequest, QDiscNewRequest, TrafficChainGetRequest, - TrafficClassGetRequest, TrafficFilterGetRequest, TrafficFilterNewRequest, + TrafficClassGetRequest, TrafficFilterDelRequest, TrafficFilterGetRequest, + TrafficFilterNewRequest, }; use crate::Handle; @@ -103,6 +104,12 @@ impl TrafficFilterHandle { ) } + /// Delete a filter from a node, don't replace if the object already exists. + /// ( equivalent to `tc filter del dev STRING`) + pub fn del(&mut self) -> TrafficFilterDelRequest { + TrafficFilterDelRequest::new(self.handle.clone(), self.ifindex) + } + /// Change the filter, the handle cannot be changed and neither can the /// parent. In other words, change cannot move a node. /// ( equivalent to `tc filter change dev STRING`) diff --git a/src/traffic_control/mod.rs b/src/traffic_control/mod.rs index e65f577..a7224a1 100644 --- a/src/traffic_control/mod.rs +++ b/src/traffic_control/mod.rs @@ -2,6 +2,7 @@ mod add_filter; mod add_qdisc; +mod del_filter; mod del_qdisc; mod get; mod handle; @@ -9,6 +10,7 @@ mod handle; mod test; pub use self::add_filter::TrafficFilterNewRequest; +pub use self::del_filter::TrafficFilterDelRequest; pub use self::add_qdisc::QDiscNewRequest; pub use self::del_qdisc::QDiscDelRequest; pub use self::get::{