rtnetlink/link/bond.rs
1// SPDX-License-Identifier: MIT
2
3use std::net::{Ipv4Addr, Ipv6Addr};
4
5use crate::{
6 link::LinkMessageBuilder,
7 packet_route::link::{
8 BondAllPortActive, BondArpAllTargets, BondArpValidate, BondFailOverMac,
9 BondLacpRate, BondMode, BondPrimaryReselect, BondXmitHashPolicy,
10 InfoBond, InfoData, InfoKind,
11 },
12};
13
14///
15/// Represent bond interface.
16/// Example code on creating a bond interface
17/// ```no_run
18/// use rtnetlink::{new_connection, LinkBond, packet_route::link::BondMode};
19///
20/// #[tokio::main]
21/// async fn main() -> Result<(), String> {
22/// let (connection, handle, _) = new_connection().map_err(|e|
23/// format!("{e}"))?;
24/// tokio::spawn(connection);
25///
26/// let message = LinkBond::new("bond0")
27/// .mode(BondMode::ActiveBackup)
28/// .miimon(100)
29/// .updelay(100)
30/// .downdelay(100)
31/// .min_links(2)
32/// .up()
33/// .build();
34///
35/// handle
36/// .link()
37/// .add(message)
38/// .execute()
39/// .await
40/// .map_err(|e| format!("{e}"))
41/// }
42/// ```
43///
44/// Please check LinkMessageBuilder::<LinkBond> for more detail.
45#[derive(Debug)]
46pub struct LinkBond;
47
48impl LinkBond {
49 /// Equal to `LinkMessageBuilder::<LinkBond>::new()`
50 pub fn new(name: &str) -> LinkMessageBuilder<Self> {
51 LinkMessageBuilder::<LinkBond>::new(name)
52 }
53}
54
55impl LinkMessageBuilder<LinkBond> {
56 /// Create [LinkMessageBuilder] for bond
57 pub fn new(name: &str) -> Self {
58 LinkMessageBuilder::<LinkBond>::new_with_info_kind(InfoKind::Bond)
59 .name(name.to_string())
60 }
61
62 pub fn append_info_data(self, info: InfoBond) -> Self {
63 let mut ret = self;
64 if let InfoData::Bond(infos) = ret
65 .info_data
66 .get_or_insert_with(|| InfoData::Bond(Vec::new()))
67 {
68 infos.push(info);
69 }
70 ret
71 }
72
73 /// Adds the `mode` attribute to the bond
74 /// This is equivalent to `ip link add name NAME type bond mode MODE`.
75 pub fn mode(self, mode: BondMode) -> Self {
76 self.append_info_data(InfoBond::Mode(mode))
77 }
78
79 /// Adds the `active_port` attribute to the bond, where `active_port`
80 /// is the ifindex of an interface attached to the bond.
81 /// This is equivalent to `ip link add name NAME type bond active_slave
82 /// ACTIVE_PORT_NAME`.
83 pub fn active_port(self, active_port: u32) -> Self {
84 self.append_info_data(InfoBond::ActivePort(active_port))
85 }
86
87 /// Adds the `miimon` attribute to the bond
88 /// This is equivalent to `ip link add name NAME type bond miimon MIIMON`.
89 pub fn miimon(self, miimon: u32) -> Self {
90 self.append_info_data(InfoBond::MiiMon(miimon))
91 }
92
93 /// Adds the `updelay` attribute to the bond
94 /// This is equivalent to `ip link add name NAME type bond updelay UPDELAY`.
95 pub fn updelay(self, updelay: u32) -> Self {
96 self.append_info_data(InfoBond::UpDelay(updelay))
97 }
98
99 /// Adds the `downdelay` attribute to the bond
100 /// This is equivalent to `ip link add name NAME type bond downdelay
101 /// DOWNDELAY`.
102 pub fn downdelay(self, downdelay: u32) -> Self {
103 self.append_info_data(InfoBond::DownDelay(downdelay))
104 }
105
106 /// Adds the `use_carrier` attribute to the bond
107 /// This is equivalent to `ip link add name NAME type bond use_carrier
108 /// USE_CARRIER`.
109 pub fn use_carrier(self, use_carrier: bool) -> Self {
110 self.append_info_data(InfoBond::UseCarrier(use_carrier))
111 }
112
113 /// Adds the `arp_interval` attribute to the bond
114 /// This is equivalent to `ip link add name NAME type bond arp_interval
115 /// ARP_INTERVAL`.
116 pub fn arp_interval(self, arp_interval: u32) -> Self {
117 self.append_info_data(InfoBond::ArpInterval(arp_interval))
118 }
119
120 /// Adds the `arp_validate` attribute to the bond
121 /// This is equivalent to `ip link add name NAME type bond arp_validate
122 /// ARP_VALIDATE`.
123 pub fn arp_validate(self, arp_validate: BondArpValidate) -> Self {
124 self.append_info_data(InfoBond::ArpValidate(arp_validate))
125 }
126
127 /// Adds the `arp_all_targets` attribute to the bond
128 /// This is equivalent to `ip link add name NAME type bond arp_all_targets
129 /// ARP_ALL_TARGETS`
130 pub fn arp_all_targets(self, arp_all_targets: BondArpAllTargets) -> Self {
131 self.append_info_data(InfoBond::ArpAllTargets(arp_all_targets))
132 }
133
134 /// Adds the `primary` attribute to the bond, where `primary` is the ifindex
135 /// of an interface.
136 /// This is equivalent to `ip link add name NAME type bond primary
137 /// PRIMARY_NAME`
138 pub fn primary(self, primary: u32) -> Self {
139 self.append_info_data(InfoBond::Primary(primary))
140 }
141
142 /// Adds the `primary_reselect` attribute to the bond
143 /// This is equivalent to `ip link add name NAME type bond primary_reselect
144 /// PRIMARY_RESELECT`.
145 pub fn primary_reselect(
146 self,
147 primary_reselect: BondPrimaryReselect,
148 ) -> Self {
149 self.append_info_data(InfoBond::PrimaryReselect(primary_reselect))
150 }
151
152 /// Adds the `fail_over_mac` attribute to the bond
153 /// This is equivalent to `ip link add name NAME type bond fail_over_mac
154 /// FAIL_OVER_MAC`.
155 pub fn fail_over_mac(self, fail_over_mac: BondFailOverMac) -> Self {
156 self.append_info_data(InfoBond::FailOverMac(fail_over_mac))
157 }
158
159 /// Adds the `xmit_hash_policy` attribute to the bond
160 /// This is equivalent to `ip link add name NAME type bond xmit_hash_policy
161 /// XMIT_HASH_POLICY`.
162 pub fn xmit_hash_policy(
163 self,
164 xmit_hash_policy: BondXmitHashPolicy,
165 ) -> Self {
166 self.append_info_data(InfoBond::XmitHashPolicy(xmit_hash_policy))
167 }
168
169 /// Adds the `resend_igmp` attribute to the bond
170 /// This is equivalent to `ip link add name NAME type bond resend_igmp
171 /// RESEND_IGMP`.
172 pub fn resend_igmp(self, resend_igmp: u32) -> Self {
173 self.append_info_data(InfoBond::ResendIgmp(resend_igmp))
174 }
175
176 /// Adds the `num_peer_notif` attribute to the bond
177 /// This is equivalent to `ip link add name NAME type bond num_peer_notif
178 /// NUM_PEER_NOTIF`.
179 pub fn num_peer_notif(self, num_peer_notif: u8) -> Self {
180 self.append_info_data(InfoBond::NumPeerNotif(num_peer_notif))
181 }
182
183 /// Adds the `all_ports_active` attribute to the bond
184 /// This is equivalent to `ip link add name NAME type bond all_slaves_active
185 /// ALL_PORTS_ACTIVE`.
186 pub fn all_ports_active(self, all_ports_active: BondAllPortActive) -> Self {
187 self.append_info_data(InfoBond::AllPortsActive(all_ports_active))
188 }
189
190 /// Adds the `min_links` attribute to the bond
191 /// This is equivalent to `ip link add name NAME type bond min_links
192 /// MIN_LINKS`.
193 pub fn min_links(self, min_links: u32) -> Self {
194 self.append_info_data(InfoBond::MinLinks(min_links))
195 }
196
197 /// Adds the `lp_interval` attribute to the bond
198 /// This is equivalent to `ip link add name NAME type bond lp_interval
199 /// LP_INTERVAL`.
200 pub fn lp_interval(self, lp_interval: u32) -> Self {
201 self.append_info_data(InfoBond::LpInterval(lp_interval))
202 }
203
204 /// Adds the `packets_per_port` attribute to the bond
205 /// This is equivalent to `ip link add name NAME type bond packets_per_slave
206 /// PACKETS_PER_PORT`.
207 pub fn packets_per_port(self, packets_per_port: u32) -> Self {
208 self.append_info_data(InfoBond::PacketsPerPort(packets_per_port))
209 }
210
211 /// Adds the `ad_lacp_rate` attribute to the bond
212 /// This is equivalent to `ip link add name NAME type bond ad_lacp_rate
213 /// AD_LACP_RATE`.
214 pub fn ad_lacp_rate(self, ad_lacp_rate: BondLacpRate) -> Self {
215 self.append_info_data(InfoBond::AdLacpRate(ad_lacp_rate))
216 }
217
218 /// Adds the `ad_select` attribute to the bond
219 /// This is equivalent to `ip link add name NAME type bond ad_select
220 /// AD_SELECT`.
221 pub fn ad_select(self, ad_select: u8) -> Self {
222 self.append_info_data(InfoBond::AdSelect(ad_select))
223 }
224
225 /// Adds the `ad_actor_sys_prio` attribute to the bond
226 /// This is equivalent to `ip link add name NAME type bond ad_actor_sys_prio
227 /// AD_ACTOR_SYS_PRIO`.
228 pub fn ad_actor_sys_prio(self, ad_actor_sys_prio: u16) -> Self {
229 self.append_info_data(InfoBond::AdActorSysPrio(ad_actor_sys_prio))
230 }
231
232 /// Adds the `ad_user_port_key` attribute to the bond
233 /// This is equivalent to `ip link add name NAME type bond ad_user_port_key
234 /// AD_USER_PORT_KEY`.
235 pub fn ad_user_port_key(self, ad_user_port_key: u16) -> Self {
236 self.append_info_data(InfoBond::AdUserPortKey(ad_user_port_key))
237 }
238
239 /// Adds the `ad_actor_system` attribute to the bond
240 /// This is equivalent to `ip link add name NAME type bond ad_actor_system
241 /// AD_ACTOR_SYSTEM`.
242 pub fn ad_actor_system(self, ad_actor_system: [u8; 6]) -> Self {
243 self.append_info_data(InfoBond::AdActorSystem(ad_actor_system))
244 }
245
246 /// Adds the `tlb_dynamic_lb` attribute to the bond
247 /// This is equivalent to `ip link add name NAME type bond tlb_dynamic_lb
248 /// TLB_DYNAMIC_LB`.
249 pub fn tlb_dynamic_lb(self, tlb_dynamic_lb: bool) -> Self {
250 self.append_info_data(InfoBond::TlbDynamicLb(tlb_dynamic_lb))
251 }
252
253 /// Adds the `peer_notif_delay` attribute to the bond
254 /// This is equivalent to `ip link add name NAME type bond peer_notif_delay
255 /// PEER_NOTIF_DELAY`.
256 pub fn peer_notif_delay(self, peer_notif_delay: u32) -> Self {
257 self.append_info_data(InfoBond::PeerNotifDelay(peer_notif_delay))
258 }
259
260 /// Adds the `ad_lacp_active` attribute to the bond
261 /// This is equivalent to `ip link add name NAME type bond ad_lacp_active
262 /// AD_LACP_ACTIVE`.
263 pub fn ad_lacp_active(self, ad_lacp_active: bool) -> Self {
264 self.append_info_data(InfoBond::AdLacpActive(ad_lacp_active))
265 }
266
267 /// Adds the `missed_max` attribute to the bond
268 /// This is equivalent to `ip link add name NAME type bond missed_max
269 /// MISSED_MAX`.
270 pub fn missed_max(self, missed_max: u8) -> Self {
271 self.append_info_data(InfoBond::MissedMax(missed_max))
272 }
273
274 /// Adds the `arp_ip_target` attribute to the bond
275 /// This is equivalent to `ip link add name NAME type bond arp_ip_target
276 /// LIST`.
277 pub fn arp_ip_target(self, arp_ip_target: Vec<Ipv4Addr>) -> Self {
278 self.append_info_data(InfoBond::ArpIpTarget(arp_ip_target))
279 }
280
281 /// Adds the `ns_ip6_target` attribute to the bond
282 /// This is equivalent to `ip link add name NAME type bond ns_ip6_target
283 /// LIST`.
284 pub fn ns_ip6_target(self, ns_ip6_target: Vec<Ipv6Addr>) -> Self {
285 self.append_info_data(InfoBond::NsIp6Target(ns_ip6_target))
286 }
287}