netlink_packet_route/link/sriov/
vf_vlan.rs
1use anyhow::Context;
4use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer};
5use netlink_packet_utils::{DecodeError, Emitable, Parseable};
6
7use crate::link::VlanProtocol;
8
9const IFLA_VF_VLAN_INFO: u16 = 1;
10
11#[derive(Debug, Clone, Eq, PartialEq)]
12#[non_exhaustive]
13pub enum VfVlan {
14 Info(VfVlanInfo),
15 Other(DefaultNla),
16}
17
18impl Nla for VfVlan {
19 fn value_len(&self) -> usize {
20 match self {
21 Self::Info(v) => v.buffer_len(),
22 Self::Other(v) => v.value_len(),
23 }
24 }
25
26 fn emit_value(&self, buffer: &mut [u8]) {
27 match self {
28 Self::Info(v) => v.emit(buffer),
29 Self::Other(attr) => attr.emit_value(buffer),
30 }
31 }
32
33 fn kind(&self) -> u16 {
34 match self {
35 Self::Info(_) => IFLA_VF_VLAN_INFO,
36 Self::Other(v) => v.kind(),
37 }
38 }
39}
40
41impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VfVlan {
42 type Error = DecodeError;
43 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
44 let payload = buf.value();
45 Ok(match buf.kind() {
46 IFLA_VF_VLAN_INFO => Self::Info(
47 VfVlanInfo::parse(&VfVlanInfoBuffer::new(payload))
48 .context(format!("invalid IFLA_VF_VLAN_INFO {payload:?}"))?,
49 ),
50 kind => Self::Other(
51 DefaultNla::parse(buf)
52 .context(format!("failed to parse {kind} as DefaultNla: {payload:?}"))?,
53 ),
54 })
55 }
56}
57
58const VF_VLAN_INFO_LEN: usize = 16; #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
61#[non_exhaustive]
62pub struct VfVlanInfo {
63 pub vf_id: u32,
64 pub vlan_id: u32,
65 pub qos: u32,
66 pub protocol: VlanProtocol,
67}
68
69impl VfVlanInfo {
70 pub fn new(vf_id: u32, vlan_id: u32, qos: u32, protocol: VlanProtocol) -> Self {
71 Self { vf_id, vlan_id, qos, protocol }
72 }
73}
74
75buffer!(VfVlanInfoBuffer(VF_VLAN_INFO_LEN) {
76 vf_id: (u32, 0..4),
77 vlan_id: (u32, 4..8),
78 qos: (u32, 8..12),
79 protocol: (u16, 12..14),
80});
81
82impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<VfVlanInfoBuffer<&'a T>> for VfVlanInfo {
83 type Error = DecodeError;
84 fn parse(buf: &VfVlanInfoBuffer<&T>) -> Result<Self, DecodeError> {
85 Ok(Self {
86 vf_id: buf.vf_id(),
87 vlan_id: buf.vlan_id(),
88 qos: buf.qos(),
89 protocol: u16::from_be(buf.protocol()).into(),
90 })
91 }
92}
93
94impl Emitable for VfVlanInfo {
95 fn buffer_len(&self) -> usize {
96 VF_VLAN_INFO_LEN
97 }
98
99 fn emit(&self, buffer: &mut [u8]) {
100 let mut buffer = VfVlanInfoBuffer::new(buffer);
101 buffer.set_vf_id(self.vf_id);
102 buffer.set_vlan_id(self.vlan_id);
103 buffer.set_qos(self.qos);
104 buffer.set_protocol(u16::from(self.protocol).to_be());
105 }
106}