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