netlink_packet_route/link/sriov/
vf_port.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use netlink_packet_utils::{
5    nla::{DefaultNla, Nla, NlaBuffer, NlasIterator},
6    DecodeError, Emitable, Parseable,
7};
8
9#[derive(Debug, Clone, Eq, PartialEq)]
10pub(crate) struct VecLinkVfPort(pub(crate) Vec<LinkVfPort>);
11
12impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
13    for VecLinkVfPort
14{
15    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
16        let mut nlas = vec![];
17        for nla in NlasIterator::new(buf.into_inner()) {
18            let nla = &nla.context(format!(
19                "invalid IFLA_VF_PORTS value: {:?}",
20                buf.value()
21            ))?;
22            if nla.kind() == IFLA_VF_PORT {
23                nlas.push(LinkVfPort::parse(&NlaBuffer::new_checked(
24                    nla.value(),
25                )?)?);
26            } else {
27                log::warn!(
28                    "BUG: Expecting IFLA_VF_PORT in IFLA_VF_PORTS, \
29                    but got {}",
30                    nla.kind()
31                );
32            }
33        }
34        Ok(Self(nlas))
35    }
36}
37
38const IFLA_VF_PORT: u16 = 1;
39
40#[derive(Debug, Clone, Default, Eq, PartialEq)]
41pub struct LinkVfPort(pub Vec<VfPort>);
42
43impl Nla for LinkVfPort {
44    fn value_len(&self) -> usize {
45        self.0.as_slice().buffer_len()
46    }
47
48    fn emit_value(&self, buffer: &mut [u8]) {
49        self.0.as_slice().emit(buffer)
50    }
51
52    fn kind(&self) -> u16 {
53        IFLA_VF_PORT
54    }
55}
56
57impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for LinkVfPort {
58    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
59        let mut nlas = vec![];
60        for nla in NlasIterator::new(buf.into_inner()) {
61            let nla = &nla.context(format!(
62                "invalid IFLA_VF_PORT value {:?}",
63                buf.value()
64            ))?;
65            nlas.push(VfPort::parse(nla)?);
66        }
67        Ok(Self(nlas))
68    }
69}
70
71/*
72const IFLA_PORT_VF: u16 = 1;
73const IFLA_PORT_PROFILE: u16 = 2;
74// No kernel code is accepting or generating IFLA_PORT_VSI_TYPE.
75// const IFLA_PORT_VSI_TYPE: u16 = 3;
76const IFLA_PORT_INSTANCE_UUID: u16 = 4;
77const IFLA_PORT_HOST_UUID: u16 = 5;
78const IFLA_PORT_REQUEST: u16 = 6;
79const IFLA_PORT_RESPONSE: u16 = 7;
80
81const UUID_LEN: usize = 16;
82*/
83
84#[derive(Debug, Clone, Eq, PartialEq)]
85#[non_exhaustive]
86pub enum VfPort {
87    //    Vf(u32),
88    //    Profile(String),
89    //    InstanceUuid([u8; UUID_LEN]),
90    //    HostUuid([u8; UUID_LEN]),
91    //    Request(u8),
92    Other(DefaultNla),
93}
94
95impl Nla for VfPort {
96    fn value_len(&self) -> usize {
97        match self {
98            Self::Other(v) => v.value_len(),
99        }
100    }
101
102    fn emit_value(&self, buffer: &mut [u8]) {
103        match self {
104            Self::Other(attr) => attr.emit_value(buffer),
105        }
106    }
107
108    fn kind(&self) -> u16 {
109        match self {
110            Self::Other(v) => v.kind(),
111        }
112    }
113}
114
115impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VfPort {
116    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
117        let payload = buf.value();
118        #[allow(clippy::match_single_binding)]
119        Ok(match buf.kind() {
120            kind => Self::Other(DefaultNla::parse(buf).context(format!(
121                "failed to parse {kind} as DefaultNla: {payload:?}"
122            ))?),
123        })
124    }
125}