1use futures::{
4 future::{self, Either},
5 stream::{StreamExt, TryStream},
6 FutureExt,
7};
8
9use crate::{
10 packet::{constants::*, nlas::link::Nla, LinkMessage, NetlinkMessage, RtnlMessage},
11 try_rtnl,
12 Error,
13 Handle,
14};
15
16pub struct LinkGetRequest {
17 handle: Handle,
18 message: LinkMessage,
19 dump: bool,
26}
27
28impl LinkGetRequest {
29 pub(crate) fn new(handle: Handle) -> Self {
30 LinkGetRequest {
31 handle,
32 message: LinkMessage::default(),
33 dump: true,
34 }
35 }
36
37 pub fn set_filter_mask(mut self, family: u8, filter_mask: u32) -> Self {
39 self.message.header.interface_family = family;
40 self.message.nlas.push(Nla::ExtMask(filter_mask));
41 self
42 }
43
44 pub fn execute(self) -> impl TryStream<Ok = LinkMessage, Error = Error> {
46 let LinkGetRequest {
47 mut handle,
48 message,
49 dump,
50 } = self;
51
52 let mut req = NetlinkMessage::from(RtnlMessage::GetLink(message));
53
54 if dump {
55 req.header.flags = NLM_F_REQUEST | NLM_F_DUMP;
56 } else {
57 req.header.flags = NLM_F_REQUEST;
58 }
59
60 match handle.request(req) {
61 Ok(response) => {
62 Either::Left(response.map(move |msg| Ok(try_rtnl!(msg, RtnlMessage::NewLink))))
63 }
64 Err(e) => Either::Right(future::err::<LinkMessage, Error>(e).into_stream()),
65 }
66 }
67
68 pub fn message_mut(&mut self) -> &mut LinkMessage {
70 &mut self.message
71 }
72
73 pub fn match_index(mut self, index: u32) -> Self {
75 self.dump = false;
76 self.message.header.index = index;
77 self
78 }
79
80 pub fn match_name(mut self, name: String) -> Self {
85 self.dump = false;
86 self.message.nlas.push(Nla::IfName(name));
87 self
88 }
89}