netlink_packet_route/link/link_info/
info_data.rs1use anyhow::Context;
4
5use netlink_packet_utils::{
6 nla::{Nla, NlaBuffer, NlasIterator},
7 DecodeError, Emitable, Parseable,
8};
9
10use super::super::{
11 InfoBond, InfoBridge, InfoGeneve, InfoGreTap, InfoGreTap6, InfoGreTun,
12 InfoGreTun6, InfoGtp, InfoHsr, InfoIpVlan, InfoIpVtap, InfoIpoib, InfoKind,
13 InfoMacSec, InfoMacVlan, InfoMacVtap, InfoSitTun, InfoTun, InfoVeth,
14 InfoVlan, InfoVrf, InfoVti, InfoVxlan, InfoXfrm,
15};
16
17const IFLA_INFO_DATA: u16 = 2;
18
19#[derive(Debug, PartialEq, Eq, Clone)]
20#[non_exhaustive]
21pub enum InfoData {
22 Bridge(Vec<InfoBridge>),
23 Tun(Vec<InfoTun>),
24 Vlan(Vec<InfoVlan>),
25 Veth(InfoVeth),
26 Vxlan(Vec<InfoVxlan>),
27 Bond(Vec<InfoBond>),
28 IpVlan(Vec<InfoIpVlan>),
29 IpVtap(Vec<InfoIpVtap>),
30 MacVlan(Vec<InfoMacVlan>),
31 MacVtap(Vec<InfoMacVtap>),
32 GreTap(Vec<InfoGreTap>),
33 GreTap6(Vec<InfoGreTap6>),
34 SitTun(Vec<InfoSitTun>),
35 GreTun(Vec<InfoGreTun>),
36 GreTun6(Vec<InfoGreTun6>),
37 Vti(Vec<InfoVti>),
38 Vrf(Vec<InfoVrf>),
39 Gtp(Vec<InfoGtp>),
40 Ipoib(Vec<InfoIpoib>),
41 Xfrm(Vec<InfoXfrm>),
42 MacSec(Vec<InfoMacSec>),
43 Hsr(Vec<InfoHsr>),
44 Geneve(Vec<InfoGeneve>),
45 Other(Vec<u8>),
46}
47
48impl Nla for InfoData {
49 fn value_len(&self) -> usize {
50 match self {
51 Self::Bond(nlas) => nlas.as_slice().buffer_len(),
52 Self::Bridge(nlas) => nlas.as_slice().buffer_len(),
53 Self::Vlan(nlas) => nlas.as_slice().buffer_len(),
54 Self::Veth(msg) => msg.buffer_len(),
55 Self::IpVlan(nlas) => nlas.as_slice().buffer_len(),
56 Self::IpVtap(nlas) => nlas.as_slice().buffer_len(),
57 Self::Ipoib(nlas) => nlas.as_slice().buffer_len(),
58 Self::MacVlan(nlas) => nlas.as_slice().buffer_len(),
59 Self::MacVtap(nlas) => nlas.as_slice().buffer_len(),
60 Self::Vrf(nlas) => nlas.as_slice().buffer_len(),
61 Self::Vxlan(nlas) => nlas.as_slice().buffer_len(),
62 Self::Xfrm(nlas) => nlas.as_slice().buffer_len(),
63 Self::MacSec(nlas) => nlas.as_slice().buffer_len(),
64 Self::Hsr(nlas) => nlas.as_slice().buffer_len(),
65 Self::Tun(nlas) => nlas.as_slice().buffer_len(),
66 Self::GreTap(nlas) => nlas.as_slice().buffer_len(),
67 Self::GreTap6(nlas) => nlas.as_slice().buffer_len(),
68 Self::SitTun(nlas) => nlas.as_slice().buffer_len(),
69 Self::GreTun(nlas) => nlas.as_slice().buffer_len(),
70 Self::GreTun6(nlas) => nlas.as_slice().buffer_len(),
71 Self::Vti(nlas) => nlas.as_slice().buffer_len(),
72 Self::Gtp(nlas) => nlas.as_slice().buffer_len(),
73 Self::Geneve(nlas) => nlas.as_slice().buffer_len(),
74 Self::Other(v) => v.len(),
75 }
76 }
77
78 fn emit_value(&self, buffer: &mut [u8]) {
79 match self {
80 Self::Bond(nlas) => nlas.as_slice().emit(buffer),
81 Self::Bridge(nlas) => nlas.as_slice().emit(buffer),
82 Self::Vlan(nlas) => nlas.as_slice().emit(buffer),
83 Self::Veth(msg) => msg.emit(buffer),
84 Self::IpVlan(nlas) => nlas.as_slice().emit(buffer),
85 Self::IpVtap(nlas) => nlas.as_slice().emit(buffer),
86 Self::Ipoib(nlas) => nlas.as_slice().emit(buffer),
87 Self::MacVlan(nlas) => nlas.as_slice().emit(buffer),
88 Self::MacVtap(nlas) => nlas.as_slice().emit(buffer),
89 Self::Vrf(nlas) => nlas.as_slice().emit(buffer),
90 Self::Vxlan(nlas) => nlas.as_slice().emit(buffer),
91 Self::Xfrm(nlas) => nlas.as_slice().emit(buffer),
92 Self::MacSec(nlas) => nlas.as_slice().emit(buffer),
93 Self::Hsr(nlas) => nlas.as_slice().emit(buffer),
94 Self::Tun(nlas) => nlas.as_slice().emit(buffer),
95 Self::GreTap(nlas) => nlas.as_slice().emit(buffer),
96 Self::GreTap6(nlas) => nlas.as_slice().emit(buffer),
97 Self::SitTun(nlas) => nlas.as_slice().emit(buffer),
98 Self::GreTun(nlas) => nlas.as_slice().emit(buffer),
99 Self::GreTun6(nlas) => nlas.as_slice().emit(buffer),
100 Self::Vti(nlas) => nlas.as_slice().emit(buffer),
101 Self::Gtp(nlas) => nlas.as_slice().emit(buffer),
102 Self::Geneve(nlas) => nlas.as_slice().emit(buffer),
103 Self::Other(v) => buffer.copy_from_slice(v.as_slice()),
104 }
105 }
106
107 fn kind(&self) -> u16 {
108 IFLA_INFO_DATA
109 }
110}
111
112impl InfoData {
113 pub(crate) fn parse_with_param(
114 payload: &[u8],
115 kind: &InfoKind,
116 ) -> Result<InfoData, DecodeError> {
117 Ok(match kind {
118 InfoKind::Bridge => {
119 let mut v = Vec::new();
120 for nla in NlasIterator::new(payload) {
121 let nla = &nla.context(format!(
122 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
123 ))?;
124 let parsed = InfoBridge::parse(nla)?;
125 v.push(parsed);
126 }
127 InfoData::Bridge(v)
128 }
129 InfoKind::Vlan => {
130 let mut v = Vec::new();
131 for nla in NlasIterator::new(payload) {
132 let nla = &nla.context(format!(
133 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
134 ))?;
135 let parsed = InfoVlan::parse(nla)?;
136 v.push(parsed);
137 }
138 InfoData::Vlan(v)
139 }
140 InfoKind::Tun => {
141 let mut nlas = Vec::new();
142 for nla in NlasIterator::new(payload) {
143 let nla = &nla.context(format!(
144 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
145 ))?;
146 let parsed = InfoTun::parse(nla)?;
147 nlas.push(parsed);
148 }
149 InfoData::Tun(nlas)
150 }
151 InfoKind::Veth => {
152 let nla_buf = NlaBuffer::new_checked(&payload).context(
153 format!("invalid IFLA_INFO_DATA for {kind} {payload:?}"),
154 )?;
155 let parsed = InfoVeth::parse(&nla_buf)?;
156 InfoData::Veth(parsed)
157 }
158 InfoKind::Vxlan => {
159 let mut v = Vec::new();
160 for nla in NlasIterator::new(payload) {
161 let nla = &nla.context(format!(
162 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
163 ))?;
164 let parsed = InfoVxlan::parse(nla)?;
165 v.push(parsed);
166 }
167 InfoData::Vxlan(v)
168 }
169 InfoKind::Bond => {
170 let mut v = Vec::new();
171 for nla in NlasIterator::new(payload) {
172 let nla = &nla.context(format!(
173 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
174 ))?;
175 let parsed = InfoBond::parse(nla)?;
176 v.push(parsed);
177 }
178 InfoData::Bond(v)
179 }
180 InfoKind::IpVlan => {
181 let mut v = Vec::new();
182 for nla in NlasIterator::new(payload) {
183 let nla = &nla.context(format!(
184 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
185 ))?;
186 let parsed = InfoIpVlan::parse(nla)?;
187 v.push(parsed);
188 }
189 InfoData::IpVlan(v)
190 }
191 InfoKind::IpVtap => {
192 let mut v = Vec::new();
193 for nla in NlasIterator::new(payload) {
194 let nla = &nla.context(format!(
195 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
196 ))?;
197 let parsed = InfoIpVtap::parse(nla)?;
198 v.push(parsed);
199 }
200 InfoData::IpVtap(v)
201 }
202 InfoKind::MacVlan => {
203 let mut v = Vec::new();
204 for nla in NlasIterator::new(payload) {
205 let nla = &nla.context(format!(
206 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
207 ))?;
208 let parsed = InfoMacVlan::parse(nla)?;
209 v.push(parsed);
210 }
211 InfoData::MacVlan(v)
212 }
213 InfoKind::MacVtap => {
214 let mut v = Vec::new();
215 for nla in NlasIterator::new(payload) {
216 let nla = &nla.context(format!(
217 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
218 ))?;
219 let parsed = InfoMacVtap::parse(nla)?;
220 v.push(parsed);
221 }
222 InfoData::MacVtap(v)
223 }
224 InfoKind::GreTap => {
225 let mut v = Vec::new();
226 for nla in NlasIterator::new(payload) {
227 let nla = &nla.context(format!(
228 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
229 ))?;
230 let parsed = InfoGreTap::parse(nla)?;
231 v.push(parsed);
232 }
233 InfoData::GreTap(v)
234 }
235 InfoKind::GreTap6 => {
236 let mut v = Vec::new();
237 for nla in NlasIterator::new(payload) {
238 let nla = &nla.context(format!(
239 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
240 ))?;
241 let parsed = InfoGreTap6::parse(nla)?;
242 v.push(parsed);
243 }
244 InfoData::GreTap6(v)
245 }
246 InfoKind::SitTun => {
247 let mut v = Vec::new();
248 for nla in NlasIterator::new(payload) {
249 let nla = &nla.context(format!(
250 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
251 ))?;
252 let parsed = InfoSitTun::parse(nla)?;
253 v.push(parsed);
254 }
255 InfoData::SitTun(v)
256 }
257 InfoKind::GreTun => {
258 let mut v = Vec::new();
259 for nla in NlasIterator::new(payload) {
260 let nla = &nla.context(format!(
261 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
262 ))?;
263 let parsed = InfoGreTun::parse(nla)?;
264 v.push(parsed);
265 }
266 InfoData::GreTun(v)
267 }
268 InfoKind::GreTun6 => {
269 let mut v = Vec::new();
270 for nla in NlasIterator::new(payload) {
271 let nla = &nla.context(format!(
272 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
273 ))?;
274 let parsed = InfoGreTun6::parse(nla)?;
275 v.push(parsed);
276 }
277 InfoData::GreTun6(v)
278 }
279 InfoKind::Vti => {
280 let mut v = Vec::new();
281 for nla in NlasIterator::new(payload) {
282 let nla = &nla.context(format!(
283 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
284 ))?;
285 let parsed = InfoVti::parse(nla)?;
286 v.push(parsed);
287 }
288 InfoData::Vti(v)
289 }
290 InfoKind::Vrf => {
291 let mut v = Vec::new();
292 for nla in NlasIterator::new(payload) {
293 let nla = &nla.context(format!(
294 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
295 ))?;
296 let parsed = InfoVrf::parse(nla)?;
297 v.push(parsed);
298 }
299 InfoData::Vrf(v)
300 }
301 InfoKind::Gtp => {
302 let mut v = Vec::new();
303 for nla in NlasIterator::new(payload) {
304 let nla = &nla.context(format!(
305 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
306 ))?;
307 let parsed = InfoGtp::parse(nla)?;
308 v.push(parsed);
309 }
310 InfoData::Gtp(v)
311 }
312 InfoKind::Ipoib => {
313 let mut v = Vec::new();
314 for nla in NlasIterator::new(payload) {
315 let nla = &nla.context(format!(
316 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
317 ))?;
318 let parsed = InfoIpoib::parse(nla)?;
319 v.push(parsed);
320 }
321 InfoData::Ipoib(v)
322 }
323 InfoKind::Xfrm => {
324 let mut v = Vec::new();
325 for nla in NlasIterator::new(payload) {
326 let nla = &nla.context(format!(
327 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
328 ))?;
329 let parsed = InfoXfrm::parse(nla)?;
330 v.push(parsed);
331 }
332 InfoData::Xfrm(v)
333 }
334 InfoKind::MacSec => {
335 let mut v = Vec::new();
336 for nla in NlasIterator::new(payload) {
337 let nla = &nla.context(format!(
338 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
339 ))?;
340 let parsed = InfoMacSec::parse(nla)?;
341 v.push(parsed);
342 }
343 InfoData::MacSec(v)
344 }
345 InfoKind::Hsr => {
346 let mut v = Vec::new();
347 for nla in NlasIterator::new(payload) {
348 let nla = &nla.context(format!(
349 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
350 ))?;
351 let parsed = InfoHsr::parse(nla)?;
352 v.push(parsed);
353 }
354 InfoData::Hsr(v)
355 }
356 InfoKind::Geneve => {
357 let mut v = Vec::new();
358 for nla in NlasIterator::new(payload) {
359 let nla = &nla.context(format!(
360 "invalid IFLA_INFO_DATA for {kind} {payload:?}"
361 ))?;
362 let parsed = InfoGeneve::parse(nla)?;
363 v.push(parsed);
364 }
365 InfoData::Geneve(v)
366 }
367 _ => InfoData::Other(payload.to_vec()),
368 })
369 }
370}