diff --git a/src/link/link_info/bond.rs b/src/link/link_info/bond.rs index 9f38f95a..a7eab146 100644 --- a/src/link/link_info/bond.rs +++ b/src/link/link_info/bond.rs @@ -71,6 +71,12 @@ const BOND_ARP_VALIDATE_ALL: u32 = const BOND_ARP_FILTER: u32 = BOND_ARP_VALIDATE_ALL + 1; const BOND_ARP_FILTER_ACTIVE: u32 = BOND_ARP_FILTER | BOND_ARP_VALIDATE_ACTIVE; const BOND_ARP_FILTER_BACKUP: u32 = BOND_ARP_FILTER | BOND_ARP_VALIDATE_BACKUP; +const BOND_XMIT_POLICY_LAYER2: u8 = 0; +const BOND_XMIT_POLICY_LAYER34: u8 = 1; +const BOND_XMIT_POLICY_LAYER23: u8 = 2; +const BOND_XMIT_POLICY_ENCAP23: u8 = 3; +const BOND_XMIT_POLICY_ENCAP34: u8 = 4; +const BOND_XMIT_POLICY_VLAN_SRCMAC: u8 = 5; const BOND_OPT_ARP_ALL_TARGETS_ANY: u32 = 0; const BOND_OPT_ARP_ALL_TARGETS_ALL: u32 = 1; @@ -274,6 +280,63 @@ impl std::fmt::Display for BondArpValidate { } } +#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] +pub enum BondXmitHashPolicy { + #[default] + Layer2, + Layer34, + Layer23, + Encap23, + Encap34, + VlanSrcMac, + Other(u8), +} + +impl From for u8 { + fn from(value: BondXmitHashPolicy) -> Self { + match value { + BondXmitHashPolicy::Layer2 => BOND_XMIT_POLICY_LAYER2, + BondXmitHashPolicy::Layer34 => BOND_XMIT_POLICY_LAYER34, + BondXmitHashPolicy::Layer23 => BOND_XMIT_POLICY_LAYER23, + BondXmitHashPolicy::Encap23 => BOND_XMIT_POLICY_ENCAP23, + BondXmitHashPolicy::Encap34 => BOND_XMIT_POLICY_ENCAP34, + BondXmitHashPolicy::VlanSrcMac => BOND_XMIT_POLICY_VLAN_SRCMAC, + BondXmitHashPolicy::Other(d) => d, + } + } +} + +impl From for BondXmitHashPolicy { + fn from(value: u8) -> Self { + match value { + BOND_XMIT_POLICY_LAYER2 => BondXmitHashPolicy::Layer2, + BOND_XMIT_POLICY_LAYER34 => BondXmitHashPolicy::Layer34, + BOND_XMIT_POLICY_LAYER23 => BondXmitHashPolicy::Layer23, + BOND_XMIT_POLICY_ENCAP23 => BondXmitHashPolicy::Encap23, + BOND_XMIT_POLICY_ENCAP34 => BondXmitHashPolicy::Encap34, + BOND_XMIT_POLICY_VLAN_SRCMAC => BondXmitHashPolicy::VlanSrcMac, + d => BondXmitHashPolicy::Other(d), + } + } +} + +impl std::fmt::Display for BondXmitHashPolicy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let kernel_name = match self { + BondXmitHashPolicy::Layer2 => "layer2", + BondXmitHashPolicy::Layer34 => "layer34", + BondXmitHashPolicy::Layer23 => "layer23", + BondXmitHashPolicy::Encap23 => "encap23", + BondXmitHashPolicy::Encap34 => "encap34", + BondXmitHashPolicy::VlanSrcMac => "vlan-src-mac", + BondXmitHashPolicy::Other(d) => { + return write!(f, "unknown-variant ({d})") + } + }; + f.write_str(kernel_name) + } +} + #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] pub enum BondArpAllTargets { #[default] @@ -397,7 +460,7 @@ pub enum InfoBond { Primary(u32), PrimaryReselect(u8), FailOverMac(u8), - XmitHashPolicy(u8), + XmitHashPolicy(BondXmitHashPolicy), ResendIgmp(u32), NumPeerNotif(u8), AllPortsActive(u8), @@ -462,10 +525,10 @@ impl Nla for InfoBond { fn emit_value(&self, buffer: &mut [u8]) { match self { Self::Mode(value) => buffer[0] = (*value).into(), + Self::XmitHashPolicy(value) => buffer[0] = (*value).into(), Self::UseCarrier(value) | Self::PrimaryReselect(value) | Self::FailOverMac(value) - | Self::XmitHashPolicy(value) | Self::NumPeerNotif(value) | Self::AllPortsActive(value) | Self::AdLacpActive(value) @@ -612,7 +675,8 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoBond { ), IFLA_BOND_XMIT_HASH_POLICY => Self::XmitHashPolicy( parse_u8(payload) - .context("invalid IFLA_BOND_XMIT_HASH_POLICY value")?, + .context("invalid IFLA_BOND_XMIT_HASH_POLICY value")? + .into(), ), IFLA_BOND_RESEND_IGMP => Self::ResendIgmp( parse_u32(payload) diff --git a/src/link/link_info/mod.rs b/src/link/link_info/mod.rs index 459915f1..24f262a5 100644 --- a/src/link/link_info/mod.rs +++ b/src/link/link_info/mod.rs @@ -29,7 +29,8 @@ mod xfrm; mod xstats; pub use self::bond::{ - BondAdInfo, BondArpAllTargets, BondArpValidate, BondMode, InfoBond, + BondAdInfo, BondArpAllTargets, BondArpValidate, BondMode, + BondXmitHashPolicy, InfoBond, }; pub use self::bond_port::{BondPortState, InfoBondPort, MiiStatus}; pub use self::bridge::{ diff --git a/src/link/mod.rs b/src/link/mod.rs index 32f4a6a7..c3b4922c 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -40,14 +40,14 @@ pub use self::header::{LinkHeader, LinkMessageBuffer}; pub use self::link_flag::LinkFlags; pub use self::link_info::{ BondAdInfo, BondArpAllTargets, BondArpValidate, BondMode, BondPortState, - BridgeId, BridgeIdBuffer, BridgePortMulticastRouter, BridgePortState, - BridgeQuerierState, GeneveDf, HsrProtocol, InfoBond, InfoBondPort, - InfoBridge, InfoBridgePort, InfoData, InfoGeneve, InfoGreTap, InfoGreTap6, - InfoGreTun, InfoGreTun6, InfoGtp, InfoHsr, InfoIpVlan, InfoIpVtap, - InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan, InfoMacVtap, InfoPortData, - InfoPortKind, InfoSitTun, InfoTun, InfoVeth, InfoVlan, InfoVrf, - InfoVrfPort, InfoVti, InfoVxlan, InfoXfrm, IpVlanFlags, IpVlanMode, - IpVtapFlags, IpVtapMode, LinkInfo, LinkXstats, MacSecCipherId, + BondXmitHashPolicy, BridgeId, BridgeIdBuffer, BridgePortMulticastRouter, + BridgePortState, BridgeQuerierState, GeneveDf, HsrProtocol, InfoBond, + InfoBondPort, InfoBridge, InfoBridgePort, InfoData, InfoGeneve, InfoGreTap, + InfoGreTap6, InfoGreTun, InfoGreTun6, InfoGtp, InfoHsr, InfoIpVlan, + InfoIpVtap, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan, InfoMacVtap, + InfoPortData, InfoPortKind, InfoSitTun, InfoTun, InfoVeth, InfoVlan, + InfoVrf, InfoVrfPort, InfoVti, InfoVxlan, InfoXfrm, IpVlanFlags, + IpVlanMode, IpVtapFlags, IpVtapMode, LinkInfo, LinkXstats, MacSecCipherId, MacSecOffload, MacSecValidate, MacVlanMode, MacVtapMode, MiiStatus, VlanQosMapping, }; diff --git a/src/link/tests/bond.rs b/src/link/tests/bond.rs index d8e540cd..d4dbdd79 100644 --- a/src/link/tests/bond.rs +++ b/src/link/tests/bond.rs @@ -4,10 +4,10 @@ use netlink_packet_utils::{Emitable, Parseable}; use crate::link::link_flag::LinkFlags; use crate::link::{ - BondArpAllTargets, BondArpValidate, BondMode, BondPortState, InfoBond, - InfoBondPort, InfoData, InfoKind, InfoPortData, InfoPortKind, - LinkAttribute, LinkHeader, LinkInfo, LinkLayerType, LinkMessage, - LinkMessageBuffer, Map, MiiStatus, State, + BondArpAllTargets, BondArpValidate, BondMode, BondPortState, + BondXmitHashPolicy, InfoBond, InfoBondPort, InfoData, InfoKind, + InfoPortData, InfoPortKind, LinkAttribute, LinkHeader, LinkInfo, + LinkLayerType, LinkMessage, LinkMessageBuffer, Map, MiiStatus, State, }; use crate::{AddressFamily, RouteNetlinkMessage}; @@ -68,7 +68,7 @@ fn test_bond_link_info() { InfoBond::ArpAllTargets(BondArpAllTargets::Any), InfoBond::PrimaryReselect(0), InfoBond::FailOverMac(0), - InfoBond::XmitHashPolicy(0), + InfoBond::XmitHashPolicy(BondXmitHashPolicy::Layer2), InfoBond::ResendIgmp(1), InfoBond::NumPeerNotif(1), InfoBond::AllPortsActive(0),