rtnetlink/traffic_control/
get.rs

1// SPDX-License-Identifier: MIT
2
3use futures::{
4    future::{self, Either},
5    stream::{StreamExt, TryStream},
6    FutureExt,
7};
8use netlink_packet_core::{NetlinkMessage, NLM_F_DUMP, NLM_F_REQUEST};
9use netlink_packet_route::{
10    tc::constants::{TC_H_INGRESS, TC_H_ROOT},
11    RtnlMessage, TcMessage,
12};
13
14use crate::{try_rtnl, Error, Handle};
15
16pub struct QDiscGetRequest {
17    handle: Handle,
18    message: TcMessage,
19}
20
21impl QDiscGetRequest {
22    pub(crate) fn new(handle: Handle) -> Self {
23        QDiscGetRequest {
24            handle,
25            message: TcMessage::default(),
26        }
27    }
28
29    /// Execute the request
30    pub fn execute(self) -> impl TryStream<Ok = TcMessage, Error = Error> {
31        let QDiscGetRequest {
32            mut handle,
33            message,
34        } = self;
35
36        let mut req =
37            NetlinkMessage::from(RtnlMessage::GetQueueDiscipline(message));
38        req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
39
40        match handle.request(req) {
41            Ok(response) => Either::Left(response.map(move |msg| {
42                Ok(try_rtnl!(msg, RtnlMessage::NewQueueDiscipline))
43            })),
44            Err(e) => {
45                Either::Right(future::err::<TcMessage, Error>(e).into_stream())
46            }
47        }
48    }
49
50    pub fn index(mut self, index: i32) -> Self {
51        self.message.header.index = index;
52        self
53    }
54
55    /// Get ingress qdisc
56    pub fn ingress(mut self) -> Self {
57        self.message.header.parent = TC_H_INGRESS;
58        self
59    }
60}
61
62pub struct TrafficClassGetRequest {
63    handle: Handle,
64    message: TcMessage,
65}
66
67impl TrafficClassGetRequest {
68    pub(crate) fn new(handle: Handle, ifindex: i32) -> Self {
69        let mut message = TcMessage::default();
70        message.header.index = ifindex;
71        TrafficClassGetRequest { handle, message }
72    }
73
74    /// Execute the request
75    pub fn execute(self) -> impl TryStream<Ok = TcMessage, Error = Error> {
76        let TrafficClassGetRequest {
77            mut handle,
78            message,
79        } = self;
80
81        let mut req =
82            NetlinkMessage::from(RtnlMessage::GetTrafficClass(message));
83        req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
84
85        match handle.request(req) {
86            Ok(response) => Either::Left(response.map(move |msg| {
87                Ok(try_rtnl!(msg, RtnlMessage::NewTrafficClass))
88            })),
89            Err(e) => {
90                Either::Right(future::err::<TcMessage, Error>(e).into_stream())
91            }
92        }
93    }
94}
95
96pub struct TrafficFilterGetRequest {
97    handle: Handle,
98    message: TcMessage,
99}
100
101impl TrafficFilterGetRequest {
102    pub(crate) fn new(handle: Handle, ifindex: i32) -> Self {
103        let mut message = TcMessage::default();
104        message.header.index = ifindex;
105        TrafficFilterGetRequest { handle, message }
106    }
107
108    /// Execute the request
109    pub fn execute(self) -> impl TryStream<Ok = TcMessage, Error = Error> {
110        let TrafficFilterGetRequest {
111            mut handle,
112            message,
113        } = self;
114
115        let mut req =
116            NetlinkMessage::from(RtnlMessage::GetTrafficFilter(message));
117        req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
118
119        match handle.request(req) {
120            Ok(response) => Either::Left(response.map(move |msg| {
121                Ok(try_rtnl!(msg, RtnlMessage::NewTrafficFilter))
122            })),
123            Err(e) => {
124                Either::Right(future::err::<TcMessage, Error>(e).into_stream())
125            }
126        }
127    }
128
129    /// Set parent to root.
130    pub fn root(mut self) -> Self {
131        self.message.header.parent = TC_H_ROOT;
132        self
133    }
134}
135
136pub struct TrafficChainGetRequest {
137    handle: Handle,
138    message: TcMessage,
139}
140
141impl TrafficChainGetRequest {
142    pub(crate) fn new(handle: Handle, ifindex: i32) -> Self {
143        let mut message = TcMessage::default();
144        message.header.index = ifindex;
145        TrafficChainGetRequest { handle, message }
146    }
147
148    /// Execute the request
149    pub fn execute(self) -> impl TryStream<Ok = TcMessage, Error = Error> {
150        let TrafficChainGetRequest {
151            mut handle,
152            message,
153        } = self;
154
155        let mut req =
156            NetlinkMessage::from(RtnlMessage::GetTrafficChain(message));
157        req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
158
159        match handle.request(req) {
160            Ok(response) => Either::Left(response.map(move |msg| {
161                Ok(try_rtnl!(msg, RtnlMessage::NewTrafficChain))
162            })),
163            Err(e) => {
164                Either::Right(future::err::<TcMessage, Error>(e).into_stream())
165            }
166        }
167    }
168}