netlink_packet_route/link/link_info/
bond_port.rs1use netlink_packet_core::{
4 emit_i32, emit_u16, emit_u32, parse_i32, parse_u16, parse_u32, parse_u8,
5 DecodeError, DefaultNla, ErrorContext, Nla, NlaBuffer, Parseable,
6};
7
8const IFLA_BOND_PORT_STATE_ACTIVE: u8 = 0;
9const IFLA_BOND_PORT_STATE_BACKUP: u8 = 1;
10
11const IFLA_BOND_PORT_MII_STATUS_UP: u8 = 0;
12const IFLA_BOND_PORT_MII_STATUS_GOING_DOWN: u8 = 1;
13const IFLA_BOND_PORT_MII_STATUS_DOWN: u8 = 2;
14const IFLA_BOND_PORT_MII_STATUS_GOING_BACK: u8 = 3;
15
16const IFLA_BOND_PORT_STATE: u16 = 1;
17const IFLA_BOND_PORT_MII_STATUS: u16 = 2;
18const IFLA_BOND_PORT_LINK_FAILURE_COUNT: u16 = 3;
19const IFLA_BOND_PORT_PERM_HWADDR: u16 = 4;
20const IFLA_BOND_PORT_QUEUE_ID: u16 = 5;
21const IFLA_BOND_PORT_PRIO: u16 = 9;
25
26#[derive(Debug, Clone, Copy, Eq, PartialEq)]
27#[non_exhaustive]
28pub enum BondPortState {
29 Active,
30 Backup,
31 Other(u8),
32}
33
34impl From<u8> for BondPortState {
35 fn from(value: u8) -> Self {
36 use self::BondPortState::*;
37 match value {
38 IFLA_BOND_PORT_STATE_ACTIVE => Active,
39 IFLA_BOND_PORT_STATE_BACKUP => Backup,
40 _ => Other(value),
41 }
42 }
43}
44
45impl From<BondPortState> for u8 {
46 fn from(value: BondPortState) -> Self {
47 use self::BondPortState::*;
48 match value {
49 Active => IFLA_BOND_PORT_STATE_ACTIVE,
50 Backup => IFLA_BOND_PORT_STATE_BACKUP,
51 Other(other) => other,
52 }
53 }
54}
55
56#[derive(Debug, Clone, Copy, Eq, PartialEq)]
57#[non_exhaustive]
58pub enum MiiStatus {
59 Up,
60 GoingDown,
61 Down,
62 GoingBack,
63 Other(u8),
64}
65
66impl From<u8> for MiiStatus {
67 fn from(value: u8) -> Self {
68 use self::MiiStatus::*;
69 match value {
70 IFLA_BOND_PORT_MII_STATUS_UP => Up,
71 IFLA_BOND_PORT_MII_STATUS_GOING_DOWN => GoingDown,
72 IFLA_BOND_PORT_MII_STATUS_DOWN => Down,
73 IFLA_BOND_PORT_MII_STATUS_GOING_BACK => GoingBack,
74 _ => Other(value),
75 }
76 }
77}
78
79impl From<MiiStatus> for u8 {
80 fn from(value: MiiStatus) -> Self {
81 use self::MiiStatus::*;
82 match value {
83 Up => IFLA_BOND_PORT_MII_STATUS_UP,
84 GoingDown => IFLA_BOND_PORT_MII_STATUS_GOING_DOWN,
85 Down => IFLA_BOND_PORT_MII_STATUS_DOWN,
86 GoingBack => IFLA_BOND_PORT_MII_STATUS_GOING_BACK,
87 Other(other) => other,
88 }
89 }
90}
91
92#[derive(Debug, PartialEq, Eq, Clone)]
93#[non_exhaustive]
94pub enum InfoBondPort {
95 LinkFailureCount(u32),
96 MiiStatus(MiiStatus),
97 PermHwaddr(Vec<u8>),
98 Prio(i32),
99 QueueId(u16),
100 BondPortState(BondPortState),
101 Other(DefaultNla),
102}
103
104impl Nla for InfoBondPort {
105 #[rustfmt::skip]
106 fn value_len(&self) -> usize {
107 use self::InfoBondPort::*;
108 match self {
109 QueueId(_)
110 => 2,
111 LinkFailureCount(_) |
112 Prio(_)
113 => 4,
114 PermHwaddr(ref bytes)
115 => bytes.len(),
116 MiiStatus(_) => 1,
117 BondPortState(_) => 1,
118 Other(nla)
119 => nla.value_len(),
120 }
121 }
122
123 #[rustfmt::skip]
124 fn emit_value(&self, buffer: &mut [u8]) {
125 use self::InfoBondPort::*;
126 match self {
127 QueueId(ref value)
128 => emit_u16(buffer, *value).unwrap(),
129 PermHwaddr(ref bytes)
130 => buffer.copy_from_slice(bytes.as_slice()),
131 Prio(ref value)
132 => emit_i32(buffer, *value).unwrap(),
133 LinkFailureCount(value)
134 => emit_u32(buffer, *value).unwrap(),
135 MiiStatus(state) => buffer[0] = (*state).into(),
136 BondPortState(state) => buffer[0] = (*state).into(),
137 Other(nla)
138 => nla.emit_value(buffer),
139 }
140 }
141
142 fn kind(&self) -> u16 {
143 use self::InfoBondPort::*;
144
145 match self {
146 LinkFailureCount(_) => IFLA_BOND_PORT_LINK_FAILURE_COUNT,
147 MiiStatus(_) => IFLA_BOND_PORT_MII_STATUS,
148 PermHwaddr(_) => IFLA_BOND_PORT_PERM_HWADDR,
149 Prio(_) => IFLA_BOND_PORT_PRIO,
150 QueueId(_) => IFLA_BOND_PORT_QUEUE_ID,
151 BondPortState(_) => IFLA_BOND_PORT_STATE,
152 Other(nla) => nla.kind(),
153 }
154 }
155}
156
157impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoBondPort {
158 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
159 use self::InfoBondPort::*;
160 let payload = buf.value();
161 Ok(match buf.kind() {
162 IFLA_BOND_PORT_LINK_FAILURE_COUNT => {
163 LinkFailureCount(parse_u32(payload).context(
164 "invalid IFLA_BOND_PORT_LINK_FAILURE_COUNT value",
165 )?)
166 }
167 IFLA_BOND_PORT_MII_STATUS => MiiStatus(
168 parse_u8(payload)
169 .context("invalid IFLA_BOND_PORT_MII_STATUS value")?
170 .into(),
171 ),
172 IFLA_BOND_PORT_PERM_HWADDR => PermHwaddr(payload.to_vec()),
173 IFLA_BOND_PORT_PRIO => Prio(
174 parse_i32(payload)
175 .context("invalid IFLA_BOND_PORT_PRIO value")?,
176 ),
177 IFLA_BOND_PORT_QUEUE_ID => QueueId(
178 parse_u16(payload)
179 .context("invalid IFLA_BOND_PORT_QUEUE_ID value")?,
180 ),
181 IFLA_BOND_PORT_STATE => BondPortState(
182 parse_u8(payload)
183 .context("invalid IFLA_BOND_PORT_STATE value")?
184 .into(),
185 ),
186 kind => Other(
187 DefaultNla::parse(buf)
188 .context(format!("unknown NLA type {kind}"))?,
189 ),
190 })
191 }
192}