netlink_packet_route/link/sriov/
vf_list.rs
1use 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}