netlink_packet_route/link/link_info/
info_data.rs

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