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