diff --git a/src/link/link_info/ipvlan.rs b/src/link/link_info/ipvlan.rs index a08cc2f2..af30afe1 100644 --- a/src/link/link_info/ipvlan.rs +++ b/src/link/link_info/ipvlan.rs @@ -16,7 +16,7 @@ const IFLA_IPVLAN_FLAGS: u16 = 2; #[non_exhaustive] pub enum InfoIpVlan { Mode(IpVlanMode), - Flags(u16), + Flags(IpVlanFlag), Other(DefaultNla), } @@ -33,7 +33,7 @@ impl Nla for InfoIpVlan { use self::InfoIpVlan::*; match self { Mode(value) => NativeEndian::write_u16(buffer, (*value).into()), - Flags(value) => NativeEndian::write_u16(buffer, *value), + Flags(f) => NativeEndian::write_u16(buffer, f.bits()), Other(nla) => nla.emit_value(buffer), } } @@ -58,10 +58,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoIpVlan { .context("invalid IFLA_IPVLAN_MODE value")? .into(), ), - IFLA_IPVLAN_FLAGS => Flags( - parse_u16(payload) - .context("invalid IFLA_IPVLAN_FLAGS value")?, - ), + IFLA_IPVLAN_FLAGS => Self::Flags(IpVlanFlag::from_bits_retain( + parse_u16(payload).context("failed to parse IPVLAN_FLAG")?, + )), kind => Other(DefaultNla::parse(buf).context(format!( "unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)" ))?), @@ -73,7 +72,7 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoIpVlan { #[non_exhaustive] pub enum InfoIpVtap { Mode(IpVtapMode), - Flags(u16), + Flags(IpVtapFlag), Other(DefaultNla), } @@ -90,7 +89,7 @@ impl Nla for InfoIpVtap { use self::InfoIpVtap::*; match self { Mode(value) => NativeEndian::write_u16(buffer, (*value).into()), - Flags(value) => NativeEndian::write_u16(buffer, *value), + Flags(f) => NativeEndian::write_u16(buffer, f.bits()), Other(nla) => nla.emit_value(buffer), } } @@ -115,10 +114,9 @@ impl<'a, T: AsRef<[u8]> + ?Sized> Parseable> for InfoIpVtap { .context("invalid IFLA_IPVLAN_MODE value")? .into(), ), - IFLA_IPVLAN_FLAGS => Flags( - parse_u16(payload) - .context("invalid IFLA_IPVLAN_FLAGS value")?, - ), + IFLA_IPVLAN_FLAGS => Self::Flags(IpVtapFlag::from_bits_retain( + parse_u16(payload).context("failed to parse IPVTAP_FLAG")?, + )), kind => Other(DefaultNla::parse(buf).context(format!( "unknown NLA type {kind} for IFLA_INFO_DATA(ipvlan)" ))?), @@ -165,3 +163,24 @@ impl From for u16 { } } } + +const IPVLAN_F_PRIVATE: u16 = 0x01; +const IPVLAN_F_VEPA: u16 = 0x02; + +bitflags! { + #[non_exhaustive] + #[derive(Debug, Clone, Copy, Eq, PartialEq)] + pub struct IpVlanFlag: u16 { + const PRIVATE = IPVLAN_F_PRIVATE as u16; + const VEPA = IPVLAN_F_VEPA as u16; + const _ = !0; + } +} + +impl Default for IpVlanFlag { + fn default() -> Self { + Self::empty() + } +} + +pub type IpVtapFlag = IpVlanFlag; diff --git a/src/link/link_info/mod.rs b/src/link/link_info/mod.rs index 628b4fbf..0d4c9029 100644 --- a/src/link/link_info/mod.rs +++ b/src/link/link_info/mod.rs @@ -45,7 +45,9 @@ pub use self::info_data::InfoData; pub use self::info_port::{InfoPortData, InfoPortKind, InfoVrfPort}; pub use self::infos::{InfoKind, LinkInfo}; pub use self::ipoib::InfoIpoib; -pub use self::ipvlan::{InfoIpVlan, InfoIpVtap, IpVlanMode, IpVtapMode}; +pub use self::ipvlan::{ + InfoIpVlan, InfoIpVtap, IpVlanFlag, IpVlanMode, IpVtapFlag, IpVtapMode, +}; pub use self::mac_vlan::{InfoMacVlan, InfoMacVtap, MacVlanMode, MacVtapMode}; pub use self::macsec::{ InfoMacSec, MacSecCipherId, MacSecOffload, MacSecValidate, diff --git a/src/link/mod.rs b/src/link/mod.rs index eb27982e..bb00d4a3 100644 --- a/src/link/mod.rs +++ b/src/link/mod.rs @@ -44,9 +44,10 @@ pub use self::link_info::{ InfoGreTap, InfoGreTap6, InfoGreTun, InfoGreTun6, InfoGtp, InfoHsr, InfoIpVlan, InfoIpVtap, InfoIpoib, InfoKind, InfoMacSec, InfoMacVlan, InfoMacVtap, InfoPortData, InfoPortKind, InfoSitTun, InfoTun, InfoVeth, - InfoVlan, InfoVrf, InfoVrfPort, InfoVti, InfoVxlan, InfoXfrm, IpVlanMode, - IpVtapMode, LinkInfo, LinkXstats, MacSecCipherId, MacSecOffload, - MacSecValidate, MacVlanMode, MacVtapMode, MiiStatus, VlanQosMapping, + InfoVlan, InfoVrf, InfoVrfPort, InfoVti, InfoVxlan, InfoXfrm, IpVlanFlag, + IpVlanMode, IpVtapFlag, IpVtapMode, LinkInfo, LinkXstats, MacSecCipherId, + MacSecOffload, MacSecValidate, MacVlanMode, MacVtapMode, MiiStatus, + VlanQosMapping, }; pub use self::link_layer_type::LinkLayerType; pub use self::link_state::State; diff --git a/src/link/tests/ipvlan.rs b/src/link/tests/ipvlan.rs index b3eaa7fe..942211a6 100644 --- a/src/link/tests/ipvlan.rs +++ b/src/link/tests/ipvlan.rs @@ -4,8 +4,8 @@ use netlink_packet_utils::{Emitable, Parseable}; use crate::link::link_flag::LinkFlags; use crate::link::{ - InfoData, InfoIpVlan, InfoKind, IpVlanMode, LinkAttribute, LinkHeader, - LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer, + InfoData, InfoIpVlan, InfoKind, IpVlanFlag, IpVlanMode, LinkAttribute, + LinkHeader, LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer, }; use crate::AddressFamily; @@ -16,7 +16,7 @@ fn test_ipvlan_link_info() { 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x69, 0x70, 0x76, 0x6c, 0x61, 0x6e, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, - 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, ]; let expected = LinkMessage { @@ -31,7 +31,7 @@ fn test_ipvlan_link_info() { LinkInfo::Kind(InfoKind::IpVlan), LinkInfo::Data(InfoData::IpVlan(vec![ InfoIpVlan::Mode(IpVlanMode::L2), - InfoIpVlan::Flags(2), + InfoIpVlan::Flags(IpVlanFlag::default()), ])), ])], }; diff --git a/src/link/tests/ipvtap.rs b/src/link/tests/ipvtap.rs index 9839c0d1..9cf2ee2e 100644 --- a/src/link/tests/ipvtap.rs +++ b/src/link/tests/ipvtap.rs @@ -4,8 +4,8 @@ use netlink_packet_utils::{Emitable, Parseable}; use crate::link::link_flag::LinkFlags; use crate::link::{ - InfoData, InfoIpVtap, InfoKind, IpVtapMode, LinkAttribute, LinkHeader, - LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer, + InfoData, InfoIpVtap, InfoKind, IpVtapFlag, IpVtapMode, LinkAttribute, + LinkHeader, LinkInfo, LinkLayerType, LinkMessage, LinkMessageBuffer, }; use crate::AddressFamily; @@ -16,7 +16,7 @@ fn test_ipvtap_link_info() { 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x69, 0x70, 0x76, 0x74, 0x61, 0x70, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, - 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, ]; let expected = LinkMessage { @@ -31,7 +31,7 @@ fn test_ipvtap_link_info() { LinkInfo::Kind(InfoKind::IpVtap), LinkInfo::Data(InfoData::IpVtap(vec![ InfoIpVtap::Mode(IpVtapMode::L2), - InfoIpVtap::Flags(2), + InfoIpVtap::Flags(IpVtapFlag::PRIVATE), ])), ])], };