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