1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
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::{address::AddressMessage, RouteNetlinkMessage};
11
12use crate::{addr::AddressMessageBuilder, try_nl, Error, Handle};
13
14pub struct AddressAddRequest {
17 handle: Handle,
18 message: AddressMessage,
19 replace: bool,
20}
21
22impl AddressAddRequest {
23 pub(crate) fn new(
24 handle: Handle,
25 index: u32,
26 address: IpAddr,
27 prefix_len: u8,
28 ) -> Self {
29 let message = match address {
30 IpAddr::V4(address) => AddressMessageBuilder::<Ipv4Addr>::new()
31 .index(index)
32 .address(address, prefix_len)
33 .build(),
34 IpAddr::V6(address) => AddressMessageBuilder::<Ipv6Addr>::new()
35 .index(index)
36 .address(address, prefix_len)
37 .build(),
38 };
39
40 AddressAddRequest {
41 handle,
42 message,
43 replace: false,
44 }
45 }
46
47 pub fn replace(self) -> Self {
49 Self {
50 replace: true,
51 ..self
52 }
53 }
54
55 pub async fn execute(self) -> Result<(), Error> {
57 let AddressAddRequest {
58 mut handle,
59 message,
60 replace,
61 } = self;
62 let mut req =
63 NetlinkMessage::from(RouteNetlinkMessage::NewAddress(message));
64 let replace = if replace { NLM_F_REPLACE } else { NLM_F_EXCL };
65 req.header.flags = NLM_F_REQUEST | NLM_F_ACK | replace | NLM_F_CREATE;
66
67 let mut response = handle.request(req)?;
68 while let Some(message) = response.next().await {
69 try_nl!(message);
70 }
71 Ok(())
72 }
73
74 pub fn message_mut(&mut self) -> &mut AddressMessage {
76 &mut self.message
77 }
78}