rtnetlink 0.13.1

manipulate linux networking resources via netlink
Documentation
// SPDX-License-Identifier: MIT

use futures::{
    future::{self, Either},
    stream::{StreamExt, TryStream},
    FutureExt,
};
use netlink_packet_core::{NetlinkMessage, NLM_F_DUMP, NLM_F_REQUEST};
use netlink_packet_route::{
    RtnlMessage, RuleMessage, FR_ACT_UNSPEC, RT_TABLE_UNSPEC,
};

use crate::{try_rtnl, Error, Handle, IpVersion};

pub struct RuleGetRequest {
    handle: Handle,
    message: RuleMessage,
}

impl RuleGetRequest {
    pub(crate) fn new(handle: Handle, ip_version: IpVersion) -> Self {
        let mut message = RuleMessage::default();
        message.header.family = ip_version.family();

        message.header.dst_len = 0;
        message.header.src_len = 0;
        message.header.tos = 0;
        message.header.action = FR_ACT_UNSPEC;
        message.header.table = RT_TABLE_UNSPEC;

        RuleGetRequest { handle, message }
    }

    pub fn message_mut(&mut self) -> &mut RuleMessage {
        &mut self.message
    }

    pub fn execute(self) -> impl TryStream<Ok = RuleMessage, Error = Error> {
        let RuleGetRequest {
            mut handle,
            message,
        } = self;

        let mut req = NetlinkMessage::from(RtnlMessage::GetRule(message));
        req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;

        match handle.request(req) {
            Ok(response) => Either::Left(
                response
                    .map(move |msg| Ok(try_rtnl!(msg, RtnlMessage::NewRule))),
            ),
            Err(e) => Either::Right(
                future::err::<RuleMessage, Error>(e).into_stream(),
            ),
        }
    }
}