Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ futures-channel = "0.3.11"
log = "0.4.8"
thiserror = "1"
netlink-sys = { version = "0.8" }
netlink-packet-route = { version = "0.26" }
netlink-packet-route = { version = "0.27" }
netlink-packet-core = { version = "0.8" }
netlink-proto = { default-features = false, version = "0.12.0" }
nix = { version = "0.30.0", default-features = false, features = ["fs", "mount", "sched", "signal"] }
Expand Down
15 changes: 8 additions & 7 deletions src/link/bond.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ use std::net::{Ipv4Addr, Ipv6Addr};
use crate::{
link::LinkMessageBuilder,
packet_route::link::{
BondArpAllTargets, BondArpValidate, BondFailOverMac, BondMode,
BondPrimaryReselect, BondXmitHashPolicy, InfoBond, InfoData, InfoKind,
BondAllPortActive, BondArpAllTargets, BondArpValidate, BondFailOverMac,
BondLacpRate, BondMode, BondPrimaryReselect, BondXmitHashPolicy,
InfoBond, InfoData, InfoKind,
},
};

Expand Down Expand Up @@ -105,7 +106,7 @@ impl LinkMessageBuilder<LinkBond> {
/// 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: u8) -> Self {
pub fn use_carrier(self, use_carrier: bool) -> Self {
self.append_info_data(InfoBond::UseCarrier(use_carrier))
}

Expand Down Expand Up @@ -182,7 +183,7 @@ impl LinkMessageBuilder<LinkBond> {
/// 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: u8) -> Self {
pub fn all_ports_active(self, all_ports_active: BondAllPortActive) -> Self {
self.append_info_data(InfoBond::AllPortsActive(all_ports_active))
}

Expand Down Expand Up @@ -210,7 +211,7 @@ impl LinkMessageBuilder<LinkBond> {
/// 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: u8) -> Self {
pub fn ad_lacp_rate(self, ad_lacp_rate: BondLacpRate) -> Self {
self.append_info_data(InfoBond::AdLacpRate(ad_lacp_rate))
}

Expand Down Expand Up @@ -245,7 +246,7 @@ impl LinkMessageBuilder<LinkBond> {
/// 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: u8) -> Self {
pub fn tlb_dynamic_lb(self, tlb_dynamic_lb: bool) -> Self {
self.append_info_data(InfoBond::TlbDynamicLb(tlb_dynamic_lb))
}

Expand All @@ -259,7 +260,7 @@ impl LinkMessageBuilder<LinkBond> {
/// 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: u8) -> Self {
pub fn ad_lacp_active(self, ad_lacp_active: bool) -> Self {
self.append_info_data(InfoBond::AdLacpActive(ad_lacp_active))
}

Expand Down
211 changes: 210 additions & 1 deletion src/link/bridge.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// SPDX-License-Identifier: MIT

use crate::{link::LinkMessageBuilder, packet_route::link::InfoKind};
use crate::{
link::LinkMessageBuilder,
packet_route::link::{
BridgeBooleanOptionFlags, BridgeBooleanOptions,
BridgeMulticastRouterType, BridgeStpState, InfoBridge, InfoData,
InfoKind, VlanProtocol,
},
};

/// Represent dummy interface.
/// Example code on creating a linux bridge interface
Expand Down Expand Up @@ -37,4 +44,206 @@ impl LinkMessageBuilder<LinkBridge> {
LinkMessageBuilder::<LinkBridge>::new_with_info_kind(InfoKind::Bridge)
.name(name.to_string())
}

pub fn append_info_data(self, info: InfoBridge) -> Self {
let mut ret = self;
if let InfoData::Bridge(infos) = ret
.info_data
.get_or_insert_with(|| InfoData::Bridge(Vec::new()))
{
infos.push(info);
}
ret
}

pub fn set_boolean_opt(
self,
opt: BridgeBooleanOptionFlags,
value: bool,
) -> Self {
let mut ret = self;
if let InfoData::Bridge(infos) = ret
.info_data
.get_or_insert_with(|| InfoData::Bridge(Vec::new()))
{
let mut found = false;
for info in infos.iter_mut() {
if let InfoBridge::MultiBoolOpt(opts) = info {
found = true;
opts.value.set(opt, value);
opts.mask.set(opt, true);
break;
}
}
if !found {
infos.push(InfoBridge::MultiBoolOpt(BridgeBooleanOptions {
value: if value {
opt
} else {
BridgeBooleanOptionFlags::empty()
},
mask: opt,
}));
}
}
ret
}

pub fn ageing_time(self, value: u32) -> Self {
self.append_info_data(InfoBridge::AgeingTime(value))
}

pub fn group_fwd_mask(self, value: u16) -> Self {
self.append_info_data(InfoBridge::GroupFwdMask(value))
}

pub fn group_address(self, value: [u8; 6]) -> Self {
self.append_info_data(InfoBridge::GroupAddr(value))
}

pub fn forward_delay(self, value: u32) -> Self {
self.append_info_data(InfoBridge::ForwardDelay(value))
}

pub fn hello_time(self, value: u32) -> Self {
self.append_info_data(InfoBridge::HelloTime(value))
}

pub fn max_age(self, value: u32) -> Self {
self.append_info_data(InfoBridge::MaxAge(value))
}

pub fn stp_state(self, value: BridgeStpState) -> Self {
self.append_info_data(InfoBridge::StpState(value))
}

pub fn mst_enabled(self, value: bool) -> Self {
self.set_boolean_opt(BridgeBooleanOptionFlags::MstEnable, value)
}

pub fn priority(self, value: u16) -> Self {
self.append_info_data(InfoBridge::Priority(value))
}

pub fn no_linklocal_learn(self, value: bool) -> Self {
self.set_boolean_opt(BridgeBooleanOptionFlags::NoLinkLocalLearn, value)
}

pub fn fdb_local_vlan_0(self, value: bool) -> Self {
self.set_boolean_opt(BridgeBooleanOptionFlags::FdbLocalVlan0, value)
}

pub fn fdb_max_learned(self, value: u32) -> Self {
self.append_info_data(InfoBridge::FdbMaxLearned(value))
}

pub fn vlan_filtering(self, value: bool) -> Self {
self.append_info_data(InfoBridge::VlanFiltering(value))
}

pub fn vlan_protocol(self, value: VlanProtocol) -> Self {
self.append_info_data(InfoBridge::VlanProtocol(value))
}

pub fn vlan_default_pvid(self, value: u16) -> Self {
self.append_info_data(InfoBridge::VlanDefaultPvid(value))
}

pub fn vlan_stats_enabled(self, value: bool) -> Self {
self.append_info_data(InfoBridge::VlanStatsEnabled(value))
}

pub fn vlan_stats_per_port(self, value: bool) -> Self {
self.append_info_data(InfoBridge::VlanStatsPerPort(value))
}

pub fn mcast_snooping(self, value: bool) -> Self {
self.append_info_data(InfoBridge::MulticastSnooping(value))
}

pub fn mcast_vlan_snooping(self, value: bool) -> Self {
self.set_boolean_opt(
BridgeBooleanOptionFlags::VlanMulticastSnooping,
value,
)
}

pub fn mcast_router(self, value: BridgeMulticastRouterType) -> Self {
self.append_info_data(InfoBridge::MulticastRouter(value))
}

pub fn mcast_query_use_ifaddr(self, value: bool) -> Self {
self.append_info_data(InfoBridge::MulticastQueryUseIfaddr(value))
}

pub fn mcast_querier(self, value: bool) -> Self {
self.append_info_data(InfoBridge::MulticastQuerier(value))
}

pub fn mcast_hash_max(self, value: u32) -> Self {
self.append_info_data(InfoBridge::MulticastHashMax(value))
}

pub fn mcast_last_member_count(self, value: u32) -> Self {
self.append_info_data(InfoBridge::MulticastLastMemberCount(value))
}

pub fn mcast_startup_query_count(self, value: u32) -> Self {
self.append_info_data(InfoBridge::MulticastStartupQueryCount(value))
}

pub fn mcast_last_member_interval(self, value: u64) -> Self {
self.append_info_data(InfoBridge::MulticastLastMemberInterval(value))
}

pub fn mcast_membership_interval(self, value: u64) -> Self {
self.append_info_data(InfoBridge::MulticastMembershipInterval(value))
}

pub fn mcast_querier_interval(self, value: u64) -> Self {
self.append_info_data(InfoBridge::MulticastQuerierInterval(value))
}

pub fn mcast_query_interval(self, value: u64) -> Self {
self.append_info_data(InfoBridge::MulticastQueryInterval(value))
}

pub fn mcast_query_response_interval(self, value: u64) -> Self {
self.append_info_data(InfoBridge::MulticastQueryResponseInterval(value))
}

pub fn mcast_startup_query_interval(self, value: u64) -> Self {
self.append_info_data(InfoBridge::MulticastStartupQueryInterval(value))
}

pub fn mcast_stats_enabled(self, value: bool) -> Self {
self.append_info_data(InfoBridge::MulticastStatsEnabled(value))
}

pub fn mcast_igmp_version(self, value: u8) -> Self {
self.append_info_data(InfoBridge::MulticastIgmpVersion(value))
}

pub fn mcast_mld_version(self, value: u8) -> Self {
self.append_info_data(InfoBridge::MulticastMldVersion(value))
}

pub fn nf_call_iptables(self, value: bool) -> Self {
self.append_info_data(InfoBridge::NfCallIpTables(value))
}

pub fn nf_call_ip6tables(self, value: bool) -> Self {
self.append_info_data(InfoBridge::NfCallIp6Tables(value))
}

pub fn nf_call_arptables(self, value: bool) -> Self {
self.append_info_data(InfoBridge::NfCallArpTables(value))
}

pub fn mdb_offload_fail_notification(self, value: bool) -> Self {
self.set_boolean_opt(
BridgeBooleanOptionFlags::MdbOffloadFailNotif,
value,
)
}
}