1use netlink_packet_core::{
4 emit_i32, emit_u16, emit_u32, parse_i32, parse_mac, parse_u16, parse_u32,
5 DecodeError, DefaultNla, Emitable, ErrorContext, Nla, NlaBuffer,
6 NlasIterator, Parseable,
7};
8
9const IFLA_MACVLAN_MODE: u16 = 1;
10const IFLA_MACVLAN_FLAGS: u16 = 2;
11const IFLA_MACVLAN_MACADDR_MODE: u16 = 3;
12const IFLA_MACVLAN_MACADDR: u16 = 4;
13const IFLA_MACVLAN_MACADDR_DATA: u16 = 5;
14const IFLA_MACVLAN_MACADDR_COUNT: u16 = 6;
15const IFLA_MACVLAN_BC_QUEUE_LEN: u16 = 7;
16const IFLA_MACVLAN_BC_QUEUE_LEN_USED: u16 = 8;
17const IFLA_MACVLAN_BC_CUTOFF: u16 = 9;
18
19#[derive(Debug, PartialEq, Eq, Clone)]
20#[non_exhaustive]
21pub enum InfoMacVlan {
22 Mode(MacVlanMode),
23 Flags(u16),
24 MacAddrMode(u32),
25 MacAddr([u8; 6]),
26 MacAddrData(Vec<InfoMacVlan>),
28 MacAddrCount(u32),
29 BcQueueLen(u32),
30 BcQueueLenUsed(u32),
31 BcCutoff(i32),
32 Other(DefaultNla),
33}
34
35impl Nla for InfoMacVlan {
36 fn value_len(&self) -> usize {
37 match self {
38 Self::Mode(_) => 4,
39 Self::Flags(_) => 2,
40 Self::MacAddrMode(_) => 4,
41 Self::MacAddr(_) => 6,
42 Self::MacAddrData(ref nlas) => nlas.as_slice().buffer_len(),
43 Self::MacAddrCount(_) => 4,
44 Self::BcQueueLen(_) => 4,
45 Self::BcQueueLenUsed(_) => 4,
46 Self::BcCutoff(_) => 4,
47 Self::Other(nla) => nla.value_len(),
48 }
49 }
50
51 fn emit_value(&self, buffer: &mut [u8]) {
52 match self {
53 Self::Mode(value) => emit_u32(buffer, (*value).into()).unwrap(),
54 Self::Flags(value) => emit_u16(buffer, *value).unwrap(),
55 Self::MacAddrMode(value) => emit_u32(buffer, *value).unwrap(),
56 Self::MacAddr(bytes) => buffer.copy_from_slice(bytes),
57 Self::MacAddrData(ref nlas) => nlas.as_slice().emit(buffer),
58 Self::MacAddrCount(value) => emit_u32(buffer, *value).unwrap(),
59 Self::BcQueueLen(value) => emit_u32(buffer, *value).unwrap(),
60 Self::BcQueueLenUsed(value) => emit_u32(buffer, *value).unwrap(),
61 Self::BcCutoff(value) => emit_i32(buffer, *value).unwrap(),
62 Self::Other(nla) => nla.emit_value(buffer),
63 }
64 }
65
66 fn kind(&self) -> u16 {
67 use self::InfoMacVlan::*;
68 match self {
69 Mode(_) => IFLA_MACVLAN_MODE,
70 Flags(_) => IFLA_MACVLAN_FLAGS,
71 MacAddrMode(_) => IFLA_MACVLAN_MACADDR_MODE,
72 MacAddr(_) => IFLA_MACVLAN_MACADDR,
73 MacAddrData(_) => IFLA_MACVLAN_MACADDR_DATA,
74 MacAddrCount(_) => IFLA_MACVLAN_MACADDR_COUNT,
75 BcQueueLen(_) => IFLA_MACVLAN_BC_QUEUE_LEN,
76 BcQueueLenUsed(_) => IFLA_MACVLAN_BC_QUEUE_LEN_USED,
77 BcCutoff(_) => IFLA_MACVLAN_BC_CUTOFF,
78 Other(nla) => nla.kind(),
79 }
80 }
81}
82
83impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoMacVlan {
84 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
85 use self::InfoMacVlan::*;
86 let payload = buf.value();
87 Ok(match buf.kind() {
88 IFLA_MACVLAN_MODE => Mode(
89 parse_u32(payload)
90 .context("invalid IFLA_MACVLAN_MODE value")?
91 .into(),
92 ),
93 IFLA_MACVLAN_FLAGS => Flags(
94 parse_u16(payload)
95 .context("invalid IFLA_MACVLAN_FLAGS value")?,
96 ),
97 IFLA_MACVLAN_MACADDR_MODE => MacAddrMode(
98 parse_u32(payload)
99 .context("invalid IFLA_MACVLAN_MACADDR_MODE value")?,
100 ),
101 IFLA_MACVLAN_MACADDR => MacAddr(
102 parse_mac(payload)
103 .context("invalid IFLA_MACVLAN_MACADDR value")?,
104 ),
105 IFLA_MACVLAN_MACADDR_DATA => {
106 let mut mac_data = Vec::new();
107 let err = "failed to parse IFLA_MACVLAN_MACADDR_DATA";
108 for nla in NlasIterator::new(payload) {
109 let nla = &nla.context(err)?;
110 let parsed = InfoMacVlan::parse(nla).context(err)?;
111 mac_data.push(parsed);
112 }
113 MacAddrData(mac_data)
114 }
115 IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount(
116 parse_u32(payload)
117 .context("invalid IFLA_MACVLAN_MACADDR_COUNT value")?,
118 ),
119 IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen(
120 parse_u32(payload)
121 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN value")?,
122 ),
123 IFLA_MACVLAN_BC_QUEUE_LEN_USED => BcQueueLenUsed(
124 parse_u32(payload)
125 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN_USED value")?,
126 ),
127 IFLA_MACVLAN_BC_CUTOFF => BcCutoff(
128 parse_i32(payload)
129 .context("invalid IFLA_MACVLAN_BC_CUTOFF value")?,
130 ),
131 kind => Other(DefaultNla::parse(buf).context(format!(
132 "unknown NLA type {kind} for IFLA_INFO_DATA(mac_vlan)"
133 ))?),
134 })
135 }
136}
137
138#[derive(Debug, PartialEq, Eq, Clone)]
139#[non_exhaustive]
140pub enum InfoMacVtap {
141 Mode(MacVtapMode),
142 Flags(u16),
143 MacAddrMode(u32),
144 MacAddr([u8; 6]),
145 MacAddrData(Vec<InfoMacVtap>),
146 MacAddrCount(u32),
147 BcQueueLen(u32),
148 BcQueueLenUsed(u32),
149 BcCutoff(i32),
150 Other(DefaultNla),
151}
152
153impl Nla for InfoMacVtap {
154 fn value_len(&self) -> usize {
155 use self::InfoMacVtap::*;
156 match self {
157 Mode(_) => 4,
158 Flags(_) => 2,
159 MacAddrMode(_) => 4,
160 MacAddr(_) => 6,
161 MacAddrData(ref nlas) => nlas.as_slice().buffer_len(),
162 MacAddrCount(_) => 4,
163 BcQueueLen(_) => 4,
164 BcQueueLenUsed(_) => 4,
165 BcCutoff(_) => 4,
166 Other(nla) => nla.value_len(),
167 }
168 }
169
170 fn emit_value(&self, buffer: &mut [u8]) {
171 use self::InfoMacVtap::*;
172 match self {
173 Mode(value) => emit_u32(buffer, (*value).into()).unwrap(),
174 Flags(value) => emit_u16(buffer, *value).unwrap(),
175 MacAddrMode(value) => emit_u32(buffer, *value).unwrap(),
176 MacAddr(bytes) => buffer.copy_from_slice(bytes),
177 MacAddrData(ref nlas) => nlas.as_slice().emit(buffer),
178 MacAddrCount(value) => emit_u32(buffer, *value).unwrap(),
179 BcQueueLen(value) => emit_u32(buffer, *value).unwrap(),
180 BcQueueLenUsed(value) => emit_u32(buffer, *value).unwrap(),
181 BcCutoff(value) => emit_i32(buffer, *value).unwrap(),
182 Other(nla) => nla.emit_value(buffer),
183 }
184 }
185
186 fn kind(&self) -> u16 {
187 use self::InfoMacVtap::*;
188 match self {
189 Mode(_) => IFLA_MACVLAN_MODE,
190 Flags(_) => IFLA_MACVLAN_FLAGS,
191 MacAddrMode(_) => IFLA_MACVLAN_MACADDR_MODE,
192 MacAddr(_) => IFLA_MACVLAN_MACADDR,
193 MacAddrData(_) => IFLA_MACVLAN_MACADDR_DATA,
194 MacAddrCount(_) => IFLA_MACVLAN_MACADDR_COUNT,
195 BcQueueLen(_) => IFLA_MACVLAN_BC_QUEUE_LEN,
196 BcQueueLenUsed(_) => IFLA_MACVLAN_BC_QUEUE_LEN_USED,
197 BcCutoff(_) => IFLA_MACVLAN_BC_CUTOFF,
198 Other(nla) => nla.kind(),
199 }
200 }
201}
202
203impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoMacVtap {
204 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
205 use self::InfoMacVtap::*;
206 let payload = buf.value();
207 Ok(match buf.kind() {
208 IFLA_MACVLAN_MODE => Mode(
209 parse_u32(payload)
210 .context("invalid IFLA_MACVLAN_MODE value")?
211 .into(),
212 ),
213 IFLA_MACVLAN_FLAGS => Flags(
214 parse_u16(payload)
215 .context("invalid IFLA_MACVLAN_FLAGS value")?,
216 ),
217 IFLA_MACVLAN_MACADDR_MODE => MacAddrMode(
218 parse_u32(payload)
219 .context("invalid IFLA_MACVLAN_MACADDR_MODE value")?,
220 ),
221 IFLA_MACVLAN_MACADDR => MacAddr(
222 parse_mac(payload)
223 .context("invalid IFLA_MACVLAN_MACADDR value")?,
224 ),
225 IFLA_MACVLAN_MACADDR_DATA => {
226 let mut mac_data = Vec::new();
227 let err = "failed to parse IFLA_MACVLAN_MACADDR_DATA";
228 for nla in NlasIterator::new(payload) {
229 let nla = &nla.context(err)?;
230 let parsed = InfoMacVtap::parse(nla).context(err)?;
231 mac_data.push(parsed);
232 }
233 MacAddrData(mac_data)
234 }
235 IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount(
236 parse_u32(payload)
237 .context("invalid IFLA_MACVLAN_MACADDR_COUNT value")?,
238 ),
239 IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen(
240 parse_u32(payload)
241 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN value")?,
242 ),
243 IFLA_MACVLAN_BC_QUEUE_LEN_USED => BcQueueLenUsed(
244 parse_u32(payload)
245 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN_USED value")?,
246 ),
247 IFLA_MACVLAN_BC_CUTOFF => BcCutoff(
248 parse_i32(payload)
249 .context("invalid IFLA_MACVLAN_BC_CUTOFF value")?,
250 ),
251 kind => Other(DefaultNla::parse(buf).context(format!(
252 "unknown NLA type {kind} for IFLA_INFO_DATA(mac_vtap)"
253 ))?),
254 })
255 }
256}
257
258const MACVLAN_MODE_PRIVATE: u32 = 1;
259const MACVLAN_MODE_VEPA: u32 = 2;
260const MACVLAN_MODE_BRIDGE: u32 = 4;
261const MACVLAN_MODE_PASSTHRU: u32 = 8;
262const MACVLAN_MODE_SOURCE: u32 = 16;
263
264#[derive(Debug, PartialEq, Eq, Clone, Copy)]
265#[non_exhaustive]
266pub enum MacVlanMode {
267 Private,
268 Vepa,
269 Bridge,
270 Passthrough,
271 Source,
272 Other(u32),
273}
274
275pub type MacVtapMode = MacVlanMode;
276
277impl From<u32> for MacVlanMode {
278 fn from(d: u32) -> Self {
279 match d {
280 MACVLAN_MODE_PRIVATE => Self::Private,
281 MACVLAN_MODE_VEPA => Self::Vepa,
282 MACVLAN_MODE_BRIDGE => Self::Bridge,
283 MACVLAN_MODE_PASSTHRU => Self::Passthrough,
284 MACVLAN_MODE_SOURCE => Self::Source,
285 _ => {
286 log::warn!("Unknown MAC VLAN mode {d}");
287 Self::Other(d)
288 }
289 }
290 }
291}
292
293impl From<MacVlanMode> for u32 {
294 fn from(v: MacVlanMode) -> u32 {
295 match v {
296 MacVlanMode::Private => MACVLAN_MODE_PRIVATE,
297 MacVlanMode::Vepa => MACVLAN_MODE_VEPA,
298 MacVlanMode::Bridge => MACVLAN_MODE_BRIDGE,
299 MacVlanMode::Passthrough => MACVLAN_MODE_PASSTHRU,
300 MacVlanMode::Source => MACVLAN_MODE_SOURCE,
301 MacVlanMode::Other(d) => d,
302 }
303 }
304}