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