rtnetlink/link/
bridge.rs

1// SPDX-License-Identifier: MIT
2
3use crate::{
4    link::LinkMessageBuilder,
5    packet_route::link::{
6        BridgeBooleanOptionFlags, BridgeBooleanOptions,
7        BridgeMulticastRouterType, BridgeStpState, InfoBridge, InfoData,
8        InfoKind, VlanProtocol,
9    },
10};
11
12/// Represent Linux Bridge interface.
13/// Example code on creating a linux bridge interface
14/// ```no_run
15/// use rtnetlink::{new_connection, LinkBridge};
16/// #[tokio::main]
17/// async fn main() -> Result<(), String> {
18///     let (connection, handle, _) = new_connection().unwrap();
19///     tokio::spawn(connection);
20///
21///     handle
22///         .link()
23///         .add(LinkBridge::new("br0").build())
24///         .execute()
25///         .await
26///         .map_err(|e| format!("{e}"))
27/// }
28/// ```
29///
30/// Please check LinkMessageBuilder::<LinkBridge> for more detail.
31#[derive(Debug)]
32pub struct LinkBridge;
33
34impl LinkBridge {
35    /// Equal to `LinkMessageBuilder::<LinkBridge>::new().up()`
36    pub fn new(name: &str) -> LinkMessageBuilder<Self> {
37        LinkMessageBuilder::<LinkBridge>::new(name).up()
38    }
39}
40
41impl LinkMessageBuilder<LinkBridge> {
42    /// Create [LinkMessageBuilder] for linux bridge
43    pub fn new(name: &str) -> Self {
44        LinkMessageBuilder::<LinkBridge>::new_with_info_kind(InfoKind::Bridge)
45            .name(name.to_string())
46    }
47
48    pub fn append_info_data(self, info: InfoBridge) -> Self {
49        let mut ret = self;
50        if let InfoData::Bridge(infos) = ret
51            .info_data
52            .get_or_insert_with(|| InfoData::Bridge(Vec::new()))
53        {
54            infos.push(info);
55        }
56        ret
57    }
58
59    pub fn set_boolean_opt(
60        self,
61        opt: BridgeBooleanOptionFlags,
62        value: bool,
63    ) -> Self {
64        let mut ret = self;
65        if let InfoData::Bridge(infos) = ret
66            .info_data
67            .get_or_insert_with(|| InfoData::Bridge(Vec::new()))
68        {
69            let mut found = false;
70            for info in infos.iter_mut() {
71                if let InfoBridge::MultiBoolOpt(opts) = info {
72                    found = true;
73                    opts.value.set(opt, value);
74                    opts.mask.set(opt, true);
75                    break;
76                }
77            }
78            if !found {
79                infos.push(InfoBridge::MultiBoolOpt(BridgeBooleanOptions {
80                    value: if value {
81                        opt
82                    } else {
83                        BridgeBooleanOptionFlags::empty()
84                    },
85                    mask: opt,
86                }));
87            }
88        }
89        ret
90    }
91
92    pub fn ageing_time(self, value: u32) -> Self {
93        self.append_info_data(InfoBridge::AgeingTime(value))
94    }
95
96    pub fn group_fwd_mask(self, value: u16) -> Self {
97        self.append_info_data(InfoBridge::GroupFwdMask(value))
98    }
99
100    pub fn group_address(self, value: [u8; 6]) -> Self {
101        self.append_info_data(InfoBridge::GroupAddr(value))
102    }
103
104    pub fn forward_delay(self, value: u32) -> Self {
105        self.append_info_data(InfoBridge::ForwardDelay(value))
106    }
107
108    pub fn hello_time(self, value: u32) -> Self {
109        self.append_info_data(InfoBridge::HelloTime(value))
110    }
111
112    pub fn max_age(self, value: u32) -> Self {
113        self.append_info_data(InfoBridge::MaxAge(value))
114    }
115
116    pub fn stp_state(self, value: BridgeStpState) -> Self {
117        self.append_info_data(InfoBridge::StpState(value))
118    }
119
120    pub fn mst_enabled(self, value: bool) -> Self {
121        self.set_boolean_opt(BridgeBooleanOptionFlags::MstEnable, value)
122    }
123
124    pub fn priority(self, value: u16) -> Self {
125        self.append_info_data(InfoBridge::Priority(value))
126    }
127
128    pub fn no_linklocal_learn(self, value: bool) -> Self {
129        self.set_boolean_opt(BridgeBooleanOptionFlags::NoLinkLocalLearn, value)
130    }
131
132    pub fn fdb_local_vlan_0(self, value: bool) -> Self {
133        self.set_boolean_opt(BridgeBooleanOptionFlags::FdbLocalVlan0, value)
134    }
135
136    pub fn fdb_max_learned(self, value: u32) -> Self {
137        self.append_info_data(InfoBridge::FdbMaxLearned(value))
138    }
139
140    pub fn vlan_filtering(self, value: bool) -> Self {
141        self.append_info_data(InfoBridge::VlanFiltering(value))
142    }
143
144    pub fn vlan_protocol(self, value: VlanProtocol) -> Self {
145        self.append_info_data(InfoBridge::VlanProtocol(value))
146    }
147
148    pub fn vlan_default_pvid(self, value: u16) -> Self {
149        self.append_info_data(InfoBridge::VlanDefaultPvid(value))
150    }
151
152    pub fn vlan_stats_enabled(self, value: bool) -> Self {
153        self.append_info_data(InfoBridge::VlanStatsEnabled(value))
154    }
155
156    pub fn vlan_stats_per_port(self, value: bool) -> Self {
157        self.append_info_data(InfoBridge::VlanStatsPerPort(value))
158    }
159
160    pub fn mcast_snooping(self, value: bool) -> Self {
161        self.append_info_data(InfoBridge::MulticastSnooping(value))
162    }
163
164    pub fn mcast_vlan_snooping(self, value: bool) -> Self {
165        self.set_boolean_opt(
166            BridgeBooleanOptionFlags::VlanMulticastSnooping,
167            value,
168        )
169    }
170
171    pub fn mcast_router(self, value: BridgeMulticastRouterType) -> Self {
172        self.append_info_data(InfoBridge::MulticastRouter(value))
173    }
174
175    pub fn mcast_query_use_ifaddr(self, value: bool) -> Self {
176        self.append_info_data(InfoBridge::MulticastQueryUseIfaddr(value))
177    }
178
179    pub fn mcast_querier(self, value: bool) -> Self {
180        self.append_info_data(InfoBridge::MulticastQuerier(value))
181    }
182
183    pub fn mcast_hash_max(self, value: u32) -> Self {
184        self.append_info_data(InfoBridge::MulticastHashMax(value))
185    }
186
187    pub fn mcast_last_member_count(self, value: u32) -> Self {
188        self.append_info_data(InfoBridge::MulticastLastMemberCount(value))
189    }
190
191    pub fn mcast_startup_query_count(self, value: u32) -> Self {
192        self.append_info_data(InfoBridge::MulticastStartupQueryCount(value))
193    }
194
195    pub fn mcast_last_member_interval(self, value: u64) -> Self {
196        self.append_info_data(InfoBridge::MulticastLastMemberInterval(value))
197    }
198
199    pub fn mcast_membership_interval(self, value: u64) -> Self {
200        self.append_info_data(InfoBridge::MulticastMembershipInterval(value))
201    }
202
203    pub fn mcast_querier_interval(self, value: u64) -> Self {
204        self.append_info_data(InfoBridge::MulticastQuerierInterval(value))
205    }
206
207    pub fn mcast_query_interval(self, value: u64) -> Self {
208        self.append_info_data(InfoBridge::MulticastQueryInterval(value))
209    }
210
211    pub fn mcast_query_response_interval(self, value: u64) -> Self {
212        self.append_info_data(InfoBridge::MulticastQueryResponseInterval(value))
213    }
214
215    pub fn mcast_startup_query_interval(self, value: u64) -> Self {
216        self.append_info_data(InfoBridge::MulticastStartupQueryInterval(value))
217    }
218
219    pub fn mcast_stats_enabled(self, value: bool) -> Self {
220        self.append_info_data(InfoBridge::MulticastStatsEnabled(value))
221    }
222
223    pub fn mcast_igmp_version(self, value: u8) -> Self {
224        self.append_info_data(InfoBridge::MulticastIgmpVersion(value))
225    }
226
227    pub fn mcast_mld_version(self, value: u8) -> Self {
228        self.append_info_data(InfoBridge::MulticastMldVersion(value))
229    }
230
231    pub fn nf_call_iptables(self, value: bool) -> Self {
232        self.append_info_data(InfoBridge::NfCallIpTables(value))
233    }
234
235    pub fn nf_call_ip6tables(self, value: bool) -> Self {
236        self.append_info_data(InfoBridge::NfCallIp6Tables(value))
237    }
238
239    pub fn nf_call_arptables(self, value: bool) -> Self {
240        self.append_info_data(InfoBridge::NfCallArpTables(value))
241    }
242
243    pub fn mdb_offload_fail_notification(self, value: bool) -> Self {
244        self.set_boolean_opt(
245            BridgeBooleanOptionFlags::MdbOffloadFailNotif,
246            value,
247        )
248    }
249}