1// SPDX-License-Identifier: MIT
23use crate::{
4 packet::{
5 nlas::link::Nla,
6 LinkMessage,
7 NetlinkMessage,
8 RtnlMessage,
9 IFF_NOARP,
10 IFF_PROMISC,
11 IFF_UP,
12 NLM_F_ACK,
13 NLM_F_CREATE,
14 NLM_F_EXCL,
15 NLM_F_REQUEST,
16 },
17 try_nl,
18 Error,
19 Handle,
20};
21use futures::stream::StreamExt;
22use std::os::unix::io::RawFd;
2324pub struct LinkSetRequest {
25 handle: Handle,
26 message: LinkMessage,
27}
2829impl LinkSetRequest {
30pub(crate) fn new(handle: Handle, index: u32) -> Self {
31let mut message = LinkMessage::default();
32 message.header.index = index;
33 LinkSetRequest { handle, message }
34 }
3536/// Execute the request
37pub async fn execute(self) -> Result<(), Error> {
38let LinkSetRequest {
39mut handle,
40 message,
41 } = self;
42let mut req = NetlinkMessage::from(RtnlMessage::SetLink(message));
43 req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
4445let mut response = handle.request(req)?;
46while let Some(message) = response.next().await {
47try_nl!(message);
48 }
49Ok(())
50 }
5152/// Return a mutable reference to the request
53pub fn message_mut(&mut self) -> &mut LinkMessage {
54&mut self.message
55 }
5657/// Attach the link to a bridge (its _master_). This is equivalent to `ip link set LINK master
58 /// BRIDGE`. To succeed, both the bridge and the link that is being attached must be UP.
59 ///
60 /// To Remove a link from a bridge, set its master to zero.
61 /// This is equvalent to `ip link set LINK nomaster`
62pub fn master(mut self, master_index: u32) -> Self {
63self.message.nlas.push(Nla::Master(master_index));
64self
65}
6667/// Detach the link from its _master_. This is equivalent to `ip link set LINK nomaster`.
68 ///To succeed, the link that is being detached must be UP.
69pub fn nomaster(mut self) -> Self {
70self.message.nlas.push(Nla::Master(0u32));
71self
72}
7374/// Set the link with the given index up (equivalent to `ip link set dev DEV up`)
75pub fn up(mut self) -> Self {
76self.message.header.flags |= IFF_UP;
77self.message.header.change_mask |= IFF_UP;
78self
79}
8081/// Set the link with the given index down (equivalent to `ip link set dev DEV down`)
82pub fn down(mut self) -> Self {
83self.message.header.flags &= !IFF_UP;
84self.message.header.change_mask |= IFF_UP;
85self
86}
8788/// Enable or disable promiscious mode of the link with the given index (equivalent to `ip link set dev DEV promisc on/off`)
89pub fn promiscuous(mut self, enable: bool) -> Self {
90if enable {
91self.message.header.flags |= IFF_PROMISC;
92 } else {
93self.message.header.flags &= !IFF_PROMISC;
94 }
95self.message.header.change_mask |= IFF_PROMISC;
96self
97}
9899/// Enable or disable the ARP protocol of the link with the given index (equivalent to `ip link set dev DEV arp on/off`)
100pub fn arp(mut self, enable: bool) -> Self {
101if enable {
102self.message.header.flags &= !IFF_NOARP;
103 } else {
104self.message.header.flags |= IFF_NOARP;
105 }
106self.message.header.change_mask |= IFF_NOARP;
107self
108}
109110/// Set the name of the link with the given index (equivalent to `ip link set DEV name NAME`)
111pub fn name(mut self, name: String) -> Self {
112self.message.nlas.push(Nla::IfName(name));
113self
114}
115116/// Set the mtu of the link with the given index (equivalent to `ip link set DEV mtu MTU`)
117pub fn mtu(mut self, mtu: u32) -> Self {
118self.message.nlas.push(Nla::Mtu(mtu));
119self
120}
121122/// Set the hardware address of the link with the given index (equivalent to `ip link set DEV address ADDRESS`)
123pub fn address(mut self, address: Vec<u8>) -> Self {
124self.message.nlas.push(Nla::Address(address));
125self
126}
127128/// Move this network device into the network namespace of the process with the given `pid`.
129pub fn setns_by_pid(mut self, pid: u32) -> Self {
130self.message.nlas.push(Nla::NetNsPid(pid));
131self
132}
133134/// Move this network device into the network namespace corresponding to the given file
135 /// descriptor.
136pub fn setns_by_fd(mut self, fd: RawFd) -> Self {
137self.message.nlas.push(Nla::NetNsFd(fd));
138self
139}
140}