1use 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;
23
24pub struct LinkSetRequest {
25 handle: Handle,
26 message: LinkMessage,
27}
28
29impl LinkSetRequest {
30 pub(crate) fn new(handle: Handle, index: u32) -> Self {
31 let mut message = LinkMessage::default();
32 message.header.index = index;
33 LinkSetRequest { handle, message }
34 }
35
36 pub async fn execute(self) -> Result<(), Error> {
38 let LinkSetRequest {
39 mut handle,
40 message,
41 } = self;
42 let mut req = NetlinkMessage::from(RtnlMessage::SetLink(message));
43 req.header.flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
44
45 let mut response = handle.request(req)?;
46 while let Some(message) = response.next().await {
47 try_nl!(message);
48 }
49 Ok(())
50 }
51
52 pub fn message_mut(&mut self) -> &mut LinkMessage {
54 &mut self.message
55 }
56
57 pub fn master(mut self, master_index: u32) -> Self {
63 self.message.nlas.push(Nla::Master(master_index));
64 self
65 }
66
67 pub fn nomaster(mut self) -> Self {
70 self.message.nlas.push(Nla::Master(0u32));
71 self
72 }
73
74 pub fn up(mut self) -> Self {
76 self.message.header.flags |= IFF_UP;
77 self.message.header.change_mask |= IFF_UP;
78 self
79 }
80
81 pub fn down(mut self) -> Self {
83 self.message.header.flags &= !IFF_UP;
84 self.message.header.change_mask |= IFF_UP;
85 self
86 }
87
88 pub fn promiscuous(mut self, enable: bool) -> Self {
90 if enable {
91 self.message.header.flags |= IFF_PROMISC;
92 } else {
93 self.message.header.flags &= !IFF_PROMISC;
94 }
95 self.message.header.change_mask |= IFF_PROMISC;
96 self
97 }
98
99 pub fn arp(mut self, enable: bool) -> Self {
101 if enable {
102 self.message.header.flags &= !IFF_NOARP;
103 } else {
104 self.message.header.flags |= IFF_NOARP;
105 }
106 self.message.header.change_mask |= IFF_NOARP;
107 self
108 }
109
110 pub fn name(mut self, name: String) -> Self {
112 self.message.nlas.push(Nla::IfName(name));
113 self
114 }
115
116 pub fn mtu(mut self, mtu: u32) -> Self {
118 self.message.nlas.push(Nla::Mtu(mtu));
119 self
120 }
121
122 pub fn address(mut self, address: Vec<u8>) -> Self {
124 self.message.nlas.push(Nla::Address(address));
125 self
126 }
127
128 pub fn setns_by_pid(mut self, pid: u32) -> Self {
130 self.message.nlas.push(Nla::NetNsPid(pid));
131 self
132 }
133
134 pub fn setns_by_fd(mut self, fd: RawFd) -> Self {
137 self.message.nlas.push(Nla::NetNsFd(fd));
138 self
139 }
140}