netlink_packet_route/link/sriov/
vf_port.rs
1use anyhow::Context;
4use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer, NlasIterator};
5use netlink_packet_utils::{DecodeError, Emitable, Parseable};
6
7#[derive(Debug, Clone, Eq, PartialEq)]
8pub(crate) struct VecLinkVfPort(pub(crate) Vec<LinkVfPort>);
9
10impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VecLinkVfPort {
11 type Error = DecodeError;
12 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
13 let mut nlas = vec![];
14 for nla in NlasIterator::new(buf.into_inner()) {
15 let nla = &nla.context(format!("invalid IFLA_VF_PORTS value: {:?}", buf.value()))?;
16 if nla.kind() == IFLA_VF_PORT {
17 nlas.push(LinkVfPort::parse(&NlaBuffer::new_checked(nla.value())?)?);
18 } else {
19 log::warn!(
20 "BUG: Expecting IFLA_VF_PORT in IFLA_VF_PORTS, \
21 but got {}",
22 nla.kind()
23 );
24 }
25 }
26 Ok(Self(nlas))
27 }
28}
29
30const IFLA_VF_PORT: u16 = 1;
31
32#[derive(Debug, Clone, Default, Eq, PartialEq)]
33pub struct LinkVfPort(pub Vec<VfPort>);
34
35impl Nla for LinkVfPort {
36 fn value_len(&self) -> usize {
37 self.0.as_slice().buffer_len()
38 }
39
40 fn emit_value(&self, buffer: &mut [u8]) {
41 self.0.as_slice().emit(buffer)
42 }
43
44 fn kind(&self) -> u16 {
45 IFLA_VF_PORT
46 }
47}
48
49impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for LinkVfPort {
50 type Error = DecodeError;
51 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
52 let mut nlas = vec![];
53 for nla in NlasIterator::new(buf.into_inner()) {
54 let nla = &nla.context(format!("invalid IFLA_VF_PORT value {:?}", buf.value()))?;
55 nlas.push(VfPort::parse(nla)?);
56 }
57 Ok(Self(nlas))
58 }
59}
60
61#[derive(Debug, Clone, Eq, PartialEq)]
75#[non_exhaustive]
76pub enum VfPort {
77 Other(DefaultNla),
83}
84
85impl Nla for VfPort {
86 fn value_len(&self) -> usize {
87 match self {
88 Self::Other(v) => v.value_len(),
89 }
90 }
91
92 fn emit_value(&self, buffer: &mut [u8]) {
93 match self {
94 Self::Other(attr) => attr.emit_value(buffer),
95 }
96 }
97
98 fn kind(&self) -> u16 {
99 match self {
100 Self::Other(v) => v.kind(),
101 }
102 }
103}
104
105impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VfPort {
106 type Error = DecodeError;
107 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
108 let payload = buf.value();
109 #[allow(clippy::match_single_binding)]
110 Ok(match buf.kind() {
111 kind => Self::Other(
112 DefaultNla::parse(buf)
113 .context(format!("failed to parse {kind} as DefaultNla: {payload:?}"))?,
114 ),
115 })
116 }
117}