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