1use crate::IpVersion;
4use futures::{
5 future::{self, Either},
6 stream::{StreamExt, TryStream},
7 FutureExt,
8};
9
10use netlink_packet_route::{constants::*, NetlinkMessage, RtnlMessage, RuleMessage};
11
12use crate::{try_rtnl, Error, Handle};
13
14pub struct RuleGetRequest {
15 handle: Handle,
16 message: RuleMessage,
17}
18
19impl RuleGetRequest {
20 pub(crate) fn new(handle: Handle, ip_version: IpVersion) -> Self {
21 let mut message = RuleMessage::default();
22 message.header.family = ip_version.family();
23
24 message.header.dst_len = 0;
25 message.header.src_len = 0;
26 message.header.tos = 0;
27 message.header.action = FR_ACT_UNSPEC;
28 message.header.table = RT_TABLE_UNSPEC;
29
30 RuleGetRequest { handle, message }
31 }
32
33 pub fn message_mut(&mut self) -> &mut RuleMessage {
34 &mut self.message
35 }
36
37 pub fn execute(self) -> impl TryStream<Ok = RuleMessage, Error = Error> {
38 let RuleGetRequest {
39 mut handle,
40 message,
41 } = self;
42
43 let mut req = NetlinkMessage::from(RtnlMessage::GetRule(message));
44 req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
45
46 match handle.request(req) {
47 Ok(response) => {
48 Either::Left(response.map(move |msg| Ok(try_rtnl!(msg, RtnlMessage::NewRule))))
49 }
50 Err(e) => Either::Right(future::err::<RuleMessage, Error>(e).into_stream()),
51 }
52 }
53}