rtnetlink/neighbour/
get.rs

1// SPDX-License-Identifier: MIT
2
3use futures_util::{
4    future::{self, Either},
5    stream::{Stream, StreamExt},
6    FutureExt,
7};
8use netlink_packet_core::{
9    NetlinkMessage, NetlinkPayload, NLM_F_DUMP, NLM_F_REQUEST,
10};
11use netlink_packet_route::{
12    neighbour::{NeighbourFlags, NeighbourMessage},
13    RouteNetlinkMessage,
14};
15
16use crate::{Error, Handle, IpVersion};
17
18pub struct NeighbourGetRequest {
19    handle: Handle,
20    message: NeighbourMessage,
21}
22
23impl NeighbourGetRequest {
24    pub(crate) fn new(handle: Handle) -> Self {
25        let message = NeighbourMessage::default();
26        NeighbourGetRequest { handle, message }
27    }
28
29    /// List neighbor proxies in the system (equivalent to: `ip neighbor show
30    /// proxy`).
31    pub fn proxies(mut self) -> Self {
32        self.message.header.flags |= NeighbourFlags::Proxy;
33        self
34    }
35
36    pub fn set_family(mut self, ip_version: IpVersion) -> Self {
37        self.message.header.family = ip_version.family();
38        self
39    }
40
41    /// Execute the request
42    pub fn execute(
43        self,
44    ) -> impl Stream<Item = Result<NeighbourMessage, Error>> {
45        let NeighbourGetRequest {
46            mut handle,
47            message,
48        } = self;
49
50        let mut req =
51            NetlinkMessage::from(RouteNetlinkMessage::GetNeighbour(message));
52        req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
53
54        match handle.request(req) {
55            Ok(response) => Either::Left(response.map(move |msg| {
56                let (header, payload) = msg.into_parts();
57                match payload {
58                    NetlinkPayload::InnerMessage(
59                        RouteNetlinkMessage::NewNeighbour(msg),
60                    ) => Ok(msg),
61                    NetlinkPayload::Error(err) => Err(Error::NetlinkError(err)),
62                    _ => Err(Error::UnexpectedMessage(NetlinkMessage::new(
63                        header, payload,
64                    ))),
65                }
66            })),
67            Err(e) => Either::Right(
68                future::err::<NeighbourMessage, Error>(e).into_stream(),
69            ),
70        }
71    }
72
73    /// Return a mutable reference to the request
74    pub fn message_mut(&mut self) -> &mut NeighbourMessage {
75        &mut self.message
76    }
77}