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}