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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
// SPDX-License-Identifier: MIT
use std::net::{Ipv4Addr, Ipv6Addr};
use crate::{
link::LinkMessageBuilder,
packet_route::link::{
BondAdSelect, BondAllPortActive, BondArpAllTargets, BondArpValidate,
BondFailOverMac, BondLacpRate, BondMode, BondPrimaryReselect,
BondXmitHashPolicy, InfoBond, InfoData, InfoKind,
},
};
///
/// Represent bond interface.
/// Example code on creating a bond interface
/// ```no_run
/// use rtnetlink::{new_connection, LinkBond, packet_route::link::BondMode};
///
/// #[tokio::main]
/// async fn main() -> Result<(), String> {
/// let (connection, handle, _) = new_connection().map_err(|e|
/// format!("{e}"))?;
/// tokio::spawn(connection);
///
/// let message = LinkBond::new("bond0")
/// .mode(BondMode::ActiveBackup)
/// .miimon(100)
/// .updelay(100)
/// .downdelay(100)
/// .min_links(2)
/// .up()
/// .build();
///
/// handle
/// .link()
/// .add(message)
/// .execute()
/// .await
/// .map_err(|e| format!("{e}"))
/// }
/// ```
///
/// Please check LinkMessageBuilder::<LinkBond> for more detail.
#[derive(Debug)]
pub struct LinkBond;
impl LinkBond {
/// Equal to `LinkMessageBuilder::<LinkBond>::new()`
pub fn new(name: &str) -> LinkMessageBuilder<Self> {
LinkMessageBuilder::<LinkBond>::new(name)
}
}
impl LinkMessageBuilder<LinkBond> {
/// Create [LinkMessageBuilder] for bond
pub fn new(name: &str) -> Self {
LinkMessageBuilder::<LinkBond>::new_with_info_kind(InfoKind::Bond)
.name(name.to_string())
}
pub fn append_info_data(self, info: InfoBond) -> Self {
let mut ret = self;
if let InfoData::Bond(infos) = ret
.info_data
.get_or_insert_with(|| InfoData::Bond(Vec::new()))
{
infos.push(info);
}
ret
}
/// Adds the `mode` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond mode MODE`.
pub fn mode(self, mode: BondMode) -> Self {
self.append_info_data(InfoBond::Mode(mode))
}
/// Adds the `active_port` attribute to the bond, where `active_port`
/// is the ifindex of an interface attached to the bond.
/// This is equivalent to `ip link add name NAME type bond active_slave
/// ACTIVE_PORT_NAME`.
pub fn active_port(self, active_port: u32) -> Self {
self.append_info_data(InfoBond::ActivePort(active_port))
}
/// Adds the `miimon` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond miimon MIIMON`.
pub fn miimon(self, miimon: u32) -> Self {
self.append_info_data(InfoBond::MiiMon(miimon))
}
/// Adds the `updelay` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond updelay UPDELAY`.
pub fn updelay(self, updelay: u32) -> Self {
self.append_info_data(InfoBond::UpDelay(updelay))
}
/// Adds the `downdelay` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond downdelay
/// DOWNDELAY`.
pub fn downdelay(self, downdelay: u32) -> Self {
self.append_info_data(InfoBond::DownDelay(downdelay))
}
/// Adds the `use_carrier` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond use_carrier
/// USE_CARRIER`.
pub fn use_carrier(self, use_carrier: bool) -> Self {
self.append_info_data(InfoBond::UseCarrier(use_carrier))
}
/// Adds the `arp_interval` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond arp_interval
/// ARP_INTERVAL`.
pub fn arp_interval(self, arp_interval: u32) -> Self {
self.append_info_data(InfoBond::ArpInterval(arp_interval))
}
/// Adds the `arp_validate` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond arp_validate
/// ARP_VALIDATE`.
pub fn arp_validate(self, arp_validate: BondArpValidate) -> Self {
self.append_info_data(InfoBond::ArpValidate(arp_validate))
}
/// Adds the `arp_all_targets` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond arp_all_targets
/// ARP_ALL_TARGETS`
pub fn arp_all_targets(self, arp_all_targets: BondArpAllTargets) -> Self {
self.append_info_data(InfoBond::ArpAllTargets(arp_all_targets))
}
/// Adds the `primary` attribute to the bond, where `primary` is the ifindex
/// of an interface.
/// This is equivalent to `ip link add name NAME type bond primary
/// PRIMARY_NAME`
pub fn primary(self, primary: u32) -> Self {
self.append_info_data(InfoBond::Primary(primary))
}
/// Adds the `primary_reselect` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond primary_reselect
/// PRIMARY_RESELECT`.
pub fn primary_reselect(
self,
primary_reselect: BondPrimaryReselect,
) -> Self {
self.append_info_data(InfoBond::PrimaryReselect(primary_reselect))
}
/// Adds the `fail_over_mac` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond fail_over_mac
/// FAIL_OVER_MAC`.
pub fn fail_over_mac(self, fail_over_mac: BondFailOverMac) -> Self {
self.append_info_data(InfoBond::FailOverMac(fail_over_mac))
}
/// Adds the `xmit_hash_policy` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond xmit_hash_policy
/// XMIT_HASH_POLICY`.
pub fn xmit_hash_policy(
self,
xmit_hash_policy: BondXmitHashPolicy,
) -> Self {
self.append_info_data(InfoBond::XmitHashPolicy(xmit_hash_policy))
}
/// Adds the `resend_igmp` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond resend_igmp
/// RESEND_IGMP`.
pub fn resend_igmp(self, resend_igmp: u32) -> Self {
self.append_info_data(InfoBond::ResendIgmp(resend_igmp))
}
/// Adds the `num_peer_notif` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond num_peer_notif
/// NUM_PEER_NOTIF`.
pub fn num_peer_notif(self, num_peer_notif: u8) -> Self {
self.append_info_data(InfoBond::NumPeerNotif(num_peer_notif))
}
/// Adds the `all_ports_active` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond all_slaves_active
/// ALL_PORTS_ACTIVE`.
pub fn all_ports_active(self, all_ports_active: BondAllPortActive) -> Self {
self.append_info_data(InfoBond::AllPortsActive(all_ports_active))
}
/// Adds the `min_links` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond min_links
/// MIN_LINKS`.
pub fn min_links(self, min_links: u32) -> Self {
self.append_info_data(InfoBond::MinLinks(min_links))
}
/// Adds the `lp_interval` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond lp_interval
/// LP_INTERVAL`.
pub fn lp_interval(self, lp_interval: u32) -> Self {
self.append_info_data(InfoBond::LpInterval(lp_interval))
}
/// Adds the `packets_per_port` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond packets_per_slave
/// PACKETS_PER_PORT`.
pub fn packets_per_port(self, packets_per_port: u32) -> Self {
self.append_info_data(InfoBond::PacketsPerPort(packets_per_port))
}
/// Adds the `ad_lacp_rate` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_lacp_rate
/// AD_LACP_RATE`.
pub fn ad_lacp_rate(self, ad_lacp_rate: BondLacpRate) -> Self {
self.append_info_data(InfoBond::AdLacpRate(ad_lacp_rate))
}
/// Adds the `ad_select` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_select
/// AD_SELECT`.
pub fn ad_select(self, ad_select: BondAdSelect) -> Self {
self.append_info_data(InfoBond::AdSelect(ad_select))
}
/// Adds the `ad_actor_sys_prio` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_actor_sys_prio
/// AD_ACTOR_SYS_PRIO`.
pub fn ad_actor_sys_prio(self, ad_actor_sys_prio: u16) -> Self {
self.append_info_data(InfoBond::AdActorSysPrio(ad_actor_sys_prio))
}
/// Adds the `ad_user_port_key` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_user_port_key
/// AD_USER_PORT_KEY`.
pub fn ad_user_port_key(self, ad_user_port_key: u16) -> Self {
self.append_info_data(InfoBond::AdUserPortKey(ad_user_port_key))
}
/// Adds the `ad_actor_system` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_actor_system
/// AD_ACTOR_SYSTEM`.
pub fn ad_actor_system(self, ad_actor_system: [u8; 6]) -> Self {
self.append_info_data(InfoBond::AdActorSystem(ad_actor_system))
}
/// Adds the `tlb_dynamic_lb` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond tlb_dynamic_lb
/// TLB_DYNAMIC_LB`.
pub fn tlb_dynamic_lb(self, tlb_dynamic_lb: bool) -> Self {
self.append_info_data(InfoBond::TlbDynamicLb(tlb_dynamic_lb))
}
/// Adds the `peer_notif_delay` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond peer_notif_delay
/// PEER_NOTIF_DELAY`.
pub fn peer_notif_delay(self, peer_notif_delay: u32) -> Self {
self.append_info_data(InfoBond::PeerNotifDelay(peer_notif_delay))
}
/// Adds the `ad_lacp_active` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ad_lacp_active
/// AD_LACP_ACTIVE`.
pub fn ad_lacp_active(self, ad_lacp_active: bool) -> Self {
self.append_info_data(InfoBond::AdLacpActive(ad_lacp_active))
}
/// Adds the `missed_max` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond missed_max
/// MISSED_MAX`.
pub fn missed_max(self, missed_max: u8) -> Self {
self.append_info_data(InfoBond::MissedMax(missed_max))
}
/// Adds the `arp_ip_target` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond arp_ip_target
/// LIST`.
pub fn arp_ip_target(self, arp_ip_target: Vec<Ipv4Addr>) -> Self {
self.append_info_data(InfoBond::ArpIpTarget(arp_ip_target))
}
/// Adds the `ns_ip6_target` attribute to the bond
/// This is equivalent to `ip link add name NAME type bond ns_ip6_target
/// LIST`.
pub fn ns_ip6_target(self, ns_ip6_target: Vec<Ipv6Addr>) -> Self {
self.append_info_data(InfoBond::NsIp6Target(ns_ip6_target))
}
}