rtnetlink/link/
property_add.rs

1// SPDX-License-Identifier: MIT
2
3use futures::stream::StreamExt;
4use netlink_packet_core::{
5    NetlinkMessage, NetlinkPayload, NLM_F_ACK, NLM_F_APPEND, NLM_F_CREATE,
6    NLM_F_EXCL, NLM_F_REQUEST,
7};
8use netlink_packet_route::{
9    link::nlas::{Nla, Prop},
10    LinkMessage, RtnlMessage,
11};
12
13use crate::{Error, Handle};
14
15pub struct LinkNewPropRequest {
16    handle: Handle,
17    message: LinkMessage,
18}
19
20impl LinkNewPropRequest {
21    pub(crate) fn new(handle: Handle, index: u32) -> Self {
22        let mut message = LinkMessage::default();
23        message.header.index = index;
24        LinkNewPropRequest { handle, message }
25    }
26
27    /// Execute the request
28    pub async fn execute(self) -> Result<(), Error> {
29        let LinkNewPropRequest {
30            mut handle,
31            message,
32        } = self;
33        let mut req = NetlinkMessage::from(RtnlMessage::NewLinkProp(message));
34        req.header.flags = NLM_F_REQUEST
35            | NLM_F_ACK
36            | NLM_F_EXCL
37            | NLM_F_CREATE
38            | NLM_F_APPEND;
39
40        let mut response = handle.request(req)?;
41        while let Some(message) = response.next().await {
42            if let NetlinkPayload::Error(err) = message.payload {
43                return Err(Error::NetlinkError(err));
44            }
45        }
46        Ok(())
47    }
48
49    /// Return a mutable reference to the request
50    pub fn message_mut(&mut self) -> &mut LinkMessage {
51        &mut self.message
52    }
53
54    /// Add alternative name to the link. This is equivalent to `ip link
55    /// property add altname ALT_IFNAME dev LINK`.
56    pub fn alt_ifname(mut self, alt_ifnames: &[&str]) -> Self {
57        let mut props = Vec::new();
58        for alt_ifname in alt_ifnames {
59            props.push(Prop::AltIfName(alt_ifname.to_string()));
60        }
61
62        self.message.nlas.push(Nla::PropList(props));
63        self
64    }
65}