netlink_packet_route/link/sriov/
vf_list.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
7use crate::link::{
8    VfInfoBroadcast, VfInfoBroadcastBuffer, VfInfoGuid, VfInfoGuidBuffer, VfInfoLinkState,
9    VfInfoLinkStateBuffer, VfInfoMac, VfInfoMacBuffer, VfInfoRate, VfInfoRateBuffer,
10    VfInfoRssQueryEn, VfInfoRssQueryEnBuffer, VfInfoSpoofCheck, VfInfoSpoofCheckBuffer,
11    VfInfoTrust, VfInfoTrustBuffer, VfInfoTxRate, VfInfoTxRateBuffer, VfInfoVlan, VfInfoVlanBuffer,
12    VfStats, VfVlan,
13};
14
15const IFLA_VF_INFO: u16 = 1;
16
17#[derive(Debug, Clone, Eq, PartialEq)]
18pub(crate) struct VecLinkVfInfo(pub(crate) Vec<LinkVfInfo>);
19
20impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VecLinkVfInfo {
21    type Error = DecodeError;
22    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
23        let mut nlas = vec![];
24        for nla in NlasIterator::new(buf.into_inner()) {
25            let nla = &nla.context(format!("invalid IFLA_VFINFO_LIST value: {:?}", buf.value()))?;
26            if nla.kind() == IFLA_VF_INFO {
27                nlas.push(LinkVfInfo::parse(&NlaBuffer::new_checked(nla.value())?)?);
28            } else {
29                log::warn!(
30                    "BUG: Expecting IFLA_VF_INFO in IFLA_VFINFO_LIST, \
31                    but got {}",
32                    nla.kind()
33                );
34            }
35        }
36        Ok(Self(nlas))
37    }
38}
39
40#[derive(Debug, Clone, Default, Eq, PartialEq)]
41pub struct LinkVfInfo(pub Vec<VfInfo>);
42
43impl Nla for LinkVfInfo {
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_INFO
54    }
55}
56
57impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for LinkVfInfo {
58    type Error = DecodeError;
59    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
60        let mut nlas = vec![];
61        for nla in NlasIterator::new(buf.into_inner()) {
62            let nla = &nla.context(format!("invalid IFLA_VF_INFO value {:?}", buf.value()))?;
63            nlas.push(VfInfo::parse(nla)?);
64        }
65        Ok(Self(nlas))
66    }
67}
68
69const IFLA_VF_MAC: u16 = 1;
70const IFLA_VF_VLAN: u16 = 2;
71const IFLA_VF_TX_RATE: u16 = 3;
72const IFLA_VF_SPOOFCHK: u16 = 4;
73const IFLA_VF_LINK_STATE: u16 = 5;
74const IFLA_VF_RATE: u16 = 6;
75const IFLA_VF_RSS_QUERY_EN: u16 = 7;
76const IFLA_VF_STATS: u16 = 8;
77const IFLA_VF_TRUST: u16 = 9;
78const IFLA_VF_IB_NODE_GUID: u16 = 10;
79const IFLA_VF_IB_PORT_GUID: u16 = 11;
80const IFLA_VF_VLAN_LIST: u16 = 12;
81const IFLA_VF_BROADCAST: u16 = 13;
82
83#[derive(Debug, Clone, Eq, PartialEq)]
84#[non_exhaustive]
85pub enum VfInfo {
86    Mac(VfInfoMac),
87    Broadcast(VfInfoBroadcast),
88    Vlan(VfInfoVlan),
89    Rate(VfInfoRate),
90    TxRate(VfInfoTxRate),
91    SpoofCheck(VfInfoSpoofCheck),
92    LinkState(VfInfoLinkState),
93    RssQueryEn(VfInfoRssQueryEn),
94    Trust(VfInfoTrust),
95    IbNodeGuid(VfInfoGuid),
96    IbPortGuid(VfInfoGuid),
97    VlanList(Vec<VfVlan>),
98    Stats(Vec<VfStats>),
99    Other(DefaultNla),
100}
101
102impl Nla for VfInfo {
103    fn value_len(&self) -> usize {
104        match self {
105            Self::Mac(v) => v.buffer_len(),
106            Self::Vlan(v) => v.buffer_len(),
107            Self::Broadcast(v) => v.buffer_len(),
108            Self::Rate(v) => v.buffer_len(),
109            Self::TxRate(v) => v.buffer_len(),
110            Self::SpoofCheck(v) => v.buffer_len(),
111            Self::LinkState(v) => v.buffer_len(),
112            Self::RssQueryEn(v) => v.buffer_len(),
113            Self::Trust(v) => v.buffer_len(),
114            Self::IbNodeGuid(v) => v.buffer_len(),
115            Self::IbPortGuid(v) => v.buffer_len(),
116            Self::VlanList(v) => v.as_slice().buffer_len(),
117            Self::Stats(v) => v.as_slice().buffer_len(),
118            Self::Other(v) => v.value_len(),
119        }
120    }
121
122    fn emit_value(&self, buffer: &mut [u8]) {
123        match self {
124            Self::Mac(v) => v.emit(buffer),
125            Self::Vlan(v) => v.emit(buffer),
126            Self::Broadcast(v) => v.emit(buffer),
127            Self::Rate(v) => v.emit(buffer),
128            Self::TxRate(v) => v.emit(buffer),
129            Self::SpoofCheck(v) => v.emit(buffer),
130            Self::LinkState(v) => v.emit(buffer),
131            Self::RssQueryEn(v) => v.emit(buffer),
132            Self::Trust(v) => v.emit(buffer),
133            Self::IbNodeGuid(v) => v.emit(buffer),
134            Self::IbPortGuid(v) => v.emit(buffer),
135            Self::VlanList(v) => v.as_slice().emit(buffer),
136            Self::Stats(v) => v.as_slice().emit(buffer),
137            Self::Other(attr) => attr.emit_value(buffer),
138        }
139    }
140
141    fn kind(&self) -> u16 {
142        match self {
143            Self::Mac(_) => IFLA_VF_MAC,
144            Self::Vlan(_) => IFLA_VF_VLAN,
145            Self::Broadcast(_) => IFLA_VF_BROADCAST,
146            Self::Rate(_) => IFLA_VF_RATE,
147            Self::TxRate(_) => IFLA_VF_TX_RATE,
148            Self::SpoofCheck(_) => IFLA_VF_SPOOFCHK,
149            Self::LinkState(_) => IFLA_VF_LINK_STATE,
150            Self::RssQueryEn(_) => IFLA_VF_RSS_QUERY_EN,
151            Self::Trust(_) => IFLA_VF_TRUST,
152            Self::IbNodeGuid(_) => IFLA_VF_IB_NODE_GUID,
153            Self::IbPortGuid(_) => IFLA_VF_IB_PORT_GUID,
154            Self::VlanList(_) => IFLA_VF_VLAN_LIST,
155            Self::Stats(_) => IFLA_VF_STATS,
156            Self::Other(v) => v.kind(),
157        }
158    }
159}
160
161impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VfInfo {
162    type Error = DecodeError;
163    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
164        let payload = buf.value();
165        Ok(match buf.kind() {
166            IFLA_VF_MAC => Self::Mac(
167                VfInfoMac::parse(&VfInfoMacBuffer::new(payload))
168                    .context(format!("invalid IFLA_VF_MAC {payload:?}"))?,
169            ),
170            IFLA_VF_VLAN => Self::Vlan(
171                VfInfoVlan::parse(&VfInfoVlanBuffer::new(payload))
172                    .context(format!("invalid IFLA_VF_VLAN {payload:?}"))?,
173            ),
174            IFLA_VF_BROADCAST => Self::Broadcast(
175                VfInfoBroadcast::parse(&VfInfoBroadcastBuffer::new(payload))
176                    .context(format!("invalid IFLA_VF_BROADCAST {payload:?}"))?,
177            ),
178            IFLA_VF_RATE => Self::Rate(
179                VfInfoRate::parse(&VfInfoRateBuffer::new(payload))
180                    .context(format!("invalid IFLA_VF_RATE {payload:?}"))?,
181            ),
182            IFLA_VF_TX_RATE => Self::TxRate(
183                VfInfoTxRate::parse(&VfInfoTxRateBuffer::new(payload))
184                    .context(format!("invalid IFLA_VF_TX_RATE {payload:?}"))?,
185            ),
186            IFLA_VF_SPOOFCHK => Self::SpoofCheck(
187                VfInfoSpoofCheck::parse(&VfInfoSpoofCheckBuffer::new(payload))
188                    .context(format!("invalid IFLA_VF_SPOOFCHK {payload:?}"))?,
189            ),
190            IFLA_VF_LINK_STATE => Self::LinkState(
191                VfInfoLinkState::parse(&VfInfoLinkStateBuffer::new(payload))
192                    .context(format!("invalid IFLA_VF_LINK_STATE {payload:?}"))?,
193            ),
194            IFLA_VF_RSS_QUERY_EN => Self::RssQueryEn(
195                VfInfoRssQueryEn::parse(&VfInfoRssQueryEnBuffer::new(payload))
196                    .context(format!("invalid IFLA_VF_RSS_QUERY_EN {payload:?}"))?,
197            ),
198            IFLA_VF_TRUST => Self::Trust(
199                VfInfoTrust::parse(&VfInfoTrustBuffer::new(payload))
200                    .context(format!("invalid IFLA_VF_TRUST {payload:?}"))?,
201            ),
202            IFLA_VF_IB_NODE_GUID => Self::IbNodeGuid(
203                VfInfoGuid::parse(&VfInfoGuidBuffer::new(payload))
204                    .context(format!("invalid IFLA_VF_IB_NODE_GUID {payload:?}"))?,
205            ),
206            IFLA_VF_IB_PORT_GUID => Self::IbPortGuid(
207                VfInfoGuid::parse(&VfInfoGuidBuffer::new(payload))
208                    .context(format!("invalid IFLA_VF_IB_PORT_GUID {payload:?}"))?,
209            ),
210            IFLA_VF_VLAN_LIST => {
211                let mut nlas: Vec<VfVlan> = Vec::new();
212                for nla in NlasIterator::new(payload) {
213                    let nla = &nla
214                        .context(format!("invalid IFLA_VF_VLAN_LIST value: {:?}", buf.value()))?;
215
216                    nlas.push(VfVlan::parse(nla)?);
217                }
218                Self::VlanList(nlas)
219            }
220            IFLA_VF_STATS => {
221                let mut nlas: Vec<VfStats> = Vec::new();
222                for nla in NlasIterator::new(payload) {
223                    let nla =
224                        &nla.context(format!("invalid IFLA_VF_STATS value: {:?}", buf.value()))?;
225
226                    nlas.push(VfStats::parse(nla)?);
227                }
228                Self::Stats(nlas)
229            }
230            kind => Self::Other(
231                DefaultNla::parse(buf)
232                    .context(format!("failed to parse {kind} as DefaultNla: {payload:?}"))?,
233            ),
234        })
235    }
236}