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(MacVlanFlags),
24 MacAddrMode(MacVlanMacAddressMode),
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.bits()).unwrap(),
55 Self::MacAddrMode(value) => {
56 emit_u32(buffer, (*value).into()).unwrap()
57 }
58 Self::MacAddr(bytes) => buffer.copy_from_slice(bytes),
59 Self::MacAddrData(ref nlas) => nlas.as_slice().emit(buffer),
60 Self::MacAddrCount(value) => emit_u32(buffer, *value).unwrap(),
61 Self::BcQueueLen(value) => emit_u32(buffer, *value).unwrap(),
62 Self::BcQueueLenUsed(value) => emit_u32(buffer, *value).unwrap(),
63 Self::BcCutoff(value) => emit_i32(buffer, *value).unwrap(),
64 Self::Other(nla) => nla.emit_value(buffer),
65 }
66 }
67
68 fn kind(&self) -> u16 {
69 use self::InfoMacVlan::*;
70 match self {
71 Mode(_) => IFLA_MACVLAN_MODE,
72 Flags(_) => IFLA_MACVLAN_FLAGS,
73 MacAddrMode(_) => IFLA_MACVLAN_MACADDR_MODE,
74 MacAddr(_) => IFLA_MACVLAN_MACADDR,
75 MacAddrData(_) => IFLA_MACVLAN_MACADDR_DATA,
76 MacAddrCount(_) => IFLA_MACVLAN_MACADDR_COUNT,
77 BcQueueLen(_) => IFLA_MACVLAN_BC_QUEUE_LEN,
78 BcQueueLenUsed(_) => IFLA_MACVLAN_BC_QUEUE_LEN_USED,
79 BcCutoff(_) => IFLA_MACVLAN_BC_CUTOFF,
80 Other(nla) => nla.kind(),
81 }
82 }
83}
84
85impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoMacVlan {
86 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
87 use self::InfoMacVlan::*;
88 let payload = buf.value();
89 Ok(match buf.kind() {
90 IFLA_MACVLAN_MODE => Mode(
91 parse_u32(payload)
92 .context("invalid IFLA_MACVLAN_MODE value")?
93 .into(),
94 ),
95 IFLA_MACVLAN_FLAGS => Flags(MacVlanFlags::from_bits_retain(
96 parse_u16(payload)
97 .context("invalid IFLA_MACVLAN_FLAGS value")?,
98 )),
99 IFLA_MACVLAN_MACADDR_MODE => MacAddrMode(
100 parse_u32(payload)
101 .context("invalid IFLA_MACVLAN_MACADDR_MODE value")?
102 .into(),
103 ),
104 IFLA_MACVLAN_MACADDR => MacAddr(
105 parse_mac(payload)
106 .context("invalid IFLA_MACVLAN_MACADDR value")?,
107 ),
108 IFLA_MACVLAN_MACADDR_DATA => {
109 let mut mac_data = Vec::new();
110 let err = "failed to parse IFLA_MACVLAN_MACADDR_DATA";
111 for nla in NlasIterator::new(payload) {
112 let nla = &nla.context(err)?;
113 let parsed = InfoMacVlan::parse(nla).context(err)?;
114 mac_data.push(parsed);
115 }
116 MacAddrData(mac_data)
117 }
118 IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount(
119 parse_u32(payload)
120 .context("invalid IFLA_MACVLAN_MACADDR_COUNT value")?,
121 ),
122 IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen(
123 parse_u32(payload)
124 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN value")?,
125 ),
126 IFLA_MACVLAN_BC_QUEUE_LEN_USED => BcQueueLenUsed(
127 parse_u32(payload)
128 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN_USED value")?,
129 ),
130 IFLA_MACVLAN_BC_CUTOFF => BcCutoff(
131 parse_i32(payload)
132 .context("invalid IFLA_MACVLAN_BC_CUTOFF value")?,
133 ),
134 kind => Other(DefaultNla::parse(buf).context(format!(
135 "unknown NLA type {kind} for IFLA_INFO_DATA(mac_vlan)"
136 ))?),
137 })
138 }
139}
140
141#[derive(Debug, PartialEq, Eq, Clone)]
142#[non_exhaustive]
143pub enum InfoMacVtap {
144 Mode(MacVtapMode),
145 Flags(MacVtapFlags),
146 MacAddrMode(MacVtapMacAddressMode),
147 MacAddr([u8; 6]),
148 MacAddrData(Vec<InfoMacVtap>),
149 MacAddrCount(u32),
150 BcQueueLen(u32),
151 BcQueueLenUsed(u32),
152 BcCutoff(i32),
153 Other(DefaultNla),
154}
155
156impl Nla for InfoMacVtap {
157 fn value_len(&self) -> usize {
158 use self::InfoMacVtap::*;
159 match self {
160 Mode(_) => 4,
161 Flags(_) => 2,
162 MacAddrMode(_) => 4,
163 MacAddr(_) => 6,
164 MacAddrData(ref nlas) => nlas.as_slice().buffer_len(),
165 MacAddrCount(_) => 4,
166 BcQueueLen(_) => 4,
167 BcQueueLenUsed(_) => 4,
168 BcCutoff(_) => 4,
169 Other(nla) => nla.value_len(),
170 }
171 }
172
173 fn emit_value(&self, buffer: &mut [u8]) {
174 use self::InfoMacVtap::*;
175 match self {
176 Mode(value) => emit_u32(buffer, (*value).into()).unwrap(),
177 Flags(value) => emit_u16(buffer, value.bits()).unwrap(),
178 MacAddrMode(value) => emit_u32(buffer, (*value).into()).unwrap(),
179 MacAddr(bytes) => buffer.copy_from_slice(bytes),
180 MacAddrData(ref nlas) => nlas.as_slice().emit(buffer),
181 MacAddrCount(value) => emit_u32(buffer, *value).unwrap(),
182 BcQueueLen(value) => emit_u32(buffer, *value).unwrap(),
183 BcQueueLenUsed(value) => emit_u32(buffer, *value).unwrap(),
184 BcCutoff(value) => emit_i32(buffer, *value).unwrap(),
185 Other(nla) => nla.emit_value(buffer),
186 }
187 }
188
189 fn kind(&self) -> u16 {
190 use self::InfoMacVtap::*;
191 match self {
192 Mode(_) => IFLA_MACVLAN_MODE,
193 Flags(_) => IFLA_MACVLAN_FLAGS,
194 MacAddrMode(_) => IFLA_MACVLAN_MACADDR_MODE,
195 MacAddr(_) => IFLA_MACVLAN_MACADDR,
196 MacAddrData(_) => IFLA_MACVLAN_MACADDR_DATA,
197 MacAddrCount(_) => IFLA_MACVLAN_MACADDR_COUNT,
198 BcQueueLen(_) => IFLA_MACVLAN_BC_QUEUE_LEN,
199 BcQueueLenUsed(_) => IFLA_MACVLAN_BC_QUEUE_LEN_USED,
200 BcCutoff(_) => IFLA_MACVLAN_BC_CUTOFF,
201 Other(nla) => nla.kind(),
202 }
203 }
204}
205
206impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for InfoMacVtap {
207 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
208 use self::InfoMacVtap::*;
209 let payload = buf.value();
210 Ok(match buf.kind() {
211 IFLA_MACVLAN_MODE => Mode(
212 parse_u32(payload)
213 .context("invalid IFLA_MACVLAN_MODE value")?
214 .into(),
215 ),
216 IFLA_MACVLAN_FLAGS => Flags(MacVtapFlags::from_bits_retain(
217 parse_u16(payload)
218 .context("invalid IFLA_MACVLAN_FLAGS value")?,
219 )),
220 IFLA_MACVLAN_MACADDR_MODE => MacAddrMode(
221 parse_u32(payload)
222 .context("invalid IFLA_MACVLAN_MACADDR_MODE value")?
223 .into(),
224 ),
225 IFLA_MACVLAN_MACADDR => MacAddr(
226 parse_mac(payload)
227 .context("invalid IFLA_MACVLAN_MACADDR value")?,
228 ),
229 IFLA_MACVLAN_MACADDR_DATA => {
230 let mut mac_data = Vec::new();
231 let err = "failed to parse IFLA_MACVLAN_MACADDR_DATA";
232 for nla in NlasIterator::new(payload) {
233 let nla = &nla.context(err)?;
234 let parsed = InfoMacVtap::parse(nla).context(err)?;
235 mac_data.push(parsed);
236 }
237 MacAddrData(mac_data)
238 }
239 IFLA_MACVLAN_MACADDR_COUNT => MacAddrCount(
240 parse_u32(payload)
241 .context("invalid IFLA_MACVLAN_MACADDR_COUNT value")?,
242 ),
243 IFLA_MACVLAN_BC_QUEUE_LEN => BcQueueLen(
244 parse_u32(payload)
245 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN value")?,
246 ),
247 IFLA_MACVLAN_BC_QUEUE_LEN_USED => BcQueueLenUsed(
248 parse_u32(payload)
249 .context("invalid IFLA_MACVLAN_BC_QUEUE_LEN_USED value")?,
250 ),
251 IFLA_MACVLAN_BC_CUTOFF => BcCutoff(
252 parse_i32(payload)
253 .context("invalid IFLA_MACVLAN_BC_CUTOFF value")?,
254 ),
255 kind => Other(DefaultNla::parse(buf).context(format!(
256 "unknown NLA type {kind} for IFLA_INFO_DATA(mac_vtap)"
257 ))?),
258 })
259 }
260}
261
262const MACVLAN_MODE_PRIVATE: u32 = 1;
263const MACVLAN_MODE_VEPA: u32 = 2;
264const MACVLAN_MODE_BRIDGE: u32 = 4;
265const MACVLAN_MODE_PASSTHRU: u32 = 8;
266const MACVLAN_MODE_SOURCE: u32 = 16;
267
268#[derive(Debug, PartialEq, Eq, Clone, Copy)]
269#[non_exhaustive]
270pub enum MacVlanMode {
271 Private,
272 Vepa,
273 Bridge,
274 Passthrough,
275 Source,
276 Other(u32),
277}
278
279pub type MacVtapMode = MacVlanMode;
280pub type MacVtapFlags = MacVlanFlags;
281
282impl From<u32> for MacVlanMode {
283 fn from(d: u32) -> Self {
284 match d {
285 MACVLAN_MODE_PRIVATE => Self::Private,
286 MACVLAN_MODE_VEPA => Self::Vepa,
287 MACVLAN_MODE_BRIDGE => Self::Bridge,
288 MACVLAN_MODE_PASSTHRU => Self::Passthrough,
289 MACVLAN_MODE_SOURCE => Self::Source,
290 _ => {
291 log::warn!("Unknown MAC VLAN mode {d}");
292 Self::Other(d)
293 }
294 }
295 }
296}
297
298impl From<MacVlanMode> for u32 {
299 fn from(v: MacVlanMode) -> u32 {
300 match v {
301 MacVlanMode::Private => MACVLAN_MODE_PRIVATE,
302 MacVlanMode::Vepa => MACVLAN_MODE_VEPA,
303 MacVlanMode::Bridge => MACVLAN_MODE_BRIDGE,
304 MacVlanMode::Passthrough => MACVLAN_MODE_PASSTHRU,
305 MacVlanMode::Source => MACVLAN_MODE_SOURCE,
306 MacVlanMode::Other(d) => d,
307 }
308 }
309}
310
311const MACVLAN_FLAG_NOPROMISC: u16 = 1;
312const MACVLAN_FLAG_NODST: u16 = 2;
313
314bitflags! {
315 #[non_exhaustive]
316 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
317 pub struct MacVlanFlags: u16 {
318 const NoPromisc = MACVLAN_FLAG_NOPROMISC;
319 const NoDst = MACVLAN_FLAG_NODST;
320 const _ = !0;
321 }
322}
323
324const MACVLAN_MACADDR_ADD: u32 = 0;
325const MACVLAN_MACADDR_DEL: u32 = 1;
326const MACVLAN_MACADDR_FLUSH: u32 = 2;
327const MACVLAN_MACADDR_SET: u32 = 3;
328
329#[derive(Debug, PartialEq, Eq, Clone, Copy)]
330#[non_exhaustive]
331pub enum MacVlanMacAddressMode {
332 Add,
333 Del,
334 Flush,
335 Set,
336 Other(u32),
337}
338
339pub type MacVtapMacAddressMode = MacVlanMacAddressMode;
340
341impl From<u32> for MacVlanMacAddressMode {
342 fn from(d: u32) -> Self {
343 match d {
344 MACVLAN_MACADDR_ADD => Self::Add,
345 MACVLAN_MACADDR_DEL => Self::Del,
346 MACVLAN_MACADDR_FLUSH => Self::Flush,
347 MACVLAN_MACADDR_SET => Self::Set,
348 _ => Self::Other(d),
349 }
350 }
351}
352
353impl From<MacVlanMacAddressMode> for u32 {
354 fn from(v: MacVlanMacAddressMode) -> u32 {
355 match v {
356 MacVlanMacAddressMode::Add => MACVLAN_MACADDR_ADD,
357 MacVlanMacAddressMode::Del => MACVLAN_MACADDR_DEL,
358 MacVlanMacAddressMode::Flush => MACVLAN_MACADDR_FLUSH,
359 MacVlanMacAddressMode::Set => MACVLAN_MACADDR_SET,
360 MacVlanMacAddressMode::Other(d) => d,
361 }
362 }
363}