netlink_packet_route/link/link_info/
info_data.rs
1use 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}