netlink_packet_route/link/sriov/
vf_port.rs

1// SPDX-License-Identifier: MIT
2
3use 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/*
62const IFLA_PORT_VF: u16 = 1;
63const IFLA_PORT_PROFILE: u16 = 2;
64// No kernel code is accepting or generating IFLA_PORT_VSI_TYPE.
65// const IFLA_PORT_VSI_TYPE: u16 = 3;
66const IFLA_PORT_INSTANCE_UUID: u16 = 4;
67const IFLA_PORT_HOST_UUID: u16 = 5;
68const IFLA_PORT_REQUEST: u16 = 6;
69const IFLA_PORT_RESPONSE: u16 = 7;
70
71const UUID_LEN: usize = 16;
72*/
73
74#[derive(Debug, Clone, Eq, PartialEq)]
75#[non_exhaustive]
76pub enum VfPort {
77    //    Vf(u32),
78    //    Profile(String),
79    //    InstanceUuid([u8; UUID_LEN]),
80    //    HostUuid([u8; UUID_LEN]),
81    //    Request(u8),
82    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}