netlink_packet_route/link/link_info/
info_data.rs

1// SPDX-License-Identifier: MIT
2
3use 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}