1use std::{marker::PhantomData, net::IpAddr};
4
5use futures_util::stream::StreamExt;
6use netlink_packet_core::{
7 NetlinkMessage, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REPLACE,
8 NLM_F_REQUEST,
9};
10use netlink_packet_route::{route::RouteMessage, RouteNetlinkMessage};
11
12use crate::{try_nl, Error, Handle};
13
14#[derive(Debug, Clone)]
17pub struct RouteAddRequest<T = IpAddr> {
18 handle: Handle,
19 message: RouteMessage,
20 replace: bool,
21 _phantom: PhantomData<T>,
22}
23
24impl<T> RouteAddRequest<T> {
25 pub(crate) fn new(handle: Handle, message: RouteMessage) -> Self {
26 RouteAddRequest {
27 handle,
28 message,
29 replace: false,
30 _phantom: Default::default(),
31 }
32 }
33
34 pub fn message_mut(&mut self) -> &mut RouteMessage {
35 &mut self.message
36 }
37
38 pub fn replace(self) -> Self {
40 Self {
41 replace: true,
42 ..self
43 }
44 }
45
46 pub async fn execute(self) -> Result<(), Error> {
48 let RouteAddRequest {
49 mut handle,
50 message,
51 replace,
52 ..
53 } = self;
54 let mut req =
55 NetlinkMessage::from(RouteNetlinkMessage::NewRoute(message));
56 let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
57 req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;
58
59 let mut response = handle.request(req)?;
60 while let Some(message) = response.next().await {
61 try_nl!(message);
62 }
63 Ok(())
64 }
65}