netlink_packet_route/link/sriov/
vf_vlan.rs1use netlink_packet_core::{
4 DecodeError, DefaultNla, Emitable, ErrorContext, Nla, NlaBuffer, Parseable,
5};
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 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
43 let payload = buf.value();
44 Ok(match buf.kind() {
45 IFLA_VF_VLAN_INFO => Self::Info(
46 VfVlanInfo::parse(&VfVlanInfoBuffer::new(payload)).context(
47 format!("invalid IFLA_VF_VLAN_INFO {payload:?}"),
48 )?,
49 ),
50 kind => Self::Other(DefaultNla::parse(buf).context(format!(
51 "failed to parse {kind} as DefaultNla: {payload:?}"
52 ))?),
53 })
54 }
55}
56
57const VF_VLAN_INFO_LEN: usize = 16; #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
60#[non_exhaustive]
61pub struct VfVlanInfo {
62 pub vf_id: u32,
63 pub vlan_id: u32,
64 pub qos: u32,
65 pub protocol: VlanProtocol,
66}
67
68impl VfVlanInfo {
69 pub fn new(
70 vf_id: u32,
71 vlan_id: u32,
72 qos: u32,
73 protocol: VlanProtocol,
74 ) -> Self {
75 Self {
76 vf_id,
77 vlan_id,
78 qos,
79 protocol,
80 }
81 }
82}
83
84buffer!(VfVlanInfoBuffer(VF_VLAN_INFO_LEN) {
85 vf_id: (u32, 0..4),
86 vlan_id: (u32, 4..8),
87 qos: (u32, 8..12),
88 protocol: (u16, 12..14),
89});
90
91impl<T: AsRef<[u8]> + ?Sized> Parseable<VfVlanInfoBuffer<&T>> for VfVlanInfo {
92 fn parse(buf: &VfVlanInfoBuffer<&T>) -> Result<Self, DecodeError> {
93 Ok(Self {
94 vf_id: buf.vf_id(),
95 vlan_id: buf.vlan_id(),
96 qos: buf.qos(),
97 protocol: u16::from_be(buf.protocol()).into(),
98 })
99 }
100}
101
102impl Emitable for VfVlanInfo {
103 fn buffer_len(&self) -> usize {
104 VF_VLAN_INFO_LEN
105 }
106
107 fn emit(&self, buffer: &mut [u8]) {
108 let mut buffer = VfVlanInfoBuffer::new(buffer);
109 buffer.set_vf_id(self.vf_id);
110 buffer.set_vlan_id(self.vlan_id);
111 buffer.set_qos(self.qos);
112 buffer.set_protocol(u16::from(self.protocol).to_be());
113 }
114}