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