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