1use futures::{future::Either, FutureExt, Stream, StreamExt, TryStream};
4use genetlink::GenetlinkHandle;
5use netlink_packet_core::DecodeError;
6use netlink_packet_core::{NetlinkMessage, NLM_F_DUMP, NLM_F_REQUEST};
7use netlink_packet_generic::GenlMessage;
8
9use crate::{
10 try_mptcp, MptcpPathManagerAddressHandle, MptcpPathManagerCmd,
11 MptcpPathManagerError, MptcpPathManagerLimitsHandle,
12 MptcpPathManagerMessage,
13};
14
15#[derive(Clone, Debug)]
16pub struct MptcpPathManagerHandle {
17 pub handle: GenetlinkHandle,
18}
19
20impl MptcpPathManagerHandle {
21 pub(crate) fn new(handle: GenetlinkHandle) -> Self {
22 MptcpPathManagerHandle { handle }
23 }
24
25 pub fn address(&self) -> MptcpPathManagerAddressHandle {
29 MptcpPathManagerAddressHandle::new(self.clone())
30 }
31
32 pub fn limits(&self) -> MptcpPathManagerLimitsHandle {
34 MptcpPathManagerLimitsHandle::new(self.clone())
35 }
36
37 pub async fn request(
38 &mut self,
39 message: NetlinkMessage<GenlMessage<MptcpPathManagerMessage>>,
40 ) -> Result<
41 impl Stream<
42 Item = Result<
43 NetlinkMessage<GenlMessage<MptcpPathManagerMessage>>,
44 DecodeError,
45 >,
46 >,
47 MptcpPathManagerError,
48 > {
49 self.handle.request(message).await.map_err(|e| {
50 MptcpPathManagerError::RequestFailed(format!(
51 "BUG: Request failed with {e}"
52 ))
53 })
54 }
55}
56
57pub(crate) async fn mptcp_execute(
58 handle: &mut MptcpPathManagerHandle,
59 mptcp_msg: MptcpPathManagerMessage,
60) -> impl TryStream<
61 Ok = GenlMessage<MptcpPathManagerMessage>,
62 Error = MptcpPathManagerError,
63> {
64 let nl_header_flags = match mptcp_msg.cmd {
65 MptcpPathManagerCmd::AddressGet => NLM_F_REQUEST | NLM_F_DUMP,
66 MptcpPathManagerCmd::LimitsGet => NLM_F_REQUEST,
67 };
68
69 let mut nl_msg = NetlinkMessage::from(GenlMessage::from_payload(mptcp_msg));
70
71 nl_msg.header.flags = nl_header_flags;
72
73 match handle.request(nl_msg).await {
74 Ok(response) => {
75 Either::Left(response.map(move |msg| Ok(try_mptcp!(msg))))
76 }
77 Err(e) => Either::Right(
78 futures::future::err::<
79 GenlMessage<MptcpPathManagerMessage>,
80 MptcpPathManagerError,
81 >(e)
82 .into_stream(),
83 ),
84 }
85}