netlink_packet_route/link/link_info/
info_data.rs

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