rtnetlink/traffic_control/
handle.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::{NLM_F_CREATE, NLM_F_EXCL, NLM_F_REPLACE};
4use netlink_packet_route::tc::TcMessage;
5
6use super::{
7    QDiscDelRequest, QDiscGetRequest, QDiscNewRequest, TrafficChainGetRequest,
8    TrafficClassGetRequest, TrafficFilterDelRequest, TrafficFilterGetRequest,
9    TrafficFilterNewRequest,
10};
11use crate::Handle;
12
13#[derive(Debug, Clone)]
14pub struct QDiscHandle(Handle);
15
16impl QDiscHandle {
17    pub fn new(handle: Handle) -> Self {
18        QDiscHandle(handle)
19    }
20
21    /// Retrieve the list of qdisc (equivalent to `tc qdisc show`)
22    pub fn get(&mut self) -> QDiscGetRequest {
23        QDiscGetRequest::new(self.0.clone())
24    }
25
26    /// Create a new qdisc, don't replace if the object already exists.
27    /// ( equivalent to `tc qdisc add dev STRING`)
28    pub fn add(&mut self, index: i32) -> QDiscNewRequest {
29        let msg = TcMessage::with_index(index);
30        QDiscNewRequest::new(self.0.clone(), msg, NLM_F_EXCL | NLM_F_CREATE)
31    }
32
33    /// Change the qdisc, the handle cannot be changed and neither can the
34    /// parent. In other words, change cannot move a node.
35    /// ( equivalent to `tc qdisc change dev STRING`)
36    pub fn change(&mut self, index: i32) -> QDiscNewRequest {
37        let msg = TcMessage::with_index(index);
38        QDiscNewRequest::new(self.0.clone(), msg, 0)
39    }
40
41    /// Replace existing matching qdisc, create qdisc if it doesn't already
42    /// exist. ( equivalent to `tc qdisc replace dev STRING`)
43    pub fn replace(&mut self, index: i32) -> QDiscNewRequest {
44        let msg = TcMessage::with_index(index);
45        QDiscNewRequest::new(self.0.clone(), msg, NLM_F_CREATE | NLM_F_REPLACE)
46    }
47
48    /// Performs a replace where the node must exist already.
49    /// ( equivalent to `tc qdisc link dev STRING`)
50    pub fn link(&mut self, index: i32) -> QDiscNewRequest {
51        let msg = TcMessage::with_index(index);
52        QDiscNewRequest::new(self.0.clone(), msg, NLM_F_REPLACE)
53    }
54
55    /// Delete the qdisc ( equivalent to `tc qdisc del dev STRING`)
56    pub fn del(&mut self, index: i32) -> QDiscDelRequest {
57        let msg = TcMessage::with_index(index);
58        QDiscDelRequest::new(self.0.clone(), msg)
59    }
60}
61
62#[derive(Debug, Clone)]
63pub struct TrafficClassHandle {
64    handle: Handle,
65    ifindex: i32,
66}
67
68impl TrafficClassHandle {
69    pub fn new(handle: Handle, ifindex: i32) -> Self {
70        TrafficClassHandle { handle, ifindex }
71    }
72
73    /// Retrieve the list of traffic class (equivalent to
74    /// `tc class show dev <interface_name>`)
75    pub fn get(&mut self) -> TrafficClassGetRequest {
76        TrafficClassGetRequest::new(self.handle.clone(), self.ifindex)
77    }
78}
79
80#[derive(Debug, Clone)]
81pub struct TrafficFilterHandle {
82    handle: Handle,
83    ifindex: i32,
84}
85
86impl TrafficFilterHandle {
87    pub fn new(handle: Handle, ifindex: i32) -> Self {
88        TrafficFilterHandle { handle, ifindex }
89    }
90
91    /// Retrieve the list of filter (equivalent to
92    /// `tc filter show dev <iface_name>`)
93    pub fn get(&mut self) -> TrafficFilterGetRequest {
94        TrafficFilterGetRequest::new(self.handle.clone(), self.ifindex)
95    }
96
97    /// Add a filter to a node, don't replace if the object already exists.
98    /// ( equivalent to `tc filter add dev STRING`)
99    pub fn add(&mut self) -> TrafficFilterNewRequest {
100        TrafficFilterNewRequest::new(
101            self.handle.clone(),
102            self.ifindex,
103            NLM_F_EXCL | NLM_F_CREATE,
104        )
105    }
106
107    /// Delete a filter from a node, don't replace if the object already exists.
108    /// ( equivalent to `tc filter del dev STRING`)
109    pub fn del(&mut self) -> TrafficFilterDelRequest {
110        TrafficFilterDelRequest::new(self.handle.clone(), self.ifindex)
111    }
112
113    /// Change the filter, the handle cannot be changed and neither can the
114    /// parent. In other words, change cannot move a node.
115    /// ( equivalent to `tc filter change dev STRING`)
116    pub fn change(&mut self) -> TrafficFilterNewRequest {
117        TrafficFilterNewRequest::new(self.handle.clone(), self.ifindex, 0)
118    }
119
120    /// Replace existing matching filter, create filter if it doesn't already
121    /// exist. ( equivalent to `tc filter replace dev STRING`)
122    pub fn replace(&mut self) -> TrafficFilterNewRequest {
123        TrafficFilterNewRequest::new(
124            self.handle.clone(),
125            self.ifindex,
126            NLM_F_CREATE,
127        )
128    }
129}
130
131#[derive(Debug, Clone)]
132pub struct TrafficChainHandle {
133    handle: Handle,
134    ifindex: i32,
135}
136
137impl TrafficChainHandle {
138    pub fn new(handle: Handle, ifindex: i32) -> Self {
139        TrafficChainHandle { handle, ifindex }
140    }
141
142    /// Retrieve the list of chain (equivalent to
143    /// `tc chain show dev <iface_name>`)
144    pub fn get(&mut self) -> TrafficChainGetRequest {
145        TrafficChainGetRequest::new(self.handle.clone(), self.ifindex)
146    }
147}