1use std::os::unix::io::RawFd;
4
5use futures::stream::StreamExt;
6use netlink_packet_core::{
7 NetlinkMessage, NLM_F_ACK, NLM_F_CREATE, NLM_F_EXCL, NLM_F_REQUEST,
8};
9use netlink_packet_route::{
10 link::nlas::Nla, LinkMessage, RtnlMessage, IFF_NOARP, IFF_PROMISC, IFF_UP,
11};
12
13use crate::{try_nl, Error, Handle};
14
15pub struct LinkSetRequest {
16 handle: Handle,
17 message: LinkMessage,
18}
19
20impl LinkSetRequest {
21 pub(crate) fn new(handle: Handle, index: u32) -> Self {
22 let mut message = LinkMessage::default();
23 message.header.index = index;
24 LinkSetRequest { handle, message }
25 }
26
27 pub async fn execute(self) -> Result<(), Error> {
29 let LinkSetRequest {
30 mut handle,
31 message,
32 } = self;
33 let mut req = NetlinkMessage::from(RtnlMessage::SetLink(message));
34 req.header.flags =
35 NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
36
37 let mut response = handle.request(req)?;
38 while let Some(message) = response.next().await {
39 try_nl!(message);
40 }
41 Ok(())
42 }
43
44 pub fn message_mut(&mut self) -> &mut LinkMessage {
46 &mut self.message
47 }
48
49 pub fn master(mut self, master_index: u32) -> Self {
56 self.message.nlas.push(Nla::Master(master_index));
57 self
58 }
59
60 pub fn nomaster(mut self) -> Self {
64 self.message.nlas.push(Nla::Master(0u32));
65 self
66 }
67
68 pub fn up(mut self) -> Self {
71 self.message.header.flags |= IFF_UP;
72 self.message.header.change_mask |= IFF_UP;
73 self
74 }
75
76 pub fn down(mut self) -> Self {
79 self.message.header.flags &= !IFF_UP;
80 self.message.header.change_mask |= IFF_UP;
81 self
82 }
83
84 pub fn promiscuous(mut self, enable: bool) -> Self {
87 if enable {
88 self.message.header.flags |= IFF_PROMISC;
89 } else {
90 self.message.header.flags &= !IFF_PROMISC;
91 }
92 self.message.header.change_mask |= IFF_PROMISC;
93 self
94 }
95
96 pub fn arp(mut self, enable: bool) -> Self {
99 if enable {
100 self.message.header.flags &= !IFF_NOARP;
101 } else {
102 self.message.header.flags |= IFF_NOARP;
103 }
104 self.message.header.change_mask |= IFF_NOARP;
105 self
106 }
107
108 pub fn name(mut self, name: String) -> Self {
111 self.message.nlas.push(Nla::IfName(name));
112 self
113 }
114
115 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 {
125 self.message.nlas.push(Nla::Address(address));
126 self
127 }
128
129 pub fn setns_by_pid(mut self, pid: u32) -> Self {
132 self.message.nlas.push(Nla::NetNsPid(pid));
133 self
134 }
135
136 pub fn setns_by_fd(mut self, fd: RawFd) -> Self {
139 self.message.nlas.push(Nla::NetNsFd(fd));
140 self
141 }
142}