use crate::link::{BridgeId, BridgeIdBuffer};
use anyhow::Context;
use byteorder::{ByteOrder, NativeEndian};
use netlink_packet_utils::{
nla::{DefaultNla, Nla, NlaBuffer},
parsers::{parse_u16, parse_u32, parse_u64, parse_u8},
traits::{Emitable, Parseable},
DecodeError,
};
const IFLA_BRPORT_STATE: u16 = 1;
const IFLA_BRPORT_PRIORITY: u16 = 2;
const IFLA_BRPORT_COST: u16 = 3;
const IFLA_BRPORT_MODE: u16 = 4;
const IFLA_BRPORT_GUARD: u16 = 5;
const IFLA_BRPORT_PROTECT: u16 = 6;
const IFLA_BRPORT_FAST_LEAVE: u16 = 7;
const IFLA_BRPORT_LEARNING: u16 = 8;
const IFLA_BRPORT_UNICAST_FLOOD: u16 = 9;
const IFLA_BRPORT_PROXYARP: u16 = 10;
const IFLA_BRPORT_PROXYARP_WIFI: u16 = 12;
const IFLA_BRPORT_ROOT_ID: u16 = 13;
const IFLA_BRPORT_BRIDGE_ID: u16 = 14;
const IFLA_BRPORT_DESIGNATED_PORT: u16 = 15;
const IFLA_BRPORT_DESIGNATED_COST: u16 = 16;
const IFLA_BRPORT_ID: u16 = 17;
const IFLA_BRPORT_NO: u16 = 18;
const IFLA_BRPORT_TOPOLOGY_CHANGE_ACK: u16 = 19;
const IFLA_BRPORT_CONFIG_PENDING: u16 = 20;
const IFLA_BRPORT_MESSAGE_AGE_TIMER: u16 = 21;
const IFLA_BRPORT_FORWARD_DELAY_TIMER: u16 = 22;
const IFLA_BRPORT_HOLD_TIMER: u16 = 23;
const IFLA_BRPORT_FLUSH: u16 = 24;
const IFLA_BRPORT_MULTICAST_ROUTER: u16 = 25;
const IFLA_BRPORT_MCAST_FLOOD: u16 = 27;
const IFLA_BRPORT_MCAST_TO_UCAST: u16 = 28;
const IFLA_BRPORT_VLAN_TUNNEL: u16 = 29;
const IFLA_BRPORT_BCAST_FLOOD: u16 = 30;
const IFLA_BRPORT_GROUP_FWD_MASK: u16 = 31;
const IFLA_BRPORT_NEIGH_SUPPRESS: u16 = 32;
const IFLA_BRPORT_ISOLATED: u16 = 33;
const IFLA_BRPORT_BACKUP_PORT: u16 = 34;
const IFLA_BRPORT_MRP_RING_OPEN: u16 = 35;
const IFLA_BRPORT_MRP_IN_OPEN: u16 = 36;
const IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT: u16 = 37;
const IFLA_BRPORT_MCAST_EHT_HOSTS_CNT: u16 = 38;
const IFLA_BRPORT_LOCKED: u16 = 39;
const IFLA_BRPORT_MAB: u16 = 40;
const IFLA_BRPORT_MCAST_N_GROUPS: u16 = 41;
const IFLA_BRPORT_MCAST_MAX_GROUPS: u16 = 42;
const IFLA_BRPORT_NEIGH_VLAN_SUPPRESS: u16 = 43;
const IFLA_BRPORT_BACKUP_NHID: u16 = 44;
#[derive(Debug, PartialEq, Eq, Clone)]
#[non_exhaustive]
pub enum InfoBridgePort {
State(BridgePortState),
Priority(u16),
Cost(u32),
HairpinMode(bool),
Guard(bool),
Protect(bool),
FastLeave(bool),
Learning(bool),
UnicastFlood(bool),
ProxyARP(bool),
ProxyARPWifi(bool),
RootId(BridgeId),
BridgeId(BridgeId),
DesignatedPort(u16),
DesignatedCost(u16),
PortId(u16),
PortNumber(u16),
TopologyChangeAck(bool),
ConfigPending(bool),
MessageAgeTimer(u64),
ForwardDelayTimer(u64),
HoldTimer(u64),
Flush,
MulticastRouter(BridgePortMulticastRouter),
MulticastFlood(bool),
MulticastToUnicast(bool),
VlanTunnel(bool),
BroadcastFlood(bool),
GroupFwdMask(u16),
NeighSupress(bool),
Isolated(bool),
BackupPort(u32),
MrpRingOpen(bool),
MrpInOpen(bool),
MulticastEhtHostsLimit(u32),
MulticastEhtHostsCnt(u32),
Locked(bool),
Mab(bool),
MulticastNGroups(u32),
MulticastMaxGroups(u32),
NeighVlanSupress(bool),
BackupNextHopId(u32),
Other(DefaultNla),
}
impl Nla for InfoBridgePort {
fn value_len(&self) -> usize {
match self {
InfoBridgePort::Flush => 0,
InfoBridgePort::State(_)
| InfoBridgePort::HairpinMode(_)
| InfoBridgePort::Guard(_)
| InfoBridgePort::Protect(_)
| InfoBridgePort::FastLeave(_)
| InfoBridgePort::Learning(_)
| InfoBridgePort::UnicastFlood(_)
| InfoBridgePort::ProxyARP(_)
| InfoBridgePort::ProxyARPWifi(_)
| InfoBridgePort::TopologyChangeAck(_)
| InfoBridgePort::ConfigPending(_)
| InfoBridgePort::MulticastRouter(_)
| InfoBridgePort::MulticastFlood(_)
| InfoBridgePort::MulticastToUnicast(_)
| InfoBridgePort::VlanTunnel(_)
| InfoBridgePort::BroadcastFlood(_)
| InfoBridgePort::NeighSupress(_)
| InfoBridgePort::Isolated(_)
| InfoBridgePort::MrpRingOpen(_)
| InfoBridgePort::MrpInOpen(_)
| InfoBridgePort::Locked(_)
| InfoBridgePort::Mab(_)
| InfoBridgePort::NeighVlanSupress(_) => 1,
InfoBridgePort::Priority(_)
| InfoBridgePort::DesignatedPort(_)
| InfoBridgePort::DesignatedCost(_)
| InfoBridgePort::PortId(_)
| InfoBridgePort::PortNumber(_)
| InfoBridgePort::GroupFwdMask(_) => 2,
InfoBridgePort::Cost(_)
| InfoBridgePort::BackupPort(_)
| InfoBridgePort::MulticastEhtHostsLimit(_)
| InfoBridgePort::MulticastEhtHostsCnt(_)
| InfoBridgePort::MulticastNGroups(_)
| InfoBridgePort::MulticastMaxGroups(_)
| InfoBridgePort::BackupNextHopId(_) => 4,
InfoBridgePort::RootId(_)
| InfoBridgePort::BridgeId(_)
| InfoBridgePort::MessageAgeTimer(_)
| InfoBridgePort::ForwardDelayTimer(_)
| InfoBridgePort::HoldTimer(_) => 8,
InfoBridgePort::Other(nla) => nla.value_len(),
}
}
fn emit_value(&self, buffer: &mut [u8]) {
match self {
InfoBridgePort::Flush => (),
InfoBridgePort::HairpinMode(value)
| InfoBridgePort::Guard(value)
| InfoBridgePort::Protect(value)
| InfoBridgePort::FastLeave(value)
| InfoBridgePort::Learning(value)
| InfoBridgePort::UnicastFlood(value)
| InfoBridgePort::ProxyARP(value)
| InfoBridgePort::TopologyChangeAck(value)
| InfoBridgePort::ConfigPending(value)
| InfoBridgePort::ProxyARPWifi(value)
| InfoBridgePort::MulticastFlood(value)
| InfoBridgePort::MulticastToUnicast(value)
| InfoBridgePort::VlanTunnel(value)
| InfoBridgePort::BroadcastFlood(value)
| InfoBridgePort::NeighSupress(value)
| InfoBridgePort::Isolated(value)
| InfoBridgePort::MrpRingOpen(value)
| InfoBridgePort::MrpInOpen(value)
| InfoBridgePort::Locked(value)
| InfoBridgePort::Mab(value)
| InfoBridgePort::NeighVlanSupress(value) => {
buffer[0] = if *value { 1 } else { 0 }
}
InfoBridgePort::Priority(value)
| InfoBridgePort::DesignatedPort(value)
| InfoBridgePort::DesignatedCost(value)
| InfoBridgePort::PortId(value)
| InfoBridgePort::PortNumber(value)
| InfoBridgePort::GroupFwdMask(value) => {
NativeEndian::write_u16(buffer, *value)
}
InfoBridgePort::Cost(value)
| InfoBridgePort::BackupPort(value)
| InfoBridgePort::MulticastEhtHostsLimit(value)
| InfoBridgePort::MulticastEhtHostsCnt(value)
| InfoBridgePort::MulticastNGroups(value)
| InfoBridgePort::MulticastMaxGroups(value)
| InfoBridgePort::BackupNextHopId(value) => {
NativeEndian::write_u32(buffer, *value)
}
InfoBridgePort::MessageAgeTimer(value)
| InfoBridgePort::ForwardDelayTimer(value)
| InfoBridgePort::HoldTimer(value) => {
NativeEndian::write_u64(buffer, *value)
}
InfoBridgePort::RootId(bridge_id)
| InfoBridgePort::BridgeId(bridge_id) => bridge_id.emit(buffer),
InfoBridgePort::State(state) => buffer[0] = (*state).into(),
InfoBridgePort::MulticastRouter(mcast_router) => {
buffer[0] = (*mcast_router).into()
}
InfoBridgePort::Other(nla) => nla.emit_value(buffer),
}
}
fn kind(&self) -> u16 {
match self {
InfoBridgePort::State(_) => IFLA_BRPORT_STATE,
InfoBridgePort::Priority(_) => IFLA_BRPORT_PRIORITY,
InfoBridgePort::Cost(_) => IFLA_BRPORT_COST,
InfoBridgePort::HairpinMode(_) => IFLA_BRPORT_MODE,
InfoBridgePort::Guard(_) => IFLA_BRPORT_GUARD,
InfoBridgePort::Protect(_) => IFLA_BRPORT_PROTECT,
InfoBridgePort::FastLeave(_) => IFLA_BRPORT_FAST_LEAVE,
InfoBridgePort::Learning(_) => IFLA_BRPORT_LEARNING,
InfoBridgePort::UnicastFlood(_) => IFLA_BRPORT_UNICAST_FLOOD,
InfoBridgePort::ProxyARP(_) => IFLA_BRPORT_PROXYARP,
InfoBridgePort::ProxyARPWifi(_) => IFLA_BRPORT_PROXYARP_WIFI,
InfoBridgePort::RootId(_) => IFLA_BRPORT_ROOT_ID,
InfoBridgePort::BridgeId(_) => IFLA_BRPORT_BRIDGE_ID,
InfoBridgePort::DesignatedPort(_) => IFLA_BRPORT_DESIGNATED_PORT,
InfoBridgePort::DesignatedCost(_) => IFLA_BRPORT_DESIGNATED_COST,
InfoBridgePort::PortId(_) => IFLA_BRPORT_ID,
InfoBridgePort::PortNumber(_) => IFLA_BRPORT_NO,
InfoBridgePort::TopologyChangeAck(_) => {
IFLA_BRPORT_TOPOLOGY_CHANGE_ACK
}
InfoBridgePort::ConfigPending(_) => IFLA_BRPORT_CONFIG_PENDING,
InfoBridgePort::MessageAgeTimer(_) => IFLA_BRPORT_MESSAGE_AGE_TIMER,
InfoBridgePort::ForwardDelayTimer(_) => {
IFLA_BRPORT_FORWARD_DELAY_TIMER
}
InfoBridgePort::HoldTimer(_) => IFLA_BRPORT_HOLD_TIMER,
InfoBridgePort::Flush => IFLA_BRPORT_FLUSH,
InfoBridgePort::MulticastRouter(_) => IFLA_BRPORT_MULTICAST_ROUTER,
InfoBridgePort::MulticastFlood(_) => IFLA_BRPORT_MCAST_FLOOD,
InfoBridgePort::MulticastToUnicast(_) => IFLA_BRPORT_MCAST_TO_UCAST,
InfoBridgePort::VlanTunnel(_) => IFLA_BRPORT_VLAN_TUNNEL,
InfoBridgePort::BroadcastFlood(_) => IFLA_BRPORT_BCAST_FLOOD,
InfoBridgePort::GroupFwdMask(_) => IFLA_BRPORT_GROUP_FWD_MASK,
InfoBridgePort::NeighSupress(_) => IFLA_BRPORT_NEIGH_SUPPRESS,
InfoBridgePort::Isolated(_) => IFLA_BRPORT_ISOLATED,
InfoBridgePort::BackupPort(_) => IFLA_BRPORT_BACKUP_PORT,
InfoBridgePort::MrpRingOpen(_) => IFLA_BRPORT_MRP_RING_OPEN,
InfoBridgePort::MrpInOpen(_) => IFLA_BRPORT_MRP_IN_OPEN,
InfoBridgePort::MulticastEhtHostsLimit(_) => {
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT
}
InfoBridgePort::MulticastEhtHostsCnt(_) => {
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT
}
InfoBridgePort::Locked(_) => IFLA_BRPORT_LOCKED,
InfoBridgePort::Mab(_) => IFLA_BRPORT_MAB,
InfoBridgePort::MulticastNGroups(_) => IFLA_BRPORT_MCAST_N_GROUPS,
InfoBridgePort::MulticastMaxGroups(_) => {
IFLA_BRPORT_MCAST_MAX_GROUPS
}
InfoBridgePort::NeighVlanSupress(_) => {
IFLA_BRPORT_NEIGH_VLAN_SUPPRESS
}
InfoBridgePort::BackupNextHopId(_) => IFLA_BRPORT_BACKUP_NHID,
InfoBridgePort::Other(nla) => nla.kind(),
}
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
for InfoBridgePort
{
fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
let payload = buf.value();
Ok(match buf.kind() {
IFLA_BRPORT_STATE => InfoBridgePort::State(
parse_u8(payload)
.with_context(|| {
format!("invalid IFLA_BRPORT_STATE {payload:?}")
})?
.into(),
),
IFLA_BRPORT_PRIORITY => {
InfoBridgePort::Priority(parse_u16(payload).with_context(
|| format!("invalid IFLA_BRPORT_PRIORITY {payload:?}"),
)?)
}
IFLA_BRPORT_COST => {
InfoBridgePort::Cost(parse_u32(payload).with_context(|| {
format!("invalid IFLA_BRPORT_COST {payload:?}")
})?)
}
IFLA_BRPORT_MODE => InfoBridgePort::HairpinMode(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MODE {payload:?}")
})? > 0,
),
IFLA_BRPORT_GUARD => InfoBridgePort::Guard(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_GUARD {payload:?}")
})? > 0,
),
IFLA_BRPORT_PROTECT => InfoBridgePort::Protect(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_PROTECT {payload:?}")
})? > 0,
),
IFLA_BRPORT_FAST_LEAVE => InfoBridgePort::FastLeave(
parse_u8(payload).with_context(|| {
format!(
"invalid IFLA_BRPORT_FAST_LEAVE {payload:?}"
)
})? > 0,
),
IFLA_BRPORT_LEARNING => InfoBridgePort::Learning(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_LEARNING {payload:?}")
})? > 0,
),
IFLA_BRPORT_UNICAST_FLOOD => InfoBridgePort::UnicastFlood(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_UNICAST_FLOOD {payload:?}")
})? > 0,
),
IFLA_BRPORT_PROXYARP => InfoBridgePort::ProxyARP(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_PROXYARP {payload:?}")
})? > 0,
),
IFLA_BRPORT_PROXYARP_WIFI => InfoBridgePort::ProxyARPWifi(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_PROXYARP_WIFI {payload:?}")
})? > 0,
),
IFLA_BRPORT_ROOT_ID => Self::RootId(
BridgeId::parse(&BridgeIdBuffer::new(payload)).with_context(|| {
format!("invalid IFLA_BRPORT_ROOT_ID {payload:?}")
})?,
),
IFLA_BRPORT_BRIDGE_ID => Self::BridgeId(
BridgeId::parse(&BridgeIdBuffer::new(payload)).with_context(|| {
format!("invalid IFLA_BRPORT_BRIDGE_ID {payload:?}")
})?,
),
IFLA_BRPORT_DESIGNATED_PORT => InfoBridgePort::DesignatedPort(
parse_u16(payload).with_context(|| {
format!("invalid IFLA_BRPORT_DESIGNATED_PORT {payload:?}")
})?,
),
IFLA_BRPORT_DESIGNATED_COST => InfoBridgePort::DesignatedCost(
parse_u16(payload).with_context(|| {
format!("invalid IFLA_BRPORT_DESIGNATED_COST {payload:?}")
})?,
),
IFLA_BRPORT_ID => {
InfoBridgePort::PortId(parse_u16(payload).with_context(|| {
format!("invalid IFLA_BRPORT_ID {payload:?}")
})?)
}
IFLA_BRPORT_NO => {
InfoBridgePort::PortNumber(parse_u16(payload).with_context(|| {
format!("invalid IFLA_BRPORT_NO {payload:?}")
})?)
}
IFLA_BRPORT_TOPOLOGY_CHANGE_ACK => {
InfoBridgePort::TopologyChangeAck(
parse_u8(payload).with_context(|| {
format!(
"invalid IFLA_BRPORT_TOPOLOGY_CHANGE_ACK {payload:?}"
)
})? > 0,
)
}
IFLA_BRPORT_CONFIG_PENDING => InfoBridgePort::ConfigPending(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_CONFIG_PENDING {payload:?}")
})? > 0,
),
IFLA_BRPORT_MESSAGE_AGE_TIMER => InfoBridgePort::MessageAgeTimer(
parse_u64(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MESSAGE_AGE_TIMER {payload:?}")
})?,
),
IFLA_BRPORT_FORWARD_DELAY_TIMER => {
InfoBridgePort::ForwardDelayTimer(
parse_u64(payload).with_context(|| {
format!(
"invalid IFLA_BRPORT_FORWARD_DELAY_TIMER {payload:?}"
)
})?,
)
}
IFLA_BRPORT_HOLD_TIMER => {
InfoBridgePort::HoldTimer(parse_u64(payload).with_context(
|| format!("invalid IFLA_BRPORT_HOLD_TIMER {payload:?}"),
)?)
}
IFLA_BRPORT_FLUSH => InfoBridgePort::Flush,
IFLA_BRPORT_MULTICAST_ROUTER => InfoBridgePort::MulticastRouter(
parse_u8(payload)
.with_context(|| {
format!(
"invalid IFLA_BRPORT_MULTICAST_ROUTER {payload:?}"
)
})?
.into(),
),
IFLA_BRPORT_MCAST_FLOOD => InfoBridgePort::MulticastFlood(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MCAST_FLOOD {payload:?}")
})? > 0,
),
IFLA_BRPORT_MCAST_TO_UCAST => InfoBridgePort::MulticastToUnicast(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MCAST_TO_UCAST {payload:?}")
})? > 0,
),
IFLA_BRPORT_VLAN_TUNNEL => InfoBridgePort::VlanTunnel(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_VLAN_TUNNEL {payload:?}")
})? > 0,
),
IFLA_BRPORT_BCAST_FLOOD => InfoBridgePort::BroadcastFlood(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_BCAST_FLOOD {payload:?}")
})? > 0,
),
IFLA_BRPORT_GROUP_FWD_MASK => InfoBridgePort::GroupFwdMask(
parse_u16(payload).with_context(|| {
format!("invalid IFLA_BRPORT_GROUP_FWD_MASK {payload:?}")
})?,
),
IFLA_BRPORT_NEIGH_SUPPRESS => InfoBridgePort::NeighSupress(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_NEIGH_SUPPRESS {payload:?}")
})? > 0,
),
IFLA_BRPORT_ISOLATED => InfoBridgePort::Isolated(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_ISOLATED {payload:?}")
})? > 0,
),
IFLA_BRPORT_BACKUP_PORT => {
InfoBridgePort::BackupPort(parse_u32(payload).with_context(
|| format!("invalid IFLA_BRPORT_BACKUP_PORT {payload:?}"),
)?)
}
IFLA_BRPORT_MRP_RING_OPEN => InfoBridgePort::MrpRingOpen(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MRP_RING_OPEN {payload:?}")
})? > 0,
),
IFLA_BRPORT_MRP_IN_OPEN => InfoBridgePort::MrpInOpen(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MRP_IN_OPEN {payload:?}")
})? > 0,
),
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT => {
InfoBridgePort::MulticastEhtHostsLimit(
parse_u32(payload).with_context(|| {
format!(
"invalid IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT {payload:?}"
)
})?,
)
}
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT => {
InfoBridgePort::MulticastEhtHostsCnt(
parse_u32(payload).with_context(|| {
format!(
"invalid IFLA_BRPORT_MCAST_EHT_HOSTS_CNT {payload:?}"
)
})?
)
}
IFLA_BRPORT_LOCKED => InfoBridgePort::Locked(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_LOCKED {payload:?}")
})? > 0,
),
IFLA_BRPORT_MAB => InfoBridgePort::Mab(
parse_u8(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MAB {payload:?}")
})? > 0,
),
IFLA_BRPORT_MCAST_N_GROUPS => InfoBridgePort::MulticastNGroups(
parse_u32(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MCAST_N_GROUPS {payload:?}")
})?,
),
IFLA_BRPORT_MCAST_MAX_GROUPS => InfoBridgePort::MulticastMaxGroups(
parse_u32(payload).with_context(|| {
format!("invalid IFLA_BRPORT_MCAST_MAX_GROUPS {payload:?}")
})?,
),
IFLA_BRPORT_NEIGH_VLAN_SUPPRESS => InfoBridgePort::NeighVlanSupress(
parse_u8(payload).with_context(|| {
format!(
"invalid IFLA_BRPORT_NEIGH_VLAN_SUPPRESS {payload:?}"
)
})? > 0,
),
IFLA_BRPORT_BACKUP_NHID => InfoBridgePort::BackupNextHopId(
parse_u32(payload).with_context(|| {
format!("invalid IFLA_BRPORT_BACKUP_NHID {payload:?}")
})?,
),
kind => InfoBridgePort::Other(
DefaultNla::parse(buf).with_context(|| {
format!(
"failed to parse bridge port NLA of type '{kind}' into DefaultNla"
)
})?,
),
})
}
}
const BR_STATE_DISABLED: u8 = 0;
const BR_STATE_LISTENING: u8 = 1;
const BR_STATE_LEARNING: u8 = 2;
const BR_STATE_FORWARDING: u8 = 3;
const BR_STATE_BLOCKING: u8 = 4;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
pub enum BridgePortState {
Disabled,
Listening,
Learning,
Forwarding,
Blocking,
Other(u8),
}
impl From<u8> for BridgePortState {
fn from(value: u8) -> Self {
match value {
BR_STATE_DISABLED => BridgePortState::Disabled,
BR_STATE_LISTENING => BridgePortState::Listening,
BR_STATE_LEARNING => BridgePortState::Learning,
BR_STATE_FORWARDING => BridgePortState::Forwarding,
BR_STATE_BLOCKING => BridgePortState::Blocking,
_ => BridgePortState::Other(value),
}
}
}
impl From<BridgePortState> for u8 {
fn from(value: BridgePortState) -> Self {
match value {
BridgePortState::Disabled => BR_STATE_DISABLED,
BridgePortState::Listening => BR_STATE_LISTENING,
BridgePortState::Learning => BR_STATE_LEARNING,
BridgePortState::Forwarding => BR_STATE_FORWARDING,
BridgePortState::Blocking => BR_STATE_BLOCKING,
BridgePortState::Other(v) => v,
}
}
}
const MDB_RTR_TYPE_DISABLED: u8 = 0;
const MDB_RTR_TYPE_TEMP_QUERY: u8 = 1;
const MDB_RTR_TYPE_PERM: u8 = 2;
const MDB_RTR_TYPE_TEMP: u8 = 3;
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[non_exhaustive]
pub enum BridgePortMulticastRouter {
Disabled,
TempQuery,
Perm,
Temp,
Other(u8),
}
impl From<u8> for BridgePortMulticastRouter {
fn from(value: u8) -> Self {
match value {
MDB_RTR_TYPE_DISABLED => BridgePortMulticastRouter::Disabled,
MDB_RTR_TYPE_TEMP_QUERY => BridgePortMulticastRouter::TempQuery,
MDB_RTR_TYPE_PERM => BridgePortMulticastRouter::Perm,
MDB_RTR_TYPE_TEMP => BridgePortMulticastRouter::Temp,
_ => BridgePortMulticastRouter::Other(value),
}
}
}
impl From<BridgePortMulticastRouter> for u8 {
fn from(value: BridgePortMulticastRouter) -> Self {
match value {
BridgePortMulticastRouter::Disabled => MDB_RTR_TYPE_DISABLED,
BridgePortMulticastRouter::TempQuery => MDB_RTR_TYPE_TEMP_QUERY,
BridgePortMulticastRouter::Perm => MDB_RTR_TYPE_PERM,
BridgePortMulticastRouter::Temp => MDB_RTR_TYPE_TEMP,
BridgePortMulticastRouter::Other(v) => v,
}
}
}