rtnetlink/traffic_control/
get.rs

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