1#![doc = "Link configuration over rtnetlink.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "rt-link";
17pub const PROTONAME_CSTR: &CStr = c"rt-link";
18pub const PROTONUM: u16 = 0u16;
19#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
20#[derive(Debug, Clone, Copy)]
21pub enum IfinfoFlags {
22 Up = 1 << 0,
23 Broadcast = 1 << 1,
24 Debug = 1 << 2,
25 Loopback = 1 << 3,
26 PointToPoint = 1 << 4,
27 NoTrailers = 1 << 5,
28 Running = 1 << 6,
29 NoArp = 1 << 7,
30 Promisc = 1 << 8,
31 AllMulti = 1 << 9,
32 Master = 1 << 10,
33 Slave = 1 << 11,
34 Multicast = 1 << 12,
35 Portsel = 1 << 13,
36 AutoMedia = 1 << 14,
37 Dynamic = 1 << 15,
38 LowerUp = 1 << 16,
39 Dormant = 1 << 17,
40 Echo = 1 << 18,
41}
42impl IfinfoFlags {
43 pub fn from_value(value: u64) -> Option<Self> {
44 Some(match value {
45 n if n == 1 << 0 => Self::Up,
46 n if n == 1 << 1 => Self::Broadcast,
47 n if n == 1 << 2 => Self::Debug,
48 n if n == 1 << 3 => Self::Loopback,
49 n if n == 1 << 4 => Self::PointToPoint,
50 n if n == 1 << 5 => Self::NoTrailers,
51 n if n == 1 << 6 => Self::Running,
52 n if n == 1 << 7 => Self::NoArp,
53 n if n == 1 << 8 => Self::Promisc,
54 n if n == 1 << 9 => Self::AllMulti,
55 n if n == 1 << 10 => Self::Master,
56 n if n == 1 << 11 => Self::Slave,
57 n if n == 1 << 12 => Self::Multicast,
58 n if n == 1 << 13 => Self::Portsel,
59 n if n == 1 << 14 => Self::AutoMedia,
60 n if n == 1 << 15 => Self::Dynamic,
61 n if n == 1 << 16 => Self::LowerUp,
62 n if n == 1 << 17 => Self::Dormant,
63 n if n == 1 << 18 => Self::Echo,
64 _ => return None,
65 })
66 }
67}
68#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
69#[derive(Debug, Clone, Copy)]
70pub enum VlanProtocols {
71 _8021q = 33024,
72 _8021ad = 34984,
73}
74impl VlanProtocols {
75 pub fn from_value(value: u64) -> Option<Self> {
76 Some(match value {
77 33024 => Self::_8021q,
78 34984 => Self::_8021ad,
79 _ => return None,
80 })
81 }
82}
83#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
84#[derive(Debug, Clone, Copy)]
85pub enum Ipv4Devconf {
86 Forwarding = 0,
87 McForwarding = 1,
88 ProxyArp = 2,
89 AcceptRedirects = 3,
90 SecureRedirects = 4,
91 SendRedirects = 5,
92 SharedMedia = 6,
93 RpFilter = 7,
94 AcceptSourceRoute = 8,
95 BootpRelay = 9,
96 LogMartians = 10,
97 Tag = 11,
98 Arpfilter = 12,
99 MediumId = 13,
100 Noxfrm = 14,
101 Nopolicy = 15,
102 ForceIgmpVersion = 16,
103 ArpAnnounce = 17,
104 ArpIgnore = 18,
105 PromoteSecondaries = 19,
106 ArpAccept = 20,
107 ArpNotify = 21,
108 AcceptLocal = 22,
109 SrcVmark = 23,
110 ProxyArpPvlan = 24,
111 RouteLocalnet = 25,
112 Igmpv2UnsolicitedReportInterval = 26,
113 Igmpv3UnsolicitedReportInterval = 27,
114 IgnoreRoutesWithLinkdown = 28,
115 DropUnicastInL2Multicast = 29,
116 DropGratuitousArp = 30,
117 BcForwarding = 31,
118 ArpEvictNocarrier = 32,
119}
120impl Ipv4Devconf {
121 pub fn from_value(value: u64) -> Option<Self> {
122 Some(match value {
123 0 => Self::Forwarding,
124 1 => Self::McForwarding,
125 2 => Self::ProxyArp,
126 3 => Self::AcceptRedirects,
127 4 => Self::SecureRedirects,
128 5 => Self::SendRedirects,
129 6 => Self::SharedMedia,
130 7 => Self::RpFilter,
131 8 => Self::AcceptSourceRoute,
132 9 => Self::BootpRelay,
133 10 => Self::LogMartians,
134 11 => Self::Tag,
135 12 => Self::Arpfilter,
136 13 => Self::MediumId,
137 14 => Self::Noxfrm,
138 15 => Self::Nopolicy,
139 16 => Self::ForceIgmpVersion,
140 17 => Self::ArpAnnounce,
141 18 => Self::ArpIgnore,
142 19 => Self::PromoteSecondaries,
143 20 => Self::ArpAccept,
144 21 => Self::ArpNotify,
145 22 => Self::AcceptLocal,
146 23 => Self::SrcVmark,
147 24 => Self::ProxyArpPvlan,
148 25 => Self::RouteLocalnet,
149 26 => Self::Igmpv2UnsolicitedReportInterval,
150 27 => Self::Igmpv3UnsolicitedReportInterval,
151 28 => Self::IgnoreRoutesWithLinkdown,
152 29 => Self::DropUnicastInL2Multicast,
153 30 => Self::DropGratuitousArp,
154 31 => Self::BcForwarding,
155 32 => Self::ArpEvictNocarrier,
156 _ => return None,
157 })
158 }
159}
160#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
161#[derive(Debug, Clone, Copy)]
162pub enum Ipv6Devconf {
163 Forwarding = 0,
164 Hoplimit = 1,
165 Mtu6 = 2,
166 AcceptRa = 3,
167 AcceptRedirects = 4,
168 Autoconf = 5,
169 DadTransmits = 6,
170 RtrSolicits = 7,
171 RtrSolicitInterval = 8,
172 RtrSolicitDelay = 9,
173 UseTempaddr = 10,
174 TempValidLft = 11,
175 TempPreferedLft = 12,
176 RegenMaxRetry = 13,
177 MaxDesyncFactor = 14,
178 MaxAddresses = 15,
179 ForceMldVersion = 16,
180 AcceptRaDefrtr = 17,
181 AcceptRaPinfo = 18,
182 AcceptRaRtrPref = 19,
183 RtrProbeInterval = 20,
184 AcceptRaRtInfoMaxPlen = 21,
185 ProxyNdp = 22,
186 OptimisticDad = 23,
187 AcceptSourceRoute = 24,
188 McForwarding = 25,
189 DisableIpv6 = 26,
190 AcceptDad = 27,
191 ForceTllao = 28,
192 NdiscNotify = 29,
193 Mldv1UnsolicitedReportInterval = 30,
194 Mldv2UnsolicitedReportInterval = 31,
195 SuppressFragNdisc = 32,
196 AcceptRaFromLocal = 33,
197 UseOptimistic = 34,
198 AcceptRaMtu = 35,
199 StableSecret = 36,
200 UseOifAddrsOnly = 37,
201 AcceptRaMinHopLimit = 38,
202 IgnoreRoutesWithLinkdown = 39,
203 DropUnicastInL2Multicast = 40,
204 DropUnsolicitedNa = 41,
205 KeepAddrOnDown = 42,
206 RtrSolicitMaxInterval = 43,
207 Seg6Enabled = 44,
208 Seg6RequireHmac = 45,
209 EnhancedDad = 46,
210 AddrGenMode = 47,
211 DisablePolicy = 48,
212 AcceptRaRtInfoMinPlen = 49,
213 NdiscTclass = 50,
214 RplSegEnabled = 51,
215 RaDefrtrMetric = 52,
216 Ioam6Enabled = 53,
217 Ioam6Id = 54,
218 Ioam6IdWide = 55,
219 NdiscEvictNocarrier = 56,
220 AcceptUntrackedNa = 57,
221}
222impl Ipv6Devconf {
223 pub fn from_value(value: u64) -> Option<Self> {
224 Some(match value {
225 0 => Self::Forwarding,
226 1 => Self::Hoplimit,
227 2 => Self::Mtu6,
228 3 => Self::AcceptRa,
229 4 => Self::AcceptRedirects,
230 5 => Self::Autoconf,
231 6 => Self::DadTransmits,
232 7 => Self::RtrSolicits,
233 8 => Self::RtrSolicitInterval,
234 9 => Self::RtrSolicitDelay,
235 10 => Self::UseTempaddr,
236 11 => Self::TempValidLft,
237 12 => Self::TempPreferedLft,
238 13 => Self::RegenMaxRetry,
239 14 => Self::MaxDesyncFactor,
240 15 => Self::MaxAddresses,
241 16 => Self::ForceMldVersion,
242 17 => Self::AcceptRaDefrtr,
243 18 => Self::AcceptRaPinfo,
244 19 => Self::AcceptRaRtrPref,
245 20 => Self::RtrProbeInterval,
246 21 => Self::AcceptRaRtInfoMaxPlen,
247 22 => Self::ProxyNdp,
248 23 => Self::OptimisticDad,
249 24 => Self::AcceptSourceRoute,
250 25 => Self::McForwarding,
251 26 => Self::DisableIpv6,
252 27 => Self::AcceptDad,
253 28 => Self::ForceTllao,
254 29 => Self::NdiscNotify,
255 30 => Self::Mldv1UnsolicitedReportInterval,
256 31 => Self::Mldv2UnsolicitedReportInterval,
257 32 => Self::SuppressFragNdisc,
258 33 => Self::AcceptRaFromLocal,
259 34 => Self::UseOptimistic,
260 35 => Self::AcceptRaMtu,
261 36 => Self::StableSecret,
262 37 => Self::UseOifAddrsOnly,
263 38 => Self::AcceptRaMinHopLimit,
264 39 => Self::IgnoreRoutesWithLinkdown,
265 40 => Self::DropUnicastInL2Multicast,
266 41 => Self::DropUnsolicitedNa,
267 42 => Self::KeepAddrOnDown,
268 43 => Self::RtrSolicitMaxInterval,
269 44 => Self::Seg6Enabled,
270 45 => Self::Seg6RequireHmac,
271 46 => Self::EnhancedDad,
272 47 => Self::AddrGenMode,
273 48 => Self::DisablePolicy,
274 49 => Self::AcceptRaRtInfoMinPlen,
275 50 => Self::NdiscTclass,
276 51 => Self::RplSegEnabled,
277 52 => Self::RaDefrtrMetric,
278 53 => Self::Ioam6Enabled,
279 54 => Self::Ioam6Id,
280 55 => Self::Ioam6IdWide,
281 56 => Self::NdiscEvictNocarrier,
282 57 => Self::AcceptUntrackedNa,
283 _ => return None,
284 })
285 }
286}
287#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
288#[derive(Debug, Clone, Copy)]
289pub enum IflaIcmp6Stats {
290 Num = 0,
291 Inmsgs = 1,
292 Inerrors = 2,
293 Outmsgs = 3,
294 Outerrors = 4,
295 Csumerrors = 5,
296 Ratelimithost = 6,
297}
298impl IflaIcmp6Stats {
299 pub fn from_value(value: u64) -> Option<Self> {
300 Some(match value {
301 0 => Self::Num,
302 1 => Self::Inmsgs,
303 2 => Self::Inerrors,
304 3 => Self::Outmsgs,
305 4 => Self::Outerrors,
306 5 => Self::Csumerrors,
307 6 => Self::Ratelimithost,
308 _ => return None,
309 })
310 }
311}
312#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
313#[derive(Debug, Clone, Copy)]
314pub enum IflaInet6Stats {
315 Num = 0,
316 Inpkts = 1,
317 Inoctets = 2,
318 Indelivers = 3,
319 Outforwdatagrams = 4,
320 Outpkts = 5,
321 Outoctets = 6,
322 Inhdrerrors = 7,
323 Intoobigerrors = 8,
324 Innoroutes = 9,
325 Inaddrerrors = 10,
326 Inunknownprotos = 11,
327 Intruncatedpkts = 12,
328 Indiscards = 13,
329 Outdiscards = 14,
330 Outnoroutes = 15,
331 Reasmtimeout = 16,
332 Reasmreqds = 17,
333 Reasmoks = 18,
334 Reasmfails = 19,
335 Fragoks = 20,
336 Fragfails = 21,
337 Fragcreates = 22,
338 Inmcastpkts = 23,
339 Outmcastpkts = 24,
340 Inbcastpkts = 25,
341 Outbcastpkts = 26,
342 Inmcastoctets = 27,
343 Outmcastoctets = 28,
344 Inbcastoctets = 29,
345 Outbcastoctets = 30,
346 Csumerrors = 31,
347 Noectpkts = 32,
348 Ect1Pkts = 33,
349 Ect0Pkts = 34,
350 Cepkts = 35,
351 ReasmOverlaps = 36,
352}
353impl IflaInet6Stats {
354 pub fn from_value(value: u64) -> Option<Self> {
355 Some(match value {
356 0 => Self::Num,
357 1 => Self::Inpkts,
358 2 => Self::Inoctets,
359 3 => Self::Indelivers,
360 4 => Self::Outforwdatagrams,
361 5 => Self::Outpkts,
362 6 => Self::Outoctets,
363 7 => Self::Inhdrerrors,
364 8 => Self::Intoobigerrors,
365 9 => Self::Innoroutes,
366 10 => Self::Inaddrerrors,
367 11 => Self::Inunknownprotos,
368 12 => Self::Intruncatedpkts,
369 13 => Self::Indiscards,
370 14 => Self::Outdiscards,
371 15 => Self::Outnoroutes,
372 16 => Self::Reasmtimeout,
373 17 => Self::Reasmreqds,
374 18 => Self::Reasmoks,
375 19 => Self::Reasmfails,
376 20 => Self::Fragoks,
377 21 => Self::Fragfails,
378 22 => Self::Fragcreates,
379 23 => Self::Inmcastpkts,
380 24 => Self::Outmcastpkts,
381 25 => Self::Inbcastpkts,
382 26 => Self::Outbcastpkts,
383 27 => Self::Inmcastoctets,
384 28 => Self::Outmcastoctets,
385 29 => Self::Inbcastoctets,
386 30 => Self::Outbcastoctets,
387 31 => Self::Csumerrors,
388 32 => Self::Noectpkts,
389 33 => Self::Ect1Pkts,
390 34 => Self::Ect0Pkts,
391 35 => Self::Cepkts,
392 36 => Self::ReasmOverlaps,
393 _ => return None,
394 })
395 }
396}
397#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
398#[derive(Debug, Clone, Copy)]
399pub enum VlanFlags {
400 ReorderHdr = 1 << 0,
401 Gvrp = 1 << 1,
402 LooseBinding = 1 << 2,
403 Mvrp = 1 << 3,
404 BridgeBinding = 1 << 4,
405}
406impl VlanFlags {
407 pub fn from_value(value: u64) -> Option<Self> {
408 Some(match value {
409 n if n == 1 << 0 => Self::ReorderHdr,
410 n if n == 1 << 1 => Self::Gvrp,
411 n if n == 1 << 2 => Self::LooseBinding,
412 n if n == 1 << 3 => Self::Mvrp,
413 n if n == 1 << 4 => Self::BridgeBinding,
414 _ => return None,
415 })
416 }
417}
418#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
419#[derive(Debug, Clone, Copy)]
420pub enum IflaVfLinkStateEnum {
421 Auto = 0,
422 Enable = 1,
423 Disable = 2,
424}
425impl IflaVfLinkStateEnum {
426 pub fn from_value(value: u64) -> Option<Self> {
427 Some(match value {
428 0 => Self::Auto,
429 1 => Self::Enable,
430 2 => Self::Disable,
431 _ => return None,
432 })
433 }
434}
435#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
436#[derive(Debug, Clone, Copy)]
437pub enum RtextFilter {
438 Vf = 1 << 0,
439 Brvlan = 1 << 1,
440 BrvlanCompressed = 1 << 2,
441 SkipStats = 1 << 3,
442 Mrp = 1 << 4,
443 CfmConfig = 1 << 5,
444 CfmStatus = 1 << 6,
445 Mst = 1 << 7,
446}
447impl RtextFilter {
448 pub fn from_value(value: u64) -> Option<Self> {
449 Some(match value {
450 n if n == 1 << 0 => Self::Vf,
451 n if n == 1 << 1 => Self::Brvlan,
452 n if n == 1 << 2 => Self::BrvlanCompressed,
453 n if n == 1 << 3 => Self::SkipStats,
454 n if n == 1 << 4 => Self::Mrp,
455 n if n == 1 << 5 => Self::CfmConfig,
456 n if n == 1 << 6 => Self::CfmStatus,
457 n if n == 1 << 7 => Self::Mst,
458 _ => return None,
459 })
460 }
461}
462#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
463#[derive(Debug, Clone, Copy)]
464pub enum NetkitPolicy {
465 Forward = 0,
466 Blackhole = 2,
467}
468impl NetkitPolicy {
469 pub fn from_value(value: u64) -> Option<Self> {
470 Some(match value {
471 0 => Self::Forward,
472 2 => Self::Blackhole,
473 _ => return None,
474 })
475 }
476}
477#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
478#[derive(Debug, Clone, Copy)]
479pub enum NetkitMode {
480 L2 = 0,
481 L3 = 1,
482}
483impl NetkitMode {
484 pub fn from_value(value: u64) -> Option<Self> {
485 Some(match value {
486 0 => Self::L2,
487 1 => Self::L3,
488 _ => return None,
489 })
490 }
491}
492#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
493#[derive(Debug, Clone, Copy)]
494pub enum NetkitScrub {
495 None = 0,
496 Default = 1,
497}
498impl NetkitScrub {
499 pub fn from_value(value: u64) -> Option<Self> {
500 Some(match value {
501 0 => Self::None,
502 1 => Self::Default,
503 _ => return None,
504 })
505 }
506}
507#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
508#[derive(Debug, Clone, Copy)]
509pub enum NetkitPairing {
510 Pair = 0,
511 Single = 1,
512}
513impl NetkitPairing {
514 pub fn from_value(value: u64) -> Option<Self> {
515 Some(match value {
516 0 => Self::Pair,
517 1 => Self::Single,
518 _ => return None,
519 })
520 }
521}
522#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
523#[derive(Debug, Clone, Copy)]
524pub enum OvpnMode {
525 P2p = 0,
526 Mp = 1,
527}
528impl OvpnMode {
529 pub fn from_value(value: u64) -> Option<Self> {
530 Some(match value {
531 0 => Self::P2p,
532 1 => Self::Mp,
533 _ => return None,
534 })
535 }
536}
537#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
538#[derive(Debug, Clone, Copy)]
539pub enum BrStpMode {
540 Auto = 0,
541 User = 1,
542 Kernel = 2,
543}
544impl BrStpMode {
545 pub fn from_value(value: u64) -> Option<Self> {
546 Some(match value {
547 0 => Self::Auto,
548 1 => Self::User,
549 2 => Self::Kernel,
550 _ => return None,
551 })
552 }
553}
554#[derive(Debug)]
555#[repr(C, packed(4))]
556pub struct Rtgenmsg {
557 pub family: u8,
558}
559impl Clone for Rtgenmsg {
560 fn clone(&self) -> Self {
561 Self::new_from_array(*self.as_array())
562 }
563}
564#[doc = "Create zero-initialized struct"]
565impl Default for Rtgenmsg {
566 fn default() -> Self {
567 Self::new()
568 }
569}
570impl Rtgenmsg {
571 #[doc = "Create zero-initialized struct"]
572 pub fn new() -> Self {
573 Self::new_from_array([0u8; Self::len()])
574 }
575 #[doc = "Copy from contents from slice"]
576 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
577 if other.len() != Self::len() {
578 return None;
579 }
580 let mut buf = [0u8; Self::len()];
581 buf.clone_from_slice(other);
582 Some(Self::new_from_array(buf))
583 }
584 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
585 pub fn new_from_zeroed(other: &[u8]) -> Self {
586 let mut buf = [0u8; Self::len()];
587 let len = buf.len().min(other.len());
588 buf[..len].clone_from_slice(&other[..len]);
589 Self::new_from_array(buf)
590 }
591 pub fn new_from_array(buf: [u8; 1usize]) -> Self {
592 unsafe { std::mem::transmute(buf) }
593 }
594 pub fn as_slice(&self) -> &[u8] {
595 unsafe {
596 let ptr: *const u8 = std::mem::transmute(self as *const Self);
597 std::slice::from_raw_parts(ptr, Self::len())
598 }
599 }
600 pub fn from_slice(buf: &[u8]) -> &Self {
601 assert!(buf.len() >= Self::len());
602 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
603 unsafe { std::mem::transmute(buf.as_ptr()) }
604 }
605 pub fn as_array(&self) -> &[u8; 1usize] {
606 unsafe { std::mem::transmute(self) }
607 }
608 pub fn from_array(buf: &[u8; 1usize]) -> &Self {
609 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
610 unsafe { std::mem::transmute(buf) }
611 }
612 pub fn into_array(self) -> [u8; 1usize] {
613 unsafe { std::mem::transmute(self) }
614 }
615 pub const fn len() -> usize {
616 const _: () = assert!(std::mem::size_of::<Rtgenmsg>() == 1usize);
617 1usize
618 }
619}
620#[repr(C, packed(4))]
621pub struct Ifinfomsg {
622 pub ifi_family: u8,
623 pub _pad: [u8; 1usize],
624 pub ifi_type: u16,
625 pub ifi_index: i32,
626 #[doc = "Associated type: [`IfinfoFlags`] (1 bit per enumeration)"]
627 pub ifi_flags: u32,
628 pub ifi_change: u32,
629}
630impl Clone for Ifinfomsg {
631 fn clone(&self) -> Self {
632 Self::new_from_array(*self.as_array())
633 }
634}
635#[doc = "Create zero-initialized struct"]
636impl Default for Ifinfomsg {
637 fn default() -> Self {
638 Self::new()
639 }
640}
641impl Ifinfomsg {
642 #[doc = "Create zero-initialized struct"]
643 pub fn new() -> Self {
644 Self::new_from_array([0u8; Self::len()])
645 }
646 #[doc = "Copy from contents from slice"]
647 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
648 if other.len() != Self::len() {
649 return None;
650 }
651 let mut buf = [0u8; Self::len()];
652 buf.clone_from_slice(other);
653 Some(Self::new_from_array(buf))
654 }
655 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
656 pub fn new_from_zeroed(other: &[u8]) -> Self {
657 let mut buf = [0u8; Self::len()];
658 let len = buf.len().min(other.len());
659 buf[..len].clone_from_slice(&other[..len]);
660 Self::new_from_array(buf)
661 }
662 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
663 unsafe { std::mem::transmute(buf) }
664 }
665 pub fn as_slice(&self) -> &[u8] {
666 unsafe {
667 let ptr: *const u8 = std::mem::transmute(self as *const Self);
668 std::slice::from_raw_parts(ptr, Self::len())
669 }
670 }
671 pub fn from_slice(buf: &[u8]) -> &Self {
672 assert!(buf.len() >= Self::len());
673 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
674 unsafe { std::mem::transmute(buf.as_ptr()) }
675 }
676 pub fn as_array(&self) -> &[u8; 16usize] {
677 unsafe { std::mem::transmute(self) }
678 }
679 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
680 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
681 unsafe { std::mem::transmute(buf) }
682 }
683 pub fn into_array(self) -> [u8; 16usize] {
684 unsafe { std::mem::transmute(self) }
685 }
686 pub const fn len() -> usize {
687 const _: () = assert!(std::mem::size_of::<Ifinfomsg>() == 16usize);
688 16usize
689 }
690}
691impl std::fmt::Debug for Ifinfomsg {
692 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
693 fmt.debug_struct("Ifinfomsg")
694 .field("ifi_family", &self.ifi_family)
695 .field("ifi_type", &self.ifi_type)
696 .field("ifi_index", &self.ifi_index)
697 .field(
698 "ifi_flags",
699 &FormatFlags(self.ifi_flags.into(), IfinfoFlags::from_value),
700 )
701 .field("ifi_change", &self.ifi_change)
702 .finish()
703 }
704}
705#[derive(Debug)]
706#[repr(C, packed(4))]
707pub struct IflaBridgeId {
708 pub prio: u16,
709 pub addr: [u8; 6usize],
710}
711impl Clone for IflaBridgeId {
712 fn clone(&self) -> Self {
713 Self::new_from_array(*self.as_array())
714 }
715}
716#[doc = "Create zero-initialized struct"]
717impl Default for IflaBridgeId {
718 fn default() -> Self {
719 Self::new()
720 }
721}
722impl IflaBridgeId {
723 #[doc = "Create zero-initialized struct"]
724 pub fn new() -> Self {
725 Self::new_from_array([0u8; Self::len()])
726 }
727 #[doc = "Copy from contents from slice"]
728 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
729 if other.len() != Self::len() {
730 return None;
731 }
732 let mut buf = [0u8; Self::len()];
733 buf.clone_from_slice(other);
734 Some(Self::new_from_array(buf))
735 }
736 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
737 pub fn new_from_zeroed(other: &[u8]) -> Self {
738 let mut buf = [0u8; Self::len()];
739 let len = buf.len().min(other.len());
740 buf[..len].clone_from_slice(&other[..len]);
741 Self::new_from_array(buf)
742 }
743 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
744 unsafe { std::mem::transmute(buf) }
745 }
746 pub fn as_slice(&self) -> &[u8] {
747 unsafe {
748 let ptr: *const u8 = std::mem::transmute(self as *const Self);
749 std::slice::from_raw_parts(ptr, Self::len())
750 }
751 }
752 pub fn from_slice(buf: &[u8]) -> &Self {
753 assert!(buf.len() >= Self::len());
754 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
755 unsafe { std::mem::transmute(buf.as_ptr()) }
756 }
757 pub fn as_array(&self) -> &[u8; 8usize] {
758 unsafe { std::mem::transmute(self) }
759 }
760 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
761 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
762 unsafe { std::mem::transmute(buf) }
763 }
764 pub fn into_array(self) -> [u8; 8usize] {
765 unsafe { std::mem::transmute(self) }
766 }
767 pub const fn len() -> usize {
768 const _: () = assert!(std::mem::size_of::<IflaBridgeId>() == 8usize);
769 8usize
770 }
771}
772#[derive(Debug)]
773#[repr(C, packed(4))]
774pub struct IflaCacheinfo {
775 pub max_reasm_len: u32,
776 pub tstamp: u32,
777 pub reachable_time: i32,
778 pub retrans_time: u32,
779}
780impl Clone for IflaCacheinfo {
781 fn clone(&self) -> Self {
782 Self::new_from_array(*self.as_array())
783 }
784}
785#[doc = "Create zero-initialized struct"]
786impl Default for IflaCacheinfo {
787 fn default() -> Self {
788 Self::new()
789 }
790}
791impl IflaCacheinfo {
792 #[doc = "Create zero-initialized struct"]
793 pub fn new() -> Self {
794 Self::new_from_array([0u8; Self::len()])
795 }
796 #[doc = "Copy from contents from slice"]
797 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
798 if other.len() != Self::len() {
799 return None;
800 }
801 let mut buf = [0u8; Self::len()];
802 buf.clone_from_slice(other);
803 Some(Self::new_from_array(buf))
804 }
805 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
806 pub fn new_from_zeroed(other: &[u8]) -> Self {
807 let mut buf = [0u8; Self::len()];
808 let len = buf.len().min(other.len());
809 buf[..len].clone_from_slice(&other[..len]);
810 Self::new_from_array(buf)
811 }
812 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
813 unsafe { std::mem::transmute(buf) }
814 }
815 pub fn as_slice(&self) -> &[u8] {
816 unsafe {
817 let ptr: *const u8 = std::mem::transmute(self as *const Self);
818 std::slice::from_raw_parts(ptr, Self::len())
819 }
820 }
821 pub fn from_slice(buf: &[u8]) -> &Self {
822 assert!(buf.len() >= Self::len());
823 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
824 unsafe { std::mem::transmute(buf.as_ptr()) }
825 }
826 pub fn as_array(&self) -> &[u8; 16usize] {
827 unsafe { std::mem::transmute(self) }
828 }
829 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
830 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
831 unsafe { std::mem::transmute(buf) }
832 }
833 pub fn into_array(self) -> [u8; 16usize] {
834 unsafe { std::mem::transmute(self) }
835 }
836 pub const fn len() -> usize {
837 const _: () = assert!(std::mem::size_of::<IflaCacheinfo>() == 16usize);
838 16usize
839 }
840}
841#[derive(Debug)]
842#[repr(C, packed(4))]
843pub struct RtnlLinkStats {
844 pub rx_packets: u32,
845 pub tx_packets: u32,
846 pub rx_bytes: u32,
847 pub tx_bytes: u32,
848 pub rx_errors: u32,
849 pub tx_errors: u32,
850 pub rx_dropped: u32,
851 pub tx_dropped: u32,
852 pub multicast: u32,
853 pub collisions: u32,
854 pub rx_length_errors: u32,
855 pub rx_over_errors: u32,
856 pub rx_crc_errors: u32,
857 pub rx_frame_errors: u32,
858 pub rx_fifo_errors: u32,
859 pub rx_missed_errors: u32,
860 pub tx_aborted_errors: u32,
861 pub tx_carrier_errors: u32,
862 pub tx_fifo_errors: u32,
863 pub tx_heartbeat_errors: u32,
864 pub tx_window_errors: u32,
865 pub rx_compressed: u32,
866 pub tx_compressed: u32,
867 pub rx_nohandler: u32,
868}
869impl Clone for RtnlLinkStats {
870 fn clone(&self) -> Self {
871 Self::new_from_array(*self.as_array())
872 }
873}
874#[doc = "Create zero-initialized struct"]
875impl Default for RtnlLinkStats {
876 fn default() -> Self {
877 Self::new()
878 }
879}
880impl RtnlLinkStats {
881 #[doc = "Create zero-initialized struct"]
882 pub fn new() -> Self {
883 Self::new_from_array([0u8; Self::len()])
884 }
885 #[doc = "Copy from contents from slice"]
886 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
887 if other.len() != Self::len() {
888 return None;
889 }
890 let mut buf = [0u8; Self::len()];
891 buf.clone_from_slice(other);
892 Some(Self::new_from_array(buf))
893 }
894 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
895 pub fn new_from_zeroed(other: &[u8]) -> Self {
896 let mut buf = [0u8; Self::len()];
897 let len = buf.len().min(other.len());
898 buf[..len].clone_from_slice(&other[..len]);
899 Self::new_from_array(buf)
900 }
901 pub fn new_from_array(buf: [u8; 96usize]) -> Self {
902 unsafe { std::mem::transmute(buf) }
903 }
904 pub fn as_slice(&self) -> &[u8] {
905 unsafe {
906 let ptr: *const u8 = std::mem::transmute(self as *const Self);
907 std::slice::from_raw_parts(ptr, Self::len())
908 }
909 }
910 pub fn from_slice(buf: &[u8]) -> &Self {
911 assert!(buf.len() >= Self::len());
912 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
913 unsafe { std::mem::transmute(buf.as_ptr()) }
914 }
915 pub fn as_array(&self) -> &[u8; 96usize] {
916 unsafe { std::mem::transmute(self) }
917 }
918 pub fn from_array(buf: &[u8; 96usize]) -> &Self {
919 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
920 unsafe { std::mem::transmute(buf) }
921 }
922 pub fn into_array(self) -> [u8; 96usize] {
923 unsafe { std::mem::transmute(self) }
924 }
925 pub const fn len() -> usize {
926 const _: () = assert!(std::mem::size_of::<RtnlLinkStats>() == 96usize);
927 96usize
928 }
929}
930#[repr(C, packed(4))]
931pub struct RtnlLinkStats64 {
932 pub rx_packets: u64,
933 pub tx_packets: u64,
934 pub rx_bytes: u64,
935 pub tx_bytes: u64,
936 pub rx_errors: u64,
937 pub tx_errors: u64,
938 pub rx_dropped: u64,
939 pub tx_dropped: u64,
940 pub multicast: u64,
941 pub collisions: u64,
942 pub rx_length_errors: u64,
943 pub rx_over_errors: u64,
944 pub rx_crc_errors: u64,
945 pub rx_frame_errors: u64,
946 pub rx_fifo_errors: u64,
947 pub rx_missed_errors: u64,
948 pub tx_aborted_errors: u64,
949 pub tx_carrier_errors: u64,
950 pub tx_fifo_errors: u64,
951 pub tx_heartbeat_errors: u64,
952 pub tx_window_errors: u64,
953 pub rx_compressed: u64,
954 pub tx_compressed: u64,
955 pub rx_nohandler: u64,
956 pub rx_otherhost_dropped: u64,
957}
958impl Clone for RtnlLinkStats64 {
959 fn clone(&self) -> Self {
960 Self::new_from_array(*self.as_array())
961 }
962}
963#[doc = "Create zero-initialized struct"]
964impl Default for RtnlLinkStats64 {
965 fn default() -> Self {
966 Self::new()
967 }
968}
969impl RtnlLinkStats64 {
970 #[doc = "Create zero-initialized struct"]
971 pub fn new() -> Self {
972 Self::new_from_array([0u8; Self::len()])
973 }
974 #[doc = "Copy from contents from slice"]
975 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
976 if other.len() != Self::len() {
977 return None;
978 }
979 let mut buf = [0u8; Self::len()];
980 buf.clone_from_slice(other);
981 Some(Self::new_from_array(buf))
982 }
983 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
984 pub fn new_from_zeroed(other: &[u8]) -> Self {
985 let mut buf = [0u8; Self::len()];
986 let len = buf.len().min(other.len());
987 buf[..len].clone_from_slice(&other[..len]);
988 Self::new_from_array(buf)
989 }
990 pub fn new_from_array(buf: [u8; 200usize]) -> Self {
991 unsafe { std::mem::transmute(buf) }
992 }
993 pub fn as_slice(&self) -> &[u8] {
994 unsafe {
995 let ptr: *const u8 = std::mem::transmute(self as *const Self);
996 std::slice::from_raw_parts(ptr, Self::len())
997 }
998 }
999 pub fn from_slice(buf: &[u8]) -> &Self {
1000 assert!(buf.len() >= Self::len());
1001 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1002 unsafe { std::mem::transmute(buf.as_ptr()) }
1003 }
1004 pub fn as_array(&self) -> &[u8; 200usize] {
1005 unsafe { std::mem::transmute(self) }
1006 }
1007 pub fn from_array(buf: &[u8; 200usize]) -> &Self {
1008 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1009 unsafe { std::mem::transmute(buf) }
1010 }
1011 pub fn into_array(self) -> [u8; 200usize] {
1012 unsafe { std::mem::transmute(self) }
1013 }
1014 pub const fn len() -> usize {
1015 const _: () = assert!(std::mem::size_of::<RtnlLinkStats64>() == 200usize);
1016 200usize
1017 }
1018}
1019impl std::fmt::Debug for RtnlLinkStats64 {
1020 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1021 fmt.debug_struct("RtnlLinkStats64")
1022 .field("rx_packets", &{ self.rx_packets })
1023 .field("tx_packets", &{ self.tx_packets })
1024 .field("rx_bytes", &{ self.rx_bytes })
1025 .field("tx_bytes", &{ self.tx_bytes })
1026 .field("rx_errors", &{ self.rx_errors })
1027 .field("tx_errors", &{ self.tx_errors })
1028 .field("rx_dropped", &{ self.rx_dropped })
1029 .field("tx_dropped", &{ self.tx_dropped })
1030 .field("multicast", &{ self.multicast })
1031 .field("collisions", &{ self.collisions })
1032 .field("rx_length_errors", &{ self.rx_length_errors })
1033 .field("rx_over_errors", &{ self.rx_over_errors })
1034 .field("rx_crc_errors", &{ self.rx_crc_errors })
1035 .field("rx_frame_errors", &{ self.rx_frame_errors })
1036 .field("rx_fifo_errors", &{ self.rx_fifo_errors })
1037 .field("rx_missed_errors", &{ self.rx_missed_errors })
1038 .field("tx_aborted_errors", &{ self.tx_aborted_errors })
1039 .field("tx_carrier_errors", &{ self.tx_carrier_errors })
1040 .field("tx_fifo_errors", &{ self.tx_fifo_errors })
1041 .field("tx_heartbeat_errors", &{ self.tx_heartbeat_errors })
1042 .field("tx_window_errors", &{ self.tx_window_errors })
1043 .field("rx_compressed", &{ self.rx_compressed })
1044 .field("tx_compressed", &{ self.tx_compressed })
1045 .field("rx_nohandler", &{ self.rx_nohandler })
1046 .field("rx_otherhost_dropped", &{ self.rx_otherhost_dropped })
1047 .finish()
1048 }
1049}
1050#[repr(C, packed(4))]
1051pub struct RtnlLinkIfmap {
1052 pub mem_start: u64,
1053 pub mem_end: u64,
1054 pub base_addr: u64,
1055 pub irq: u16,
1056 pub dma: u8,
1057 pub port: u8,
1058 pub _pad_28: [u8; 4usize],
1059}
1060impl Clone for RtnlLinkIfmap {
1061 fn clone(&self) -> Self {
1062 Self::new_from_array(*self.as_array())
1063 }
1064}
1065#[doc = "Create zero-initialized struct"]
1066impl Default for RtnlLinkIfmap {
1067 fn default() -> Self {
1068 Self::new()
1069 }
1070}
1071impl RtnlLinkIfmap {
1072 #[doc = "Create zero-initialized struct"]
1073 pub fn new() -> Self {
1074 Self::new_from_array([0u8; Self::len()])
1075 }
1076 #[doc = "Copy from contents from slice"]
1077 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1078 if other.len() != Self::len() {
1079 return None;
1080 }
1081 let mut buf = [0u8; Self::len()];
1082 buf.clone_from_slice(other);
1083 Some(Self::new_from_array(buf))
1084 }
1085 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1086 pub fn new_from_zeroed(other: &[u8]) -> Self {
1087 let mut buf = [0u8; Self::len()];
1088 let len = buf.len().min(other.len());
1089 buf[..len].clone_from_slice(&other[..len]);
1090 Self::new_from_array(buf)
1091 }
1092 pub fn new_from_array(buf: [u8; 32usize]) -> Self {
1093 unsafe { std::mem::transmute(buf) }
1094 }
1095 pub fn as_slice(&self) -> &[u8] {
1096 unsafe {
1097 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1098 std::slice::from_raw_parts(ptr, Self::len())
1099 }
1100 }
1101 pub fn from_slice(buf: &[u8]) -> &Self {
1102 assert!(buf.len() >= Self::len());
1103 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1104 unsafe { std::mem::transmute(buf.as_ptr()) }
1105 }
1106 pub fn as_array(&self) -> &[u8; 32usize] {
1107 unsafe { std::mem::transmute(self) }
1108 }
1109 pub fn from_array(buf: &[u8; 32usize]) -> &Self {
1110 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1111 unsafe { std::mem::transmute(buf) }
1112 }
1113 pub fn into_array(self) -> [u8; 32usize] {
1114 unsafe { std::mem::transmute(self) }
1115 }
1116 pub const fn len() -> usize {
1117 const _: () = assert!(std::mem::size_of::<RtnlLinkIfmap>() == 32usize);
1118 32usize
1119 }
1120}
1121impl std::fmt::Debug for RtnlLinkIfmap {
1122 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1123 fmt.debug_struct("RtnlLinkIfmap")
1124 .field("mem_start", &{ self.mem_start })
1125 .field("mem_end", &{ self.mem_end })
1126 .field("base_addr", &{ self.base_addr })
1127 .field("irq", &self.irq)
1128 .field("dma", &self.dma)
1129 .field("port", &self.port)
1130 .finish()
1131 }
1132}
1133#[derive(Debug)]
1134#[repr(C, packed(4))]
1135pub struct BrBooloptMulti {
1136 pub optval: u32,
1137 pub optmask: u32,
1138}
1139impl Clone for BrBooloptMulti {
1140 fn clone(&self) -> Self {
1141 Self::new_from_array(*self.as_array())
1142 }
1143}
1144#[doc = "Create zero-initialized struct"]
1145impl Default for BrBooloptMulti {
1146 fn default() -> Self {
1147 Self::new()
1148 }
1149}
1150impl BrBooloptMulti {
1151 #[doc = "Create zero-initialized struct"]
1152 pub fn new() -> Self {
1153 Self::new_from_array([0u8; Self::len()])
1154 }
1155 #[doc = "Copy from contents from slice"]
1156 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1157 if other.len() != Self::len() {
1158 return None;
1159 }
1160 let mut buf = [0u8; Self::len()];
1161 buf.clone_from_slice(other);
1162 Some(Self::new_from_array(buf))
1163 }
1164 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1165 pub fn new_from_zeroed(other: &[u8]) -> Self {
1166 let mut buf = [0u8; Self::len()];
1167 let len = buf.len().min(other.len());
1168 buf[..len].clone_from_slice(&other[..len]);
1169 Self::new_from_array(buf)
1170 }
1171 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1172 unsafe { std::mem::transmute(buf) }
1173 }
1174 pub fn as_slice(&self) -> &[u8] {
1175 unsafe {
1176 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1177 std::slice::from_raw_parts(ptr, Self::len())
1178 }
1179 }
1180 pub fn from_slice(buf: &[u8]) -> &Self {
1181 assert!(buf.len() >= Self::len());
1182 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1183 unsafe { std::mem::transmute(buf.as_ptr()) }
1184 }
1185 pub fn as_array(&self) -> &[u8; 8usize] {
1186 unsafe { std::mem::transmute(self) }
1187 }
1188 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1189 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1190 unsafe { std::mem::transmute(buf) }
1191 }
1192 pub fn into_array(self) -> [u8; 8usize] {
1193 unsafe { std::mem::transmute(self) }
1194 }
1195 pub const fn len() -> usize {
1196 const _: () = assert!(std::mem::size_of::<BrBooloptMulti>() == 8usize);
1197 8usize
1198 }
1199}
1200#[repr(C, packed(4))]
1201pub struct IfStatsMsg {
1202 pub family: u8,
1203 pub _pad: [u8; 3usize],
1204 pub ifindex: u32,
1205 pub filter_mask: u32,
1206}
1207impl Clone for IfStatsMsg {
1208 fn clone(&self) -> Self {
1209 Self::new_from_array(*self.as_array())
1210 }
1211}
1212#[doc = "Create zero-initialized struct"]
1213impl Default for IfStatsMsg {
1214 fn default() -> Self {
1215 Self::new()
1216 }
1217}
1218impl IfStatsMsg {
1219 #[doc = "Create zero-initialized struct"]
1220 pub fn new() -> Self {
1221 Self::new_from_array([0u8; Self::len()])
1222 }
1223 #[doc = "Copy from contents from slice"]
1224 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1225 if other.len() != Self::len() {
1226 return None;
1227 }
1228 let mut buf = [0u8; Self::len()];
1229 buf.clone_from_slice(other);
1230 Some(Self::new_from_array(buf))
1231 }
1232 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1233 pub fn new_from_zeroed(other: &[u8]) -> Self {
1234 let mut buf = [0u8; Self::len()];
1235 let len = buf.len().min(other.len());
1236 buf[..len].clone_from_slice(&other[..len]);
1237 Self::new_from_array(buf)
1238 }
1239 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1240 unsafe { std::mem::transmute(buf) }
1241 }
1242 pub fn as_slice(&self) -> &[u8] {
1243 unsafe {
1244 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1245 std::slice::from_raw_parts(ptr, Self::len())
1246 }
1247 }
1248 pub fn from_slice(buf: &[u8]) -> &Self {
1249 assert!(buf.len() >= Self::len());
1250 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1251 unsafe { std::mem::transmute(buf.as_ptr()) }
1252 }
1253 pub fn as_array(&self) -> &[u8; 12usize] {
1254 unsafe { std::mem::transmute(self) }
1255 }
1256 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1257 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1258 unsafe { std::mem::transmute(buf) }
1259 }
1260 pub fn into_array(self) -> [u8; 12usize] {
1261 unsafe { std::mem::transmute(self) }
1262 }
1263 pub const fn len() -> usize {
1264 const _: () = assert!(std::mem::size_of::<IfStatsMsg>() == 12usize);
1265 12usize
1266 }
1267}
1268impl std::fmt::Debug for IfStatsMsg {
1269 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1270 fmt.debug_struct("IfStatsMsg")
1271 .field("family", &self.family)
1272 .field("ifindex", &self.ifindex)
1273 .field("filter_mask", &self.filter_mask)
1274 .finish()
1275 }
1276}
1277#[repr(C, packed(4))]
1278pub struct IflaVlanFlags {
1279 #[doc = "Associated type: [`VlanFlags`] (1 bit per enumeration)"]
1280 pub flags: u32,
1281 pub mask: u32,
1282}
1283impl Clone for IflaVlanFlags {
1284 fn clone(&self) -> Self {
1285 Self::new_from_array(*self.as_array())
1286 }
1287}
1288#[doc = "Create zero-initialized struct"]
1289impl Default for IflaVlanFlags {
1290 fn default() -> Self {
1291 Self::new()
1292 }
1293}
1294impl IflaVlanFlags {
1295 #[doc = "Create zero-initialized struct"]
1296 pub fn new() -> Self {
1297 Self::new_from_array([0u8; Self::len()])
1298 }
1299 #[doc = "Copy from contents from slice"]
1300 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1301 if other.len() != Self::len() {
1302 return None;
1303 }
1304 let mut buf = [0u8; Self::len()];
1305 buf.clone_from_slice(other);
1306 Some(Self::new_from_array(buf))
1307 }
1308 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1309 pub fn new_from_zeroed(other: &[u8]) -> Self {
1310 let mut buf = [0u8; Self::len()];
1311 let len = buf.len().min(other.len());
1312 buf[..len].clone_from_slice(&other[..len]);
1313 Self::new_from_array(buf)
1314 }
1315 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1316 unsafe { std::mem::transmute(buf) }
1317 }
1318 pub fn as_slice(&self) -> &[u8] {
1319 unsafe {
1320 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1321 std::slice::from_raw_parts(ptr, Self::len())
1322 }
1323 }
1324 pub fn from_slice(buf: &[u8]) -> &Self {
1325 assert!(buf.len() >= Self::len());
1326 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1327 unsafe { std::mem::transmute(buf.as_ptr()) }
1328 }
1329 pub fn as_array(&self) -> &[u8; 8usize] {
1330 unsafe { std::mem::transmute(self) }
1331 }
1332 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1333 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1334 unsafe { std::mem::transmute(buf) }
1335 }
1336 pub fn into_array(self) -> [u8; 8usize] {
1337 unsafe { std::mem::transmute(self) }
1338 }
1339 pub const fn len() -> usize {
1340 const _: () = assert!(std::mem::size_of::<IflaVlanFlags>() == 8usize);
1341 8usize
1342 }
1343}
1344impl std::fmt::Debug for IflaVlanFlags {
1345 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1346 fmt.debug_struct("IflaVlanFlags")
1347 .field(
1348 "flags",
1349 &FormatFlags(self.flags.into(), VlanFlags::from_value),
1350 )
1351 .field("mask", &FormatHex(self.mask.to_ne_bytes()))
1352 .finish()
1353 }
1354}
1355#[derive(Debug)]
1356#[repr(C, packed(4))]
1357pub struct IflaVlanQosMapping {
1358 pub from: u32,
1359 pub to: u32,
1360}
1361impl Clone for IflaVlanQosMapping {
1362 fn clone(&self) -> Self {
1363 Self::new_from_array(*self.as_array())
1364 }
1365}
1366#[doc = "Create zero-initialized struct"]
1367impl Default for IflaVlanQosMapping {
1368 fn default() -> Self {
1369 Self::new()
1370 }
1371}
1372impl IflaVlanQosMapping {
1373 #[doc = "Create zero-initialized struct"]
1374 pub fn new() -> Self {
1375 Self::new_from_array([0u8; Self::len()])
1376 }
1377 #[doc = "Copy from contents from slice"]
1378 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1379 if other.len() != Self::len() {
1380 return None;
1381 }
1382 let mut buf = [0u8; Self::len()];
1383 buf.clone_from_slice(other);
1384 Some(Self::new_from_array(buf))
1385 }
1386 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1387 pub fn new_from_zeroed(other: &[u8]) -> Self {
1388 let mut buf = [0u8; Self::len()];
1389 let len = buf.len().min(other.len());
1390 buf[..len].clone_from_slice(&other[..len]);
1391 Self::new_from_array(buf)
1392 }
1393 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1394 unsafe { std::mem::transmute(buf) }
1395 }
1396 pub fn as_slice(&self) -> &[u8] {
1397 unsafe {
1398 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1399 std::slice::from_raw_parts(ptr, Self::len())
1400 }
1401 }
1402 pub fn from_slice(buf: &[u8]) -> &Self {
1403 assert!(buf.len() >= Self::len());
1404 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1405 unsafe { std::mem::transmute(buf.as_ptr()) }
1406 }
1407 pub fn as_array(&self) -> &[u8; 8usize] {
1408 unsafe { std::mem::transmute(self) }
1409 }
1410 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1411 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1412 unsafe { std::mem::transmute(buf) }
1413 }
1414 pub fn into_array(self) -> [u8; 8usize] {
1415 unsafe { std::mem::transmute(self) }
1416 }
1417 pub const fn len() -> usize {
1418 const _: () = assert!(std::mem::size_of::<IflaVlanQosMapping>() == 8usize);
1419 8usize
1420 }
1421}
1422#[repr(C, packed(4))]
1423pub struct IflaGenevePortRange {
1424 pub _low_be: u16,
1425 pub _high_be: u16,
1426}
1427impl Clone for IflaGenevePortRange {
1428 fn clone(&self) -> Self {
1429 Self::new_from_array(*self.as_array())
1430 }
1431}
1432#[doc = "Create zero-initialized struct"]
1433impl Default for IflaGenevePortRange {
1434 fn default() -> Self {
1435 Self::new()
1436 }
1437}
1438impl IflaGenevePortRange {
1439 #[doc = "Create zero-initialized struct"]
1440 pub fn new() -> Self {
1441 Self::new_from_array([0u8; Self::len()])
1442 }
1443 #[doc = "Copy from contents from slice"]
1444 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1445 if other.len() != Self::len() {
1446 return None;
1447 }
1448 let mut buf = [0u8; Self::len()];
1449 buf.clone_from_slice(other);
1450 Some(Self::new_from_array(buf))
1451 }
1452 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1453 pub fn new_from_zeroed(other: &[u8]) -> Self {
1454 let mut buf = [0u8; Self::len()];
1455 let len = buf.len().min(other.len());
1456 buf[..len].clone_from_slice(&other[..len]);
1457 Self::new_from_array(buf)
1458 }
1459 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
1460 unsafe { std::mem::transmute(buf) }
1461 }
1462 pub fn as_slice(&self) -> &[u8] {
1463 unsafe {
1464 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1465 std::slice::from_raw_parts(ptr, Self::len())
1466 }
1467 }
1468 pub fn from_slice(buf: &[u8]) -> &Self {
1469 assert!(buf.len() >= Self::len());
1470 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1471 unsafe { std::mem::transmute(buf.as_ptr()) }
1472 }
1473 pub fn as_array(&self) -> &[u8; 4usize] {
1474 unsafe { std::mem::transmute(self) }
1475 }
1476 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
1477 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1478 unsafe { std::mem::transmute(buf) }
1479 }
1480 pub fn into_array(self) -> [u8; 4usize] {
1481 unsafe { std::mem::transmute(self) }
1482 }
1483 pub const fn len() -> usize {
1484 const _: () = assert!(std::mem::size_of::<IflaGenevePortRange>() == 4usize);
1485 4usize
1486 }
1487 pub fn low(&self) -> u16 {
1488 u16::from_be(self._low_be)
1489 }
1490 pub fn set_low(&mut self, value: u16) {
1491 self._low_be = value.to_be();
1492 }
1493 pub fn high(&self) -> u16 {
1494 u16::from_be(self._high_be)
1495 }
1496 pub fn set_high(&mut self, value: u16) {
1497 self._high_be = value.to_be();
1498 }
1499}
1500impl std::fmt::Debug for IflaGenevePortRange {
1501 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1502 fmt.debug_struct("IflaGenevePortRange")
1503 .field("low", &self.low())
1504 .field("high", &self.high())
1505 .finish()
1506 }
1507}
1508#[derive(Debug)]
1509#[repr(C, packed(4))]
1510pub struct IflaVfMac {
1511 pub vf: u32,
1512 pub mac: [u8; 32usize],
1513}
1514impl Clone for IflaVfMac {
1515 fn clone(&self) -> Self {
1516 Self::new_from_array(*self.as_array())
1517 }
1518}
1519#[doc = "Create zero-initialized struct"]
1520impl Default for IflaVfMac {
1521 fn default() -> Self {
1522 Self::new()
1523 }
1524}
1525impl IflaVfMac {
1526 #[doc = "Create zero-initialized struct"]
1527 pub fn new() -> Self {
1528 Self::new_from_array([0u8; Self::len()])
1529 }
1530 #[doc = "Copy from contents from slice"]
1531 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1532 if other.len() != Self::len() {
1533 return None;
1534 }
1535 let mut buf = [0u8; Self::len()];
1536 buf.clone_from_slice(other);
1537 Some(Self::new_from_array(buf))
1538 }
1539 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1540 pub fn new_from_zeroed(other: &[u8]) -> Self {
1541 let mut buf = [0u8; Self::len()];
1542 let len = buf.len().min(other.len());
1543 buf[..len].clone_from_slice(&other[..len]);
1544 Self::new_from_array(buf)
1545 }
1546 pub fn new_from_array(buf: [u8; 36usize]) -> Self {
1547 unsafe { std::mem::transmute(buf) }
1548 }
1549 pub fn as_slice(&self) -> &[u8] {
1550 unsafe {
1551 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1552 std::slice::from_raw_parts(ptr, Self::len())
1553 }
1554 }
1555 pub fn from_slice(buf: &[u8]) -> &Self {
1556 assert!(buf.len() >= Self::len());
1557 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1558 unsafe { std::mem::transmute(buf.as_ptr()) }
1559 }
1560 pub fn as_array(&self) -> &[u8; 36usize] {
1561 unsafe { std::mem::transmute(self) }
1562 }
1563 pub fn from_array(buf: &[u8; 36usize]) -> &Self {
1564 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1565 unsafe { std::mem::transmute(buf) }
1566 }
1567 pub fn into_array(self) -> [u8; 36usize] {
1568 unsafe { std::mem::transmute(self) }
1569 }
1570 pub const fn len() -> usize {
1571 const _: () = assert!(std::mem::size_of::<IflaVfMac>() == 36usize);
1572 36usize
1573 }
1574}
1575#[derive(Debug)]
1576#[repr(C, packed(4))]
1577pub struct IflaVfVlan {
1578 pub vf: u32,
1579 pub vlan: u32,
1580 pub qos: u32,
1581}
1582impl Clone for IflaVfVlan {
1583 fn clone(&self) -> Self {
1584 Self::new_from_array(*self.as_array())
1585 }
1586}
1587#[doc = "Create zero-initialized struct"]
1588impl Default for IflaVfVlan {
1589 fn default() -> Self {
1590 Self::new()
1591 }
1592}
1593impl IflaVfVlan {
1594 #[doc = "Create zero-initialized struct"]
1595 pub fn new() -> Self {
1596 Self::new_from_array([0u8; Self::len()])
1597 }
1598 #[doc = "Copy from contents from slice"]
1599 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1600 if other.len() != Self::len() {
1601 return None;
1602 }
1603 let mut buf = [0u8; Self::len()];
1604 buf.clone_from_slice(other);
1605 Some(Self::new_from_array(buf))
1606 }
1607 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1608 pub fn new_from_zeroed(other: &[u8]) -> Self {
1609 let mut buf = [0u8; Self::len()];
1610 let len = buf.len().min(other.len());
1611 buf[..len].clone_from_slice(&other[..len]);
1612 Self::new_from_array(buf)
1613 }
1614 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1615 unsafe { std::mem::transmute(buf) }
1616 }
1617 pub fn as_slice(&self) -> &[u8] {
1618 unsafe {
1619 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1620 std::slice::from_raw_parts(ptr, Self::len())
1621 }
1622 }
1623 pub fn from_slice(buf: &[u8]) -> &Self {
1624 assert!(buf.len() >= Self::len());
1625 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1626 unsafe { std::mem::transmute(buf.as_ptr()) }
1627 }
1628 pub fn as_array(&self) -> &[u8; 12usize] {
1629 unsafe { std::mem::transmute(self) }
1630 }
1631 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1632 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1633 unsafe { std::mem::transmute(buf) }
1634 }
1635 pub fn into_array(self) -> [u8; 12usize] {
1636 unsafe { std::mem::transmute(self) }
1637 }
1638 pub const fn len() -> usize {
1639 const _: () = assert!(std::mem::size_of::<IflaVfVlan>() == 12usize);
1640 12usize
1641 }
1642}
1643#[derive(Debug)]
1644#[repr(C, packed(4))]
1645pub struct IflaVfTxRate {
1646 pub vf: u32,
1647 pub rate: u32,
1648}
1649impl Clone for IflaVfTxRate {
1650 fn clone(&self) -> Self {
1651 Self::new_from_array(*self.as_array())
1652 }
1653}
1654#[doc = "Create zero-initialized struct"]
1655impl Default for IflaVfTxRate {
1656 fn default() -> Self {
1657 Self::new()
1658 }
1659}
1660impl IflaVfTxRate {
1661 #[doc = "Create zero-initialized struct"]
1662 pub fn new() -> Self {
1663 Self::new_from_array([0u8; Self::len()])
1664 }
1665 #[doc = "Copy from contents from slice"]
1666 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1667 if other.len() != Self::len() {
1668 return None;
1669 }
1670 let mut buf = [0u8; Self::len()];
1671 buf.clone_from_slice(other);
1672 Some(Self::new_from_array(buf))
1673 }
1674 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1675 pub fn new_from_zeroed(other: &[u8]) -> Self {
1676 let mut buf = [0u8; Self::len()];
1677 let len = buf.len().min(other.len());
1678 buf[..len].clone_from_slice(&other[..len]);
1679 Self::new_from_array(buf)
1680 }
1681 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1682 unsafe { std::mem::transmute(buf) }
1683 }
1684 pub fn as_slice(&self) -> &[u8] {
1685 unsafe {
1686 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1687 std::slice::from_raw_parts(ptr, Self::len())
1688 }
1689 }
1690 pub fn from_slice(buf: &[u8]) -> &Self {
1691 assert!(buf.len() >= Self::len());
1692 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1693 unsafe { std::mem::transmute(buf.as_ptr()) }
1694 }
1695 pub fn as_array(&self) -> &[u8; 8usize] {
1696 unsafe { std::mem::transmute(self) }
1697 }
1698 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1699 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1700 unsafe { std::mem::transmute(buf) }
1701 }
1702 pub fn into_array(self) -> [u8; 8usize] {
1703 unsafe { std::mem::transmute(self) }
1704 }
1705 pub const fn len() -> usize {
1706 const _: () = assert!(std::mem::size_of::<IflaVfTxRate>() == 8usize);
1707 8usize
1708 }
1709}
1710#[derive(Debug)]
1711#[repr(C, packed(4))]
1712pub struct IflaVfSpoofchk {
1713 pub vf: u32,
1714 pub setting: u32,
1715}
1716impl Clone for IflaVfSpoofchk {
1717 fn clone(&self) -> Self {
1718 Self::new_from_array(*self.as_array())
1719 }
1720}
1721#[doc = "Create zero-initialized struct"]
1722impl Default for IflaVfSpoofchk {
1723 fn default() -> Self {
1724 Self::new()
1725 }
1726}
1727impl IflaVfSpoofchk {
1728 #[doc = "Create zero-initialized struct"]
1729 pub fn new() -> Self {
1730 Self::new_from_array([0u8; Self::len()])
1731 }
1732 #[doc = "Copy from contents from slice"]
1733 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1734 if other.len() != Self::len() {
1735 return None;
1736 }
1737 let mut buf = [0u8; Self::len()];
1738 buf.clone_from_slice(other);
1739 Some(Self::new_from_array(buf))
1740 }
1741 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1742 pub fn new_from_zeroed(other: &[u8]) -> Self {
1743 let mut buf = [0u8; Self::len()];
1744 let len = buf.len().min(other.len());
1745 buf[..len].clone_from_slice(&other[..len]);
1746 Self::new_from_array(buf)
1747 }
1748 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1749 unsafe { std::mem::transmute(buf) }
1750 }
1751 pub fn as_slice(&self) -> &[u8] {
1752 unsafe {
1753 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1754 std::slice::from_raw_parts(ptr, Self::len())
1755 }
1756 }
1757 pub fn from_slice(buf: &[u8]) -> &Self {
1758 assert!(buf.len() >= Self::len());
1759 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1760 unsafe { std::mem::transmute(buf.as_ptr()) }
1761 }
1762 pub fn as_array(&self) -> &[u8; 8usize] {
1763 unsafe { std::mem::transmute(self) }
1764 }
1765 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1766 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1767 unsafe { std::mem::transmute(buf) }
1768 }
1769 pub fn into_array(self) -> [u8; 8usize] {
1770 unsafe { std::mem::transmute(self) }
1771 }
1772 pub const fn len() -> usize {
1773 const _: () = assert!(std::mem::size_of::<IflaVfSpoofchk>() == 8usize);
1774 8usize
1775 }
1776}
1777#[repr(C, packed(4))]
1778pub struct IflaVfLinkState {
1779 pub vf: u32,
1780 #[doc = "Associated type: [`IflaVfLinkStateEnum`] (enum)"]
1781 pub link_state: u32,
1782}
1783impl Clone for IflaVfLinkState {
1784 fn clone(&self) -> Self {
1785 Self::new_from_array(*self.as_array())
1786 }
1787}
1788#[doc = "Create zero-initialized struct"]
1789impl Default for IflaVfLinkState {
1790 fn default() -> Self {
1791 Self::new()
1792 }
1793}
1794impl IflaVfLinkState {
1795 #[doc = "Create zero-initialized struct"]
1796 pub fn new() -> Self {
1797 Self::new_from_array([0u8; Self::len()])
1798 }
1799 #[doc = "Copy from contents from slice"]
1800 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1801 if other.len() != Self::len() {
1802 return None;
1803 }
1804 let mut buf = [0u8; Self::len()];
1805 buf.clone_from_slice(other);
1806 Some(Self::new_from_array(buf))
1807 }
1808 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1809 pub fn new_from_zeroed(other: &[u8]) -> Self {
1810 let mut buf = [0u8; Self::len()];
1811 let len = buf.len().min(other.len());
1812 buf[..len].clone_from_slice(&other[..len]);
1813 Self::new_from_array(buf)
1814 }
1815 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1816 unsafe { std::mem::transmute(buf) }
1817 }
1818 pub fn as_slice(&self) -> &[u8] {
1819 unsafe {
1820 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1821 std::slice::from_raw_parts(ptr, Self::len())
1822 }
1823 }
1824 pub fn from_slice(buf: &[u8]) -> &Self {
1825 assert!(buf.len() >= Self::len());
1826 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1827 unsafe { std::mem::transmute(buf.as_ptr()) }
1828 }
1829 pub fn as_array(&self) -> &[u8; 8usize] {
1830 unsafe { std::mem::transmute(self) }
1831 }
1832 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1833 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1834 unsafe { std::mem::transmute(buf) }
1835 }
1836 pub fn into_array(self) -> [u8; 8usize] {
1837 unsafe { std::mem::transmute(self) }
1838 }
1839 pub const fn len() -> usize {
1840 const _: () = assert!(std::mem::size_of::<IflaVfLinkState>() == 8usize);
1841 8usize
1842 }
1843}
1844impl std::fmt::Debug for IflaVfLinkState {
1845 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1846 fmt.debug_struct("IflaVfLinkState")
1847 .field("vf", &self.vf)
1848 .field(
1849 "link_state",
1850 &FormatEnum(self.link_state.into(), IflaVfLinkStateEnum::from_value),
1851 )
1852 .finish()
1853 }
1854}
1855#[derive(Debug)]
1856#[repr(C, packed(4))]
1857pub struct IflaVfRate {
1858 pub vf: u32,
1859 pub min_tx_rate: u32,
1860 pub max_tx_rate: u32,
1861}
1862impl Clone for IflaVfRate {
1863 fn clone(&self) -> Self {
1864 Self::new_from_array(*self.as_array())
1865 }
1866}
1867#[doc = "Create zero-initialized struct"]
1868impl Default for IflaVfRate {
1869 fn default() -> Self {
1870 Self::new()
1871 }
1872}
1873impl IflaVfRate {
1874 #[doc = "Create zero-initialized struct"]
1875 pub fn new() -> Self {
1876 Self::new_from_array([0u8; Self::len()])
1877 }
1878 #[doc = "Copy from contents from slice"]
1879 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1880 if other.len() != Self::len() {
1881 return None;
1882 }
1883 let mut buf = [0u8; Self::len()];
1884 buf.clone_from_slice(other);
1885 Some(Self::new_from_array(buf))
1886 }
1887 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1888 pub fn new_from_zeroed(other: &[u8]) -> Self {
1889 let mut buf = [0u8; Self::len()];
1890 let len = buf.len().min(other.len());
1891 buf[..len].clone_from_slice(&other[..len]);
1892 Self::new_from_array(buf)
1893 }
1894 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1895 unsafe { std::mem::transmute(buf) }
1896 }
1897 pub fn as_slice(&self) -> &[u8] {
1898 unsafe {
1899 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1900 std::slice::from_raw_parts(ptr, Self::len())
1901 }
1902 }
1903 pub fn from_slice(buf: &[u8]) -> &Self {
1904 assert!(buf.len() >= Self::len());
1905 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1906 unsafe { std::mem::transmute(buf.as_ptr()) }
1907 }
1908 pub fn as_array(&self) -> &[u8; 12usize] {
1909 unsafe { std::mem::transmute(self) }
1910 }
1911 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1912 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1913 unsafe { std::mem::transmute(buf) }
1914 }
1915 pub fn into_array(self) -> [u8; 12usize] {
1916 unsafe { std::mem::transmute(self) }
1917 }
1918 pub const fn len() -> usize {
1919 const _: () = assert!(std::mem::size_of::<IflaVfRate>() == 12usize);
1920 12usize
1921 }
1922}
1923#[derive(Debug)]
1924#[repr(C, packed(4))]
1925pub struct IflaVfRssQueryEn {
1926 pub vf: u32,
1927 pub setting: u32,
1928}
1929impl Clone for IflaVfRssQueryEn {
1930 fn clone(&self) -> Self {
1931 Self::new_from_array(*self.as_array())
1932 }
1933}
1934#[doc = "Create zero-initialized struct"]
1935impl Default for IflaVfRssQueryEn {
1936 fn default() -> Self {
1937 Self::new()
1938 }
1939}
1940impl IflaVfRssQueryEn {
1941 #[doc = "Create zero-initialized struct"]
1942 pub fn new() -> Self {
1943 Self::new_from_array([0u8; Self::len()])
1944 }
1945 #[doc = "Copy from contents from slice"]
1946 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1947 if other.len() != Self::len() {
1948 return None;
1949 }
1950 let mut buf = [0u8; Self::len()];
1951 buf.clone_from_slice(other);
1952 Some(Self::new_from_array(buf))
1953 }
1954 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1955 pub fn new_from_zeroed(other: &[u8]) -> Self {
1956 let mut buf = [0u8; Self::len()];
1957 let len = buf.len().min(other.len());
1958 buf[..len].clone_from_slice(&other[..len]);
1959 Self::new_from_array(buf)
1960 }
1961 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1962 unsafe { std::mem::transmute(buf) }
1963 }
1964 pub fn as_slice(&self) -> &[u8] {
1965 unsafe {
1966 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1967 std::slice::from_raw_parts(ptr, Self::len())
1968 }
1969 }
1970 pub fn from_slice(buf: &[u8]) -> &Self {
1971 assert!(buf.len() >= Self::len());
1972 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1973 unsafe { std::mem::transmute(buf.as_ptr()) }
1974 }
1975 pub fn as_array(&self) -> &[u8; 8usize] {
1976 unsafe { std::mem::transmute(self) }
1977 }
1978 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1979 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1980 unsafe { std::mem::transmute(buf) }
1981 }
1982 pub fn into_array(self) -> [u8; 8usize] {
1983 unsafe { std::mem::transmute(self) }
1984 }
1985 pub const fn len() -> usize {
1986 const _: () = assert!(std::mem::size_of::<IflaVfRssQueryEn>() == 8usize);
1987 8usize
1988 }
1989}
1990#[derive(Debug)]
1991#[repr(C, packed(4))]
1992pub struct IflaVfTrust {
1993 pub vf: u32,
1994 pub setting: u32,
1995}
1996impl Clone for IflaVfTrust {
1997 fn clone(&self) -> Self {
1998 Self::new_from_array(*self.as_array())
1999 }
2000}
2001#[doc = "Create zero-initialized struct"]
2002impl Default for IflaVfTrust {
2003 fn default() -> Self {
2004 Self::new()
2005 }
2006}
2007impl IflaVfTrust {
2008 #[doc = "Create zero-initialized struct"]
2009 pub fn new() -> Self {
2010 Self::new_from_array([0u8; Self::len()])
2011 }
2012 #[doc = "Copy from contents from slice"]
2013 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2014 if other.len() != Self::len() {
2015 return None;
2016 }
2017 let mut buf = [0u8; Self::len()];
2018 buf.clone_from_slice(other);
2019 Some(Self::new_from_array(buf))
2020 }
2021 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2022 pub fn new_from_zeroed(other: &[u8]) -> Self {
2023 let mut buf = [0u8; Self::len()];
2024 let len = buf.len().min(other.len());
2025 buf[..len].clone_from_slice(&other[..len]);
2026 Self::new_from_array(buf)
2027 }
2028 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
2029 unsafe { std::mem::transmute(buf) }
2030 }
2031 pub fn as_slice(&self) -> &[u8] {
2032 unsafe {
2033 let ptr: *const u8 = std::mem::transmute(self as *const Self);
2034 std::slice::from_raw_parts(ptr, Self::len())
2035 }
2036 }
2037 pub fn from_slice(buf: &[u8]) -> &Self {
2038 assert!(buf.len() >= Self::len());
2039 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2040 unsafe { std::mem::transmute(buf.as_ptr()) }
2041 }
2042 pub fn as_array(&self) -> &[u8; 8usize] {
2043 unsafe { std::mem::transmute(self) }
2044 }
2045 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
2046 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2047 unsafe { std::mem::transmute(buf) }
2048 }
2049 pub fn into_array(self) -> [u8; 8usize] {
2050 unsafe { std::mem::transmute(self) }
2051 }
2052 pub const fn len() -> usize {
2053 const _: () = assert!(std::mem::size_of::<IflaVfTrust>() == 8usize);
2054 8usize
2055 }
2056}
2057#[repr(C, packed(4))]
2058pub struct IflaVfGuid {
2059 pub vf: u32,
2060 pub _pad_4: [u8; 4usize],
2061 pub guid: u64,
2062}
2063impl Clone for IflaVfGuid {
2064 fn clone(&self) -> Self {
2065 Self::new_from_array(*self.as_array())
2066 }
2067}
2068#[doc = "Create zero-initialized struct"]
2069impl Default for IflaVfGuid {
2070 fn default() -> Self {
2071 Self::new()
2072 }
2073}
2074impl IflaVfGuid {
2075 #[doc = "Create zero-initialized struct"]
2076 pub fn new() -> Self {
2077 Self::new_from_array([0u8; Self::len()])
2078 }
2079 #[doc = "Copy from contents from slice"]
2080 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2081 if other.len() != Self::len() {
2082 return None;
2083 }
2084 let mut buf = [0u8; Self::len()];
2085 buf.clone_from_slice(other);
2086 Some(Self::new_from_array(buf))
2087 }
2088 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2089 pub fn new_from_zeroed(other: &[u8]) -> Self {
2090 let mut buf = [0u8; Self::len()];
2091 let len = buf.len().min(other.len());
2092 buf[..len].clone_from_slice(&other[..len]);
2093 Self::new_from_array(buf)
2094 }
2095 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
2096 unsafe { std::mem::transmute(buf) }
2097 }
2098 pub fn as_slice(&self) -> &[u8] {
2099 unsafe {
2100 let ptr: *const u8 = std::mem::transmute(self as *const Self);
2101 std::slice::from_raw_parts(ptr, Self::len())
2102 }
2103 }
2104 pub fn from_slice(buf: &[u8]) -> &Self {
2105 assert!(buf.len() >= Self::len());
2106 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2107 unsafe { std::mem::transmute(buf.as_ptr()) }
2108 }
2109 pub fn as_array(&self) -> &[u8; 16usize] {
2110 unsafe { std::mem::transmute(self) }
2111 }
2112 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
2113 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2114 unsafe { std::mem::transmute(buf) }
2115 }
2116 pub fn into_array(self) -> [u8; 16usize] {
2117 unsafe { std::mem::transmute(self) }
2118 }
2119 pub const fn len() -> usize {
2120 const _: () = assert!(std::mem::size_of::<IflaVfGuid>() == 16usize);
2121 16usize
2122 }
2123}
2124impl std::fmt::Debug for IflaVfGuid {
2125 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2126 fmt.debug_struct("IflaVfGuid")
2127 .field("vf", &self.vf)
2128 .field("guid", &{ self.guid })
2129 .finish()
2130 }
2131}
2132#[derive(Debug)]
2133#[repr(C, packed(4))]
2134pub struct IflaVfVlanInfo {
2135 pub vf: u32,
2136 pub vlan: u32,
2137 pub qos: u32,
2138 pub vlan_proto: u32,
2139}
2140impl Clone for IflaVfVlanInfo {
2141 fn clone(&self) -> Self {
2142 Self::new_from_array(*self.as_array())
2143 }
2144}
2145#[doc = "Create zero-initialized struct"]
2146impl Default for IflaVfVlanInfo {
2147 fn default() -> Self {
2148 Self::new()
2149 }
2150}
2151impl IflaVfVlanInfo {
2152 #[doc = "Create zero-initialized struct"]
2153 pub fn new() -> Self {
2154 Self::new_from_array([0u8; Self::len()])
2155 }
2156 #[doc = "Copy from contents from slice"]
2157 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2158 if other.len() != Self::len() {
2159 return None;
2160 }
2161 let mut buf = [0u8; Self::len()];
2162 buf.clone_from_slice(other);
2163 Some(Self::new_from_array(buf))
2164 }
2165 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2166 pub fn new_from_zeroed(other: &[u8]) -> Self {
2167 let mut buf = [0u8; Self::len()];
2168 let len = buf.len().min(other.len());
2169 buf[..len].clone_from_slice(&other[..len]);
2170 Self::new_from_array(buf)
2171 }
2172 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
2173 unsafe { std::mem::transmute(buf) }
2174 }
2175 pub fn as_slice(&self) -> &[u8] {
2176 unsafe {
2177 let ptr: *const u8 = std::mem::transmute(self as *const Self);
2178 std::slice::from_raw_parts(ptr, Self::len())
2179 }
2180 }
2181 pub fn from_slice(buf: &[u8]) -> &Self {
2182 assert!(buf.len() >= Self::len());
2183 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2184 unsafe { std::mem::transmute(buf.as_ptr()) }
2185 }
2186 pub fn as_array(&self) -> &[u8; 16usize] {
2187 unsafe { std::mem::transmute(self) }
2188 }
2189 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
2190 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2191 unsafe { std::mem::transmute(buf) }
2192 }
2193 pub fn into_array(self) -> [u8; 16usize] {
2194 unsafe { std::mem::transmute(self) }
2195 }
2196 pub const fn len() -> usize {
2197 const _: () = assert!(std::mem::size_of::<IflaVfVlanInfo>() == 16usize);
2198 16usize
2199 }
2200}
2201#[derive(Clone)]
2202pub enum LinkAttrs<'a> {
2203 Address(&'a [u8]),
2204 Broadcast(&'a [u8]),
2205 Ifname(&'a CStr),
2206 Mtu(u32),
2207 Link(u32),
2208 Qdisc(&'a CStr),
2209 Stats(RtnlLinkStats),
2210 Master(u32),
2211 #[doc = "struct iw_event\n"]
2212 Wireless(&'a [u8]),
2213 #[doc = "A nest of ifla6-attrs or linkinfo-brport-attrs\n"]
2214 Protinfo(&'a [u8]),
2215 Txqlen(u32),
2216 Map(RtnlLinkIfmap),
2217 Weight(u32),
2218 Operstate(u8),
2219 Linkmode(u8),
2220 Linkinfo(IterableLinkinfoAttrs<'a>),
2221 NetNsPid(u32),
2222 Ifalias(&'a CStr),
2223 NumVf(u32),
2224 VfinfoList(IterableVfinfoListAttrs<'a>),
2225 Stats64(RtnlLinkStats64),
2226 VfPorts(IterableVfPortsAttrs<'a>),
2227 PortSelf(IterablePortSelfAttrs<'a>),
2228 AfSpec(IterableAfSpecAttrs<'a>),
2229 Group(u32),
2230 NetNsFd(u32),
2231 #[doc = "Associated type: [`RtextFilter`] (1 bit per enumeration)"]
2232 ExtMask(u32),
2233 Promiscuity(u32),
2234 NumTxQueues(u32),
2235 NumRxQueues(u32),
2236 Carrier(u8),
2237 PhysPortId(&'a [u8]),
2238 CarrierChanges(u32),
2239 PhysSwitchId(&'a [u8]),
2240 LinkNetnsid(i32),
2241 PhysPortName(&'a CStr),
2242 ProtoDown(u8),
2243 GsoMaxSegs(u32),
2244 GsoMaxSize(u32),
2245 Pad(&'a [u8]),
2246 Xdp(IterableXdpAttrs<'a>),
2247 Event(u32),
2248 NewNetnsid(i32),
2249 TargetNetnsid(i32),
2250 CarrierUpCount(u32),
2251 CarrierDownCount(u32),
2252 NewIfindex(i32),
2253 MinMtu(u32),
2254 MaxMtu(u32),
2255 PropList(IterablePropListLinkAttrs<'a>),
2256 AltIfname(&'a CStr),
2257 PermAddress(&'a [u8]),
2258 ProtoDownReason(&'a CStr),
2259 ParentDevName(&'a CStr),
2260 ParentDevBusName(&'a CStr),
2261 GroMaxSize(u32),
2262 TsoMaxSize(u32),
2263 TsoMaxSegs(u32),
2264 Allmulti(u32),
2265 DevlinkPort(&'a [u8]),
2266 GsoIpv4MaxSize(u32),
2267 GroIpv4MaxSize(u32),
2268 DpllPin(IterableLinkDpllPinAttrs<'a>),
2269 #[doc = "EDT offload horizon supported by the device (in nsec).\n"]
2270 MaxPacingOffloadHorizon(u32),
2271 NetnsImmutable(u8),
2272 Headroom(u16),
2273 Tailroom(u16),
2274}
2275impl<'a> IterableLinkAttrs<'a> {
2276 pub fn get_address(&self) -> Result<&'a [u8], ErrorContext> {
2277 let mut iter = self.clone();
2278 iter.pos = 0;
2279 for attr in iter {
2280 if let Ok(LinkAttrs::Address(val)) = attr {
2281 return Ok(val);
2282 }
2283 }
2284 Err(ErrorContext::new_missing(
2285 "LinkAttrs",
2286 "Address",
2287 self.orig_loc,
2288 self.buf.as_ptr() as usize,
2289 ))
2290 }
2291 pub fn get_broadcast(&self) -> Result<&'a [u8], ErrorContext> {
2292 let mut iter = self.clone();
2293 iter.pos = 0;
2294 for attr in iter {
2295 if let Ok(LinkAttrs::Broadcast(val)) = attr {
2296 return Ok(val);
2297 }
2298 }
2299 Err(ErrorContext::new_missing(
2300 "LinkAttrs",
2301 "Broadcast",
2302 self.orig_loc,
2303 self.buf.as_ptr() as usize,
2304 ))
2305 }
2306 pub fn get_ifname(&self) -> Result<&'a CStr, ErrorContext> {
2307 let mut iter = self.clone();
2308 iter.pos = 0;
2309 for attr in iter {
2310 if let Ok(LinkAttrs::Ifname(val)) = attr {
2311 return Ok(val);
2312 }
2313 }
2314 Err(ErrorContext::new_missing(
2315 "LinkAttrs",
2316 "Ifname",
2317 self.orig_loc,
2318 self.buf.as_ptr() as usize,
2319 ))
2320 }
2321 pub fn get_mtu(&self) -> Result<u32, ErrorContext> {
2322 let mut iter = self.clone();
2323 iter.pos = 0;
2324 for attr in iter {
2325 if let Ok(LinkAttrs::Mtu(val)) = attr {
2326 return Ok(val);
2327 }
2328 }
2329 Err(ErrorContext::new_missing(
2330 "LinkAttrs",
2331 "Mtu",
2332 self.orig_loc,
2333 self.buf.as_ptr() as usize,
2334 ))
2335 }
2336 pub fn get_link(&self) -> Result<u32, ErrorContext> {
2337 let mut iter = self.clone();
2338 iter.pos = 0;
2339 for attr in iter {
2340 if let Ok(LinkAttrs::Link(val)) = attr {
2341 return Ok(val);
2342 }
2343 }
2344 Err(ErrorContext::new_missing(
2345 "LinkAttrs",
2346 "Link",
2347 self.orig_loc,
2348 self.buf.as_ptr() as usize,
2349 ))
2350 }
2351 pub fn get_qdisc(&self) -> Result<&'a CStr, ErrorContext> {
2352 let mut iter = self.clone();
2353 iter.pos = 0;
2354 for attr in iter {
2355 if let Ok(LinkAttrs::Qdisc(val)) = attr {
2356 return Ok(val);
2357 }
2358 }
2359 Err(ErrorContext::new_missing(
2360 "LinkAttrs",
2361 "Qdisc",
2362 self.orig_loc,
2363 self.buf.as_ptr() as usize,
2364 ))
2365 }
2366 pub fn get_stats(&self) -> Result<RtnlLinkStats, ErrorContext> {
2367 let mut iter = self.clone();
2368 iter.pos = 0;
2369 for attr in iter {
2370 if let Ok(LinkAttrs::Stats(val)) = attr {
2371 return Ok(val);
2372 }
2373 }
2374 Err(ErrorContext::new_missing(
2375 "LinkAttrs",
2376 "Stats",
2377 self.orig_loc,
2378 self.buf.as_ptr() as usize,
2379 ))
2380 }
2381 pub fn get_master(&self) -> Result<u32, ErrorContext> {
2382 let mut iter = self.clone();
2383 iter.pos = 0;
2384 for attr in iter {
2385 if let Ok(LinkAttrs::Master(val)) = attr {
2386 return Ok(val);
2387 }
2388 }
2389 Err(ErrorContext::new_missing(
2390 "LinkAttrs",
2391 "Master",
2392 self.orig_loc,
2393 self.buf.as_ptr() as usize,
2394 ))
2395 }
2396 #[doc = "struct iw_event\n"]
2397 pub fn get_wireless(&self) -> Result<&'a [u8], ErrorContext> {
2398 let mut iter = self.clone();
2399 iter.pos = 0;
2400 for attr in iter {
2401 if let Ok(LinkAttrs::Wireless(val)) = attr {
2402 return Ok(val);
2403 }
2404 }
2405 Err(ErrorContext::new_missing(
2406 "LinkAttrs",
2407 "Wireless",
2408 self.orig_loc,
2409 self.buf.as_ptr() as usize,
2410 ))
2411 }
2412 #[doc = "A nest of ifla6-attrs or linkinfo-brport-attrs\n"]
2413 pub fn get_protinfo(&self) -> Result<&'a [u8], ErrorContext> {
2414 let mut iter = self.clone();
2415 iter.pos = 0;
2416 for attr in iter {
2417 if let Ok(LinkAttrs::Protinfo(val)) = attr {
2418 return Ok(val);
2419 }
2420 }
2421 Err(ErrorContext::new_missing(
2422 "LinkAttrs",
2423 "Protinfo",
2424 self.orig_loc,
2425 self.buf.as_ptr() as usize,
2426 ))
2427 }
2428 pub fn get_txqlen(&self) -> Result<u32, ErrorContext> {
2429 let mut iter = self.clone();
2430 iter.pos = 0;
2431 for attr in iter {
2432 if let Ok(LinkAttrs::Txqlen(val)) = attr {
2433 return Ok(val);
2434 }
2435 }
2436 Err(ErrorContext::new_missing(
2437 "LinkAttrs",
2438 "Txqlen",
2439 self.orig_loc,
2440 self.buf.as_ptr() as usize,
2441 ))
2442 }
2443 pub fn get_map(&self) -> Result<RtnlLinkIfmap, ErrorContext> {
2444 let mut iter = self.clone();
2445 iter.pos = 0;
2446 for attr in iter {
2447 if let Ok(LinkAttrs::Map(val)) = attr {
2448 return Ok(val);
2449 }
2450 }
2451 Err(ErrorContext::new_missing(
2452 "LinkAttrs",
2453 "Map",
2454 self.orig_loc,
2455 self.buf.as_ptr() as usize,
2456 ))
2457 }
2458 pub fn get_weight(&self) -> Result<u32, ErrorContext> {
2459 let mut iter = self.clone();
2460 iter.pos = 0;
2461 for attr in iter {
2462 if let Ok(LinkAttrs::Weight(val)) = attr {
2463 return Ok(val);
2464 }
2465 }
2466 Err(ErrorContext::new_missing(
2467 "LinkAttrs",
2468 "Weight",
2469 self.orig_loc,
2470 self.buf.as_ptr() as usize,
2471 ))
2472 }
2473 pub fn get_operstate(&self) -> Result<u8, ErrorContext> {
2474 let mut iter = self.clone();
2475 iter.pos = 0;
2476 for attr in iter {
2477 if let Ok(LinkAttrs::Operstate(val)) = attr {
2478 return Ok(val);
2479 }
2480 }
2481 Err(ErrorContext::new_missing(
2482 "LinkAttrs",
2483 "Operstate",
2484 self.orig_loc,
2485 self.buf.as_ptr() as usize,
2486 ))
2487 }
2488 pub fn get_linkmode(&self) -> Result<u8, ErrorContext> {
2489 let mut iter = self.clone();
2490 iter.pos = 0;
2491 for attr in iter {
2492 if let Ok(LinkAttrs::Linkmode(val)) = attr {
2493 return Ok(val);
2494 }
2495 }
2496 Err(ErrorContext::new_missing(
2497 "LinkAttrs",
2498 "Linkmode",
2499 self.orig_loc,
2500 self.buf.as_ptr() as usize,
2501 ))
2502 }
2503 pub fn get_linkinfo(&self) -> Result<IterableLinkinfoAttrs<'a>, ErrorContext> {
2504 let mut iter = self.clone();
2505 iter.pos = 0;
2506 for attr in iter {
2507 if let Ok(LinkAttrs::Linkinfo(val)) = attr {
2508 return Ok(val);
2509 }
2510 }
2511 Err(ErrorContext::new_missing(
2512 "LinkAttrs",
2513 "Linkinfo",
2514 self.orig_loc,
2515 self.buf.as_ptr() as usize,
2516 ))
2517 }
2518 pub fn get_net_ns_pid(&self) -> Result<u32, ErrorContext> {
2519 let mut iter = self.clone();
2520 iter.pos = 0;
2521 for attr in iter {
2522 if let Ok(LinkAttrs::NetNsPid(val)) = attr {
2523 return Ok(val);
2524 }
2525 }
2526 Err(ErrorContext::new_missing(
2527 "LinkAttrs",
2528 "NetNsPid",
2529 self.orig_loc,
2530 self.buf.as_ptr() as usize,
2531 ))
2532 }
2533 pub fn get_ifalias(&self) -> Result<&'a CStr, ErrorContext> {
2534 let mut iter = self.clone();
2535 iter.pos = 0;
2536 for attr in iter {
2537 if let Ok(LinkAttrs::Ifalias(val)) = attr {
2538 return Ok(val);
2539 }
2540 }
2541 Err(ErrorContext::new_missing(
2542 "LinkAttrs",
2543 "Ifalias",
2544 self.orig_loc,
2545 self.buf.as_ptr() as usize,
2546 ))
2547 }
2548 pub fn get_num_vf(&self) -> Result<u32, ErrorContext> {
2549 let mut iter = self.clone();
2550 iter.pos = 0;
2551 for attr in iter {
2552 if let Ok(LinkAttrs::NumVf(val)) = attr {
2553 return Ok(val);
2554 }
2555 }
2556 Err(ErrorContext::new_missing(
2557 "LinkAttrs",
2558 "NumVf",
2559 self.orig_loc,
2560 self.buf.as_ptr() as usize,
2561 ))
2562 }
2563 pub fn get_vfinfo_list(&self) -> Result<IterableVfinfoListAttrs<'a>, ErrorContext> {
2564 let mut iter = self.clone();
2565 iter.pos = 0;
2566 for attr in iter {
2567 if let Ok(LinkAttrs::VfinfoList(val)) = attr {
2568 return Ok(val);
2569 }
2570 }
2571 Err(ErrorContext::new_missing(
2572 "LinkAttrs",
2573 "VfinfoList",
2574 self.orig_loc,
2575 self.buf.as_ptr() as usize,
2576 ))
2577 }
2578 pub fn get_stats64(&self) -> Result<RtnlLinkStats64, ErrorContext> {
2579 let mut iter = self.clone();
2580 iter.pos = 0;
2581 for attr in iter {
2582 if let Ok(LinkAttrs::Stats64(val)) = attr {
2583 return Ok(val);
2584 }
2585 }
2586 Err(ErrorContext::new_missing(
2587 "LinkAttrs",
2588 "Stats64",
2589 self.orig_loc,
2590 self.buf.as_ptr() as usize,
2591 ))
2592 }
2593 pub fn get_vf_ports(&self) -> Result<IterableVfPortsAttrs<'a>, ErrorContext> {
2594 let mut iter = self.clone();
2595 iter.pos = 0;
2596 for attr in iter {
2597 if let Ok(LinkAttrs::VfPorts(val)) = attr {
2598 return Ok(val);
2599 }
2600 }
2601 Err(ErrorContext::new_missing(
2602 "LinkAttrs",
2603 "VfPorts",
2604 self.orig_loc,
2605 self.buf.as_ptr() as usize,
2606 ))
2607 }
2608 pub fn get_port_self(&self) -> Result<IterablePortSelfAttrs<'a>, ErrorContext> {
2609 let mut iter = self.clone();
2610 iter.pos = 0;
2611 for attr in iter {
2612 if let Ok(LinkAttrs::PortSelf(val)) = attr {
2613 return Ok(val);
2614 }
2615 }
2616 Err(ErrorContext::new_missing(
2617 "LinkAttrs",
2618 "PortSelf",
2619 self.orig_loc,
2620 self.buf.as_ptr() as usize,
2621 ))
2622 }
2623 pub fn get_af_spec(&self) -> Result<IterableAfSpecAttrs<'a>, ErrorContext> {
2624 let mut iter = self.clone();
2625 iter.pos = 0;
2626 for attr in iter {
2627 if let Ok(LinkAttrs::AfSpec(val)) = attr {
2628 return Ok(val);
2629 }
2630 }
2631 Err(ErrorContext::new_missing(
2632 "LinkAttrs",
2633 "AfSpec",
2634 self.orig_loc,
2635 self.buf.as_ptr() as usize,
2636 ))
2637 }
2638 pub fn get_group(&self) -> Result<u32, ErrorContext> {
2639 let mut iter = self.clone();
2640 iter.pos = 0;
2641 for attr in iter {
2642 if let Ok(LinkAttrs::Group(val)) = attr {
2643 return Ok(val);
2644 }
2645 }
2646 Err(ErrorContext::new_missing(
2647 "LinkAttrs",
2648 "Group",
2649 self.orig_loc,
2650 self.buf.as_ptr() as usize,
2651 ))
2652 }
2653 pub fn get_net_ns_fd(&self) -> Result<u32, ErrorContext> {
2654 let mut iter = self.clone();
2655 iter.pos = 0;
2656 for attr in iter {
2657 if let Ok(LinkAttrs::NetNsFd(val)) = attr {
2658 return Ok(val);
2659 }
2660 }
2661 Err(ErrorContext::new_missing(
2662 "LinkAttrs",
2663 "NetNsFd",
2664 self.orig_loc,
2665 self.buf.as_ptr() as usize,
2666 ))
2667 }
2668 #[doc = "Associated type: [`RtextFilter`] (1 bit per enumeration)"]
2669 pub fn get_ext_mask(&self) -> Result<u32, ErrorContext> {
2670 let mut iter = self.clone();
2671 iter.pos = 0;
2672 for attr in iter {
2673 if let Ok(LinkAttrs::ExtMask(val)) = attr {
2674 return Ok(val);
2675 }
2676 }
2677 Err(ErrorContext::new_missing(
2678 "LinkAttrs",
2679 "ExtMask",
2680 self.orig_loc,
2681 self.buf.as_ptr() as usize,
2682 ))
2683 }
2684 pub fn get_promiscuity(&self) -> Result<u32, ErrorContext> {
2685 let mut iter = self.clone();
2686 iter.pos = 0;
2687 for attr in iter {
2688 if let Ok(LinkAttrs::Promiscuity(val)) = attr {
2689 return Ok(val);
2690 }
2691 }
2692 Err(ErrorContext::new_missing(
2693 "LinkAttrs",
2694 "Promiscuity",
2695 self.orig_loc,
2696 self.buf.as_ptr() as usize,
2697 ))
2698 }
2699 pub fn get_num_tx_queues(&self) -> Result<u32, ErrorContext> {
2700 let mut iter = self.clone();
2701 iter.pos = 0;
2702 for attr in iter {
2703 if let Ok(LinkAttrs::NumTxQueues(val)) = attr {
2704 return Ok(val);
2705 }
2706 }
2707 Err(ErrorContext::new_missing(
2708 "LinkAttrs",
2709 "NumTxQueues",
2710 self.orig_loc,
2711 self.buf.as_ptr() as usize,
2712 ))
2713 }
2714 pub fn get_num_rx_queues(&self) -> Result<u32, ErrorContext> {
2715 let mut iter = self.clone();
2716 iter.pos = 0;
2717 for attr in iter {
2718 if let Ok(LinkAttrs::NumRxQueues(val)) = attr {
2719 return Ok(val);
2720 }
2721 }
2722 Err(ErrorContext::new_missing(
2723 "LinkAttrs",
2724 "NumRxQueues",
2725 self.orig_loc,
2726 self.buf.as_ptr() as usize,
2727 ))
2728 }
2729 pub fn get_carrier(&self) -> Result<u8, ErrorContext> {
2730 let mut iter = self.clone();
2731 iter.pos = 0;
2732 for attr in iter {
2733 if let Ok(LinkAttrs::Carrier(val)) = attr {
2734 return Ok(val);
2735 }
2736 }
2737 Err(ErrorContext::new_missing(
2738 "LinkAttrs",
2739 "Carrier",
2740 self.orig_loc,
2741 self.buf.as_ptr() as usize,
2742 ))
2743 }
2744 pub fn get_phys_port_id(&self) -> Result<&'a [u8], ErrorContext> {
2745 let mut iter = self.clone();
2746 iter.pos = 0;
2747 for attr in iter {
2748 if let Ok(LinkAttrs::PhysPortId(val)) = attr {
2749 return Ok(val);
2750 }
2751 }
2752 Err(ErrorContext::new_missing(
2753 "LinkAttrs",
2754 "PhysPortId",
2755 self.orig_loc,
2756 self.buf.as_ptr() as usize,
2757 ))
2758 }
2759 pub fn get_carrier_changes(&self) -> Result<u32, ErrorContext> {
2760 let mut iter = self.clone();
2761 iter.pos = 0;
2762 for attr in iter {
2763 if let Ok(LinkAttrs::CarrierChanges(val)) = attr {
2764 return Ok(val);
2765 }
2766 }
2767 Err(ErrorContext::new_missing(
2768 "LinkAttrs",
2769 "CarrierChanges",
2770 self.orig_loc,
2771 self.buf.as_ptr() as usize,
2772 ))
2773 }
2774 pub fn get_phys_switch_id(&self) -> Result<&'a [u8], ErrorContext> {
2775 let mut iter = self.clone();
2776 iter.pos = 0;
2777 for attr in iter {
2778 if let Ok(LinkAttrs::PhysSwitchId(val)) = attr {
2779 return Ok(val);
2780 }
2781 }
2782 Err(ErrorContext::new_missing(
2783 "LinkAttrs",
2784 "PhysSwitchId",
2785 self.orig_loc,
2786 self.buf.as_ptr() as usize,
2787 ))
2788 }
2789 pub fn get_link_netnsid(&self) -> Result<i32, ErrorContext> {
2790 let mut iter = self.clone();
2791 iter.pos = 0;
2792 for attr in iter {
2793 if let Ok(LinkAttrs::LinkNetnsid(val)) = attr {
2794 return Ok(val);
2795 }
2796 }
2797 Err(ErrorContext::new_missing(
2798 "LinkAttrs",
2799 "LinkNetnsid",
2800 self.orig_loc,
2801 self.buf.as_ptr() as usize,
2802 ))
2803 }
2804 pub fn get_phys_port_name(&self) -> Result<&'a CStr, ErrorContext> {
2805 let mut iter = self.clone();
2806 iter.pos = 0;
2807 for attr in iter {
2808 if let Ok(LinkAttrs::PhysPortName(val)) = attr {
2809 return Ok(val);
2810 }
2811 }
2812 Err(ErrorContext::new_missing(
2813 "LinkAttrs",
2814 "PhysPortName",
2815 self.orig_loc,
2816 self.buf.as_ptr() as usize,
2817 ))
2818 }
2819 pub fn get_proto_down(&self) -> Result<u8, ErrorContext> {
2820 let mut iter = self.clone();
2821 iter.pos = 0;
2822 for attr in iter {
2823 if let Ok(LinkAttrs::ProtoDown(val)) = attr {
2824 return Ok(val);
2825 }
2826 }
2827 Err(ErrorContext::new_missing(
2828 "LinkAttrs",
2829 "ProtoDown",
2830 self.orig_loc,
2831 self.buf.as_ptr() as usize,
2832 ))
2833 }
2834 pub fn get_gso_max_segs(&self) -> Result<u32, ErrorContext> {
2835 let mut iter = self.clone();
2836 iter.pos = 0;
2837 for attr in iter {
2838 if let Ok(LinkAttrs::GsoMaxSegs(val)) = attr {
2839 return Ok(val);
2840 }
2841 }
2842 Err(ErrorContext::new_missing(
2843 "LinkAttrs",
2844 "GsoMaxSegs",
2845 self.orig_loc,
2846 self.buf.as_ptr() as usize,
2847 ))
2848 }
2849 pub fn get_gso_max_size(&self) -> Result<u32, ErrorContext> {
2850 let mut iter = self.clone();
2851 iter.pos = 0;
2852 for attr in iter {
2853 if let Ok(LinkAttrs::GsoMaxSize(val)) = attr {
2854 return Ok(val);
2855 }
2856 }
2857 Err(ErrorContext::new_missing(
2858 "LinkAttrs",
2859 "GsoMaxSize",
2860 self.orig_loc,
2861 self.buf.as_ptr() as usize,
2862 ))
2863 }
2864 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
2865 let mut iter = self.clone();
2866 iter.pos = 0;
2867 for attr in iter {
2868 if let Ok(LinkAttrs::Pad(val)) = attr {
2869 return Ok(val);
2870 }
2871 }
2872 Err(ErrorContext::new_missing(
2873 "LinkAttrs",
2874 "Pad",
2875 self.orig_loc,
2876 self.buf.as_ptr() as usize,
2877 ))
2878 }
2879 pub fn get_xdp(&self) -> Result<IterableXdpAttrs<'a>, ErrorContext> {
2880 let mut iter = self.clone();
2881 iter.pos = 0;
2882 for attr in iter {
2883 if let Ok(LinkAttrs::Xdp(val)) = attr {
2884 return Ok(val);
2885 }
2886 }
2887 Err(ErrorContext::new_missing(
2888 "LinkAttrs",
2889 "Xdp",
2890 self.orig_loc,
2891 self.buf.as_ptr() as usize,
2892 ))
2893 }
2894 pub fn get_event(&self) -> Result<u32, ErrorContext> {
2895 let mut iter = self.clone();
2896 iter.pos = 0;
2897 for attr in iter {
2898 if let Ok(LinkAttrs::Event(val)) = attr {
2899 return Ok(val);
2900 }
2901 }
2902 Err(ErrorContext::new_missing(
2903 "LinkAttrs",
2904 "Event",
2905 self.orig_loc,
2906 self.buf.as_ptr() as usize,
2907 ))
2908 }
2909 pub fn get_new_netnsid(&self) -> Result<i32, ErrorContext> {
2910 let mut iter = self.clone();
2911 iter.pos = 0;
2912 for attr in iter {
2913 if let Ok(LinkAttrs::NewNetnsid(val)) = attr {
2914 return Ok(val);
2915 }
2916 }
2917 Err(ErrorContext::new_missing(
2918 "LinkAttrs",
2919 "NewNetnsid",
2920 self.orig_loc,
2921 self.buf.as_ptr() as usize,
2922 ))
2923 }
2924 pub fn get_target_netnsid(&self) -> Result<i32, ErrorContext> {
2925 let mut iter = self.clone();
2926 iter.pos = 0;
2927 for attr in iter {
2928 if let Ok(LinkAttrs::TargetNetnsid(val)) = attr {
2929 return Ok(val);
2930 }
2931 }
2932 Err(ErrorContext::new_missing(
2933 "LinkAttrs",
2934 "TargetNetnsid",
2935 self.orig_loc,
2936 self.buf.as_ptr() as usize,
2937 ))
2938 }
2939 pub fn get_carrier_up_count(&self) -> Result<u32, ErrorContext> {
2940 let mut iter = self.clone();
2941 iter.pos = 0;
2942 for attr in iter {
2943 if let Ok(LinkAttrs::CarrierUpCount(val)) = attr {
2944 return Ok(val);
2945 }
2946 }
2947 Err(ErrorContext::new_missing(
2948 "LinkAttrs",
2949 "CarrierUpCount",
2950 self.orig_loc,
2951 self.buf.as_ptr() as usize,
2952 ))
2953 }
2954 pub fn get_carrier_down_count(&self) -> Result<u32, ErrorContext> {
2955 let mut iter = self.clone();
2956 iter.pos = 0;
2957 for attr in iter {
2958 if let Ok(LinkAttrs::CarrierDownCount(val)) = attr {
2959 return Ok(val);
2960 }
2961 }
2962 Err(ErrorContext::new_missing(
2963 "LinkAttrs",
2964 "CarrierDownCount",
2965 self.orig_loc,
2966 self.buf.as_ptr() as usize,
2967 ))
2968 }
2969 pub fn get_new_ifindex(&self) -> Result<i32, ErrorContext> {
2970 let mut iter = self.clone();
2971 iter.pos = 0;
2972 for attr in iter {
2973 if let Ok(LinkAttrs::NewIfindex(val)) = attr {
2974 return Ok(val);
2975 }
2976 }
2977 Err(ErrorContext::new_missing(
2978 "LinkAttrs",
2979 "NewIfindex",
2980 self.orig_loc,
2981 self.buf.as_ptr() as usize,
2982 ))
2983 }
2984 pub fn get_min_mtu(&self) -> Result<u32, ErrorContext> {
2985 let mut iter = self.clone();
2986 iter.pos = 0;
2987 for attr in iter {
2988 if let Ok(LinkAttrs::MinMtu(val)) = attr {
2989 return Ok(val);
2990 }
2991 }
2992 Err(ErrorContext::new_missing(
2993 "LinkAttrs",
2994 "MinMtu",
2995 self.orig_loc,
2996 self.buf.as_ptr() as usize,
2997 ))
2998 }
2999 pub fn get_max_mtu(&self) -> Result<u32, ErrorContext> {
3000 let mut iter = self.clone();
3001 iter.pos = 0;
3002 for attr in iter {
3003 if let Ok(LinkAttrs::MaxMtu(val)) = attr {
3004 return Ok(val);
3005 }
3006 }
3007 Err(ErrorContext::new_missing(
3008 "LinkAttrs",
3009 "MaxMtu",
3010 self.orig_loc,
3011 self.buf.as_ptr() as usize,
3012 ))
3013 }
3014 pub fn get_prop_list(&self) -> Result<IterablePropListLinkAttrs<'a>, ErrorContext> {
3015 let mut iter = self.clone();
3016 iter.pos = 0;
3017 for attr in iter {
3018 if let Ok(LinkAttrs::PropList(val)) = attr {
3019 return Ok(val);
3020 }
3021 }
3022 Err(ErrorContext::new_missing(
3023 "LinkAttrs",
3024 "PropList",
3025 self.orig_loc,
3026 self.buf.as_ptr() as usize,
3027 ))
3028 }
3029 pub fn get_alt_ifname(&self) -> Result<&'a CStr, ErrorContext> {
3030 let mut iter = self.clone();
3031 iter.pos = 0;
3032 for attr in iter {
3033 if let Ok(LinkAttrs::AltIfname(val)) = attr {
3034 return Ok(val);
3035 }
3036 }
3037 Err(ErrorContext::new_missing(
3038 "LinkAttrs",
3039 "AltIfname",
3040 self.orig_loc,
3041 self.buf.as_ptr() as usize,
3042 ))
3043 }
3044 pub fn get_perm_address(&self) -> Result<&'a [u8], ErrorContext> {
3045 let mut iter = self.clone();
3046 iter.pos = 0;
3047 for attr in iter {
3048 if let Ok(LinkAttrs::PermAddress(val)) = attr {
3049 return Ok(val);
3050 }
3051 }
3052 Err(ErrorContext::new_missing(
3053 "LinkAttrs",
3054 "PermAddress",
3055 self.orig_loc,
3056 self.buf.as_ptr() as usize,
3057 ))
3058 }
3059 pub fn get_proto_down_reason(&self) -> Result<&'a CStr, ErrorContext> {
3060 let mut iter = self.clone();
3061 iter.pos = 0;
3062 for attr in iter {
3063 if let Ok(LinkAttrs::ProtoDownReason(val)) = attr {
3064 return Ok(val);
3065 }
3066 }
3067 Err(ErrorContext::new_missing(
3068 "LinkAttrs",
3069 "ProtoDownReason",
3070 self.orig_loc,
3071 self.buf.as_ptr() as usize,
3072 ))
3073 }
3074 pub fn get_parent_dev_name(&self) -> Result<&'a CStr, ErrorContext> {
3075 let mut iter = self.clone();
3076 iter.pos = 0;
3077 for attr in iter {
3078 if let Ok(LinkAttrs::ParentDevName(val)) = attr {
3079 return Ok(val);
3080 }
3081 }
3082 Err(ErrorContext::new_missing(
3083 "LinkAttrs",
3084 "ParentDevName",
3085 self.orig_loc,
3086 self.buf.as_ptr() as usize,
3087 ))
3088 }
3089 pub fn get_parent_dev_bus_name(&self) -> Result<&'a CStr, ErrorContext> {
3090 let mut iter = self.clone();
3091 iter.pos = 0;
3092 for attr in iter {
3093 if let Ok(LinkAttrs::ParentDevBusName(val)) = attr {
3094 return Ok(val);
3095 }
3096 }
3097 Err(ErrorContext::new_missing(
3098 "LinkAttrs",
3099 "ParentDevBusName",
3100 self.orig_loc,
3101 self.buf.as_ptr() as usize,
3102 ))
3103 }
3104 pub fn get_gro_max_size(&self) -> Result<u32, ErrorContext> {
3105 let mut iter = self.clone();
3106 iter.pos = 0;
3107 for attr in iter {
3108 if let Ok(LinkAttrs::GroMaxSize(val)) = attr {
3109 return Ok(val);
3110 }
3111 }
3112 Err(ErrorContext::new_missing(
3113 "LinkAttrs",
3114 "GroMaxSize",
3115 self.orig_loc,
3116 self.buf.as_ptr() as usize,
3117 ))
3118 }
3119 pub fn get_tso_max_size(&self) -> Result<u32, ErrorContext> {
3120 let mut iter = self.clone();
3121 iter.pos = 0;
3122 for attr in iter {
3123 if let Ok(LinkAttrs::TsoMaxSize(val)) = attr {
3124 return Ok(val);
3125 }
3126 }
3127 Err(ErrorContext::new_missing(
3128 "LinkAttrs",
3129 "TsoMaxSize",
3130 self.orig_loc,
3131 self.buf.as_ptr() as usize,
3132 ))
3133 }
3134 pub fn get_tso_max_segs(&self) -> Result<u32, ErrorContext> {
3135 let mut iter = self.clone();
3136 iter.pos = 0;
3137 for attr in iter {
3138 if let Ok(LinkAttrs::TsoMaxSegs(val)) = attr {
3139 return Ok(val);
3140 }
3141 }
3142 Err(ErrorContext::new_missing(
3143 "LinkAttrs",
3144 "TsoMaxSegs",
3145 self.orig_loc,
3146 self.buf.as_ptr() as usize,
3147 ))
3148 }
3149 pub fn get_allmulti(&self) -> Result<u32, ErrorContext> {
3150 let mut iter = self.clone();
3151 iter.pos = 0;
3152 for attr in iter {
3153 if let Ok(LinkAttrs::Allmulti(val)) = attr {
3154 return Ok(val);
3155 }
3156 }
3157 Err(ErrorContext::new_missing(
3158 "LinkAttrs",
3159 "Allmulti",
3160 self.orig_loc,
3161 self.buf.as_ptr() as usize,
3162 ))
3163 }
3164 pub fn get_devlink_port(&self) -> Result<&'a [u8], ErrorContext> {
3165 let mut iter = self.clone();
3166 iter.pos = 0;
3167 for attr in iter {
3168 if let Ok(LinkAttrs::DevlinkPort(val)) = attr {
3169 return Ok(val);
3170 }
3171 }
3172 Err(ErrorContext::new_missing(
3173 "LinkAttrs",
3174 "DevlinkPort",
3175 self.orig_loc,
3176 self.buf.as_ptr() as usize,
3177 ))
3178 }
3179 pub fn get_gso_ipv4_max_size(&self) -> Result<u32, ErrorContext> {
3180 let mut iter = self.clone();
3181 iter.pos = 0;
3182 for attr in iter {
3183 if let Ok(LinkAttrs::GsoIpv4MaxSize(val)) = attr {
3184 return Ok(val);
3185 }
3186 }
3187 Err(ErrorContext::new_missing(
3188 "LinkAttrs",
3189 "GsoIpv4MaxSize",
3190 self.orig_loc,
3191 self.buf.as_ptr() as usize,
3192 ))
3193 }
3194 pub fn get_gro_ipv4_max_size(&self) -> Result<u32, ErrorContext> {
3195 let mut iter = self.clone();
3196 iter.pos = 0;
3197 for attr in iter {
3198 if let Ok(LinkAttrs::GroIpv4MaxSize(val)) = attr {
3199 return Ok(val);
3200 }
3201 }
3202 Err(ErrorContext::new_missing(
3203 "LinkAttrs",
3204 "GroIpv4MaxSize",
3205 self.orig_loc,
3206 self.buf.as_ptr() as usize,
3207 ))
3208 }
3209 pub fn get_dpll_pin(&self) -> Result<IterableLinkDpllPinAttrs<'a>, ErrorContext> {
3210 let mut iter = self.clone();
3211 iter.pos = 0;
3212 for attr in iter {
3213 if let Ok(LinkAttrs::DpllPin(val)) = attr {
3214 return Ok(val);
3215 }
3216 }
3217 Err(ErrorContext::new_missing(
3218 "LinkAttrs",
3219 "DpllPin",
3220 self.orig_loc,
3221 self.buf.as_ptr() as usize,
3222 ))
3223 }
3224 #[doc = "EDT offload horizon supported by the device (in nsec).\n"]
3225 pub fn get_max_pacing_offload_horizon(&self) -> Result<u32, ErrorContext> {
3226 let mut iter = self.clone();
3227 iter.pos = 0;
3228 for attr in iter {
3229 if let Ok(LinkAttrs::MaxPacingOffloadHorizon(val)) = attr {
3230 return Ok(val);
3231 }
3232 }
3233 Err(ErrorContext::new_missing(
3234 "LinkAttrs",
3235 "MaxPacingOffloadHorizon",
3236 self.orig_loc,
3237 self.buf.as_ptr() as usize,
3238 ))
3239 }
3240 pub fn get_netns_immutable(&self) -> Result<u8, ErrorContext> {
3241 let mut iter = self.clone();
3242 iter.pos = 0;
3243 for attr in iter {
3244 if let Ok(LinkAttrs::NetnsImmutable(val)) = attr {
3245 return Ok(val);
3246 }
3247 }
3248 Err(ErrorContext::new_missing(
3249 "LinkAttrs",
3250 "NetnsImmutable",
3251 self.orig_loc,
3252 self.buf.as_ptr() as usize,
3253 ))
3254 }
3255 pub fn get_headroom(&self) -> Result<u16, ErrorContext> {
3256 let mut iter = self.clone();
3257 iter.pos = 0;
3258 for attr in iter {
3259 if let Ok(LinkAttrs::Headroom(val)) = attr {
3260 return Ok(val);
3261 }
3262 }
3263 Err(ErrorContext::new_missing(
3264 "LinkAttrs",
3265 "Headroom",
3266 self.orig_loc,
3267 self.buf.as_ptr() as usize,
3268 ))
3269 }
3270 pub fn get_tailroom(&self) -> Result<u16, ErrorContext> {
3271 let mut iter = self.clone();
3272 iter.pos = 0;
3273 for attr in iter {
3274 if let Ok(LinkAttrs::Tailroom(val)) = attr {
3275 return Ok(val);
3276 }
3277 }
3278 Err(ErrorContext::new_missing(
3279 "LinkAttrs",
3280 "Tailroom",
3281 self.orig_loc,
3282 self.buf.as_ptr() as usize,
3283 ))
3284 }
3285}
3286impl LinkAttrs<'_> {
3287 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkAttrs<'a> {
3288 IterableLinkAttrs::with_loc(buf, buf.as_ptr() as usize)
3289 }
3290 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3291 let res = match r#type {
3292 1u16 => "Address",
3293 2u16 => "Broadcast",
3294 3u16 => "Ifname",
3295 4u16 => "Mtu",
3296 5u16 => "Link",
3297 6u16 => "Qdisc",
3298 7u16 => "Stats",
3299 8u16 => "Cost",
3300 9u16 => "Priority",
3301 10u16 => "Master",
3302 11u16 => "Wireless",
3303 12u16 => "Protinfo",
3304 13u16 => "Txqlen",
3305 14u16 => "Map",
3306 15u16 => "Weight",
3307 16u16 => "Operstate",
3308 17u16 => "Linkmode",
3309 18u16 => "Linkinfo",
3310 19u16 => "NetNsPid",
3311 20u16 => "Ifalias",
3312 21u16 => "NumVf",
3313 22u16 => "VfinfoList",
3314 23u16 => "Stats64",
3315 24u16 => "VfPorts",
3316 25u16 => "PortSelf",
3317 26u16 => "AfSpec",
3318 27u16 => "Group",
3319 28u16 => "NetNsFd",
3320 29u16 => "ExtMask",
3321 30u16 => "Promiscuity",
3322 31u16 => "NumTxQueues",
3323 32u16 => "NumRxQueues",
3324 33u16 => "Carrier",
3325 34u16 => "PhysPortId",
3326 35u16 => "CarrierChanges",
3327 36u16 => "PhysSwitchId",
3328 37u16 => "LinkNetnsid",
3329 38u16 => "PhysPortName",
3330 39u16 => "ProtoDown",
3331 40u16 => "GsoMaxSegs",
3332 41u16 => "GsoMaxSize",
3333 42u16 => "Pad",
3334 43u16 => "Xdp",
3335 44u16 => "Event",
3336 45u16 => "NewNetnsid",
3337 46u16 => "TargetNetnsid",
3338 47u16 => "CarrierUpCount",
3339 48u16 => "CarrierDownCount",
3340 49u16 => "NewIfindex",
3341 50u16 => "MinMtu",
3342 51u16 => "MaxMtu",
3343 52u16 => "PropList",
3344 53u16 => "AltIfname",
3345 54u16 => "PermAddress",
3346 55u16 => "ProtoDownReason",
3347 56u16 => "ParentDevName",
3348 57u16 => "ParentDevBusName",
3349 58u16 => "GroMaxSize",
3350 59u16 => "TsoMaxSize",
3351 60u16 => "TsoMaxSegs",
3352 61u16 => "Allmulti",
3353 62u16 => "DevlinkPort",
3354 63u16 => "GsoIpv4MaxSize",
3355 64u16 => "GroIpv4MaxSize",
3356 65u16 => "DpllPin",
3357 66u16 => "MaxPacingOffloadHorizon",
3358 67u16 => "NetnsImmutable",
3359 68u16 => "Headroom",
3360 69u16 => "Tailroom",
3361 _ => return None,
3362 };
3363 Some(res)
3364 }
3365}
3366#[derive(Clone, Copy, Default)]
3367pub struct IterableLinkAttrs<'a> {
3368 buf: &'a [u8],
3369 pos: usize,
3370 orig_loc: usize,
3371}
3372impl<'a> IterableLinkAttrs<'a> {
3373 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3374 Self {
3375 buf,
3376 pos: 0,
3377 orig_loc,
3378 }
3379 }
3380 pub fn get_buf(&self) -> &'a [u8] {
3381 self.buf
3382 }
3383}
3384impl<'a> Iterator for IterableLinkAttrs<'a> {
3385 type Item = Result<LinkAttrs<'a>, ErrorContext>;
3386 fn next(&mut self) -> Option<Self::Item> {
3387 let mut pos;
3388 let mut r#type;
3389 loop {
3390 pos = self.pos;
3391 r#type = None;
3392 if self.buf.len() == self.pos {
3393 return None;
3394 }
3395 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3396 self.pos = self.buf.len();
3397 break;
3398 };
3399 r#type = Some(header.r#type);
3400 let res = match header.r#type {
3401 1u16 => LinkAttrs::Address({
3402 let res = Some(next);
3403 let Some(val) = res else { break };
3404 val
3405 }),
3406 2u16 => LinkAttrs::Broadcast({
3407 let res = Some(next);
3408 let Some(val) = res else { break };
3409 val
3410 }),
3411 3u16 => LinkAttrs::Ifname({
3412 let res = CStr::from_bytes_with_nul(next).ok();
3413 let Some(val) = res else { break };
3414 val
3415 }),
3416 4u16 => LinkAttrs::Mtu({
3417 let res = parse_u32(next);
3418 let Some(val) = res else { break };
3419 val
3420 }),
3421 5u16 => LinkAttrs::Link({
3422 let res = parse_u32(next);
3423 let Some(val) = res else { break };
3424 val
3425 }),
3426 6u16 => LinkAttrs::Qdisc({
3427 let res = CStr::from_bytes_with_nul(next).ok();
3428 let Some(val) = res else { break };
3429 val
3430 }),
3431 7u16 => LinkAttrs::Stats({
3432 let res = Some(RtnlLinkStats::new_from_zeroed(next));
3433 let Some(val) = res else { break };
3434 val
3435 }),
3436 10u16 => LinkAttrs::Master({
3437 let res = parse_u32(next);
3438 let Some(val) = res else { break };
3439 val
3440 }),
3441 11u16 => LinkAttrs::Wireless({
3442 let res = Some(next);
3443 let Some(val) = res else { break };
3444 val
3445 }),
3446 12u16 => LinkAttrs::Protinfo({
3447 let res = Some(next);
3448 let Some(val) = res else { break };
3449 val
3450 }),
3451 13u16 => LinkAttrs::Txqlen({
3452 let res = parse_u32(next);
3453 let Some(val) = res else { break };
3454 val
3455 }),
3456 14u16 => LinkAttrs::Map({
3457 let res = Some(RtnlLinkIfmap::new_from_zeroed(next));
3458 let Some(val) = res else { break };
3459 val
3460 }),
3461 15u16 => LinkAttrs::Weight({
3462 let res = parse_u32(next);
3463 let Some(val) = res else { break };
3464 val
3465 }),
3466 16u16 => LinkAttrs::Operstate({
3467 let res = parse_u8(next);
3468 let Some(val) = res else { break };
3469 val
3470 }),
3471 17u16 => LinkAttrs::Linkmode({
3472 let res = parse_u8(next);
3473 let Some(val) = res else { break };
3474 val
3475 }),
3476 18u16 => LinkAttrs::Linkinfo({
3477 let res = Some(IterableLinkinfoAttrs::with_loc(next, self.orig_loc));
3478 let Some(val) = res else { break };
3479 val
3480 }),
3481 19u16 => LinkAttrs::NetNsPid({
3482 let res = parse_u32(next);
3483 let Some(val) = res else { break };
3484 val
3485 }),
3486 20u16 => LinkAttrs::Ifalias({
3487 let res = CStr::from_bytes_with_nul(next).ok();
3488 let Some(val) = res else { break };
3489 val
3490 }),
3491 21u16 => LinkAttrs::NumVf({
3492 let res = parse_u32(next);
3493 let Some(val) = res else { break };
3494 val
3495 }),
3496 22u16 => LinkAttrs::VfinfoList({
3497 let res = Some(IterableVfinfoListAttrs::with_loc(next, self.orig_loc));
3498 let Some(val) = res else { break };
3499 val
3500 }),
3501 23u16 => LinkAttrs::Stats64({
3502 let res = Some(RtnlLinkStats64::new_from_zeroed(next));
3503 let Some(val) = res else { break };
3504 val
3505 }),
3506 24u16 => LinkAttrs::VfPorts({
3507 let res = Some(IterableVfPortsAttrs::with_loc(next, self.orig_loc));
3508 let Some(val) = res else { break };
3509 val
3510 }),
3511 25u16 => LinkAttrs::PortSelf({
3512 let res = Some(IterablePortSelfAttrs::with_loc(next, self.orig_loc));
3513 let Some(val) = res else { break };
3514 val
3515 }),
3516 26u16 => LinkAttrs::AfSpec({
3517 let res = Some(IterableAfSpecAttrs::with_loc(next, self.orig_loc));
3518 let Some(val) = res else { break };
3519 val
3520 }),
3521 27u16 => LinkAttrs::Group({
3522 let res = parse_u32(next);
3523 let Some(val) = res else { break };
3524 val
3525 }),
3526 28u16 => LinkAttrs::NetNsFd({
3527 let res = parse_u32(next);
3528 let Some(val) = res else { break };
3529 val
3530 }),
3531 29u16 => LinkAttrs::ExtMask({
3532 let res = parse_u32(next);
3533 let Some(val) = res else { break };
3534 val
3535 }),
3536 30u16 => LinkAttrs::Promiscuity({
3537 let res = parse_u32(next);
3538 let Some(val) = res else { break };
3539 val
3540 }),
3541 31u16 => LinkAttrs::NumTxQueues({
3542 let res = parse_u32(next);
3543 let Some(val) = res else { break };
3544 val
3545 }),
3546 32u16 => LinkAttrs::NumRxQueues({
3547 let res = parse_u32(next);
3548 let Some(val) = res else { break };
3549 val
3550 }),
3551 33u16 => LinkAttrs::Carrier({
3552 let res = parse_u8(next);
3553 let Some(val) = res else { break };
3554 val
3555 }),
3556 34u16 => LinkAttrs::PhysPortId({
3557 let res = Some(next);
3558 let Some(val) = res else { break };
3559 val
3560 }),
3561 35u16 => LinkAttrs::CarrierChanges({
3562 let res = parse_u32(next);
3563 let Some(val) = res else { break };
3564 val
3565 }),
3566 36u16 => LinkAttrs::PhysSwitchId({
3567 let res = Some(next);
3568 let Some(val) = res else { break };
3569 val
3570 }),
3571 37u16 => LinkAttrs::LinkNetnsid({
3572 let res = parse_i32(next);
3573 let Some(val) = res else { break };
3574 val
3575 }),
3576 38u16 => LinkAttrs::PhysPortName({
3577 let res = CStr::from_bytes_with_nul(next).ok();
3578 let Some(val) = res else { break };
3579 val
3580 }),
3581 39u16 => LinkAttrs::ProtoDown({
3582 let res = parse_u8(next);
3583 let Some(val) = res else { break };
3584 val
3585 }),
3586 40u16 => LinkAttrs::GsoMaxSegs({
3587 let res = parse_u32(next);
3588 let Some(val) = res else { break };
3589 val
3590 }),
3591 41u16 => LinkAttrs::GsoMaxSize({
3592 let res = parse_u32(next);
3593 let Some(val) = res else { break };
3594 val
3595 }),
3596 42u16 => LinkAttrs::Pad({
3597 let res = Some(next);
3598 let Some(val) = res else { break };
3599 val
3600 }),
3601 43u16 => LinkAttrs::Xdp({
3602 let res = Some(IterableXdpAttrs::with_loc(next, self.orig_loc));
3603 let Some(val) = res else { break };
3604 val
3605 }),
3606 44u16 => LinkAttrs::Event({
3607 let res = parse_u32(next);
3608 let Some(val) = res else { break };
3609 val
3610 }),
3611 45u16 => LinkAttrs::NewNetnsid({
3612 let res = parse_i32(next);
3613 let Some(val) = res else { break };
3614 val
3615 }),
3616 46u16 => LinkAttrs::TargetNetnsid({
3617 let res = parse_i32(next);
3618 let Some(val) = res else { break };
3619 val
3620 }),
3621 47u16 => LinkAttrs::CarrierUpCount({
3622 let res = parse_u32(next);
3623 let Some(val) = res else { break };
3624 val
3625 }),
3626 48u16 => LinkAttrs::CarrierDownCount({
3627 let res = parse_u32(next);
3628 let Some(val) = res else { break };
3629 val
3630 }),
3631 49u16 => LinkAttrs::NewIfindex({
3632 let res = parse_i32(next);
3633 let Some(val) = res else { break };
3634 val
3635 }),
3636 50u16 => LinkAttrs::MinMtu({
3637 let res = parse_u32(next);
3638 let Some(val) = res else { break };
3639 val
3640 }),
3641 51u16 => LinkAttrs::MaxMtu({
3642 let res = parse_u32(next);
3643 let Some(val) = res else { break };
3644 val
3645 }),
3646 52u16 => LinkAttrs::PropList({
3647 let res = Some(IterablePropListLinkAttrs::with_loc(next, self.orig_loc));
3648 let Some(val) = res else { break };
3649 val
3650 }),
3651 53u16 => LinkAttrs::AltIfname({
3652 let res = CStr::from_bytes_with_nul(next).ok();
3653 let Some(val) = res else { break };
3654 val
3655 }),
3656 54u16 => LinkAttrs::PermAddress({
3657 let res = Some(next);
3658 let Some(val) = res else { break };
3659 val
3660 }),
3661 55u16 => LinkAttrs::ProtoDownReason({
3662 let res = CStr::from_bytes_with_nul(next).ok();
3663 let Some(val) = res else { break };
3664 val
3665 }),
3666 56u16 => LinkAttrs::ParentDevName({
3667 let res = CStr::from_bytes_with_nul(next).ok();
3668 let Some(val) = res else { break };
3669 val
3670 }),
3671 57u16 => LinkAttrs::ParentDevBusName({
3672 let res = CStr::from_bytes_with_nul(next).ok();
3673 let Some(val) = res else { break };
3674 val
3675 }),
3676 58u16 => LinkAttrs::GroMaxSize({
3677 let res = parse_u32(next);
3678 let Some(val) = res else { break };
3679 val
3680 }),
3681 59u16 => LinkAttrs::TsoMaxSize({
3682 let res = parse_u32(next);
3683 let Some(val) = res else { break };
3684 val
3685 }),
3686 60u16 => LinkAttrs::TsoMaxSegs({
3687 let res = parse_u32(next);
3688 let Some(val) = res else { break };
3689 val
3690 }),
3691 61u16 => LinkAttrs::Allmulti({
3692 let res = parse_u32(next);
3693 let Some(val) = res else { break };
3694 val
3695 }),
3696 62u16 => LinkAttrs::DevlinkPort({
3697 let res = Some(next);
3698 let Some(val) = res else { break };
3699 val
3700 }),
3701 63u16 => LinkAttrs::GsoIpv4MaxSize({
3702 let res = parse_u32(next);
3703 let Some(val) = res else { break };
3704 val
3705 }),
3706 64u16 => LinkAttrs::GroIpv4MaxSize({
3707 let res = parse_u32(next);
3708 let Some(val) = res else { break };
3709 val
3710 }),
3711 65u16 => LinkAttrs::DpllPin({
3712 let res = Some(IterableLinkDpllPinAttrs::with_loc(next, self.orig_loc));
3713 let Some(val) = res else { break };
3714 val
3715 }),
3716 66u16 => LinkAttrs::MaxPacingOffloadHorizon({
3717 let res = parse_u32(next);
3718 let Some(val) = res else { break };
3719 val
3720 }),
3721 67u16 => LinkAttrs::NetnsImmutable({
3722 let res = parse_u8(next);
3723 let Some(val) = res else { break };
3724 val
3725 }),
3726 68u16 => LinkAttrs::Headroom({
3727 let res = parse_u16(next);
3728 let Some(val) = res else { break };
3729 val
3730 }),
3731 69u16 => LinkAttrs::Tailroom({
3732 let res = parse_u16(next);
3733 let Some(val) = res else { break };
3734 val
3735 }),
3736 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3737 n => continue,
3738 };
3739 return Some(Ok(res));
3740 }
3741 Some(Err(ErrorContext::new(
3742 "LinkAttrs",
3743 r#type.and_then(|t| LinkAttrs::attr_from_type(t)),
3744 self.orig_loc,
3745 self.buf.as_ptr().wrapping_add(pos) as usize,
3746 )))
3747 }
3748}
3749impl<'a> std::fmt::Debug for IterableLinkAttrs<'_> {
3750 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3751 let mut fmt = f.debug_struct("LinkAttrs");
3752 for attr in self.clone() {
3753 let attr = match attr {
3754 Ok(a) => a,
3755 Err(err) => {
3756 fmt.finish()?;
3757 f.write_str("Err(")?;
3758 err.fmt(f)?;
3759 return f.write_str(")");
3760 }
3761 };
3762 match attr {
3763 LinkAttrs::Address(val) => fmt.field("Address", &FormatMac(val)),
3764 LinkAttrs::Broadcast(val) => fmt.field("Broadcast", &FormatMac(val)),
3765 LinkAttrs::Ifname(val) => fmt.field("Ifname", &val),
3766 LinkAttrs::Mtu(val) => fmt.field("Mtu", &val),
3767 LinkAttrs::Link(val) => fmt.field("Link", &val),
3768 LinkAttrs::Qdisc(val) => fmt.field("Qdisc", &val),
3769 LinkAttrs::Stats(val) => fmt.field("Stats", &val),
3770 LinkAttrs::Master(val) => fmt.field("Master", &val),
3771 LinkAttrs::Wireless(val) => fmt.field("Wireless", &val),
3772 LinkAttrs::Protinfo(val) => fmt.field("Protinfo", &val),
3773 LinkAttrs::Txqlen(val) => fmt.field("Txqlen", &val),
3774 LinkAttrs::Map(val) => fmt.field("Map", &val),
3775 LinkAttrs::Weight(val) => fmt.field("Weight", &val),
3776 LinkAttrs::Operstate(val) => fmt.field("Operstate", &val),
3777 LinkAttrs::Linkmode(val) => fmt.field("Linkmode", &val),
3778 LinkAttrs::Linkinfo(val) => fmt.field("Linkinfo", &val),
3779 LinkAttrs::NetNsPid(val) => fmt.field("NetNsPid", &val),
3780 LinkAttrs::Ifalias(val) => fmt.field("Ifalias", &val),
3781 LinkAttrs::NumVf(val) => fmt.field("NumVf", &val),
3782 LinkAttrs::VfinfoList(val) => fmt.field("VfinfoList", &val),
3783 LinkAttrs::Stats64(val) => fmt.field("Stats64", &val),
3784 LinkAttrs::VfPorts(val) => fmt.field("VfPorts", &val),
3785 LinkAttrs::PortSelf(val) => fmt.field("PortSelf", &val),
3786 LinkAttrs::AfSpec(val) => fmt.field("AfSpec", &val),
3787 LinkAttrs::Group(val) => fmt.field("Group", &val),
3788 LinkAttrs::NetNsFd(val) => fmt.field("NetNsFd", &val),
3789 LinkAttrs::ExtMask(val) => {
3790 fmt.field("ExtMask", &FormatFlags(val.into(), RtextFilter::from_value))
3791 }
3792 LinkAttrs::Promiscuity(val) => fmt.field("Promiscuity", &val),
3793 LinkAttrs::NumTxQueues(val) => fmt.field("NumTxQueues", &val),
3794 LinkAttrs::NumRxQueues(val) => fmt.field("NumRxQueues", &val),
3795 LinkAttrs::Carrier(val) => fmt.field("Carrier", &val),
3796 LinkAttrs::PhysPortId(val) => fmt.field("PhysPortId", &val),
3797 LinkAttrs::CarrierChanges(val) => fmt.field("CarrierChanges", &val),
3798 LinkAttrs::PhysSwitchId(val) => fmt.field("PhysSwitchId", &val),
3799 LinkAttrs::LinkNetnsid(val) => fmt.field("LinkNetnsid", &val),
3800 LinkAttrs::PhysPortName(val) => fmt.field("PhysPortName", &val),
3801 LinkAttrs::ProtoDown(val) => fmt.field("ProtoDown", &val),
3802 LinkAttrs::GsoMaxSegs(val) => fmt.field("GsoMaxSegs", &val),
3803 LinkAttrs::GsoMaxSize(val) => fmt.field("GsoMaxSize", &val),
3804 LinkAttrs::Pad(val) => fmt.field("Pad", &val),
3805 LinkAttrs::Xdp(val) => fmt.field("Xdp", &val),
3806 LinkAttrs::Event(val) => fmt.field("Event", &val),
3807 LinkAttrs::NewNetnsid(val) => fmt.field("NewNetnsid", &val),
3808 LinkAttrs::TargetNetnsid(val) => fmt.field("TargetNetnsid", &val),
3809 LinkAttrs::CarrierUpCount(val) => fmt.field("CarrierUpCount", &val),
3810 LinkAttrs::CarrierDownCount(val) => fmt.field("CarrierDownCount", &val),
3811 LinkAttrs::NewIfindex(val) => fmt.field("NewIfindex", &val),
3812 LinkAttrs::MinMtu(val) => fmt.field("MinMtu", &val),
3813 LinkAttrs::MaxMtu(val) => fmt.field("MaxMtu", &val),
3814 LinkAttrs::PropList(val) => fmt.field("PropList", &val),
3815 LinkAttrs::AltIfname(val) => fmt.field("AltIfname", &val),
3816 LinkAttrs::PermAddress(val) => fmt.field("PermAddress", &FormatMac(val)),
3817 LinkAttrs::ProtoDownReason(val) => fmt.field("ProtoDownReason", &val),
3818 LinkAttrs::ParentDevName(val) => fmt.field("ParentDevName", &val),
3819 LinkAttrs::ParentDevBusName(val) => fmt.field("ParentDevBusName", &val),
3820 LinkAttrs::GroMaxSize(val) => fmt.field("GroMaxSize", &val),
3821 LinkAttrs::TsoMaxSize(val) => fmt.field("TsoMaxSize", &val),
3822 LinkAttrs::TsoMaxSegs(val) => fmt.field("TsoMaxSegs", &val),
3823 LinkAttrs::Allmulti(val) => fmt.field("Allmulti", &val),
3824 LinkAttrs::DevlinkPort(val) => fmt.field("DevlinkPort", &val),
3825 LinkAttrs::GsoIpv4MaxSize(val) => fmt.field("GsoIpv4MaxSize", &val),
3826 LinkAttrs::GroIpv4MaxSize(val) => fmt.field("GroIpv4MaxSize", &val),
3827 LinkAttrs::DpllPin(val) => fmt.field("DpllPin", &val),
3828 LinkAttrs::MaxPacingOffloadHorizon(val) => {
3829 fmt.field("MaxPacingOffloadHorizon", &val)
3830 }
3831 LinkAttrs::NetnsImmutable(val) => fmt.field("NetnsImmutable", &val),
3832 LinkAttrs::Headroom(val) => fmt.field("Headroom", &val),
3833 LinkAttrs::Tailroom(val) => fmt.field("Tailroom", &val),
3834 };
3835 }
3836 fmt.finish()
3837 }
3838}
3839impl IterableLinkAttrs<'_> {
3840 pub fn lookup_attr(
3841 &self,
3842 offset: usize,
3843 missing_type: Option<u16>,
3844 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3845 let mut stack = Vec::new();
3846 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3847 if missing_type.is_some() && cur == offset {
3848 stack.push(("LinkAttrs", offset));
3849 return (
3850 stack,
3851 missing_type.and_then(|t| LinkAttrs::attr_from_type(t)),
3852 );
3853 }
3854 if cur > offset || cur + self.buf.len() < offset {
3855 return (stack, None);
3856 }
3857 let mut attrs = self.clone();
3858 let mut last_off = cur + attrs.pos;
3859 let mut missing = None;
3860 while let Some(attr) = attrs.next() {
3861 let Ok(attr) = attr else { break };
3862 match attr {
3863 LinkAttrs::Address(val) => {
3864 if last_off == offset {
3865 stack.push(("Address", last_off));
3866 break;
3867 }
3868 }
3869 LinkAttrs::Broadcast(val) => {
3870 if last_off == offset {
3871 stack.push(("Broadcast", last_off));
3872 break;
3873 }
3874 }
3875 LinkAttrs::Ifname(val) => {
3876 if last_off == offset {
3877 stack.push(("Ifname", last_off));
3878 break;
3879 }
3880 }
3881 LinkAttrs::Mtu(val) => {
3882 if last_off == offset {
3883 stack.push(("Mtu", last_off));
3884 break;
3885 }
3886 }
3887 LinkAttrs::Link(val) => {
3888 if last_off == offset {
3889 stack.push(("Link", last_off));
3890 break;
3891 }
3892 }
3893 LinkAttrs::Qdisc(val) => {
3894 if last_off == offset {
3895 stack.push(("Qdisc", last_off));
3896 break;
3897 }
3898 }
3899 LinkAttrs::Stats(val) => {
3900 if last_off == offset {
3901 stack.push(("Stats", last_off));
3902 break;
3903 }
3904 }
3905 LinkAttrs::Master(val) => {
3906 if last_off == offset {
3907 stack.push(("Master", last_off));
3908 break;
3909 }
3910 }
3911 LinkAttrs::Wireless(val) => {
3912 if last_off == offset {
3913 stack.push(("Wireless", last_off));
3914 break;
3915 }
3916 }
3917 LinkAttrs::Protinfo(val) => {
3918 if last_off == offset {
3919 stack.push(("Protinfo", last_off));
3920 break;
3921 }
3922 }
3923 LinkAttrs::Txqlen(val) => {
3924 if last_off == offset {
3925 stack.push(("Txqlen", last_off));
3926 break;
3927 }
3928 }
3929 LinkAttrs::Map(val) => {
3930 if last_off == offset {
3931 stack.push(("Map", last_off));
3932 break;
3933 }
3934 }
3935 LinkAttrs::Weight(val) => {
3936 if last_off == offset {
3937 stack.push(("Weight", last_off));
3938 break;
3939 }
3940 }
3941 LinkAttrs::Operstate(val) => {
3942 if last_off == offset {
3943 stack.push(("Operstate", last_off));
3944 break;
3945 }
3946 }
3947 LinkAttrs::Linkmode(val) => {
3948 if last_off == offset {
3949 stack.push(("Linkmode", last_off));
3950 break;
3951 }
3952 }
3953 LinkAttrs::Linkinfo(val) => {
3954 (stack, missing) = val.lookup_attr(offset, missing_type);
3955 if !stack.is_empty() {
3956 break;
3957 }
3958 }
3959 LinkAttrs::NetNsPid(val) => {
3960 if last_off == offset {
3961 stack.push(("NetNsPid", last_off));
3962 break;
3963 }
3964 }
3965 LinkAttrs::Ifalias(val) => {
3966 if last_off == offset {
3967 stack.push(("Ifalias", last_off));
3968 break;
3969 }
3970 }
3971 LinkAttrs::NumVf(val) => {
3972 if last_off == offset {
3973 stack.push(("NumVf", last_off));
3974 break;
3975 }
3976 }
3977 LinkAttrs::VfinfoList(val) => {
3978 (stack, missing) = val.lookup_attr(offset, missing_type);
3979 if !stack.is_empty() {
3980 break;
3981 }
3982 }
3983 LinkAttrs::Stats64(val) => {
3984 if last_off == offset {
3985 stack.push(("Stats64", last_off));
3986 break;
3987 }
3988 }
3989 LinkAttrs::VfPorts(val) => {
3990 (stack, missing) = val.lookup_attr(offset, missing_type);
3991 if !stack.is_empty() {
3992 break;
3993 }
3994 }
3995 LinkAttrs::PortSelf(val) => {
3996 (stack, missing) = val.lookup_attr(offset, missing_type);
3997 if !stack.is_empty() {
3998 break;
3999 }
4000 }
4001 LinkAttrs::AfSpec(val) => {
4002 (stack, missing) = val.lookup_attr(offset, missing_type);
4003 if !stack.is_empty() {
4004 break;
4005 }
4006 }
4007 LinkAttrs::Group(val) => {
4008 if last_off == offset {
4009 stack.push(("Group", last_off));
4010 break;
4011 }
4012 }
4013 LinkAttrs::NetNsFd(val) => {
4014 if last_off == offset {
4015 stack.push(("NetNsFd", last_off));
4016 break;
4017 }
4018 }
4019 LinkAttrs::ExtMask(val) => {
4020 if last_off == offset {
4021 stack.push(("ExtMask", last_off));
4022 break;
4023 }
4024 }
4025 LinkAttrs::Promiscuity(val) => {
4026 if last_off == offset {
4027 stack.push(("Promiscuity", last_off));
4028 break;
4029 }
4030 }
4031 LinkAttrs::NumTxQueues(val) => {
4032 if last_off == offset {
4033 stack.push(("NumTxQueues", last_off));
4034 break;
4035 }
4036 }
4037 LinkAttrs::NumRxQueues(val) => {
4038 if last_off == offset {
4039 stack.push(("NumRxQueues", last_off));
4040 break;
4041 }
4042 }
4043 LinkAttrs::Carrier(val) => {
4044 if last_off == offset {
4045 stack.push(("Carrier", last_off));
4046 break;
4047 }
4048 }
4049 LinkAttrs::PhysPortId(val) => {
4050 if last_off == offset {
4051 stack.push(("PhysPortId", last_off));
4052 break;
4053 }
4054 }
4055 LinkAttrs::CarrierChanges(val) => {
4056 if last_off == offset {
4057 stack.push(("CarrierChanges", last_off));
4058 break;
4059 }
4060 }
4061 LinkAttrs::PhysSwitchId(val) => {
4062 if last_off == offset {
4063 stack.push(("PhysSwitchId", last_off));
4064 break;
4065 }
4066 }
4067 LinkAttrs::LinkNetnsid(val) => {
4068 if last_off == offset {
4069 stack.push(("LinkNetnsid", last_off));
4070 break;
4071 }
4072 }
4073 LinkAttrs::PhysPortName(val) => {
4074 if last_off == offset {
4075 stack.push(("PhysPortName", last_off));
4076 break;
4077 }
4078 }
4079 LinkAttrs::ProtoDown(val) => {
4080 if last_off == offset {
4081 stack.push(("ProtoDown", last_off));
4082 break;
4083 }
4084 }
4085 LinkAttrs::GsoMaxSegs(val) => {
4086 if last_off == offset {
4087 stack.push(("GsoMaxSegs", last_off));
4088 break;
4089 }
4090 }
4091 LinkAttrs::GsoMaxSize(val) => {
4092 if last_off == offset {
4093 stack.push(("GsoMaxSize", last_off));
4094 break;
4095 }
4096 }
4097 LinkAttrs::Pad(val) => {
4098 if last_off == offset {
4099 stack.push(("Pad", last_off));
4100 break;
4101 }
4102 }
4103 LinkAttrs::Xdp(val) => {
4104 (stack, missing) = val.lookup_attr(offset, missing_type);
4105 if !stack.is_empty() {
4106 break;
4107 }
4108 }
4109 LinkAttrs::Event(val) => {
4110 if last_off == offset {
4111 stack.push(("Event", last_off));
4112 break;
4113 }
4114 }
4115 LinkAttrs::NewNetnsid(val) => {
4116 if last_off == offset {
4117 stack.push(("NewNetnsid", last_off));
4118 break;
4119 }
4120 }
4121 LinkAttrs::TargetNetnsid(val) => {
4122 if last_off == offset {
4123 stack.push(("TargetNetnsid", last_off));
4124 break;
4125 }
4126 }
4127 LinkAttrs::CarrierUpCount(val) => {
4128 if last_off == offset {
4129 stack.push(("CarrierUpCount", last_off));
4130 break;
4131 }
4132 }
4133 LinkAttrs::CarrierDownCount(val) => {
4134 if last_off == offset {
4135 stack.push(("CarrierDownCount", last_off));
4136 break;
4137 }
4138 }
4139 LinkAttrs::NewIfindex(val) => {
4140 if last_off == offset {
4141 stack.push(("NewIfindex", last_off));
4142 break;
4143 }
4144 }
4145 LinkAttrs::MinMtu(val) => {
4146 if last_off == offset {
4147 stack.push(("MinMtu", last_off));
4148 break;
4149 }
4150 }
4151 LinkAttrs::MaxMtu(val) => {
4152 if last_off == offset {
4153 stack.push(("MaxMtu", last_off));
4154 break;
4155 }
4156 }
4157 LinkAttrs::PropList(val) => {
4158 (stack, missing) = val.lookup_attr(offset, missing_type);
4159 if !stack.is_empty() {
4160 break;
4161 }
4162 }
4163 LinkAttrs::AltIfname(val) => {
4164 if last_off == offset {
4165 stack.push(("AltIfname", last_off));
4166 break;
4167 }
4168 }
4169 LinkAttrs::PermAddress(val) => {
4170 if last_off == offset {
4171 stack.push(("PermAddress", last_off));
4172 break;
4173 }
4174 }
4175 LinkAttrs::ProtoDownReason(val) => {
4176 if last_off == offset {
4177 stack.push(("ProtoDownReason", last_off));
4178 break;
4179 }
4180 }
4181 LinkAttrs::ParentDevName(val) => {
4182 if last_off == offset {
4183 stack.push(("ParentDevName", last_off));
4184 break;
4185 }
4186 }
4187 LinkAttrs::ParentDevBusName(val) => {
4188 if last_off == offset {
4189 stack.push(("ParentDevBusName", last_off));
4190 break;
4191 }
4192 }
4193 LinkAttrs::GroMaxSize(val) => {
4194 if last_off == offset {
4195 stack.push(("GroMaxSize", last_off));
4196 break;
4197 }
4198 }
4199 LinkAttrs::TsoMaxSize(val) => {
4200 if last_off == offset {
4201 stack.push(("TsoMaxSize", last_off));
4202 break;
4203 }
4204 }
4205 LinkAttrs::TsoMaxSegs(val) => {
4206 if last_off == offset {
4207 stack.push(("TsoMaxSegs", last_off));
4208 break;
4209 }
4210 }
4211 LinkAttrs::Allmulti(val) => {
4212 if last_off == offset {
4213 stack.push(("Allmulti", last_off));
4214 break;
4215 }
4216 }
4217 LinkAttrs::DevlinkPort(val) => {
4218 if last_off == offset {
4219 stack.push(("DevlinkPort", last_off));
4220 break;
4221 }
4222 }
4223 LinkAttrs::GsoIpv4MaxSize(val) => {
4224 if last_off == offset {
4225 stack.push(("GsoIpv4MaxSize", last_off));
4226 break;
4227 }
4228 }
4229 LinkAttrs::GroIpv4MaxSize(val) => {
4230 if last_off == offset {
4231 stack.push(("GroIpv4MaxSize", last_off));
4232 break;
4233 }
4234 }
4235 LinkAttrs::DpllPin(val) => {
4236 (stack, missing) = val.lookup_attr(offset, missing_type);
4237 if !stack.is_empty() {
4238 break;
4239 }
4240 }
4241 LinkAttrs::MaxPacingOffloadHorizon(val) => {
4242 if last_off == offset {
4243 stack.push(("MaxPacingOffloadHorizon", last_off));
4244 break;
4245 }
4246 }
4247 LinkAttrs::NetnsImmutable(val) => {
4248 if last_off == offset {
4249 stack.push(("NetnsImmutable", last_off));
4250 break;
4251 }
4252 }
4253 LinkAttrs::Headroom(val) => {
4254 if last_off == offset {
4255 stack.push(("Headroom", last_off));
4256 break;
4257 }
4258 }
4259 LinkAttrs::Tailroom(val) => {
4260 if last_off == offset {
4261 stack.push(("Tailroom", last_off));
4262 break;
4263 }
4264 }
4265 _ => {}
4266 };
4267 last_off = cur + attrs.pos;
4268 }
4269 if !stack.is_empty() {
4270 stack.push(("LinkAttrs", cur));
4271 }
4272 (stack, missing)
4273 }
4274}
4275#[derive(Clone)]
4276pub enum PropListLinkAttrs<'a> {
4277 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4278 AltIfname(&'a CStr),
4279}
4280impl<'a> IterablePropListLinkAttrs<'a> {
4281 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4282 pub fn get_alt_ifname(&self) -> MultiAttrIterable<Self, PropListLinkAttrs<'a>, &'a CStr> {
4283 MultiAttrIterable::new(self.clone(), |variant| {
4284 if let PropListLinkAttrs::AltIfname(val) = variant {
4285 Some(val)
4286 } else {
4287 None
4288 }
4289 })
4290 }
4291}
4292impl PropListLinkAttrs<'_> {
4293 pub fn new<'a>(buf: &'a [u8]) -> IterablePropListLinkAttrs<'a> {
4294 IterablePropListLinkAttrs::with_loc(buf, buf.as_ptr() as usize)
4295 }
4296 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4297 LinkAttrs::attr_from_type(r#type)
4298 }
4299}
4300#[derive(Clone, Copy, Default)]
4301pub struct IterablePropListLinkAttrs<'a> {
4302 buf: &'a [u8],
4303 pos: usize,
4304 orig_loc: usize,
4305}
4306impl<'a> IterablePropListLinkAttrs<'a> {
4307 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4308 Self {
4309 buf,
4310 pos: 0,
4311 orig_loc,
4312 }
4313 }
4314 pub fn get_buf(&self) -> &'a [u8] {
4315 self.buf
4316 }
4317}
4318impl<'a> Iterator for IterablePropListLinkAttrs<'a> {
4319 type Item = Result<PropListLinkAttrs<'a>, ErrorContext>;
4320 fn next(&mut self) -> Option<Self::Item> {
4321 let mut pos;
4322 let mut r#type;
4323 loop {
4324 pos = self.pos;
4325 r#type = None;
4326 if self.buf.len() == self.pos {
4327 return None;
4328 }
4329 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4330 self.pos = self.buf.len();
4331 break;
4332 };
4333 r#type = Some(header.r#type);
4334 let res = match header.r#type {
4335 53u16 => PropListLinkAttrs::AltIfname({
4336 let res = CStr::from_bytes_with_nul(next).ok();
4337 let Some(val) = res else { break };
4338 val
4339 }),
4340 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4341 n => continue,
4342 };
4343 return Some(Ok(res));
4344 }
4345 Some(Err(ErrorContext::new(
4346 "PropListLinkAttrs",
4347 r#type.and_then(|t| PropListLinkAttrs::attr_from_type(t)),
4348 self.orig_loc,
4349 self.buf.as_ptr().wrapping_add(pos) as usize,
4350 )))
4351 }
4352}
4353impl<'a> std::fmt::Debug for IterablePropListLinkAttrs<'_> {
4354 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4355 let mut fmt = f.debug_struct("PropListLinkAttrs");
4356 for attr in self.clone() {
4357 let attr = match attr {
4358 Ok(a) => a,
4359 Err(err) => {
4360 fmt.finish()?;
4361 f.write_str("Err(")?;
4362 err.fmt(f)?;
4363 return f.write_str(")");
4364 }
4365 };
4366 match attr {
4367 PropListLinkAttrs::AltIfname(val) => fmt.field("AltIfname", &val),
4368 };
4369 }
4370 fmt.finish()
4371 }
4372}
4373impl IterablePropListLinkAttrs<'_> {
4374 pub fn lookup_attr(
4375 &self,
4376 offset: usize,
4377 missing_type: Option<u16>,
4378 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4379 let mut stack = Vec::new();
4380 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4381 if missing_type.is_some() && cur == offset {
4382 stack.push(("PropListLinkAttrs", offset));
4383 return (
4384 stack,
4385 missing_type.and_then(|t| PropListLinkAttrs::attr_from_type(t)),
4386 );
4387 }
4388 if cur > offset || cur + self.buf.len() < offset {
4389 return (stack, None);
4390 }
4391 let mut attrs = self.clone();
4392 let mut last_off = cur + attrs.pos;
4393 while let Some(attr) = attrs.next() {
4394 let Ok(attr) = attr else { break };
4395 match attr {
4396 PropListLinkAttrs::AltIfname(val) => {
4397 if last_off == offset {
4398 stack.push(("AltIfname", last_off));
4399 break;
4400 }
4401 }
4402 _ => {}
4403 };
4404 last_off = cur + attrs.pos;
4405 }
4406 if !stack.is_empty() {
4407 stack.push(("PropListLinkAttrs", cur));
4408 }
4409 (stack, None)
4410 }
4411}
4412#[derive(Clone)]
4413pub enum AfSpecAttrs<'a> {
4414 Inet(IterableIflaAttrs<'a>),
4415 Inet6(IterableIfla6Attrs<'a>),
4416 Mctp(IterableMctpAttrs<'a>),
4417}
4418impl<'a> IterableAfSpecAttrs<'a> {
4419 pub fn get_inet(&self) -> Result<IterableIflaAttrs<'a>, ErrorContext> {
4420 let mut iter = self.clone();
4421 iter.pos = 0;
4422 for attr in iter {
4423 if let Ok(AfSpecAttrs::Inet(val)) = attr {
4424 return Ok(val);
4425 }
4426 }
4427 Err(ErrorContext::new_missing(
4428 "AfSpecAttrs",
4429 "Inet",
4430 self.orig_loc,
4431 self.buf.as_ptr() as usize,
4432 ))
4433 }
4434 pub fn get_inet6(&self) -> Result<IterableIfla6Attrs<'a>, ErrorContext> {
4435 let mut iter = self.clone();
4436 iter.pos = 0;
4437 for attr in iter {
4438 if let Ok(AfSpecAttrs::Inet6(val)) = attr {
4439 return Ok(val);
4440 }
4441 }
4442 Err(ErrorContext::new_missing(
4443 "AfSpecAttrs",
4444 "Inet6",
4445 self.orig_loc,
4446 self.buf.as_ptr() as usize,
4447 ))
4448 }
4449 pub fn get_mctp(&self) -> Result<IterableMctpAttrs<'a>, ErrorContext> {
4450 let mut iter = self.clone();
4451 iter.pos = 0;
4452 for attr in iter {
4453 if let Ok(AfSpecAttrs::Mctp(val)) = attr {
4454 return Ok(val);
4455 }
4456 }
4457 Err(ErrorContext::new_missing(
4458 "AfSpecAttrs",
4459 "Mctp",
4460 self.orig_loc,
4461 self.buf.as_ptr() as usize,
4462 ))
4463 }
4464}
4465impl AfSpecAttrs<'_> {
4466 pub fn new<'a>(buf: &'a [u8]) -> IterableAfSpecAttrs<'a> {
4467 IterableAfSpecAttrs::with_loc(buf, buf.as_ptr() as usize)
4468 }
4469 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4470 let res = match r#type {
4471 2u16 => "Inet",
4472 10u16 => "Inet6",
4473 45u16 => "Mctp",
4474 _ => return None,
4475 };
4476 Some(res)
4477 }
4478}
4479#[derive(Clone, Copy, Default)]
4480pub struct IterableAfSpecAttrs<'a> {
4481 buf: &'a [u8],
4482 pos: usize,
4483 orig_loc: usize,
4484}
4485impl<'a> IterableAfSpecAttrs<'a> {
4486 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4487 Self {
4488 buf,
4489 pos: 0,
4490 orig_loc,
4491 }
4492 }
4493 pub fn get_buf(&self) -> &'a [u8] {
4494 self.buf
4495 }
4496}
4497impl<'a> Iterator for IterableAfSpecAttrs<'a> {
4498 type Item = Result<AfSpecAttrs<'a>, ErrorContext>;
4499 fn next(&mut self) -> Option<Self::Item> {
4500 let mut pos;
4501 let mut r#type;
4502 loop {
4503 pos = self.pos;
4504 r#type = None;
4505 if self.buf.len() == self.pos {
4506 return None;
4507 }
4508 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4509 self.pos = self.buf.len();
4510 break;
4511 };
4512 r#type = Some(header.r#type);
4513 let res = match header.r#type {
4514 2u16 => AfSpecAttrs::Inet({
4515 let res = Some(IterableIflaAttrs::with_loc(next, self.orig_loc));
4516 let Some(val) = res else { break };
4517 val
4518 }),
4519 10u16 => AfSpecAttrs::Inet6({
4520 let res = Some(IterableIfla6Attrs::with_loc(next, self.orig_loc));
4521 let Some(val) = res else { break };
4522 val
4523 }),
4524 45u16 => AfSpecAttrs::Mctp({
4525 let res = Some(IterableMctpAttrs::with_loc(next, self.orig_loc));
4526 let Some(val) = res else { break };
4527 val
4528 }),
4529 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4530 n => continue,
4531 };
4532 return Some(Ok(res));
4533 }
4534 Some(Err(ErrorContext::new(
4535 "AfSpecAttrs",
4536 r#type.and_then(|t| AfSpecAttrs::attr_from_type(t)),
4537 self.orig_loc,
4538 self.buf.as_ptr().wrapping_add(pos) as usize,
4539 )))
4540 }
4541}
4542impl<'a> std::fmt::Debug for IterableAfSpecAttrs<'_> {
4543 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4544 let mut fmt = f.debug_struct("AfSpecAttrs");
4545 for attr in self.clone() {
4546 let attr = match attr {
4547 Ok(a) => a,
4548 Err(err) => {
4549 fmt.finish()?;
4550 f.write_str("Err(")?;
4551 err.fmt(f)?;
4552 return f.write_str(")");
4553 }
4554 };
4555 match attr {
4556 AfSpecAttrs::Inet(val) => fmt.field("Inet", &val),
4557 AfSpecAttrs::Inet6(val) => fmt.field("Inet6", &val),
4558 AfSpecAttrs::Mctp(val) => fmt.field("Mctp", &val),
4559 };
4560 }
4561 fmt.finish()
4562 }
4563}
4564impl IterableAfSpecAttrs<'_> {
4565 pub fn lookup_attr(
4566 &self,
4567 offset: usize,
4568 missing_type: Option<u16>,
4569 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4570 let mut stack = Vec::new();
4571 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4572 if missing_type.is_some() && cur == offset {
4573 stack.push(("AfSpecAttrs", offset));
4574 return (
4575 stack,
4576 missing_type.and_then(|t| AfSpecAttrs::attr_from_type(t)),
4577 );
4578 }
4579 if cur > offset || cur + self.buf.len() < offset {
4580 return (stack, None);
4581 }
4582 let mut attrs = self.clone();
4583 let mut last_off = cur + attrs.pos;
4584 let mut missing = None;
4585 while let Some(attr) = attrs.next() {
4586 let Ok(attr) = attr else { break };
4587 match attr {
4588 AfSpecAttrs::Inet(val) => {
4589 (stack, missing) = val.lookup_attr(offset, missing_type);
4590 if !stack.is_empty() {
4591 break;
4592 }
4593 }
4594 AfSpecAttrs::Inet6(val) => {
4595 (stack, missing) = val.lookup_attr(offset, missing_type);
4596 if !stack.is_empty() {
4597 break;
4598 }
4599 }
4600 AfSpecAttrs::Mctp(val) => {
4601 (stack, missing) = val.lookup_attr(offset, missing_type);
4602 if !stack.is_empty() {
4603 break;
4604 }
4605 }
4606 _ => {}
4607 };
4608 last_off = cur + attrs.pos;
4609 }
4610 if !stack.is_empty() {
4611 stack.push(("AfSpecAttrs", cur));
4612 }
4613 (stack, missing)
4614 }
4615}
4616#[derive(Clone)]
4617pub enum VfinfoListAttrs<'a> {
4618 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4619 Info(IterableVfinfoAttrs<'a>),
4620}
4621impl<'a> IterableVfinfoListAttrs<'a> {
4622 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4623 pub fn get_info(
4624 &self,
4625 ) -> MultiAttrIterable<Self, VfinfoListAttrs<'a>, IterableVfinfoAttrs<'a>> {
4626 MultiAttrIterable::new(self.clone(), |variant| {
4627 if let VfinfoListAttrs::Info(val) = variant {
4628 Some(val)
4629 } else {
4630 None
4631 }
4632 })
4633 }
4634}
4635impl VfinfoListAttrs<'_> {
4636 pub fn new<'a>(buf: &'a [u8]) -> IterableVfinfoListAttrs<'a> {
4637 IterableVfinfoListAttrs::with_loc(buf, buf.as_ptr() as usize)
4638 }
4639 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4640 let res = match r#type {
4641 1u16 => "Info",
4642 _ => return None,
4643 };
4644 Some(res)
4645 }
4646}
4647#[derive(Clone, Copy, Default)]
4648pub struct IterableVfinfoListAttrs<'a> {
4649 buf: &'a [u8],
4650 pos: usize,
4651 orig_loc: usize,
4652}
4653impl<'a> IterableVfinfoListAttrs<'a> {
4654 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4655 Self {
4656 buf,
4657 pos: 0,
4658 orig_loc,
4659 }
4660 }
4661 pub fn get_buf(&self) -> &'a [u8] {
4662 self.buf
4663 }
4664}
4665impl<'a> Iterator for IterableVfinfoListAttrs<'a> {
4666 type Item = Result<VfinfoListAttrs<'a>, ErrorContext>;
4667 fn next(&mut self) -> Option<Self::Item> {
4668 let mut pos;
4669 let mut r#type;
4670 loop {
4671 pos = self.pos;
4672 r#type = None;
4673 if self.buf.len() == self.pos {
4674 return None;
4675 }
4676 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4677 self.pos = self.buf.len();
4678 break;
4679 };
4680 r#type = Some(header.r#type);
4681 let res = match header.r#type {
4682 1u16 => VfinfoListAttrs::Info({
4683 let res = Some(IterableVfinfoAttrs::with_loc(next, self.orig_loc));
4684 let Some(val) = res else { break };
4685 val
4686 }),
4687 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4688 n => continue,
4689 };
4690 return Some(Ok(res));
4691 }
4692 Some(Err(ErrorContext::new(
4693 "VfinfoListAttrs",
4694 r#type.and_then(|t| VfinfoListAttrs::attr_from_type(t)),
4695 self.orig_loc,
4696 self.buf.as_ptr().wrapping_add(pos) as usize,
4697 )))
4698 }
4699}
4700impl<'a> std::fmt::Debug for IterableVfinfoListAttrs<'_> {
4701 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4702 let mut fmt = f.debug_struct("VfinfoListAttrs");
4703 for attr in self.clone() {
4704 let attr = match attr {
4705 Ok(a) => a,
4706 Err(err) => {
4707 fmt.finish()?;
4708 f.write_str("Err(")?;
4709 err.fmt(f)?;
4710 return f.write_str(")");
4711 }
4712 };
4713 match attr {
4714 VfinfoListAttrs::Info(val) => fmt.field("Info", &val),
4715 };
4716 }
4717 fmt.finish()
4718 }
4719}
4720impl IterableVfinfoListAttrs<'_> {
4721 pub fn lookup_attr(
4722 &self,
4723 offset: usize,
4724 missing_type: Option<u16>,
4725 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4726 let mut stack = Vec::new();
4727 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4728 if missing_type.is_some() && cur == offset {
4729 stack.push(("VfinfoListAttrs", offset));
4730 return (
4731 stack,
4732 missing_type.and_then(|t| VfinfoListAttrs::attr_from_type(t)),
4733 );
4734 }
4735 if cur > offset || cur + self.buf.len() < offset {
4736 return (stack, None);
4737 }
4738 let mut attrs = self.clone();
4739 let mut last_off = cur + attrs.pos;
4740 let mut missing = None;
4741 while let Some(attr) = attrs.next() {
4742 let Ok(attr) = attr else { break };
4743 match attr {
4744 VfinfoListAttrs::Info(val) => {
4745 (stack, missing) = val.lookup_attr(offset, missing_type);
4746 if !stack.is_empty() {
4747 break;
4748 }
4749 }
4750 _ => {}
4751 };
4752 last_off = cur + attrs.pos;
4753 }
4754 if !stack.is_empty() {
4755 stack.push(("VfinfoListAttrs", cur));
4756 }
4757 (stack, missing)
4758 }
4759}
4760#[derive(Clone)]
4761pub enum VfinfoAttrs<'a> {
4762 Mac(IflaVfMac),
4763 Vlan(IflaVfVlan),
4764 TxRate(IflaVfTxRate),
4765 Spoofchk(IflaVfSpoofchk),
4766 LinkState(IflaVfLinkState),
4767 Rate(IflaVfRate),
4768 RssQueryEn(IflaVfRssQueryEn),
4769 Stats(IterableVfStatsAttrs<'a>),
4770 Trust(IflaVfTrust),
4771 IbNodeGuid(IflaVfGuid),
4772 IbPortGuid(IflaVfGuid),
4773 VlanList(IterableVfVlanAttrs<'a>),
4774 Broadcast(&'a [u8]),
4775}
4776impl<'a> IterableVfinfoAttrs<'a> {
4777 pub fn get_mac(&self) -> Result<IflaVfMac, ErrorContext> {
4778 let mut iter = self.clone();
4779 iter.pos = 0;
4780 for attr in iter {
4781 if let Ok(VfinfoAttrs::Mac(val)) = attr {
4782 return Ok(val);
4783 }
4784 }
4785 Err(ErrorContext::new_missing(
4786 "VfinfoAttrs",
4787 "Mac",
4788 self.orig_loc,
4789 self.buf.as_ptr() as usize,
4790 ))
4791 }
4792 pub fn get_vlan(&self) -> Result<IflaVfVlan, ErrorContext> {
4793 let mut iter = self.clone();
4794 iter.pos = 0;
4795 for attr in iter {
4796 if let Ok(VfinfoAttrs::Vlan(val)) = attr {
4797 return Ok(val);
4798 }
4799 }
4800 Err(ErrorContext::new_missing(
4801 "VfinfoAttrs",
4802 "Vlan",
4803 self.orig_loc,
4804 self.buf.as_ptr() as usize,
4805 ))
4806 }
4807 pub fn get_tx_rate(&self) -> Result<IflaVfTxRate, ErrorContext> {
4808 let mut iter = self.clone();
4809 iter.pos = 0;
4810 for attr in iter {
4811 if let Ok(VfinfoAttrs::TxRate(val)) = attr {
4812 return Ok(val);
4813 }
4814 }
4815 Err(ErrorContext::new_missing(
4816 "VfinfoAttrs",
4817 "TxRate",
4818 self.orig_loc,
4819 self.buf.as_ptr() as usize,
4820 ))
4821 }
4822 pub fn get_spoofchk(&self) -> Result<IflaVfSpoofchk, ErrorContext> {
4823 let mut iter = self.clone();
4824 iter.pos = 0;
4825 for attr in iter {
4826 if let Ok(VfinfoAttrs::Spoofchk(val)) = attr {
4827 return Ok(val);
4828 }
4829 }
4830 Err(ErrorContext::new_missing(
4831 "VfinfoAttrs",
4832 "Spoofchk",
4833 self.orig_loc,
4834 self.buf.as_ptr() as usize,
4835 ))
4836 }
4837 pub fn get_link_state(&self) -> Result<IflaVfLinkState, ErrorContext> {
4838 let mut iter = self.clone();
4839 iter.pos = 0;
4840 for attr in iter {
4841 if let Ok(VfinfoAttrs::LinkState(val)) = attr {
4842 return Ok(val);
4843 }
4844 }
4845 Err(ErrorContext::new_missing(
4846 "VfinfoAttrs",
4847 "LinkState",
4848 self.orig_loc,
4849 self.buf.as_ptr() as usize,
4850 ))
4851 }
4852 pub fn get_rate(&self) -> Result<IflaVfRate, ErrorContext> {
4853 let mut iter = self.clone();
4854 iter.pos = 0;
4855 for attr in iter {
4856 if let Ok(VfinfoAttrs::Rate(val)) = attr {
4857 return Ok(val);
4858 }
4859 }
4860 Err(ErrorContext::new_missing(
4861 "VfinfoAttrs",
4862 "Rate",
4863 self.orig_loc,
4864 self.buf.as_ptr() as usize,
4865 ))
4866 }
4867 pub fn get_rss_query_en(&self) -> Result<IflaVfRssQueryEn, ErrorContext> {
4868 let mut iter = self.clone();
4869 iter.pos = 0;
4870 for attr in iter {
4871 if let Ok(VfinfoAttrs::RssQueryEn(val)) = attr {
4872 return Ok(val);
4873 }
4874 }
4875 Err(ErrorContext::new_missing(
4876 "VfinfoAttrs",
4877 "RssQueryEn",
4878 self.orig_loc,
4879 self.buf.as_ptr() as usize,
4880 ))
4881 }
4882 pub fn get_stats(&self) -> Result<IterableVfStatsAttrs<'a>, ErrorContext> {
4883 let mut iter = self.clone();
4884 iter.pos = 0;
4885 for attr in iter {
4886 if let Ok(VfinfoAttrs::Stats(val)) = attr {
4887 return Ok(val);
4888 }
4889 }
4890 Err(ErrorContext::new_missing(
4891 "VfinfoAttrs",
4892 "Stats",
4893 self.orig_loc,
4894 self.buf.as_ptr() as usize,
4895 ))
4896 }
4897 pub fn get_trust(&self) -> Result<IflaVfTrust, ErrorContext> {
4898 let mut iter = self.clone();
4899 iter.pos = 0;
4900 for attr in iter {
4901 if let Ok(VfinfoAttrs::Trust(val)) = attr {
4902 return Ok(val);
4903 }
4904 }
4905 Err(ErrorContext::new_missing(
4906 "VfinfoAttrs",
4907 "Trust",
4908 self.orig_loc,
4909 self.buf.as_ptr() as usize,
4910 ))
4911 }
4912 pub fn get_ib_node_guid(&self) -> Result<IflaVfGuid, ErrorContext> {
4913 let mut iter = self.clone();
4914 iter.pos = 0;
4915 for attr in iter {
4916 if let Ok(VfinfoAttrs::IbNodeGuid(val)) = attr {
4917 return Ok(val);
4918 }
4919 }
4920 Err(ErrorContext::new_missing(
4921 "VfinfoAttrs",
4922 "IbNodeGuid",
4923 self.orig_loc,
4924 self.buf.as_ptr() as usize,
4925 ))
4926 }
4927 pub fn get_ib_port_guid(&self) -> Result<IflaVfGuid, ErrorContext> {
4928 let mut iter = self.clone();
4929 iter.pos = 0;
4930 for attr in iter {
4931 if let Ok(VfinfoAttrs::IbPortGuid(val)) = attr {
4932 return Ok(val);
4933 }
4934 }
4935 Err(ErrorContext::new_missing(
4936 "VfinfoAttrs",
4937 "IbPortGuid",
4938 self.orig_loc,
4939 self.buf.as_ptr() as usize,
4940 ))
4941 }
4942 pub fn get_vlan_list(&self) -> Result<IterableVfVlanAttrs<'a>, ErrorContext> {
4943 let mut iter = self.clone();
4944 iter.pos = 0;
4945 for attr in iter {
4946 if let Ok(VfinfoAttrs::VlanList(val)) = attr {
4947 return Ok(val);
4948 }
4949 }
4950 Err(ErrorContext::new_missing(
4951 "VfinfoAttrs",
4952 "VlanList",
4953 self.orig_loc,
4954 self.buf.as_ptr() as usize,
4955 ))
4956 }
4957 pub fn get_broadcast(&self) -> Result<&'a [u8], ErrorContext> {
4958 let mut iter = self.clone();
4959 iter.pos = 0;
4960 for attr in iter {
4961 if let Ok(VfinfoAttrs::Broadcast(val)) = attr {
4962 return Ok(val);
4963 }
4964 }
4965 Err(ErrorContext::new_missing(
4966 "VfinfoAttrs",
4967 "Broadcast",
4968 self.orig_loc,
4969 self.buf.as_ptr() as usize,
4970 ))
4971 }
4972}
4973impl VfinfoAttrs<'_> {
4974 pub fn new<'a>(buf: &'a [u8]) -> IterableVfinfoAttrs<'a> {
4975 IterableVfinfoAttrs::with_loc(buf, buf.as_ptr() as usize)
4976 }
4977 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4978 let res = match r#type {
4979 1u16 => "Mac",
4980 2u16 => "Vlan",
4981 3u16 => "TxRate",
4982 4u16 => "Spoofchk",
4983 5u16 => "LinkState",
4984 6u16 => "Rate",
4985 7u16 => "RssQueryEn",
4986 8u16 => "Stats",
4987 9u16 => "Trust",
4988 10u16 => "IbNodeGuid",
4989 11u16 => "IbPortGuid",
4990 12u16 => "VlanList",
4991 13u16 => "Broadcast",
4992 _ => return None,
4993 };
4994 Some(res)
4995 }
4996}
4997#[derive(Clone, Copy, Default)]
4998pub struct IterableVfinfoAttrs<'a> {
4999 buf: &'a [u8],
5000 pos: usize,
5001 orig_loc: usize,
5002}
5003impl<'a> IterableVfinfoAttrs<'a> {
5004 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5005 Self {
5006 buf,
5007 pos: 0,
5008 orig_loc,
5009 }
5010 }
5011 pub fn get_buf(&self) -> &'a [u8] {
5012 self.buf
5013 }
5014}
5015impl<'a> Iterator for IterableVfinfoAttrs<'a> {
5016 type Item = Result<VfinfoAttrs<'a>, ErrorContext>;
5017 fn next(&mut self) -> Option<Self::Item> {
5018 let mut pos;
5019 let mut r#type;
5020 loop {
5021 pos = self.pos;
5022 r#type = None;
5023 if self.buf.len() == self.pos {
5024 return None;
5025 }
5026 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5027 self.pos = self.buf.len();
5028 break;
5029 };
5030 r#type = Some(header.r#type);
5031 let res = match header.r#type {
5032 1u16 => VfinfoAttrs::Mac({
5033 let res = Some(IflaVfMac::new_from_zeroed(next));
5034 let Some(val) = res else { break };
5035 val
5036 }),
5037 2u16 => VfinfoAttrs::Vlan({
5038 let res = Some(IflaVfVlan::new_from_zeroed(next));
5039 let Some(val) = res else { break };
5040 val
5041 }),
5042 3u16 => VfinfoAttrs::TxRate({
5043 let res = Some(IflaVfTxRate::new_from_zeroed(next));
5044 let Some(val) = res else { break };
5045 val
5046 }),
5047 4u16 => VfinfoAttrs::Spoofchk({
5048 let res = Some(IflaVfSpoofchk::new_from_zeroed(next));
5049 let Some(val) = res else { break };
5050 val
5051 }),
5052 5u16 => VfinfoAttrs::LinkState({
5053 let res = Some(IflaVfLinkState::new_from_zeroed(next));
5054 let Some(val) = res else { break };
5055 val
5056 }),
5057 6u16 => VfinfoAttrs::Rate({
5058 let res = Some(IflaVfRate::new_from_zeroed(next));
5059 let Some(val) = res else { break };
5060 val
5061 }),
5062 7u16 => VfinfoAttrs::RssQueryEn({
5063 let res = Some(IflaVfRssQueryEn::new_from_zeroed(next));
5064 let Some(val) = res else { break };
5065 val
5066 }),
5067 8u16 => VfinfoAttrs::Stats({
5068 let res = Some(IterableVfStatsAttrs::with_loc(next, self.orig_loc));
5069 let Some(val) = res else { break };
5070 val
5071 }),
5072 9u16 => VfinfoAttrs::Trust({
5073 let res = Some(IflaVfTrust::new_from_zeroed(next));
5074 let Some(val) = res else { break };
5075 val
5076 }),
5077 10u16 => VfinfoAttrs::IbNodeGuid({
5078 let res = Some(IflaVfGuid::new_from_zeroed(next));
5079 let Some(val) = res else { break };
5080 val
5081 }),
5082 11u16 => VfinfoAttrs::IbPortGuid({
5083 let res = Some(IflaVfGuid::new_from_zeroed(next));
5084 let Some(val) = res else { break };
5085 val
5086 }),
5087 12u16 => VfinfoAttrs::VlanList({
5088 let res = Some(IterableVfVlanAttrs::with_loc(next, self.orig_loc));
5089 let Some(val) = res else { break };
5090 val
5091 }),
5092 13u16 => VfinfoAttrs::Broadcast({
5093 let res = Some(next);
5094 let Some(val) = res else { break };
5095 val
5096 }),
5097 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5098 n => continue,
5099 };
5100 return Some(Ok(res));
5101 }
5102 Some(Err(ErrorContext::new(
5103 "VfinfoAttrs",
5104 r#type.and_then(|t| VfinfoAttrs::attr_from_type(t)),
5105 self.orig_loc,
5106 self.buf.as_ptr().wrapping_add(pos) as usize,
5107 )))
5108 }
5109}
5110impl<'a> std::fmt::Debug for IterableVfinfoAttrs<'_> {
5111 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5112 let mut fmt = f.debug_struct("VfinfoAttrs");
5113 for attr in self.clone() {
5114 let attr = match attr {
5115 Ok(a) => a,
5116 Err(err) => {
5117 fmt.finish()?;
5118 f.write_str("Err(")?;
5119 err.fmt(f)?;
5120 return f.write_str(")");
5121 }
5122 };
5123 match attr {
5124 VfinfoAttrs::Mac(val) => fmt.field("Mac", &val),
5125 VfinfoAttrs::Vlan(val) => fmt.field("Vlan", &val),
5126 VfinfoAttrs::TxRate(val) => fmt.field("TxRate", &val),
5127 VfinfoAttrs::Spoofchk(val) => fmt.field("Spoofchk", &val),
5128 VfinfoAttrs::LinkState(val) => fmt.field("LinkState", &val),
5129 VfinfoAttrs::Rate(val) => fmt.field("Rate", &val),
5130 VfinfoAttrs::RssQueryEn(val) => fmt.field("RssQueryEn", &val),
5131 VfinfoAttrs::Stats(val) => fmt.field("Stats", &val),
5132 VfinfoAttrs::Trust(val) => fmt.field("Trust", &val),
5133 VfinfoAttrs::IbNodeGuid(val) => fmt.field("IbNodeGuid", &val),
5134 VfinfoAttrs::IbPortGuid(val) => fmt.field("IbPortGuid", &val),
5135 VfinfoAttrs::VlanList(val) => fmt.field("VlanList", &val),
5136 VfinfoAttrs::Broadcast(val) => fmt.field("Broadcast", &val),
5137 };
5138 }
5139 fmt.finish()
5140 }
5141}
5142impl IterableVfinfoAttrs<'_> {
5143 pub fn lookup_attr(
5144 &self,
5145 offset: usize,
5146 missing_type: Option<u16>,
5147 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5148 let mut stack = Vec::new();
5149 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5150 if missing_type.is_some() && cur == offset {
5151 stack.push(("VfinfoAttrs", offset));
5152 return (
5153 stack,
5154 missing_type.and_then(|t| VfinfoAttrs::attr_from_type(t)),
5155 );
5156 }
5157 if cur > offset || cur + self.buf.len() < offset {
5158 return (stack, None);
5159 }
5160 let mut attrs = self.clone();
5161 let mut last_off = cur + attrs.pos;
5162 let mut missing = None;
5163 while let Some(attr) = attrs.next() {
5164 let Ok(attr) = attr else { break };
5165 match attr {
5166 VfinfoAttrs::Mac(val) => {
5167 if last_off == offset {
5168 stack.push(("Mac", last_off));
5169 break;
5170 }
5171 }
5172 VfinfoAttrs::Vlan(val) => {
5173 if last_off == offset {
5174 stack.push(("Vlan", last_off));
5175 break;
5176 }
5177 }
5178 VfinfoAttrs::TxRate(val) => {
5179 if last_off == offset {
5180 stack.push(("TxRate", last_off));
5181 break;
5182 }
5183 }
5184 VfinfoAttrs::Spoofchk(val) => {
5185 if last_off == offset {
5186 stack.push(("Spoofchk", last_off));
5187 break;
5188 }
5189 }
5190 VfinfoAttrs::LinkState(val) => {
5191 if last_off == offset {
5192 stack.push(("LinkState", last_off));
5193 break;
5194 }
5195 }
5196 VfinfoAttrs::Rate(val) => {
5197 if last_off == offset {
5198 stack.push(("Rate", last_off));
5199 break;
5200 }
5201 }
5202 VfinfoAttrs::RssQueryEn(val) => {
5203 if last_off == offset {
5204 stack.push(("RssQueryEn", last_off));
5205 break;
5206 }
5207 }
5208 VfinfoAttrs::Stats(val) => {
5209 (stack, missing) = val.lookup_attr(offset, missing_type);
5210 if !stack.is_empty() {
5211 break;
5212 }
5213 }
5214 VfinfoAttrs::Trust(val) => {
5215 if last_off == offset {
5216 stack.push(("Trust", last_off));
5217 break;
5218 }
5219 }
5220 VfinfoAttrs::IbNodeGuid(val) => {
5221 if last_off == offset {
5222 stack.push(("IbNodeGuid", last_off));
5223 break;
5224 }
5225 }
5226 VfinfoAttrs::IbPortGuid(val) => {
5227 if last_off == offset {
5228 stack.push(("IbPortGuid", last_off));
5229 break;
5230 }
5231 }
5232 VfinfoAttrs::VlanList(val) => {
5233 (stack, missing) = val.lookup_attr(offset, missing_type);
5234 if !stack.is_empty() {
5235 break;
5236 }
5237 }
5238 VfinfoAttrs::Broadcast(val) => {
5239 if last_off == offset {
5240 stack.push(("Broadcast", last_off));
5241 break;
5242 }
5243 }
5244 _ => {}
5245 };
5246 last_off = cur + attrs.pos;
5247 }
5248 if !stack.is_empty() {
5249 stack.push(("VfinfoAttrs", cur));
5250 }
5251 (stack, missing)
5252 }
5253}
5254#[derive(Clone)]
5255pub enum VfStatsAttrs<'a> {
5256 RxPackets(u64),
5257 TxPackets(u64),
5258 RxBytes(u64),
5259 TxBytes(u64),
5260 Broadcast(u64),
5261 Multicast(u64),
5262 Pad(&'a [u8]),
5263 RxDropped(u64),
5264 TxDropped(u64),
5265}
5266impl<'a> IterableVfStatsAttrs<'a> {
5267 pub fn get_rx_packets(&self) -> Result<u64, ErrorContext> {
5268 let mut iter = self.clone();
5269 iter.pos = 0;
5270 for attr in iter {
5271 if let Ok(VfStatsAttrs::RxPackets(val)) = attr {
5272 return Ok(val);
5273 }
5274 }
5275 Err(ErrorContext::new_missing(
5276 "VfStatsAttrs",
5277 "RxPackets",
5278 self.orig_loc,
5279 self.buf.as_ptr() as usize,
5280 ))
5281 }
5282 pub fn get_tx_packets(&self) -> Result<u64, ErrorContext> {
5283 let mut iter = self.clone();
5284 iter.pos = 0;
5285 for attr in iter {
5286 if let Ok(VfStatsAttrs::TxPackets(val)) = attr {
5287 return Ok(val);
5288 }
5289 }
5290 Err(ErrorContext::new_missing(
5291 "VfStatsAttrs",
5292 "TxPackets",
5293 self.orig_loc,
5294 self.buf.as_ptr() as usize,
5295 ))
5296 }
5297 pub fn get_rx_bytes(&self) -> Result<u64, ErrorContext> {
5298 let mut iter = self.clone();
5299 iter.pos = 0;
5300 for attr in iter {
5301 if let Ok(VfStatsAttrs::RxBytes(val)) = attr {
5302 return Ok(val);
5303 }
5304 }
5305 Err(ErrorContext::new_missing(
5306 "VfStatsAttrs",
5307 "RxBytes",
5308 self.orig_loc,
5309 self.buf.as_ptr() as usize,
5310 ))
5311 }
5312 pub fn get_tx_bytes(&self) -> Result<u64, ErrorContext> {
5313 let mut iter = self.clone();
5314 iter.pos = 0;
5315 for attr in iter {
5316 if let Ok(VfStatsAttrs::TxBytes(val)) = attr {
5317 return Ok(val);
5318 }
5319 }
5320 Err(ErrorContext::new_missing(
5321 "VfStatsAttrs",
5322 "TxBytes",
5323 self.orig_loc,
5324 self.buf.as_ptr() as usize,
5325 ))
5326 }
5327 pub fn get_broadcast(&self) -> Result<u64, ErrorContext> {
5328 let mut iter = self.clone();
5329 iter.pos = 0;
5330 for attr in iter {
5331 if let Ok(VfStatsAttrs::Broadcast(val)) = attr {
5332 return Ok(val);
5333 }
5334 }
5335 Err(ErrorContext::new_missing(
5336 "VfStatsAttrs",
5337 "Broadcast",
5338 self.orig_loc,
5339 self.buf.as_ptr() as usize,
5340 ))
5341 }
5342 pub fn get_multicast(&self) -> Result<u64, ErrorContext> {
5343 let mut iter = self.clone();
5344 iter.pos = 0;
5345 for attr in iter {
5346 if let Ok(VfStatsAttrs::Multicast(val)) = attr {
5347 return Ok(val);
5348 }
5349 }
5350 Err(ErrorContext::new_missing(
5351 "VfStatsAttrs",
5352 "Multicast",
5353 self.orig_loc,
5354 self.buf.as_ptr() as usize,
5355 ))
5356 }
5357 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
5358 let mut iter = self.clone();
5359 iter.pos = 0;
5360 for attr in iter {
5361 if let Ok(VfStatsAttrs::Pad(val)) = attr {
5362 return Ok(val);
5363 }
5364 }
5365 Err(ErrorContext::new_missing(
5366 "VfStatsAttrs",
5367 "Pad",
5368 self.orig_loc,
5369 self.buf.as_ptr() as usize,
5370 ))
5371 }
5372 pub fn get_rx_dropped(&self) -> Result<u64, ErrorContext> {
5373 let mut iter = self.clone();
5374 iter.pos = 0;
5375 for attr in iter {
5376 if let Ok(VfStatsAttrs::RxDropped(val)) = attr {
5377 return Ok(val);
5378 }
5379 }
5380 Err(ErrorContext::new_missing(
5381 "VfStatsAttrs",
5382 "RxDropped",
5383 self.orig_loc,
5384 self.buf.as_ptr() as usize,
5385 ))
5386 }
5387 pub fn get_tx_dropped(&self) -> Result<u64, ErrorContext> {
5388 let mut iter = self.clone();
5389 iter.pos = 0;
5390 for attr in iter {
5391 if let Ok(VfStatsAttrs::TxDropped(val)) = attr {
5392 return Ok(val);
5393 }
5394 }
5395 Err(ErrorContext::new_missing(
5396 "VfStatsAttrs",
5397 "TxDropped",
5398 self.orig_loc,
5399 self.buf.as_ptr() as usize,
5400 ))
5401 }
5402}
5403impl VfStatsAttrs<'_> {
5404 pub fn new<'a>(buf: &'a [u8]) -> IterableVfStatsAttrs<'a> {
5405 IterableVfStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
5406 }
5407 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5408 let res = match r#type {
5409 0u16 => "RxPackets",
5410 1u16 => "TxPackets",
5411 2u16 => "RxBytes",
5412 3u16 => "TxBytes",
5413 4u16 => "Broadcast",
5414 5u16 => "Multicast",
5415 6u16 => "Pad",
5416 7u16 => "RxDropped",
5417 8u16 => "TxDropped",
5418 _ => return None,
5419 };
5420 Some(res)
5421 }
5422}
5423#[derive(Clone, Copy, Default)]
5424pub struct IterableVfStatsAttrs<'a> {
5425 buf: &'a [u8],
5426 pos: usize,
5427 orig_loc: usize,
5428}
5429impl<'a> IterableVfStatsAttrs<'a> {
5430 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5431 Self {
5432 buf,
5433 pos: 0,
5434 orig_loc,
5435 }
5436 }
5437 pub fn get_buf(&self) -> &'a [u8] {
5438 self.buf
5439 }
5440}
5441impl<'a> Iterator for IterableVfStatsAttrs<'a> {
5442 type Item = Result<VfStatsAttrs<'a>, ErrorContext>;
5443 fn next(&mut self) -> Option<Self::Item> {
5444 let mut pos;
5445 let mut r#type;
5446 loop {
5447 pos = self.pos;
5448 r#type = None;
5449 if self.buf.len() == self.pos {
5450 return None;
5451 }
5452 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5453 self.pos = self.buf.len();
5454 break;
5455 };
5456 r#type = Some(header.r#type);
5457 let res = match header.r#type {
5458 0u16 => VfStatsAttrs::RxPackets({
5459 let res = parse_u64(next);
5460 let Some(val) = res else { break };
5461 val
5462 }),
5463 1u16 => VfStatsAttrs::TxPackets({
5464 let res = parse_u64(next);
5465 let Some(val) = res else { break };
5466 val
5467 }),
5468 2u16 => VfStatsAttrs::RxBytes({
5469 let res = parse_u64(next);
5470 let Some(val) = res else { break };
5471 val
5472 }),
5473 3u16 => VfStatsAttrs::TxBytes({
5474 let res = parse_u64(next);
5475 let Some(val) = res else { break };
5476 val
5477 }),
5478 4u16 => VfStatsAttrs::Broadcast({
5479 let res = parse_u64(next);
5480 let Some(val) = res else { break };
5481 val
5482 }),
5483 5u16 => VfStatsAttrs::Multicast({
5484 let res = parse_u64(next);
5485 let Some(val) = res else { break };
5486 val
5487 }),
5488 6u16 => VfStatsAttrs::Pad({
5489 let res = Some(next);
5490 let Some(val) = res else { break };
5491 val
5492 }),
5493 7u16 => VfStatsAttrs::RxDropped({
5494 let res = parse_u64(next);
5495 let Some(val) = res else { break };
5496 val
5497 }),
5498 8u16 => VfStatsAttrs::TxDropped({
5499 let res = parse_u64(next);
5500 let Some(val) = res else { break };
5501 val
5502 }),
5503 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5504 n => continue,
5505 };
5506 return Some(Ok(res));
5507 }
5508 Some(Err(ErrorContext::new(
5509 "VfStatsAttrs",
5510 r#type.and_then(|t| VfStatsAttrs::attr_from_type(t)),
5511 self.orig_loc,
5512 self.buf.as_ptr().wrapping_add(pos) as usize,
5513 )))
5514 }
5515}
5516impl<'a> std::fmt::Debug for IterableVfStatsAttrs<'_> {
5517 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5518 let mut fmt = f.debug_struct("VfStatsAttrs");
5519 for attr in self.clone() {
5520 let attr = match attr {
5521 Ok(a) => a,
5522 Err(err) => {
5523 fmt.finish()?;
5524 f.write_str("Err(")?;
5525 err.fmt(f)?;
5526 return f.write_str(")");
5527 }
5528 };
5529 match attr {
5530 VfStatsAttrs::RxPackets(val) => fmt.field("RxPackets", &val),
5531 VfStatsAttrs::TxPackets(val) => fmt.field("TxPackets", &val),
5532 VfStatsAttrs::RxBytes(val) => fmt.field("RxBytes", &val),
5533 VfStatsAttrs::TxBytes(val) => fmt.field("TxBytes", &val),
5534 VfStatsAttrs::Broadcast(val) => fmt.field("Broadcast", &val),
5535 VfStatsAttrs::Multicast(val) => fmt.field("Multicast", &val),
5536 VfStatsAttrs::Pad(val) => fmt.field("Pad", &val),
5537 VfStatsAttrs::RxDropped(val) => fmt.field("RxDropped", &val),
5538 VfStatsAttrs::TxDropped(val) => fmt.field("TxDropped", &val),
5539 };
5540 }
5541 fmt.finish()
5542 }
5543}
5544impl IterableVfStatsAttrs<'_> {
5545 pub fn lookup_attr(
5546 &self,
5547 offset: usize,
5548 missing_type: Option<u16>,
5549 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5550 let mut stack = Vec::new();
5551 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5552 if missing_type.is_some() && cur == offset {
5553 stack.push(("VfStatsAttrs", offset));
5554 return (
5555 stack,
5556 missing_type.and_then(|t| VfStatsAttrs::attr_from_type(t)),
5557 );
5558 }
5559 if cur > offset || cur + self.buf.len() < offset {
5560 return (stack, None);
5561 }
5562 let mut attrs = self.clone();
5563 let mut last_off = cur + attrs.pos;
5564 while let Some(attr) = attrs.next() {
5565 let Ok(attr) = attr else { break };
5566 match attr {
5567 VfStatsAttrs::RxPackets(val) => {
5568 if last_off == offset {
5569 stack.push(("RxPackets", last_off));
5570 break;
5571 }
5572 }
5573 VfStatsAttrs::TxPackets(val) => {
5574 if last_off == offset {
5575 stack.push(("TxPackets", last_off));
5576 break;
5577 }
5578 }
5579 VfStatsAttrs::RxBytes(val) => {
5580 if last_off == offset {
5581 stack.push(("RxBytes", last_off));
5582 break;
5583 }
5584 }
5585 VfStatsAttrs::TxBytes(val) => {
5586 if last_off == offset {
5587 stack.push(("TxBytes", last_off));
5588 break;
5589 }
5590 }
5591 VfStatsAttrs::Broadcast(val) => {
5592 if last_off == offset {
5593 stack.push(("Broadcast", last_off));
5594 break;
5595 }
5596 }
5597 VfStatsAttrs::Multicast(val) => {
5598 if last_off == offset {
5599 stack.push(("Multicast", last_off));
5600 break;
5601 }
5602 }
5603 VfStatsAttrs::Pad(val) => {
5604 if last_off == offset {
5605 stack.push(("Pad", last_off));
5606 break;
5607 }
5608 }
5609 VfStatsAttrs::RxDropped(val) => {
5610 if last_off == offset {
5611 stack.push(("RxDropped", last_off));
5612 break;
5613 }
5614 }
5615 VfStatsAttrs::TxDropped(val) => {
5616 if last_off == offset {
5617 stack.push(("TxDropped", last_off));
5618 break;
5619 }
5620 }
5621 _ => {}
5622 };
5623 last_off = cur + attrs.pos;
5624 }
5625 if !stack.is_empty() {
5626 stack.push(("VfStatsAttrs", cur));
5627 }
5628 (stack, None)
5629 }
5630}
5631#[derive(Clone)]
5632pub enum VfVlanAttrs {
5633 #[doc = "Attribute may repeat multiple times (treat it as array)"]
5634 Info(IflaVfVlanInfo),
5635}
5636impl<'a> IterableVfVlanAttrs<'a> {
5637 #[doc = "Attribute may repeat multiple times (treat it as array)"]
5638 pub fn get_info(&self) -> MultiAttrIterable<Self, VfVlanAttrs, IflaVfVlanInfo> {
5639 MultiAttrIterable::new(self.clone(), |variant| {
5640 if let VfVlanAttrs::Info(val) = variant {
5641 Some(val)
5642 } else {
5643 None
5644 }
5645 })
5646 }
5647}
5648impl VfVlanAttrs {
5649 pub fn new<'a>(buf: &'a [u8]) -> IterableVfVlanAttrs<'a> {
5650 IterableVfVlanAttrs::with_loc(buf, buf.as_ptr() as usize)
5651 }
5652 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5653 let res = match r#type {
5654 1u16 => "Info",
5655 _ => return None,
5656 };
5657 Some(res)
5658 }
5659}
5660#[derive(Clone, Copy, Default)]
5661pub struct IterableVfVlanAttrs<'a> {
5662 buf: &'a [u8],
5663 pos: usize,
5664 orig_loc: usize,
5665}
5666impl<'a> IterableVfVlanAttrs<'a> {
5667 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5668 Self {
5669 buf,
5670 pos: 0,
5671 orig_loc,
5672 }
5673 }
5674 pub fn get_buf(&self) -> &'a [u8] {
5675 self.buf
5676 }
5677}
5678impl<'a> Iterator for IterableVfVlanAttrs<'a> {
5679 type Item = Result<VfVlanAttrs, ErrorContext>;
5680 fn next(&mut self) -> Option<Self::Item> {
5681 let mut pos;
5682 let mut r#type;
5683 loop {
5684 pos = self.pos;
5685 r#type = None;
5686 if self.buf.len() == self.pos {
5687 return None;
5688 }
5689 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5690 self.pos = self.buf.len();
5691 break;
5692 };
5693 r#type = Some(header.r#type);
5694 let res = match header.r#type {
5695 1u16 => VfVlanAttrs::Info({
5696 let res = Some(IflaVfVlanInfo::new_from_zeroed(next));
5697 let Some(val) = res else { break };
5698 val
5699 }),
5700 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5701 n => continue,
5702 };
5703 return Some(Ok(res));
5704 }
5705 Some(Err(ErrorContext::new(
5706 "VfVlanAttrs",
5707 r#type.and_then(|t| VfVlanAttrs::attr_from_type(t)),
5708 self.orig_loc,
5709 self.buf.as_ptr().wrapping_add(pos) as usize,
5710 )))
5711 }
5712}
5713impl std::fmt::Debug for IterableVfVlanAttrs<'_> {
5714 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5715 let mut fmt = f.debug_struct("VfVlanAttrs");
5716 for attr in self.clone() {
5717 let attr = match attr {
5718 Ok(a) => a,
5719 Err(err) => {
5720 fmt.finish()?;
5721 f.write_str("Err(")?;
5722 err.fmt(f)?;
5723 return f.write_str(")");
5724 }
5725 };
5726 match attr {
5727 VfVlanAttrs::Info(val) => fmt.field("Info", &val),
5728 };
5729 }
5730 fmt.finish()
5731 }
5732}
5733impl IterableVfVlanAttrs<'_> {
5734 pub fn lookup_attr(
5735 &self,
5736 offset: usize,
5737 missing_type: Option<u16>,
5738 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5739 let mut stack = Vec::new();
5740 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5741 if missing_type.is_some() && cur == offset {
5742 stack.push(("VfVlanAttrs", offset));
5743 return (
5744 stack,
5745 missing_type.and_then(|t| VfVlanAttrs::attr_from_type(t)),
5746 );
5747 }
5748 if cur > offset || cur + self.buf.len() < offset {
5749 return (stack, None);
5750 }
5751 let mut attrs = self.clone();
5752 let mut last_off = cur + attrs.pos;
5753 while let Some(attr) = attrs.next() {
5754 let Ok(attr) = attr else { break };
5755 match attr {
5756 VfVlanAttrs::Info(val) => {
5757 if last_off == offset {
5758 stack.push(("Info", last_off));
5759 break;
5760 }
5761 }
5762 _ => {}
5763 };
5764 last_off = cur + attrs.pos;
5765 }
5766 if !stack.is_empty() {
5767 stack.push(("VfVlanAttrs", cur));
5768 }
5769 (stack, None)
5770 }
5771}
5772#[derive(Clone)]
5773pub enum VfPortsAttrs {}
5774impl<'a> IterableVfPortsAttrs<'a> {}
5775impl VfPortsAttrs {
5776 pub fn new<'a>(buf: &'a [u8]) -> IterableVfPortsAttrs<'a> {
5777 IterableVfPortsAttrs::with_loc(buf, buf.as_ptr() as usize)
5778 }
5779 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5780 None
5781 }
5782}
5783#[derive(Clone, Copy, Default)]
5784pub struct IterableVfPortsAttrs<'a> {
5785 buf: &'a [u8],
5786 pos: usize,
5787 orig_loc: usize,
5788}
5789impl<'a> IterableVfPortsAttrs<'a> {
5790 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5791 Self {
5792 buf,
5793 pos: 0,
5794 orig_loc,
5795 }
5796 }
5797 pub fn get_buf(&self) -> &'a [u8] {
5798 self.buf
5799 }
5800}
5801impl<'a> Iterator for IterableVfPortsAttrs<'a> {
5802 type Item = Result<VfPortsAttrs, ErrorContext>;
5803 fn next(&mut self) -> Option<Self::Item> {
5804 let mut pos;
5805 let mut r#type;
5806 loop {
5807 pos = self.pos;
5808 r#type = None;
5809 if self.buf.len() == self.pos {
5810 return None;
5811 }
5812 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5813 self.pos = self.buf.len();
5814 break;
5815 };
5816 r#type = Some(header.r#type);
5817 let res = match header.r#type {
5818 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5819 n => continue,
5820 };
5821 return Some(Ok(res));
5822 }
5823 Some(Err(ErrorContext::new(
5824 "VfPortsAttrs",
5825 r#type.and_then(|t| VfPortsAttrs::attr_from_type(t)),
5826 self.orig_loc,
5827 self.buf.as_ptr().wrapping_add(pos) as usize,
5828 )))
5829 }
5830}
5831impl std::fmt::Debug for IterableVfPortsAttrs<'_> {
5832 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5833 let mut fmt = f.debug_struct("VfPortsAttrs");
5834 for attr in self.clone() {
5835 let attr = match attr {
5836 Ok(a) => a,
5837 Err(err) => {
5838 fmt.finish()?;
5839 f.write_str("Err(")?;
5840 err.fmt(f)?;
5841 return f.write_str(")");
5842 }
5843 };
5844 match attr {};
5845 }
5846 fmt.finish()
5847 }
5848}
5849impl IterableVfPortsAttrs<'_> {
5850 pub fn lookup_attr(
5851 &self,
5852 offset: usize,
5853 missing_type: Option<u16>,
5854 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5855 let mut stack = Vec::new();
5856 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5857 if missing_type.is_some() && cur == offset {
5858 stack.push(("VfPortsAttrs", offset));
5859 return (
5860 stack,
5861 missing_type.and_then(|t| VfPortsAttrs::attr_from_type(t)),
5862 );
5863 }
5864 (stack, None)
5865 }
5866}
5867#[derive(Clone)]
5868pub enum PortSelfAttrs {}
5869impl<'a> IterablePortSelfAttrs<'a> {}
5870impl PortSelfAttrs {
5871 pub fn new<'a>(buf: &'a [u8]) -> IterablePortSelfAttrs<'a> {
5872 IterablePortSelfAttrs::with_loc(buf, buf.as_ptr() as usize)
5873 }
5874 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5875 None
5876 }
5877}
5878#[derive(Clone, Copy, Default)]
5879pub struct IterablePortSelfAttrs<'a> {
5880 buf: &'a [u8],
5881 pos: usize,
5882 orig_loc: usize,
5883}
5884impl<'a> IterablePortSelfAttrs<'a> {
5885 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5886 Self {
5887 buf,
5888 pos: 0,
5889 orig_loc,
5890 }
5891 }
5892 pub fn get_buf(&self) -> &'a [u8] {
5893 self.buf
5894 }
5895}
5896impl<'a> Iterator for IterablePortSelfAttrs<'a> {
5897 type Item = Result<PortSelfAttrs, ErrorContext>;
5898 fn next(&mut self) -> Option<Self::Item> {
5899 let mut pos;
5900 let mut r#type;
5901 loop {
5902 pos = self.pos;
5903 r#type = None;
5904 if self.buf.len() == self.pos {
5905 return None;
5906 }
5907 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5908 self.pos = self.buf.len();
5909 break;
5910 };
5911 r#type = Some(header.r#type);
5912 let res = match header.r#type {
5913 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5914 n => continue,
5915 };
5916 return Some(Ok(res));
5917 }
5918 Some(Err(ErrorContext::new(
5919 "PortSelfAttrs",
5920 r#type.and_then(|t| PortSelfAttrs::attr_from_type(t)),
5921 self.orig_loc,
5922 self.buf.as_ptr().wrapping_add(pos) as usize,
5923 )))
5924 }
5925}
5926impl std::fmt::Debug for IterablePortSelfAttrs<'_> {
5927 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5928 let mut fmt = f.debug_struct("PortSelfAttrs");
5929 for attr in self.clone() {
5930 let attr = match attr {
5931 Ok(a) => a,
5932 Err(err) => {
5933 fmt.finish()?;
5934 f.write_str("Err(")?;
5935 err.fmt(f)?;
5936 return f.write_str(")");
5937 }
5938 };
5939 match attr {};
5940 }
5941 fmt.finish()
5942 }
5943}
5944impl IterablePortSelfAttrs<'_> {
5945 pub fn lookup_attr(
5946 &self,
5947 offset: usize,
5948 missing_type: Option<u16>,
5949 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5950 let mut stack = Vec::new();
5951 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5952 if missing_type.is_some() && cur == offset {
5953 stack.push(("PortSelfAttrs", offset));
5954 return (
5955 stack,
5956 missing_type.and_then(|t| PortSelfAttrs::attr_from_type(t)),
5957 );
5958 }
5959 (stack, None)
5960 }
5961}
5962#[derive(Clone)]
5963pub enum LinkinfoAttrs<'a> {
5964 Kind(&'a CStr),
5965 Data(LinkinfoDataMsg<'a>),
5966 Xstats(&'a [u8]),
5967 SlaveKind(&'a CStr),
5968 SlaveData(LinkinfoMemberDataMsg<'a>),
5969}
5970impl<'a> IterableLinkinfoAttrs<'a> {
5971 pub fn get_kind(&self) -> Result<&'a CStr, ErrorContext> {
5972 let mut iter = self.clone();
5973 iter.pos = 0;
5974 for attr in iter {
5975 if let Ok(LinkinfoAttrs::Kind(val)) = attr {
5976 return Ok(val);
5977 }
5978 }
5979 Err(ErrorContext::new_missing(
5980 "LinkinfoAttrs",
5981 "Kind",
5982 self.orig_loc,
5983 self.buf.as_ptr() as usize,
5984 ))
5985 }
5986 pub fn get_data(&self) -> Result<LinkinfoDataMsg<'a>, ErrorContext> {
5987 let mut iter = self.clone();
5988 iter.pos = 0;
5989 for attr in iter {
5990 if let Ok(LinkinfoAttrs::Data(val)) = attr {
5991 return Ok(val);
5992 }
5993 }
5994 Err(ErrorContext::new_missing(
5995 "LinkinfoAttrs",
5996 "Data",
5997 self.orig_loc,
5998 self.buf.as_ptr() as usize,
5999 ))
6000 }
6001 pub fn get_xstats(&self) -> Result<&'a [u8], ErrorContext> {
6002 let mut iter = self.clone();
6003 iter.pos = 0;
6004 for attr in iter {
6005 if let Ok(LinkinfoAttrs::Xstats(val)) = attr {
6006 return Ok(val);
6007 }
6008 }
6009 Err(ErrorContext::new_missing(
6010 "LinkinfoAttrs",
6011 "Xstats",
6012 self.orig_loc,
6013 self.buf.as_ptr() as usize,
6014 ))
6015 }
6016 pub fn get_slave_kind(&self) -> Result<&'a CStr, ErrorContext> {
6017 let mut iter = self.clone();
6018 iter.pos = 0;
6019 for attr in iter {
6020 if let Ok(LinkinfoAttrs::SlaveKind(val)) = attr {
6021 return Ok(val);
6022 }
6023 }
6024 Err(ErrorContext::new_missing(
6025 "LinkinfoAttrs",
6026 "SlaveKind",
6027 self.orig_loc,
6028 self.buf.as_ptr() as usize,
6029 ))
6030 }
6031 pub fn get_slave_data(&self) -> Result<LinkinfoMemberDataMsg<'a>, ErrorContext> {
6032 let mut iter = self.clone();
6033 iter.pos = 0;
6034 for attr in iter {
6035 if let Ok(LinkinfoAttrs::SlaveData(val)) = attr {
6036 return Ok(val);
6037 }
6038 }
6039 Err(ErrorContext::new_missing(
6040 "LinkinfoAttrs",
6041 "SlaveData",
6042 self.orig_loc,
6043 self.buf.as_ptr() as usize,
6044 ))
6045 }
6046}
6047#[derive(Debug, Clone)]
6048pub enum LinkinfoDataMsg<'a> {
6049 Bond(IterableLinkinfoBondAttrs<'a>),
6050 Bridge(IterableLinkinfoBridgeAttrs<'a>),
6051 Erspan(IterableLinkinfoGreAttrs<'a>),
6052 Gre(IterableLinkinfoGreAttrs<'a>),
6053 Gretap(IterableLinkinfoGreAttrs<'a>),
6054 Ip6gre(IterableLinkinfoGre6Attrs<'a>),
6055 Geneve(IterableLinkinfoGeneveAttrs<'a>),
6056 Hsr(IterableLinkinfoHsrAttrs<'a>),
6057 Ipip(IterableLinkinfoIptunAttrs<'a>),
6058 Ip6tnl(IterableLinkinfoIp6tnlAttrs<'a>),
6059 Sit(IterableLinkinfoIptunAttrs<'a>),
6060 Tun(IterableLinkinfoTunAttrs<'a>),
6061 Vlan(IterableLinkinfoVlanAttrs<'a>),
6062 Vrf(IterableLinkinfoVrfAttrs<'a>),
6063 Vti(IterableLinkinfoVtiAttrs<'a>),
6064 Vti6(IterableLinkinfoVti6Attrs<'a>),
6065 Netkit(IterableLinkinfoNetkitAttrs<'a>),
6066 Ovpn(IterableLinkinfoOvpnAttrs<'a>),
6067}
6068impl<'a> LinkinfoDataMsg<'a> {
6069 fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
6070 match selector.to_bytes() {
6071 b"bond" => Some(LinkinfoDataMsg::Bond(IterableLinkinfoBondAttrs::with_loc(
6072 buf, loc,
6073 ))),
6074 b"bridge" => Some(LinkinfoDataMsg::Bridge(
6075 IterableLinkinfoBridgeAttrs::with_loc(buf, loc),
6076 )),
6077 b"erspan" => Some(LinkinfoDataMsg::Erspan(IterableLinkinfoGreAttrs::with_loc(
6078 buf, loc,
6079 ))),
6080 b"gre" => Some(LinkinfoDataMsg::Gre(IterableLinkinfoGreAttrs::with_loc(
6081 buf, loc,
6082 ))),
6083 b"gretap" => Some(LinkinfoDataMsg::Gretap(IterableLinkinfoGreAttrs::with_loc(
6084 buf, loc,
6085 ))),
6086 b"ip6gre" => Some(LinkinfoDataMsg::Ip6gre(
6087 IterableLinkinfoGre6Attrs::with_loc(buf, loc),
6088 )),
6089 b"geneve" => Some(LinkinfoDataMsg::Geneve(
6090 IterableLinkinfoGeneveAttrs::with_loc(buf, loc),
6091 )),
6092 b"hsr" => Some(LinkinfoDataMsg::Hsr(IterableLinkinfoHsrAttrs::with_loc(
6093 buf, loc,
6094 ))),
6095 b"ipip" => Some(LinkinfoDataMsg::Ipip(IterableLinkinfoIptunAttrs::with_loc(
6096 buf, loc,
6097 ))),
6098 b"ip6tnl" => Some(LinkinfoDataMsg::Ip6tnl(
6099 IterableLinkinfoIp6tnlAttrs::with_loc(buf, loc),
6100 )),
6101 b"sit" => Some(LinkinfoDataMsg::Sit(IterableLinkinfoIptunAttrs::with_loc(
6102 buf, loc,
6103 ))),
6104 b"tun" => Some(LinkinfoDataMsg::Tun(IterableLinkinfoTunAttrs::with_loc(
6105 buf, loc,
6106 ))),
6107 b"vlan" => Some(LinkinfoDataMsg::Vlan(IterableLinkinfoVlanAttrs::with_loc(
6108 buf, loc,
6109 ))),
6110 b"vrf" => Some(LinkinfoDataMsg::Vrf(IterableLinkinfoVrfAttrs::with_loc(
6111 buf, loc,
6112 ))),
6113 b"vti" => Some(LinkinfoDataMsg::Vti(IterableLinkinfoVtiAttrs::with_loc(
6114 buf, loc,
6115 ))),
6116 b"vti6" => Some(LinkinfoDataMsg::Vti6(IterableLinkinfoVti6Attrs::with_loc(
6117 buf, loc,
6118 ))),
6119 b"netkit" => Some(LinkinfoDataMsg::Netkit(
6120 IterableLinkinfoNetkitAttrs::with_loc(buf, loc),
6121 )),
6122 b"ovpn" => Some(LinkinfoDataMsg::Ovpn(IterableLinkinfoOvpnAttrs::with_loc(
6123 buf, loc,
6124 ))),
6125 _ => None,
6126 }
6127 }
6128}
6129#[derive(Debug, Clone)]
6130pub enum LinkinfoMemberDataMsg<'a> {
6131 Bridge(IterableLinkinfoBrportAttrs<'a>),
6132 Bond(IterableBondSlaveAttrs<'a>),
6133}
6134impl<'a> LinkinfoMemberDataMsg<'a> {
6135 fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
6136 match selector.to_bytes() {
6137 b"bridge" => Some(LinkinfoMemberDataMsg::Bridge(
6138 IterableLinkinfoBrportAttrs::with_loc(buf, loc),
6139 )),
6140 b"bond" => Some(LinkinfoMemberDataMsg::Bond(
6141 IterableBondSlaveAttrs::with_loc(buf, loc),
6142 )),
6143 _ => None,
6144 }
6145 }
6146}
6147impl LinkinfoAttrs<'_> {
6148 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoAttrs<'a> {
6149 IterableLinkinfoAttrs::with_loc(buf, buf.as_ptr() as usize)
6150 }
6151 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6152 let res = match r#type {
6153 1u16 => "Kind",
6154 2u16 => "Data",
6155 3u16 => "Xstats",
6156 4u16 => "SlaveKind",
6157 5u16 => "SlaveData",
6158 _ => return None,
6159 };
6160 Some(res)
6161 }
6162}
6163#[derive(Clone, Copy, Default)]
6164pub struct IterableLinkinfoAttrs<'a> {
6165 buf: &'a [u8],
6166 pos: usize,
6167 orig_loc: usize,
6168}
6169impl<'a> IterableLinkinfoAttrs<'a> {
6170 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6171 Self {
6172 buf,
6173 pos: 0,
6174 orig_loc,
6175 }
6176 }
6177 pub fn get_buf(&self) -> &'a [u8] {
6178 self.buf
6179 }
6180}
6181impl<'a> Iterator for IterableLinkinfoAttrs<'a> {
6182 type Item = Result<LinkinfoAttrs<'a>, ErrorContext>;
6183 fn next(&mut self) -> Option<Self::Item> {
6184 let mut pos;
6185 let mut r#type;
6186 loop {
6187 pos = self.pos;
6188 r#type = None;
6189 if self.buf.len() == self.pos {
6190 return None;
6191 }
6192 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6193 self.pos = self.buf.len();
6194 break;
6195 };
6196 r#type = Some(header.r#type);
6197 let res = match header.r#type {
6198 1u16 => LinkinfoAttrs::Kind({
6199 let res = CStr::from_bytes_with_nul(next).ok();
6200 let Some(val) = res else { break };
6201 val
6202 }),
6203 2u16 => LinkinfoAttrs::Data({
6204 let res = {
6205 let Ok(selector) = self.get_kind() else { break };
6206 match LinkinfoDataMsg::select_with_loc(selector, next, self.orig_loc) {
6207 Some(sub) => Some(sub),
6208 None if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6209 None => continue,
6210 }
6211 };
6212 let Some(val) = res else { break };
6213 val
6214 }),
6215 3u16 => LinkinfoAttrs::Xstats({
6216 let res = Some(next);
6217 let Some(val) = res else { break };
6218 val
6219 }),
6220 4u16 => LinkinfoAttrs::SlaveKind({
6221 let res = CStr::from_bytes_with_nul(next).ok();
6222 let Some(val) = res else { break };
6223 val
6224 }),
6225 5u16 => LinkinfoAttrs::SlaveData({
6226 let res = {
6227 let Ok(selector) = self.get_slave_kind() else {
6228 break;
6229 };
6230 match LinkinfoMemberDataMsg::select_with_loc(selector, next, self.orig_loc)
6231 {
6232 Some(sub) => Some(sub),
6233 None if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6234 None => continue,
6235 }
6236 };
6237 let Some(val) = res else { break };
6238 val
6239 }),
6240 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6241 n => continue,
6242 };
6243 return Some(Ok(res));
6244 }
6245 Some(Err(ErrorContext::new(
6246 "LinkinfoAttrs",
6247 r#type.and_then(|t| LinkinfoAttrs::attr_from_type(t)),
6248 self.orig_loc,
6249 self.buf.as_ptr().wrapping_add(pos) as usize,
6250 )))
6251 }
6252}
6253impl<'a> std::fmt::Debug for IterableLinkinfoAttrs<'_> {
6254 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6255 let mut fmt = f.debug_struct("LinkinfoAttrs");
6256 for attr in self.clone() {
6257 let attr = match attr {
6258 Ok(a) => a,
6259 Err(err) => {
6260 fmt.finish()?;
6261 f.write_str("Err(")?;
6262 err.fmt(f)?;
6263 return f.write_str(")");
6264 }
6265 };
6266 match attr {
6267 LinkinfoAttrs::Kind(val) => fmt.field("Kind", &val),
6268 LinkinfoAttrs::Data(val) => fmt.field("Data", &val),
6269 LinkinfoAttrs::Xstats(val) => fmt.field("Xstats", &val),
6270 LinkinfoAttrs::SlaveKind(val) => fmt.field("SlaveKind", &val),
6271 LinkinfoAttrs::SlaveData(val) => fmt.field("SlaveData", &val),
6272 };
6273 }
6274 fmt.finish()
6275 }
6276}
6277impl IterableLinkinfoAttrs<'_> {
6278 pub fn lookup_attr(
6279 &self,
6280 offset: usize,
6281 missing_type: Option<u16>,
6282 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6283 let mut stack = Vec::new();
6284 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6285 if missing_type.is_some() && cur == offset {
6286 stack.push(("LinkinfoAttrs", offset));
6287 return (
6288 stack,
6289 missing_type.and_then(|t| LinkinfoAttrs::attr_from_type(t)),
6290 );
6291 }
6292 if cur > offset || cur + self.buf.len() < offset {
6293 return (stack, None);
6294 }
6295 let mut attrs = self.clone();
6296 let mut last_off = cur + attrs.pos;
6297 while let Some(attr) = attrs.next() {
6298 let Ok(attr) = attr else { break };
6299 match attr {
6300 LinkinfoAttrs::Kind(val) => {
6301 if last_off == offset {
6302 stack.push(("Kind", last_off));
6303 break;
6304 }
6305 }
6306 LinkinfoAttrs::Data(val) => {
6307 if last_off == offset {
6308 stack.push(("Data", last_off));
6309 break;
6310 }
6311 }
6312 LinkinfoAttrs::Xstats(val) => {
6313 if last_off == offset {
6314 stack.push(("Xstats", last_off));
6315 break;
6316 }
6317 }
6318 LinkinfoAttrs::SlaveKind(val) => {
6319 if last_off == offset {
6320 stack.push(("SlaveKind", last_off));
6321 break;
6322 }
6323 }
6324 LinkinfoAttrs::SlaveData(val) => {
6325 if last_off == offset {
6326 stack.push(("SlaveData", last_off));
6327 break;
6328 }
6329 }
6330 _ => {}
6331 };
6332 last_off = cur + attrs.pos;
6333 }
6334 if !stack.is_empty() {
6335 stack.push(("LinkinfoAttrs", cur));
6336 }
6337 (stack, None)
6338 }
6339}
6340#[derive(Clone)]
6341pub enum LinkinfoBondAttrs<'a> {
6342 Mode(u8),
6343 ActiveSlave(u32),
6344 Miimon(u32),
6345 Updelay(u32),
6346 Downdelay(u32),
6347 UseCarrier(u8),
6348 ArpInterval(u32),
6349 ArpIpTarget(IterableArrayIpv4Addr<'a>),
6350 ArpValidate(u32),
6351 ArpAllTargets(u32),
6352 Primary(u32),
6353 PrimaryReselect(u8),
6354 FailOverMac(u8),
6355 XmitHashPolicy(u8),
6356 ResendIgmp(u32),
6357 NumPeerNotif(u8),
6358 AllSlavesActive(u8),
6359 MinLinks(u32),
6360 LpInterval(u32),
6361 PacketsPerSlave(u32),
6362 AdLacpRate(u8),
6363 AdSelect(u8),
6364 AdInfo(IterableBondAdInfoAttrs<'a>),
6365 AdActorSysPrio(u16),
6366 AdUserPortKey(u16),
6367 AdActorSystem(&'a [u8]),
6368 TlbDynamicLb(u8),
6369 PeerNotifDelay(u32),
6370 AdLacpActive(u8),
6371 MissedMax(u8),
6372 NsIp6Target(IterableArrayBinary<'a>),
6373 CoupledControl(u8),
6374}
6375impl<'a> IterableLinkinfoBondAttrs<'a> {
6376 pub fn get_mode(&self) -> Result<u8, ErrorContext> {
6377 let mut iter = self.clone();
6378 iter.pos = 0;
6379 for attr in iter {
6380 if let Ok(LinkinfoBondAttrs::Mode(val)) = attr {
6381 return Ok(val);
6382 }
6383 }
6384 Err(ErrorContext::new_missing(
6385 "LinkinfoBondAttrs",
6386 "Mode",
6387 self.orig_loc,
6388 self.buf.as_ptr() as usize,
6389 ))
6390 }
6391 pub fn get_active_slave(&self) -> Result<u32, ErrorContext> {
6392 let mut iter = self.clone();
6393 iter.pos = 0;
6394 for attr in iter {
6395 if let Ok(LinkinfoBondAttrs::ActiveSlave(val)) = attr {
6396 return Ok(val);
6397 }
6398 }
6399 Err(ErrorContext::new_missing(
6400 "LinkinfoBondAttrs",
6401 "ActiveSlave",
6402 self.orig_loc,
6403 self.buf.as_ptr() as usize,
6404 ))
6405 }
6406 pub fn get_miimon(&self) -> Result<u32, ErrorContext> {
6407 let mut iter = self.clone();
6408 iter.pos = 0;
6409 for attr in iter {
6410 if let Ok(LinkinfoBondAttrs::Miimon(val)) = attr {
6411 return Ok(val);
6412 }
6413 }
6414 Err(ErrorContext::new_missing(
6415 "LinkinfoBondAttrs",
6416 "Miimon",
6417 self.orig_loc,
6418 self.buf.as_ptr() as usize,
6419 ))
6420 }
6421 pub fn get_updelay(&self) -> Result<u32, ErrorContext> {
6422 let mut iter = self.clone();
6423 iter.pos = 0;
6424 for attr in iter {
6425 if let Ok(LinkinfoBondAttrs::Updelay(val)) = attr {
6426 return Ok(val);
6427 }
6428 }
6429 Err(ErrorContext::new_missing(
6430 "LinkinfoBondAttrs",
6431 "Updelay",
6432 self.orig_loc,
6433 self.buf.as_ptr() as usize,
6434 ))
6435 }
6436 pub fn get_downdelay(&self) -> Result<u32, ErrorContext> {
6437 let mut iter = self.clone();
6438 iter.pos = 0;
6439 for attr in iter {
6440 if let Ok(LinkinfoBondAttrs::Downdelay(val)) = attr {
6441 return Ok(val);
6442 }
6443 }
6444 Err(ErrorContext::new_missing(
6445 "LinkinfoBondAttrs",
6446 "Downdelay",
6447 self.orig_loc,
6448 self.buf.as_ptr() as usize,
6449 ))
6450 }
6451 pub fn get_use_carrier(&self) -> Result<u8, ErrorContext> {
6452 let mut iter = self.clone();
6453 iter.pos = 0;
6454 for attr in iter {
6455 if let Ok(LinkinfoBondAttrs::UseCarrier(val)) = attr {
6456 return Ok(val);
6457 }
6458 }
6459 Err(ErrorContext::new_missing(
6460 "LinkinfoBondAttrs",
6461 "UseCarrier",
6462 self.orig_loc,
6463 self.buf.as_ptr() as usize,
6464 ))
6465 }
6466 pub fn get_arp_interval(&self) -> Result<u32, ErrorContext> {
6467 let mut iter = self.clone();
6468 iter.pos = 0;
6469 for attr in iter {
6470 if let Ok(LinkinfoBondAttrs::ArpInterval(val)) = attr {
6471 return Ok(val);
6472 }
6473 }
6474 Err(ErrorContext::new_missing(
6475 "LinkinfoBondAttrs",
6476 "ArpInterval",
6477 self.orig_loc,
6478 self.buf.as_ptr() as usize,
6479 ))
6480 }
6481 pub fn get_arp_ip_target(
6482 &self,
6483 ) -> Result<ArrayIterable<IterableArrayIpv4Addr<'a>, std::net::Ipv4Addr>, ErrorContext> {
6484 for attr in self.clone() {
6485 if let Ok(LinkinfoBondAttrs::ArpIpTarget(val)) = attr {
6486 return Ok(ArrayIterable::new(val));
6487 }
6488 }
6489 Err(ErrorContext::new_missing(
6490 "LinkinfoBondAttrs",
6491 "ArpIpTarget",
6492 self.orig_loc,
6493 self.buf.as_ptr() as usize,
6494 ))
6495 }
6496 pub fn get_arp_validate(&self) -> Result<u32, ErrorContext> {
6497 let mut iter = self.clone();
6498 iter.pos = 0;
6499 for attr in iter {
6500 if let Ok(LinkinfoBondAttrs::ArpValidate(val)) = attr {
6501 return Ok(val);
6502 }
6503 }
6504 Err(ErrorContext::new_missing(
6505 "LinkinfoBondAttrs",
6506 "ArpValidate",
6507 self.orig_loc,
6508 self.buf.as_ptr() as usize,
6509 ))
6510 }
6511 pub fn get_arp_all_targets(&self) -> Result<u32, ErrorContext> {
6512 let mut iter = self.clone();
6513 iter.pos = 0;
6514 for attr in iter {
6515 if let Ok(LinkinfoBondAttrs::ArpAllTargets(val)) = attr {
6516 return Ok(val);
6517 }
6518 }
6519 Err(ErrorContext::new_missing(
6520 "LinkinfoBondAttrs",
6521 "ArpAllTargets",
6522 self.orig_loc,
6523 self.buf.as_ptr() as usize,
6524 ))
6525 }
6526 pub fn get_primary(&self) -> Result<u32, ErrorContext> {
6527 let mut iter = self.clone();
6528 iter.pos = 0;
6529 for attr in iter {
6530 if let Ok(LinkinfoBondAttrs::Primary(val)) = attr {
6531 return Ok(val);
6532 }
6533 }
6534 Err(ErrorContext::new_missing(
6535 "LinkinfoBondAttrs",
6536 "Primary",
6537 self.orig_loc,
6538 self.buf.as_ptr() as usize,
6539 ))
6540 }
6541 pub fn get_primary_reselect(&self) -> Result<u8, ErrorContext> {
6542 let mut iter = self.clone();
6543 iter.pos = 0;
6544 for attr in iter {
6545 if let Ok(LinkinfoBondAttrs::PrimaryReselect(val)) = attr {
6546 return Ok(val);
6547 }
6548 }
6549 Err(ErrorContext::new_missing(
6550 "LinkinfoBondAttrs",
6551 "PrimaryReselect",
6552 self.orig_loc,
6553 self.buf.as_ptr() as usize,
6554 ))
6555 }
6556 pub fn get_fail_over_mac(&self) -> Result<u8, ErrorContext> {
6557 let mut iter = self.clone();
6558 iter.pos = 0;
6559 for attr in iter {
6560 if let Ok(LinkinfoBondAttrs::FailOverMac(val)) = attr {
6561 return Ok(val);
6562 }
6563 }
6564 Err(ErrorContext::new_missing(
6565 "LinkinfoBondAttrs",
6566 "FailOverMac",
6567 self.orig_loc,
6568 self.buf.as_ptr() as usize,
6569 ))
6570 }
6571 pub fn get_xmit_hash_policy(&self) -> Result<u8, ErrorContext> {
6572 let mut iter = self.clone();
6573 iter.pos = 0;
6574 for attr in iter {
6575 if let Ok(LinkinfoBondAttrs::XmitHashPolicy(val)) = attr {
6576 return Ok(val);
6577 }
6578 }
6579 Err(ErrorContext::new_missing(
6580 "LinkinfoBondAttrs",
6581 "XmitHashPolicy",
6582 self.orig_loc,
6583 self.buf.as_ptr() as usize,
6584 ))
6585 }
6586 pub fn get_resend_igmp(&self) -> Result<u32, ErrorContext> {
6587 let mut iter = self.clone();
6588 iter.pos = 0;
6589 for attr in iter {
6590 if let Ok(LinkinfoBondAttrs::ResendIgmp(val)) = attr {
6591 return Ok(val);
6592 }
6593 }
6594 Err(ErrorContext::new_missing(
6595 "LinkinfoBondAttrs",
6596 "ResendIgmp",
6597 self.orig_loc,
6598 self.buf.as_ptr() as usize,
6599 ))
6600 }
6601 pub fn get_num_peer_notif(&self) -> Result<u8, ErrorContext> {
6602 let mut iter = self.clone();
6603 iter.pos = 0;
6604 for attr in iter {
6605 if let Ok(LinkinfoBondAttrs::NumPeerNotif(val)) = attr {
6606 return Ok(val);
6607 }
6608 }
6609 Err(ErrorContext::new_missing(
6610 "LinkinfoBondAttrs",
6611 "NumPeerNotif",
6612 self.orig_loc,
6613 self.buf.as_ptr() as usize,
6614 ))
6615 }
6616 pub fn get_all_slaves_active(&self) -> Result<u8, ErrorContext> {
6617 let mut iter = self.clone();
6618 iter.pos = 0;
6619 for attr in iter {
6620 if let Ok(LinkinfoBondAttrs::AllSlavesActive(val)) = attr {
6621 return Ok(val);
6622 }
6623 }
6624 Err(ErrorContext::new_missing(
6625 "LinkinfoBondAttrs",
6626 "AllSlavesActive",
6627 self.orig_loc,
6628 self.buf.as_ptr() as usize,
6629 ))
6630 }
6631 pub fn get_min_links(&self) -> Result<u32, ErrorContext> {
6632 let mut iter = self.clone();
6633 iter.pos = 0;
6634 for attr in iter {
6635 if let Ok(LinkinfoBondAttrs::MinLinks(val)) = attr {
6636 return Ok(val);
6637 }
6638 }
6639 Err(ErrorContext::new_missing(
6640 "LinkinfoBondAttrs",
6641 "MinLinks",
6642 self.orig_loc,
6643 self.buf.as_ptr() as usize,
6644 ))
6645 }
6646 pub fn get_lp_interval(&self) -> Result<u32, ErrorContext> {
6647 let mut iter = self.clone();
6648 iter.pos = 0;
6649 for attr in iter {
6650 if let Ok(LinkinfoBondAttrs::LpInterval(val)) = attr {
6651 return Ok(val);
6652 }
6653 }
6654 Err(ErrorContext::new_missing(
6655 "LinkinfoBondAttrs",
6656 "LpInterval",
6657 self.orig_loc,
6658 self.buf.as_ptr() as usize,
6659 ))
6660 }
6661 pub fn get_packets_per_slave(&self) -> Result<u32, ErrorContext> {
6662 let mut iter = self.clone();
6663 iter.pos = 0;
6664 for attr in iter {
6665 if let Ok(LinkinfoBondAttrs::PacketsPerSlave(val)) = attr {
6666 return Ok(val);
6667 }
6668 }
6669 Err(ErrorContext::new_missing(
6670 "LinkinfoBondAttrs",
6671 "PacketsPerSlave",
6672 self.orig_loc,
6673 self.buf.as_ptr() as usize,
6674 ))
6675 }
6676 pub fn get_ad_lacp_rate(&self) -> Result<u8, ErrorContext> {
6677 let mut iter = self.clone();
6678 iter.pos = 0;
6679 for attr in iter {
6680 if let Ok(LinkinfoBondAttrs::AdLacpRate(val)) = attr {
6681 return Ok(val);
6682 }
6683 }
6684 Err(ErrorContext::new_missing(
6685 "LinkinfoBondAttrs",
6686 "AdLacpRate",
6687 self.orig_loc,
6688 self.buf.as_ptr() as usize,
6689 ))
6690 }
6691 pub fn get_ad_select(&self) -> Result<u8, ErrorContext> {
6692 let mut iter = self.clone();
6693 iter.pos = 0;
6694 for attr in iter {
6695 if let Ok(LinkinfoBondAttrs::AdSelect(val)) = attr {
6696 return Ok(val);
6697 }
6698 }
6699 Err(ErrorContext::new_missing(
6700 "LinkinfoBondAttrs",
6701 "AdSelect",
6702 self.orig_loc,
6703 self.buf.as_ptr() as usize,
6704 ))
6705 }
6706 pub fn get_ad_info(&self) -> Result<IterableBondAdInfoAttrs<'a>, ErrorContext> {
6707 let mut iter = self.clone();
6708 iter.pos = 0;
6709 for attr in iter {
6710 if let Ok(LinkinfoBondAttrs::AdInfo(val)) = attr {
6711 return Ok(val);
6712 }
6713 }
6714 Err(ErrorContext::new_missing(
6715 "LinkinfoBondAttrs",
6716 "AdInfo",
6717 self.orig_loc,
6718 self.buf.as_ptr() as usize,
6719 ))
6720 }
6721 pub fn get_ad_actor_sys_prio(&self) -> Result<u16, ErrorContext> {
6722 let mut iter = self.clone();
6723 iter.pos = 0;
6724 for attr in iter {
6725 if let Ok(LinkinfoBondAttrs::AdActorSysPrio(val)) = attr {
6726 return Ok(val);
6727 }
6728 }
6729 Err(ErrorContext::new_missing(
6730 "LinkinfoBondAttrs",
6731 "AdActorSysPrio",
6732 self.orig_loc,
6733 self.buf.as_ptr() as usize,
6734 ))
6735 }
6736 pub fn get_ad_user_port_key(&self) -> Result<u16, ErrorContext> {
6737 let mut iter = self.clone();
6738 iter.pos = 0;
6739 for attr in iter {
6740 if let Ok(LinkinfoBondAttrs::AdUserPortKey(val)) = attr {
6741 return Ok(val);
6742 }
6743 }
6744 Err(ErrorContext::new_missing(
6745 "LinkinfoBondAttrs",
6746 "AdUserPortKey",
6747 self.orig_loc,
6748 self.buf.as_ptr() as usize,
6749 ))
6750 }
6751 pub fn get_ad_actor_system(&self) -> Result<&'a [u8], ErrorContext> {
6752 let mut iter = self.clone();
6753 iter.pos = 0;
6754 for attr in iter {
6755 if let Ok(LinkinfoBondAttrs::AdActorSystem(val)) = attr {
6756 return Ok(val);
6757 }
6758 }
6759 Err(ErrorContext::new_missing(
6760 "LinkinfoBondAttrs",
6761 "AdActorSystem",
6762 self.orig_loc,
6763 self.buf.as_ptr() as usize,
6764 ))
6765 }
6766 pub fn get_tlb_dynamic_lb(&self) -> Result<u8, ErrorContext> {
6767 let mut iter = self.clone();
6768 iter.pos = 0;
6769 for attr in iter {
6770 if let Ok(LinkinfoBondAttrs::TlbDynamicLb(val)) = attr {
6771 return Ok(val);
6772 }
6773 }
6774 Err(ErrorContext::new_missing(
6775 "LinkinfoBondAttrs",
6776 "TlbDynamicLb",
6777 self.orig_loc,
6778 self.buf.as_ptr() as usize,
6779 ))
6780 }
6781 pub fn get_peer_notif_delay(&self) -> Result<u32, ErrorContext> {
6782 let mut iter = self.clone();
6783 iter.pos = 0;
6784 for attr in iter {
6785 if let Ok(LinkinfoBondAttrs::PeerNotifDelay(val)) = attr {
6786 return Ok(val);
6787 }
6788 }
6789 Err(ErrorContext::new_missing(
6790 "LinkinfoBondAttrs",
6791 "PeerNotifDelay",
6792 self.orig_loc,
6793 self.buf.as_ptr() as usize,
6794 ))
6795 }
6796 pub fn get_ad_lacp_active(&self) -> Result<u8, ErrorContext> {
6797 let mut iter = self.clone();
6798 iter.pos = 0;
6799 for attr in iter {
6800 if let Ok(LinkinfoBondAttrs::AdLacpActive(val)) = attr {
6801 return Ok(val);
6802 }
6803 }
6804 Err(ErrorContext::new_missing(
6805 "LinkinfoBondAttrs",
6806 "AdLacpActive",
6807 self.orig_loc,
6808 self.buf.as_ptr() as usize,
6809 ))
6810 }
6811 pub fn get_missed_max(&self) -> Result<u8, ErrorContext> {
6812 let mut iter = self.clone();
6813 iter.pos = 0;
6814 for attr in iter {
6815 if let Ok(LinkinfoBondAttrs::MissedMax(val)) = attr {
6816 return Ok(val);
6817 }
6818 }
6819 Err(ErrorContext::new_missing(
6820 "LinkinfoBondAttrs",
6821 "MissedMax",
6822 self.orig_loc,
6823 self.buf.as_ptr() as usize,
6824 ))
6825 }
6826 pub fn get_ns_ip6_target(
6827 &self,
6828 ) -> Result<ArrayIterable<IterableArrayBinary<'a>, &'a [u8]>, ErrorContext> {
6829 for attr in self.clone() {
6830 if let Ok(LinkinfoBondAttrs::NsIp6Target(val)) = attr {
6831 return Ok(ArrayIterable::new(val));
6832 }
6833 }
6834 Err(ErrorContext::new_missing(
6835 "LinkinfoBondAttrs",
6836 "NsIp6Target",
6837 self.orig_loc,
6838 self.buf.as_ptr() as usize,
6839 ))
6840 }
6841 pub fn get_coupled_control(&self) -> Result<u8, ErrorContext> {
6842 let mut iter = self.clone();
6843 iter.pos = 0;
6844 for attr in iter {
6845 if let Ok(LinkinfoBondAttrs::CoupledControl(val)) = attr {
6846 return Ok(val);
6847 }
6848 }
6849 Err(ErrorContext::new_missing(
6850 "LinkinfoBondAttrs",
6851 "CoupledControl",
6852 self.orig_loc,
6853 self.buf.as_ptr() as usize,
6854 ))
6855 }
6856}
6857#[derive(Clone, Copy, Default)]
6858pub struct IterableArrayIpv4Addr<'a> {
6859 buf: &'a [u8],
6860 pos: usize,
6861 orig_loc: usize,
6862}
6863impl<'a> IterableArrayIpv4Addr<'a> {
6864 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6865 Self {
6866 buf,
6867 pos: 0,
6868 orig_loc,
6869 }
6870 }
6871 pub fn get_buf(&self) -> &'a [u8] {
6872 self.buf
6873 }
6874}
6875impl<'a> Iterator for IterableArrayIpv4Addr<'a> {
6876 type Item = Result<std::net::Ipv4Addr, ErrorContext>;
6877 fn next(&mut self) -> Option<Self::Item> {
6878 if self.buf.len() == self.pos {
6879 return None;
6880 }
6881 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
6882 {
6883 let Some(res) = parse_be_u32(next).map(Ipv4Addr::from_bits) else {
6884 break;
6885 };
6886 return Some(Ok(res));
6887 }
6888 }
6889 let pos = self.pos;
6890 self.pos = self.buf.len();
6891 Some(Err(ErrorContext::new(
6892 "Ipv4Addr",
6893 None,
6894 self.orig_loc,
6895 self.buf.as_ptr().wrapping_add(pos) as usize,
6896 )))
6897 }
6898}
6899#[derive(Clone, Copy, Default)]
6900pub struct IterableArrayBinary<'a> {
6901 buf: &'a [u8],
6902 pos: usize,
6903 orig_loc: usize,
6904}
6905impl<'a> IterableArrayBinary<'a> {
6906 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6907 Self {
6908 buf,
6909 pos: 0,
6910 orig_loc,
6911 }
6912 }
6913 pub fn get_buf(&self) -> &'a [u8] {
6914 self.buf
6915 }
6916}
6917impl<'a> Iterator for IterableArrayBinary<'a> {
6918 type Item = Result<&'a [u8], ErrorContext>;
6919 fn next(&mut self) -> Option<Self::Item> {
6920 if self.buf.len() == self.pos {
6921 return None;
6922 }
6923 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
6924 {
6925 let Some(res) = Some(next) else { break };
6926 return Some(Ok(res));
6927 }
6928 }
6929 let pos = self.pos;
6930 self.pos = self.buf.len();
6931 Some(Err(ErrorContext::new(
6932 "Binary",
6933 None,
6934 self.orig_loc,
6935 self.buf.as_ptr().wrapping_add(pos) as usize,
6936 )))
6937 }
6938}
6939impl LinkinfoBondAttrs<'_> {
6940 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoBondAttrs<'a> {
6941 IterableLinkinfoBondAttrs::with_loc(buf, buf.as_ptr() as usize)
6942 }
6943 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6944 let res = match r#type {
6945 1u16 => "Mode",
6946 2u16 => "ActiveSlave",
6947 3u16 => "Miimon",
6948 4u16 => "Updelay",
6949 5u16 => "Downdelay",
6950 6u16 => "UseCarrier",
6951 7u16 => "ArpInterval",
6952 8u16 => "ArpIpTarget",
6953 9u16 => "ArpValidate",
6954 10u16 => "ArpAllTargets",
6955 11u16 => "Primary",
6956 12u16 => "PrimaryReselect",
6957 13u16 => "FailOverMac",
6958 14u16 => "XmitHashPolicy",
6959 15u16 => "ResendIgmp",
6960 16u16 => "NumPeerNotif",
6961 17u16 => "AllSlavesActive",
6962 18u16 => "MinLinks",
6963 19u16 => "LpInterval",
6964 20u16 => "PacketsPerSlave",
6965 21u16 => "AdLacpRate",
6966 22u16 => "AdSelect",
6967 23u16 => "AdInfo",
6968 24u16 => "AdActorSysPrio",
6969 25u16 => "AdUserPortKey",
6970 26u16 => "AdActorSystem",
6971 27u16 => "TlbDynamicLb",
6972 28u16 => "PeerNotifDelay",
6973 29u16 => "AdLacpActive",
6974 30u16 => "MissedMax",
6975 31u16 => "NsIp6Target",
6976 32u16 => "CoupledControl",
6977 _ => return None,
6978 };
6979 Some(res)
6980 }
6981}
6982#[derive(Clone, Copy, Default)]
6983pub struct IterableLinkinfoBondAttrs<'a> {
6984 buf: &'a [u8],
6985 pos: usize,
6986 orig_loc: usize,
6987}
6988impl<'a> IterableLinkinfoBondAttrs<'a> {
6989 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6990 Self {
6991 buf,
6992 pos: 0,
6993 orig_loc,
6994 }
6995 }
6996 pub fn get_buf(&self) -> &'a [u8] {
6997 self.buf
6998 }
6999}
7000impl<'a> Iterator for IterableLinkinfoBondAttrs<'a> {
7001 type Item = Result<LinkinfoBondAttrs<'a>, ErrorContext>;
7002 fn next(&mut self) -> Option<Self::Item> {
7003 let mut pos;
7004 let mut r#type;
7005 loop {
7006 pos = self.pos;
7007 r#type = None;
7008 if self.buf.len() == self.pos {
7009 return None;
7010 }
7011 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
7012 self.pos = self.buf.len();
7013 break;
7014 };
7015 r#type = Some(header.r#type);
7016 let res = match header.r#type {
7017 1u16 => LinkinfoBondAttrs::Mode({
7018 let res = parse_u8(next);
7019 let Some(val) = res else { break };
7020 val
7021 }),
7022 2u16 => LinkinfoBondAttrs::ActiveSlave({
7023 let res = parse_u32(next);
7024 let Some(val) = res else { break };
7025 val
7026 }),
7027 3u16 => LinkinfoBondAttrs::Miimon({
7028 let res = parse_u32(next);
7029 let Some(val) = res else { break };
7030 val
7031 }),
7032 4u16 => LinkinfoBondAttrs::Updelay({
7033 let res = parse_u32(next);
7034 let Some(val) = res else { break };
7035 val
7036 }),
7037 5u16 => LinkinfoBondAttrs::Downdelay({
7038 let res = parse_u32(next);
7039 let Some(val) = res else { break };
7040 val
7041 }),
7042 6u16 => LinkinfoBondAttrs::UseCarrier({
7043 let res = parse_u8(next);
7044 let Some(val) = res else { break };
7045 val
7046 }),
7047 7u16 => LinkinfoBondAttrs::ArpInterval({
7048 let res = parse_u32(next);
7049 let Some(val) = res else { break };
7050 val
7051 }),
7052 8u16 => LinkinfoBondAttrs::ArpIpTarget({
7053 let res = Some(IterableArrayIpv4Addr::with_loc(next, self.orig_loc));
7054 let Some(val) = res else { break };
7055 val
7056 }),
7057 9u16 => LinkinfoBondAttrs::ArpValidate({
7058 let res = parse_u32(next);
7059 let Some(val) = res else { break };
7060 val
7061 }),
7062 10u16 => LinkinfoBondAttrs::ArpAllTargets({
7063 let res = parse_u32(next);
7064 let Some(val) = res else { break };
7065 val
7066 }),
7067 11u16 => LinkinfoBondAttrs::Primary({
7068 let res = parse_u32(next);
7069 let Some(val) = res else { break };
7070 val
7071 }),
7072 12u16 => LinkinfoBondAttrs::PrimaryReselect({
7073 let res = parse_u8(next);
7074 let Some(val) = res else { break };
7075 val
7076 }),
7077 13u16 => LinkinfoBondAttrs::FailOverMac({
7078 let res = parse_u8(next);
7079 let Some(val) = res else { break };
7080 val
7081 }),
7082 14u16 => LinkinfoBondAttrs::XmitHashPolicy({
7083 let res = parse_u8(next);
7084 let Some(val) = res else { break };
7085 val
7086 }),
7087 15u16 => LinkinfoBondAttrs::ResendIgmp({
7088 let res = parse_u32(next);
7089 let Some(val) = res else { break };
7090 val
7091 }),
7092 16u16 => LinkinfoBondAttrs::NumPeerNotif({
7093 let res = parse_u8(next);
7094 let Some(val) = res else { break };
7095 val
7096 }),
7097 17u16 => LinkinfoBondAttrs::AllSlavesActive({
7098 let res = parse_u8(next);
7099 let Some(val) = res else { break };
7100 val
7101 }),
7102 18u16 => LinkinfoBondAttrs::MinLinks({
7103 let res = parse_u32(next);
7104 let Some(val) = res else { break };
7105 val
7106 }),
7107 19u16 => LinkinfoBondAttrs::LpInterval({
7108 let res = parse_u32(next);
7109 let Some(val) = res else { break };
7110 val
7111 }),
7112 20u16 => LinkinfoBondAttrs::PacketsPerSlave({
7113 let res = parse_u32(next);
7114 let Some(val) = res else { break };
7115 val
7116 }),
7117 21u16 => LinkinfoBondAttrs::AdLacpRate({
7118 let res = parse_u8(next);
7119 let Some(val) = res else { break };
7120 val
7121 }),
7122 22u16 => LinkinfoBondAttrs::AdSelect({
7123 let res = parse_u8(next);
7124 let Some(val) = res else { break };
7125 val
7126 }),
7127 23u16 => LinkinfoBondAttrs::AdInfo({
7128 let res = Some(IterableBondAdInfoAttrs::with_loc(next, self.orig_loc));
7129 let Some(val) = res else { break };
7130 val
7131 }),
7132 24u16 => LinkinfoBondAttrs::AdActorSysPrio({
7133 let res = parse_u16(next);
7134 let Some(val) = res else { break };
7135 val
7136 }),
7137 25u16 => LinkinfoBondAttrs::AdUserPortKey({
7138 let res = parse_u16(next);
7139 let Some(val) = res else { break };
7140 val
7141 }),
7142 26u16 => LinkinfoBondAttrs::AdActorSystem({
7143 let res = Some(next);
7144 let Some(val) = res else { break };
7145 val
7146 }),
7147 27u16 => LinkinfoBondAttrs::TlbDynamicLb({
7148 let res = parse_u8(next);
7149 let Some(val) = res else { break };
7150 val
7151 }),
7152 28u16 => LinkinfoBondAttrs::PeerNotifDelay({
7153 let res = parse_u32(next);
7154 let Some(val) = res else { break };
7155 val
7156 }),
7157 29u16 => LinkinfoBondAttrs::AdLacpActive({
7158 let res = parse_u8(next);
7159 let Some(val) = res else { break };
7160 val
7161 }),
7162 30u16 => LinkinfoBondAttrs::MissedMax({
7163 let res = parse_u8(next);
7164 let Some(val) = res else { break };
7165 val
7166 }),
7167 31u16 => LinkinfoBondAttrs::NsIp6Target({
7168 let res = Some(IterableArrayBinary::with_loc(next, self.orig_loc));
7169 let Some(val) = res else { break };
7170 val
7171 }),
7172 32u16 => LinkinfoBondAttrs::CoupledControl({
7173 let res = parse_u8(next);
7174 let Some(val) = res else { break };
7175 val
7176 }),
7177 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
7178 n => continue,
7179 };
7180 return Some(Ok(res));
7181 }
7182 Some(Err(ErrorContext::new(
7183 "LinkinfoBondAttrs",
7184 r#type.and_then(|t| LinkinfoBondAttrs::attr_from_type(t)),
7185 self.orig_loc,
7186 self.buf.as_ptr().wrapping_add(pos) as usize,
7187 )))
7188 }
7189}
7190impl std::fmt::Debug for IterableArrayIpv4Addr<'_> {
7191 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7192 fmt.debug_list()
7193 .entries(self.clone().map(FlattenErrorContext))
7194 .finish()
7195 }
7196}
7197impl std::fmt::Debug for IterableArrayBinary<'_> {
7198 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7199 fmt.debug_list()
7200 .entries(self.clone().map(FlattenErrorContext))
7201 .finish()
7202 }
7203}
7204impl<'a> std::fmt::Debug for IterableLinkinfoBondAttrs<'_> {
7205 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7206 let mut fmt = f.debug_struct("LinkinfoBondAttrs");
7207 for attr in self.clone() {
7208 let attr = match attr {
7209 Ok(a) => a,
7210 Err(err) => {
7211 fmt.finish()?;
7212 f.write_str("Err(")?;
7213 err.fmt(f)?;
7214 return f.write_str(")");
7215 }
7216 };
7217 match attr {
7218 LinkinfoBondAttrs::Mode(val) => fmt.field("Mode", &val),
7219 LinkinfoBondAttrs::ActiveSlave(val) => fmt.field("ActiveSlave", &val),
7220 LinkinfoBondAttrs::Miimon(val) => fmt.field("Miimon", &val),
7221 LinkinfoBondAttrs::Updelay(val) => fmt.field("Updelay", &val),
7222 LinkinfoBondAttrs::Downdelay(val) => fmt.field("Downdelay", &val),
7223 LinkinfoBondAttrs::UseCarrier(val) => fmt.field("UseCarrier", &val),
7224 LinkinfoBondAttrs::ArpInterval(val) => fmt.field("ArpInterval", &val),
7225 LinkinfoBondAttrs::ArpIpTarget(val) => fmt.field("ArpIpTarget", &val),
7226 LinkinfoBondAttrs::ArpValidate(val) => fmt.field("ArpValidate", &val),
7227 LinkinfoBondAttrs::ArpAllTargets(val) => fmt.field("ArpAllTargets", &val),
7228 LinkinfoBondAttrs::Primary(val) => fmt.field("Primary", &val),
7229 LinkinfoBondAttrs::PrimaryReselect(val) => fmt.field("PrimaryReselect", &val),
7230 LinkinfoBondAttrs::FailOverMac(val) => fmt.field("FailOverMac", &val),
7231 LinkinfoBondAttrs::XmitHashPolicy(val) => fmt.field("XmitHashPolicy", &val),
7232 LinkinfoBondAttrs::ResendIgmp(val) => fmt.field("ResendIgmp", &val),
7233 LinkinfoBondAttrs::NumPeerNotif(val) => fmt.field("NumPeerNotif", &val),
7234 LinkinfoBondAttrs::AllSlavesActive(val) => fmt.field("AllSlavesActive", &val),
7235 LinkinfoBondAttrs::MinLinks(val) => fmt.field("MinLinks", &val),
7236 LinkinfoBondAttrs::LpInterval(val) => fmt.field("LpInterval", &val),
7237 LinkinfoBondAttrs::PacketsPerSlave(val) => fmt.field("PacketsPerSlave", &val),
7238 LinkinfoBondAttrs::AdLacpRate(val) => fmt.field("AdLacpRate", &val),
7239 LinkinfoBondAttrs::AdSelect(val) => fmt.field("AdSelect", &val),
7240 LinkinfoBondAttrs::AdInfo(val) => fmt.field("AdInfo", &val),
7241 LinkinfoBondAttrs::AdActorSysPrio(val) => fmt.field("AdActorSysPrio", &val),
7242 LinkinfoBondAttrs::AdUserPortKey(val) => fmt.field("AdUserPortKey", &val),
7243 LinkinfoBondAttrs::AdActorSystem(val) => {
7244 fmt.field("AdActorSystem", &FormatMac(val))
7245 }
7246 LinkinfoBondAttrs::TlbDynamicLb(val) => fmt.field("TlbDynamicLb", &val),
7247 LinkinfoBondAttrs::PeerNotifDelay(val) => fmt.field("PeerNotifDelay", &val),
7248 LinkinfoBondAttrs::AdLacpActive(val) => fmt.field("AdLacpActive", &val),
7249 LinkinfoBondAttrs::MissedMax(val) => fmt.field("MissedMax", &val),
7250 LinkinfoBondAttrs::NsIp6Target(val) => fmt.field("NsIp6Target", &val),
7251 LinkinfoBondAttrs::CoupledControl(val) => fmt.field("CoupledControl", &val),
7252 };
7253 }
7254 fmt.finish()
7255 }
7256}
7257impl IterableLinkinfoBondAttrs<'_> {
7258 pub fn lookup_attr(
7259 &self,
7260 offset: usize,
7261 missing_type: Option<u16>,
7262 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7263 let mut stack = Vec::new();
7264 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
7265 if missing_type.is_some() && cur == offset {
7266 stack.push(("LinkinfoBondAttrs", offset));
7267 return (
7268 stack,
7269 missing_type.and_then(|t| LinkinfoBondAttrs::attr_from_type(t)),
7270 );
7271 }
7272 if cur > offset || cur + self.buf.len() < offset {
7273 return (stack, None);
7274 }
7275 let mut attrs = self.clone();
7276 let mut last_off = cur + attrs.pos;
7277 let mut missing = None;
7278 while let Some(attr) = attrs.next() {
7279 let Ok(attr) = attr else { break };
7280 match attr {
7281 LinkinfoBondAttrs::Mode(val) => {
7282 if last_off == offset {
7283 stack.push(("Mode", last_off));
7284 break;
7285 }
7286 }
7287 LinkinfoBondAttrs::ActiveSlave(val) => {
7288 if last_off == offset {
7289 stack.push(("ActiveSlave", last_off));
7290 break;
7291 }
7292 }
7293 LinkinfoBondAttrs::Miimon(val) => {
7294 if last_off == offset {
7295 stack.push(("Miimon", last_off));
7296 break;
7297 }
7298 }
7299 LinkinfoBondAttrs::Updelay(val) => {
7300 if last_off == offset {
7301 stack.push(("Updelay", last_off));
7302 break;
7303 }
7304 }
7305 LinkinfoBondAttrs::Downdelay(val) => {
7306 if last_off == offset {
7307 stack.push(("Downdelay", last_off));
7308 break;
7309 }
7310 }
7311 LinkinfoBondAttrs::UseCarrier(val) => {
7312 if last_off == offset {
7313 stack.push(("UseCarrier", last_off));
7314 break;
7315 }
7316 }
7317 LinkinfoBondAttrs::ArpInterval(val) => {
7318 if last_off == offset {
7319 stack.push(("ArpInterval", last_off));
7320 break;
7321 }
7322 }
7323 LinkinfoBondAttrs::ArpIpTarget(val) => {
7324 if last_off == offset {
7325 stack.push(("ArpIpTarget", last_off));
7326 break;
7327 }
7328 }
7329 LinkinfoBondAttrs::ArpValidate(val) => {
7330 if last_off == offset {
7331 stack.push(("ArpValidate", last_off));
7332 break;
7333 }
7334 }
7335 LinkinfoBondAttrs::ArpAllTargets(val) => {
7336 if last_off == offset {
7337 stack.push(("ArpAllTargets", last_off));
7338 break;
7339 }
7340 }
7341 LinkinfoBondAttrs::Primary(val) => {
7342 if last_off == offset {
7343 stack.push(("Primary", last_off));
7344 break;
7345 }
7346 }
7347 LinkinfoBondAttrs::PrimaryReselect(val) => {
7348 if last_off == offset {
7349 stack.push(("PrimaryReselect", last_off));
7350 break;
7351 }
7352 }
7353 LinkinfoBondAttrs::FailOverMac(val) => {
7354 if last_off == offset {
7355 stack.push(("FailOverMac", last_off));
7356 break;
7357 }
7358 }
7359 LinkinfoBondAttrs::XmitHashPolicy(val) => {
7360 if last_off == offset {
7361 stack.push(("XmitHashPolicy", last_off));
7362 break;
7363 }
7364 }
7365 LinkinfoBondAttrs::ResendIgmp(val) => {
7366 if last_off == offset {
7367 stack.push(("ResendIgmp", last_off));
7368 break;
7369 }
7370 }
7371 LinkinfoBondAttrs::NumPeerNotif(val) => {
7372 if last_off == offset {
7373 stack.push(("NumPeerNotif", last_off));
7374 break;
7375 }
7376 }
7377 LinkinfoBondAttrs::AllSlavesActive(val) => {
7378 if last_off == offset {
7379 stack.push(("AllSlavesActive", last_off));
7380 break;
7381 }
7382 }
7383 LinkinfoBondAttrs::MinLinks(val) => {
7384 if last_off == offset {
7385 stack.push(("MinLinks", last_off));
7386 break;
7387 }
7388 }
7389 LinkinfoBondAttrs::LpInterval(val) => {
7390 if last_off == offset {
7391 stack.push(("LpInterval", last_off));
7392 break;
7393 }
7394 }
7395 LinkinfoBondAttrs::PacketsPerSlave(val) => {
7396 if last_off == offset {
7397 stack.push(("PacketsPerSlave", last_off));
7398 break;
7399 }
7400 }
7401 LinkinfoBondAttrs::AdLacpRate(val) => {
7402 if last_off == offset {
7403 stack.push(("AdLacpRate", last_off));
7404 break;
7405 }
7406 }
7407 LinkinfoBondAttrs::AdSelect(val) => {
7408 if last_off == offset {
7409 stack.push(("AdSelect", last_off));
7410 break;
7411 }
7412 }
7413 LinkinfoBondAttrs::AdInfo(val) => {
7414 (stack, missing) = val.lookup_attr(offset, missing_type);
7415 if !stack.is_empty() {
7416 break;
7417 }
7418 }
7419 LinkinfoBondAttrs::AdActorSysPrio(val) => {
7420 if last_off == offset {
7421 stack.push(("AdActorSysPrio", last_off));
7422 break;
7423 }
7424 }
7425 LinkinfoBondAttrs::AdUserPortKey(val) => {
7426 if last_off == offset {
7427 stack.push(("AdUserPortKey", last_off));
7428 break;
7429 }
7430 }
7431 LinkinfoBondAttrs::AdActorSystem(val) => {
7432 if last_off == offset {
7433 stack.push(("AdActorSystem", last_off));
7434 break;
7435 }
7436 }
7437 LinkinfoBondAttrs::TlbDynamicLb(val) => {
7438 if last_off == offset {
7439 stack.push(("TlbDynamicLb", last_off));
7440 break;
7441 }
7442 }
7443 LinkinfoBondAttrs::PeerNotifDelay(val) => {
7444 if last_off == offset {
7445 stack.push(("PeerNotifDelay", last_off));
7446 break;
7447 }
7448 }
7449 LinkinfoBondAttrs::AdLacpActive(val) => {
7450 if last_off == offset {
7451 stack.push(("AdLacpActive", last_off));
7452 break;
7453 }
7454 }
7455 LinkinfoBondAttrs::MissedMax(val) => {
7456 if last_off == offset {
7457 stack.push(("MissedMax", last_off));
7458 break;
7459 }
7460 }
7461 LinkinfoBondAttrs::NsIp6Target(val) => {
7462 if last_off == offset {
7463 stack.push(("NsIp6Target", last_off));
7464 break;
7465 }
7466 }
7467 LinkinfoBondAttrs::CoupledControl(val) => {
7468 if last_off == offset {
7469 stack.push(("CoupledControl", last_off));
7470 break;
7471 }
7472 }
7473 _ => {}
7474 };
7475 last_off = cur + attrs.pos;
7476 }
7477 if !stack.is_empty() {
7478 stack.push(("LinkinfoBondAttrs", cur));
7479 }
7480 (stack, missing)
7481 }
7482}
7483#[derive(Clone)]
7484pub enum BondAdInfoAttrs<'a> {
7485 Aggregator(u16),
7486 NumPorts(u16),
7487 ActorKey(u16),
7488 PartnerKey(u16),
7489 PartnerMac(&'a [u8]),
7490}
7491impl<'a> IterableBondAdInfoAttrs<'a> {
7492 pub fn get_aggregator(&self) -> Result<u16, ErrorContext> {
7493 let mut iter = self.clone();
7494 iter.pos = 0;
7495 for attr in iter {
7496 if let Ok(BondAdInfoAttrs::Aggregator(val)) = attr {
7497 return Ok(val);
7498 }
7499 }
7500 Err(ErrorContext::new_missing(
7501 "BondAdInfoAttrs",
7502 "Aggregator",
7503 self.orig_loc,
7504 self.buf.as_ptr() as usize,
7505 ))
7506 }
7507 pub fn get_num_ports(&self) -> Result<u16, ErrorContext> {
7508 let mut iter = self.clone();
7509 iter.pos = 0;
7510 for attr in iter {
7511 if let Ok(BondAdInfoAttrs::NumPorts(val)) = attr {
7512 return Ok(val);
7513 }
7514 }
7515 Err(ErrorContext::new_missing(
7516 "BondAdInfoAttrs",
7517 "NumPorts",
7518 self.orig_loc,
7519 self.buf.as_ptr() as usize,
7520 ))
7521 }
7522 pub fn get_actor_key(&self) -> Result<u16, ErrorContext> {
7523 let mut iter = self.clone();
7524 iter.pos = 0;
7525 for attr in iter {
7526 if let Ok(BondAdInfoAttrs::ActorKey(val)) = attr {
7527 return Ok(val);
7528 }
7529 }
7530 Err(ErrorContext::new_missing(
7531 "BondAdInfoAttrs",
7532 "ActorKey",
7533 self.orig_loc,
7534 self.buf.as_ptr() as usize,
7535 ))
7536 }
7537 pub fn get_partner_key(&self) -> Result<u16, ErrorContext> {
7538 let mut iter = self.clone();
7539 iter.pos = 0;
7540 for attr in iter {
7541 if let Ok(BondAdInfoAttrs::PartnerKey(val)) = attr {
7542 return Ok(val);
7543 }
7544 }
7545 Err(ErrorContext::new_missing(
7546 "BondAdInfoAttrs",
7547 "PartnerKey",
7548 self.orig_loc,
7549 self.buf.as_ptr() as usize,
7550 ))
7551 }
7552 pub fn get_partner_mac(&self) -> Result<&'a [u8], ErrorContext> {
7553 let mut iter = self.clone();
7554 iter.pos = 0;
7555 for attr in iter {
7556 if let Ok(BondAdInfoAttrs::PartnerMac(val)) = attr {
7557 return Ok(val);
7558 }
7559 }
7560 Err(ErrorContext::new_missing(
7561 "BondAdInfoAttrs",
7562 "PartnerMac",
7563 self.orig_loc,
7564 self.buf.as_ptr() as usize,
7565 ))
7566 }
7567}
7568impl BondAdInfoAttrs<'_> {
7569 pub fn new<'a>(buf: &'a [u8]) -> IterableBondAdInfoAttrs<'a> {
7570 IterableBondAdInfoAttrs::with_loc(buf, buf.as_ptr() as usize)
7571 }
7572 fn attr_from_type(r#type: u16) -> Option<&'static str> {
7573 let res = match r#type {
7574 1u16 => "Aggregator",
7575 2u16 => "NumPorts",
7576 3u16 => "ActorKey",
7577 4u16 => "PartnerKey",
7578 5u16 => "PartnerMac",
7579 _ => return None,
7580 };
7581 Some(res)
7582 }
7583}
7584#[derive(Clone, Copy, Default)]
7585pub struct IterableBondAdInfoAttrs<'a> {
7586 buf: &'a [u8],
7587 pos: usize,
7588 orig_loc: usize,
7589}
7590impl<'a> IterableBondAdInfoAttrs<'a> {
7591 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
7592 Self {
7593 buf,
7594 pos: 0,
7595 orig_loc,
7596 }
7597 }
7598 pub fn get_buf(&self) -> &'a [u8] {
7599 self.buf
7600 }
7601}
7602impl<'a> Iterator for IterableBondAdInfoAttrs<'a> {
7603 type Item = Result<BondAdInfoAttrs<'a>, ErrorContext>;
7604 fn next(&mut self) -> Option<Self::Item> {
7605 let mut pos;
7606 let mut r#type;
7607 loop {
7608 pos = self.pos;
7609 r#type = None;
7610 if self.buf.len() == self.pos {
7611 return None;
7612 }
7613 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
7614 self.pos = self.buf.len();
7615 break;
7616 };
7617 r#type = Some(header.r#type);
7618 let res = match header.r#type {
7619 1u16 => BondAdInfoAttrs::Aggregator({
7620 let res = parse_u16(next);
7621 let Some(val) = res else { break };
7622 val
7623 }),
7624 2u16 => BondAdInfoAttrs::NumPorts({
7625 let res = parse_u16(next);
7626 let Some(val) = res else { break };
7627 val
7628 }),
7629 3u16 => BondAdInfoAttrs::ActorKey({
7630 let res = parse_u16(next);
7631 let Some(val) = res else { break };
7632 val
7633 }),
7634 4u16 => BondAdInfoAttrs::PartnerKey({
7635 let res = parse_u16(next);
7636 let Some(val) = res else { break };
7637 val
7638 }),
7639 5u16 => BondAdInfoAttrs::PartnerMac({
7640 let res = Some(next);
7641 let Some(val) = res else { break };
7642 val
7643 }),
7644 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
7645 n => continue,
7646 };
7647 return Some(Ok(res));
7648 }
7649 Some(Err(ErrorContext::new(
7650 "BondAdInfoAttrs",
7651 r#type.and_then(|t| BondAdInfoAttrs::attr_from_type(t)),
7652 self.orig_loc,
7653 self.buf.as_ptr().wrapping_add(pos) as usize,
7654 )))
7655 }
7656}
7657impl<'a> std::fmt::Debug for IterableBondAdInfoAttrs<'_> {
7658 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7659 let mut fmt = f.debug_struct("BondAdInfoAttrs");
7660 for attr in self.clone() {
7661 let attr = match attr {
7662 Ok(a) => a,
7663 Err(err) => {
7664 fmt.finish()?;
7665 f.write_str("Err(")?;
7666 err.fmt(f)?;
7667 return f.write_str(")");
7668 }
7669 };
7670 match attr {
7671 BondAdInfoAttrs::Aggregator(val) => fmt.field("Aggregator", &val),
7672 BondAdInfoAttrs::NumPorts(val) => fmt.field("NumPorts", &val),
7673 BondAdInfoAttrs::ActorKey(val) => fmt.field("ActorKey", &val),
7674 BondAdInfoAttrs::PartnerKey(val) => fmt.field("PartnerKey", &val),
7675 BondAdInfoAttrs::PartnerMac(val) => fmt.field("PartnerMac", &FormatMac(val)),
7676 };
7677 }
7678 fmt.finish()
7679 }
7680}
7681impl IterableBondAdInfoAttrs<'_> {
7682 pub fn lookup_attr(
7683 &self,
7684 offset: usize,
7685 missing_type: Option<u16>,
7686 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7687 let mut stack = Vec::new();
7688 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
7689 if missing_type.is_some() && cur == offset {
7690 stack.push(("BondAdInfoAttrs", offset));
7691 return (
7692 stack,
7693 missing_type.and_then(|t| BondAdInfoAttrs::attr_from_type(t)),
7694 );
7695 }
7696 if cur > offset || cur + self.buf.len() < offset {
7697 return (stack, None);
7698 }
7699 let mut attrs = self.clone();
7700 let mut last_off = cur + attrs.pos;
7701 while let Some(attr) = attrs.next() {
7702 let Ok(attr) = attr else { break };
7703 match attr {
7704 BondAdInfoAttrs::Aggregator(val) => {
7705 if last_off == offset {
7706 stack.push(("Aggregator", last_off));
7707 break;
7708 }
7709 }
7710 BondAdInfoAttrs::NumPorts(val) => {
7711 if last_off == offset {
7712 stack.push(("NumPorts", last_off));
7713 break;
7714 }
7715 }
7716 BondAdInfoAttrs::ActorKey(val) => {
7717 if last_off == offset {
7718 stack.push(("ActorKey", last_off));
7719 break;
7720 }
7721 }
7722 BondAdInfoAttrs::PartnerKey(val) => {
7723 if last_off == offset {
7724 stack.push(("PartnerKey", last_off));
7725 break;
7726 }
7727 }
7728 BondAdInfoAttrs::PartnerMac(val) => {
7729 if last_off == offset {
7730 stack.push(("PartnerMac", last_off));
7731 break;
7732 }
7733 }
7734 _ => {}
7735 };
7736 last_off = cur + attrs.pos;
7737 }
7738 if !stack.is_empty() {
7739 stack.push(("BondAdInfoAttrs", cur));
7740 }
7741 (stack, None)
7742 }
7743}
7744#[derive(Clone)]
7745pub enum BondSlaveAttrs<'a> {
7746 State(u8),
7747 MiiStatus(u8),
7748 LinkFailureCount(u32),
7749 PermHwaddr(&'a [u8]),
7750 QueueId(u16),
7751 AdAggregatorId(u16),
7752 AdActorOperPortState(u8),
7753 AdPartnerOperPortState(u16),
7754 Prio(u32),
7755}
7756impl<'a> IterableBondSlaveAttrs<'a> {
7757 pub fn get_state(&self) -> Result<u8, ErrorContext> {
7758 let mut iter = self.clone();
7759 iter.pos = 0;
7760 for attr in iter {
7761 if let Ok(BondSlaveAttrs::State(val)) = attr {
7762 return Ok(val);
7763 }
7764 }
7765 Err(ErrorContext::new_missing(
7766 "BondSlaveAttrs",
7767 "State",
7768 self.orig_loc,
7769 self.buf.as_ptr() as usize,
7770 ))
7771 }
7772 pub fn get_mii_status(&self) -> Result<u8, ErrorContext> {
7773 let mut iter = self.clone();
7774 iter.pos = 0;
7775 for attr in iter {
7776 if let Ok(BondSlaveAttrs::MiiStatus(val)) = attr {
7777 return Ok(val);
7778 }
7779 }
7780 Err(ErrorContext::new_missing(
7781 "BondSlaveAttrs",
7782 "MiiStatus",
7783 self.orig_loc,
7784 self.buf.as_ptr() as usize,
7785 ))
7786 }
7787 pub fn get_link_failure_count(&self) -> Result<u32, ErrorContext> {
7788 let mut iter = self.clone();
7789 iter.pos = 0;
7790 for attr in iter {
7791 if let Ok(BondSlaveAttrs::LinkFailureCount(val)) = attr {
7792 return Ok(val);
7793 }
7794 }
7795 Err(ErrorContext::new_missing(
7796 "BondSlaveAttrs",
7797 "LinkFailureCount",
7798 self.orig_loc,
7799 self.buf.as_ptr() as usize,
7800 ))
7801 }
7802 pub fn get_perm_hwaddr(&self) -> Result<&'a [u8], ErrorContext> {
7803 let mut iter = self.clone();
7804 iter.pos = 0;
7805 for attr in iter {
7806 if let Ok(BondSlaveAttrs::PermHwaddr(val)) = attr {
7807 return Ok(val);
7808 }
7809 }
7810 Err(ErrorContext::new_missing(
7811 "BondSlaveAttrs",
7812 "PermHwaddr",
7813 self.orig_loc,
7814 self.buf.as_ptr() as usize,
7815 ))
7816 }
7817 pub fn get_queue_id(&self) -> Result<u16, ErrorContext> {
7818 let mut iter = self.clone();
7819 iter.pos = 0;
7820 for attr in iter {
7821 if let Ok(BondSlaveAttrs::QueueId(val)) = attr {
7822 return Ok(val);
7823 }
7824 }
7825 Err(ErrorContext::new_missing(
7826 "BondSlaveAttrs",
7827 "QueueId",
7828 self.orig_loc,
7829 self.buf.as_ptr() as usize,
7830 ))
7831 }
7832 pub fn get_ad_aggregator_id(&self) -> Result<u16, ErrorContext> {
7833 let mut iter = self.clone();
7834 iter.pos = 0;
7835 for attr in iter {
7836 if let Ok(BondSlaveAttrs::AdAggregatorId(val)) = attr {
7837 return Ok(val);
7838 }
7839 }
7840 Err(ErrorContext::new_missing(
7841 "BondSlaveAttrs",
7842 "AdAggregatorId",
7843 self.orig_loc,
7844 self.buf.as_ptr() as usize,
7845 ))
7846 }
7847 pub fn get_ad_actor_oper_port_state(&self) -> Result<u8, ErrorContext> {
7848 let mut iter = self.clone();
7849 iter.pos = 0;
7850 for attr in iter {
7851 if let Ok(BondSlaveAttrs::AdActorOperPortState(val)) = attr {
7852 return Ok(val);
7853 }
7854 }
7855 Err(ErrorContext::new_missing(
7856 "BondSlaveAttrs",
7857 "AdActorOperPortState",
7858 self.orig_loc,
7859 self.buf.as_ptr() as usize,
7860 ))
7861 }
7862 pub fn get_ad_partner_oper_port_state(&self) -> Result<u16, ErrorContext> {
7863 let mut iter = self.clone();
7864 iter.pos = 0;
7865 for attr in iter {
7866 if let Ok(BondSlaveAttrs::AdPartnerOperPortState(val)) = attr {
7867 return Ok(val);
7868 }
7869 }
7870 Err(ErrorContext::new_missing(
7871 "BondSlaveAttrs",
7872 "AdPartnerOperPortState",
7873 self.orig_loc,
7874 self.buf.as_ptr() as usize,
7875 ))
7876 }
7877 pub fn get_prio(&self) -> Result<u32, ErrorContext> {
7878 let mut iter = self.clone();
7879 iter.pos = 0;
7880 for attr in iter {
7881 if let Ok(BondSlaveAttrs::Prio(val)) = attr {
7882 return Ok(val);
7883 }
7884 }
7885 Err(ErrorContext::new_missing(
7886 "BondSlaveAttrs",
7887 "Prio",
7888 self.orig_loc,
7889 self.buf.as_ptr() as usize,
7890 ))
7891 }
7892}
7893impl BondSlaveAttrs<'_> {
7894 pub fn new<'a>(buf: &'a [u8]) -> IterableBondSlaveAttrs<'a> {
7895 IterableBondSlaveAttrs::with_loc(buf, buf.as_ptr() as usize)
7896 }
7897 fn attr_from_type(r#type: u16) -> Option<&'static str> {
7898 let res = match r#type {
7899 1u16 => "State",
7900 2u16 => "MiiStatus",
7901 3u16 => "LinkFailureCount",
7902 4u16 => "PermHwaddr",
7903 5u16 => "QueueId",
7904 6u16 => "AdAggregatorId",
7905 7u16 => "AdActorOperPortState",
7906 8u16 => "AdPartnerOperPortState",
7907 9u16 => "Prio",
7908 _ => return None,
7909 };
7910 Some(res)
7911 }
7912}
7913#[derive(Clone, Copy, Default)]
7914pub struct IterableBondSlaveAttrs<'a> {
7915 buf: &'a [u8],
7916 pos: usize,
7917 orig_loc: usize,
7918}
7919impl<'a> IterableBondSlaveAttrs<'a> {
7920 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
7921 Self {
7922 buf,
7923 pos: 0,
7924 orig_loc,
7925 }
7926 }
7927 pub fn get_buf(&self) -> &'a [u8] {
7928 self.buf
7929 }
7930}
7931impl<'a> Iterator for IterableBondSlaveAttrs<'a> {
7932 type Item = Result<BondSlaveAttrs<'a>, ErrorContext>;
7933 fn next(&mut self) -> Option<Self::Item> {
7934 let mut pos;
7935 let mut r#type;
7936 loop {
7937 pos = self.pos;
7938 r#type = None;
7939 if self.buf.len() == self.pos {
7940 return None;
7941 }
7942 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
7943 self.pos = self.buf.len();
7944 break;
7945 };
7946 r#type = Some(header.r#type);
7947 let res = match header.r#type {
7948 1u16 => BondSlaveAttrs::State({
7949 let res = parse_u8(next);
7950 let Some(val) = res else { break };
7951 val
7952 }),
7953 2u16 => BondSlaveAttrs::MiiStatus({
7954 let res = parse_u8(next);
7955 let Some(val) = res else { break };
7956 val
7957 }),
7958 3u16 => BondSlaveAttrs::LinkFailureCount({
7959 let res = parse_u32(next);
7960 let Some(val) = res else { break };
7961 val
7962 }),
7963 4u16 => BondSlaveAttrs::PermHwaddr({
7964 let res = Some(next);
7965 let Some(val) = res else { break };
7966 val
7967 }),
7968 5u16 => BondSlaveAttrs::QueueId({
7969 let res = parse_u16(next);
7970 let Some(val) = res else { break };
7971 val
7972 }),
7973 6u16 => BondSlaveAttrs::AdAggregatorId({
7974 let res = parse_u16(next);
7975 let Some(val) = res else { break };
7976 val
7977 }),
7978 7u16 => BondSlaveAttrs::AdActorOperPortState({
7979 let res = parse_u8(next);
7980 let Some(val) = res else { break };
7981 val
7982 }),
7983 8u16 => BondSlaveAttrs::AdPartnerOperPortState({
7984 let res = parse_u16(next);
7985 let Some(val) = res else { break };
7986 val
7987 }),
7988 9u16 => BondSlaveAttrs::Prio({
7989 let res = parse_u32(next);
7990 let Some(val) = res else { break };
7991 val
7992 }),
7993 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
7994 n => continue,
7995 };
7996 return Some(Ok(res));
7997 }
7998 Some(Err(ErrorContext::new(
7999 "BondSlaveAttrs",
8000 r#type.and_then(|t| BondSlaveAttrs::attr_from_type(t)),
8001 self.orig_loc,
8002 self.buf.as_ptr().wrapping_add(pos) as usize,
8003 )))
8004 }
8005}
8006impl<'a> std::fmt::Debug for IterableBondSlaveAttrs<'_> {
8007 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8008 let mut fmt = f.debug_struct("BondSlaveAttrs");
8009 for attr in self.clone() {
8010 let attr = match attr {
8011 Ok(a) => a,
8012 Err(err) => {
8013 fmt.finish()?;
8014 f.write_str("Err(")?;
8015 err.fmt(f)?;
8016 return f.write_str(")");
8017 }
8018 };
8019 match attr {
8020 BondSlaveAttrs::State(val) => fmt.field("State", &val),
8021 BondSlaveAttrs::MiiStatus(val) => fmt.field("MiiStatus", &val),
8022 BondSlaveAttrs::LinkFailureCount(val) => fmt.field("LinkFailureCount", &val),
8023 BondSlaveAttrs::PermHwaddr(val) => fmt.field("PermHwaddr", &FormatMac(val)),
8024 BondSlaveAttrs::QueueId(val) => fmt.field("QueueId", &val),
8025 BondSlaveAttrs::AdAggregatorId(val) => fmt.field("AdAggregatorId", &val),
8026 BondSlaveAttrs::AdActorOperPortState(val) => {
8027 fmt.field("AdActorOperPortState", &val)
8028 }
8029 BondSlaveAttrs::AdPartnerOperPortState(val) => {
8030 fmt.field("AdPartnerOperPortState", &val)
8031 }
8032 BondSlaveAttrs::Prio(val) => fmt.field("Prio", &val),
8033 };
8034 }
8035 fmt.finish()
8036 }
8037}
8038impl IterableBondSlaveAttrs<'_> {
8039 pub fn lookup_attr(
8040 &self,
8041 offset: usize,
8042 missing_type: Option<u16>,
8043 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
8044 let mut stack = Vec::new();
8045 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
8046 if missing_type.is_some() && cur == offset {
8047 stack.push(("BondSlaveAttrs", offset));
8048 return (
8049 stack,
8050 missing_type.and_then(|t| BondSlaveAttrs::attr_from_type(t)),
8051 );
8052 }
8053 if cur > offset || cur + self.buf.len() < offset {
8054 return (stack, None);
8055 }
8056 let mut attrs = self.clone();
8057 let mut last_off = cur + attrs.pos;
8058 while let Some(attr) = attrs.next() {
8059 let Ok(attr) = attr else { break };
8060 match attr {
8061 BondSlaveAttrs::State(val) => {
8062 if last_off == offset {
8063 stack.push(("State", last_off));
8064 break;
8065 }
8066 }
8067 BondSlaveAttrs::MiiStatus(val) => {
8068 if last_off == offset {
8069 stack.push(("MiiStatus", last_off));
8070 break;
8071 }
8072 }
8073 BondSlaveAttrs::LinkFailureCount(val) => {
8074 if last_off == offset {
8075 stack.push(("LinkFailureCount", last_off));
8076 break;
8077 }
8078 }
8079 BondSlaveAttrs::PermHwaddr(val) => {
8080 if last_off == offset {
8081 stack.push(("PermHwaddr", last_off));
8082 break;
8083 }
8084 }
8085 BondSlaveAttrs::QueueId(val) => {
8086 if last_off == offset {
8087 stack.push(("QueueId", last_off));
8088 break;
8089 }
8090 }
8091 BondSlaveAttrs::AdAggregatorId(val) => {
8092 if last_off == offset {
8093 stack.push(("AdAggregatorId", last_off));
8094 break;
8095 }
8096 }
8097 BondSlaveAttrs::AdActorOperPortState(val) => {
8098 if last_off == offset {
8099 stack.push(("AdActorOperPortState", last_off));
8100 break;
8101 }
8102 }
8103 BondSlaveAttrs::AdPartnerOperPortState(val) => {
8104 if last_off == offset {
8105 stack.push(("AdPartnerOperPortState", last_off));
8106 break;
8107 }
8108 }
8109 BondSlaveAttrs::Prio(val) => {
8110 if last_off == offset {
8111 stack.push(("Prio", last_off));
8112 break;
8113 }
8114 }
8115 _ => {}
8116 };
8117 last_off = cur + attrs.pos;
8118 }
8119 if !stack.is_empty() {
8120 stack.push(("BondSlaveAttrs", cur));
8121 }
8122 (stack, None)
8123 }
8124}
8125#[derive(Clone)]
8126pub enum LinkinfoBridgeAttrs<'a> {
8127 ForwardDelay(u32),
8128 HelloTime(u32),
8129 MaxAge(u32),
8130 AgeingTime(u32),
8131 StpState(u32),
8132 Priority(u16),
8133 VlanFiltering(u8),
8134 VlanProtocol(u16),
8135 GroupFwdMask(u16),
8136 RootId(IflaBridgeId),
8137 BridgeId(IflaBridgeId),
8138 RootPort(u16),
8139 RootPathCost(u32),
8140 TopologyChange(u8),
8141 TopologyChangeDetected(u8),
8142 HelloTimer(u64),
8143 TcnTimer(u64),
8144 TopologyChangeTimer(u64),
8145 GcTimer(u64),
8146 GroupAddr(&'a [u8]),
8147 FdbFlush(&'a [u8]),
8148 McastRouter(u8),
8149 McastSnooping(u8),
8150 McastQueryUseIfaddr(u8),
8151 McastQuerier(u8),
8152 McastHashElasticity(u32),
8153 McastHashMax(u32),
8154 McastLastMemberCnt(u32),
8155 McastStartupQueryCnt(u32),
8156 McastLastMemberIntvl(u64),
8157 McastMembershipIntvl(u64),
8158 McastQuerierIntvl(u64),
8159 McastQueryIntvl(u64),
8160 McastQueryResponseIntvl(u64),
8161 McastStartupQueryIntvl(u64),
8162 NfCallIptables(u8),
8163 NfCallIp6tables(u8),
8164 NfCallArptables(u8),
8165 VlanDefaultPvid(u16),
8166 Pad(&'a [u8]),
8167 VlanStatsEnabled(u8),
8168 McastStatsEnabled(u8),
8169 McastIgmpVersion(u8),
8170 McastMldVersion(u8),
8171 VlanStatsPerPort(u8),
8172 MultiBoolopt(BrBooloptMulti),
8173 McastQuerierState(&'a [u8]),
8174 FdbNLearned(u32),
8175 FdbMaxLearned(u32),
8176 #[doc = "Associated type: [`BrStpMode`] (enum)"]
8177 StpMode(u32),
8178}
8179impl<'a> IterableLinkinfoBridgeAttrs<'a> {
8180 pub fn get_forward_delay(&self) -> Result<u32, ErrorContext> {
8181 let mut iter = self.clone();
8182 iter.pos = 0;
8183 for attr in iter {
8184 if let Ok(LinkinfoBridgeAttrs::ForwardDelay(val)) = attr {
8185 return Ok(val);
8186 }
8187 }
8188 Err(ErrorContext::new_missing(
8189 "LinkinfoBridgeAttrs",
8190 "ForwardDelay",
8191 self.orig_loc,
8192 self.buf.as_ptr() as usize,
8193 ))
8194 }
8195 pub fn get_hello_time(&self) -> Result<u32, ErrorContext> {
8196 let mut iter = self.clone();
8197 iter.pos = 0;
8198 for attr in iter {
8199 if let Ok(LinkinfoBridgeAttrs::HelloTime(val)) = attr {
8200 return Ok(val);
8201 }
8202 }
8203 Err(ErrorContext::new_missing(
8204 "LinkinfoBridgeAttrs",
8205 "HelloTime",
8206 self.orig_loc,
8207 self.buf.as_ptr() as usize,
8208 ))
8209 }
8210 pub fn get_max_age(&self) -> Result<u32, ErrorContext> {
8211 let mut iter = self.clone();
8212 iter.pos = 0;
8213 for attr in iter {
8214 if let Ok(LinkinfoBridgeAttrs::MaxAge(val)) = attr {
8215 return Ok(val);
8216 }
8217 }
8218 Err(ErrorContext::new_missing(
8219 "LinkinfoBridgeAttrs",
8220 "MaxAge",
8221 self.orig_loc,
8222 self.buf.as_ptr() as usize,
8223 ))
8224 }
8225 pub fn get_ageing_time(&self) -> Result<u32, ErrorContext> {
8226 let mut iter = self.clone();
8227 iter.pos = 0;
8228 for attr in iter {
8229 if let Ok(LinkinfoBridgeAttrs::AgeingTime(val)) = attr {
8230 return Ok(val);
8231 }
8232 }
8233 Err(ErrorContext::new_missing(
8234 "LinkinfoBridgeAttrs",
8235 "AgeingTime",
8236 self.orig_loc,
8237 self.buf.as_ptr() as usize,
8238 ))
8239 }
8240 pub fn get_stp_state(&self) -> Result<u32, ErrorContext> {
8241 let mut iter = self.clone();
8242 iter.pos = 0;
8243 for attr in iter {
8244 if let Ok(LinkinfoBridgeAttrs::StpState(val)) = attr {
8245 return Ok(val);
8246 }
8247 }
8248 Err(ErrorContext::new_missing(
8249 "LinkinfoBridgeAttrs",
8250 "StpState",
8251 self.orig_loc,
8252 self.buf.as_ptr() as usize,
8253 ))
8254 }
8255 pub fn get_priority(&self) -> Result<u16, ErrorContext> {
8256 let mut iter = self.clone();
8257 iter.pos = 0;
8258 for attr in iter {
8259 if let Ok(LinkinfoBridgeAttrs::Priority(val)) = attr {
8260 return Ok(val);
8261 }
8262 }
8263 Err(ErrorContext::new_missing(
8264 "LinkinfoBridgeAttrs",
8265 "Priority",
8266 self.orig_loc,
8267 self.buf.as_ptr() as usize,
8268 ))
8269 }
8270 pub fn get_vlan_filtering(&self) -> Result<u8, ErrorContext> {
8271 let mut iter = self.clone();
8272 iter.pos = 0;
8273 for attr in iter {
8274 if let Ok(LinkinfoBridgeAttrs::VlanFiltering(val)) = attr {
8275 return Ok(val);
8276 }
8277 }
8278 Err(ErrorContext::new_missing(
8279 "LinkinfoBridgeAttrs",
8280 "VlanFiltering",
8281 self.orig_loc,
8282 self.buf.as_ptr() as usize,
8283 ))
8284 }
8285 pub fn get_vlan_protocol(&self) -> Result<u16, ErrorContext> {
8286 let mut iter = self.clone();
8287 iter.pos = 0;
8288 for attr in iter {
8289 if let Ok(LinkinfoBridgeAttrs::VlanProtocol(val)) = attr {
8290 return Ok(val);
8291 }
8292 }
8293 Err(ErrorContext::new_missing(
8294 "LinkinfoBridgeAttrs",
8295 "VlanProtocol",
8296 self.orig_loc,
8297 self.buf.as_ptr() as usize,
8298 ))
8299 }
8300 pub fn get_group_fwd_mask(&self) -> Result<u16, ErrorContext> {
8301 let mut iter = self.clone();
8302 iter.pos = 0;
8303 for attr in iter {
8304 if let Ok(LinkinfoBridgeAttrs::GroupFwdMask(val)) = attr {
8305 return Ok(val);
8306 }
8307 }
8308 Err(ErrorContext::new_missing(
8309 "LinkinfoBridgeAttrs",
8310 "GroupFwdMask",
8311 self.orig_loc,
8312 self.buf.as_ptr() as usize,
8313 ))
8314 }
8315 pub fn get_root_id(&self) -> Result<IflaBridgeId, ErrorContext> {
8316 let mut iter = self.clone();
8317 iter.pos = 0;
8318 for attr in iter {
8319 if let Ok(LinkinfoBridgeAttrs::RootId(val)) = attr {
8320 return Ok(val);
8321 }
8322 }
8323 Err(ErrorContext::new_missing(
8324 "LinkinfoBridgeAttrs",
8325 "RootId",
8326 self.orig_loc,
8327 self.buf.as_ptr() as usize,
8328 ))
8329 }
8330 pub fn get_bridge_id(&self) -> Result<IflaBridgeId, ErrorContext> {
8331 let mut iter = self.clone();
8332 iter.pos = 0;
8333 for attr in iter {
8334 if let Ok(LinkinfoBridgeAttrs::BridgeId(val)) = attr {
8335 return Ok(val);
8336 }
8337 }
8338 Err(ErrorContext::new_missing(
8339 "LinkinfoBridgeAttrs",
8340 "BridgeId",
8341 self.orig_loc,
8342 self.buf.as_ptr() as usize,
8343 ))
8344 }
8345 pub fn get_root_port(&self) -> Result<u16, ErrorContext> {
8346 let mut iter = self.clone();
8347 iter.pos = 0;
8348 for attr in iter {
8349 if let Ok(LinkinfoBridgeAttrs::RootPort(val)) = attr {
8350 return Ok(val);
8351 }
8352 }
8353 Err(ErrorContext::new_missing(
8354 "LinkinfoBridgeAttrs",
8355 "RootPort",
8356 self.orig_loc,
8357 self.buf.as_ptr() as usize,
8358 ))
8359 }
8360 pub fn get_root_path_cost(&self) -> Result<u32, ErrorContext> {
8361 let mut iter = self.clone();
8362 iter.pos = 0;
8363 for attr in iter {
8364 if let Ok(LinkinfoBridgeAttrs::RootPathCost(val)) = attr {
8365 return Ok(val);
8366 }
8367 }
8368 Err(ErrorContext::new_missing(
8369 "LinkinfoBridgeAttrs",
8370 "RootPathCost",
8371 self.orig_loc,
8372 self.buf.as_ptr() as usize,
8373 ))
8374 }
8375 pub fn get_topology_change(&self) -> Result<u8, ErrorContext> {
8376 let mut iter = self.clone();
8377 iter.pos = 0;
8378 for attr in iter {
8379 if let Ok(LinkinfoBridgeAttrs::TopologyChange(val)) = attr {
8380 return Ok(val);
8381 }
8382 }
8383 Err(ErrorContext::new_missing(
8384 "LinkinfoBridgeAttrs",
8385 "TopologyChange",
8386 self.orig_loc,
8387 self.buf.as_ptr() as usize,
8388 ))
8389 }
8390 pub fn get_topology_change_detected(&self) -> Result<u8, ErrorContext> {
8391 let mut iter = self.clone();
8392 iter.pos = 0;
8393 for attr in iter {
8394 if let Ok(LinkinfoBridgeAttrs::TopologyChangeDetected(val)) = attr {
8395 return Ok(val);
8396 }
8397 }
8398 Err(ErrorContext::new_missing(
8399 "LinkinfoBridgeAttrs",
8400 "TopologyChangeDetected",
8401 self.orig_loc,
8402 self.buf.as_ptr() as usize,
8403 ))
8404 }
8405 pub fn get_hello_timer(&self) -> Result<u64, ErrorContext> {
8406 let mut iter = self.clone();
8407 iter.pos = 0;
8408 for attr in iter {
8409 if let Ok(LinkinfoBridgeAttrs::HelloTimer(val)) = attr {
8410 return Ok(val);
8411 }
8412 }
8413 Err(ErrorContext::new_missing(
8414 "LinkinfoBridgeAttrs",
8415 "HelloTimer",
8416 self.orig_loc,
8417 self.buf.as_ptr() as usize,
8418 ))
8419 }
8420 pub fn get_tcn_timer(&self) -> Result<u64, ErrorContext> {
8421 let mut iter = self.clone();
8422 iter.pos = 0;
8423 for attr in iter {
8424 if let Ok(LinkinfoBridgeAttrs::TcnTimer(val)) = attr {
8425 return Ok(val);
8426 }
8427 }
8428 Err(ErrorContext::new_missing(
8429 "LinkinfoBridgeAttrs",
8430 "TcnTimer",
8431 self.orig_loc,
8432 self.buf.as_ptr() as usize,
8433 ))
8434 }
8435 pub fn get_topology_change_timer(&self) -> Result<u64, ErrorContext> {
8436 let mut iter = self.clone();
8437 iter.pos = 0;
8438 for attr in iter {
8439 if let Ok(LinkinfoBridgeAttrs::TopologyChangeTimer(val)) = attr {
8440 return Ok(val);
8441 }
8442 }
8443 Err(ErrorContext::new_missing(
8444 "LinkinfoBridgeAttrs",
8445 "TopologyChangeTimer",
8446 self.orig_loc,
8447 self.buf.as_ptr() as usize,
8448 ))
8449 }
8450 pub fn get_gc_timer(&self) -> Result<u64, ErrorContext> {
8451 let mut iter = self.clone();
8452 iter.pos = 0;
8453 for attr in iter {
8454 if let Ok(LinkinfoBridgeAttrs::GcTimer(val)) = attr {
8455 return Ok(val);
8456 }
8457 }
8458 Err(ErrorContext::new_missing(
8459 "LinkinfoBridgeAttrs",
8460 "GcTimer",
8461 self.orig_loc,
8462 self.buf.as_ptr() as usize,
8463 ))
8464 }
8465 pub fn get_group_addr(&self) -> Result<&'a [u8], ErrorContext> {
8466 let mut iter = self.clone();
8467 iter.pos = 0;
8468 for attr in iter {
8469 if let Ok(LinkinfoBridgeAttrs::GroupAddr(val)) = attr {
8470 return Ok(val);
8471 }
8472 }
8473 Err(ErrorContext::new_missing(
8474 "LinkinfoBridgeAttrs",
8475 "GroupAddr",
8476 self.orig_loc,
8477 self.buf.as_ptr() as usize,
8478 ))
8479 }
8480 pub fn get_fdb_flush(&self) -> Result<&'a [u8], ErrorContext> {
8481 let mut iter = self.clone();
8482 iter.pos = 0;
8483 for attr in iter {
8484 if let Ok(LinkinfoBridgeAttrs::FdbFlush(val)) = attr {
8485 return Ok(val);
8486 }
8487 }
8488 Err(ErrorContext::new_missing(
8489 "LinkinfoBridgeAttrs",
8490 "FdbFlush",
8491 self.orig_loc,
8492 self.buf.as_ptr() as usize,
8493 ))
8494 }
8495 pub fn get_mcast_router(&self) -> Result<u8, ErrorContext> {
8496 let mut iter = self.clone();
8497 iter.pos = 0;
8498 for attr in iter {
8499 if let Ok(LinkinfoBridgeAttrs::McastRouter(val)) = attr {
8500 return Ok(val);
8501 }
8502 }
8503 Err(ErrorContext::new_missing(
8504 "LinkinfoBridgeAttrs",
8505 "McastRouter",
8506 self.orig_loc,
8507 self.buf.as_ptr() as usize,
8508 ))
8509 }
8510 pub fn get_mcast_snooping(&self) -> Result<u8, ErrorContext> {
8511 let mut iter = self.clone();
8512 iter.pos = 0;
8513 for attr in iter {
8514 if let Ok(LinkinfoBridgeAttrs::McastSnooping(val)) = attr {
8515 return Ok(val);
8516 }
8517 }
8518 Err(ErrorContext::new_missing(
8519 "LinkinfoBridgeAttrs",
8520 "McastSnooping",
8521 self.orig_loc,
8522 self.buf.as_ptr() as usize,
8523 ))
8524 }
8525 pub fn get_mcast_query_use_ifaddr(&self) -> Result<u8, ErrorContext> {
8526 let mut iter = self.clone();
8527 iter.pos = 0;
8528 for attr in iter {
8529 if let Ok(LinkinfoBridgeAttrs::McastQueryUseIfaddr(val)) = attr {
8530 return Ok(val);
8531 }
8532 }
8533 Err(ErrorContext::new_missing(
8534 "LinkinfoBridgeAttrs",
8535 "McastQueryUseIfaddr",
8536 self.orig_loc,
8537 self.buf.as_ptr() as usize,
8538 ))
8539 }
8540 pub fn get_mcast_querier(&self) -> Result<u8, ErrorContext> {
8541 let mut iter = self.clone();
8542 iter.pos = 0;
8543 for attr in iter {
8544 if let Ok(LinkinfoBridgeAttrs::McastQuerier(val)) = attr {
8545 return Ok(val);
8546 }
8547 }
8548 Err(ErrorContext::new_missing(
8549 "LinkinfoBridgeAttrs",
8550 "McastQuerier",
8551 self.orig_loc,
8552 self.buf.as_ptr() as usize,
8553 ))
8554 }
8555 pub fn get_mcast_hash_elasticity(&self) -> Result<u32, ErrorContext> {
8556 let mut iter = self.clone();
8557 iter.pos = 0;
8558 for attr in iter {
8559 if let Ok(LinkinfoBridgeAttrs::McastHashElasticity(val)) = attr {
8560 return Ok(val);
8561 }
8562 }
8563 Err(ErrorContext::new_missing(
8564 "LinkinfoBridgeAttrs",
8565 "McastHashElasticity",
8566 self.orig_loc,
8567 self.buf.as_ptr() as usize,
8568 ))
8569 }
8570 pub fn get_mcast_hash_max(&self) -> Result<u32, ErrorContext> {
8571 let mut iter = self.clone();
8572 iter.pos = 0;
8573 for attr in iter {
8574 if let Ok(LinkinfoBridgeAttrs::McastHashMax(val)) = attr {
8575 return Ok(val);
8576 }
8577 }
8578 Err(ErrorContext::new_missing(
8579 "LinkinfoBridgeAttrs",
8580 "McastHashMax",
8581 self.orig_loc,
8582 self.buf.as_ptr() as usize,
8583 ))
8584 }
8585 pub fn get_mcast_last_member_cnt(&self) -> Result<u32, ErrorContext> {
8586 let mut iter = self.clone();
8587 iter.pos = 0;
8588 for attr in iter {
8589 if let Ok(LinkinfoBridgeAttrs::McastLastMemberCnt(val)) = attr {
8590 return Ok(val);
8591 }
8592 }
8593 Err(ErrorContext::new_missing(
8594 "LinkinfoBridgeAttrs",
8595 "McastLastMemberCnt",
8596 self.orig_loc,
8597 self.buf.as_ptr() as usize,
8598 ))
8599 }
8600 pub fn get_mcast_startup_query_cnt(&self) -> Result<u32, ErrorContext> {
8601 let mut iter = self.clone();
8602 iter.pos = 0;
8603 for attr in iter {
8604 if let Ok(LinkinfoBridgeAttrs::McastStartupQueryCnt(val)) = attr {
8605 return Ok(val);
8606 }
8607 }
8608 Err(ErrorContext::new_missing(
8609 "LinkinfoBridgeAttrs",
8610 "McastStartupQueryCnt",
8611 self.orig_loc,
8612 self.buf.as_ptr() as usize,
8613 ))
8614 }
8615 pub fn get_mcast_last_member_intvl(&self) -> Result<u64, ErrorContext> {
8616 let mut iter = self.clone();
8617 iter.pos = 0;
8618 for attr in iter {
8619 if let Ok(LinkinfoBridgeAttrs::McastLastMemberIntvl(val)) = attr {
8620 return Ok(val);
8621 }
8622 }
8623 Err(ErrorContext::new_missing(
8624 "LinkinfoBridgeAttrs",
8625 "McastLastMemberIntvl",
8626 self.orig_loc,
8627 self.buf.as_ptr() as usize,
8628 ))
8629 }
8630 pub fn get_mcast_membership_intvl(&self) -> Result<u64, ErrorContext> {
8631 let mut iter = self.clone();
8632 iter.pos = 0;
8633 for attr in iter {
8634 if let Ok(LinkinfoBridgeAttrs::McastMembershipIntvl(val)) = attr {
8635 return Ok(val);
8636 }
8637 }
8638 Err(ErrorContext::new_missing(
8639 "LinkinfoBridgeAttrs",
8640 "McastMembershipIntvl",
8641 self.orig_loc,
8642 self.buf.as_ptr() as usize,
8643 ))
8644 }
8645 pub fn get_mcast_querier_intvl(&self) -> Result<u64, ErrorContext> {
8646 let mut iter = self.clone();
8647 iter.pos = 0;
8648 for attr in iter {
8649 if let Ok(LinkinfoBridgeAttrs::McastQuerierIntvl(val)) = attr {
8650 return Ok(val);
8651 }
8652 }
8653 Err(ErrorContext::new_missing(
8654 "LinkinfoBridgeAttrs",
8655 "McastQuerierIntvl",
8656 self.orig_loc,
8657 self.buf.as_ptr() as usize,
8658 ))
8659 }
8660 pub fn get_mcast_query_intvl(&self) -> Result<u64, ErrorContext> {
8661 let mut iter = self.clone();
8662 iter.pos = 0;
8663 for attr in iter {
8664 if let Ok(LinkinfoBridgeAttrs::McastQueryIntvl(val)) = attr {
8665 return Ok(val);
8666 }
8667 }
8668 Err(ErrorContext::new_missing(
8669 "LinkinfoBridgeAttrs",
8670 "McastQueryIntvl",
8671 self.orig_loc,
8672 self.buf.as_ptr() as usize,
8673 ))
8674 }
8675 pub fn get_mcast_query_response_intvl(&self) -> Result<u64, ErrorContext> {
8676 let mut iter = self.clone();
8677 iter.pos = 0;
8678 for attr in iter {
8679 if let Ok(LinkinfoBridgeAttrs::McastQueryResponseIntvl(val)) = attr {
8680 return Ok(val);
8681 }
8682 }
8683 Err(ErrorContext::new_missing(
8684 "LinkinfoBridgeAttrs",
8685 "McastQueryResponseIntvl",
8686 self.orig_loc,
8687 self.buf.as_ptr() as usize,
8688 ))
8689 }
8690 pub fn get_mcast_startup_query_intvl(&self) -> Result<u64, ErrorContext> {
8691 let mut iter = self.clone();
8692 iter.pos = 0;
8693 for attr in iter {
8694 if let Ok(LinkinfoBridgeAttrs::McastStartupQueryIntvl(val)) = attr {
8695 return Ok(val);
8696 }
8697 }
8698 Err(ErrorContext::new_missing(
8699 "LinkinfoBridgeAttrs",
8700 "McastStartupQueryIntvl",
8701 self.orig_loc,
8702 self.buf.as_ptr() as usize,
8703 ))
8704 }
8705 pub fn get_nf_call_iptables(&self) -> Result<u8, ErrorContext> {
8706 let mut iter = self.clone();
8707 iter.pos = 0;
8708 for attr in iter {
8709 if let Ok(LinkinfoBridgeAttrs::NfCallIptables(val)) = attr {
8710 return Ok(val);
8711 }
8712 }
8713 Err(ErrorContext::new_missing(
8714 "LinkinfoBridgeAttrs",
8715 "NfCallIptables",
8716 self.orig_loc,
8717 self.buf.as_ptr() as usize,
8718 ))
8719 }
8720 pub fn get_nf_call_ip6tables(&self) -> Result<u8, ErrorContext> {
8721 let mut iter = self.clone();
8722 iter.pos = 0;
8723 for attr in iter {
8724 if let Ok(LinkinfoBridgeAttrs::NfCallIp6tables(val)) = attr {
8725 return Ok(val);
8726 }
8727 }
8728 Err(ErrorContext::new_missing(
8729 "LinkinfoBridgeAttrs",
8730 "NfCallIp6tables",
8731 self.orig_loc,
8732 self.buf.as_ptr() as usize,
8733 ))
8734 }
8735 pub fn get_nf_call_arptables(&self) -> Result<u8, ErrorContext> {
8736 let mut iter = self.clone();
8737 iter.pos = 0;
8738 for attr in iter {
8739 if let Ok(LinkinfoBridgeAttrs::NfCallArptables(val)) = attr {
8740 return Ok(val);
8741 }
8742 }
8743 Err(ErrorContext::new_missing(
8744 "LinkinfoBridgeAttrs",
8745 "NfCallArptables",
8746 self.orig_loc,
8747 self.buf.as_ptr() as usize,
8748 ))
8749 }
8750 pub fn get_vlan_default_pvid(&self) -> Result<u16, ErrorContext> {
8751 let mut iter = self.clone();
8752 iter.pos = 0;
8753 for attr in iter {
8754 if let Ok(LinkinfoBridgeAttrs::VlanDefaultPvid(val)) = attr {
8755 return Ok(val);
8756 }
8757 }
8758 Err(ErrorContext::new_missing(
8759 "LinkinfoBridgeAttrs",
8760 "VlanDefaultPvid",
8761 self.orig_loc,
8762 self.buf.as_ptr() as usize,
8763 ))
8764 }
8765 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
8766 let mut iter = self.clone();
8767 iter.pos = 0;
8768 for attr in iter {
8769 if let Ok(LinkinfoBridgeAttrs::Pad(val)) = attr {
8770 return Ok(val);
8771 }
8772 }
8773 Err(ErrorContext::new_missing(
8774 "LinkinfoBridgeAttrs",
8775 "Pad",
8776 self.orig_loc,
8777 self.buf.as_ptr() as usize,
8778 ))
8779 }
8780 pub fn get_vlan_stats_enabled(&self) -> Result<u8, ErrorContext> {
8781 let mut iter = self.clone();
8782 iter.pos = 0;
8783 for attr in iter {
8784 if let Ok(LinkinfoBridgeAttrs::VlanStatsEnabled(val)) = attr {
8785 return Ok(val);
8786 }
8787 }
8788 Err(ErrorContext::new_missing(
8789 "LinkinfoBridgeAttrs",
8790 "VlanStatsEnabled",
8791 self.orig_loc,
8792 self.buf.as_ptr() as usize,
8793 ))
8794 }
8795 pub fn get_mcast_stats_enabled(&self) -> Result<u8, ErrorContext> {
8796 let mut iter = self.clone();
8797 iter.pos = 0;
8798 for attr in iter {
8799 if let Ok(LinkinfoBridgeAttrs::McastStatsEnabled(val)) = attr {
8800 return Ok(val);
8801 }
8802 }
8803 Err(ErrorContext::new_missing(
8804 "LinkinfoBridgeAttrs",
8805 "McastStatsEnabled",
8806 self.orig_loc,
8807 self.buf.as_ptr() as usize,
8808 ))
8809 }
8810 pub fn get_mcast_igmp_version(&self) -> Result<u8, ErrorContext> {
8811 let mut iter = self.clone();
8812 iter.pos = 0;
8813 for attr in iter {
8814 if let Ok(LinkinfoBridgeAttrs::McastIgmpVersion(val)) = attr {
8815 return Ok(val);
8816 }
8817 }
8818 Err(ErrorContext::new_missing(
8819 "LinkinfoBridgeAttrs",
8820 "McastIgmpVersion",
8821 self.orig_loc,
8822 self.buf.as_ptr() as usize,
8823 ))
8824 }
8825 pub fn get_mcast_mld_version(&self) -> Result<u8, ErrorContext> {
8826 let mut iter = self.clone();
8827 iter.pos = 0;
8828 for attr in iter {
8829 if let Ok(LinkinfoBridgeAttrs::McastMldVersion(val)) = attr {
8830 return Ok(val);
8831 }
8832 }
8833 Err(ErrorContext::new_missing(
8834 "LinkinfoBridgeAttrs",
8835 "McastMldVersion",
8836 self.orig_loc,
8837 self.buf.as_ptr() as usize,
8838 ))
8839 }
8840 pub fn get_vlan_stats_per_port(&self) -> Result<u8, ErrorContext> {
8841 let mut iter = self.clone();
8842 iter.pos = 0;
8843 for attr in iter {
8844 if let Ok(LinkinfoBridgeAttrs::VlanStatsPerPort(val)) = attr {
8845 return Ok(val);
8846 }
8847 }
8848 Err(ErrorContext::new_missing(
8849 "LinkinfoBridgeAttrs",
8850 "VlanStatsPerPort",
8851 self.orig_loc,
8852 self.buf.as_ptr() as usize,
8853 ))
8854 }
8855 pub fn get_multi_boolopt(&self) -> Result<BrBooloptMulti, ErrorContext> {
8856 let mut iter = self.clone();
8857 iter.pos = 0;
8858 for attr in iter {
8859 if let Ok(LinkinfoBridgeAttrs::MultiBoolopt(val)) = attr {
8860 return Ok(val);
8861 }
8862 }
8863 Err(ErrorContext::new_missing(
8864 "LinkinfoBridgeAttrs",
8865 "MultiBoolopt",
8866 self.orig_loc,
8867 self.buf.as_ptr() as usize,
8868 ))
8869 }
8870 pub fn get_mcast_querier_state(&self) -> Result<&'a [u8], ErrorContext> {
8871 let mut iter = self.clone();
8872 iter.pos = 0;
8873 for attr in iter {
8874 if let Ok(LinkinfoBridgeAttrs::McastQuerierState(val)) = attr {
8875 return Ok(val);
8876 }
8877 }
8878 Err(ErrorContext::new_missing(
8879 "LinkinfoBridgeAttrs",
8880 "McastQuerierState",
8881 self.orig_loc,
8882 self.buf.as_ptr() as usize,
8883 ))
8884 }
8885 pub fn get_fdb_n_learned(&self) -> Result<u32, ErrorContext> {
8886 let mut iter = self.clone();
8887 iter.pos = 0;
8888 for attr in iter {
8889 if let Ok(LinkinfoBridgeAttrs::FdbNLearned(val)) = attr {
8890 return Ok(val);
8891 }
8892 }
8893 Err(ErrorContext::new_missing(
8894 "LinkinfoBridgeAttrs",
8895 "FdbNLearned",
8896 self.orig_loc,
8897 self.buf.as_ptr() as usize,
8898 ))
8899 }
8900 pub fn get_fdb_max_learned(&self) -> Result<u32, ErrorContext> {
8901 let mut iter = self.clone();
8902 iter.pos = 0;
8903 for attr in iter {
8904 if let Ok(LinkinfoBridgeAttrs::FdbMaxLearned(val)) = attr {
8905 return Ok(val);
8906 }
8907 }
8908 Err(ErrorContext::new_missing(
8909 "LinkinfoBridgeAttrs",
8910 "FdbMaxLearned",
8911 self.orig_loc,
8912 self.buf.as_ptr() as usize,
8913 ))
8914 }
8915 #[doc = "Associated type: [`BrStpMode`] (enum)"]
8916 pub fn get_stp_mode(&self) -> Result<u32, ErrorContext> {
8917 let mut iter = self.clone();
8918 iter.pos = 0;
8919 for attr in iter {
8920 if let Ok(LinkinfoBridgeAttrs::StpMode(val)) = attr {
8921 return Ok(val);
8922 }
8923 }
8924 Err(ErrorContext::new_missing(
8925 "LinkinfoBridgeAttrs",
8926 "StpMode",
8927 self.orig_loc,
8928 self.buf.as_ptr() as usize,
8929 ))
8930 }
8931}
8932impl LinkinfoBridgeAttrs<'_> {
8933 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoBridgeAttrs<'a> {
8934 IterableLinkinfoBridgeAttrs::with_loc(buf, buf.as_ptr() as usize)
8935 }
8936 fn attr_from_type(r#type: u16) -> Option<&'static str> {
8937 let res = match r#type {
8938 1u16 => "ForwardDelay",
8939 2u16 => "HelloTime",
8940 3u16 => "MaxAge",
8941 4u16 => "AgeingTime",
8942 5u16 => "StpState",
8943 6u16 => "Priority",
8944 7u16 => "VlanFiltering",
8945 8u16 => "VlanProtocol",
8946 9u16 => "GroupFwdMask",
8947 10u16 => "RootId",
8948 11u16 => "BridgeId",
8949 12u16 => "RootPort",
8950 13u16 => "RootPathCost",
8951 14u16 => "TopologyChange",
8952 15u16 => "TopologyChangeDetected",
8953 16u16 => "HelloTimer",
8954 17u16 => "TcnTimer",
8955 18u16 => "TopologyChangeTimer",
8956 19u16 => "GcTimer",
8957 20u16 => "GroupAddr",
8958 21u16 => "FdbFlush",
8959 22u16 => "McastRouter",
8960 23u16 => "McastSnooping",
8961 24u16 => "McastQueryUseIfaddr",
8962 25u16 => "McastQuerier",
8963 26u16 => "McastHashElasticity",
8964 27u16 => "McastHashMax",
8965 28u16 => "McastLastMemberCnt",
8966 29u16 => "McastStartupQueryCnt",
8967 30u16 => "McastLastMemberIntvl",
8968 31u16 => "McastMembershipIntvl",
8969 32u16 => "McastQuerierIntvl",
8970 33u16 => "McastQueryIntvl",
8971 34u16 => "McastQueryResponseIntvl",
8972 35u16 => "McastStartupQueryIntvl",
8973 36u16 => "NfCallIptables",
8974 37u16 => "NfCallIp6tables",
8975 38u16 => "NfCallArptables",
8976 39u16 => "VlanDefaultPvid",
8977 40u16 => "Pad",
8978 41u16 => "VlanStatsEnabled",
8979 42u16 => "McastStatsEnabled",
8980 43u16 => "McastIgmpVersion",
8981 44u16 => "McastMldVersion",
8982 45u16 => "VlanStatsPerPort",
8983 46u16 => "MultiBoolopt",
8984 47u16 => "McastQuerierState",
8985 48u16 => "FdbNLearned",
8986 49u16 => "FdbMaxLearned",
8987 50u16 => "StpMode",
8988 _ => return None,
8989 };
8990 Some(res)
8991 }
8992}
8993#[derive(Clone, Copy, Default)]
8994pub struct IterableLinkinfoBridgeAttrs<'a> {
8995 buf: &'a [u8],
8996 pos: usize,
8997 orig_loc: usize,
8998}
8999impl<'a> IterableLinkinfoBridgeAttrs<'a> {
9000 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
9001 Self {
9002 buf,
9003 pos: 0,
9004 orig_loc,
9005 }
9006 }
9007 pub fn get_buf(&self) -> &'a [u8] {
9008 self.buf
9009 }
9010}
9011impl<'a> Iterator for IterableLinkinfoBridgeAttrs<'a> {
9012 type Item = Result<LinkinfoBridgeAttrs<'a>, ErrorContext>;
9013 fn next(&mut self) -> Option<Self::Item> {
9014 let mut pos;
9015 let mut r#type;
9016 loop {
9017 pos = self.pos;
9018 r#type = None;
9019 if self.buf.len() == self.pos {
9020 return None;
9021 }
9022 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
9023 self.pos = self.buf.len();
9024 break;
9025 };
9026 r#type = Some(header.r#type);
9027 let res = match header.r#type {
9028 1u16 => LinkinfoBridgeAttrs::ForwardDelay({
9029 let res = parse_u32(next);
9030 let Some(val) = res else { break };
9031 val
9032 }),
9033 2u16 => LinkinfoBridgeAttrs::HelloTime({
9034 let res = parse_u32(next);
9035 let Some(val) = res else { break };
9036 val
9037 }),
9038 3u16 => LinkinfoBridgeAttrs::MaxAge({
9039 let res = parse_u32(next);
9040 let Some(val) = res else { break };
9041 val
9042 }),
9043 4u16 => LinkinfoBridgeAttrs::AgeingTime({
9044 let res = parse_u32(next);
9045 let Some(val) = res else { break };
9046 val
9047 }),
9048 5u16 => LinkinfoBridgeAttrs::StpState({
9049 let res = parse_u32(next);
9050 let Some(val) = res else { break };
9051 val
9052 }),
9053 6u16 => LinkinfoBridgeAttrs::Priority({
9054 let res = parse_u16(next);
9055 let Some(val) = res else { break };
9056 val
9057 }),
9058 7u16 => LinkinfoBridgeAttrs::VlanFiltering({
9059 let res = parse_u8(next);
9060 let Some(val) = res else { break };
9061 val
9062 }),
9063 8u16 => LinkinfoBridgeAttrs::VlanProtocol({
9064 let res = parse_u16(next);
9065 let Some(val) = res else { break };
9066 val
9067 }),
9068 9u16 => LinkinfoBridgeAttrs::GroupFwdMask({
9069 let res = parse_u16(next);
9070 let Some(val) = res else { break };
9071 val
9072 }),
9073 10u16 => LinkinfoBridgeAttrs::RootId({
9074 let res = Some(IflaBridgeId::new_from_zeroed(next));
9075 let Some(val) = res else { break };
9076 val
9077 }),
9078 11u16 => LinkinfoBridgeAttrs::BridgeId({
9079 let res = Some(IflaBridgeId::new_from_zeroed(next));
9080 let Some(val) = res else { break };
9081 val
9082 }),
9083 12u16 => LinkinfoBridgeAttrs::RootPort({
9084 let res = parse_u16(next);
9085 let Some(val) = res else { break };
9086 val
9087 }),
9088 13u16 => LinkinfoBridgeAttrs::RootPathCost({
9089 let res = parse_u32(next);
9090 let Some(val) = res else { break };
9091 val
9092 }),
9093 14u16 => LinkinfoBridgeAttrs::TopologyChange({
9094 let res = parse_u8(next);
9095 let Some(val) = res else { break };
9096 val
9097 }),
9098 15u16 => LinkinfoBridgeAttrs::TopologyChangeDetected({
9099 let res = parse_u8(next);
9100 let Some(val) = res else { break };
9101 val
9102 }),
9103 16u16 => LinkinfoBridgeAttrs::HelloTimer({
9104 let res = parse_u64(next);
9105 let Some(val) = res else { break };
9106 val
9107 }),
9108 17u16 => LinkinfoBridgeAttrs::TcnTimer({
9109 let res = parse_u64(next);
9110 let Some(val) = res else { break };
9111 val
9112 }),
9113 18u16 => LinkinfoBridgeAttrs::TopologyChangeTimer({
9114 let res = parse_u64(next);
9115 let Some(val) = res else { break };
9116 val
9117 }),
9118 19u16 => LinkinfoBridgeAttrs::GcTimer({
9119 let res = parse_u64(next);
9120 let Some(val) = res else { break };
9121 val
9122 }),
9123 20u16 => LinkinfoBridgeAttrs::GroupAddr({
9124 let res = Some(next);
9125 let Some(val) = res else { break };
9126 val
9127 }),
9128 21u16 => LinkinfoBridgeAttrs::FdbFlush({
9129 let res = Some(next);
9130 let Some(val) = res else { break };
9131 val
9132 }),
9133 22u16 => LinkinfoBridgeAttrs::McastRouter({
9134 let res = parse_u8(next);
9135 let Some(val) = res else { break };
9136 val
9137 }),
9138 23u16 => LinkinfoBridgeAttrs::McastSnooping({
9139 let res = parse_u8(next);
9140 let Some(val) = res else { break };
9141 val
9142 }),
9143 24u16 => LinkinfoBridgeAttrs::McastQueryUseIfaddr({
9144 let res = parse_u8(next);
9145 let Some(val) = res else { break };
9146 val
9147 }),
9148 25u16 => LinkinfoBridgeAttrs::McastQuerier({
9149 let res = parse_u8(next);
9150 let Some(val) = res else { break };
9151 val
9152 }),
9153 26u16 => LinkinfoBridgeAttrs::McastHashElasticity({
9154 let res = parse_u32(next);
9155 let Some(val) = res else { break };
9156 val
9157 }),
9158 27u16 => LinkinfoBridgeAttrs::McastHashMax({
9159 let res = parse_u32(next);
9160 let Some(val) = res else { break };
9161 val
9162 }),
9163 28u16 => LinkinfoBridgeAttrs::McastLastMemberCnt({
9164 let res = parse_u32(next);
9165 let Some(val) = res else { break };
9166 val
9167 }),
9168 29u16 => LinkinfoBridgeAttrs::McastStartupQueryCnt({
9169 let res = parse_u32(next);
9170 let Some(val) = res else { break };
9171 val
9172 }),
9173 30u16 => LinkinfoBridgeAttrs::McastLastMemberIntvl({
9174 let res = parse_u64(next);
9175 let Some(val) = res else { break };
9176 val
9177 }),
9178 31u16 => LinkinfoBridgeAttrs::McastMembershipIntvl({
9179 let res = parse_u64(next);
9180 let Some(val) = res else { break };
9181 val
9182 }),
9183 32u16 => LinkinfoBridgeAttrs::McastQuerierIntvl({
9184 let res = parse_u64(next);
9185 let Some(val) = res else { break };
9186 val
9187 }),
9188 33u16 => LinkinfoBridgeAttrs::McastQueryIntvl({
9189 let res = parse_u64(next);
9190 let Some(val) = res else { break };
9191 val
9192 }),
9193 34u16 => LinkinfoBridgeAttrs::McastQueryResponseIntvl({
9194 let res = parse_u64(next);
9195 let Some(val) = res else { break };
9196 val
9197 }),
9198 35u16 => LinkinfoBridgeAttrs::McastStartupQueryIntvl({
9199 let res = parse_u64(next);
9200 let Some(val) = res else { break };
9201 val
9202 }),
9203 36u16 => LinkinfoBridgeAttrs::NfCallIptables({
9204 let res = parse_u8(next);
9205 let Some(val) = res else { break };
9206 val
9207 }),
9208 37u16 => LinkinfoBridgeAttrs::NfCallIp6tables({
9209 let res = parse_u8(next);
9210 let Some(val) = res else { break };
9211 val
9212 }),
9213 38u16 => LinkinfoBridgeAttrs::NfCallArptables({
9214 let res = parse_u8(next);
9215 let Some(val) = res else { break };
9216 val
9217 }),
9218 39u16 => LinkinfoBridgeAttrs::VlanDefaultPvid({
9219 let res = parse_u16(next);
9220 let Some(val) = res else { break };
9221 val
9222 }),
9223 40u16 => LinkinfoBridgeAttrs::Pad({
9224 let res = Some(next);
9225 let Some(val) = res else { break };
9226 val
9227 }),
9228 41u16 => LinkinfoBridgeAttrs::VlanStatsEnabled({
9229 let res = parse_u8(next);
9230 let Some(val) = res else { break };
9231 val
9232 }),
9233 42u16 => LinkinfoBridgeAttrs::McastStatsEnabled({
9234 let res = parse_u8(next);
9235 let Some(val) = res else { break };
9236 val
9237 }),
9238 43u16 => LinkinfoBridgeAttrs::McastIgmpVersion({
9239 let res = parse_u8(next);
9240 let Some(val) = res else { break };
9241 val
9242 }),
9243 44u16 => LinkinfoBridgeAttrs::McastMldVersion({
9244 let res = parse_u8(next);
9245 let Some(val) = res else { break };
9246 val
9247 }),
9248 45u16 => LinkinfoBridgeAttrs::VlanStatsPerPort({
9249 let res = parse_u8(next);
9250 let Some(val) = res else { break };
9251 val
9252 }),
9253 46u16 => LinkinfoBridgeAttrs::MultiBoolopt({
9254 let res = Some(BrBooloptMulti::new_from_zeroed(next));
9255 let Some(val) = res else { break };
9256 val
9257 }),
9258 47u16 => LinkinfoBridgeAttrs::McastQuerierState({
9259 let res = Some(next);
9260 let Some(val) = res else { break };
9261 val
9262 }),
9263 48u16 => LinkinfoBridgeAttrs::FdbNLearned({
9264 let res = parse_u32(next);
9265 let Some(val) = res else { break };
9266 val
9267 }),
9268 49u16 => LinkinfoBridgeAttrs::FdbMaxLearned({
9269 let res = parse_u32(next);
9270 let Some(val) = res else { break };
9271 val
9272 }),
9273 50u16 => LinkinfoBridgeAttrs::StpMode({
9274 let res = parse_u32(next);
9275 let Some(val) = res else { break };
9276 val
9277 }),
9278 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
9279 n => continue,
9280 };
9281 return Some(Ok(res));
9282 }
9283 Some(Err(ErrorContext::new(
9284 "LinkinfoBridgeAttrs",
9285 r#type.and_then(|t| LinkinfoBridgeAttrs::attr_from_type(t)),
9286 self.orig_loc,
9287 self.buf.as_ptr().wrapping_add(pos) as usize,
9288 )))
9289 }
9290}
9291impl<'a> std::fmt::Debug for IterableLinkinfoBridgeAttrs<'_> {
9292 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9293 let mut fmt = f.debug_struct("LinkinfoBridgeAttrs");
9294 for attr in self.clone() {
9295 let attr = match attr {
9296 Ok(a) => a,
9297 Err(err) => {
9298 fmt.finish()?;
9299 f.write_str("Err(")?;
9300 err.fmt(f)?;
9301 return f.write_str(")");
9302 }
9303 };
9304 match attr {
9305 LinkinfoBridgeAttrs::ForwardDelay(val) => fmt.field("ForwardDelay", &val),
9306 LinkinfoBridgeAttrs::HelloTime(val) => fmt.field("HelloTime", &val),
9307 LinkinfoBridgeAttrs::MaxAge(val) => fmt.field("MaxAge", &val),
9308 LinkinfoBridgeAttrs::AgeingTime(val) => fmt.field("AgeingTime", &val),
9309 LinkinfoBridgeAttrs::StpState(val) => fmt.field("StpState", &val),
9310 LinkinfoBridgeAttrs::Priority(val) => fmt.field("Priority", &val),
9311 LinkinfoBridgeAttrs::VlanFiltering(val) => fmt.field("VlanFiltering", &val),
9312 LinkinfoBridgeAttrs::VlanProtocol(val) => fmt.field("VlanProtocol", &val),
9313 LinkinfoBridgeAttrs::GroupFwdMask(val) => fmt.field("GroupFwdMask", &val),
9314 LinkinfoBridgeAttrs::RootId(val) => fmt.field("RootId", &val),
9315 LinkinfoBridgeAttrs::BridgeId(val) => fmt.field("BridgeId", &val),
9316 LinkinfoBridgeAttrs::RootPort(val) => fmt.field("RootPort", &val),
9317 LinkinfoBridgeAttrs::RootPathCost(val) => fmt.field("RootPathCost", &val),
9318 LinkinfoBridgeAttrs::TopologyChange(val) => fmt.field("TopologyChange", &val),
9319 LinkinfoBridgeAttrs::TopologyChangeDetected(val) => {
9320 fmt.field("TopologyChangeDetected", &val)
9321 }
9322 LinkinfoBridgeAttrs::HelloTimer(val) => fmt.field("HelloTimer", &val),
9323 LinkinfoBridgeAttrs::TcnTimer(val) => fmt.field("TcnTimer", &val),
9324 LinkinfoBridgeAttrs::TopologyChangeTimer(val) => {
9325 fmt.field("TopologyChangeTimer", &val)
9326 }
9327 LinkinfoBridgeAttrs::GcTimer(val) => fmt.field("GcTimer", &val),
9328 LinkinfoBridgeAttrs::GroupAddr(val) => fmt.field("GroupAddr", &FormatMac(val)),
9329 LinkinfoBridgeAttrs::FdbFlush(val) => fmt.field("FdbFlush", &val),
9330 LinkinfoBridgeAttrs::McastRouter(val) => fmt.field("McastRouter", &val),
9331 LinkinfoBridgeAttrs::McastSnooping(val) => fmt.field("McastSnooping", &val),
9332 LinkinfoBridgeAttrs::McastQueryUseIfaddr(val) => {
9333 fmt.field("McastQueryUseIfaddr", &val)
9334 }
9335 LinkinfoBridgeAttrs::McastQuerier(val) => fmt.field("McastQuerier", &val),
9336 LinkinfoBridgeAttrs::McastHashElasticity(val) => {
9337 fmt.field("McastHashElasticity", &val)
9338 }
9339 LinkinfoBridgeAttrs::McastHashMax(val) => fmt.field("McastHashMax", &val),
9340 LinkinfoBridgeAttrs::McastLastMemberCnt(val) => {
9341 fmt.field("McastLastMemberCnt", &val)
9342 }
9343 LinkinfoBridgeAttrs::McastStartupQueryCnt(val) => {
9344 fmt.field("McastStartupQueryCnt", &val)
9345 }
9346 LinkinfoBridgeAttrs::McastLastMemberIntvl(val) => {
9347 fmt.field("McastLastMemberIntvl", &val)
9348 }
9349 LinkinfoBridgeAttrs::McastMembershipIntvl(val) => {
9350 fmt.field("McastMembershipIntvl", &val)
9351 }
9352 LinkinfoBridgeAttrs::McastQuerierIntvl(val) => fmt.field("McastQuerierIntvl", &val),
9353 LinkinfoBridgeAttrs::McastQueryIntvl(val) => fmt.field("McastQueryIntvl", &val),
9354 LinkinfoBridgeAttrs::McastQueryResponseIntvl(val) => {
9355 fmt.field("McastQueryResponseIntvl", &val)
9356 }
9357 LinkinfoBridgeAttrs::McastStartupQueryIntvl(val) => {
9358 fmt.field("McastStartupQueryIntvl", &val)
9359 }
9360 LinkinfoBridgeAttrs::NfCallIptables(val) => fmt.field("NfCallIptables", &val),
9361 LinkinfoBridgeAttrs::NfCallIp6tables(val) => fmt.field("NfCallIp6tables", &val),
9362 LinkinfoBridgeAttrs::NfCallArptables(val) => fmt.field("NfCallArptables", &val),
9363 LinkinfoBridgeAttrs::VlanDefaultPvid(val) => fmt.field("VlanDefaultPvid", &val),
9364 LinkinfoBridgeAttrs::Pad(val) => fmt.field("Pad", &val),
9365 LinkinfoBridgeAttrs::VlanStatsEnabled(val) => fmt.field("VlanStatsEnabled", &val),
9366 LinkinfoBridgeAttrs::McastStatsEnabled(val) => fmt.field("McastStatsEnabled", &val),
9367 LinkinfoBridgeAttrs::McastIgmpVersion(val) => fmt.field("McastIgmpVersion", &val),
9368 LinkinfoBridgeAttrs::McastMldVersion(val) => fmt.field("McastMldVersion", &val),
9369 LinkinfoBridgeAttrs::VlanStatsPerPort(val) => fmt.field("VlanStatsPerPort", &val),
9370 LinkinfoBridgeAttrs::MultiBoolopt(val) => fmt.field("MultiBoolopt", &val),
9371 LinkinfoBridgeAttrs::McastQuerierState(val) => fmt.field("McastQuerierState", &val),
9372 LinkinfoBridgeAttrs::FdbNLearned(val) => fmt.field("FdbNLearned", &val),
9373 LinkinfoBridgeAttrs::FdbMaxLearned(val) => fmt.field("FdbMaxLearned", &val),
9374 LinkinfoBridgeAttrs::StpMode(val) => {
9375 fmt.field("StpMode", &FormatEnum(val.into(), BrStpMode::from_value))
9376 }
9377 };
9378 }
9379 fmt.finish()
9380 }
9381}
9382impl IterableLinkinfoBridgeAttrs<'_> {
9383 pub fn lookup_attr(
9384 &self,
9385 offset: usize,
9386 missing_type: Option<u16>,
9387 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
9388 let mut stack = Vec::new();
9389 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
9390 if missing_type.is_some() && cur == offset {
9391 stack.push(("LinkinfoBridgeAttrs", offset));
9392 return (
9393 stack,
9394 missing_type.and_then(|t| LinkinfoBridgeAttrs::attr_from_type(t)),
9395 );
9396 }
9397 if cur > offset || cur + self.buf.len() < offset {
9398 return (stack, None);
9399 }
9400 let mut attrs = self.clone();
9401 let mut last_off = cur + attrs.pos;
9402 while let Some(attr) = attrs.next() {
9403 let Ok(attr) = attr else { break };
9404 match attr {
9405 LinkinfoBridgeAttrs::ForwardDelay(val) => {
9406 if last_off == offset {
9407 stack.push(("ForwardDelay", last_off));
9408 break;
9409 }
9410 }
9411 LinkinfoBridgeAttrs::HelloTime(val) => {
9412 if last_off == offset {
9413 stack.push(("HelloTime", last_off));
9414 break;
9415 }
9416 }
9417 LinkinfoBridgeAttrs::MaxAge(val) => {
9418 if last_off == offset {
9419 stack.push(("MaxAge", last_off));
9420 break;
9421 }
9422 }
9423 LinkinfoBridgeAttrs::AgeingTime(val) => {
9424 if last_off == offset {
9425 stack.push(("AgeingTime", last_off));
9426 break;
9427 }
9428 }
9429 LinkinfoBridgeAttrs::StpState(val) => {
9430 if last_off == offset {
9431 stack.push(("StpState", last_off));
9432 break;
9433 }
9434 }
9435 LinkinfoBridgeAttrs::Priority(val) => {
9436 if last_off == offset {
9437 stack.push(("Priority", last_off));
9438 break;
9439 }
9440 }
9441 LinkinfoBridgeAttrs::VlanFiltering(val) => {
9442 if last_off == offset {
9443 stack.push(("VlanFiltering", last_off));
9444 break;
9445 }
9446 }
9447 LinkinfoBridgeAttrs::VlanProtocol(val) => {
9448 if last_off == offset {
9449 stack.push(("VlanProtocol", last_off));
9450 break;
9451 }
9452 }
9453 LinkinfoBridgeAttrs::GroupFwdMask(val) => {
9454 if last_off == offset {
9455 stack.push(("GroupFwdMask", last_off));
9456 break;
9457 }
9458 }
9459 LinkinfoBridgeAttrs::RootId(val) => {
9460 if last_off == offset {
9461 stack.push(("RootId", last_off));
9462 break;
9463 }
9464 }
9465 LinkinfoBridgeAttrs::BridgeId(val) => {
9466 if last_off == offset {
9467 stack.push(("BridgeId", last_off));
9468 break;
9469 }
9470 }
9471 LinkinfoBridgeAttrs::RootPort(val) => {
9472 if last_off == offset {
9473 stack.push(("RootPort", last_off));
9474 break;
9475 }
9476 }
9477 LinkinfoBridgeAttrs::RootPathCost(val) => {
9478 if last_off == offset {
9479 stack.push(("RootPathCost", last_off));
9480 break;
9481 }
9482 }
9483 LinkinfoBridgeAttrs::TopologyChange(val) => {
9484 if last_off == offset {
9485 stack.push(("TopologyChange", last_off));
9486 break;
9487 }
9488 }
9489 LinkinfoBridgeAttrs::TopologyChangeDetected(val) => {
9490 if last_off == offset {
9491 stack.push(("TopologyChangeDetected", last_off));
9492 break;
9493 }
9494 }
9495 LinkinfoBridgeAttrs::HelloTimer(val) => {
9496 if last_off == offset {
9497 stack.push(("HelloTimer", last_off));
9498 break;
9499 }
9500 }
9501 LinkinfoBridgeAttrs::TcnTimer(val) => {
9502 if last_off == offset {
9503 stack.push(("TcnTimer", last_off));
9504 break;
9505 }
9506 }
9507 LinkinfoBridgeAttrs::TopologyChangeTimer(val) => {
9508 if last_off == offset {
9509 stack.push(("TopologyChangeTimer", last_off));
9510 break;
9511 }
9512 }
9513 LinkinfoBridgeAttrs::GcTimer(val) => {
9514 if last_off == offset {
9515 stack.push(("GcTimer", last_off));
9516 break;
9517 }
9518 }
9519 LinkinfoBridgeAttrs::GroupAddr(val) => {
9520 if last_off == offset {
9521 stack.push(("GroupAddr", last_off));
9522 break;
9523 }
9524 }
9525 LinkinfoBridgeAttrs::FdbFlush(val) => {
9526 if last_off == offset {
9527 stack.push(("FdbFlush", last_off));
9528 break;
9529 }
9530 }
9531 LinkinfoBridgeAttrs::McastRouter(val) => {
9532 if last_off == offset {
9533 stack.push(("McastRouter", last_off));
9534 break;
9535 }
9536 }
9537 LinkinfoBridgeAttrs::McastSnooping(val) => {
9538 if last_off == offset {
9539 stack.push(("McastSnooping", last_off));
9540 break;
9541 }
9542 }
9543 LinkinfoBridgeAttrs::McastQueryUseIfaddr(val) => {
9544 if last_off == offset {
9545 stack.push(("McastQueryUseIfaddr", last_off));
9546 break;
9547 }
9548 }
9549 LinkinfoBridgeAttrs::McastQuerier(val) => {
9550 if last_off == offset {
9551 stack.push(("McastQuerier", last_off));
9552 break;
9553 }
9554 }
9555 LinkinfoBridgeAttrs::McastHashElasticity(val) => {
9556 if last_off == offset {
9557 stack.push(("McastHashElasticity", last_off));
9558 break;
9559 }
9560 }
9561 LinkinfoBridgeAttrs::McastHashMax(val) => {
9562 if last_off == offset {
9563 stack.push(("McastHashMax", last_off));
9564 break;
9565 }
9566 }
9567 LinkinfoBridgeAttrs::McastLastMemberCnt(val) => {
9568 if last_off == offset {
9569 stack.push(("McastLastMemberCnt", last_off));
9570 break;
9571 }
9572 }
9573 LinkinfoBridgeAttrs::McastStartupQueryCnt(val) => {
9574 if last_off == offset {
9575 stack.push(("McastStartupQueryCnt", last_off));
9576 break;
9577 }
9578 }
9579 LinkinfoBridgeAttrs::McastLastMemberIntvl(val) => {
9580 if last_off == offset {
9581 stack.push(("McastLastMemberIntvl", last_off));
9582 break;
9583 }
9584 }
9585 LinkinfoBridgeAttrs::McastMembershipIntvl(val) => {
9586 if last_off == offset {
9587 stack.push(("McastMembershipIntvl", last_off));
9588 break;
9589 }
9590 }
9591 LinkinfoBridgeAttrs::McastQuerierIntvl(val) => {
9592 if last_off == offset {
9593 stack.push(("McastQuerierIntvl", last_off));
9594 break;
9595 }
9596 }
9597 LinkinfoBridgeAttrs::McastQueryIntvl(val) => {
9598 if last_off == offset {
9599 stack.push(("McastQueryIntvl", last_off));
9600 break;
9601 }
9602 }
9603 LinkinfoBridgeAttrs::McastQueryResponseIntvl(val) => {
9604 if last_off == offset {
9605 stack.push(("McastQueryResponseIntvl", last_off));
9606 break;
9607 }
9608 }
9609 LinkinfoBridgeAttrs::McastStartupQueryIntvl(val) => {
9610 if last_off == offset {
9611 stack.push(("McastStartupQueryIntvl", last_off));
9612 break;
9613 }
9614 }
9615 LinkinfoBridgeAttrs::NfCallIptables(val) => {
9616 if last_off == offset {
9617 stack.push(("NfCallIptables", last_off));
9618 break;
9619 }
9620 }
9621 LinkinfoBridgeAttrs::NfCallIp6tables(val) => {
9622 if last_off == offset {
9623 stack.push(("NfCallIp6tables", last_off));
9624 break;
9625 }
9626 }
9627 LinkinfoBridgeAttrs::NfCallArptables(val) => {
9628 if last_off == offset {
9629 stack.push(("NfCallArptables", last_off));
9630 break;
9631 }
9632 }
9633 LinkinfoBridgeAttrs::VlanDefaultPvid(val) => {
9634 if last_off == offset {
9635 stack.push(("VlanDefaultPvid", last_off));
9636 break;
9637 }
9638 }
9639 LinkinfoBridgeAttrs::Pad(val) => {
9640 if last_off == offset {
9641 stack.push(("Pad", last_off));
9642 break;
9643 }
9644 }
9645 LinkinfoBridgeAttrs::VlanStatsEnabled(val) => {
9646 if last_off == offset {
9647 stack.push(("VlanStatsEnabled", last_off));
9648 break;
9649 }
9650 }
9651 LinkinfoBridgeAttrs::McastStatsEnabled(val) => {
9652 if last_off == offset {
9653 stack.push(("McastStatsEnabled", last_off));
9654 break;
9655 }
9656 }
9657 LinkinfoBridgeAttrs::McastIgmpVersion(val) => {
9658 if last_off == offset {
9659 stack.push(("McastIgmpVersion", last_off));
9660 break;
9661 }
9662 }
9663 LinkinfoBridgeAttrs::McastMldVersion(val) => {
9664 if last_off == offset {
9665 stack.push(("McastMldVersion", last_off));
9666 break;
9667 }
9668 }
9669 LinkinfoBridgeAttrs::VlanStatsPerPort(val) => {
9670 if last_off == offset {
9671 stack.push(("VlanStatsPerPort", last_off));
9672 break;
9673 }
9674 }
9675 LinkinfoBridgeAttrs::MultiBoolopt(val) => {
9676 if last_off == offset {
9677 stack.push(("MultiBoolopt", last_off));
9678 break;
9679 }
9680 }
9681 LinkinfoBridgeAttrs::McastQuerierState(val) => {
9682 if last_off == offset {
9683 stack.push(("McastQuerierState", last_off));
9684 break;
9685 }
9686 }
9687 LinkinfoBridgeAttrs::FdbNLearned(val) => {
9688 if last_off == offset {
9689 stack.push(("FdbNLearned", last_off));
9690 break;
9691 }
9692 }
9693 LinkinfoBridgeAttrs::FdbMaxLearned(val) => {
9694 if last_off == offset {
9695 stack.push(("FdbMaxLearned", last_off));
9696 break;
9697 }
9698 }
9699 LinkinfoBridgeAttrs::StpMode(val) => {
9700 if last_off == offset {
9701 stack.push(("StpMode", last_off));
9702 break;
9703 }
9704 }
9705 _ => {}
9706 };
9707 last_off = cur + attrs.pos;
9708 }
9709 if !stack.is_empty() {
9710 stack.push(("LinkinfoBridgeAttrs", cur));
9711 }
9712 (stack, None)
9713 }
9714}
9715#[derive(Clone)]
9716pub enum LinkinfoBrportAttrs<'a> {
9717 State(u8),
9718 Priority(u16),
9719 Cost(u32),
9720 Mode(()),
9721 Guard(()),
9722 Protect(()),
9723 FastLeave(()),
9724 Learning(()),
9725 UnicastFlood(()),
9726 Proxyarp(()),
9727 LearningSync(()),
9728 ProxyarpWifi(()),
9729 RootId(IflaBridgeId),
9730 BridgeId(IflaBridgeId),
9731 DesignatedPort(u16),
9732 DesignatedCost(u16),
9733 Id(u16),
9734 No(u16),
9735 TopologyChangeAck(u8),
9736 ConfigPending(u8),
9737 MessageAgeTimer(u64),
9738 ForwardDelayTimer(u64),
9739 HoldTimer(u64),
9740 Flush(()),
9741 MulticastRouter(u8),
9742 Pad(&'a [u8]),
9743 McastFlood(()),
9744 McastToUcast(()),
9745 VlanTunnel(()),
9746 BcastFlood(()),
9747 GroupFwdMask(u16),
9748 NeighSuppress(()),
9749 Isolated(()),
9750 BackupPort(u32),
9751 MrpRingOpen(()),
9752 MrpInOpen(()),
9753 McastEhtHostsLimit(u32),
9754 McastEhtHostsCnt(u32),
9755 Locked(()),
9756 Mab(()),
9757 McastNGroups(u32),
9758 McastMaxGroups(u32),
9759 NeighVlanSuppress(()),
9760 BackupNhid(u32),
9761 NeighForwardGrat(u8),
9762}
9763impl<'a> IterableLinkinfoBrportAttrs<'a> {
9764 pub fn get_state(&self) -> Result<u8, ErrorContext> {
9765 let mut iter = self.clone();
9766 iter.pos = 0;
9767 for attr in iter {
9768 if let Ok(LinkinfoBrportAttrs::State(val)) = attr {
9769 return Ok(val);
9770 }
9771 }
9772 Err(ErrorContext::new_missing(
9773 "LinkinfoBrportAttrs",
9774 "State",
9775 self.orig_loc,
9776 self.buf.as_ptr() as usize,
9777 ))
9778 }
9779 pub fn get_priority(&self) -> Result<u16, ErrorContext> {
9780 let mut iter = self.clone();
9781 iter.pos = 0;
9782 for attr in iter {
9783 if let Ok(LinkinfoBrportAttrs::Priority(val)) = attr {
9784 return Ok(val);
9785 }
9786 }
9787 Err(ErrorContext::new_missing(
9788 "LinkinfoBrportAttrs",
9789 "Priority",
9790 self.orig_loc,
9791 self.buf.as_ptr() as usize,
9792 ))
9793 }
9794 pub fn get_cost(&self) -> Result<u32, ErrorContext> {
9795 let mut iter = self.clone();
9796 iter.pos = 0;
9797 for attr in iter {
9798 if let Ok(LinkinfoBrportAttrs::Cost(val)) = attr {
9799 return Ok(val);
9800 }
9801 }
9802 Err(ErrorContext::new_missing(
9803 "LinkinfoBrportAttrs",
9804 "Cost",
9805 self.orig_loc,
9806 self.buf.as_ptr() as usize,
9807 ))
9808 }
9809 pub fn get_mode(&self) -> Result<(), ErrorContext> {
9810 let mut iter = self.clone();
9811 iter.pos = 0;
9812 for attr in iter {
9813 if let Ok(LinkinfoBrportAttrs::Mode(val)) = attr {
9814 return Ok(val);
9815 }
9816 }
9817 Err(ErrorContext::new_missing(
9818 "LinkinfoBrportAttrs",
9819 "Mode",
9820 self.orig_loc,
9821 self.buf.as_ptr() as usize,
9822 ))
9823 }
9824 pub fn get_guard(&self) -> Result<(), ErrorContext> {
9825 let mut iter = self.clone();
9826 iter.pos = 0;
9827 for attr in iter {
9828 if let Ok(LinkinfoBrportAttrs::Guard(val)) = attr {
9829 return Ok(val);
9830 }
9831 }
9832 Err(ErrorContext::new_missing(
9833 "LinkinfoBrportAttrs",
9834 "Guard",
9835 self.orig_loc,
9836 self.buf.as_ptr() as usize,
9837 ))
9838 }
9839 pub fn get_protect(&self) -> Result<(), ErrorContext> {
9840 let mut iter = self.clone();
9841 iter.pos = 0;
9842 for attr in iter {
9843 if let Ok(LinkinfoBrportAttrs::Protect(val)) = attr {
9844 return Ok(val);
9845 }
9846 }
9847 Err(ErrorContext::new_missing(
9848 "LinkinfoBrportAttrs",
9849 "Protect",
9850 self.orig_loc,
9851 self.buf.as_ptr() as usize,
9852 ))
9853 }
9854 pub fn get_fast_leave(&self) -> Result<(), ErrorContext> {
9855 let mut iter = self.clone();
9856 iter.pos = 0;
9857 for attr in iter {
9858 if let Ok(LinkinfoBrportAttrs::FastLeave(val)) = attr {
9859 return Ok(val);
9860 }
9861 }
9862 Err(ErrorContext::new_missing(
9863 "LinkinfoBrportAttrs",
9864 "FastLeave",
9865 self.orig_loc,
9866 self.buf.as_ptr() as usize,
9867 ))
9868 }
9869 pub fn get_learning(&self) -> Result<(), ErrorContext> {
9870 let mut iter = self.clone();
9871 iter.pos = 0;
9872 for attr in iter {
9873 if let Ok(LinkinfoBrportAttrs::Learning(val)) = attr {
9874 return Ok(val);
9875 }
9876 }
9877 Err(ErrorContext::new_missing(
9878 "LinkinfoBrportAttrs",
9879 "Learning",
9880 self.orig_loc,
9881 self.buf.as_ptr() as usize,
9882 ))
9883 }
9884 pub fn get_unicast_flood(&self) -> Result<(), ErrorContext> {
9885 let mut iter = self.clone();
9886 iter.pos = 0;
9887 for attr in iter {
9888 if let Ok(LinkinfoBrportAttrs::UnicastFlood(val)) = attr {
9889 return Ok(val);
9890 }
9891 }
9892 Err(ErrorContext::new_missing(
9893 "LinkinfoBrportAttrs",
9894 "UnicastFlood",
9895 self.orig_loc,
9896 self.buf.as_ptr() as usize,
9897 ))
9898 }
9899 pub fn get_proxyarp(&self) -> Result<(), ErrorContext> {
9900 let mut iter = self.clone();
9901 iter.pos = 0;
9902 for attr in iter {
9903 if let Ok(LinkinfoBrportAttrs::Proxyarp(val)) = attr {
9904 return Ok(val);
9905 }
9906 }
9907 Err(ErrorContext::new_missing(
9908 "LinkinfoBrportAttrs",
9909 "Proxyarp",
9910 self.orig_loc,
9911 self.buf.as_ptr() as usize,
9912 ))
9913 }
9914 pub fn get_learning_sync(&self) -> Result<(), ErrorContext> {
9915 let mut iter = self.clone();
9916 iter.pos = 0;
9917 for attr in iter {
9918 if let Ok(LinkinfoBrportAttrs::LearningSync(val)) = attr {
9919 return Ok(val);
9920 }
9921 }
9922 Err(ErrorContext::new_missing(
9923 "LinkinfoBrportAttrs",
9924 "LearningSync",
9925 self.orig_loc,
9926 self.buf.as_ptr() as usize,
9927 ))
9928 }
9929 pub fn get_proxyarp_wifi(&self) -> Result<(), ErrorContext> {
9930 let mut iter = self.clone();
9931 iter.pos = 0;
9932 for attr in iter {
9933 if let Ok(LinkinfoBrportAttrs::ProxyarpWifi(val)) = attr {
9934 return Ok(val);
9935 }
9936 }
9937 Err(ErrorContext::new_missing(
9938 "LinkinfoBrportAttrs",
9939 "ProxyarpWifi",
9940 self.orig_loc,
9941 self.buf.as_ptr() as usize,
9942 ))
9943 }
9944 pub fn get_root_id(&self) -> Result<IflaBridgeId, ErrorContext> {
9945 let mut iter = self.clone();
9946 iter.pos = 0;
9947 for attr in iter {
9948 if let Ok(LinkinfoBrportAttrs::RootId(val)) = attr {
9949 return Ok(val);
9950 }
9951 }
9952 Err(ErrorContext::new_missing(
9953 "LinkinfoBrportAttrs",
9954 "RootId",
9955 self.orig_loc,
9956 self.buf.as_ptr() as usize,
9957 ))
9958 }
9959 pub fn get_bridge_id(&self) -> Result<IflaBridgeId, ErrorContext> {
9960 let mut iter = self.clone();
9961 iter.pos = 0;
9962 for attr in iter {
9963 if let Ok(LinkinfoBrportAttrs::BridgeId(val)) = attr {
9964 return Ok(val);
9965 }
9966 }
9967 Err(ErrorContext::new_missing(
9968 "LinkinfoBrportAttrs",
9969 "BridgeId",
9970 self.orig_loc,
9971 self.buf.as_ptr() as usize,
9972 ))
9973 }
9974 pub fn get_designated_port(&self) -> Result<u16, ErrorContext> {
9975 let mut iter = self.clone();
9976 iter.pos = 0;
9977 for attr in iter {
9978 if let Ok(LinkinfoBrportAttrs::DesignatedPort(val)) = attr {
9979 return Ok(val);
9980 }
9981 }
9982 Err(ErrorContext::new_missing(
9983 "LinkinfoBrportAttrs",
9984 "DesignatedPort",
9985 self.orig_loc,
9986 self.buf.as_ptr() as usize,
9987 ))
9988 }
9989 pub fn get_designated_cost(&self) -> Result<u16, ErrorContext> {
9990 let mut iter = self.clone();
9991 iter.pos = 0;
9992 for attr in iter {
9993 if let Ok(LinkinfoBrportAttrs::DesignatedCost(val)) = attr {
9994 return Ok(val);
9995 }
9996 }
9997 Err(ErrorContext::new_missing(
9998 "LinkinfoBrportAttrs",
9999 "DesignatedCost",
10000 self.orig_loc,
10001 self.buf.as_ptr() as usize,
10002 ))
10003 }
10004 pub fn get_id(&self) -> Result<u16, ErrorContext> {
10005 let mut iter = self.clone();
10006 iter.pos = 0;
10007 for attr in iter {
10008 if let Ok(LinkinfoBrportAttrs::Id(val)) = attr {
10009 return Ok(val);
10010 }
10011 }
10012 Err(ErrorContext::new_missing(
10013 "LinkinfoBrportAttrs",
10014 "Id",
10015 self.orig_loc,
10016 self.buf.as_ptr() as usize,
10017 ))
10018 }
10019 pub fn get_no(&self) -> Result<u16, ErrorContext> {
10020 let mut iter = self.clone();
10021 iter.pos = 0;
10022 for attr in iter {
10023 if let Ok(LinkinfoBrportAttrs::No(val)) = attr {
10024 return Ok(val);
10025 }
10026 }
10027 Err(ErrorContext::new_missing(
10028 "LinkinfoBrportAttrs",
10029 "No",
10030 self.orig_loc,
10031 self.buf.as_ptr() as usize,
10032 ))
10033 }
10034 pub fn get_topology_change_ack(&self) -> Result<u8, ErrorContext> {
10035 let mut iter = self.clone();
10036 iter.pos = 0;
10037 for attr in iter {
10038 if let Ok(LinkinfoBrportAttrs::TopologyChangeAck(val)) = attr {
10039 return Ok(val);
10040 }
10041 }
10042 Err(ErrorContext::new_missing(
10043 "LinkinfoBrportAttrs",
10044 "TopologyChangeAck",
10045 self.orig_loc,
10046 self.buf.as_ptr() as usize,
10047 ))
10048 }
10049 pub fn get_config_pending(&self) -> Result<u8, ErrorContext> {
10050 let mut iter = self.clone();
10051 iter.pos = 0;
10052 for attr in iter {
10053 if let Ok(LinkinfoBrportAttrs::ConfigPending(val)) = attr {
10054 return Ok(val);
10055 }
10056 }
10057 Err(ErrorContext::new_missing(
10058 "LinkinfoBrportAttrs",
10059 "ConfigPending",
10060 self.orig_loc,
10061 self.buf.as_ptr() as usize,
10062 ))
10063 }
10064 pub fn get_message_age_timer(&self) -> Result<u64, ErrorContext> {
10065 let mut iter = self.clone();
10066 iter.pos = 0;
10067 for attr in iter {
10068 if let Ok(LinkinfoBrportAttrs::MessageAgeTimer(val)) = attr {
10069 return Ok(val);
10070 }
10071 }
10072 Err(ErrorContext::new_missing(
10073 "LinkinfoBrportAttrs",
10074 "MessageAgeTimer",
10075 self.orig_loc,
10076 self.buf.as_ptr() as usize,
10077 ))
10078 }
10079 pub fn get_forward_delay_timer(&self) -> Result<u64, ErrorContext> {
10080 let mut iter = self.clone();
10081 iter.pos = 0;
10082 for attr in iter {
10083 if let Ok(LinkinfoBrportAttrs::ForwardDelayTimer(val)) = attr {
10084 return Ok(val);
10085 }
10086 }
10087 Err(ErrorContext::new_missing(
10088 "LinkinfoBrportAttrs",
10089 "ForwardDelayTimer",
10090 self.orig_loc,
10091 self.buf.as_ptr() as usize,
10092 ))
10093 }
10094 pub fn get_hold_timer(&self) -> Result<u64, ErrorContext> {
10095 let mut iter = self.clone();
10096 iter.pos = 0;
10097 for attr in iter {
10098 if let Ok(LinkinfoBrportAttrs::HoldTimer(val)) = attr {
10099 return Ok(val);
10100 }
10101 }
10102 Err(ErrorContext::new_missing(
10103 "LinkinfoBrportAttrs",
10104 "HoldTimer",
10105 self.orig_loc,
10106 self.buf.as_ptr() as usize,
10107 ))
10108 }
10109 pub fn get_flush(&self) -> Result<(), ErrorContext> {
10110 let mut iter = self.clone();
10111 iter.pos = 0;
10112 for attr in iter {
10113 if let Ok(LinkinfoBrportAttrs::Flush(val)) = attr {
10114 return Ok(val);
10115 }
10116 }
10117 Err(ErrorContext::new_missing(
10118 "LinkinfoBrportAttrs",
10119 "Flush",
10120 self.orig_loc,
10121 self.buf.as_ptr() as usize,
10122 ))
10123 }
10124 pub fn get_multicast_router(&self) -> Result<u8, ErrorContext> {
10125 let mut iter = self.clone();
10126 iter.pos = 0;
10127 for attr in iter {
10128 if let Ok(LinkinfoBrportAttrs::MulticastRouter(val)) = attr {
10129 return Ok(val);
10130 }
10131 }
10132 Err(ErrorContext::new_missing(
10133 "LinkinfoBrportAttrs",
10134 "MulticastRouter",
10135 self.orig_loc,
10136 self.buf.as_ptr() as usize,
10137 ))
10138 }
10139 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
10140 let mut iter = self.clone();
10141 iter.pos = 0;
10142 for attr in iter {
10143 if let Ok(LinkinfoBrportAttrs::Pad(val)) = attr {
10144 return Ok(val);
10145 }
10146 }
10147 Err(ErrorContext::new_missing(
10148 "LinkinfoBrportAttrs",
10149 "Pad",
10150 self.orig_loc,
10151 self.buf.as_ptr() as usize,
10152 ))
10153 }
10154 pub fn get_mcast_flood(&self) -> Result<(), ErrorContext> {
10155 let mut iter = self.clone();
10156 iter.pos = 0;
10157 for attr in iter {
10158 if let Ok(LinkinfoBrportAttrs::McastFlood(val)) = attr {
10159 return Ok(val);
10160 }
10161 }
10162 Err(ErrorContext::new_missing(
10163 "LinkinfoBrportAttrs",
10164 "McastFlood",
10165 self.orig_loc,
10166 self.buf.as_ptr() as usize,
10167 ))
10168 }
10169 pub fn get_mcast_to_ucast(&self) -> Result<(), ErrorContext> {
10170 let mut iter = self.clone();
10171 iter.pos = 0;
10172 for attr in iter {
10173 if let Ok(LinkinfoBrportAttrs::McastToUcast(val)) = attr {
10174 return Ok(val);
10175 }
10176 }
10177 Err(ErrorContext::new_missing(
10178 "LinkinfoBrportAttrs",
10179 "McastToUcast",
10180 self.orig_loc,
10181 self.buf.as_ptr() as usize,
10182 ))
10183 }
10184 pub fn get_vlan_tunnel(&self) -> Result<(), ErrorContext> {
10185 let mut iter = self.clone();
10186 iter.pos = 0;
10187 for attr in iter {
10188 if let Ok(LinkinfoBrportAttrs::VlanTunnel(val)) = attr {
10189 return Ok(val);
10190 }
10191 }
10192 Err(ErrorContext::new_missing(
10193 "LinkinfoBrportAttrs",
10194 "VlanTunnel",
10195 self.orig_loc,
10196 self.buf.as_ptr() as usize,
10197 ))
10198 }
10199 pub fn get_bcast_flood(&self) -> Result<(), ErrorContext> {
10200 let mut iter = self.clone();
10201 iter.pos = 0;
10202 for attr in iter {
10203 if let Ok(LinkinfoBrportAttrs::BcastFlood(val)) = attr {
10204 return Ok(val);
10205 }
10206 }
10207 Err(ErrorContext::new_missing(
10208 "LinkinfoBrportAttrs",
10209 "BcastFlood",
10210 self.orig_loc,
10211 self.buf.as_ptr() as usize,
10212 ))
10213 }
10214 pub fn get_group_fwd_mask(&self) -> Result<u16, ErrorContext> {
10215 let mut iter = self.clone();
10216 iter.pos = 0;
10217 for attr in iter {
10218 if let Ok(LinkinfoBrportAttrs::GroupFwdMask(val)) = attr {
10219 return Ok(val);
10220 }
10221 }
10222 Err(ErrorContext::new_missing(
10223 "LinkinfoBrportAttrs",
10224 "GroupFwdMask",
10225 self.orig_loc,
10226 self.buf.as_ptr() as usize,
10227 ))
10228 }
10229 pub fn get_neigh_suppress(&self) -> Result<(), ErrorContext> {
10230 let mut iter = self.clone();
10231 iter.pos = 0;
10232 for attr in iter {
10233 if let Ok(LinkinfoBrportAttrs::NeighSuppress(val)) = attr {
10234 return Ok(val);
10235 }
10236 }
10237 Err(ErrorContext::new_missing(
10238 "LinkinfoBrportAttrs",
10239 "NeighSuppress",
10240 self.orig_loc,
10241 self.buf.as_ptr() as usize,
10242 ))
10243 }
10244 pub fn get_isolated(&self) -> Result<(), ErrorContext> {
10245 let mut iter = self.clone();
10246 iter.pos = 0;
10247 for attr in iter {
10248 if let Ok(LinkinfoBrportAttrs::Isolated(val)) = attr {
10249 return Ok(val);
10250 }
10251 }
10252 Err(ErrorContext::new_missing(
10253 "LinkinfoBrportAttrs",
10254 "Isolated",
10255 self.orig_loc,
10256 self.buf.as_ptr() as usize,
10257 ))
10258 }
10259 pub fn get_backup_port(&self) -> Result<u32, ErrorContext> {
10260 let mut iter = self.clone();
10261 iter.pos = 0;
10262 for attr in iter {
10263 if let Ok(LinkinfoBrportAttrs::BackupPort(val)) = attr {
10264 return Ok(val);
10265 }
10266 }
10267 Err(ErrorContext::new_missing(
10268 "LinkinfoBrportAttrs",
10269 "BackupPort",
10270 self.orig_loc,
10271 self.buf.as_ptr() as usize,
10272 ))
10273 }
10274 pub fn get_mrp_ring_open(&self) -> Result<(), ErrorContext> {
10275 let mut iter = self.clone();
10276 iter.pos = 0;
10277 for attr in iter {
10278 if let Ok(LinkinfoBrportAttrs::MrpRingOpen(val)) = attr {
10279 return Ok(val);
10280 }
10281 }
10282 Err(ErrorContext::new_missing(
10283 "LinkinfoBrportAttrs",
10284 "MrpRingOpen",
10285 self.orig_loc,
10286 self.buf.as_ptr() as usize,
10287 ))
10288 }
10289 pub fn get_mrp_in_open(&self) -> Result<(), ErrorContext> {
10290 let mut iter = self.clone();
10291 iter.pos = 0;
10292 for attr in iter {
10293 if let Ok(LinkinfoBrportAttrs::MrpInOpen(val)) = attr {
10294 return Ok(val);
10295 }
10296 }
10297 Err(ErrorContext::new_missing(
10298 "LinkinfoBrportAttrs",
10299 "MrpInOpen",
10300 self.orig_loc,
10301 self.buf.as_ptr() as usize,
10302 ))
10303 }
10304 pub fn get_mcast_eht_hosts_limit(&self) -> Result<u32, ErrorContext> {
10305 let mut iter = self.clone();
10306 iter.pos = 0;
10307 for attr in iter {
10308 if let Ok(LinkinfoBrportAttrs::McastEhtHostsLimit(val)) = attr {
10309 return Ok(val);
10310 }
10311 }
10312 Err(ErrorContext::new_missing(
10313 "LinkinfoBrportAttrs",
10314 "McastEhtHostsLimit",
10315 self.orig_loc,
10316 self.buf.as_ptr() as usize,
10317 ))
10318 }
10319 pub fn get_mcast_eht_hosts_cnt(&self) -> Result<u32, ErrorContext> {
10320 let mut iter = self.clone();
10321 iter.pos = 0;
10322 for attr in iter {
10323 if let Ok(LinkinfoBrportAttrs::McastEhtHostsCnt(val)) = attr {
10324 return Ok(val);
10325 }
10326 }
10327 Err(ErrorContext::new_missing(
10328 "LinkinfoBrportAttrs",
10329 "McastEhtHostsCnt",
10330 self.orig_loc,
10331 self.buf.as_ptr() as usize,
10332 ))
10333 }
10334 pub fn get_locked(&self) -> Result<(), ErrorContext> {
10335 let mut iter = self.clone();
10336 iter.pos = 0;
10337 for attr in iter {
10338 if let Ok(LinkinfoBrportAttrs::Locked(val)) = attr {
10339 return Ok(val);
10340 }
10341 }
10342 Err(ErrorContext::new_missing(
10343 "LinkinfoBrportAttrs",
10344 "Locked",
10345 self.orig_loc,
10346 self.buf.as_ptr() as usize,
10347 ))
10348 }
10349 pub fn get_mab(&self) -> Result<(), ErrorContext> {
10350 let mut iter = self.clone();
10351 iter.pos = 0;
10352 for attr in iter {
10353 if let Ok(LinkinfoBrportAttrs::Mab(val)) = attr {
10354 return Ok(val);
10355 }
10356 }
10357 Err(ErrorContext::new_missing(
10358 "LinkinfoBrportAttrs",
10359 "Mab",
10360 self.orig_loc,
10361 self.buf.as_ptr() as usize,
10362 ))
10363 }
10364 pub fn get_mcast_n_groups(&self) -> Result<u32, ErrorContext> {
10365 let mut iter = self.clone();
10366 iter.pos = 0;
10367 for attr in iter {
10368 if let Ok(LinkinfoBrportAttrs::McastNGroups(val)) = attr {
10369 return Ok(val);
10370 }
10371 }
10372 Err(ErrorContext::new_missing(
10373 "LinkinfoBrportAttrs",
10374 "McastNGroups",
10375 self.orig_loc,
10376 self.buf.as_ptr() as usize,
10377 ))
10378 }
10379 pub fn get_mcast_max_groups(&self) -> Result<u32, ErrorContext> {
10380 let mut iter = self.clone();
10381 iter.pos = 0;
10382 for attr in iter {
10383 if let Ok(LinkinfoBrportAttrs::McastMaxGroups(val)) = attr {
10384 return Ok(val);
10385 }
10386 }
10387 Err(ErrorContext::new_missing(
10388 "LinkinfoBrportAttrs",
10389 "McastMaxGroups",
10390 self.orig_loc,
10391 self.buf.as_ptr() as usize,
10392 ))
10393 }
10394 pub fn get_neigh_vlan_suppress(&self) -> Result<(), ErrorContext> {
10395 let mut iter = self.clone();
10396 iter.pos = 0;
10397 for attr in iter {
10398 if let Ok(LinkinfoBrportAttrs::NeighVlanSuppress(val)) = attr {
10399 return Ok(val);
10400 }
10401 }
10402 Err(ErrorContext::new_missing(
10403 "LinkinfoBrportAttrs",
10404 "NeighVlanSuppress",
10405 self.orig_loc,
10406 self.buf.as_ptr() as usize,
10407 ))
10408 }
10409 pub fn get_backup_nhid(&self) -> Result<u32, ErrorContext> {
10410 let mut iter = self.clone();
10411 iter.pos = 0;
10412 for attr in iter {
10413 if let Ok(LinkinfoBrportAttrs::BackupNhid(val)) = attr {
10414 return Ok(val);
10415 }
10416 }
10417 Err(ErrorContext::new_missing(
10418 "LinkinfoBrportAttrs",
10419 "BackupNhid",
10420 self.orig_loc,
10421 self.buf.as_ptr() as usize,
10422 ))
10423 }
10424 pub fn get_neigh_forward_grat(&self) -> Result<u8, ErrorContext> {
10425 let mut iter = self.clone();
10426 iter.pos = 0;
10427 for attr in iter {
10428 if let Ok(LinkinfoBrportAttrs::NeighForwardGrat(val)) = attr {
10429 return Ok(val);
10430 }
10431 }
10432 Err(ErrorContext::new_missing(
10433 "LinkinfoBrportAttrs",
10434 "NeighForwardGrat",
10435 self.orig_loc,
10436 self.buf.as_ptr() as usize,
10437 ))
10438 }
10439}
10440impl LinkinfoBrportAttrs<'_> {
10441 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoBrportAttrs<'a> {
10442 IterableLinkinfoBrportAttrs::with_loc(buf, buf.as_ptr() as usize)
10443 }
10444 fn attr_from_type(r#type: u16) -> Option<&'static str> {
10445 let res = match r#type {
10446 1u16 => "State",
10447 2u16 => "Priority",
10448 3u16 => "Cost",
10449 4u16 => "Mode",
10450 5u16 => "Guard",
10451 6u16 => "Protect",
10452 7u16 => "FastLeave",
10453 8u16 => "Learning",
10454 9u16 => "UnicastFlood",
10455 10u16 => "Proxyarp",
10456 11u16 => "LearningSync",
10457 12u16 => "ProxyarpWifi",
10458 13u16 => "RootId",
10459 14u16 => "BridgeId",
10460 15u16 => "DesignatedPort",
10461 16u16 => "DesignatedCost",
10462 17u16 => "Id",
10463 18u16 => "No",
10464 19u16 => "TopologyChangeAck",
10465 20u16 => "ConfigPending",
10466 21u16 => "MessageAgeTimer",
10467 22u16 => "ForwardDelayTimer",
10468 23u16 => "HoldTimer",
10469 24u16 => "Flush",
10470 25u16 => "MulticastRouter",
10471 26u16 => "Pad",
10472 27u16 => "McastFlood",
10473 28u16 => "McastToUcast",
10474 29u16 => "VlanTunnel",
10475 30u16 => "BcastFlood",
10476 31u16 => "GroupFwdMask",
10477 32u16 => "NeighSuppress",
10478 33u16 => "Isolated",
10479 34u16 => "BackupPort",
10480 35u16 => "MrpRingOpen",
10481 36u16 => "MrpInOpen",
10482 37u16 => "McastEhtHostsLimit",
10483 38u16 => "McastEhtHostsCnt",
10484 39u16 => "Locked",
10485 40u16 => "Mab",
10486 41u16 => "McastNGroups",
10487 42u16 => "McastMaxGroups",
10488 43u16 => "NeighVlanSuppress",
10489 44u16 => "BackupNhid",
10490 45u16 => "NeighForwardGrat",
10491 _ => return None,
10492 };
10493 Some(res)
10494 }
10495}
10496#[derive(Clone, Copy, Default)]
10497pub struct IterableLinkinfoBrportAttrs<'a> {
10498 buf: &'a [u8],
10499 pos: usize,
10500 orig_loc: usize,
10501}
10502impl<'a> IterableLinkinfoBrportAttrs<'a> {
10503 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
10504 Self {
10505 buf,
10506 pos: 0,
10507 orig_loc,
10508 }
10509 }
10510 pub fn get_buf(&self) -> &'a [u8] {
10511 self.buf
10512 }
10513}
10514impl<'a> Iterator for IterableLinkinfoBrportAttrs<'a> {
10515 type Item = Result<LinkinfoBrportAttrs<'a>, ErrorContext>;
10516 fn next(&mut self) -> Option<Self::Item> {
10517 let mut pos;
10518 let mut r#type;
10519 loop {
10520 pos = self.pos;
10521 r#type = None;
10522 if self.buf.len() == self.pos {
10523 return None;
10524 }
10525 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
10526 self.pos = self.buf.len();
10527 break;
10528 };
10529 r#type = Some(header.r#type);
10530 let res = match header.r#type {
10531 1u16 => LinkinfoBrportAttrs::State({
10532 let res = parse_u8(next);
10533 let Some(val) = res else { break };
10534 val
10535 }),
10536 2u16 => LinkinfoBrportAttrs::Priority({
10537 let res = parse_u16(next);
10538 let Some(val) = res else { break };
10539 val
10540 }),
10541 3u16 => LinkinfoBrportAttrs::Cost({
10542 let res = parse_u32(next);
10543 let Some(val) = res else { break };
10544 val
10545 }),
10546 4u16 => LinkinfoBrportAttrs::Mode(()),
10547 5u16 => LinkinfoBrportAttrs::Guard(()),
10548 6u16 => LinkinfoBrportAttrs::Protect(()),
10549 7u16 => LinkinfoBrportAttrs::FastLeave(()),
10550 8u16 => LinkinfoBrportAttrs::Learning(()),
10551 9u16 => LinkinfoBrportAttrs::UnicastFlood(()),
10552 10u16 => LinkinfoBrportAttrs::Proxyarp(()),
10553 11u16 => LinkinfoBrportAttrs::LearningSync(()),
10554 12u16 => LinkinfoBrportAttrs::ProxyarpWifi(()),
10555 13u16 => LinkinfoBrportAttrs::RootId({
10556 let res = Some(IflaBridgeId::new_from_zeroed(next));
10557 let Some(val) = res else { break };
10558 val
10559 }),
10560 14u16 => LinkinfoBrportAttrs::BridgeId({
10561 let res = Some(IflaBridgeId::new_from_zeroed(next));
10562 let Some(val) = res else { break };
10563 val
10564 }),
10565 15u16 => LinkinfoBrportAttrs::DesignatedPort({
10566 let res = parse_u16(next);
10567 let Some(val) = res else { break };
10568 val
10569 }),
10570 16u16 => LinkinfoBrportAttrs::DesignatedCost({
10571 let res = parse_u16(next);
10572 let Some(val) = res else { break };
10573 val
10574 }),
10575 17u16 => LinkinfoBrportAttrs::Id({
10576 let res = parse_u16(next);
10577 let Some(val) = res else { break };
10578 val
10579 }),
10580 18u16 => LinkinfoBrportAttrs::No({
10581 let res = parse_u16(next);
10582 let Some(val) = res else { break };
10583 val
10584 }),
10585 19u16 => LinkinfoBrportAttrs::TopologyChangeAck({
10586 let res = parse_u8(next);
10587 let Some(val) = res else { break };
10588 val
10589 }),
10590 20u16 => LinkinfoBrportAttrs::ConfigPending({
10591 let res = parse_u8(next);
10592 let Some(val) = res else { break };
10593 val
10594 }),
10595 21u16 => LinkinfoBrportAttrs::MessageAgeTimer({
10596 let res = parse_u64(next);
10597 let Some(val) = res else { break };
10598 val
10599 }),
10600 22u16 => LinkinfoBrportAttrs::ForwardDelayTimer({
10601 let res = parse_u64(next);
10602 let Some(val) = res else { break };
10603 val
10604 }),
10605 23u16 => LinkinfoBrportAttrs::HoldTimer({
10606 let res = parse_u64(next);
10607 let Some(val) = res else { break };
10608 val
10609 }),
10610 24u16 => LinkinfoBrportAttrs::Flush(()),
10611 25u16 => LinkinfoBrportAttrs::MulticastRouter({
10612 let res = parse_u8(next);
10613 let Some(val) = res else { break };
10614 val
10615 }),
10616 26u16 => LinkinfoBrportAttrs::Pad({
10617 let res = Some(next);
10618 let Some(val) = res else { break };
10619 val
10620 }),
10621 27u16 => LinkinfoBrportAttrs::McastFlood(()),
10622 28u16 => LinkinfoBrportAttrs::McastToUcast(()),
10623 29u16 => LinkinfoBrportAttrs::VlanTunnel(()),
10624 30u16 => LinkinfoBrportAttrs::BcastFlood(()),
10625 31u16 => LinkinfoBrportAttrs::GroupFwdMask({
10626 let res = parse_u16(next);
10627 let Some(val) = res else { break };
10628 val
10629 }),
10630 32u16 => LinkinfoBrportAttrs::NeighSuppress(()),
10631 33u16 => LinkinfoBrportAttrs::Isolated(()),
10632 34u16 => LinkinfoBrportAttrs::BackupPort({
10633 let res = parse_u32(next);
10634 let Some(val) = res else { break };
10635 val
10636 }),
10637 35u16 => LinkinfoBrportAttrs::MrpRingOpen(()),
10638 36u16 => LinkinfoBrportAttrs::MrpInOpen(()),
10639 37u16 => LinkinfoBrportAttrs::McastEhtHostsLimit({
10640 let res = parse_u32(next);
10641 let Some(val) = res else { break };
10642 val
10643 }),
10644 38u16 => LinkinfoBrportAttrs::McastEhtHostsCnt({
10645 let res = parse_u32(next);
10646 let Some(val) = res else { break };
10647 val
10648 }),
10649 39u16 => LinkinfoBrportAttrs::Locked(()),
10650 40u16 => LinkinfoBrportAttrs::Mab(()),
10651 41u16 => LinkinfoBrportAttrs::McastNGroups({
10652 let res = parse_u32(next);
10653 let Some(val) = res else { break };
10654 val
10655 }),
10656 42u16 => LinkinfoBrportAttrs::McastMaxGroups({
10657 let res = parse_u32(next);
10658 let Some(val) = res else { break };
10659 val
10660 }),
10661 43u16 => LinkinfoBrportAttrs::NeighVlanSuppress(()),
10662 44u16 => LinkinfoBrportAttrs::BackupNhid({
10663 let res = parse_u32(next);
10664 let Some(val) = res else { break };
10665 val
10666 }),
10667 45u16 => LinkinfoBrportAttrs::NeighForwardGrat({
10668 let res = parse_u8(next);
10669 let Some(val) = res else { break };
10670 val
10671 }),
10672 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
10673 n => continue,
10674 };
10675 return Some(Ok(res));
10676 }
10677 Some(Err(ErrorContext::new(
10678 "LinkinfoBrportAttrs",
10679 r#type.and_then(|t| LinkinfoBrportAttrs::attr_from_type(t)),
10680 self.orig_loc,
10681 self.buf.as_ptr().wrapping_add(pos) as usize,
10682 )))
10683 }
10684}
10685impl<'a> std::fmt::Debug for IterableLinkinfoBrportAttrs<'_> {
10686 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10687 let mut fmt = f.debug_struct("LinkinfoBrportAttrs");
10688 for attr in self.clone() {
10689 let attr = match attr {
10690 Ok(a) => a,
10691 Err(err) => {
10692 fmt.finish()?;
10693 f.write_str("Err(")?;
10694 err.fmt(f)?;
10695 return f.write_str(")");
10696 }
10697 };
10698 match attr {
10699 LinkinfoBrportAttrs::State(val) => fmt.field("State", &val),
10700 LinkinfoBrportAttrs::Priority(val) => fmt.field("Priority", &val),
10701 LinkinfoBrportAttrs::Cost(val) => fmt.field("Cost", &val),
10702 LinkinfoBrportAttrs::Mode(val) => fmt.field("Mode", &val),
10703 LinkinfoBrportAttrs::Guard(val) => fmt.field("Guard", &val),
10704 LinkinfoBrportAttrs::Protect(val) => fmt.field("Protect", &val),
10705 LinkinfoBrportAttrs::FastLeave(val) => fmt.field("FastLeave", &val),
10706 LinkinfoBrportAttrs::Learning(val) => fmt.field("Learning", &val),
10707 LinkinfoBrportAttrs::UnicastFlood(val) => fmt.field("UnicastFlood", &val),
10708 LinkinfoBrportAttrs::Proxyarp(val) => fmt.field("Proxyarp", &val),
10709 LinkinfoBrportAttrs::LearningSync(val) => fmt.field("LearningSync", &val),
10710 LinkinfoBrportAttrs::ProxyarpWifi(val) => fmt.field("ProxyarpWifi", &val),
10711 LinkinfoBrportAttrs::RootId(val) => fmt.field("RootId", &val),
10712 LinkinfoBrportAttrs::BridgeId(val) => fmt.field("BridgeId", &val),
10713 LinkinfoBrportAttrs::DesignatedPort(val) => fmt.field("DesignatedPort", &val),
10714 LinkinfoBrportAttrs::DesignatedCost(val) => fmt.field("DesignatedCost", &val),
10715 LinkinfoBrportAttrs::Id(val) => fmt.field("Id", &val),
10716 LinkinfoBrportAttrs::No(val) => fmt.field("No", &val),
10717 LinkinfoBrportAttrs::TopologyChangeAck(val) => fmt.field("TopologyChangeAck", &val),
10718 LinkinfoBrportAttrs::ConfigPending(val) => fmt.field("ConfigPending", &val),
10719 LinkinfoBrportAttrs::MessageAgeTimer(val) => fmt.field("MessageAgeTimer", &val),
10720 LinkinfoBrportAttrs::ForwardDelayTimer(val) => fmt.field("ForwardDelayTimer", &val),
10721 LinkinfoBrportAttrs::HoldTimer(val) => fmt.field("HoldTimer", &val),
10722 LinkinfoBrportAttrs::Flush(val) => fmt.field("Flush", &val),
10723 LinkinfoBrportAttrs::MulticastRouter(val) => fmt.field("MulticastRouter", &val),
10724 LinkinfoBrportAttrs::Pad(val) => fmt.field("Pad", &val),
10725 LinkinfoBrportAttrs::McastFlood(val) => fmt.field("McastFlood", &val),
10726 LinkinfoBrportAttrs::McastToUcast(val) => fmt.field("McastToUcast", &val),
10727 LinkinfoBrportAttrs::VlanTunnel(val) => fmt.field("VlanTunnel", &val),
10728 LinkinfoBrportAttrs::BcastFlood(val) => fmt.field("BcastFlood", &val),
10729 LinkinfoBrportAttrs::GroupFwdMask(val) => fmt.field("GroupFwdMask", &val),
10730 LinkinfoBrportAttrs::NeighSuppress(val) => fmt.field("NeighSuppress", &val),
10731 LinkinfoBrportAttrs::Isolated(val) => fmt.field("Isolated", &val),
10732 LinkinfoBrportAttrs::BackupPort(val) => fmt.field("BackupPort", &val),
10733 LinkinfoBrportAttrs::MrpRingOpen(val) => fmt.field("MrpRingOpen", &val),
10734 LinkinfoBrportAttrs::MrpInOpen(val) => fmt.field("MrpInOpen", &val),
10735 LinkinfoBrportAttrs::McastEhtHostsLimit(val) => {
10736 fmt.field("McastEhtHostsLimit", &val)
10737 }
10738 LinkinfoBrportAttrs::McastEhtHostsCnt(val) => fmt.field("McastEhtHostsCnt", &val),
10739 LinkinfoBrportAttrs::Locked(val) => fmt.field("Locked", &val),
10740 LinkinfoBrportAttrs::Mab(val) => fmt.field("Mab", &val),
10741 LinkinfoBrportAttrs::McastNGroups(val) => fmt.field("McastNGroups", &val),
10742 LinkinfoBrportAttrs::McastMaxGroups(val) => fmt.field("McastMaxGroups", &val),
10743 LinkinfoBrportAttrs::NeighVlanSuppress(val) => fmt.field("NeighVlanSuppress", &val),
10744 LinkinfoBrportAttrs::BackupNhid(val) => fmt.field("BackupNhid", &val),
10745 LinkinfoBrportAttrs::NeighForwardGrat(val) => fmt.field("NeighForwardGrat", &val),
10746 };
10747 }
10748 fmt.finish()
10749 }
10750}
10751impl IterableLinkinfoBrportAttrs<'_> {
10752 pub fn lookup_attr(
10753 &self,
10754 offset: usize,
10755 missing_type: Option<u16>,
10756 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
10757 let mut stack = Vec::new();
10758 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
10759 if missing_type.is_some() && cur == offset {
10760 stack.push(("LinkinfoBrportAttrs", offset));
10761 return (
10762 stack,
10763 missing_type.and_then(|t| LinkinfoBrportAttrs::attr_from_type(t)),
10764 );
10765 }
10766 if cur > offset || cur + self.buf.len() < offset {
10767 return (stack, None);
10768 }
10769 let mut attrs = self.clone();
10770 let mut last_off = cur + attrs.pos;
10771 while let Some(attr) = attrs.next() {
10772 let Ok(attr) = attr else { break };
10773 match attr {
10774 LinkinfoBrportAttrs::State(val) => {
10775 if last_off == offset {
10776 stack.push(("State", last_off));
10777 break;
10778 }
10779 }
10780 LinkinfoBrportAttrs::Priority(val) => {
10781 if last_off == offset {
10782 stack.push(("Priority", last_off));
10783 break;
10784 }
10785 }
10786 LinkinfoBrportAttrs::Cost(val) => {
10787 if last_off == offset {
10788 stack.push(("Cost", last_off));
10789 break;
10790 }
10791 }
10792 LinkinfoBrportAttrs::Mode(val) => {
10793 if last_off == offset {
10794 stack.push(("Mode", last_off));
10795 break;
10796 }
10797 }
10798 LinkinfoBrportAttrs::Guard(val) => {
10799 if last_off == offset {
10800 stack.push(("Guard", last_off));
10801 break;
10802 }
10803 }
10804 LinkinfoBrportAttrs::Protect(val) => {
10805 if last_off == offset {
10806 stack.push(("Protect", last_off));
10807 break;
10808 }
10809 }
10810 LinkinfoBrportAttrs::FastLeave(val) => {
10811 if last_off == offset {
10812 stack.push(("FastLeave", last_off));
10813 break;
10814 }
10815 }
10816 LinkinfoBrportAttrs::Learning(val) => {
10817 if last_off == offset {
10818 stack.push(("Learning", last_off));
10819 break;
10820 }
10821 }
10822 LinkinfoBrportAttrs::UnicastFlood(val) => {
10823 if last_off == offset {
10824 stack.push(("UnicastFlood", last_off));
10825 break;
10826 }
10827 }
10828 LinkinfoBrportAttrs::Proxyarp(val) => {
10829 if last_off == offset {
10830 stack.push(("Proxyarp", last_off));
10831 break;
10832 }
10833 }
10834 LinkinfoBrportAttrs::LearningSync(val) => {
10835 if last_off == offset {
10836 stack.push(("LearningSync", last_off));
10837 break;
10838 }
10839 }
10840 LinkinfoBrportAttrs::ProxyarpWifi(val) => {
10841 if last_off == offset {
10842 stack.push(("ProxyarpWifi", last_off));
10843 break;
10844 }
10845 }
10846 LinkinfoBrportAttrs::RootId(val) => {
10847 if last_off == offset {
10848 stack.push(("RootId", last_off));
10849 break;
10850 }
10851 }
10852 LinkinfoBrportAttrs::BridgeId(val) => {
10853 if last_off == offset {
10854 stack.push(("BridgeId", last_off));
10855 break;
10856 }
10857 }
10858 LinkinfoBrportAttrs::DesignatedPort(val) => {
10859 if last_off == offset {
10860 stack.push(("DesignatedPort", last_off));
10861 break;
10862 }
10863 }
10864 LinkinfoBrportAttrs::DesignatedCost(val) => {
10865 if last_off == offset {
10866 stack.push(("DesignatedCost", last_off));
10867 break;
10868 }
10869 }
10870 LinkinfoBrportAttrs::Id(val) => {
10871 if last_off == offset {
10872 stack.push(("Id", last_off));
10873 break;
10874 }
10875 }
10876 LinkinfoBrportAttrs::No(val) => {
10877 if last_off == offset {
10878 stack.push(("No", last_off));
10879 break;
10880 }
10881 }
10882 LinkinfoBrportAttrs::TopologyChangeAck(val) => {
10883 if last_off == offset {
10884 stack.push(("TopologyChangeAck", last_off));
10885 break;
10886 }
10887 }
10888 LinkinfoBrportAttrs::ConfigPending(val) => {
10889 if last_off == offset {
10890 stack.push(("ConfigPending", last_off));
10891 break;
10892 }
10893 }
10894 LinkinfoBrportAttrs::MessageAgeTimer(val) => {
10895 if last_off == offset {
10896 stack.push(("MessageAgeTimer", last_off));
10897 break;
10898 }
10899 }
10900 LinkinfoBrportAttrs::ForwardDelayTimer(val) => {
10901 if last_off == offset {
10902 stack.push(("ForwardDelayTimer", last_off));
10903 break;
10904 }
10905 }
10906 LinkinfoBrportAttrs::HoldTimer(val) => {
10907 if last_off == offset {
10908 stack.push(("HoldTimer", last_off));
10909 break;
10910 }
10911 }
10912 LinkinfoBrportAttrs::Flush(val) => {
10913 if last_off == offset {
10914 stack.push(("Flush", last_off));
10915 break;
10916 }
10917 }
10918 LinkinfoBrportAttrs::MulticastRouter(val) => {
10919 if last_off == offset {
10920 stack.push(("MulticastRouter", last_off));
10921 break;
10922 }
10923 }
10924 LinkinfoBrportAttrs::Pad(val) => {
10925 if last_off == offset {
10926 stack.push(("Pad", last_off));
10927 break;
10928 }
10929 }
10930 LinkinfoBrportAttrs::McastFlood(val) => {
10931 if last_off == offset {
10932 stack.push(("McastFlood", last_off));
10933 break;
10934 }
10935 }
10936 LinkinfoBrportAttrs::McastToUcast(val) => {
10937 if last_off == offset {
10938 stack.push(("McastToUcast", last_off));
10939 break;
10940 }
10941 }
10942 LinkinfoBrportAttrs::VlanTunnel(val) => {
10943 if last_off == offset {
10944 stack.push(("VlanTunnel", last_off));
10945 break;
10946 }
10947 }
10948 LinkinfoBrportAttrs::BcastFlood(val) => {
10949 if last_off == offset {
10950 stack.push(("BcastFlood", last_off));
10951 break;
10952 }
10953 }
10954 LinkinfoBrportAttrs::GroupFwdMask(val) => {
10955 if last_off == offset {
10956 stack.push(("GroupFwdMask", last_off));
10957 break;
10958 }
10959 }
10960 LinkinfoBrportAttrs::NeighSuppress(val) => {
10961 if last_off == offset {
10962 stack.push(("NeighSuppress", last_off));
10963 break;
10964 }
10965 }
10966 LinkinfoBrportAttrs::Isolated(val) => {
10967 if last_off == offset {
10968 stack.push(("Isolated", last_off));
10969 break;
10970 }
10971 }
10972 LinkinfoBrportAttrs::BackupPort(val) => {
10973 if last_off == offset {
10974 stack.push(("BackupPort", last_off));
10975 break;
10976 }
10977 }
10978 LinkinfoBrportAttrs::MrpRingOpen(val) => {
10979 if last_off == offset {
10980 stack.push(("MrpRingOpen", last_off));
10981 break;
10982 }
10983 }
10984 LinkinfoBrportAttrs::MrpInOpen(val) => {
10985 if last_off == offset {
10986 stack.push(("MrpInOpen", last_off));
10987 break;
10988 }
10989 }
10990 LinkinfoBrportAttrs::McastEhtHostsLimit(val) => {
10991 if last_off == offset {
10992 stack.push(("McastEhtHostsLimit", last_off));
10993 break;
10994 }
10995 }
10996 LinkinfoBrportAttrs::McastEhtHostsCnt(val) => {
10997 if last_off == offset {
10998 stack.push(("McastEhtHostsCnt", last_off));
10999 break;
11000 }
11001 }
11002 LinkinfoBrportAttrs::Locked(val) => {
11003 if last_off == offset {
11004 stack.push(("Locked", last_off));
11005 break;
11006 }
11007 }
11008 LinkinfoBrportAttrs::Mab(val) => {
11009 if last_off == offset {
11010 stack.push(("Mab", last_off));
11011 break;
11012 }
11013 }
11014 LinkinfoBrportAttrs::McastNGroups(val) => {
11015 if last_off == offset {
11016 stack.push(("McastNGroups", last_off));
11017 break;
11018 }
11019 }
11020 LinkinfoBrportAttrs::McastMaxGroups(val) => {
11021 if last_off == offset {
11022 stack.push(("McastMaxGroups", last_off));
11023 break;
11024 }
11025 }
11026 LinkinfoBrportAttrs::NeighVlanSuppress(val) => {
11027 if last_off == offset {
11028 stack.push(("NeighVlanSuppress", last_off));
11029 break;
11030 }
11031 }
11032 LinkinfoBrportAttrs::BackupNhid(val) => {
11033 if last_off == offset {
11034 stack.push(("BackupNhid", last_off));
11035 break;
11036 }
11037 }
11038 LinkinfoBrportAttrs::NeighForwardGrat(val) => {
11039 if last_off == offset {
11040 stack.push(("NeighForwardGrat", last_off));
11041 break;
11042 }
11043 }
11044 _ => {}
11045 };
11046 last_off = cur + attrs.pos;
11047 }
11048 if !stack.is_empty() {
11049 stack.push(("LinkinfoBrportAttrs", cur));
11050 }
11051 (stack, None)
11052 }
11053}
11054#[derive(Clone)]
11055pub enum LinkinfoGreAttrs {
11056 Link(u32),
11057 Iflags(u16),
11058 Oflags(u16),
11059 Ikey(u32),
11060 Okey(u32),
11061 Local(std::net::IpAddr),
11062 Remote(std::net::IpAddr),
11063 Ttl(u8),
11064 Tos(u8),
11065 Pmtudisc(u8),
11066 EncapLimit(u8),
11067 Flowinfo(u32),
11068 Flags(u32),
11069 EncapType(u16),
11070 EncapFlags(u16),
11071 EncapSport(u16),
11072 EncapDport(u16),
11073 CollectMetadata(()),
11074 IgnoreDf(u8),
11075 Fwmark(u32),
11076 ErspanIndex(u32),
11077 ErspanVer(u8),
11078 ErspanDir(u8),
11079 ErspanHwid(u16),
11080}
11081impl<'a> IterableLinkinfoGreAttrs<'a> {
11082 pub fn get_link(&self) -> Result<u32, ErrorContext> {
11083 let mut iter = self.clone();
11084 iter.pos = 0;
11085 for attr in iter {
11086 if let Ok(LinkinfoGreAttrs::Link(val)) = attr {
11087 return Ok(val);
11088 }
11089 }
11090 Err(ErrorContext::new_missing(
11091 "LinkinfoGreAttrs",
11092 "Link",
11093 self.orig_loc,
11094 self.buf.as_ptr() as usize,
11095 ))
11096 }
11097 pub fn get_iflags(&self) -> Result<u16, ErrorContext> {
11098 let mut iter = self.clone();
11099 iter.pos = 0;
11100 for attr in iter {
11101 if let Ok(LinkinfoGreAttrs::Iflags(val)) = attr {
11102 return Ok(val);
11103 }
11104 }
11105 Err(ErrorContext::new_missing(
11106 "LinkinfoGreAttrs",
11107 "Iflags",
11108 self.orig_loc,
11109 self.buf.as_ptr() as usize,
11110 ))
11111 }
11112 pub fn get_oflags(&self) -> Result<u16, ErrorContext> {
11113 let mut iter = self.clone();
11114 iter.pos = 0;
11115 for attr in iter {
11116 if let Ok(LinkinfoGreAttrs::Oflags(val)) = attr {
11117 return Ok(val);
11118 }
11119 }
11120 Err(ErrorContext::new_missing(
11121 "LinkinfoGreAttrs",
11122 "Oflags",
11123 self.orig_loc,
11124 self.buf.as_ptr() as usize,
11125 ))
11126 }
11127 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
11128 let mut iter = self.clone();
11129 iter.pos = 0;
11130 for attr in iter {
11131 if let Ok(LinkinfoGreAttrs::Ikey(val)) = attr {
11132 return Ok(val);
11133 }
11134 }
11135 Err(ErrorContext::new_missing(
11136 "LinkinfoGreAttrs",
11137 "Ikey",
11138 self.orig_loc,
11139 self.buf.as_ptr() as usize,
11140 ))
11141 }
11142 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
11143 let mut iter = self.clone();
11144 iter.pos = 0;
11145 for attr in iter {
11146 if let Ok(LinkinfoGreAttrs::Okey(val)) = attr {
11147 return Ok(val);
11148 }
11149 }
11150 Err(ErrorContext::new_missing(
11151 "LinkinfoGreAttrs",
11152 "Okey",
11153 self.orig_loc,
11154 self.buf.as_ptr() as usize,
11155 ))
11156 }
11157 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
11158 let mut iter = self.clone();
11159 iter.pos = 0;
11160 for attr in iter {
11161 if let Ok(LinkinfoGreAttrs::Local(val)) = attr {
11162 return Ok(val);
11163 }
11164 }
11165 Err(ErrorContext::new_missing(
11166 "LinkinfoGreAttrs",
11167 "Local",
11168 self.orig_loc,
11169 self.buf.as_ptr() as usize,
11170 ))
11171 }
11172 pub fn get_remote(&self) -> Result<std::net::IpAddr, ErrorContext> {
11173 let mut iter = self.clone();
11174 iter.pos = 0;
11175 for attr in iter {
11176 if let Ok(LinkinfoGreAttrs::Remote(val)) = attr {
11177 return Ok(val);
11178 }
11179 }
11180 Err(ErrorContext::new_missing(
11181 "LinkinfoGreAttrs",
11182 "Remote",
11183 self.orig_loc,
11184 self.buf.as_ptr() as usize,
11185 ))
11186 }
11187 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
11188 let mut iter = self.clone();
11189 iter.pos = 0;
11190 for attr in iter {
11191 if let Ok(LinkinfoGreAttrs::Ttl(val)) = attr {
11192 return Ok(val);
11193 }
11194 }
11195 Err(ErrorContext::new_missing(
11196 "LinkinfoGreAttrs",
11197 "Ttl",
11198 self.orig_loc,
11199 self.buf.as_ptr() as usize,
11200 ))
11201 }
11202 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
11203 let mut iter = self.clone();
11204 iter.pos = 0;
11205 for attr in iter {
11206 if let Ok(LinkinfoGreAttrs::Tos(val)) = attr {
11207 return Ok(val);
11208 }
11209 }
11210 Err(ErrorContext::new_missing(
11211 "LinkinfoGreAttrs",
11212 "Tos",
11213 self.orig_loc,
11214 self.buf.as_ptr() as usize,
11215 ))
11216 }
11217 pub fn get_pmtudisc(&self) -> Result<u8, ErrorContext> {
11218 let mut iter = self.clone();
11219 iter.pos = 0;
11220 for attr in iter {
11221 if let Ok(LinkinfoGreAttrs::Pmtudisc(val)) = attr {
11222 return Ok(val);
11223 }
11224 }
11225 Err(ErrorContext::new_missing(
11226 "LinkinfoGreAttrs",
11227 "Pmtudisc",
11228 self.orig_loc,
11229 self.buf.as_ptr() as usize,
11230 ))
11231 }
11232 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
11233 let mut iter = self.clone();
11234 iter.pos = 0;
11235 for attr in iter {
11236 if let Ok(LinkinfoGreAttrs::EncapLimit(val)) = attr {
11237 return Ok(val);
11238 }
11239 }
11240 Err(ErrorContext::new_missing(
11241 "LinkinfoGreAttrs",
11242 "EncapLimit",
11243 self.orig_loc,
11244 self.buf.as_ptr() as usize,
11245 ))
11246 }
11247 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
11248 let mut iter = self.clone();
11249 iter.pos = 0;
11250 for attr in iter {
11251 if let Ok(LinkinfoGreAttrs::Flowinfo(val)) = attr {
11252 return Ok(val);
11253 }
11254 }
11255 Err(ErrorContext::new_missing(
11256 "LinkinfoGreAttrs",
11257 "Flowinfo",
11258 self.orig_loc,
11259 self.buf.as_ptr() as usize,
11260 ))
11261 }
11262 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
11263 let mut iter = self.clone();
11264 iter.pos = 0;
11265 for attr in iter {
11266 if let Ok(LinkinfoGreAttrs::Flags(val)) = attr {
11267 return Ok(val);
11268 }
11269 }
11270 Err(ErrorContext::new_missing(
11271 "LinkinfoGreAttrs",
11272 "Flags",
11273 self.orig_loc,
11274 self.buf.as_ptr() as usize,
11275 ))
11276 }
11277 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
11278 let mut iter = self.clone();
11279 iter.pos = 0;
11280 for attr in iter {
11281 if let Ok(LinkinfoGreAttrs::EncapType(val)) = attr {
11282 return Ok(val);
11283 }
11284 }
11285 Err(ErrorContext::new_missing(
11286 "LinkinfoGreAttrs",
11287 "EncapType",
11288 self.orig_loc,
11289 self.buf.as_ptr() as usize,
11290 ))
11291 }
11292 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
11293 let mut iter = self.clone();
11294 iter.pos = 0;
11295 for attr in iter {
11296 if let Ok(LinkinfoGreAttrs::EncapFlags(val)) = attr {
11297 return Ok(val);
11298 }
11299 }
11300 Err(ErrorContext::new_missing(
11301 "LinkinfoGreAttrs",
11302 "EncapFlags",
11303 self.orig_loc,
11304 self.buf.as_ptr() as usize,
11305 ))
11306 }
11307 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
11308 let mut iter = self.clone();
11309 iter.pos = 0;
11310 for attr in iter {
11311 if let Ok(LinkinfoGreAttrs::EncapSport(val)) = attr {
11312 return Ok(val);
11313 }
11314 }
11315 Err(ErrorContext::new_missing(
11316 "LinkinfoGreAttrs",
11317 "EncapSport",
11318 self.orig_loc,
11319 self.buf.as_ptr() as usize,
11320 ))
11321 }
11322 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
11323 let mut iter = self.clone();
11324 iter.pos = 0;
11325 for attr in iter {
11326 if let Ok(LinkinfoGreAttrs::EncapDport(val)) = attr {
11327 return Ok(val);
11328 }
11329 }
11330 Err(ErrorContext::new_missing(
11331 "LinkinfoGreAttrs",
11332 "EncapDport",
11333 self.orig_loc,
11334 self.buf.as_ptr() as usize,
11335 ))
11336 }
11337 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
11338 let mut iter = self.clone();
11339 iter.pos = 0;
11340 for attr in iter {
11341 if let Ok(LinkinfoGreAttrs::CollectMetadata(val)) = attr {
11342 return Ok(val);
11343 }
11344 }
11345 Err(ErrorContext::new_missing(
11346 "LinkinfoGreAttrs",
11347 "CollectMetadata",
11348 self.orig_loc,
11349 self.buf.as_ptr() as usize,
11350 ))
11351 }
11352 pub fn get_ignore_df(&self) -> Result<u8, ErrorContext> {
11353 let mut iter = self.clone();
11354 iter.pos = 0;
11355 for attr in iter {
11356 if let Ok(LinkinfoGreAttrs::IgnoreDf(val)) = attr {
11357 return Ok(val);
11358 }
11359 }
11360 Err(ErrorContext::new_missing(
11361 "LinkinfoGreAttrs",
11362 "IgnoreDf",
11363 self.orig_loc,
11364 self.buf.as_ptr() as usize,
11365 ))
11366 }
11367 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
11368 let mut iter = self.clone();
11369 iter.pos = 0;
11370 for attr in iter {
11371 if let Ok(LinkinfoGreAttrs::Fwmark(val)) = attr {
11372 return Ok(val);
11373 }
11374 }
11375 Err(ErrorContext::new_missing(
11376 "LinkinfoGreAttrs",
11377 "Fwmark",
11378 self.orig_loc,
11379 self.buf.as_ptr() as usize,
11380 ))
11381 }
11382 pub fn get_erspan_index(&self) -> Result<u32, ErrorContext> {
11383 let mut iter = self.clone();
11384 iter.pos = 0;
11385 for attr in iter {
11386 if let Ok(LinkinfoGreAttrs::ErspanIndex(val)) = attr {
11387 return Ok(val);
11388 }
11389 }
11390 Err(ErrorContext::new_missing(
11391 "LinkinfoGreAttrs",
11392 "ErspanIndex",
11393 self.orig_loc,
11394 self.buf.as_ptr() as usize,
11395 ))
11396 }
11397 pub fn get_erspan_ver(&self) -> Result<u8, ErrorContext> {
11398 let mut iter = self.clone();
11399 iter.pos = 0;
11400 for attr in iter {
11401 if let Ok(LinkinfoGreAttrs::ErspanVer(val)) = attr {
11402 return Ok(val);
11403 }
11404 }
11405 Err(ErrorContext::new_missing(
11406 "LinkinfoGreAttrs",
11407 "ErspanVer",
11408 self.orig_loc,
11409 self.buf.as_ptr() as usize,
11410 ))
11411 }
11412 pub fn get_erspan_dir(&self) -> Result<u8, ErrorContext> {
11413 let mut iter = self.clone();
11414 iter.pos = 0;
11415 for attr in iter {
11416 if let Ok(LinkinfoGreAttrs::ErspanDir(val)) = attr {
11417 return Ok(val);
11418 }
11419 }
11420 Err(ErrorContext::new_missing(
11421 "LinkinfoGreAttrs",
11422 "ErspanDir",
11423 self.orig_loc,
11424 self.buf.as_ptr() as usize,
11425 ))
11426 }
11427 pub fn get_erspan_hwid(&self) -> Result<u16, ErrorContext> {
11428 let mut iter = self.clone();
11429 iter.pos = 0;
11430 for attr in iter {
11431 if let Ok(LinkinfoGreAttrs::ErspanHwid(val)) = attr {
11432 return Ok(val);
11433 }
11434 }
11435 Err(ErrorContext::new_missing(
11436 "LinkinfoGreAttrs",
11437 "ErspanHwid",
11438 self.orig_loc,
11439 self.buf.as_ptr() as usize,
11440 ))
11441 }
11442}
11443impl LinkinfoGreAttrs {
11444 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoGreAttrs<'a> {
11445 IterableLinkinfoGreAttrs::with_loc(buf, buf.as_ptr() as usize)
11446 }
11447 fn attr_from_type(r#type: u16) -> Option<&'static str> {
11448 let res = match r#type {
11449 1u16 => "Link",
11450 2u16 => "Iflags",
11451 3u16 => "Oflags",
11452 4u16 => "Ikey",
11453 5u16 => "Okey",
11454 6u16 => "Local",
11455 7u16 => "Remote",
11456 8u16 => "Ttl",
11457 9u16 => "Tos",
11458 10u16 => "Pmtudisc",
11459 11u16 => "EncapLimit",
11460 12u16 => "Flowinfo",
11461 13u16 => "Flags",
11462 14u16 => "EncapType",
11463 15u16 => "EncapFlags",
11464 16u16 => "EncapSport",
11465 17u16 => "EncapDport",
11466 18u16 => "CollectMetadata",
11467 19u16 => "IgnoreDf",
11468 20u16 => "Fwmark",
11469 21u16 => "ErspanIndex",
11470 22u16 => "ErspanVer",
11471 23u16 => "ErspanDir",
11472 24u16 => "ErspanHwid",
11473 _ => return None,
11474 };
11475 Some(res)
11476 }
11477}
11478#[derive(Clone, Copy, Default)]
11479pub struct IterableLinkinfoGreAttrs<'a> {
11480 buf: &'a [u8],
11481 pos: usize,
11482 orig_loc: usize,
11483}
11484impl<'a> IterableLinkinfoGreAttrs<'a> {
11485 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
11486 Self {
11487 buf,
11488 pos: 0,
11489 orig_loc,
11490 }
11491 }
11492 pub fn get_buf(&self) -> &'a [u8] {
11493 self.buf
11494 }
11495}
11496impl<'a> Iterator for IterableLinkinfoGreAttrs<'a> {
11497 type Item = Result<LinkinfoGreAttrs, ErrorContext>;
11498 fn next(&mut self) -> Option<Self::Item> {
11499 let mut pos;
11500 let mut r#type;
11501 loop {
11502 pos = self.pos;
11503 r#type = None;
11504 if self.buf.len() == self.pos {
11505 return None;
11506 }
11507 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
11508 self.pos = self.buf.len();
11509 break;
11510 };
11511 r#type = Some(header.r#type);
11512 let res = match header.r#type {
11513 1u16 => LinkinfoGreAttrs::Link({
11514 let res = parse_u32(next);
11515 let Some(val) = res else { break };
11516 val
11517 }),
11518 2u16 => LinkinfoGreAttrs::Iflags({
11519 let res = parse_be_u16(next);
11520 let Some(val) = res else { break };
11521 val
11522 }),
11523 3u16 => LinkinfoGreAttrs::Oflags({
11524 let res = parse_be_u16(next);
11525 let Some(val) = res else { break };
11526 val
11527 }),
11528 4u16 => LinkinfoGreAttrs::Ikey({
11529 let res = parse_be_u32(next);
11530 let Some(val) = res else { break };
11531 val
11532 }),
11533 5u16 => LinkinfoGreAttrs::Okey({
11534 let res = parse_be_u32(next);
11535 let Some(val) = res else { break };
11536 val
11537 }),
11538 6u16 => LinkinfoGreAttrs::Local({
11539 let res = parse_ip(next);
11540 let Some(val) = res else { break };
11541 val
11542 }),
11543 7u16 => LinkinfoGreAttrs::Remote({
11544 let res = parse_ip(next);
11545 let Some(val) = res else { break };
11546 val
11547 }),
11548 8u16 => LinkinfoGreAttrs::Ttl({
11549 let res = parse_u8(next);
11550 let Some(val) = res else { break };
11551 val
11552 }),
11553 9u16 => LinkinfoGreAttrs::Tos({
11554 let res = parse_u8(next);
11555 let Some(val) = res else { break };
11556 val
11557 }),
11558 10u16 => LinkinfoGreAttrs::Pmtudisc({
11559 let res = parse_u8(next);
11560 let Some(val) = res else { break };
11561 val
11562 }),
11563 11u16 => LinkinfoGreAttrs::EncapLimit({
11564 let res = parse_u8(next);
11565 let Some(val) = res else { break };
11566 val
11567 }),
11568 12u16 => LinkinfoGreAttrs::Flowinfo({
11569 let res = parse_be_u32(next);
11570 let Some(val) = res else { break };
11571 val
11572 }),
11573 13u16 => LinkinfoGreAttrs::Flags({
11574 let res = parse_u32(next);
11575 let Some(val) = res else { break };
11576 val
11577 }),
11578 14u16 => LinkinfoGreAttrs::EncapType({
11579 let res = parse_u16(next);
11580 let Some(val) = res else { break };
11581 val
11582 }),
11583 15u16 => LinkinfoGreAttrs::EncapFlags({
11584 let res = parse_u16(next);
11585 let Some(val) = res else { break };
11586 val
11587 }),
11588 16u16 => LinkinfoGreAttrs::EncapSport({
11589 let res = parse_be_u16(next);
11590 let Some(val) = res else { break };
11591 val
11592 }),
11593 17u16 => LinkinfoGreAttrs::EncapDport({
11594 let res = parse_be_u16(next);
11595 let Some(val) = res else { break };
11596 val
11597 }),
11598 18u16 => LinkinfoGreAttrs::CollectMetadata(()),
11599 19u16 => LinkinfoGreAttrs::IgnoreDf({
11600 let res = parse_u8(next);
11601 let Some(val) = res else { break };
11602 val
11603 }),
11604 20u16 => LinkinfoGreAttrs::Fwmark({
11605 let res = parse_u32(next);
11606 let Some(val) = res else { break };
11607 val
11608 }),
11609 21u16 => LinkinfoGreAttrs::ErspanIndex({
11610 let res = parse_u32(next);
11611 let Some(val) = res else { break };
11612 val
11613 }),
11614 22u16 => LinkinfoGreAttrs::ErspanVer({
11615 let res = parse_u8(next);
11616 let Some(val) = res else { break };
11617 val
11618 }),
11619 23u16 => LinkinfoGreAttrs::ErspanDir({
11620 let res = parse_u8(next);
11621 let Some(val) = res else { break };
11622 val
11623 }),
11624 24u16 => LinkinfoGreAttrs::ErspanHwid({
11625 let res = parse_u16(next);
11626 let Some(val) = res else { break };
11627 val
11628 }),
11629 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
11630 n => continue,
11631 };
11632 return Some(Ok(res));
11633 }
11634 Some(Err(ErrorContext::new(
11635 "LinkinfoGreAttrs",
11636 r#type.and_then(|t| LinkinfoGreAttrs::attr_from_type(t)),
11637 self.orig_loc,
11638 self.buf.as_ptr().wrapping_add(pos) as usize,
11639 )))
11640 }
11641}
11642impl std::fmt::Debug for IterableLinkinfoGreAttrs<'_> {
11643 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11644 let mut fmt = f.debug_struct("LinkinfoGreAttrs");
11645 for attr in self.clone() {
11646 let attr = match attr {
11647 Ok(a) => a,
11648 Err(err) => {
11649 fmt.finish()?;
11650 f.write_str("Err(")?;
11651 err.fmt(f)?;
11652 return f.write_str(")");
11653 }
11654 };
11655 match attr {
11656 LinkinfoGreAttrs::Link(val) => fmt.field("Link", &val),
11657 LinkinfoGreAttrs::Iflags(val) => fmt.field("Iflags", &val),
11658 LinkinfoGreAttrs::Oflags(val) => fmt.field("Oflags", &val),
11659 LinkinfoGreAttrs::Ikey(val) => fmt.field("Ikey", &val),
11660 LinkinfoGreAttrs::Okey(val) => fmt.field("Okey", &val),
11661 LinkinfoGreAttrs::Local(val) => fmt.field("Local", &val),
11662 LinkinfoGreAttrs::Remote(val) => fmt.field("Remote", &val),
11663 LinkinfoGreAttrs::Ttl(val) => fmt.field("Ttl", &val),
11664 LinkinfoGreAttrs::Tos(val) => fmt.field("Tos", &val),
11665 LinkinfoGreAttrs::Pmtudisc(val) => fmt.field("Pmtudisc", &val),
11666 LinkinfoGreAttrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
11667 LinkinfoGreAttrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
11668 LinkinfoGreAttrs::Flags(val) => fmt.field("Flags", &val),
11669 LinkinfoGreAttrs::EncapType(val) => fmt.field("EncapType", &val),
11670 LinkinfoGreAttrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
11671 LinkinfoGreAttrs::EncapSport(val) => fmt.field("EncapSport", &val),
11672 LinkinfoGreAttrs::EncapDport(val) => fmt.field("EncapDport", &val),
11673 LinkinfoGreAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
11674 LinkinfoGreAttrs::IgnoreDf(val) => fmt.field("IgnoreDf", &val),
11675 LinkinfoGreAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
11676 LinkinfoGreAttrs::ErspanIndex(val) => fmt.field("ErspanIndex", &val),
11677 LinkinfoGreAttrs::ErspanVer(val) => fmt.field("ErspanVer", &val),
11678 LinkinfoGreAttrs::ErspanDir(val) => fmt.field("ErspanDir", &val),
11679 LinkinfoGreAttrs::ErspanHwid(val) => fmt.field("ErspanHwid", &val),
11680 };
11681 }
11682 fmt.finish()
11683 }
11684}
11685impl IterableLinkinfoGreAttrs<'_> {
11686 pub fn lookup_attr(
11687 &self,
11688 offset: usize,
11689 missing_type: Option<u16>,
11690 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
11691 let mut stack = Vec::new();
11692 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
11693 if missing_type.is_some() && cur == offset {
11694 stack.push(("LinkinfoGreAttrs", offset));
11695 return (
11696 stack,
11697 missing_type.and_then(|t| LinkinfoGreAttrs::attr_from_type(t)),
11698 );
11699 }
11700 if cur > offset || cur + self.buf.len() < offset {
11701 return (stack, None);
11702 }
11703 let mut attrs = self.clone();
11704 let mut last_off = cur + attrs.pos;
11705 while let Some(attr) = attrs.next() {
11706 let Ok(attr) = attr else { break };
11707 match attr {
11708 LinkinfoGreAttrs::Link(val) => {
11709 if last_off == offset {
11710 stack.push(("Link", last_off));
11711 break;
11712 }
11713 }
11714 LinkinfoGreAttrs::Iflags(val) => {
11715 if last_off == offset {
11716 stack.push(("Iflags", last_off));
11717 break;
11718 }
11719 }
11720 LinkinfoGreAttrs::Oflags(val) => {
11721 if last_off == offset {
11722 stack.push(("Oflags", last_off));
11723 break;
11724 }
11725 }
11726 LinkinfoGreAttrs::Ikey(val) => {
11727 if last_off == offset {
11728 stack.push(("Ikey", last_off));
11729 break;
11730 }
11731 }
11732 LinkinfoGreAttrs::Okey(val) => {
11733 if last_off == offset {
11734 stack.push(("Okey", last_off));
11735 break;
11736 }
11737 }
11738 LinkinfoGreAttrs::Local(val) => {
11739 if last_off == offset {
11740 stack.push(("Local", last_off));
11741 break;
11742 }
11743 }
11744 LinkinfoGreAttrs::Remote(val) => {
11745 if last_off == offset {
11746 stack.push(("Remote", last_off));
11747 break;
11748 }
11749 }
11750 LinkinfoGreAttrs::Ttl(val) => {
11751 if last_off == offset {
11752 stack.push(("Ttl", last_off));
11753 break;
11754 }
11755 }
11756 LinkinfoGreAttrs::Tos(val) => {
11757 if last_off == offset {
11758 stack.push(("Tos", last_off));
11759 break;
11760 }
11761 }
11762 LinkinfoGreAttrs::Pmtudisc(val) => {
11763 if last_off == offset {
11764 stack.push(("Pmtudisc", last_off));
11765 break;
11766 }
11767 }
11768 LinkinfoGreAttrs::EncapLimit(val) => {
11769 if last_off == offset {
11770 stack.push(("EncapLimit", last_off));
11771 break;
11772 }
11773 }
11774 LinkinfoGreAttrs::Flowinfo(val) => {
11775 if last_off == offset {
11776 stack.push(("Flowinfo", last_off));
11777 break;
11778 }
11779 }
11780 LinkinfoGreAttrs::Flags(val) => {
11781 if last_off == offset {
11782 stack.push(("Flags", last_off));
11783 break;
11784 }
11785 }
11786 LinkinfoGreAttrs::EncapType(val) => {
11787 if last_off == offset {
11788 stack.push(("EncapType", last_off));
11789 break;
11790 }
11791 }
11792 LinkinfoGreAttrs::EncapFlags(val) => {
11793 if last_off == offset {
11794 stack.push(("EncapFlags", last_off));
11795 break;
11796 }
11797 }
11798 LinkinfoGreAttrs::EncapSport(val) => {
11799 if last_off == offset {
11800 stack.push(("EncapSport", last_off));
11801 break;
11802 }
11803 }
11804 LinkinfoGreAttrs::EncapDport(val) => {
11805 if last_off == offset {
11806 stack.push(("EncapDport", last_off));
11807 break;
11808 }
11809 }
11810 LinkinfoGreAttrs::CollectMetadata(val) => {
11811 if last_off == offset {
11812 stack.push(("CollectMetadata", last_off));
11813 break;
11814 }
11815 }
11816 LinkinfoGreAttrs::IgnoreDf(val) => {
11817 if last_off == offset {
11818 stack.push(("IgnoreDf", last_off));
11819 break;
11820 }
11821 }
11822 LinkinfoGreAttrs::Fwmark(val) => {
11823 if last_off == offset {
11824 stack.push(("Fwmark", last_off));
11825 break;
11826 }
11827 }
11828 LinkinfoGreAttrs::ErspanIndex(val) => {
11829 if last_off == offset {
11830 stack.push(("ErspanIndex", last_off));
11831 break;
11832 }
11833 }
11834 LinkinfoGreAttrs::ErspanVer(val) => {
11835 if last_off == offset {
11836 stack.push(("ErspanVer", last_off));
11837 break;
11838 }
11839 }
11840 LinkinfoGreAttrs::ErspanDir(val) => {
11841 if last_off == offset {
11842 stack.push(("ErspanDir", last_off));
11843 break;
11844 }
11845 }
11846 LinkinfoGreAttrs::ErspanHwid(val) => {
11847 if last_off == offset {
11848 stack.push(("ErspanHwid", last_off));
11849 break;
11850 }
11851 }
11852 _ => {}
11853 };
11854 last_off = cur + attrs.pos;
11855 }
11856 if !stack.is_empty() {
11857 stack.push(("LinkinfoGreAttrs", cur));
11858 }
11859 (stack, None)
11860 }
11861}
11862#[derive(Clone)]
11863pub enum LinkinfoGre6Attrs<'a> {
11864 Link(u32),
11865 Iflags(u16),
11866 Oflags(u16),
11867 Ikey(u32),
11868 Okey(u32),
11869 Local(&'a [u8]),
11870 Remote(&'a [u8]),
11871 Ttl(u8),
11872 EncapLimit(u8),
11873 Flowinfo(u32),
11874 Flags(u32),
11875 EncapType(u16),
11876 EncapFlags(u16),
11877 EncapSport(u16),
11878 EncapDport(u16),
11879 CollectMetadata(()),
11880 Fwmark(u32),
11881 ErspanIndex(u32),
11882 ErspanVer(u8),
11883 ErspanDir(u8),
11884 ErspanHwid(u16),
11885}
11886impl<'a> IterableLinkinfoGre6Attrs<'a> {
11887 pub fn get_link(&self) -> Result<u32, ErrorContext> {
11888 let mut iter = self.clone();
11889 iter.pos = 0;
11890 for attr in iter {
11891 if let Ok(LinkinfoGre6Attrs::Link(val)) = attr {
11892 return Ok(val);
11893 }
11894 }
11895 Err(ErrorContext::new_missing(
11896 "LinkinfoGre6Attrs",
11897 "Link",
11898 self.orig_loc,
11899 self.buf.as_ptr() as usize,
11900 ))
11901 }
11902 pub fn get_iflags(&self) -> Result<u16, ErrorContext> {
11903 let mut iter = self.clone();
11904 iter.pos = 0;
11905 for attr in iter {
11906 if let Ok(LinkinfoGre6Attrs::Iflags(val)) = attr {
11907 return Ok(val);
11908 }
11909 }
11910 Err(ErrorContext::new_missing(
11911 "LinkinfoGre6Attrs",
11912 "Iflags",
11913 self.orig_loc,
11914 self.buf.as_ptr() as usize,
11915 ))
11916 }
11917 pub fn get_oflags(&self) -> Result<u16, ErrorContext> {
11918 let mut iter = self.clone();
11919 iter.pos = 0;
11920 for attr in iter {
11921 if let Ok(LinkinfoGre6Attrs::Oflags(val)) = attr {
11922 return Ok(val);
11923 }
11924 }
11925 Err(ErrorContext::new_missing(
11926 "LinkinfoGre6Attrs",
11927 "Oflags",
11928 self.orig_loc,
11929 self.buf.as_ptr() as usize,
11930 ))
11931 }
11932 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
11933 let mut iter = self.clone();
11934 iter.pos = 0;
11935 for attr in iter {
11936 if let Ok(LinkinfoGre6Attrs::Ikey(val)) = attr {
11937 return Ok(val);
11938 }
11939 }
11940 Err(ErrorContext::new_missing(
11941 "LinkinfoGre6Attrs",
11942 "Ikey",
11943 self.orig_loc,
11944 self.buf.as_ptr() as usize,
11945 ))
11946 }
11947 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
11948 let mut iter = self.clone();
11949 iter.pos = 0;
11950 for attr in iter {
11951 if let Ok(LinkinfoGre6Attrs::Okey(val)) = attr {
11952 return Ok(val);
11953 }
11954 }
11955 Err(ErrorContext::new_missing(
11956 "LinkinfoGre6Attrs",
11957 "Okey",
11958 self.orig_loc,
11959 self.buf.as_ptr() as usize,
11960 ))
11961 }
11962 pub fn get_local(&self) -> Result<&'a [u8], ErrorContext> {
11963 let mut iter = self.clone();
11964 iter.pos = 0;
11965 for attr in iter {
11966 if let Ok(LinkinfoGre6Attrs::Local(val)) = attr {
11967 return Ok(val);
11968 }
11969 }
11970 Err(ErrorContext::new_missing(
11971 "LinkinfoGre6Attrs",
11972 "Local",
11973 self.orig_loc,
11974 self.buf.as_ptr() as usize,
11975 ))
11976 }
11977 pub fn get_remote(&self) -> Result<&'a [u8], ErrorContext> {
11978 let mut iter = self.clone();
11979 iter.pos = 0;
11980 for attr in iter {
11981 if let Ok(LinkinfoGre6Attrs::Remote(val)) = attr {
11982 return Ok(val);
11983 }
11984 }
11985 Err(ErrorContext::new_missing(
11986 "LinkinfoGre6Attrs",
11987 "Remote",
11988 self.orig_loc,
11989 self.buf.as_ptr() as usize,
11990 ))
11991 }
11992 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
11993 let mut iter = self.clone();
11994 iter.pos = 0;
11995 for attr in iter {
11996 if let Ok(LinkinfoGre6Attrs::Ttl(val)) = attr {
11997 return Ok(val);
11998 }
11999 }
12000 Err(ErrorContext::new_missing(
12001 "LinkinfoGre6Attrs",
12002 "Ttl",
12003 self.orig_loc,
12004 self.buf.as_ptr() as usize,
12005 ))
12006 }
12007 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
12008 let mut iter = self.clone();
12009 iter.pos = 0;
12010 for attr in iter {
12011 if let Ok(LinkinfoGre6Attrs::EncapLimit(val)) = attr {
12012 return Ok(val);
12013 }
12014 }
12015 Err(ErrorContext::new_missing(
12016 "LinkinfoGre6Attrs",
12017 "EncapLimit",
12018 self.orig_loc,
12019 self.buf.as_ptr() as usize,
12020 ))
12021 }
12022 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
12023 let mut iter = self.clone();
12024 iter.pos = 0;
12025 for attr in iter {
12026 if let Ok(LinkinfoGre6Attrs::Flowinfo(val)) = attr {
12027 return Ok(val);
12028 }
12029 }
12030 Err(ErrorContext::new_missing(
12031 "LinkinfoGre6Attrs",
12032 "Flowinfo",
12033 self.orig_loc,
12034 self.buf.as_ptr() as usize,
12035 ))
12036 }
12037 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
12038 let mut iter = self.clone();
12039 iter.pos = 0;
12040 for attr in iter {
12041 if let Ok(LinkinfoGre6Attrs::Flags(val)) = attr {
12042 return Ok(val);
12043 }
12044 }
12045 Err(ErrorContext::new_missing(
12046 "LinkinfoGre6Attrs",
12047 "Flags",
12048 self.orig_loc,
12049 self.buf.as_ptr() as usize,
12050 ))
12051 }
12052 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
12053 let mut iter = self.clone();
12054 iter.pos = 0;
12055 for attr in iter {
12056 if let Ok(LinkinfoGre6Attrs::EncapType(val)) = attr {
12057 return Ok(val);
12058 }
12059 }
12060 Err(ErrorContext::new_missing(
12061 "LinkinfoGre6Attrs",
12062 "EncapType",
12063 self.orig_loc,
12064 self.buf.as_ptr() as usize,
12065 ))
12066 }
12067 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
12068 let mut iter = self.clone();
12069 iter.pos = 0;
12070 for attr in iter {
12071 if let Ok(LinkinfoGre6Attrs::EncapFlags(val)) = attr {
12072 return Ok(val);
12073 }
12074 }
12075 Err(ErrorContext::new_missing(
12076 "LinkinfoGre6Attrs",
12077 "EncapFlags",
12078 self.orig_loc,
12079 self.buf.as_ptr() as usize,
12080 ))
12081 }
12082 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
12083 let mut iter = self.clone();
12084 iter.pos = 0;
12085 for attr in iter {
12086 if let Ok(LinkinfoGre6Attrs::EncapSport(val)) = attr {
12087 return Ok(val);
12088 }
12089 }
12090 Err(ErrorContext::new_missing(
12091 "LinkinfoGre6Attrs",
12092 "EncapSport",
12093 self.orig_loc,
12094 self.buf.as_ptr() as usize,
12095 ))
12096 }
12097 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
12098 let mut iter = self.clone();
12099 iter.pos = 0;
12100 for attr in iter {
12101 if let Ok(LinkinfoGre6Attrs::EncapDport(val)) = attr {
12102 return Ok(val);
12103 }
12104 }
12105 Err(ErrorContext::new_missing(
12106 "LinkinfoGre6Attrs",
12107 "EncapDport",
12108 self.orig_loc,
12109 self.buf.as_ptr() as usize,
12110 ))
12111 }
12112 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
12113 let mut iter = self.clone();
12114 iter.pos = 0;
12115 for attr in iter {
12116 if let Ok(LinkinfoGre6Attrs::CollectMetadata(val)) = attr {
12117 return Ok(val);
12118 }
12119 }
12120 Err(ErrorContext::new_missing(
12121 "LinkinfoGre6Attrs",
12122 "CollectMetadata",
12123 self.orig_loc,
12124 self.buf.as_ptr() as usize,
12125 ))
12126 }
12127 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
12128 let mut iter = self.clone();
12129 iter.pos = 0;
12130 for attr in iter {
12131 if let Ok(LinkinfoGre6Attrs::Fwmark(val)) = attr {
12132 return Ok(val);
12133 }
12134 }
12135 Err(ErrorContext::new_missing(
12136 "LinkinfoGre6Attrs",
12137 "Fwmark",
12138 self.orig_loc,
12139 self.buf.as_ptr() as usize,
12140 ))
12141 }
12142 pub fn get_erspan_index(&self) -> Result<u32, ErrorContext> {
12143 let mut iter = self.clone();
12144 iter.pos = 0;
12145 for attr in iter {
12146 if let Ok(LinkinfoGre6Attrs::ErspanIndex(val)) = attr {
12147 return Ok(val);
12148 }
12149 }
12150 Err(ErrorContext::new_missing(
12151 "LinkinfoGre6Attrs",
12152 "ErspanIndex",
12153 self.orig_loc,
12154 self.buf.as_ptr() as usize,
12155 ))
12156 }
12157 pub fn get_erspan_ver(&self) -> Result<u8, ErrorContext> {
12158 let mut iter = self.clone();
12159 iter.pos = 0;
12160 for attr in iter {
12161 if let Ok(LinkinfoGre6Attrs::ErspanVer(val)) = attr {
12162 return Ok(val);
12163 }
12164 }
12165 Err(ErrorContext::new_missing(
12166 "LinkinfoGre6Attrs",
12167 "ErspanVer",
12168 self.orig_loc,
12169 self.buf.as_ptr() as usize,
12170 ))
12171 }
12172 pub fn get_erspan_dir(&self) -> Result<u8, ErrorContext> {
12173 let mut iter = self.clone();
12174 iter.pos = 0;
12175 for attr in iter {
12176 if let Ok(LinkinfoGre6Attrs::ErspanDir(val)) = attr {
12177 return Ok(val);
12178 }
12179 }
12180 Err(ErrorContext::new_missing(
12181 "LinkinfoGre6Attrs",
12182 "ErspanDir",
12183 self.orig_loc,
12184 self.buf.as_ptr() as usize,
12185 ))
12186 }
12187 pub fn get_erspan_hwid(&self) -> Result<u16, ErrorContext> {
12188 let mut iter = self.clone();
12189 iter.pos = 0;
12190 for attr in iter {
12191 if let Ok(LinkinfoGre6Attrs::ErspanHwid(val)) = attr {
12192 return Ok(val);
12193 }
12194 }
12195 Err(ErrorContext::new_missing(
12196 "LinkinfoGre6Attrs",
12197 "ErspanHwid",
12198 self.orig_loc,
12199 self.buf.as_ptr() as usize,
12200 ))
12201 }
12202}
12203impl LinkinfoGre6Attrs<'_> {
12204 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoGre6Attrs<'a> {
12205 IterableLinkinfoGre6Attrs::with_loc(buf, buf.as_ptr() as usize)
12206 }
12207 fn attr_from_type(r#type: u16) -> Option<&'static str> {
12208 LinkinfoGreAttrs::attr_from_type(r#type)
12209 }
12210}
12211#[derive(Clone, Copy, Default)]
12212pub struct IterableLinkinfoGre6Attrs<'a> {
12213 buf: &'a [u8],
12214 pos: usize,
12215 orig_loc: usize,
12216}
12217impl<'a> IterableLinkinfoGre6Attrs<'a> {
12218 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
12219 Self {
12220 buf,
12221 pos: 0,
12222 orig_loc,
12223 }
12224 }
12225 pub fn get_buf(&self) -> &'a [u8] {
12226 self.buf
12227 }
12228}
12229impl<'a> Iterator for IterableLinkinfoGre6Attrs<'a> {
12230 type Item = Result<LinkinfoGre6Attrs<'a>, ErrorContext>;
12231 fn next(&mut self) -> Option<Self::Item> {
12232 let mut pos;
12233 let mut r#type;
12234 loop {
12235 pos = self.pos;
12236 r#type = None;
12237 if self.buf.len() == self.pos {
12238 return None;
12239 }
12240 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
12241 self.pos = self.buf.len();
12242 break;
12243 };
12244 r#type = Some(header.r#type);
12245 let res = match header.r#type {
12246 1u16 => LinkinfoGre6Attrs::Link({
12247 let res = parse_u32(next);
12248 let Some(val) = res else { break };
12249 val
12250 }),
12251 2u16 => LinkinfoGre6Attrs::Iflags({
12252 let res = parse_be_u16(next);
12253 let Some(val) = res else { break };
12254 val
12255 }),
12256 3u16 => LinkinfoGre6Attrs::Oflags({
12257 let res = parse_be_u16(next);
12258 let Some(val) = res else { break };
12259 val
12260 }),
12261 4u16 => LinkinfoGre6Attrs::Ikey({
12262 let res = parse_be_u32(next);
12263 let Some(val) = res else { break };
12264 val
12265 }),
12266 5u16 => LinkinfoGre6Attrs::Okey({
12267 let res = parse_be_u32(next);
12268 let Some(val) = res else { break };
12269 val
12270 }),
12271 6u16 => LinkinfoGre6Attrs::Local({
12272 let res = Some(next);
12273 let Some(val) = res else { break };
12274 val
12275 }),
12276 7u16 => LinkinfoGre6Attrs::Remote({
12277 let res = Some(next);
12278 let Some(val) = res else { break };
12279 val
12280 }),
12281 8u16 => LinkinfoGre6Attrs::Ttl({
12282 let res = parse_u8(next);
12283 let Some(val) = res else { break };
12284 val
12285 }),
12286 11u16 => LinkinfoGre6Attrs::EncapLimit({
12287 let res = parse_u8(next);
12288 let Some(val) = res else { break };
12289 val
12290 }),
12291 12u16 => LinkinfoGre6Attrs::Flowinfo({
12292 let res = parse_be_u32(next);
12293 let Some(val) = res else { break };
12294 val
12295 }),
12296 13u16 => LinkinfoGre6Attrs::Flags({
12297 let res = parse_u32(next);
12298 let Some(val) = res else { break };
12299 val
12300 }),
12301 14u16 => LinkinfoGre6Attrs::EncapType({
12302 let res = parse_u16(next);
12303 let Some(val) = res else { break };
12304 val
12305 }),
12306 15u16 => LinkinfoGre6Attrs::EncapFlags({
12307 let res = parse_u16(next);
12308 let Some(val) = res else { break };
12309 val
12310 }),
12311 16u16 => LinkinfoGre6Attrs::EncapSport({
12312 let res = parse_be_u16(next);
12313 let Some(val) = res else { break };
12314 val
12315 }),
12316 17u16 => LinkinfoGre6Attrs::EncapDport({
12317 let res = parse_be_u16(next);
12318 let Some(val) = res else { break };
12319 val
12320 }),
12321 18u16 => LinkinfoGre6Attrs::CollectMetadata(()),
12322 20u16 => LinkinfoGre6Attrs::Fwmark({
12323 let res = parse_u32(next);
12324 let Some(val) = res else { break };
12325 val
12326 }),
12327 21u16 => LinkinfoGre6Attrs::ErspanIndex({
12328 let res = parse_u32(next);
12329 let Some(val) = res else { break };
12330 val
12331 }),
12332 22u16 => LinkinfoGre6Attrs::ErspanVer({
12333 let res = parse_u8(next);
12334 let Some(val) = res else { break };
12335 val
12336 }),
12337 23u16 => LinkinfoGre6Attrs::ErspanDir({
12338 let res = parse_u8(next);
12339 let Some(val) = res else { break };
12340 val
12341 }),
12342 24u16 => LinkinfoGre6Attrs::ErspanHwid({
12343 let res = parse_u16(next);
12344 let Some(val) = res else { break };
12345 val
12346 }),
12347 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
12348 n => continue,
12349 };
12350 return Some(Ok(res));
12351 }
12352 Some(Err(ErrorContext::new(
12353 "LinkinfoGre6Attrs",
12354 r#type.and_then(|t| LinkinfoGre6Attrs::attr_from_type(t)),
12355 self.orig_loc,
12356 self.buf.as_ptr().wrapping_add(pos) as usize,
12357 )))
12358 }
12359}
12360impl<'a> std::fmt::Debug for IterableLinkinfoGre6Attrs<'_> {
12361 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12362 let mut fmt = f.debug_struct("LinkinfoGre6Attrs");
12363 for attr in self.clone() {
12364 let attr = match attr {
12365 Ok(a) => a,
12366 Err(err) => {
12367 fmt.finish()?;
12368 f.write_str("Err(")?;
12369 err.fmt(f)?;
12370 return f.write_str(")");
12371 }
12372 };
12373 match attr {
12374 LinkinfoGre6Attrs::Link(val) => fmt.field("Link", &val),
12375 LinkinfoGre6Attrs::Iflags(val) => fmt.field("Iflags", &val),
12376 LinkinfoGre6Attrs::Oflags(val) => fmt.field("Oflags", &val),
12377 LinkinfoGre6Attrs::Ikey(val) => fmt.field("Ikey", &val),
12378 LinkinfoGre6Attrs::Okey(val) => fmt.field("Okey", &val),
12379 LinkinfoGre6Attrs::Local(val) => fmt.field("Local", &val),
12380 LinkinfoGre6Attrs::Remote(val) => fmt.field("Remote", &val),
12381 LinkinfoGre6Attrs::Ttl(val) => fmt.field("Ttl", &val),
12382 LinkinfoGre6Attrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
12383 LinkinfoGre6Attrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
12384 LinkinfoGre6Attrs::Flags(val) => fmt.field("Flags", &val),
12385 LinkinfoGre6Attrs::EncapType(val) => fmt.field("EncapType", &val),
12386 LinkinfoGre6Attrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
12387 LinkinfoGre6Attrs::EncapSport(val) => fmt.field("EncapSport", &val),
12388 LinkinfoGre6Attrs::EncapDport(val) => fmt.field("EncapDport", &val),
12389 LinkinfoGre6Attrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
12390 LinkinfoGre6Attrs::Fwmark(val) => fmt.field("Fwmark", &val),
12391 LinkinfoGre6Attrs::ErspanIndex(val) => fmt.field("ErspanIndex", &val),
12392 LinkinfoGre6Attrs::ErspanVer(val) => fmt.field("ErspanVer", &val),
12393 LinkinfoGre6Attrs::ErspanDir(val) => fmt.field("ErspanDir", &val),
12394 LinkinfoGre6Attrs::ErspanHwid(val) => fmt.field("ErspanHwid", &val),
12395 };
12396 }
12397 fmt.finish()
12398 }
12399}
12400impl IterableLinkinfoGre6Attrs<'_> {
12401 pub fn lookup_attr(
12402 &self,
12403 offset: usize,
12404 missing_type: Option<u16>,
12405 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
12406 let mut stack = Vec::new();
12407 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
12408 if missing_type.is_some() && cur == offset {
12409 stack.push(("LinkinfoGre6Attrs", offset));
12410 return (
12411 stack,
12412 missing_type.and_then(|t| LinkinfoGre6Attrs::attr_from_type(t)),
12413 );
12414 }
12415 if cur > offset || cur + self.buf.len() < offset {
12416 return (stack, None);
12417 }
12418 let mut attrs = self.clone();
12419 let mut last_off = cur + attrs.pos;
12420 while let Some(attr) = attrs.next() {
12421 let Ok(attr) = attr else { break };
12422 match attr {
12423 LinkinfoGre6Attrs::Link(val) => {
12424 if last_off == offset {
12425 stack.push(("Link", last_off));
12426 break;
12427 }
12428 }
12429 LinkinfoGre6Attrs::Iflags(val) => {
12430 if last_off == offset {
12431 stack.push(("Iflags", last_off));
12432 break;
12433 }
12434 }
12435 LinkinfoGre6Attrs::Oflags(val) => {
12436 if last_off == offset {
12437 stack.push(("Oflags", last_off));
12438 break;
12439 }
12440 }
12441 LinkinfoGre6Attrs::Ikey(val) => {
12442 if last_off == offset {
12443 stack.push(("Ikey", last_off));
12444 break;
12445 }
12446 }
12447 LinkinfoGre6Attrs::Okey(val) => {
12448 if last_off == offset {
12449 stack.push(("Okey", last_off));
12450 break;
12451 }
12452 }
12453 LinkinfoGre6Attrs::Local(val) => {
12454 if last_off == offset {
12455 stack.push(("Local", last_off));
12456 break;
12457 }
12458 }
12459 LinkinfoGre6Attrs::Remote(val) => {
12460 if last_off == offset {
12461 stack.push(("Remote", last_off));
12462 break;
12463 }
12464 }
12465 LinkinfoGre6Attrs::Ttl(val) => {
12466 if last_off == offset {
12467 stack.push(("Ttl", last_off));
12468 break;
12469 }
12470 }
12471 LinkinfoGre6Attrs::EncapLimit(val) => {
12472 if last_off == offset {
12473 stack.push(("EncapLimit", last_off));
12474 break;
12475 }
12476 }
12477 LinkinfoGre6Attrs::Flowinfo(val) => {
12478 if last_off == offset {
12479 stack.push(("Flowinfo", last_off));
12480 break;
12481 }
12482 }
12483 LinkinfoGre6Attrs::Flags(val) => {
12484 if last_off == offset {
12485 stack.push(("Flags", last_off));
12486 break;
12487 }
12488 }
12489 LinkinfoGre6Attrs::EncapType(val) => {
12490 if last_off == offset {
12491 stack.push(("EncapType", last_off));
12492 break;
12493 }
12494 }
12495 LinkinfoGre6Attrs::EncapFlags(val) => {
12496 if last_off == offset {
12497 stack.push(("EncapFlags", last_off));
12498 break;
12499 }
12500 }
12501 LinkinfoGre6Attrs::EncapSport(val) => {
12502 if last_off == offset {
12503 stack.push(("EncapSport", last_off));
12504 break;
12505 }
12506 }
12507 LinkinfoGre6Attrs::EncapDport(val) => {
12508 if last_off == offset {
12509 stack.push(("EncapDport", last_off));
12510 break;
12511 }
12512 }
12513 LinkinfoGre6Attrs::CollectMetadata(val) => {
12514 if last_off == offset {
12515 stack.push(("CollectMetadata", last_off));
12516 break;
12517 }
12518 }
12519 LinkinfoGre6Attrs::Fwmark(val) => {
12520 if last_off == offset {
12521 stack.push(("Fwmark", last_off));
12522 break;
12523 }
12524 }
12525 LinkinfoGre6Attrs::ErspanIndex(val) => {
12526 if last_off == offset {
12527 stack.push(("ErspanIndex", last_off));
12528 break;
12529 }
12530 }
12531 LinkinfoGre6Attrs::ErspanVer(val) => {
12532 if last_off == offset {
12533 stack.push(("ErspanVer", last_off));
12534 break;
12535 }
12536 }
12537 LinkinfoGre6Attrs::ErspanDir(val) => {
12538 if last_off == offset {
12539 stack.push(("ErspanDir", last_off));
12540 break;
12541 }
12542 }
12543 LinkinfoGre6Attrs::ErspanHwid(val) => {
12544 if last_off == offset {
12545 stack.push(("ErspanHwid", last_off));
12546 break;
12547 }
12548 }
12549 _ => {}
12550 };
12551 last_off = cur + attrs.pos;
12552 }
12553 if !stack.is_empty() {
12554 stack.push(("LinkinfoGre6Attrs", cur));
12555 }
12556 (stack, None)
12557 }
12558}
12559#[derive(Clone)]
12560pub enum LinkinfoVtiAttrs {
12561 Link(u32),
12562 Ikey(u32),
12563 Okey(u32),
12564 Local(std::net::IpAddr),
12565 Remote(std::net::IpAddr),
12566 Fwmark(u32),
12567}
12568impl<'a> IterableLinkinfoVtiAttrs<'a> {
12569 pub fn get_link(&self) -> Result<u32, ErrorContext> {
12570 let mut iter = self.clone();
12571 iter.pos = 0;
12572 for attr in iter {
12573 if let Ok(LinkinfoVtiAttrs::Link(val)) = attr {
12574 return Ok(val);
12575 }
12576 }
12577 Err(ErrorContext::new_missing(
12578 "LinkinfoVtiAttrs",
12579 "Link",
12580 self.orig_loc,
12581 self.buf.as_ptr() as usize,
12582 ))
12583 }
12584 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
12585 let mut iter = self.clone();
12586 iter.pos = 0;
12587 for attr in iter {
12588 if let Ok(LinkinfoVtiAttrs::Ikey(val)) = attr {
12589 return Ok(val);
12590 }
12591 }
12592 Err(ErrorContext::new_missing(
12593 "LinkinfoVtiAttrs",
12594 "Ikey",
12595 self.orig_loc,
12596 self.buf.as_ptr() as usize,
12597 ))
12598 }
12599 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
12600 let mut iter = self.clone();
12601 iter.pos = 0;
12602 for attr in iter {
12603 if let Ok(LinkinfoVtiAttrs::Okey(val)) = attr {
12604 return Ok(val);
12605 }
12606 }
12607 Err(ErrorContext::new_missing(
12608 "LinkinfoVtiAttrs",
12609 "Okey",
12610 self.orig_loc,
12611 self.buf.as_ptr() as usize,
12612 ))
12613 }
12614 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
12615 let mut iter = self.clone();
12616 iter.pos = 0;
12617 for attr in iter {
12618 if let Ok(LinkinfoVtiAttrs::Local(val)) = attr {
12619 return Ok(val);
12620 }
12621 }
12622 Err(ErrorContext::new_missing(
12623 "LinkinfoVtiAttrs",
12624 "Local",
12625 self.orig_loc,
12626 self.buf.as_ptr() as usize,
12627 ))
12628 }
12629 pub fn get_remote(&self) -> Result<std::net::IpAddr, ErrorContext> {
12630 let mut iter = self.clone();
12631 iter.pos = 0;
12632 for attr in iter {
12633 if let Ok(LinkinfoVtiAttrs::Remote(val)) = attr {
12634 return Ok(val);
12635 }
12636 }
12637 Err(ErrorContext::new_missing(
12638 "LinkinfoVtiAttrs",
12639 "Remote",
12640 self.orig_loc,
12641 self.buf.as_ptr() as usize,
12642 ))
12643 }
12644 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
12645 let mut iter = self.clone();
12646 iter.pos = 0;
12647 for attr in iter {
12648 if let Ok(LinkinfoVtiAttrs::Fwmark(val)) = attr {
12649 return Ok(val);
12650 }
12651 }
12652 Err(ErrorContext::new_missing(
12653 "LinkinfoVtiAttrs",
12654 "Fwmark",
12655 self.orig_loc,
12656 self.buf.as_ptr() as usize,
12657 ))
12658 }
12659}
12660impl LinkinfoVtiAttrs {
12661 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVtiAttrs<'a> {
12662 IterableLinkinfoVtiAttrs::with_loc(buf, buf.as_ptr() as usize)
12663 }
12664 fn attr_from_type(r#type: u16) -> Option<&'static str> {
12665 let res = match r#type {
12666 1u16 => "Link",
12667 2u16 => "Ikey",
12668 3u16 => "Okey",
12669 4u16 => "Local",
12670 5u16 => "Remote",
12671 6u16 => "Fwmark",
12672 _ => return None,
12673 };
12674 Some(res)
12675 }
12676}
12677#[derive(Clone, Copy, Default)]
12678pub struct IterableLinkinfoVtiAttrs<'a> {
12679 buf: &'a [u8],
12680 pos: usize,
12681 orig_loc: usize,
12682}
12683impl<'a> IterableLinkinfoVtiAttrs<'a> {
12684 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
12685 Self {
12686 buf,
12687 pos: 0,
12688 orig_loc,
12689 }
12690 }
12691 pub fn get_buf(&self) -> &'a [u8] {
12692 self.buf
12693 }
12694}
12695impl<'a> Iterator for IterableLinkinfoVtiAttrs<'a> {
12696 type Item = Result<LinkinfoVtiAttrs, ErrorContext>;
12697 fn next(&mut self) -> Option<Self::Item> {
12698 let mut pos;
12699 let mut r#type;
12700 loop {
12701 pos = self.pos;
12702 r#type = None;
12703 if self.buf.len() == self.pos {
12704 return None;
12705 }
12706 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
12707 self.pos = self.buf.len();
12708 break;
12709 };
12710 r#type = Some(header.r#type);
12711 let res = match header.r#type {
12712 1u16 => LinkinfoVtiAttrs::Link({
12713 let res = parse_u32(next);
12714 let Some(val) = res else { break };
12715 val
12716 }),
12717 2u16 => LinkinfoVtiAttrs::Ikey({
12718 let res = parse_be_u32(next);
12719 let Some(val) = res else { break };
12720 val
12721 }),
12722 3u16 => LinkinfoVtiAttrs::Okey({
12723 let res = parse_be_u32(next);
12724 let Some(val) = res else { break };
12725 val
12726 }),
12727 4u16 => LinkinfoVtiAttrs::Local({
12728 let res = parse_ip(next);
12729 let Some(val) = res else { break };
12730 val
12731 }),
12732 5u16 => LinkinfoVtiAttrs::Remote({
12733 let res = parse_ip(next);
12734 let Some(val) = res else { break };
12735 val
12736 }),
12737 6u16 => LinkinfoVtiAttrs::Fwmark({
12738 let res = parse_u32(next);
12739 let Some(val) = res else { break };
12740 val
12741 }),
12742 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
12743 n => continue,
12744 };
12745 return Some(Ok(res));
12746 }
12747 Some(Err(ErrorContext::new(
12748 "LinkinfoVtiAttrs",
12749 r#type.and_then(|t| LinkinfoVtiAttrs::attr_from_type(t)),
12750 self.orig_loc,
12751 self.buf.as_ptr().wrapping_add(pos) as usize,
12752 )))
12753 }
12754}
12755impl std::fmt::Debug for IterableLinkinfoVtiAttrs<'_> {
12756 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12757 let mut fmt = f.debug_struct("LinkinfoVtiAttrs");
12758 for attr in self.clone() {
12759 let attr = match attr {
12760 Ok(a) => a,
12761 Err(err) => {
12762 fmt.finish()?;
12763 f.write_str("Err(")?;
12764 err.fmt(f)?;
12765 return f.write_str(")");
12766 }
12767 };
12768 match attr {
12769 LinkinfoVtiAttrs::Link(val) => fmt.field("Link", &val),
12770 LinkinfoVtiAttrs::Ikey(val) => fmt.field("Ikey", &val),
12771 LinkinfoVtiAttrs::Okey(val) => fmt.field("Okey", &val),
12772 LinkinfoVtiAttrs::Local(val) => fmt.field("Local", &val),
12773 LinkinfoVtiAttrs::Remote(val) => fmt.field("Remote", &val),
12774 LinkinfoVtiAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
12775 };
12776 }
12777 fmt.finish()
12778 }
12779}
12780impl IterableLinkinfoVtiAttrs<'_> {
12781 pub fn lookup_attr(
12782 &self,
12783 offset: usize,
12784 missing_type: Option<u16>,
12785 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
12786 let mut stack = Vec::new();
12787 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
12788 if missing_type.is_some() && cur == offset {
12789 stack.push(("LinkinfoVtiAttrs", offset));
12790 return (
12791 stack,
12792 missing_type.and_then(|t| LinkinfoVtiAttrs::attr_from_type(t)),
12793 );
12794 }
12795 if cur > offset || cur + self.buf.len() < offset {
12796 return (stack, None);
12797 }
12798 let mut attrs = self.clone();
12799 let mut last_off = cur + attrs.pos;
12800 while let Some(attr) = attrs.next() {
12801 let Ok(attr) = attr else { break };
12802 match attr {
12803 LinkinfoVtiAttrs::Link(val) => {
12804 if last_off == offset {
12805 stack.push(("Link", last_off));
12806 break;
12807 }
12808 }
12809 LinkinfoVtiAttrs::Ikey(val) => {
12810 if last_off == offset {
12811 stack.push(("Ikey", last_off));
12812 break;
12813 }
12814 }
12815 LinkinfoVtiAttrs::Okey(val) => {
12816 if last_off == offset {
12817 stack.push(("Okey", last_off));
12818 break;
12819 }
12820 }
12821 LinkinfoVtiAttrs::Local(val) => {
12822 if last_off == offset {
12823 stack.push(("Local", last_off));
12824 break;
12825 }
12826 }
12827 LinkinfoVtiAttrs::Remote(val) => {
12828 if last_off == offset {
12829 stack.push(("Remote", last_off));
12830 break;
12831 }
12832 }
12833 LinkinfoVtiAttrs::Fwmark(val) => {
12834 if last_off == offset {
12835 stack.push(("Fwmark", last_off));
12836 break;
12837 }
12838 }
12839 _ => {}
12840 };
12841 last_off = cur + attrs.pos;
12842 }
12843 if !stack.is_empty() {
12844 stack.push(("LinkinfoVtiAttrs", cur));
12845 }
12846 (stack, None)
12847 }
12848}
12849#[derive(Clone)]
12850pub enum LinkinfoVti6Attrs<'a> {
12851 Link(u32),
12852 Ikey(u32),
12853 Okey(u32),
12854 Local(&'a [u8]),
12855 Remote(&'a [u8]),
12856 Fwmark(u32),
12857}
12858impl<'a> IterableLinkinfoVti6Attrs<'a> {
12859 pub fn get_link(&self) -> Result<u32, ErrorContext> {
12860 let mut iter = self.clone();
12861 iter.pos = 0;
12862 for attr in iter {
12863 if let Ok(LinkinfoVti6Attrs::Link(val)) = attr {
12864 return Ok(val);
12865 }
12866 }
12867 Err(ErrorContext::new_missing(
12868 "LinkinfoVti6Attrs",
12869 "Link",
12870 self.orig_loc,
12871 self.buf.as_ptr() as usize,
12872 ))
12873 }
12874 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
12875 let mut iter = self.clone();
12876 iter.pos = 0;
12877 for attr in iter {
12878 if let Ok(LinkinfoVti6Attrs::Ikey(val)) = attr {
12879 return Ok(val);
12880 }
12881 }
12882 Err(ErrorContext::new_missing(
12883 "LinkinfoVti6Attrs",
12884 "Ikey",
12885 self.orig_loc,
12886 self.buf.as_ptr() as usize,
12887 ))
12888 }
12889 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
12890 let mut iter = self.clone();
12891 iter.pos = 0;
12892 for attr in iter {
12893 if let Ok(LinkinfoVti6Attrs::Okey(val)) = attr {
12894 return Ok(val);
12895 }
12896 }
12897 Err(ErrorContext::new_missing(
12898 "LinkinfoVti6Attrs",
12899 "Okey",
12900 self.orig_loc,
12901 self.buf.as_ptr() as usize,
12902 ))
12903 }
12904 pub fn get_local(&self) -> Result<&'a [u8], ErrorContext> {
12905 let mut iter = self.clone();
12906 iter.pos = 0;
12907 for attr in iter {
12908 if let Ok(LinkinfoVti6Attrs::Local(val)) = attr {
12909 return Ok(val);
12910 }
12911 }
12912 Err(ErrorContext::new_missing(
12913 "LinkinfoVti6Attrs",
12914 "Local",
12915 self.orig_loc,
12916 self.buf.as_ptr() as usize,
12917 ))
12918 }
12919 pub fn get_remote(&self) -> Result<&'a [u8], ErrorContext> {
12920 let mut iter = self.clone();
12921 iter.pos = 0;
12922 for attr in iter {
12923 if let Ok(LinkinfoVti6Attrs::Remote(val)) = attr {
12924 return Ok(val);
12925 }
12926 }
12927 Err(ErrorContext::new_missing(
12928 "LinkinfoVti6Attrs",
12929 "Remote",
12930 self.orig_loc,
12931 self.buf.as_ptr() as usize,
12932 ))
12933 }
12934 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
12935 let mut iter = self.clone();
12936 iter.pos = 0;
12937 for attr in iter {
12938 if let Ok(LinkinfoVti6Attrs::Fwmark(val)) = attr {
12939 return Ok(val);
12940 }
12941 }
12942 Err(ErrorContext::new_missing(
12943 "LinkinfoVti6Attrs",
12944 "Fwmark",
12945 self.orig_loc,
12946 self.buf.as_ptr() as usize,
12947 ))
12948 }
12949}
12950impl LinkinfoVti6Attrs<'_> {
12951 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVti6Attrs<'a> {
12952 IterableLinkinfoVti6Attrs::with_loc(buf, buf.as_ptr() as usize)
12953 }
12954 fn attr_from_type(r#type: u16) -> Option<&'static str> {
12955 LinkinfoVtiAttrs::attr_from_type(r#type)
12956 }
12957}
12958#[derive(Clone, Copy, Default)]
12959pub struct IterableLinkinfoVti6Attrs<'a> {
12960 buf: &'a [u8],
12961 pos: usize,
12962 orig_loc: usize,
12963}
12964impl<'a> IterableLinkinfoVti6Attrs<'a> {
12965 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
12966 Self {
12967 buf,
12968 pos: 0,
12969 orig_loc,
12970 }
12971 }
12972 pub fn get_buf(&self) -> &'a [u8] {
12973 self.buf
12974 }
12975}
12976impl<'a> Iterator for IterableLinkinfoVti6Attrs<'a> {
12977 type Item = Result<LinkinfoVti6Attrs<'a>, ErrorContext>;
12978 fn next(&mut self) -> Option<Self::Item> {
12979 let mut pos;
12980 let mut r#type;
12981 loop {
12982 pos = self.pos;
12983 r#type = None;
12984 if self.buf.len() == self.pos {
12985 return None;
12986 }
12987 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
12988 self.pos = self.buf.len();
12989 break;
12990 };
12991 r#type = Some(header.r#type);
12992 let res = match header.r#type {
12993 1u16 => LinkinfoVti6Attrs::Link({
12994 let res = parse_u32(next);
12995 let Some(val) = res else { break };
12996 val
12997 }),
12998 2u16 => LinkinfoVti6Attrs::Ikey({
12999 let res = parse_be_u32(next);
13000 let Some(val) = res else { break };
13001 val
13002 }),
13003 3u16 => LinkinfoVti6Attrs::Okey({
13004 let res = parse_be_u32(next);
13005 let Some(val) = res else { break };
13006 val
13007 }),
13008 4u16 => LinkinfoVti6Attrs::Local({
13009 let res = Some(next);
13010 let Some(val) = res else { break };
13011 val
13012 }),
13013 5u16 => LinkinfoVti6Attrs::Remote({
13014 let res = Some(next);
13015 let Some(val) = res else { break };
13016 val
13017 }),
13018 6u16 => LinkinfoVti6Attrs::Fwmark({
13019 let res = parse_u32(next);
13020 let Some(val) = res else { break };
13021 val
13022 }),
13023 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
13024 n => continue,
13025 };
13026 return Some(Ok(res));
13027 }
13028 Some(Err(ErrorContext::new(
13029 "LinkinfoVti6Attrs",
13030 r#type.and_then(|t| LinkinfoVti6Attrs::attr_from_type(t)),
13031 self.orig_loc,
13032 self.buf.as_ptr().wrapping_add(pos) as usize,
13033 )))
13034 }
13035}
13036impl<'a> std::fmt::Debug for IterableLinkinfoVti6Attrs<'_> {
13037 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13038 let mut fmt = f.debug_struct("LinkinfoVti6Attrs");
13039 for attr in self.clone() {
13040 let attr = match attr {
13041 Ok(a) => a,
13042 Err(err) => {
13043 fmt.finish()?;
13044 f.write_str("Err(")?;
13045 err.fmt(f)?;
13046 return f.write_str(")");
13047 }
13048 };
13049 match attr {
13050 LinkinfoVti6Attrs::Link(val) => fmt.field("Link", &val),
13051 LinkinfoVti6Attrs::Ikey(val) => fmt.field("Ikey", &val),
13052 LinkinfoVti6Attrs::Okey(val) => fmt.field("Okey", &val),
13053 LinkinfoVti6Attrs::Local(val) => fmt.field("Local", &val),
13054 LinkinfoVti6Attrs::Remote(val) => fmt.field("Remote", &val),
13055 LinkinfoVti6Attrs::Fwmark(val) => fmt.field("Fwmark", &val),
13056 };
13057 }
13058 fmt.finish()
13059 }
13060}
13061impl IterableLinkinfoVti6Attrs<'_> {
13062 pub fn lookup_attr(
13063 &self,
13064 offset: usize,
13065 missing_type: Option<u16>,
13066 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
13067 let mut stack = Vec::new();
13068 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
13069 if missing_type.is_some() && cur == offset {
13070 stack.push(("LinkinfoVti6Attrs", offset));
13071 return (
13072 stack,
13073 missing_type.and_then(|t| LinkinfoVti6Attrs::attr_from_type(t)),
13074 );
13075 }
13076 if cur > offset || cur + self.buf.len() < offset {
13077 return (stack, None);
13078 }
13079 let mut attrs = self.clone();
13080 let mut last_off = cur + attrs.pos;
13081 while let Some(attr) = attrs.next() {
13082 let Ok(attr) = attr else { break };
13083 match attr {
13084 LinkinfoVti6Attrs::Link(val) => {
13085 if last_off == offset {
13086 stack.push(("Link", last_off));
13087 break;
13088 }
13089 }
13090 LinkinfoVti6Attrs::Ikey(val) => {
13091 if last_off == offset {
13092 stack.push(("Ikey", last_off));
13093 break;
13094 }
13095 }
13096 LinkinfoVti6Attrs::Okey(val) => {
13097 if last_off == offset {
13098 stack.push(("Okey", last_off));
13099 break;
13100 }
13101 }
13102 LinkinfoVti6Attrs::Local(val) => {
13103 if last_off == offset {
13104 stack.push(("Local", last_off));
13105 break;
13106 }
13107 }
13108 LinkinfoVti6Attrs::Remote(val) => {
13109 if last_off == offset {
13110 stack.push(("Remote", last_off));
13111 break;
13112 }
13113 }
13114 LinkinfoVti6Attrs::Fwmark(val) => {
13115 if last_off == offset {
13116 stack.push(("Fwmark", last_off));
13117 break;
13118 }
13119 }
13120 _ => {}
13121 };
13122 last_off = cur + attrs.pos;
13123 }
13124 if !stack.is_empty() {
13125 stack.push(("LinkinfoVti6Attrs", cur));
13126 }
13127 (stack, None)
13128 }
13129}
13130#[derive(Clone)]
13131pub enum LinkinfoGeneveAttrs<'a> {
13132 Id(u32),
13133 Remote(std::net::Ipv4Addr),
13134 Ttl(u8),
13135 Tos(u8),
13136 Port(u16),
13137 CollectMetadata(()),
13138 Remote6(&'a [u8]),
13139 UdpCsum(u8),
13140 UdpZeroCsum6Tx(u8),
13141 UdpZeroCsum6Rx(u8),
13142 Label(u32),
13143 TtlInherit(u8),
13144 Df(u8),
13145 InnerProtoInherit(()),
13146 PortRange(IflaGenevePortRange),
13147 GroHint(()),
13148}
13149impl<'a> IterableLinkinfoGeneveAttrs<'a> {
13150 pub fn get_id(&self) -> Result<u32, ErrorContext> {
13151 let mut iter = self.clone();
13152 iter.pos = 0;
13153 for attr in iter {
13154 if let Ok(LinkinfoGeneveAttrs::Id(val)) = attr {
13155 return Ok(val);
13156 }
13157 }
13158 Err(ErrorContext::new_missing(
13159 "LinkinfoGeneveAttrs",
13160 "Id",
13161 self.orig_loc,
13162 self.buf.as_ptr() as usize,
13163 ))
13164 }
13165 pub fn get_remote(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
13166 let mut iter = self.clone();
13167 iter.pos = 0;
13168 for attr in iter {
13169 if let Ok(LinkinfoGeneveAttrs::Remote(val)) = attr {
13170 return Ok(val);
13171 }
13172 }
13173 Err(ErrorContext::new_missing(
13174 "LinkinfoGeneveAttrs",
13175 "Remote",
13176 self.orig_loc,
13177 self.buf.as_ptr() as usize,
13178 ))
13179 }
13180 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
13181 let mut iter = self.clone();
13182 iter.pos = 0;
13183 for attr in iter {
13184 if let Ok(LinkinfoGeneveAttrs::Ttl(val)) = attr {
13185 return Ok(val);
13186 }
13187 }
13188 Err(ErrorContext::new_missing(
13189 "LinkinfoGeneveAttrs",
13190 "Ttl",
13191 self.orig_loc,
13192 self.buf.as_ptr() as usize,
13193 ))
13194 }
13195 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
13196 let mut iter = self.clone();
13197 iter.pos = 0;
13198 for attr in iter {
13199 if let Ok(LinkinfoGeneveAttrs::Tos(val)) = attr {
13200 return Ok(val);
13201 }
13202 }
13203 Err(ErrorContext::new_missing(
13204 "LinkinfoGeneveAttrs",
13205 "Tos",
13206 self.orig_loc,
13207 self.buf.as_ptr() as usize,
13208 ))
13209 }
13210 pub fn get_port(&self) -> Result<u16, ErrorContext> {
13211 let mut iter = self.clone();
13212 iter.pos = 0;
13213 for attr in iter {
13214 if let Ok(LinkinfoGeneveAttrs::Port(val)) = attr {
13215 return Ok(val);
13216 }
13217 }
13218 Err(ErrorContext::new_missing(
13219 "LinkinfoGeneveAttrs",
13220 "Port",
13221 self.orig_loc,
13222 self.buf.as_ptr() as usize,
13223 ))
13224 }
13225 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
13226 let mut iter = self.clone();
13227 iter.pos = 0;
13228 for attr in iter {
13229 if let Ok(LinkinfoGeneveAttrs::CollectMetadata(val)) = attr {
13230 return Ok(val);
13231 }
13232 }
13233 Err(ErrorContext::new_missing(
13234 "LinkinfoGeneveAttrs",
13235 "CollectMetadata",
13236 self.orig_loc,
13237 self.buf.as_ptr() as usize,
13238 ))
13239 }
13240 pub fn get_remote6(&self) -> Result<&'a [u8], ErrorContext> {
13241 let mut iter = self.clone();
13242 iter.pos = 0;
13243 for attr in iter {
13244 if let Ok(LinkinfoGeneveAttrs::Remote6(val)) = attr {
13245 return Ok(val);
13246 }
13247 }
13248 Err(ErrorContext::new_missing(
13249 "LinkinfoGeneveAttrs",
13250 "Remote6",
13251 self.orig_loc,
13252 self.buf.as_ptr() as usize,
13253 ))
13254 }
13255 pub fn get_udp_csum(&self) -> Result<u8, ErrorContext> {
13256 let mut iter = self.clone();
13257 iter.pos = 0;
13258 for attr in iter {
13259 if let Ok(LinkinfoGeneveAttrs::UdpCsum(val)) = attr {
13260 return Ok(val);
13261 }
13262 }
13263 Err(ErrorContext::new_missing(
13264 "LinkinfoGeneveAttrs",
13265 "UdpCsum",
13266 self.orig_loc,
13267 self.buf.as_ptr() as usize,
13268 ))
13269 }
13270 pub fn get_udp_zero_csum6_tx(&self) -> Result<u8, ErrorContext> {
13271 let mut iter = self.clone();
13272 iter.pos = 0;
13273 for attr in iter {
13274 if let Ok(LinkinfoGeneveAttrs::UdpZeroCsum6Tx(val)) = attr {
13275 return Ok(val);
13276 }
13277 }
13278 Err(ErrorContext::new_missing(
13279 "LinkinfoGeneveAttrs",
13280 "UdpZeroCsum6Tx",
13281 self.orig_loc,
13282 self.buf.as_ptr() as usize,
13283 ))
13284 }
13285 pub fn get_udp_zero_csum6_rx(&self) -> Result<u8, ErrorContext> {
13286 let mut iter = self.clone();
13287 iter.pos = 0;
13288 for attr in iter {
13289 if let Ok(LinkinfoGeneveAttrs::UdpZeroCsum6Rx(val)) = attr {
13290 return Ok(val);
13291 }
13292 }
13293 Err(ErrorContext::new_missing(
13294 "LinkinfoGeneveAttrs",
13295 "UdpZeroCsum6Rx",
13296 self.orig_loc,
13297 self.buf.as_ptr() as usize,
13298 ))
13299 }
13300 pub fn get_label(&self) -> Result<u32, ErrorContext> {
13301 let mut iter = self.clone();
13302 iter.pos = 0;
13303 for attr in iter {
13304 if let Ok(LinkinfoGeneveAttrs::Label(val)) = attr {
13305 return Ok(val);
13306 }
13307 }
13308 Err(ErrorContext::new_missing(
13309 "LinkinfoGeneveAttrs",
13310 "Label",
13311 self.orig_loc,
13312 self.buf.as_ptr() as usize,
13313 ))
13314 }
13315 pub fn get_ttl_inherit(&self) -> Result<u8, ErrorContext> {
13316 let mut iter = self.clone();
13317 iter.pos = 0;
13318 for attr in iter {
13319 if let Ok(LinkinfoGeneveAttrs::TtlInherit(val)) = attr {
13320 return Ok(val);
13321 }
13322 }
13323 Err(ErrorContext::new_missing(
13324 "LinkinfoGeneveAttrs",
13325 "TtlInherit",
13326 self.orig_loc,
13327 self.buf.as_ptr() as usize,
13328 ))
13329 }
13330 pub fn get_df(&self) -> Result<u8, ErrorContext> {
13331 let mut iter = self.clone();
13332 iter.pos = 0;
13333 for attr in iter {
13334 if let Ok(LinkinfoGeneveAttrs::Df(val)) = attr {
13335 return Ok(val);
13336 }
13337 }
13338 Err(ErrorContext::new_missing(
13339 "LinkinfoGeneveAttrs",
13340 "Df",
13341 self.orig_loc,
13342 self.buf.as_ptr() as usize,
13343 ))
13344 }
13345 pub fn get_inner_proto_inherit(&self) -> Result<(), ErrorContext> {
13346 let mut iter = self.clone();
13347 iter.pos = 0;
13348 for attr in iter {
13349 if let Ok(LinkinfoGeneveAttrs::InnerProtoInherit(val)) = attr {
13350 return Ok(val);
13351 }
13352 }
13353 Err(ErrorContext::new_missing(
13354 "LinkinfoGeneveAttrs",
13355 "InnerProtoInherit",
13356 self.orig_loc,
13357 self.buf.as_ptr() as usize,
13358 ))
13359 }
13360 pub fn get_port_range(&self) -> Result<IflaGenevePortRange, ErrorContext> {
13361 let mut iter = self.clone();
13362 iter.pos = 0;
13363 for attr in iter {
13364 if let Ok(LinkinfoGeneveAttrs::PortRange(val)) = attr {
13365 return Ok(val);
13366 }
13367 }
13368 Err(ErrorContext::new_missing(
13369 "LinkinfoGeneveAttrs",
13370 "PortRange",
13371 self.orig_loc,
13372 self.buf.as_ptr() as usize,
13373 ))
13374 }
13375 pub fn get_gro_hint(&self) -> Result<(), ErrorContext> {
13376 let mut iter = self.clone();
13377 iter.pos = 0;
13378 for attr in iter {
13379 if let Ok(LinkinfoGeneveAttrs::GroHint(val)) = attr {
13380 return Ok(val);
13381 }
13382 }
13383 Err(ErrorContext::new_missing(
13384 "LinkinfoGeneveAttrs",
13385 "GroHint",
13386 self.orig_loc,
13387 self.buf.as_ptr() as usize,
13388 ))
13389 }
13390}
13391impl LinkinfoGeneveAttrs<'_> {
13392 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoGeneveAttrs<'a> {
13393 IterableLinkinfoGeneveAttrs::with_loc(buf, buf.as_ptr() as usize)
13394 }
13395 fn attr_from_type(r#type: u16) -> Option<&'static str> {
13396 let res = match r#type {
13397 1u16 => "Id",
13398 2u16 => "Remote",
13399 3u16 => "Ttl",
13400 4u16 => "Tos",
13401 5u16 => "Port",
13402 6u16 => "CollectMetadata",
13403 7u16 => "Remote6",
13404 8u16 => "UdpCsum",
13405 9u16 => "UdpZeroCsum6Tx",
13406 10u16 => "UdpZeroCsum6Rx",
13407 11u16 => "Label",
13408 12u16 => "TtlInherit",
13409 13u16 => "Df",
13410 14u16 => "InnerProtoInherit",
13411 15u16 => "PortRange",
13412 16u16 => "GroHint",
13413 _ => return None,
13414 };
13415 Some(res)
13416 }
13417}
13418#[derive(Clone, Copy, Default)]
13419pub struct IterableLinkinfoGeneveAttrs<'a> {
13420 buf: &'a [u8],
13421 pos: usize,
13422 orig_loc: usize,
13423}
13424impl<'a> IterableLinkinfoGeneveAttrs<'a> {
13425 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
13426 Self {
13427 buf,
13428 pos: 0,
13429 orig_loc,
13430 }
13431 }
13432 pub fn get_buf(&self) -> &'a [u8] {
13433 self.buf
13434 }
13435}
13436impl<'a> Iterator for IterableLinkinfoGeneveAttrs<'a> {
13437 type Item = Result<LinkinfoGeneveAttrs<'a>, ErrorContext>;
13438 fn next(&mut self) -> Option<Self::Item> {
13439 let mut pos;
13440 let mut r#type;
13441 loop {
13442 pos = self.pos;
13443 r#type = None;
13444 if self.buf.len() == self.pos {
13445 return None;
13446 }
13447 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
13448 self.pos = self.buf.len();
13449 break;
13450 };
13451 r#type = Some(header.r#type);
13452 let res = match header.r#type {
13453 1u16 => LinkinfoGeneveAttrs::Id({
13454 let res = parse_u32(next);
13455 let Some(val) = res else { break };
13456 val
13457 }),
13458 2u16 => LinkinfoGeneveAttrs::Remote({
13459 let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
13460 let Some(val) = res else { break };
13461 val
13462 }),
13463 3u16 => LinkinfoGeneveAttrs::Ttl({
13464 let res = parse_u8(next);
13465 let Some(val) = res else { break };
13466 val
13467 }),
13468 4u16 => LinkinfoGeneveAttrs::Tos({
13469 let res = parse_u8(next);
13470 let Some(val) = res else { break };
13471 val
13472 }),
13473 5u16 => LinkinfoGeneveAttrs::Port({
13474 let res = parse_be_u16(next);
13475 let Some(val) = res else { break };
13476 val
13477 }),
13478 6u16 => LinkinfoGeneveAttrs::CollectMetadata(()),
13479 7u16 => LinkinfoGeneveAttrs::Remote6({
13480 let res = Some(next);
13481 let Some(val) = res else { break };
13482 val
13483 }),
13484 8u16 => LinkinfoGeneveAttrs::UdpCsum({
13485 let res = parse_u8(next);
13486 let Some(val) = res else { break };
13487 val
13488 }),
13489 9u16 => LinkinfoGeneveAttrs::UdpZeroCsum6Tx({
13490 let res = parse_u8(next);
13491 let Some(val) = res else { break };
13492 val
13493 }),
13494 10u16 => LinkinfoGeneveAttrs::UdpZeroCsum6Rx({
13495 let res = parse_u8(next);
13496 let Some(val) = res else { break };
13497 val
13498 }),
13499 11u16 => LinkinfoGeneveAttrs::Label({
13500 let res = parse_be_u32(next);
13501 let Some(val) = res else { break };
13502 val
13503 }),
13504 12u16 => LinkinfoGeneveAttrs::TtlInherit({
13505 let res = parse_u8(next);
13506 let Some(val) = res else { break };
13507 val
13508 }),
13509 13u16 => LinkinfoGeneveAttrs::Df({
13510 let res = parse_u8(next);
13511 let Some(val) = res else { break };
13512 val
13513 }),
13514 14u16 => LinkinfoGeneveAttrs::InnerProtoInherit(()),
13515 15u16 => LinkinfoGeneveAttrs::PortRange({
13516 let res = Some(IflaGenevePortRange::new_from_zeroed(next));
13517 let Some(val) = res else { break };
13518 val
13519 }),
13520 16u16 => LinkinfoGeneveAttrs::GroHint(()),
13521 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
13522 n => continue,
13523 };
13524 return Some(Ok(res));
13525 }
13526 Some(Err(ErrorContext::new(
13527 "LinkinfoGeneveAttrs",
13528 r#type.and_then(|t| LinkinfoGeneveAttrs::attr_from_type(t)),
13529 self.orig_loc,
13530 self.buf.as_ptr().wrapping_add(pos) as usize,
13531 )))
13532 }
13533}
13534impl<'a> std::fmt::Debug for IterableLinkinfoGeneveAttrs<'_> {
13535 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13536 let mut fmt = f.debug_struct("LinkinfoGeneveAttrs");
13537 for attr in self.clone() {
13538 let attr = match attr {
13539 Ok(a) => a,
13540 Err(err) => {
13541 fmt.finish()?;
13542 f.write_str("Err(")?;
13543 err.fmt(f)?;
13544 return f.write_str(")");
13545 }
13546 };
13547 match attr {
13548 LinkinfoGeneveAttrs::Id(val) => fmt.field("Id", &val),
13549 LinkinfoGeneveAttrs::Remote(val) => fmt.field("Remote", &val),
13550 LinkinfoGeneveAttrs::Ttl(val) => fmt.field("Ttl", &val),
13551 LinkinfoGeneveAttrs::Tos(val) => fmt.field("Tos", &val),
13552 LinkinfoGeneveAttrs::Port(val) => fmt.field("Port", &val),
13553 LinkinfoGeneveAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
13554 LinkinfoGeneveAttrs::Remote6(val) => fmt.field("Remote6", &val),
13555 LinkinfoGeneveAttrs::UdpCsum(val) => fmt.field("UdpCsum", &val),
13556 LinkinfoGeneveAttrs::UdpZeroCsum6Tx(val) => fmt.field("UdpZeroCsum6Tx", &val),
13557 LinkinfoGeneveAttrs::UdpZeroCsum6Rx(val) => fmt.field("UdpZeroCsum6Rx", &val),
13558 LinkinfoGeneveAttrs::Label(val) => fmt.field("Label", &val),
13559 LinkinfoGeneveAttrs::TtlInherit(val) => fmt.field("TtlInherit", &val),
13560 LinkinfoGeneveAttrs::Df(val) => fmt.field("Df", &val),
13561 LinkinfoGeneveAttrs::InnerProtoInherit(val) => fmt.field("InnerProtoInherit", &val),
13562 LinkinfoGeneveAttrs::PortRange(val) => fmt.field("PortRange", &val),
13563 LinkinfoGeneveAttrs::GroHint(val) => fmt.field("GroHint", &val),
13564 };
13565 }
13566 fmt.finish()
13567 }
13568}
13569impl IterableLinkinfoGeneveAttrs<'_> {
13570 pub fn lookup_attr(
13571 &self,
13572 offset: usize,
13573 missing_type: Option<u16>,
13574 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
13575 let mut stack = Vec::new();
13576 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
13577 if missing_type.is_some() && cur == offset {
13578 stack.push(("LinkinfoGeneveAttrs", offset));
13579 return (
13580 stack,
13581 missing_type.and_then(|t| LinkinfoGeneveAttrs::attr_from_type(t)),
13582 );
13583 }
13584 if cur > offset || cur + self.buf.len() < offset {
13585 return (stack, None);
13586 }
13587 let mut attrs = self.clone();
13588 let mut last_off = cur + attrs.pos;
13589 while let Some(attr) = attrs.next() {
13590 let Ok(attr) = attr else { break };
13591 match attr {
13592 LinkinfoGeneveAttrs::Id(val) => {
13593 if last_off == offset {
13594 stack.push(("Id", last_off));
13595 break;
13596 }
13597 }
13598 LinkinfoGeneveAttrs::Remote(val) => {
13599 if last_off == offset {
13600 stack.push(("Remote", last_off));
13601 break;
13602 }
13603 }
13604 LinkinfoGeneveAttrs::Ttl(val) => {
13605 if last_off == offset {
13606 stack.push(("Ttl", last_off));
13607 break;
13608 }
13609 }
13610 LinkinfoGeneveAttrs::Tos(val) => {
13611 if last_off == offset {
13612 stack.push(("Tos", last_off));
13613 break;
13614 }
13615 }
13616 LinkinfoGeneveAttrs::Port(val) => {
13617 if last_off == offset {
13618 stack.push(("Port", last_off));
13619 break;
13620 }
13621 }
13622 LinkinfoGeneveAttrs::CollectMetadata(val) => {
13623 if last_off == offset {
13624 stack.push(("CollectMetadata", last_off));
13625 break;
13626 }
13627 }
13628 LinkinfoGeneveAttrs::Remote6(val) => {
13629 if last_off == offset {
13630 stack.push(("Remote6", last_off));
13631 break;
13632 }
13633 }
13634 LinkinfoGeneveAttrs::UdpCsum(val) => {
13635 if last_off == offset {
13636 stack.push(("UdpCsum", last_off));
13637 break;
13638 }
13639 }
13640 LinkinfoGeneveAttrs::UdpZeroCsum6Tx(val) => {
13641 if last_off == offset {
13642 stack.push(("UdpZeroCsum6Tx", last_off));
13643 break;
13644 }
13645 }
13646 LinkinfoGeneveAttrs::UdpZeroCsum6Rx(val) => {
13647 if last_off == offset {
13648 stack.push(("UdpZeroCsum6Rx", last_off));
13649 break;
13650 }
13651 }
13652 LinkinfoGeneveAttrs::Label(val) => {
13653 if last_off == offset {
13654 stack.push(("Label", last_off));
13655 break;
13656 }
13657 }
13658 LinkinfoGeneveAttrs::TtlInherit(val) => {
13659 if last_off == offset {
13660 stack.push(("TtlInherit", last_off));
13661 break;
13662 }
13663 }
13664 LinkinfoGeneveAttrs::Df(val) => {
13665 if last_off == offset {
13666 stack.push(("Df", last_off));
13667 break;
13668 }
13669 }
13670 LinkinfoGeneveAttrs::InnerProtoInherit(val) => {
13671 if last_off == offset {
13672 stack.push(("InnerProtoInherit", last_off));
13673 break;
13674 }
13675 }
13676 LinkinfoGeneveAttrs::PortRange(val) => {
13677 if last_off == offset {
13678 stack.push(("PortRange", last_off));
13679 break;
13680 }
13681 }
13682 LinkinfoGeneveAttrs::GroHint(val) => {
13683 if last_off == offset {
13684 stack.push(("GroHint", last_off));
13685 break;
13686 }
13687 }
13688 _ => {}
13689 };
13690 last_off = cur + attrs.pos;
13691 }
13692 if !stack.is_empty() {
13693 stack.push(("LinkinfoGeneveAttrs", cur));
13694 }
13695 (stack, None)
13696 }
13697}
13698#[derive(Clone)]
13699pub enum LinkinfoHsrAttrs<'a> {
13700 Slave1(u32),
13701 Slave2(u32),
13702 MulticastSpec(u8),
13703 SupervisionAddr(&'a [u8]),
13704 SeqNr(u16),
13705 Version(u8),
13706 Protocol(u8),
13707 Interlink(u32),
13708}
13709impl<'a> IterableLinkinfoHsrAttrs<'a> {
13710 pub fn get_slave1(&self) -> Result<u32, ErrorContext> {
13711 let mut iter = self.clone();
13712 iter.pos = 0;
13713 for attr in iter {
13714 if let Ok(LinkinfoHsrAttrs::Slave1(val)) = attr {
13715 return Ok(val);
13716 }
13717 }
13718 Err(ErrorContext::new_missing(
13719 "LinkinfoHsrAttrs",
13720 "Slave1",
13721 self.orig_loc,
13722 self.buf.as_ptr() as usize,
13723 ))
13724 }
13725 pub fn get_slave2(&self) -> Result<u32, ErrorContext> {
13726 let mut iter = self.clone();
13727 iter.pos = 0;
13728 for attr in iter {
13729 if let Ok(LinkinfoHsrAttrs::Slave2(val)) = attr {
13730 return Ok(val);
13731 }
13732 }
13733 Err(ErrorContext::new_missing(
13734 "LinkinfoHsrAttrs",
13735 "Slave2",
13736 self.orig_loc,
13737 self.buf.as_ptr() as usize,
13738 ))
13739 }
13740 pub fn get_multicast_spec(&self) -> Result<u8, ErrorContext> {
13741 let mut iter = self.clone();
13742 iter.pos = 0;
13743 for attr in iter {
13744 if let Ok(LinkinfoHsrAttrs::MulticastSpec(val)) = attr {
13745 return Ok(val);
13746 }
13747 }
13748 Err(ErrorContext::new_missing(
13749 "LinkinfoHsrAttrs",
13750 "MulticastSpec",
13751 self.orig_loc,
13752 self.buf.as_ptr() as usize,
13753 ))
13754 }
13755 pub fn get_supervision_addr(&self) -> Result<&'a [u8], ErrorContext> {
13756 let mut iter = self.clone();
13757 iter.pos = 0;
13758 for attr in iter {
13759 if let Ok(LinkinfoHsrAttrs::SupervisionAddr(val)) = attr {
13760 return Ok(val);
13761 }
13762 }
13763 Err(ErrorContext::new_missing(
13764 "LinkinfoHsrAttrs",
13765 "SupervisionAddr",
13766 self.orig_loc,
13767 self.buf.as_ptr() as usize,
13768 ))
13769 }
13770 pub fn get_seq_nr(&self) -> Result<u16, ErrorContext> {
13771 let mut iter = self.clone();
13772 iter.pos = 0;
13773 for attr in iter {
13774 if let Ok(LinkinfoHsrAttrs::SeqNr(val)) = attr {
13775 return Ok(val);
13776 }
13777 }
13778 Err(ErrorContext::new_missing(
13779 "LinkinfoHsrAttrs",
13780 "SeqNr",
13781 self.orig_loc,
13782 self.buf.as_ptr() as usize,
13783 ))
13784 }
13785 pub fn get_version(&self) -> Result<u8, ErrorContext> {
13786 let mut iter = self.clone();
13787 iter.pos = 0;
13788 for attr in iter {
13789 if let Ok(LinkinfoHsrAttrs::Version(val)) = attr {
13790 return Ok(val);
13791 }
13792 }
13793 Err(ErrorContext::new_missing(
13794 "LinkinfoHsrAttrs",
13795 "Version",
13796 self.orig_loc,
13797 self.buf.as_ptr() as usize,
13798 ))
13799 }
13800 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
13801 let mut iter = self.clone();
13802 iter.pos = 0;
13803 for attr in iter {
13804 if let Ok(LinkinfoHsrAttrs::Protocol(val)) = attr {
13805 return Ok(val);
13806 }
13807 }
13808 Err(ErrorContext::new_missing(
13809 "LinkinfoHsrAttrs",
13810 "Protocol",
13811 self.orig_loc,
13812 self.buf.as_ptr() as usize,
13813 ))
13814 }
13815 pub fn get_interlink(&self) -> Result<u32, ErrorContext> {
13816 let mut iter = self.clone();
13817 iter.pos = 0;
13818 for attr in iter {
13819 if let Ok(LinkinfoHsrAttrs::Interlink(val)) = attr {
13820 return Ok(val);
13821 }
13822 }
13823 Err(ErrorContext::new_missing(
13824 "LinkinfoHsrAttrs",
13825 "Interlink",
13826 self.orig_loc,
13827 self.buf.as_ptr() as usize,
13828 ))
13829 }
13830}
13831impl LinkinfoHsrAttrs<'_> {
13832 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoHsrAttrs<'a> {
13833 IterableLinkinfoHsrAttrs::with_loc(buf, buf.as_ptr() as usize)
13834 }
13835 fn attr_from_type(r#type: u16) -> Option<&'static str> {
13836 let res = match r#type {
13837 1u16 => "Slave1",
13838 2u16 => "Slave2",
13839 3u16 => "MulticastSpec",
13840 4u16 => "SupervisionAddr",
13841 5u16 => "SeqNr",
13842 6u16 => "Version",
13843 7u16 => "Protocol",
13844 8u16 => "Interlink",
13845 _ => return None,
13846 };
13847 Some(res)
13848 }
13849}
13850#[derive(Clone, Copy, Default)]
13851pub struct IterableLinkinfoHsrAttrs<'a> {
13852 buf: &'a [u8],
13853 pos: usize,
13854 orig_loc: usize,
13855}
13856impl<'a> IterableLinkinfoHsrAttrs<'a> {
13857 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
13858 Self {
13859 buf,
13860 pos: 0,
13861 orig_loc,
13862 }
13863 }
13864 pub fn get_buf(&self) -> &'a [u8] {
13865 self.buf
13866 }
13867}
13868impl<'a> Iterator for IterableLinkinfoHsrAttrs<'a> {
13869 type Item = Result<LinkinfoHsrAttrs<'a>, ErrorContext>;
13870 fn next(&mut self) -> Option<Self::Item> {
13871 let mut pos;
13872 let mut r#type;
13873 loop {
13874 pos = self.pos;
13875 r#type = None;
13876 if self.buf.len() == self.pos {
13877 return None;
13878 }
13879 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
13880 self.pos = self.buf.len();
13881 break;
13882 };
13883 r#type = Some(header.r#type);
13884 let res = match header.r#type {
13885 1u16 => LinkinfoHsrAttrs::Slave1({
13886 let res = parse_u32(next);
13887 let Some(val) = res else { break };
13888 val
13889 }),
13890 2u16 => LinkinfoHsrAttrs::Slave2({
13891 let res = parse_u32(next);
13892 let Some(val) = res else { break };
13893 val
13894 }),
13895 3u16 => LinkinfoHsrAttrs::MulticastSpec({
13896 let res = parse_u8(next);
13897 let Some(val) = res else { break };
13898 val
13899 }),
13900 4u16 => LinkinfoHsrAttrs::SupervisionAddr({
13901 let res = Some(next);
13902 let Some(val) = res else { break };
13903 val
13904 }),
13905 5u16 => LinkinfoHsrAttrs::SeqNr({
13906 let res = parse_u16(next);
13907 let Some(val) = res else { break };
13908 val
13909 }),
13910 6u16 => LinkinfoHsrAttrs::Version({
13911 let res = parse_u8(next);
13912 let Some(val) = res else { break };
13913 val
13914 }),
13915 7u16 => LinkinfoHsrAttrs::Protocol({
13916 let res = parse_u8(next);
13917 let Some(val) = res else { break };
13918 val
13919 }),
13920 8u16 => LinkinfoHsrAttrs::Interlink({
13921 let res = parse_u32(next);
13922 let Some(val) = res else { break };
13923 val
13924 }),
13925 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
13926 n => continue,
13927 };
13928 return Some(Ok(res));
13929 }
13930 Some(Err(ErrorContext::new(
13931 "LinkinfoHsrAttrs",
13932 r#type.and_then(|t| LinkinfoHsrAttrs::attr_from_type(t)),
13933 self.orig_loc,
13934 self.buf.as_ptr().wrapping_add(pos) as usize,
13935 )))
13936 }
13937}
13938impl<'a> std::fmt::Debug for IterableLinkinfoHsrAttrs<'_> {
13939 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13940 let mut fmt = f.debug_struct("LinkinfoHsrAttrs");
13941 for attr in self.clone() {
13942 let attr = match attr {
13943 Ok(a) => a,
13944 Err(err) => {
13945 fmt.finish()?;
13946 f.write_str("Err(")?;
13947 err.fmt(f)?;
13948 return f.write_str(")");
13949 }
13950 };
13951 match attr {
13952 LinkinfoHsrAttrs::Slave1(val) => fmt.field("Slave1", &val),
13953 LinkinfoHsrAttrs::Slave2(val) => fmt.field("Slave2", &val),
13954 LinkinfoHsrAttrs::MulticastSpec(val) => fmt.field("MulticastSpec", &val),
13955 LinkinfoHsrAttrs::SupervisionAddr(val) => {
13956 fmt.field("SupervisionAddr", &FormatMac(val))
13957 }
13958 LinkinfoHsrAttrs::SeqNr(val) => fmt.field("SeqNr", &val),
13959 LinkinfoHsrAttrs::Version(val) => fmt.field("Version", &val),
13960 LinkinfoHsrAttrs::Protocol(val) => fmt.field("Protocol", &val),
13961 LinkinfoHsrAttrs::Interlink(val) => fmt.field("Interlink", &val),
13962 };
13963 }
13964 fmt.finish()
13965 }
13966}
13967impl IterableLinkinfoHsrAttrs<'_> {
13968 pub fn lookup_attr(
13969 &self,
13970 offset: usize,
13971 missing_type: Option<u16>,
13972 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
13973 let mut stack = Vec::new();
13974 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
13975 if missing_type.is_some() && cur == offset {
13976 stack.push(("LinkinfoHsrAttrs", offset));
13977 return (
13978 stack,
13979 missing_type.and_then(|t| LinkinfoHsrAttrs::attr_from_type(t)),
13980 );
13981 }
13982 if cur > offset || cur + self.buf.len() < offset {
13983 return (stack, None);
13984 }
13985 let mut attrs = self.clone();
13986 let mut last_off = cur + attrs.pos;
13987 while let Some(attr) = attrs.next() {
13988 let Ok(attr) = attr else { break };
13989 match attr {
13990 LinkinfoHsrAttrs::Slave1(val) => {
13991 if last_off == offset {
13992 stack.push(("Slave1", last_off));
13993 break;
13994 }
13995 }
13996 LinkinfoHsrAttrs::Slave2(val) => {
13997 if last_off == offset {
13998 stack.push(("Slave2", last_off));
13999 break;
14000 }
14001 }
14002 LinkinfoHsrAttrs::MulticastSpec(val) => {
14003 if last_off == offset {
14004 stack.push(("MulticastSpec", last_off));
14005 break;
14006 }
14007 }
14008 LinkinfoHsrAttrs::SupervisionAddr(val) => {
14009 if last_off == offset {
14010 stack.push(("SupervisionAddr", last_off));
14011 break;
14012 }
14013 }
14014 LinkinfoHsrAttrs::SeqNr(val) => {
14015 if last_off == offset {
14016 stack.push(("SeqNr", last_off));
14017 break;
14018 }
14019 }
14020 LinkinfoHsrAttrs::Version(val) => {
14021 if last_off == offset {
14022 stack.push(("Version", last_off));
14023 break;
14024 }
14025 }
14026 LinkinfoHsrAttrs::Protocol(val) => {
14027 if last_off == offset {
14028 stack.push(("Protocol", last_off));
14029 break;
14030 }
14031 }
14032 LinkinfoHsrAttrs::Interlink(val) => {
14033 if last_off == offset {
14034 stack.push(("Interlink", last_off));
14035 break;
14036 }
14037 }
14038 _ => {}
14039 };
14040 last_off = cur + attrs.pos;
14041 }
14042 if !stack.is_empty() {
14043 stack.push(("LinkinfoHsrAttrs", cur));
14044 }
14045 (stack, None)
14046 }
14047}
14048#[derive(Clone)]
14049pub enum LinkinfoIptunAttrs<'a> {
14050 Link(u32),
14051 Local(std::net::IpAddr),
14052 Remote(std::net::IpAddr),
14053 Ttl(u8),
14054 Tos(u8),
14055 EncapLimit(u8),
14056 Flowinfo(u32),
14057 Flags(u16),
14058 Proto(u8),
14059 Pmtudisc(u8),
14060 _6rdPrefix(&'a [u8]),
14061 _6rdRelayPrefix(std::net::Ipv4Addr),
14062 _6rdPrefixlen(u16),
14063 _6rdRelayPrefixlen(u16),
14064 EncapType(u16),
14065 EncapFlags(u16),
14066 EncapSport(u16),
14067 EncapDport(u16),
14068 CollectMetadata(()),
14069 Fwmark(u32),
14070}
14071impl<'a> IterableLinkinfoIptunAttrs<'a> {
14072 pub fn get_link(&self) -> Result<u32, ErrorContext> {
14073 let mut iter = self.clone();
14074 iter.pos = 0;
14075 for attr in iter {
14076 if let Ok(LinkinfoIptunAttrs::Link(val)) = attr {
14077 return Ok(val);
14078 }
14079 }
14080 Err(ErrorContext::new_missing(
14081 "LinkinfoIptunAttrs",
14082 "Link",
14083 self.orig_loc,
14084 self.buf.as_ptr() as usize,
14085 ))
14086 }
14087 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
14088 let mut iter = self.clone();
14089 iter.pos = 0;
14090 for attr in iter {
14091 if let Ok(LinkinfoIptunAttrs::Local(val)) = attr {
14092 return Ok(val);
14093 }
14094 }
14095 Err(ErrorContext::new_missing(
14096 "LinkinfoIptunAttrs",
14097 "Local",
14098 self.orig_loc,
14099 self.buf.as_ptr() as usize,
14100 ))
14101 }
14102 pub fn get_remote(&self) -> Result<std::net::IpAddr, ErrorContext> {
14103 let mut iter = self.clone();
14104 iter.pos = 0;
14105 for attr in iter {
14106 if let Ok(LinkinfoIptunAttrs::Remote(val)) = attr {
14107 return Ok(val);
14108 }
14109 }
14110 Err(ErrorContext::new_missing(
14111 "LinkinfoIptunAttrs",
14112 "Remote",
14113 self.orig_loc,
14114 self.buf.as_ptr() as usize,
14115 ))
14116 }
14117 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
14118 let mut iter = self.clone();
14119 iter.pos = 0;
14120 for attr in iter {
14121 if let Ok(LinkinfoIptunAttrs::Ttl(val)) = attr {
14122 return Ok(val);
14123 }
14124 }
14125 Err(ErrorContext::new_missing(
14126 "LinkinfoIptunAttrs",
14127 "Ttl",
14128 self.orig_loc,
14129 self.buf.as_ptr() as usize,
14130 ))
14131 }
14132 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
14133 let mut iter = self.clone();
14134 iter.pos = 0;
14135 for attr in iter {
14136 if let Ok(LinkinfoIptunAttrs::Tos(val)) = attr {
14137 return Ok(val);
14138 }
14139 }
14140 Err(ErrorContext::new_missing(
14141 "LinkinfoIptunAttrs",
14142 "Tos",
14143 self.orig_loc,
14144 self.buf.as_ptr() as usize,
14145 ))
14146 }
14147 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
14148 let mut iter = self.clone();
14149 iter.pos = 0;
14150 for attr in iter {
14151 if let Ok(LinkinfoIptunAttrs::EncapLimit(val)) = attr {
14152 return Ok(val);
14153 }
14154 }
14155 Err(ErrorContext::new_missing(
14156 "LinkinfoIptunAttrs",
14157 "EncapLimit",
14158 self.orig_loc,
14159 self.buf.as_ptr() as usize,
14160 ))
14161 }
14162 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
14163 let mut iter = self.clone();
14164 iter.pos = 0;
14165 for attr in iter {
14166 if let Ok(LinkinfoIptunAttrs::Flowinfo(val)) = attr {
14167 return Ok(val);
14168 }
14169 }
14170 Err(ErrorContext::new_missing(
14171 "LinkinfoIptunAttrs",
14172 "Flowinfo",
14173 self.orig_loc,
14174 self.buf.as_ptr() as usize,
14175 ))
14176 }
14177 pub fn get_flags(&self) -> Result<u16, ErrorContext> {
14178 let mut iter = self.clone();
14179 iter.pos = 0;
14180 for attr in iter {
14181 if let Ok(LinkinfoIptunAttrs::Flags(val)) = attr {
14182 return Ok(val);
14183 }
14184 }
14185 Err(ErrorContext::new_missing(
14186 "LinkinfoIptunAttrs",
14187 "Flags",
14188 self.orig_loc,
14189 self.buf.as_ptr() as usize,
14190 ))
14191 }
14192 pub fn get_proto(&self) -> Result<u8, ErrorContext> {
14193 let mut iter = self.clone();
14194 iter.pos = 0;
14195 for attr in iter {
14196 if let Ok(LinkinfoIptunAttrs::Proto(val)) = attr {
14197 return Ok(val);
14198 }
14199 }
14200 Err(ErrorContext::new_missing(
14201 "LinkinfoIptunAttrs",
14202 "Proto",
14203 self.orig_loc,
14204 self.buf.as_ptr() as usize,
14205 ))
14206 }
14207 pub fn get_pmtudisc(&self) -> Result<u8, ErrorContext> {
14208 let mut iter = self.clone();
14209 iter.pos = 0;
14210 for attr in iter {
14211 if let Ok(LinkinfoIptunAttrs::Pmtudisc(val)) = attr {
14212 return Ok(val);
14213 }
14214 }
14215 Err(ErrorContext::new_missing(
14216 "LinkinfoIptunAttrs",
14217 "Pmtudisc",
14218 self.orig_loc,
14219 self.buf.as_ptr() as usize,
14220 ))
14221 }
14222 pub fn get_6rd_prefix(&self) -> Result<&'a [u8], ErrorContext> {
14223 let mut iter = self.clone();
14224 iter.pos = 0;
14225 for attr in iter {
14226 if let Ok(LinkinfoIptunAttrs::_6rdPrefix(val)) = attr {
14227 return Ok(val);
14228 }
14229 }
14230 Err(ErrorContext::new_missing(
14231 "LinkinfoIptunAttrs",
14232 "6rdPrefix",
14233 self.orig_loc,
14234 self.buf.as_ptr() as usize,
14235 ))
14236 }
14237 pub fn get_6rd_relay_prefix(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
14238 let mut iter = self.clone();
14239 iter.pos = 0;
14240 for attr in iter {
14241 if let Ok(LinkinfoIptunAttrs::_6rdRelayPrefix(val)) = attr {
14242 return Ok(val);
14243 }
14244 }
14245 Err(ErrorContext::new_missing(
14246 "LinkinfoIptunAttrs",
14247 "6rdRelayPrefix",
14248 self.orig_loc,
14249 self.buf.as_ptr() as usize,
14250 ))
14251 }
14252 pub fn get_6rd_prefixlen(&self) -> Result<u16, ErrorContext> {
14253 let mut iter = self.clone();
14254 iter.pos = 0;
14255 for attr in iter {
14256 if let Ok(LinkinfoIptunAttrs::_6rdPrefixlen(val)) = attr {
14257 return Ok(val);
14258 }
14259 }
14260 Err(ErrorContext::new_missing(
14261 "LinkinfoIptunAttrs",
14262 "6rdPrefixlen",
14263 self.orig_loc,
14264 self.buf.as_ptr() as usize,
14265 ))
14266 }
14267 pub fn get_6rd_relay_prefixlen(&self) -> Result<u16, ErrorContext> {
14268 let mut iter = self.clone();
14269 iter.pos = 0;
14270 for attr in iter {
14271 if let Ok(LinkinfoIptunAttrs::_6rdRelayPrefixlen(val)) = attr {
14272 return Ok(val);
14273 }
14274 }
14275 Err(ErrorContext::new_missing(
14276 "LinkinfoIptunAttrs",
14277 "6rdRelayPrefixlen",
14278 self.orig_loc,
14279 self.buf.as_ptr() as usize,
14280 ))
14281 }
14282 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
14283 let mut iter = self.clone();
14284 iter.pos = 0;
14285 for attr in iter {
14286 if let Ok(LinkinfoIptunAttrs::EncapType(val)) = attr {
14287 return Ok(val);
14288 }
14289 }
14290 Err(ErrorContext::new_missing(
14291 "LinkinfoIptunAttrs",
14292 "EncapType",
14293 self.orig_loc,
14294 self.buf.as_ptr() as usize,
14295 ))
14296 }
14297 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
14298 let mut iter = self.clone();
14299 iter.pos = 0;
14300 for attr in iter {
14301 if let Ok(LinkinfoIptunAttrs::EncapFlags(val)) = attr {
14302 return Ok(val);
14303 }
14304 }
14305 Err(ErrorContext::new_missing(
14306 "LinkinfoIptunAttrs",
14307 "EncapFlags",
14308 self.orig_loc,
14309 self.buf.as_ptr() as usize,
14310 ))
14311 }
14312 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
14313 let mut iter = self.clone();
14314 iter.pos = 0;
14315 for attr in iter {
14316 if let Ok(LinkinfoIptunAttrs::EncapSport(val)) = attr {
14317 return Ok(val);
14318 }
14319 }
14320 Err(ErrorContext::new_missing(
14321 "LinkinfoIptunAttrs",
14322 "EncapSport",
14323 self.orig_loc,
14324 self.buf.as_ptr() as usize,
14325 ))
14326 }
14327 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
14328 let mut iter = self.clone();
14329 iter.pos = 0;
14330 for attr in iter {
14331 if let Ok(LinkinfoIptunAttrs::EncapDport(val)) = attr {
14332 return Ok(val);
14333 }
14334 }
14335 Err(ErrorContext::new_missing(
14336 "LinkinfoIptunAttrs",
14337 "EncapDport",
14338 self.orig_loc,
14339 self.buf.as_ptr() as usize,
14340 ))
14341 }
14342 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
14343 let mut iter = self.clone();
14344 iter.pos = 0;
14345 for attr in iter {
14346 if let Ok(LinkinfoIptunAttrs::CollectMetadata(val)) = attr {
14347 return Ok(val);
14348 }
14349 }
14350 Err(ErrorContext::new_missing(
14351 "LinkinfoIptunAttrs",
14352 "CollectMetadata",
14353 self.orig_loc,
14354 self.buf.as_ptr() as usize,
14355 ))
14356 }
14357 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
14358 let mut iter = self.clone();
14359 iter.pos = 0;
14360 for attr in iter {
14361 if let Ok(LinkinfoIptunAttrs::Fwmark(val)) = attr {
14362 return Ok(val);
14363 }
14364 }
14365 Err(ErrorContext::new_missing(
14366 "LinkinfoIptunAttrs",
14367 "Fwmark",
14368 self.orig_loc,
14369 self.buf.as_ptr() as usize,
14370 ))
14371 }
14372}
14373impl LinkinfoIptunAttrs<'_> {
14374 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoIptunAttrs<'a> {
14375 IterableLinkinfoIptunAttrs::with_loc(buf, buf.as_ptr() as usize)
14376 }
14377 fn attr_from_type(r#type: u16) -> Option<&'static str> {
14378 let res = match r#type {
14379 1u16 => "Link",
14380 2u16 => "Local",
14381 3u16 => "Remote",
14382 4u16 => "Ttl",
14383 5u16 => "Tos",
14384 6u16 => "EncapLimit",
14385 7u16 => "Flowinfo",
14386 8u16 => "Flags",
14387 9u16 => "Proto",
14388 10u16 => "Pmtudisc",
14389 11u16 => "6rdPrefix",
14390 12u16 => "6rdRelayPrefix",
14391 13u16 => "6rdPrefixlen",
14392 14u16 => "6rdRelayPrefixlen",
14393 15u16 => "EncapType",
14394 16u16 => "EncapFlags",
14395 17u16 => "EncapSport",
14396 18u16 => "EncapDport",
14397 19u16 => "CollectMetadata",
14398 20u16 => "Fwmark",
14399 _ => return None,
14400 };
14401 Some(res)
14402 }
14403}
14404#[derive(Clone, Copy, Default)]
14405pub struct IterableLinkinfoIptunAttrs<'a> {
14406 buf: &'a [u8],
14407 pos: usize,
14408 orig_loc: usize,
14409}
14410impl<'a> IterableLinkinfoIptunAttrs<'a> {
14411 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
14412 Self {
14413 buf,
14414 pos: 0,
14415 orig_loc,
14416 }
14417 }
14418 pub fn get_buf(&self) -> &'a [u8] {
14419 self.buf
14420 }
14421}
14422impl<'a> Iterator for IterableLinkinfoIptunAttrs<'a> {
14423 type Item = Result<LinkinfoIptunAttrs<'a>, ErrorContext>;
14424 fn next(&mut self) -> Option<Self::Item> {
14425 let mut pos;
14426 let mut r#type;
14427 loop {
14428 pos = self.pos;
14429 r#type = None;
14430 if self.buf.len() == self.pos {
14431 return None;
14432 }
14433 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
14434 self.pos = self.buf.len();
14435 break;
14436 };
14437 r#type = Some(header.r#type);
14438 let res = match header.r#type {
14439 1u16 => LinkinfoIptunAttrs::Link({
14440 let res = parse_u32(next);
14441 let Some(val) = res else { break };
14442 val
14443 }),
14444 2u16 => LinkinfoIptunAttrs::Local({
14445 let res = parse_ip(next);
14446 let Some(val) = res else { break };
14447 val
14448 }),
14449 3u16 => LinkinfoIptunAttrs::Remote({
14450 let res = parse_ip(next);
14451 let Some(val) = res else { break };
14452 val
14453 }),
14454 4u16 => LinkinfoIptunAttrs::Ttl({
14455 let res = parse_u8(next);
14456 let Some(val) = res else { break };
14457 val
14458 }),
14459 5u16 => LinkinfoIptunAttrs::Tos({
14460 let res = parse_u8(next);
14461 let Some(val) = res else { break };
14462 val
14463 }),
14464 6u16 => LinkinfoIptunAttrs::EncapLimit({
14465 let res = parse_u8(next);
14466 let Some(val) = res else { break };
14467 val
14468 }),
14469 7u16 => LinkinfoIptunAttrs::Flowinfo({
14470 let res = parse_be_u32(next);
14471 let Some(val) = res else { break };
14472 val
14473 }),
14474 8u16 => LinkinfoIptunAttrs::Flags({
14475 let res = parse_be_u16(next);
14476 let Some(val) = res else { break };
14477 val
14478 }),
14479 9u16 => LinkinfoIptunAttrs::Proto({
14480 let res = parse_u8(next);
14481 let Some(val) = res else { break };
14482 val
14483 }),
14484 10u16 => LinkinfoIptunAttrs::Pmtudisc({
14485 let res = parse_u8(next);
14486 let Some(val) = res else { break };
14487 val
14488 }),
14489 11u16 => LinkinfoIptunAttrs::_6rdPrefix({
14490 let res = Some(next);
14491 let Some(val) = res else { break };
14492 val
14493 }),
14494 12u16 => LinkinfoIptunAttrs::_6rdRelayPrefix({
14495 let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
14496 let Some(val) = res else { break };
14497 val
14498 }),
14499 13u16 => LinkinfoIptunAttrs::_6rdPrefixlen({
14500 let res = parse_u16(next);
14501 let Some(val) = res else { break };
14502 val
14503 }),
14504 14u16 => LinkinfoIptunAttrs::_6rdRelayPrefixlen({
14505 let res = parse_u16(next);
14506 let Some(val) = res else { break };
14507 val
14508 }),
14509 15u16 => LinkinfoIptunAttrs::EncapType({
14510 let res = parse_u16(next);
14511 let Some(val) = res else { break };
14512 val
14513 }),
14514 16u16 => LinkinfoIptunAttrs::EncapFlags({
14515 let res = parse_u16(next);
14516 let Some(val) = res else { break };
14517 val
14518 }),
14519 17u16 => LinkinfoIptunAttrs::EncapSport({
14520 let res = parse_be_u16(next);
14521 let Some(val) = res else { break };
14522 val
14523 }),
14524 18u16 => LinkinfoIptunAttrs::EncapDport({
14525 let res = parse_be_u16(next);
14526 let Some(val) = res else { break };
14527 val
14528 }),
14529 19u16 => LinkinfoIptunAttrs::CollectMetadata(()),
14530 20u16 => LinkinfoIptunAttrs::Fwmark({
14531 let res = parse_u32(next);
14532 let Some(val) = res else { break };
14533 val
14534 }),
14535 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
14536 n => continue,
14537 };
14538 return Some(Ok(res));
14539 }
14540 Some(Err(ErrorContext::new(
14541 "LinkinfoIptunAttrs",
14542 r#type.and_then(|t| LinkinfoIptunAttrs::attr_from_type(t)),
14543 self.orig_loc,
14544 self.buf.as_ptr().wrapping_add(pos) as usize,
14545 )))
14546 }
14547}
14548impl<'a> std::fmt::Debug for IterableLinkinfoIptunAttrs<'_> {
14549 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14550 let mut fmt = f.debug_struct("LinkinfoIptunAttrs");
14551 for attr in self.clone() {
14552 let attr = match attr {
14553 Ok(a) => a,
14554 Err(err) => {
14555 fmt.finish()?;
14556 f.write_str("Err(")?;
14557 err.fmt(f)?;
14558 return f.write_str(")");
14559 }
14560 };
14561 match attr {
14562 LinkinfoIptunAttrs::Link(val) => fmt.field("Link", &val),
14563 LinkinfoIptunAttrs::Local(val) => fmt.field("Local", &val),
14564 LinkinfoIptunAttrs::Remote(val) => fmt.field("Remote", &val),
14565 LinkinfoIptunAttrs::Ttl(val) => fmt.field("Ttl", &val),
14566 LinkinfoIptunAttrs::Tos(val) => fmt.field("Tos", &val),
14567 LinkinfoIptunAttrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
14568 LinkinfoIptunAttrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
14569 LinkinfoIptunAttrs::Flags(val) => fmt.field("Flags", &val),
14570 LinkinfoIptunAttrs::Proto(val) => fmt.field("Proto", &val),
14571 LinkinfoIptunAttrs::Pmtudisc(val) => fmt.field("Pmtudisc", &val),
14572 LinkinfoIptunAttrs::_6rdPrefix(val) => fmt.field("_6rdPrefix", &val),
14573 LinkinfoIptunAttrs::_6rdRelayPrefix(val) => fmt.field("_6rdRelayPrefix", &val),
14574 LinkinfoIptunAttrs::_6rdPrefixlen(val) => fmt.field("_6rdPrefixlen", &val),
14575 LinkinfoIptunAttrs::_6rdRelayPrefixlen(val) => {
14576 fmt.field("_6rdRelayPrefixlen", &val)
14577 }
14578 LinkinfoIptunAttrs::EncapType(val) => fmt.field("EncapType", &val),
14579 LinkinfoIptunAttrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
14580 LinkinfoIptunAttrs::EncapSport(val) => fmt.field("EncapSport", &val),
14581 LinkinfoIptunAttrs::EncapDport(val) => fmt.field("EncapDport", &val),
14582 LinkinfoIptunAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
14583 LinkinfoIptunAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
14584 };
14585 }
14586 fmt.finish()
14587 }
14588}
14589impl IterableLinkinfoIptunAttrs<'_> {
14590 pub fn lookup_attr(
14591 &self,
14592 offset: usize,
14593 missing_type: Option<u16>,
14594 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
14595 let mut stack = Vec::new();
14596 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
14597 if missing_type.is_some() && cur == offset {
14598 stack.push(("LinkinfoIptunAttrs", offset));
14599 return (
14600 stack,
14601 missing_type.and_then(|t| LinkinfoIptunAttrs::attr_from_type(t)),
14602 );
14603 }
14604 if cur > offset || cur + self.buf.len() < offset {
14605 return (stack, None);
14606 }
14607 let mut attrs = self.clone();
14608 let mut last_off = cur + attrs.pos;
14609 while let Some(attr) = attrs.next() {
14610 let Ok(attr) = attr else { break };
14611 match attr {
14612 LinkinfoIptunAttrs::Link(val) => {
14613 if last_off == offset {
14614 stack.push(("Link", last_off));
14615 break;
14616 }
14617 }
14618 LinkinfoIptunAttrs::Local(val) => {
14619 if last_off == offset {
14620 stack.push(("Local", last_off));
14621 break;
14622 }
14623 }
14624 LinkinfoIptunAttrs::Remote(val) => {
14625 if last_off == offset {
14626 stack.push(("Remote", last_off));
14627 break;
14628 }
14629 }
14630 LinkinfoIptunAttrs::Ttl(val) => {
14631 if last_off == offset {
14632 stack.push(("Ttl", last_off));
14633 break;
14634 }
14635 }
14636 LinkinfoIptunAttrs::Tos(val) => {
14637 if last_off == offset {
14638 stack.push(("Tos", last_off));
14639 break;
14640 }
14641 }
14642 LinkinfoIptunAttrs::EncapLimit(val) => {
14643 if last_off == offset {
14644 stack.push(("EncapLimit", last_off));
14645 break;
14646 }
14647 }
14648 LinkinfoIptunAttrs::Flowinfo(val) => {
14649 if last_off == offset {
14650 stack.push(("Flowinfo", last_off));
14651 break;
14652 }
14653 }
14654 LinkinfoIptunAttrs::Flags(val) => {
14655 if last_off == offset {
14656 stack.push(("Flags", last_off));
14657 break;
14658 }
14659 }
14660 LinkinfoIptunAttrs::Proto(val) => {
14661 if last_off == offset {
14662 stack.push(("Proto", last_off));
14663 break;
14664 }
14665 }
14666 LinkinfoIptunAttrs::Pmtudisc(val) => {
14667 if last_off == offset {
14668 stack.push(("Pmtudisc", last_off));
14669 break;
14670 }
14671 }
14672 LinkinfoIptunAttrs::_6rdPrefix(val) => {
14673 if last_off == offset {
14674 stack.push(("6rdPrefix", last_off));
14675 break;
14676 }
14677 }
14678 LinkinfoIptunAttrs::_6rdRelayPrefix(val) => {
14679 if last_off == offset {
14680 stack.push(("6rdRelayPrefix", last_off));
14681 break;
14682 }
14683 }
14684 LinkinfoIptunAttrs::_6rdPrefixlen(val) => {
14685 if last_off == offset {
14686 stack.push(("6rdPrefixlen", last_off));
14687 break;
14688 }
14689 }
14690 LinkinfoIptunAttrs::_6rdRelayPrefixlen(val) => {
14691 if last_off == offset {
14692 stack.push(("6rdRelayPrefixlen", last_off));
14693 break;
14694 }
14695 }
14696 LinkinfoIptunAttrs::EncapType(val) => {
14697 if last_off == offset {
14698 stack.push(("EncapType", last_off));
14699 break;
14700 }
14701 }
14702 LinkinfoIptunAttrs::EncapFlags(val) => {
14703 if last_off == offset {
14704 stack.push(("EncapFlags", last_off));
14705 break;
14706 }
14707 }
14708 LinkinfoIptunAttrs::EncapSport(val) => {
14709 if last_off == offset {
14710 stack.push(("EncapSport", last_off));
14711 break;
14712 }
14713 }
14714 LinkinfoIptunAttrs::EncapDport(val) => {
14715 if last_off == offset {
14716 stack.push(("EncapDport", last_off));
14717 break;
14718 }
14719 }
14720 LinkinfoIptunAttrs::CollectMetadata(val) => {
14721 if last_off == offset {
14722 stack.push(("CollectMetadata", last_off));
14723 break;
14724 }
14725 }
14726 LinkinfoIptunAttrs::Fwmark(val) => {
14727 if last_off == offset {
14728 stack.push(("Fwmark", last_off));
14729 break;
14730 }
14731 }
14732 _ => {}
14733 };
14734 last_off = cur + attrs.pos;
14735 }
14736 if !stack.is_empty() {
14737 stack.push(("LinkinfoIptunAttrs", cur));
14738 }
14739 (stack, None)
14740 }
14741}
14742#[derive(Clone)]
14743pub enum LinkinfoIp6tnlAttrs<'a> {
14744 Link(u32),
14745 Local(&'a [u8]),
14746 Remote(&'a [u8]),
14747 Ttl(u8),
14748 EncapLimit(u8),
14749 Flowinfo(u32),
14750 Flags(u32),
14751 Proto(u8),
14752 EncapType(u16),
14753 EncapFlags(u16),
14754 EncapSport(u16),
14755 EncapDport(u16),
14756 CollectMetadata(()),
14757 Fwmark(u32),
14758}
14759impl<'a> IterableLinkinfoIp6tnlAttrs<'a> {
14760 pub fn get_link(&self) -> Result<u32, ErrorContext> {
14761 let mut iter = self.clone();
14762 iter.pos = 0;
14763 for attr in iter {
14764 if let Ok(LinkinfoIp6tnlAttrs::Link(val)) = attr {
14765 return Ok(val);
14766 }
14767 }
14768 Err(ErrorContext::new_missing(
14769 "LinkinfoIp6tnlAttrs",
14770 "Link",
14771 self.orig_loc,
14772 self.buf.as_ptr() as usize,
14773 ))
14774 }
14775 pub fn get_local(&self) -> Result<&'a [u8], ErrorContext> {
14776 let mut iter = self.clone();
14777 iter.pos = 0;
14778 for attr in iter {
14779 if let Ok(LinkinfoIp6tnlAttrs::Local(val)) = attr {
14780 return Ok(val);
14781 }
14782 }
14783 Err(ErrorContext::new_missing(
14784 "LinkinfoIp6tnlAttrs",
14785 "Local",
14786 self.orig_loc,
14787 self.buf.as_ptr() as usize,
14788 ))
14789 }
14790 pub fn get_remote(&self) -> Result<&'a [u8], ErrorContext> {
14791 let mut iter = self.clone();
14792 iter.pos = 0;
14793 for attr in iter {
14794 if let Ok(LinkinfoIp6tnlAttrs::Remote(val)) = attr {
14795 return Ok(val);
14796 }
14797 }
14798 Err(ErrorContext::new_missing(
14799 "LinkinfoIp6tnlAttrs",
14800 "Remote",
14801 self.orig_loc,
14802 self.buf.as_ptr() as usize,
14803 ))
14804 }
14805 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
14806 let mut iter = self.clone();
14807 iter.pos = 0;
14808 for attr in iter {
14809 if let Ok(LinkinfoIp6tnlAttrs::Ttl(val)) = attr {
14810 return Ok(val);
14811 }
14812 }
14813 Err(ErrorContext::new_missing(
14814 "LinkinfoIp6tnlAttrs",
14815 "Ttl",
14816 self.orig_loc,
14817 self.buf.as_ptr() as usize,
14818 ))
14819 }
14820 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
14821 let mut iter = self.clone();
14822 iter.pos = 0;
14823 for attr in iter {
14824 if let Ok(LinkinfoIp6tnlAttrs::EncapLimit(val)) = attr {
14825 return Ok(val);
14826 }
14827 }
14828 Err(ErrorContext::new_missing(
14829 "LinkinfoIp6tnlAttrs",
14830 "EncapLimit",
14831 self.orig_loc,
14832 self.buf.as_ptr() as usize,
14833 ))
14834 }
14835 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
14836 let mut iter = self.clone();
14837 iter.pos = 0;
14838 for attr in iter {
14839 if let Ok(LinkinfoIp6tnlAttrs::Flowinfo(val)) = attr {
14840 return Ok(val);
14841 }
14842 }
14843 Err(ErrorContext::new_missing(
14844 "LinkinfoIp6tnlAttrs",
14845 "Flowinfo",
14846 self.orig_loc,
14847 self.buf.as_ptr() as usize,
14848 ))
14849 }
14850 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
14851 let mut iter = self.clone();
14852 iter.pos = 0;
14853 for attr in iter {
14854 if let Ok(LinkinfoIp6tnlAttrs::Flags(val)) = attr {
14855 return Ok(val);
14856 }
14857 }
14858 Err(ErrorContext::new_missing(
14859 "LinkinfoIp6tnlAttrs",
14860 "Flags",
14861 self.orig_loc,
14862 self.buf.as_ptr() as usize,
14863 ))
14864 }
14865 pub fn get_proto(&self) -> Result<u8, ErrorContext> {
14866 let mut iter = self.clone();
14867 iter.pos = 0;
14868 for attr in iter {
14869 if let Ok(LinkinfoIp6tnlAttrs::Proto(val)) = attr {
14870 return Ok(val);
14871 }
14872 }
14873 Err(ErrorContext::new_missing(
14874 "LinkinfoIp6tnlAttrs",
14875 "Proto",
14876 self.orig_loc,
14877 self.buf.as_ptr() as usize,
14878 ))
14879 }
14880 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
14881 let mut iter = self.clone();
14882 iter.pos = 0;
14883 for attr in iter {
14884 if let Ok(LinkinfoIp6tnlAttrs::EncapType(val)) = attr {
14885 return Ok(val);
14886 }
14887 }
14888 Err(ErrorContext::new_missing(
14889 "LinkinfoIp6tnlAttrs",
14890 "EncapType",
14891 self.orig_loc,
14892 self.buf.as_ptr() as usize,
14893 ))
14894 }
14895 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
14896 let mut iter = self.clone();
14897 iter.pos = 0;
14898 for attr in iter {
14899 if let Ok(LinkinfoIp6tnlAttrs::EncapFlags(val)) = attr {
14900 return Ok(val);
14901 }
14902 }
14903 Err(ErrorContext::new_missing(
14904 "LinkinfoIp6tnlAttrs",
14905 "EncapFlags",
14906 self.orig_loc,
14907 self.buf.as_ptr() as usize,
14908 ))
14909 }
14910 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
14911 let mut iter = self.clone();
14912 iter.pos = 0;
14913 for attr in iter {
14914 if let Ok(LinkinfoIp6tnlAttrs::EncapSport(val)) = attr {
14915 return Ok(val);
14916 }
14917 }
14918 Err(ErrorContext::new_missing(
14919 "LinkinfoIp6tnlAttrs",
14920 "EncapSport",
14921 self.orig_loc,
14922 self.buf.as_ptr() as usize,
14923 ))
14924 }
14925 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
14926 let mut iter = self.clone();
14927 iter.pos = 0;
14928 for attr in iter {
14929 if let Ok(LinkinfoIp6tnlAttrs::EncapDport(val)) = attr {
14930 return Ok(val);
14931 }
14932 }
14933 Err(ErrorContext::new_missing(
14934 "LinkinfoIp6tnlAttrs",
14935 "EncapDport",
14936 self.orig_loc,
14937 self.buf.as_ptr() as usize,
14938 ))
14939 }
14940 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
14941 let mut iter = self.clone();
14942 iter.pos = 0;
14943 for attr in iter {
14944 if let Ok(LinkinfoIp6tnlAttrs::CollectMetadata(val)) = attr {
14945 return Ok(val);
14946 }
14947 }
14948 Err(ErrorContext::new_missing(
14949 "LinkinfoIp6tnlAttrs",
14950 "CollectMetadata",
14951 self.orig_loc,
14952 self.buf.as_ptr() as usize,
14953 ))
14954 }
14955 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
14956 let mut iter = self.clone();
14957 iter.pos = 0;
14958 for attr in iter {
14959 if let Ok(LinkinfoIp6tnlAttrs::Fwmark(val)) = attr {
14960 return Ok(val);
14961 }
14962 }
14963 Err(ErrorContext::new_missing(
14964 "LinkinfoIp6tnlAttrs",
14965 "Fwmark",
14966 self.orig_loc,
14967 self.buf.as_ptr() as usize,
14968 ))
14969 }
14970}
14971impl LinkinfoIp6tnlAttrs<'_> {
14972 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoIp6tnlAttrs<'a> {
14973 IterableLinkinfoIp6tnlAttrs::with_loc(buf, buf.as_ptr() as usize)
14974 }
14975 fn attr_from_type(r#type: u16) -> Option<&'static str> {
14976 LinkinfoIptunAttrs::attr_from_type(r#type)
14977 }
14978}
14979#[derive(Clone, Copy, Default)]
14980pub struct IterableLinkinfoIp6tnlAttrs<'a> {
14981 buf: &'a [u8],
14982 pos: usize,
14983 orig_loc: usize,
14984}
14985impl<'a> IterableLinkinfoIp6tnlAttrs<'a> {
14986 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
14987 Self {
14988 buf,
14989 pos: 0,
14990 orig_loc,
14991 }
14992 }
14993 pub fn get_buf(&self) -> &'a [u8] {
14994 self.buf
14995 }
14996}
14997impl<'a> Iterator for IterableLinkinfoIp6tnlAttrs<'a> {
14998 type Item = Result<LinkinfoIp6tnlAttrs<'a>, ErrorContext>;
14999 fn next(&mut self) -> Option<Self::Item> {
15000 let mut pos;
15001 let mut r#type;
15002 loop {
15003 pos = self.pos;
15004 r#type = None;
15005 if self.buf.len() == self.pos {
15006 return None;
15007 }
15008 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15009 self.pos = self.buf.len();
15010 break;
15011 };
15012 r#type = Some(header.r#type);
15013 let res = match header.r#type {
15014 1u16 => LinkinfoIp6tnlAttrs::Link({
15015 let res = parse_u32(next);
15016 let Some(val) = res else { break };
15017 val
15018 }),
15019 2u16 => LinkinfoIp6tnlAttrs::Local({
15020 let res = Some(next);
15021 let Some(val) = res else { break };
15022 val
15023 }),
15024 3u16 => LinkinfoIp6tnlAttrs::Remote({
15025 let res = Some(next);
15026 let Some(val) = res else { break };
15027 val
15028 }),
15029 4u16 => LinkinfoIp6tnlAttrs::Ttl({
15030 let res = parse_u8(next);
15031 let Some(val) = res else { break };
15032 val
15033 }),
15034 6u16 => LinkinfoIp6tnlAttrs::EncapLimit({
15035 let res = parse_u8(next);
15036 let Some(val) = res else { break };
15037 val
15038 }),
15039 7u16 => LinkinfoIp6tnlAttrs::Flowinfo({
15040 let res = parse_be_u32(next);
15041 let Some(val) = res else { break };
15042 val
15043 }),
15044 8u16 => LinkinfoIp6tnlAttrs::Flags({
15045 let res = parse_be_u32(next);
15046 let Some(val) = res else { break };
15047 val
15048 }),
15049 9u16 => LinkinfoIp6tnlAttrs::Proto({
15050 let res = parse_u8(next);
15051 let Some(val) = res else { break };
15052 val
15053 }),
15054 15u16 => LinkinfoIp6tnlAttrs::EncapType({
15055 let res = parse_u16(next);
15056 let Some(val) = res else { break };
15057 val
15058 }),
15059 16u16 => LinkinfoIp6tnlAttrs::EncapFlags({
15060 let res = parse_u16(next);
15061 let Some(val) = res else { break };
15062 val
15063 }),
15064 17u16 => LinkinfoIp6tnlAttrs::EncapSport({
15065 let res = parse_be_u16(next);
15066 let Some(val) = res else { break };
15067 val
15068 }),
15069 18u16 => LinkinfoIp6tnlAttrs::EncapDport({
15070 let res = parse_be_u16(next);
15071 let Some(val) = res else { break };
15072 val
15073 }),
15074 19u16 => LinkinfoIp6tnlAttrs::CollectMetadata(()),
15075 20u16 => LinkinfoIp6tnlAttrs::Fwmark({
15076 let res = parse_u32(next);
15077 let Some(val) = res else { break };
15078 val
15079 }),
15080 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15081 n => continue,
15082 };
15083 return Some(Ok(res));
15084 }
15085 Some(Err(ErrorContext::new(
15086 "LinkinfoIp6tnlAttrs",
15087 r#type.and_then(|t| LinkinfoIp6tnlAttrs::attr_from_type(t)),
15088 self.orig_loc,
15089 self.buf.as_ptr().wrapping_add(pos) as usize,
15090 )))
15091 }
15092}
15093impl<'a> std::fmt::Debug for IterableLinkinfoIp6tnlAttrs<'_> {
15094 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15095 let mut fmt = f.debug_struct("LinkinfoIp6tnlAttrs");
15096 for attr in self.clone() {
15097 let attr = match attr {
15098 Ok(a) => a,
15099 Err(err) => {
15100 fmt.finish()?;
15101 f.write_str("Err(")?;
15102 err.fmt(f)?;
15103 return f.write_str(")");
15104 }
15105 };
15106 match attr {
15107 LinkinfoIp6tnlAttrs::Link(val) => fmt.field("Link", &val),
15108 LinkinfoIp6tnlAttrs::Local(val) => fmt.field("Local", &val),
15109 LinkinfoIp6tnlAttrs::Remote(val) => fmt.field("Remote", &val),
15110 LinkinfoIp6tnlAttrs::Ttl(val) => fmt.field("Ttl", &val),
15111 LinkinfoIp6tnlAttrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
15112 LinkinfoIp6tnlAttrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
15113 LinkinfoIp6tnlAttrs::Flags(val) => fmt.field("Flags", &val),
15114 LinkinfoIp6tnlAttrs::Proto(val) => fmt.field("Proto", &val),
15115 LinkinfoIp6tnlAttrs::EncapType(val) => fmt.field("EncapType", &val),
15116 LinkinfoIp6tnlAttrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
15117 LinkinfoIp6tnlAttrs::EncapSport(val) => fmt.field("EncapSport", &val),
15118 LinkinfoIp6tnlAttrs::EncapDport(val) => fmt.field("EncapDport", &val),
15119 LinkinfoIp6tnlAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
15120 LinkinfoIp6tnlAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
15121 };
15122 }
15123 fmt.finish()
15124 }
15125}
15126impl IterableLinkinfoIp6tnlAttrs<'_> {
15127 pub fn lookup_attr(
15128 &self,
15129 offset: usize,
15130 missing_type: Option<u16>,
15131 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15132 let mut stack = Vec::new();
15133 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15134 if missing_type.is_some() && cur == offset {
15135 stack.push(("LinkinfoIp6tnlAttrs", offset));
15136 return (
15137 stack,
15138 missing_type.and_then(|t| LinkinfoIp6tnlAttrs::attr_from_type(t)),
15139 );
15140 }
15141 if cur > offset || cur + self.buf.len() < offset {
15142 return (stack, None);
15143 }
15144 let mut attrs = self.clone();
15145 let mut last_off = cur + attrs.pos;
15146 while let Some(attr) = attrs.next() {
15147 let Ok(attr) = attr else { break };
15148 match attr {
15149 LinkinfoIp6tnlAttrs::Link(val) => {
15150 if last_off == offset {
15151 stack.push(("Link", last_off));
15152 break;
15153 }
15154 }
15155 LinkinfoIp6tnlAttrs::Local(val) => {
15156 if last_off == offset {
15157 stack.push(("Local", last_off));
15158 break;
15159 }
15160 }
15161 LinkinfoIp6tnlAttrs::Remote(val) => {
15162 if last_off == offset {
15163 stack.push(("Remote", last_off));
15164 break;
15165 }
15166 }
15167 LinkinfoIp6tnlAttrs::Ttl(val) => {
15168 if last_off == offset {
15169 stack.push(("Ttl", last_off));
15170 break;
15171 }
15172 }
15173 LinkinfoIp6tnlAttrs::EncapLimit(val) => {
15174 if last_off == offset {
15175 stack.push(("EncapLimit", last_off));
15176 break;
15177 }
15178 }
15179 LinkinfoIp6tnlAttrs::Flowinfo(val) => {
15180 if last_off == offset {
15181 stack.push(("Flowinfo", last_off));
15182 break;
15183 }
15184 }
15185 LinkinfoIp6tnlAttrs::Flags(val) => {
15186 if last_off == offset {
15187 stack.push(("Flags", last_off));
15188 break;
15189 }
15190 }
15191 LinkinfoIp6tnlAttrs::Proto(val) => {
15192 if last_off == offset {
15193 stack.push(("Proto", last_off));
15194 break;
15195 }
15196 }
15197 LinkinfoIp6tnlAttrs::EncapType(val) => {
15198 if last_off == offset {
15199 stack.push(("EncapType", last_off));
15200 break;
15201 }
15202 }
15203 LinkinfoIp6tnlAttrs::EncapFlags(val) => {
15204 if last_off == offset {
15205 stack.push(("EncapFlags", last_off));
15206 break;
15207 }
15208 }
15209 LinkinfoIp6tnlAttrs::EncapSport(val) => {
15210 if last_off == offset {
15211 stack.push(("EncapSport", last_off));
15212 break;
15213 }
15214 }
15215 LinkinfoIp6tnlAttrs::EncapDport(val) => {
15216 if last_off == offset {
15217 stack.push(("EncapDport", last_off));
15218 break;
15219 }
15220 }
15221 LinkinfoIp6tnlAttrs::CollectMetadata(val) => {
15222 if last_off == offset {
15223 stack.push(("CollectMetadata", last_off));
15224 break;
15225 }
15226 }
15227 LinkinfoIp6tnlAttrs::Fwmark(val) => {
15228 if last_off == offset {
15229 stack.push(("Fwmark", last_off));
15230 break;
15231 }
15232 }
15233 _ => {}
15234 };
15235 last_off = cur + attrs.pos;
15236 }
15237 if !stack.is_empty() {
15238 stack.push(("LinkinfoIp6tnlAttrs", cur));
15239 }
15240 (stack, None)
15241 }
15242}
15243#[derive(Clone)]
15244pub enum LinkinfoTunAttrs {
15245 Owner(u32),
15246 Group(u32),
15247 Type(u8),
15248 Pi(u8),
15249 VnetHdr(u8),
15250 Persist(u8),
15251 MultiQueue(u8),
15252 NumQueues(u32),
15253 NumDisabledQueues(u32),
15254}
15255impl<'a> IterableLinkinfoTunAttrs<'a> {
15256 pub fn get_owner(&self) -> Result<u32, ErrorContext> {
15257 let mut iter = self.clone();
15258 iter.pos = 0;
15259 for attr in iter {
15260 if let Ok(LinkinfoTunAttrs::Owner(val)) = attr {
15261 return Ok(val);
15262 }
15263 }
15264 Err(ErrorContext::new_missing(
15265 "LinkinfoTunAttrs",
15266 "Owner",
15267 self.orig_loc,
15268 self.buf.as_ptr() as usize,
15269 ))
15270 }
15271 pub fn get_group(&self) -> Result<u32, ErrorContext> {
15272 let mut iter = self.clone();
15273 iter.pos = 0;
15274 for attr in iter {
15275 if let Ok(LinkinfoTunAttrs::Group(val)) = attr {
15276 return Ok(val);
15277 }
15278 }
15279 Err(ErrorContext::new_missing(
15280 "LinkinfoTunAttrs",
15281 "Group",
15282 self.orig_loc,
15283 self.buf.as_ptr() as usize,
15284 ))
15285 }
15286 pub fn get_type(&self) -> Result<u8, ErrorContext> {
15287 let mut iter = self.clone();
15288 iter.pos = 0;
15289 for attr in iter {
15290 if let Ok(LinkinfoTunAttrs::Type(val)) = attr {
15291 return Ok(val);
15292 }
15293 }
15294 Err(ErrorContext::new_missing(
15295 "LinkinfoTunAttrs",
15296 "Type",
15297 self.orig_loc,
15298 self.buf.as_ptr() as usize,
15299 ))
15300 }
15301 pub fn get_pi(&self) -> Result<u8, ErrorContext> {
15302 let mut iter = self.clone();
15303 iter.pos = 0;
15304 for attr in iter {
15305 if let Ok(LinkinfoTunAttrs::Pi(val)) = attr {
15306 return Ok(val);
15307 }
15308 }
15309 Err(ErrorContext::new_missing(
15310 "LinkinfoTunAttrs",
15311 "Pi",
15312 self.orig_loc,
15313 self.buf.as_ptr() as usize,
15314 ))
15315 }
15316 pub fn get_vnet_hdr(&self) -> Result<u8, ErrorContext> {
15317 let mut iter = self.clone();
15318 iter.pos = 0;
15319 for attr in iter {
15320 if let Ok(LinkinfoTunAttrs::VnetHdr(val)) = attr {
15321 return Ok(val);
15322 }
15323 }
15324 Err(ErrorContext::new_missing(
15325 "LinkinfoTunAttrs",
15326 "VnetHdr",
15327 self.orig_loc,
15328 self.buf.as_ptr() as usize,
15329 ))
15330 }
15331 pub fn get_persist(&self) -> Result<u8, ErrorContext> {
15332 let mut iter = self.clone();
15333 iter.pos = 0;
15334 for attr in iter {
15335 if let Ok(LinkinfoTunAttrs::Persist(val)) = attr {
15336 return Ok(val);
15337 }
15338 }
15339 Err(ErrorContext::new_missing(
15340 "LinkinfoTunAttrs",
15341 "Persist",
15342 self.orig_loc,
15343 self.buf.as_ptr() as usize,
15344 ))
15345 }
15346 pub fn get_multi_queue(&self) -> Result<u8, ErrorContext> {
15347 let mut iter = self.clone();
15348 iter.pos = 0;
15349 for attr in iter {
15350 if let Ok(LinkinfoTunAttrs::MultiQueue(val)) = attr {
15351 return Ok(val);
15352 }
15353 }
15354 Err(ErrorContext::new_missing(
15355 "LinkinfoTunAttrs",
15356 "MultiQueue",
15357 self.orig_loc,
15358 self.buf.as_ptr() as usize,
15359 ))
15360 }
15361 pub fn get_num_queues(&self) -> Result<u32, ErrorContext> {
15362 let mut iter = self.clone();
15363 iter.pos = 0;
15364 for attr in iter {
15365 if let Ok(LinkinfoTunAttrs::NumQueues(val)) = attr {
15366 return Ok(val);
15367 }
15368 }
15369 Err(ErrorContext::new_missing(
15370 "LinkinfoTunAttrs",
15371 "NumQueues",
15372 self.orig_loc,
15373 self.buf.as_ptr() as usize,
15374 ))
15375 }
15376 pub fn get_num_disabled_queues(&self) -> Result<u32, ErrorContext> {
15377 let mut iter = self.clone();
15378 iter.pos = 0;
15379 for attr in iter {
15380 if let Ok(LinkinfoTunAttrs::NumDisabledQueues(val)) = attr {
15381 return Ok(val);
15382 }
15383 }
15384 Err(ErrorContext::new_missing(
15385 "LinkinfoTunAttrs",
15386 "NumDisabledQueues",
15387 self.orig_loc,
15388 self.buf.as_ptr() as usize,
15389 ))
15390 }
15391}
15392impl LinkinfoTunAttrs {
15393 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoTunAttrs<'a> {
15394 IterableLinkinfoTunAttrs::with_loc(buf, buf.as_ptr() as usize)
15395 }
15396 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15397 let res = match r#type {
15398 1u16 => "Owner",
15399 2u16 => "Group",
15400 3u16 => "Type",
15401 4u16 => "Pi",
15402 5u16 => "VnetHdr",
15403 6u16 => "Persist",
15404 7u16 => "MultiQueue",
15405 8u16 => "NumQueues",
15406 9u16 => "NumDisabledQueues",
15407 _ => return None,
15408 };
15409 Some(res)
15410 }
15411}
15412#[derive(Clone, Copy, Default)]
15413pub struct IterableLinkinfoTunAttrs<'a> {
15414 buf: &'a [u8],
15415 pos: usize,
15416 orig_loc: usize,
15417}
15418impl<'a> IterableLinkinfoTunAttrs<'a> {
15419 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15420 Self {
15421 buf,
15422 pos: 0,
15423 orig_loc,
15424 }
15425 }
15426 pub fn get_buf(&self) -> &'a [u8] {
15427 self.buf
15428 }
15429}
15430impl<'a> Iterator for IterableLinkinfoTunAttrs<'a> {
15431 type Item = Result<LinkinfoTunAttrs, ErrorContext>;
15432 fn next(&mut self) -> Option<Self::Item> {
15433 let mut pos;
15434 let mut r#type;
15435 loop {
15436 pos = self.pos;
15437 r#type = None;
15438 if self.buf.len() == self.pos {
15439 return None;
15440 }
15441 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15442 self.pos = self.buf.len();
15443 break;
15444 };
15445 r#type = Some(header.r#type);
15446 let res = match header.r#type {
15447 1u16 => LinkinfoTunAttrs::Owner({
15448 let res = parse_u32(next);
15449 let Some(val) = res else { break };
15450 val
15451 }),
15452 2u16 => LinkinfoTunAttrs::Group({
15453 let res = parse_u32(next);
15454 let Some(val) = res else { break };
15455 val
15456 }),
15457 3u16 => LinkinfoTunAttrs::Type({
15458 let res = parse_u8(next);
15459 let Some(val) = res else { break };
15460 val
15461 }),
15462 4u16 => LinkinfoTunAttrs::Pi({
15463 let res = parse_u8(next);
15464 let Some(val) = res else { break };
15465 val
15466 }),
15467 5u16 => LinkinfoTunAttrs::VnetHdr({
15468 let res = parse_u8(next);
15469 let Some(val) = res else { break };
15470 val
15471 }),
15472 6u16 => LinkinfoTunAttrs::Persist({
15473 let res = parse_u8(next);
15474 let Some(val) = res else { break };
15475 val
15476 }),
15477 7u16 => LinkinfoTunAttrs::MultiQueue({
15478 let res = parse_u8(next);
15479 let Some(val) = res else { break };
15480 val
15481 }),
15482 8u16 => LinkinfoTunAttrs::NumQueues({
15483 let res = parse_u32(next);
15484 let Some(val) = res else { break };
15485 val
15486 }),
15487 9u16 => LinkinfoTunAttrs::NumDisabledQueues({
15488 let res = parse_u32(next);
15489 let Some(val) = res else { break };
15490 val
15491 }),
15492 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15493 n => continue,
15494 };
15495 return Some(Ok(res));
15496 }
15497 Some(Err(ErrorContext::new(
15498 "LinkinfoTunAttrs",
15499 r#type.and_then(|t| LinkinfoTunAttrs::attr_from_type(t)),
15500 self.orig_loc,
15501 self.buf.as_ptr().wrapping_add(pos) as usize,
15502 )))
15503 }
15504}
15505impl std::fmt::Debug for IterableLinkinfoTunAttrs<'_> {
15506 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15507 let mut fmt = f.debug_struct("LinkinfoTunAttrs");
15508 for attr in self.clone() {
15509 let attr = match attr {
15510 Ok(a) => a,
15511 Err(err) => {
15512 fmt.finish()?;
15513 f.write_str("Err(")?;
15514 err.fmt(f)?;
15515 return f.write_str(")");
15516 }
15517 };
15518 match attr {
15519 LinkinfoTunAttrs::Owner(val) => fmt.field("Owner", &val),
15520 LinkinfoTunAttrs::Group(val) => fmt.field("Group", &val),
15521 LinkinfoTunAttrs::Type(val) => fmt.field("Type", &val),
15522 LinkinfoTunAttrs::Pi(val) => fmt.field("Pi", &val),
15523 LinkinfoTunAttrs::VnetHdr(val) => fmt.field("VnetHdr", &val),
15524 LinkinfoTunAttrs::Persist(val) => fmt.field("Persist", &val),
15525 LinkinfoTunAttrs::MultiQueue(val) => fmt.field("MultiQueue", &val),
15526 LinkinfoTunAttrs::NumQueues(val) => fmt.field("NumQueues", &val),
15527 LinkinfoTunAttrs::NumDisabledQueues(val) => fmt.field("NumDisabledQueues", &val),
15528 };
15529 }
15530 fmt.finish()
15531 }
15532}
15533impl IterableLinkinfoTunAttrs<'_> {
15534 pub fn lookup_attr(
15535 &self,
15536 offset: usize,
15537 missing_type: Option<u16>,
15538 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15539 let mut stack = Vec::new();
15540 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15541 if missing_type.is_some() && cur == offset {
15542 stack.push(("LinkinfoTunAttrs", offset));
15543 return (
15544 stack,
15545 missing_type.and_then(|t| LinkinfoTunAttrs::attr_from_type(t)),
15546 );
15547 }
15548 if cur > offset || cur + self.buf.len() < offset {
15549 return (stack, None);
15550 }
15551 let mut attrs = self.clone();
15552 let mut last_off = cur + attrs.pos;
15553 while let Some(attr) = attrs.next() {
15554 let Ok(attr) = attr else { break };
15555 match attr {
15556 LinkinfoTunAttrs::Owner(val) => {
15557 if last_off == offset {
15558 stack.push(("Owner", last_off));
15559 break;
15560 }
15561 }
15562 LinkinfoTunAttrs::Group(val) => {
15563 if last_off == offset {
15564 stack.push(("Group", last_off));
15565 break;
15566 }
15567 }
15568 LinkinfoTunAttrs::Type(val) => {
15569 if last_off == offset {
15570 stack.push(("Type", last_off));
15571 break;
15572 }
15573 }
15574 LinkinfoTunAttrs::Pi(val) => {
15575 if last_off == offset {
15576 stack.push(("Pi", last_off));
15577 break;
15578 }
15579 }
15580 LinkinfoTunAttrs::VnetHdr(val) => {
15581 if last_off == offset {
15582 stack.push(("VnetHdr", last_off));
15583 break;
15584 }
15585 }
15586 LinkinfoTunAttrs::Persist(val) => {
15587 if last_off == offset {
15588 stack.push(("Persist", last_off));
15589 break;
15590 }
15591 }
15592 LinkinfoTunAttrs::MultiQueue(val) => {
15593 if last_off == offset {
15594 stack.push(("MultiQueue", last_off));
15595 break;
15596 }
15597 }
15598 LinkinfoTunAttrs::NumQueues(val) => {
15599 if last_off == offset {
15600 stack.push(("NumQueues", last_off));
15601 break;
15602 }
15603 }
15604 LinkinfoTunAttrs::NumDisabledQueues(val) => {
15605 if last_off == offset {
15606 stack.push(("NumDisabledQueues", last_off));
15607 break;
15608 }
15609 }
15610 _ => {}
15611 };
15612 last_off = cur + attrs.pos;
15613 }
15614 if !stack.is_empty() {
15615 stack.push(("LinkinfoTunAttrs", cur));
15616 }
15617 (stack, None)
15618 }
15619}
15620#[derive(Clone)]
15621pub enum LinkinfoVlanAttrs<'a> {
15622 Id(u16),
15623 Flags(IflaVlanFlags),
15624 EgressQos(IterableIflaVlanQos<'a>),
15625 IngressQos(IterableIflaVlanQos<'a>),
15626 #[doc = "Associated type: [`VlanProtocols`] (enum)"]
15627 Protocol(u16),
15628}
15629impl<'a> IterableLinkinfoVlanAttrs<'a> {
15630 pub fn get_id(&self) -> Result<u16, ErrorContext> {
15631 let mut iter = self.clone();
15632 iter.pos = 0;
15633 for attr in iter {
15634 if let Ok(LinkinfoVlanAttrs::Id(val)) = attr {
15635 return Ok(val);
15636 }
15637 }
15638 Err(ErrorContext::new_missing(
15639 "LinkinfoVlanAttrs",
15640 "Id",
15641 self.orig_loc,
15642 self.buf.as_ptr() as usize,
15643 ))
15644 }
15645 pub fn get_flags(&self) -> Result<IflaVlanFlags, ErrorContext> {
15646 let mut iter = self.clone();
15647 iter.pos = 0;
15648 for attr in iter {
15649 if let Ok(LinkinfoVlanAttrs::Flags(val)) = attr {
15650 return Ok(val);
15651 }
15652 }
15653 Err(ErrorContext::new_missing(
15654 "LinkinfoVlanAttrs",
15655 "Flags",
15656 self.orig_loc,
15657 self.buf.as_ptr() as usize,
15658 ))
15659 }
15660 pub fn get_egress_qos(&self) -> Result<IterableIflaVlanQos<'a>, ErrorContext> {
15661 let mut iter = self.clone();
15662 iter.pos = 0;
15663 for attr in iter {
15664 if let Ok(LinkinfoVlanAttrs::EgressQos(val)) = attr {
15665 return Ok(val);
15666 }
15667 }
15668 Err(ErrorContext::new_missing(
15669 "LinkinfoVlanAttrs",
15670 "EgressQos",
15671 self.orig_loc,
15672 self.buf.as_ptr() as usize,
15673 ))
15674 }
15675 pub fn get_ingress_qos(&self) -> Result<IterableIflaVlanQos<'a>, ErrorContext> {
15676 let mut iter = self.clone();
15677 iter.pos = 0;
15678 for attr in iter {
15679 if let Ok(LinkinfoVlanAttrs::IngressQos(val)) = attr {
15680 return Ok(val);
15681 }
15682 }
15683 Err(ErrorContext::new_missing(
15684 "LinkinfoVlanAttrs",
15685 "IngressQos",
15686 self.orig_loc,
15687 self.buf.as_ptr() as usize,
15688 ))
15689 }
15690 #[doc = "Associated type: [`VlanProtocols`] (enum)"]
15691 pub fn get_protocol(&self) -> Result<u16, ErrorContext> {
15692 let mut iter = self.clone();
15693 iter.pos = 0;
15694 for attr in iter {
15695 if let Ok(LinkinfoVlanAttrs::Protocol(val)) = attr {
15696 return Ok(val);
15697 }
15698 }
15699 Err(ErrorContext::new_missing(
15700 "LinkinfoVlanAttrs",
15701 "Protocol",
15702 self.orig_loc,
15703 self.buf.as_ptr() as usize,
15704 ))
15705 }
15706}
15707impl LinkinfoVlanAttrs<'_> {
15708 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVlanAttrs<'a> {
15709 IterableLinkinfoVlanAttrs::with_loc(buf, buf.as_ptr() as usize)
15710 }
15711 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15712 let res = match r#type {
15713 1u16 => "Id",
15714 2u16 => "Flags",
15715 3u16 => "EgressQos",
15716 4u16 => "IngressQos",
15717 5u16 => "Protocol",
15718 _ => return None,
15719 };
15720 Some(res)
15721 }
15722}
15723#[derive(Clone, Copy, Default)]
15724pub struct IterableLinkinfoVlanAttrs<'a> {
15725 buf: &'a [u8],
15726 pos: usize,
15727 orig_loc: usize,
15728}
15729impl<'a> IterableLinkinfoVlanAttrs<'a> {
15730 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15731 Self {
15732 buf,
15733 pos: 0,
15734 orig_loc,
15735 }
15736 }
15737 pub fn get_buf(&self) -> &'a [u8] {
15738 self.buf
15739 }
15740}
15741impl<'a> Iterator for IterableLinkinfoVlanAttrs<'a> {
15742 type Item = Result<LinkinfoVlanAttrs<'a>, ErrorContext>;
15743 fn next(&mut self) -> Option<Self::Item> {
15744 let mut pos;
15745 let mut r#type;
15746 loop {
15747 pos = self.pos;
15748 r#type = None;
15749 if self.buf.len() == self.pos {
15750 return None;
15751 }
15752 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15753 self.pos = self.buf.len();
15754 break;
15755 };
15756 r#type = Some(header.r#type);
15757 let res = match header.r#type {
15758 1u16 => LinkinfoVlanAttrs::Id({
15759 let res = parse_u16(next);
15760 let Some(val) = res else { break };
15761 val
15762 }),
15763 2u16 => LinkinfoVlanAttrs::Flags({
15764 let res = Some(IflaVlanFlags::new_from_zeroed(next));
15765 let Some(val) = res else { break };
15766 val
15767 }),
15768 3u16 => LinkinfoVlanAttrs::EgressQos({
15769 let res = Some(IterableIflaVlanQos::with_loc(next, self.orig_loc));
15770 let Some(val) = res else { break };
15771 val
15772 }),
15773 4u16 => LinkinfoVlanAttrs::IngressQos({
15774 let res = Some(IterableIflaVlanQos::with_loc(next, self.orig_loc));
15775 let Some(val) = res else { break };
15776 val
15777 }),
15778 5u16 => LinkinfoVlanAttrs::Protocol({
15779 let res = parse_be_u16(next);
15780 let Some(val) = res else { break };
15781 val
15782 }),
15783 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15784 n => continue,
15785 };
15786 return Some(Ok(res));
15787 }
15788 Some(Err(ErrorContext::new(
15789 "LinkinfoVlanAttrs",
15790 r#type.and_then(|t| LinkinfoVlanAttrs::attr_from_type(t)),
15791 self.orig_loc,
15792 self.buf.as_ptr().wrapping_add(pos) as usize,
15793 )))
15794 }
15795}
15796impl<'a> std::fmt::Debug for IterableLinkinfoVlanAttrs<'_> {
15797 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15798 let mut fmt = f.debug_struct("LinkinfoVlanAttrs");
15799 for attr in self.clone() {
15800 let attr = match attr {
15801 Ok(a) => a,
15802 Err(err) => {
15803 fmt.finish()?;
15804 f.write_str("Err(")?;
15805 err.fmt(f)?;
15806 return f.write_str(")");
15807 }
15808 };
15809 match attr {
15810 LinkinfoVlanAttrs::Id(val) => fmt.field("Id", &val),
15811 LinkinfoVlanAttrs::Flags(val) => fmt.field("Flags", &val),
15812 LinkinfoVlanAttrs::EgressQos(val) => fmt.field("EgressQos", &val),
15813 LinkinfoVlanAttrs::IngressQos(val) => fmt.field("IngressQos", &val),
15814 LinkinfoVlanAttrs::Protocol(val) => fmt.field(
15815 "Protocol",
15816 &FormatEnum(val.into(), VlanProtocols::from_value),
15817 ),
15818 };
15819 }
15820 fmt.finish()
15821 }
15822}
15823impl IterableLinkinfoVlanAttrs<'_> {
15824 pub fn lookup_attr(
15825 &self,
15826 offset: usize,
15827 missing_type: Option<u16>,
15828 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15829 let mut stack = Vec::new();
15830 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15831 if missing_type.is_some() && cur == offset {
15832 stack.push(("LinkinfoVlanAttrs", offset));
15833 return (
15834 stack,
15835 missing_type.and_then(|t| LinkinfoVlanAttrs::attr_from_type(t)),
15836 );
15837 }
15838 if cur > offset || cur + self.buf.len() < offset {
15839 return (stack, None);
15840 }
15841 let mut attrs = self.clone();
15842 let mut last_off = cur + attrs.pos;
15843 let mut missing = None;
15844 while let Some(attr) = attrs.next() {
15845 let Ok(attr) = attr else { break };
15846 match attr {
15847 LinkinfoVlanAttrs::Id(val) => {
15848 if last_off == offset {
15849 stack.push(("Id", last_off));
15850 break;
15851 }
15852 }
15853 LinkinfoVlanAttrs::Flags(val) => {
15854 if last_off == offset {
15855 stack.push(("Flags", last_off));
15856 break;
15857 }
15858 }
15859 LinkinfoVlanAttrs::EgressQos(val) => {
15860 (stack, missing) = val.lookup_attr(offset, missing_type);
15861 if !stack.is_empty() {
15862 break;
15863 }
15864 }
15865 LinkinfoVlanAttrs::IngressQos(val) => {
15866 (stack, missing) = val.lookup_attr(offset, missing_type);
15867 if !stack.is_empty() {
15868 break;
15869 }
15870 }
15871 LinkinfoVlanAttrs::Protocol(val) => {
15872 if last_off == offset {
15873 stack.push(("Protocol", last_off));
15874 break;
15875 }
15876 }
15877 _ => {}
15878 };
15879 last_off = cur + attrs.pos;
15880 }
15881 if !stack.is_empty() {
15882 stack.push(("LinkinfoVlanAttrs", cur));
15883 }
15884 (stack, missing)
15885 }
15886}
15887#[derive(Clone)]
15888pub enum IflaVlanQos {
15889 #[doc = "Attribute may repeat multiple times (treat it as array)"]
15890 Mapping(IflaVlanQosMapping),
15891}
15892impl<'a> IterableIflaVlanQos<'a> {
15893 #[doc = "Attribute may repeat multiple times (treat it as array)"]
15894 pub fn get_mapping(&self) -> MultiAttrIterable<Self, IflaVlanQos, IflaVlanQosMapping> {
15895 MultiAttrIterable::new(self.clone(), |variant| {
15896 if let IflaVlanQos::Mapping(val) = variant {
15897 Some(val)
15898 } else {
15899 None
15900 }
15901 })
15902 }
15903}
15904impl IflaVlanQos {
15905 pub fn new<'a>(buf: &'a [u8]) -> IterableIflaVlanQos<'a> {
15906 IterableIflaVlanQos::with_loc(buf, buf.as_ptr() as usize)
15907 }
15908 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15909 let res = match r#type {
15910 1u16 => "Mapping",
15911 _ => return None,
15912 };
15913 Some(res)
15914 }
15915}
15916#[derive(Clone, Copy, Default)]
15917pub struct IterableIflaVlanQos<'a> {
15918 buf: &'a [u8],
15919 pos: usize,
15920 orig_loc: usize,
15921}
15922impl<'a> IterableIflaVlanQos<'a> {
15923 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15924 Self {
15925 buf,
15926 pos: 0,
15927 orig_loc,
15928 }
15929 }
15930 pub fn get_buf(&self) -> &'a [u8] {
15931 self.buf
15932 }
15933}
15934impl<'a> Iterator for IterableIflaVlanQos<'a> {
15935 type Item = Result<IflaVlanQos, ErrorContext>;
15936 fn next(&mut self) -> Option<Self::Item> {
15937 let mut pos;
15938 let mut r#type;
15939 loop {
15940 pos = self.pos;
15941 r#type = None;
15942 if self.buf.len() == self.pos {
15943 return None;
15944 }
15945 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15946 self.pos = self.buf.len();
15947 break;
15948 };
15949 r#type = Some(header.r#type);
15950 let res = match header.r#type {
15951 1u16 => IflaVlanQos::Mapping({
15952 let res = Some(IflaVlanQosMapping::new_from_zeroed(next));
15953 let Some(val) = res else { break };
15954 val
15955 }),
15956 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15957 n => continue,
15958 };
15959 return Some(Ok(res));
15960 }
15961 Some(Err(ErrorContext::new(
15962 "IflaVlanQos",
15963 r#type.and_then(|t| IflaVlanQos::attr_from_type(t)),
15964 self.orig_loc,
15965 self.buf.as_ptr().wrapping_add(pos) as usize,
15966 )))
15967 }
15968}
15969impl std::fmt::Debug for IterableIflaVlanQos<'_> {
15970 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15971 let mut fmt = f.debug_struct("IflaVlanQos");
15972 for attr in self.clone() {
15973 let attr = match attr {
15974 Ok(a) => a,
15975 Err(err) => {
15976 fmt.finish()?;
15977 f.write_str("Err(")?;
15978 err.fmt(f)?;
15979 return f.write_str(")");
15980 }
15981 };
15982 match attr {
15983 IflaVlanQos::Mapping(val) => fmt.field("Mapping", &val),
15984 };
15985 }
15986 fmt.finish()
15987 }
15988}
15989impl IterableIflaVlanQos<'_> {
15990 pub fn lookup_attr(
15991 &self,
15992 offset: usize,
15993 missing_type: Option<u16>,
15994 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15995 let mut stack = Vec::new();
15996 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15997 if missing_type.is_some() && cur == offset {
15998 stack.push(("IflaVlanQos", offset));
15999 return (
16000 stack,
16001 missing_type.and_then(|t| IflaVlanQos::attr_from_type(t)),
16002 );
16003 }
16004 if cur > offset || cur + self.buf.len() < offset {
16005 return (stack, None);
16006 }
16007 let mut attrs = self.clone();
16008 let mut last_off = cur + attrs.pos;
16009 while let Some(attr) = attrs.next() {
16010 let Ok(attr) = attr else { break };
16011 match attr {
16012 IflaVlanQos::Mapping(val) => {
16013 if last_off == offset {
16014 stack.push(("Mapping", last_off));
16015 break;
16016 }
16017 }
16018 _ => {}
16019 };
16020 last_off = cur + attrs.pos;
16021 }
16022 if !stack.is_empty() {
16023 stack.push(("IflaVlanQos", cur));
16024 }
16025 (stack, None)
16026 }
16027}
16028#[derive(Clone)]
16029pub enum LinkinfoVrfAttrs {
16030 Table(u32),
16031}
16032impl<'a> IterableLinkinfoVrfAttrs<'a> {
16033 pub fn get_table(&self) -> Result<u32, ErrorContext> {
16034 let mut iter = self.clone();
16035 iter.pos = 0;
16036 for attr in iter {
16037 if let Ok(LinkinfoVrfAttrs::Table(val)) = attr {
16038 return Ok(val);
16039 }
16040 }
16041 Err(ErrorContext::new_missing(
16042 "LinkinfoVrfAttrs",
16043 "Table",
16044 self.orig_loc,
16045 self.buf.as_ptr() as usize,
16046 ))
16047 }
16048}
16049impl LinkinfoVrfAttrs {
16050 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVrfAttrs<'a> {
16051 IterableLinkinfoVrfAttrs::with_loc(buf, buf.as_ptr() as usize)
16052 }
16053 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16054 let res = match r#type {
16055 1u16 => "Table",
16056 _ => return None,
16057 };
16058 Some(res)
16059 }
16060}
16061#[derive(Clone, Copy, Default)]
16062pub struct IterableLinkinfoVrfAttrs<'a> {
16063 buf: &'a [u8],
16064 pos: usize,
16065 orig_loc: usize,
16066}
16067impl<'a> IterableLinkinfoVrfAttrs<'a> {
16068 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16069 Self {
16070 buf,
16071 pos: 0,
16072 orig_loc,
16073 }
16074 }
16075 pub fn get_buf(&self) -> &'a [u8] {
16076 self.buf
16077 }
16078}
16079impl<'a> Iterator for IterableLinkinfoVrfAttrs<'a> {
16080 type Item = Result<LinkinfoVrfAttrs, ErrorContext>;
16081 fn next(&mut self) -> Option<Self::Item> {
16082 let mut pos;
16083 let mut r#type;
16084 loop {
16085 pos = self.pos;
16086 r#type = None;
16087 if self.buf.len() == self.pos {
16088 return None;
16089 }
16090 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16091 self.pos = self.buf.len();
16092 break;
16093 };
16094 r#type = Some(header.r#type);
16095 let res = match header.r#type {
16096 1u16 => LinkinfoVrfAttrs::Table({
16097 let res = parse_u32(next);
16098 let Some(val) = res else { break };
16099 val
16100 }),
16101 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16102 n => continue,
16103 };
16104 return Some(Ok(res));
16105 }
16106 Some(Err(ErrorContext::new(
16107 "LinkinfoVrfAttrs",
16108 r#type.and_then(|t| LinkinfoVrfAttrs::attr_from_type(t)),
16109 self.orig_loc,
16110 self.buf.as_ptr().wrapping_add(pos) as usize,
16111 )))
16112 }
16113}
16114impl std::fmt::Debug for IterableLinkinfoVrfAttrs<'_> {
16115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16116 let mut fmt = f.debug_struct("LinkinfoVrfAttrs");
16117 for attr in self.clone() {
16118 let attr = match attr {
16119 Ok(a) => a,
16120 Err(err) => {
16121 fmt.finish()?;
16122 f.write_str("Err(")?;
16123 err.fmt(f)?;
16124 return f.write_str(")");
16125 }
16126 };
16127 match attr {
16128 LinkinfoVrfAttrs::Table(val) => fmt.field("Table", &val),
16129 };
16130 }
16131 fmt.finish()
16132 }
16133}
16134impl IterableLinkinfoVrfAttrs<'_> {
16135 pub fn lookup_attr(
16136 &self,
16137 offset: usize,
16138 missing_type: Option<u16>,
16139 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16140 let mut stack = Vec::new();
16141 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16142 if missing_type.is_some() && cur == offset {
16143 stack.push(("LinkinfoVrfAttrs", offset));
16144 return (
16145 stack,
16146 missing_type.and_then(|t| LinkinfoVrfAttrs::attr_from_type(t)),
16147 );
16148 }
16149 if cur > offset || cur + self.buf.len() < offset {
16150 return (stack, None);
16151 }
16152 let mut attrs = self.clone();
16153 let mut last_off = cur + attrs.pos;
16154 while let Some(attr) = attrs.next() {
16155 let Ok(attr) = attr else { break };
16156 match attr {
16157 LinkinfoVrfAttrs::Table(val) => {
16158 if last_off == offset {
16159 stack.push(("Table", last_off));
16160 break;
16161 }
16162 }
16163 _ => {}
16164 };
16165 last_off = cur + attrs.pos;
16166 }
16167 if !stack.is_empty() {
16168 stack.push(("LinkinfoVrfAttrs", cur));
16169 }
16170 (stack, None)
16171 }
16172}
16173#[derive(Clone)]
16174pub enum XdpAttrs {
16175 Fd(i32),
16176 Attached(u8),
16177 Flags(u32),
16178 ProgId(u32),
16179 DrvProgId(u32),
16180 SkbProgId(u32),
16181 HwProgId(u32),
16182 ExpectedFd(i32),
16183}
16184impl<'a> IterableXdpAttrs<'a> {
16185 pub fn get_fd(&self) -> Result<i32, ErrorContext> {
16186 let mut iter = self.clone();
16187 iter.pos = 0;
16188 for attr in iter {
16189 if let Ok(XdpAttrs::Fd(val)) = attr {
16190 return Ok(val);
16191 }
16192 }
16193 Err(ErrorContext::new_missing(
16194 "XdpAttrs",
16195 "Fd",
16196 self.orig_loc,
16197 self.buf.as_ptr() as usize,
16198 ))
16199 }
16200 pub fn get_attached(&self) -> Result<u8, ErrorContext> {
16201 let mut iter = self.clone();
16202 iter.pos = 0;
16203 for attr in iter {
16204 if let Ok(XdpAttrs::Attached(val)) = attr {
16205 return Ok(val);
16206 }
16207 }
16208 Err(ErrorContext::new_missing(
16209 "XdpAttrs",
16210 "Attached",
16211 self.orig_loc,
16212 self.buf.as_ptr() as usize,
16213 ))
16214 }
16215 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
16216 let mut iter = self.clone();
16217 iter.pos = 0;
16218 for attr in iter {
16219 if let Ok(XdpAttrs::Flags(val)) = attr {
16220 return Ok(val);
16221 }
16222 }
16223 Err(ErrorContext::new_missing(
16224 "XdpAttrs",
16225 "Flags",
16226 self.orig_loc,
16227 self.buf.as_ptr() as usize,
16228 ))
16229 }
16230 pub fn get_prog_id(&self) -> Result<u32, ErrorContext> {
16231 let mut iter = self.clone();
16232 iter.pos = 0;
16233 for attr in iter {
16234 if let Ok(XdpAttrs::ProgId(val)) = attr {
16235 return Ok(val);
16236 }
16237 }
16238 Err(ErrorContext::new_missing(
16239 "XdpAttrs",
16240 "ProgId",
16241 self.orig_loc,
16242 self.buf.as_ptr() as usize,
16243 ))
16244 }
16245 pub fn get_drv_prog_id(&self) -> Result<u32, ErrorContext> {
16246 let mut iter = self.clone();
16247 iter.pos = 0;
16248 for attr in iter {
16249 if let Ok(XdpAttrs::DrvProgId(val)) = attr {
16250 return Ok(val);
16251 }
16252 }
16253 Err(ErrorContext::new_missing(
16254 "XdpAttrs",
16255 "DrvProgId",
16256 self.orig_loc,
16257 self.buf.as_ptr() as usize,
16258 ))
16259 }
16260 pub fn get_skb_prog_id(&self) -> Result<u32, ErrorContext> {
16261 let mut iter = self.clone();
16262 iter.pos = 0;
16263 for attr in iter {
16264 if let Ok(XdpAttrs::SkbProgId(val)) = attr {
16265 return Ok(val);
16266 }
16267 }
16268 Err(ErrorContext::new_missing(
16269 "XdpAttrs",
16270 "SkbProgId",
16271 self.orig_loc,
16272 self.buf.as_ptr() as usize,
16273 ))
16274 }
16275 pub fn get_hw_prog_id(&self) -> Result<u32, ErrorContext> {
16276 let mut iter = self.clone();
16277 iter.pos = 0;
16278 for attr in iter {
16279 if let Ok(XdpAttrs::HwProgId(val)) = attr {
16280 return Ok(val);
16281 }
16282 }
16283 Err(ErrorContext::new_missing(
16284 "XdpAttrs",
16285 "HwProgId",
16286 self.orig_loc,
16287 self.buf.as_ptr() as usize,
16288 ))
16289 }
16290 pub fn get_expected_fd(&self) -> Result<i32, ErrorContext> {
16291 let mut iter = self.clone();
16292 iter.pos = 0;
16293 for attr in iter {
16294 if let Ok(XdpAttrs::ExpectedFd(val)) = attr {
16295 return Ok(val);
16296 }
16297 }
16298 Err(ErrorContext::new_missing(
16299 "XdpAttrs",
16300 "ExpectedFd",
16301 self.orig_loc,
16302 self.buf.as_ptr() as usize,
16303 ))
16304 }
16305}
16306impl XdpAttrs {
16307 pub fn new<'a>(buf: &'a [u8]) -> IterableXdpAttrs<'a> {
16308 IterableXdpAttrs::with_loc(buf, buf.as_ptr() as usize)
16309 }
16310 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16311 let res = match r#type {
16312 1u16 => "Fd",
16313 2u16 => "Attached",
16314 3u16 => "Flags",
16315 4u16 => "ProgId",
16316 5u16 => "DrvProgId",
16317 6u16 => "SkbProgId",
16318 7u16 => "HwProgId",
16319 8u16 => "ExpectedFd",
16320 _ => return None,
16321 };
16322 Some(res)
16323 }
16324}
16325#[derive(Clone, Copy, Default)]
16326pub struct IterableXdpAttrs<'a> {
16327 buf: &'a [u8],
16328 pos: usize,
16329 orig_loc: usize,
16330}
16331impl<'a> IterableXdpAttrs<'a> {
16332 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16333 Self {
16334 buf,
16335 pos: 0,
16336 orig_loc,
16337 }
16338 }
16339 pub fn get_buf(&self) -> &'a [u8] {
16340 self.buf
16341 }
16342}
16343impl<'a> Iterator for IterableXdpAttrs<'a> {
16344 type Item = Result<XdpAttrs, ErrorContext>;
16345 fn next(&mut self) -> Option<Self::Item> {
16346 let mut pos;
16347 let mut r#type;
16348 loop {
16349 pos = self.pos;
16350 r#type = None;
16351 if self.buf.len() == self.pos {
16352 return None;
16353 }
16354 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16355 self.pos = self.buf.len();
16356 break;
16357 };
16358 r#type = Some(header.r#type);
16359 let res = match header.r#type {
16360 1u16 => XdpAttrs::Fd({
16361 let res = parse_i32(next);
16362 let Some(val) = res else { break };
16363 val
16364 }),
16365 2u16 => XdpAttrs::Attached({
16366 let res = parse_u8(next);
16367 let Some(val) = res else { break };
16368 val
16369 }),
16370 3u16 => XdpAttrs::Flags({
16371 let res = parse_u32(next);
16372 let Some(val) = res else { break };
16373 val
16374 }),
16375 4u16 => XdpAttrs::ProgId({
16376 let res = parse_u32(next);
16377 let Some(val) = res else { break };
16378 val
16379 }),
16380 5u16 => XdpAttrs::DrvProgId({
16381 let res = parse_u32(next);
16382 let Some(val) = res else { break };
16383 val
16384 }),
16385 6u16 => XdpAttrs::SkbProgId({
16386 let res = parse_u32(next);
16387 let Some(val) = res else { break };
16388 val
16389 }),
16390 7u16 => XdpAttrs::HwProgId({
16391 let res = parse_u32(next);
16392 let Some(val) = res else { break };
16393 val
16394 }),
16395 8u16 => XdpAttrs::ExpectedFd({
16396 let res = parse_i32(next);
16397 let Some(val) = res else { break };
16398 val
16399 }),
16400 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16401 n => continue,
16402 };
16403 return Some(Ok(res));
16404 }
16405 Some(Err(ErrorContext::new(
16406 "XdpAttrs",
16407 r#type.and_then(|t| XdpAttrs::attr_from_type(t)),
16408 self.orig_loc,
16409 self.buf.as_ptr().wrapping_add(pos) as usize,
16410 )))
16411 }
16412}
16413impl std::fmt::Debug for IterableXdpAttrs<'_> {
16414 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16415 let mut fmt = f.debug_struct("XdpAttrs");
16416 for attr in self.clone() {
16417 let attr = match attr {
16418 Ok(a) => a,
16419 Err(err) => {
16420 fmt.finish()?;
16421 f.write_str("Err(")?;
16422 err.fmt(f)?;
16423 return f.write_str(")");
16424 }
16425 };
16426 match attr {
16427 XdpAttrs::Fd(val) => fmt.field("Fd", &val),
16428 XdpAttrs::Attached(val) => fmt.field("Attached", &val),
16429 XdpAttrs::Flags(val) => fmt.field("Flags", &val),
16430 XdpAttrs::ProgId(val) => fmt.field("ProgId", &val),
16431 XdpAttrs::DrvProgId(val) => fmt.field("DrvProgId", &val),
16432 XdpAttrs::SkbProgId(val) => fmt.field("SkbProgId", &val),
16433 XdpAttrs::HwProgId(val) => fmt.field("HwProgId", &val),
16434 XdpAttrs::ExpectedFd(val) => fmt.field("ExpectedFd", &val),
16435 };
16436 }
16437 fmt.finish()
16438 }
16439}
16440impl IterableXdpAttrs<'_> {
16441 pub fn lookup_attr(
16442 &self,
16443 offset: usize,
16444 missing_type: Option<u16>,
16445 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16446 let mut stack = Vec::new();
16447 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16448 if missing_type.is_some() && cur == offset {
16449 stack.push(("XdpAttrs", offset));
16450 return (
16451 stack,
16452 missing_type.and_then(|t| XdpAttrs::attr_from_type(t)),
16453 );
16454 }
16455 if cur > offset || cur + self.buf.len() < offset {
16456 return (stack, None);
16457 }
16458 let mut attrs = self.clone();
16459 let mut last_off = cur + attrs.pos;
16460 while let Some(attr) = attrs.next() {
16461 let Ok(attr) = attr else { break };
16462 match attr {
16463 XdpAttrs::Fd(val) => {
16464 if last_off == offset {
16465 stack.push(("Fd", last_off));
16466 break;
16467 }
16468 }
16469 XdpAttrs::Attached(val) => {
16470 if last_off == offset {
16471 stack.push(("Attached", last_off));
16472 break;
16473 }
16474 }
16475 XdpAttrs::Flags(val) => {
16476 if last_off == offset {
16477 stack.push(("Flags", last_off));
16478 break;
16479 }
16480 }
16481 XdpAttrs::ProgId(val) => {
16482 if last_off == offset {
16483 stack.push(("ProgId", last_off));
16484 break;
16485 }
16486 }
16487 XdpAttrs::DrvProgId(val) => {
16488 if last_off == offset {
16489 stack.push(("DrvProgId", last_off));
16490 break;
16491 }
16492 }
16493 XdpAttrs::SkbProgId(val) => {
16494 if last_off == offset {
16495 stack.push(("SkbProgId", last_off));
16496 break;
16497 }
16498 }
16499 XdpAttrs::HwProgId(val) => {
16500 if last_off == offset {
16501 stack.push(("HwProgId", last_off));
16502 break;
16503 }
16504 }
16505 XdpAttrs::ExpectedFd(val) => {
16506 if last_off == offset {
16507 stack.push(("ExpectedFd", last_off));
16508 break;
16509 }
16510 }
16511 _ => {}
16512 };
16513 last_off = cur + attrs.pos;
16514 }
16515 if !stack.is_empty() {
16516 stack.push(("XdpAttrs", cur));
16517 }
16518 (stack, None)
16519 }
16520}
16521#[derive(Clone)]
16522pub enum IflaAttrs<'a> {
16523 #[doc = "u32 indexed by ipv4-devconf - 1 on output, on input it\\'s a nest\n"]
16524 Conf(&'a [u8]),
16525}
16526impl<'a> IterableIflaAttrs<'a> {
16527 #[doc = "u32 indexed by ipv4-devconf - 1 on output, on input it\\'s a nest\n"]
16528 pub fn get_conf(&self) -> Result<&'a [u8], ErrorContext> {
16529 let mut iter = self.clone();
16530 iter.pos = 0;
16531 for attr in iter {
16532 if let Ok(IflaAttrs::Conf(val)) = attr {
16533 return Ok(val);
16534 }
16535 }
16536 Err(ErrorContext::new_missing(
16537 "IflaAttrs",
16538 "Conf",
16539 self.orig_loc,
16540 self.buf.as_ptr() as usize,
16541 ))
16542 }
16543}
16544impl IflaAttrs<'_> {
16545 pub fn new<'a>(buf: &'a [u8]) -> IterableIflaAttrs<'a> {
16546 IterableIflaAttrs::with_loc(buf, buf.as_ptr() as usize)
16547 }
16548 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16549 let res = match r#type {
16550 1u16 => "Conf",
16551 _ => return None,
16552 };
16553 Some(res)
16554 }
16555}
16556#[derive(Clone, Copy, Default)]
16557pub struct IterableIflaAttrs<'a> {
16558 buf: &'a [u8],
16559 pos: usize,
16560 orig_loc: usize,
16561}
16562impl<'a> IterableIflaAttrs<'a> {
16563 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16564 Self {
16565 buf,
16566 pos: 0,
16567 orig_loc,
16568 }
16569 }
16570 pub fn get_buf(&self) -> &'a [u8] {
16571 self.buf
16572 }
16573}
16574impl<'a> Iterator for IterableIflaAttrs<'a> {
16575 type Item = Result<IflaAttrs<'a>, ErrorContext>;
16576 fn next(&mut self) -> Option<Self::Item> {
16577 let mut pos;
16578 let mut r#type;
16579 loop {
16580 pos = self.pos;
16581 r#type = None;
16582 if self.buf.len() == self.pos {
16583 return None;
16584 }
16585 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16586 self.pos = self.buf.len();
16587 break;
16588 };
16589 r#type = Some(header.r#type);
16590 let res = match header.r#type {
16591 1u16 => IflaAttrs::Conf({
16592 let res = Some(next);
16593 let Some(val) = res else { break };
16594 val
16595 }),
16596 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16597 n => continue,
16598 };
16599 return Some(Ok(res));
16600 }
16601 Some(Err(ErrorContext::new(
16602 "IflaAttrs",
16603 r#type.and_then(|t| IflaAttrs::attr_from_type(t)),
16604 self.orig_loc,
16605 self.buf.as_ptr().wrapping_add(pos) as usize,
16606 )))
16607 }
16608}
16609impl<'a> std::fmt::Debug for IterableIflaAttrs<'_> {
16610 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16611 let mut fmt = f.debug_struct("IflaAttrs");
16612 for attr in self.clone() {
16613 let attr = match attr {
16614 Ok(a) => a,
16615 Err(err) => {
16616 fmt.finish()?;
16617 f.write_str("Err(")?;
16618 err.fmt(f)?;
16619 return f.write_str(")");
16620 }
16621 };
16622 match attr {
16623 IflaAttrs::Conf(val) => fmt.field("Conf", &val),
16624 };
16625 }
16626 fmt.finish()
16627 }
16628}
16629impl IterableIflaAttrs<'_> {
16630 pub fn lookup_attr(
16631 &self,
16632 offset: usize,
16633 missing_type: Option<u16>,
16634 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16635 let mut stack = Vec::new();
16636 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16637 if missing_type.is_some() && cur == offset {
16638 stack.push(("IflaAttrs", offset));
16639 return (
16640 stack,
16641 missing_type.and_then(|t| IflaAttrs::attr_from_type(t)),
16642 );
16643 }
16644 if cur > offset || cur + self.buf.len() < offset {
16645 return (stack, None);
16646 }
16647 let mut attrs = self.clone();
16648 let mut last_off = cur + attrs.pos;
16649 while let Some(attr) = attrs.next() {
16650 let Ok(attr) = attr else { break };
16651 match attr {
16652 IflaAttrs::Conf(val) => {
16653 if last_off == offset {
16654 stack.push(("Conf", last_off));
16655 break;
16656 }
16657 }
16658 _ => {}
16659 };
16660 last_off = cur + attrs.pos;
16661 }
16662 if !stack.is_empty() {
16663 stack.push(("IflaAttrs", cur));
16664 }
16665 (stack, None)
16666 }
16667}
16668#[derive(Clone)]
16669pub enum Ifla6Attrs<'a> {
16670 Flags(u32),
16671 #[doc = "u32 indexed by ipv6-devconf - 1 on output, on input it\\'s a nest\n"]
16672 Conf(&'a [u8]),
16673 Stats(&'a [u8]),
16674 Mcast(&'a [u8]),
16675 Cacheinfo(IflaCacheinfo),
16676 Icmp6stats(&'a [u8]),
16677 Token(&'a [u8]),
16678 AddrGenMode(u8),
16679 RaMtu(u32),
16680}
16681impl<'a> IterableIfla6Attrs<'a> {
16682 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
16683 let mut iter = self.clone();
16684 iter.pos = 0;
16685 for attr in iter {
16686 if let Ok(Ifla6Attrs::Flags(val)) = attr {
16687 return Ok(val);
16688 }
16689 }
16690 Err(ErrorContext::new_missing(
16691 "Ifla6Attrs",
16692 "Flags",
16693 self.orig_loc,
16694 self.buf.as_ptr() as usize,
16695 ))
16696 }
16697 #[doc = "u32 indexed by ipv6-devconf - 1 on output, on input it\\'s a nest\n"]
16698 pub fn get_conf(&self) -> Result<&'a [u8], ErrorContext> {
16699 let mut iter = self.clone();
16700 iter.pos = 0;
16701 for attr in iter {
16702 if let Ok(Ifla6Attrs::Conf(val)) = attr {
16703 return Ok(val);
16704 }
16705 }
16706 Err(ErrorContext::new_missing(
16707 "Ifla6Attrs",
16708 "Conf",
16709 self.orig_loc,
16710 self.buf.as_ptr() as usize,
16711 ))
16712 }
16713 pub fn get_stats(&self) -> Result<&'a [u8], ErrorContext> {
16714 let mut iter = self.clone();
16715 iter.pos = 0;
16716 for attr in iter {
16717 if let Ok(Ifla6Attrs::Stats(val)) = attr {
16718 return Ok(val);
16719 }
16720 }
16721 Err(ErrorContext::new_missing(
16722 "Ifla6Attrs",
16723 "Stats",
16724 self.orig_loc,
16725 self.buf.as_ptr() as usize,
16726 ))
16727 }
16728 pub fn get_mcast(&self) -> Result<&'a [u8], ErrorContext> {
16729 let mut iter = self.clone();
16730 iter.pos = 0;
16731 for attr in iter {
16732 if let Ok(Ifla6Attrs::Mcast(val)) = attr {
16733 return Ok(val);
16734 }
16735 }
16736 Err(ErrorContext::new_missing(
16737 "Ifla6Attrs",
16738 "Mcast",
16739 self.orig_loc,
16740 self.buf.as_ptr() as usize,
16741 ))
16742 }
16743 pub fn get_cacheinfo(&self) -> Result<IflaCacheinfo, ErrorContext> {
16744 let mut iter = self.clone();
16745 iter.pos = 0;
16746 for attr in iter {
16747 if let Ok(Ifla6Attrs::Cacheinfo(val)) = attr {
16748 return Ok(val);
16749 }
16750 }
16751 Err(ErrorContext::new_missing(
16752 "Ifla6Attrs",
16753 "Cacheinfo",
16754 self.orig_loc,
16755 self.buf.as_ptr() as usize,
16756 ))
16757 }
16758 pub fn get_icmp6stats(&self) -> Result<&'a [u8], ErrorContext> {
16759 let mut iter = self.clone();
16760 iter.pos = 0;
16761 for attr in iter {
16762 if let Ok(Ifla6Attrs::Icmp6stats(val)) = attr {
16763 return Ok(val);
16764 }
16765 }
16766 Err(ErrorContext::new_missing(
16767 "Ifla6Attrs",
16768 "Icmp6stats",
16769 self.orig_loc,
16770 self.buf.as_ptr() as usize,
16771 ))
16772 }
16773 pub fn get_token(&self) -> Result<&'a [u8], ErrorContext> {
16774 let mut iter = self.clone();
16775 iter.pos = 0;
16776 for attr in iter {
16777 if let Ok(Ifla6Attrs::Token(val)) = attr {
16778 return Ok(val);
16779 }
16780 }
16781 Err(ErrorContext::new_missing(
16782 "Ifla6Attrs",
16783 "Token",
16784 self.orig_loc,
16785 self.buf.as_ptr() as usize,
16786 ))
16787 }
16788 pub fn get_addr_gen_mode(&self) -> Result<u8, ErrorContext> {
16789 let mut iter = self.clone();
16790 iter.pos = 0;
16791 for attr in iter {
16792 if let Ok(Ifla6Attrs::AddrGenMode(val)) = attr {
16793 return Ok(val);
16794 }
16795 }
16796 Err(ErrorContext::new_missing(
16797 "Ifla6Attrs",
16798 "AddrGenMode",
16799 self.orig_loc,
16800 self.buf.as_ptr() as usize,
16801 ))
16802 }
16803 pub fn get_ra_mtu(&self) -> Result<u32, ErrorContext> {
16804 let mut iter = self.clone();
16805 iter.pos = 0;
16806 for attr in iter {
16807 if let Ok(Ifla6Attrs::RaMtu(val)) = attr {
16808 return Ok(val);
16809 }
16810 }
16811 Err(ErrorContext::new_missing(
16812 "Ifla6Attrs",
16813 "RaMtu",
16814 self.orig_loc,
16815 self.buf.as_ptr() as usize,
16816 ))
16817 }
16818}
16819impl Ifla6Attrs<'_> {
16820 pub fn new<'a>(buf: &'a [u8]) -> IterableIfla6Attrs<'a> {
16821 IterableIfla6Attrs::with_loc(buf, buf.as_ptr() as usize)
16822 }
16823 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16824 let res = match r#type {
16825 1u16 => "Flags",
16826 2u16 => "Conf",
16827 3u16 => "Stats",
16828 4u16 => "Mcast",
16829 5u16 => "Cacheinfo",
16830 6u16 => "Icmp6stats",
16831 7u16 => "Token",
16832 8u16 => "AddrGenMode",
16833 9u16 => "RaMtu",
16834 _ => return None,
16835 };
16836 Some(res)
16837 }
16838}
16839#[derive(Clone, Copy, Default)]
16840pub struct IterableIfla6Attrs<'a> {
16841 buf: &'a [u8],
16842 pos: usize,
16843 orig_loc: usize,
16844}
16845impl<'a> IterableIfla6Attrs<'a> {
16846 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16847 Self {
16848 buf,
16849 pos: 0,
16850 orig_loc,
16851 }
16852 }
16853 pub fn get_buf(&self) -> &'a [u8] {
16854 self.buf
16855 }
16856}
16857impl<'a> Iterator for IterableIfla6Attrs<'a> {
16858 type Item = Result<Ifla6Attrs<'a>, ErrorContext>;
16859 fn next(&mut self) -> Option<Self::Item> {
16860 let mut pos;
16861 let mut r#type;
16862 loop {
16863 pos = self.pos;
16864 r#type = None;
16865 if self.buf.len() == self.pos {
16866 return None;
16867 }
16868 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16869 self.pos = self.buf.len();
16870 break;
16871 };
16872 r#type = Some(header.r#type);
16873 let res = match header.r#type {
16874 1u16 => Ifla6Attrs::Flags({
16875 let res = parse_u32(next);
16876 let Some(val) = res else { break };
16877 val
16878 }),
16879 2u16 => Ifla6Attrs::Conf({
16880 let res = Some(next);
16881 let Some(val) = res else { break };
16882 val
16883 }),
16884 3u16 => Ifla6Attrs::Stats({
16885 let res = Some(next);
16886 let Some(val) = res else { break };
16887 val
16888 }),
16889 4u16 => Ifla6Attrs::Mcast({
16890 let res = Some(next);
16891 let Some(val) = res else { break };
16892 val
16893 }),
16894 5u16 => Ifla6Attrs::Cacheinfo({
16895 let res = Some(IflaCacheinfo::new_from_zeroed(next));
16896 let Some(val) = res else { break };
16897 val
16898 }),
16899 6u16 => Ifla6Attrs::Icmp6stats({
16900 let res = Some(next);
16901 let Some(val) = res else { break };
16902 val
16903 }),
16904 7u16 => Ifla6Attrs::Token({
16905 let res = Some(next);
16906 let Some(val) = res else { break };
16907 val
16908 }),
16909 8u16 => Ifla6Attrs::AddrGenMode({
16910 let res = parse_u8(next);
16911 let Some(val) = res else { break };
16912 val
16913 }),
16914 9u16 => Ifla6Attrs::RaMtu({
16915 let res = parse_u32(next);
16916 let Some(val) = res else { break };
16917 val
16918 }),
16919 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16920 n => continue,
16921 };
16922 return Some(Ok(res));
16923 }
16924 Some(Err(ErrorContext::new(
16925 "Ifla6Attrs",
16926 r#type.and_then(|t| Ifla6Attrs::attr_from_type(t)),
16927 self.orig_loc,
16928 self.buf.as_ptr().wrapping_add(pos) as usize,
16929 )))
16930 }
16931}
16932impl<'a> std::fmt::Debug for IterableIfla6Attrs<'_> {
16933 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16934 let mut fmt = f.debug_struct("Ifla6Attrs");
16935 for attr in self.clone() {
16936 let attr = match attr {
16937 Ok(a) => a,
16938 Err(err) => {
16939 fmt.finish()?;
16940 f.write_str("Err(")?;
16941 err.fmt(f)?;
16942 return f.write_str(")");
16943 }
16944 };
16945 match attr {
16946 Ifla6Attrs::Flags(val) => fmt.field("Flags", &val),
16947 Ifla6Attrs::Conf(val) => fmt.field("Conf", &val),
16948 Ifla6Attrs::Stats(val) => fmt.field("Stats", &val),
16949 Ifla6Attrs::Mcast(val) => fmt.field("Mcast", &val),
16950 Ifla6Attrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
16951 Ifla6Attrs::Icmp6stats(val) => fmt.field("Icmp6stats", &val),
16952 Ifla6Attrs::Token(val) => fmt.field("Token", &val),
16953 Ifla6Attrs::AddrGenMode(val) => fmt.field("AddrGenMode", &val),
16954 Ifla6Attrs::RaMtu(val) => fmt.field("RaMtu", &val),
16955 };
16956 }
16957 fmt.finish()
16958 }
16959}
16960impl IterableIfla6Attrs<'_> {
16961 pub fn lookup_attr(
16962 &self,
16963 offset: usize,
16964 missing_type: Option<u16>,
16965 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16966 let mut stack = Vec::new();
16967 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16968 if missing_type.is_some() && cur == offset {
16969 stack.push(("Ifla6Attrs", offset));
16970 return (
16971 stack,
16972 missing_type.and_then(|t| Ifla6Attrs::attr_from_type(t)),
16973 );
16974 }
16975 if cur > offset || cur + self.buf.len() < offset {
16976 return (stack, None);
16977 }
16978 let mut attrs = self.clone();
16979 let mut last_off = cur + attrs.pos;
16980 while let Some(attr) = attrs.next() {
16981 let Ok(attr) = attr else { break };
16982 match attr {
16983 Ifla6Attrs::Flags(val) => {
16984 if last_off == offset {
16985 stack.push(("Flags", last_off));
16986 break;
16987 }
16988 }
16989 Ifla6Attrs::Conf(val) => {
16990 if last_off == offset {
16991 stack.push(("Conf", last_off));
16992 break;
16993 }
16994 }
16995 Ifla6Attrs::Stats(val) => {
16996 if last_off == offset {
16997 stack.push(("Stats", last_off));
16998 break;
16999 }
17000 }
17001 Ifla6Attrs::Mcast(val) => {
17002 if last_off == offset {
17003 stack.push(("Mcast", last_off));
17004 break;
17005 }
17006 }
17007 Ifla6Attrs::Cacheinfo(val) => {
17008 if last_off == offset {
17009 stack.push(("Cacheinfo", last_off));
17010 break;
17011 }
17012 }
17013 Ifla6Attrs::Icmp6stats(val) => {
17014 if last_off == offset {
17015 stack.push(("Icmp6stats", last_off));
17016 break;
17017 }
17018 }
17019 Ifla6Attrs::Token(val) => {
17020 if last_off == offset {
17021 stack.push(("Token", last_off));
17022 break;
17023 }
17024 }
17025 Ifla6Attrs::AddrGenMode(val) => {
17026 if last_off == offset {
17027 stack.push(("AddrGenMode", last_off));
17028 break;
17029 }
17030 }
17031 Ifla6Attrs::RaMtu(val) => {
17032 if last_off == offset {
17033 stack.push(("RaMtu", last_off));
17034 break;
17035 }
17036 }
17037 _ => {}
17038 };
17039 last_off = cur + attrs.pos;
17040 }
17041 if !stack.is_empty() {
17042 stack.push(("Ifla6Attrs", cur));
17043 }
17044 (stack, None)
17045 }
17046}
17047#[derive(Clone)]
17048pub enum MctpAttrs {
17049 Net(u32),
17050 PhysBinding(u8),
17051}
17052impl<'a> IterableMctpAttrs<'a> {
17053 pub fn get_net(&self) -> Result<u32, ErrorContext> {
17054 let mut iter = self.clone();
17055 iter.pos = 0;
17056 for attr in iter {
17057 if let Ok(MctpAttrs::Net(val)) = attr {
17058 return Ok(val);
17059 }
17060 }
17061 Err(ErrorContext::new_missing(
17062 "MctpAttrs",
17063 "Net",
17064 self.orig_loc,
17065 self.buf.as_ptr() as usize,
17066 ))
17067 }
17068 pub fn get_phys_binding(&self) -> Result<u8, ErrorContext> {
17069 let mut iter = self.clone();
17070 iter.pos = 0;
17071 for attr in iter {
17072 if let Ok(MctpAttrs::PhysBinding(val)) = attr {
17073 return Ok(val);
17074 }
17075 }
17076 Err(ErrorContext::new_missing(
17077 "MctpAttrs",
17078 "PhysBinding",
17079 self.orig_loc,
17080 self.buf.as_ptr() as usize,
17081 ))
17082 }
17083}
17084impl MctpAttrs {
17085 pub fn new<'a>(buf: &'a [u8]) -> IterableMctpAttrs<'a> {
17086 IterableMctpAttrs::with_loc(buf, buf.as_ptr() as usize)
17087 }
17088 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17089 let res = match r#type {
17090 1u16 => "Net",
17091 2u16 => "PhysBinding",
17092 _ => return None,
17093 };
17094 Some(res)
17095 }
17096}
17097#[derive(Clone, Copy, Default)]
17098pub struct IterableMctpAttrs<'a> {
17099 buf: &'a [u8],
17100 pos: usize,
17101 orig_loc: usize,
17102}
17103impl<'a> IterableMctpAttrs<'a> {
17104 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17105 Self {
17106 buf,
17107 pos: 0,
17108 orig_loc,
17109 }
17110 }
17111 pub fn get_buf(&self) -> &'a [u8] {
17112 self.buf
17113 }
17114}
17115impl<'a> Iterator for IterableMctpAttrs<'a> {
17116 type Item = Result<MctpAttrs, ErrorContext>;
17117 fn next(&mut self) -> Option<Self::Item> {
17118 let mut pos;
17119 let mut r#type;
17120 loop {
17121 pos = self.pos;
17122 r#type = None;
17123 if self.buf.len() == self.pos {
17124 return None;
17125 }
17126 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17127 self.pos = self.buf.len();
17128 break;
17129 };
17130 r#type = Some(header.r#type);
17131 let res = match header.r#type {
17132 1u16 => MctpAttrs::Net({
17133 let res = parse_u32(next);
17134 let Some(val) = res else { break };
17135 val
17136 }),
17137 2u16 => MctpAttrs::PhysBinding({
17138 let res = parse_u8(next);
17139 let Some(val) = res else { break };
17140 val
17141 }),
17142 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17143 n => continue,
17144 };
17145 return Some(Ok(res));
17146 }
17147 Some(Err(ErrorContext::new(
17148 "MctpAttrs",
17149 r#type.and_then(|t| MctpAttrs::attr_from_type(t)),
17150 self.orig_loc,
17151 self.buf.as_ptr().wrapping_add(pos) as usize,
17152 )))
17153 }
17154}
17155impl std::fmt::Debug for IterableMctpAttrs<'_> {
17156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17157 let mut fmt = f.debug_struct("MctpAttrs");
17158 for attr in self.clone() {
17159 let attr = match attr {
17160 Ok(a) => a,
17161 Err(err) => {
17162 fmt.finish()?;
17163 f.write_str("Err(")?;
17164 err.fmt(f)?;
17165 return f.write_str(")");
17166 }
17167 };
17168 match attr {
17169 MctpAttrs::Net(val) => fmt.field("Net", &val),
17170 MctpAttrs::PhysBinding(val) => fmt.field("PhysBinding", &val),
17171 };
17172 }
17173 fmt.finish()
17174 }
17175}
17176impl IterableMctpAttrs<'_> {
17177 pub fn lookup_attr(
17178 &self,
17179 offset: usize,
17180 missing_type: Option<u16>,
17181 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17182 let mut stack = Vec::new();
17183 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17184 if missing_type.is_some() && cur == offset {
17185 stack.push(("MctpAttrs", offset));
17186 return (
17187 stack,
17188 missing_type.and_then(|t| MctpAttrs::attr_from_type(t)),
17189 );
17190 }
17191 if cur > offset || cur + self.buf.len() < offset {
17192 return (stack, None);
17193 }
17194 let mut attrs = self.clone();
17195 let mut last_off = cur + attrs.pos;
17196 while let Some(attr) = attrs.next() {
17197 let Ok(attr) = attr else { break };
17198 match attr {
17199 MctpAttrs::Net(val) => {
17200 if last_off == offset {
17201 stack.push(("Net", last_off));
17202 break;
17203 }
17204 }
17205 MctpAttrs::PhysBinding(val) => {
17206 if last_off == offset {
17207 stack.push(("PhysBinding", last_off));
17208 break;
17209 }
17210 }
17211 _ => {}
17212 };
17213 last_off = cur + attrs.pos;
17214 }
17215 if !stack.is_empty() {
17216 stack.push(("MctpAttrs", cur));
17217 }
17218 (stack, None)
17219 }
17220}
17221#[derive(Clone)]
17222pub enum StatsAttrs<'a> {
17223 Link64(RtnlLinkStats64),
17224 LinkXstats(&'a [u8]),
17225 LinkXstatsSlave(&'a [u8]),
17226 LinkOffloadXstats(IterableLinkOffloadXstats<'a>),
17227 AfSpec(&'a [u8]),
17228}
17229impl<'a> IterableStatsAttrs<'a> {
17230 pub fn get_link_64(&self) -> Result<RtnlLinkStats64, ErrorContext> {
17231 let mut iter = self.clone();
17232 iter.pos = 0;
17233 for attr in iter {
17234 if let Ok(StatsAttrs::Link64(val)) = attr {
17235 return Ok(val);
17236 }
17237 }
17238 Err(ErrorContext::new_missing(
17239 "StatsAttrs",
17240 "Link64",
17241 self.orig_loc,
17242 self.buf.as_ptr() as usize,
17243 ))
17244 }
17245 pub fn get_link_xstats(&self) -> Result<&'a [u8], ErrorContext> {
17246 let mut iter = self.clone();
17247 iter.pos = 0;
17248 for attr in iter {
17249 if let Ok(StatsAttrs::LinkXstats(val)) = attr {
17250 return Ok(val);
17251 }
17252 }
17253 Err(ErrorContext::new_missing(
17254 "StatsAttrs",
17255 "LinkXstats",
17256 self.orig_loc,
17257 self.buf.as_ptr() as usize,
17258 ))
17259 }
17260 pub fn get_link_xstats_slave(&self) -> Result<&'a [u8], ErrorContext> {
17261 let mut iter = self.clone();
17262 iter.pos = 0;
17263 for attr in iter {
17264 if let Ok(StatsAttrs::LinkXstatsSlave(val)) = attr {
17265 return Ok(val);
17266 }
17267 }
17268 Err(ErrorContext::new_missing(
17269 "StatsAttrs",
17270 "LinkXstatsSlave",
17271 self.orig_loc,
17272 self.buf.as_ptr() as usize,
17273 ))
17274 }
17275 pub fn get_link_offload_xstats(&self) -> Result<IterableLinkOffloadXstats<'a>, ErrorContext> {
17276 let mut iter = self.clone();
17277 iter.pos = 0;
17278 for attr in iter {
17279 if let Ok(StatsAttrs::LinkOffloadXstats(val)) = attr {
17280 return Ok(val);
17281 }
17282 }
17283 Err(ErrorContext::new_missing(
17284 "StatsAttrs",
17285 "LinkOffloadXstats",
17286 self.orig_loc,
17287 self.buf.as_ptr() as usize,
17288 ))
17289 }
17290 pub fn get_af_spec(&self) -> Result<&'a [u8], ErrorContext> {
17291 let mut iter = self.clone();
17292 iter.pos = 0;
17293 for attr in iter {
17294 if let Ok(StatsAttrs::AfSpec(val)) = attr {
17295 return Ok(val);
17296 }
17297 }
17298 Err(ErrorContext::new_missing(
17299 "StatsAttrs",
17300 "AfSpec",
17301 self.orig_loc,
17302 self.buf.as_ptr() as usize,
17303 ))
17304 }
17305}
17306impl StatsAttrs<'_> {
17307 pub fn new<'a>(buf: &'a [u8]) -> IterableStatsAttrs<'a> {
17308 IterableStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
17309 }
17310 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17311 let res = match r#type {
17312 1u16 => "Link64",
17313 2u16 => "LinkXstats",
17314 3u16 => "LinkXstatsSlave",
17315 4u16 => "LinkOffloadXstats",
17316 5u16 => "AfSpec",
17317 _ => return None,
17318 };
17319 Some(res)
17320 }
17321}
17322#[derive(Clone, Copy, Default)]
17323pub struct IterableStatsAttrs<'a> {
17324 buf: &'a [u8],
17325 pos: usize,
17326 orig_loc: usize,
17327}
17328impl<'a> IterableStatsAttrs<'a> {
17329 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17330 Self {
17331 buf,
17332 pos: 0,
17333 orig_loc,
17334 }
17335 }
17336 pub fn get_buf(&self) -> &'a [u8] {
17337 self.buf
17338 }
17339}
17340impl<'a> Iterator for IterableStatsAttrs<'a> {
17341 type Item = Result<StatsAttrs<'a>, ErrorContext>;
17342 fn next(&mut self) -> Option<Self::Item> {
17343 let mut pos;
17344 let mut r#type;
17345 loop {
17346 pos = self.pos;
17347 r#type = None;
17348 if self.buf.len() == self.pos {
17349 return None;
17350 }
17351 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17352 self.pos = self.buf.len();
17353 break;
17354 };
17355 r#type = Some(header.r#type);
17356 let res = match header.r#type {
17357 1u16 => StatsAttrs::Link64({
17358 let res = Some(RtnlLinkStats64::new_from_zeroed(next));
17359 let Some(val) = res else { break };
17360 val
17361 }),
17362 2u16 => StatsAttrs::LinkXstats({
17363 let res = Some(next);
17364 let Some(val) = res else { break };
17365 val
17366 }),
17367 3u16 => StatsAttrs::LinkXstatsSlave({
17368 let res = Some(next);
17369 let Some(val) = res else { break };
17370 val
17371 }),
17372 4u16 => StatsAttrs::LinkOffloadXstats({
17373 let res = Some(IterableLinkOffloadXstats::with_loc(next, self.orig_loc));
17374 let Some(val) = res else { break };
17375 val
17376 }),
17377 5u16 => StatsAttrs::AfSpec({
17378 let res = Some(next);
17379 let Some(val) = res else { break };
17380 val
17381 }),
17382 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17383 n => continue,
17384 };
17385 return Some(Ok(res));
17386 }
17387 Some(Err(ErrorContext::new(
17388 "StatsAttrs",
17389 r#type.and_then(|t| StatsAttrs::attr_from_type(t)),
17390 self.orig_loc,
17391 self.buf.as_ptr().wrapping_add(pos) as usize,
17392 )))
17393 }
17394}
17395impl<'a> std::fmt::Debug for IterableStatsAttrs<'_> {
17396 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17397 let mut fmt = f.debug_struct("StatsAttrs");
17398 for attr in self.clone() {
17399 let attr = match attr {
17400 Ok(a) => a,
17401 Err(err) => {
17402 fmt.finish()?;
17403 f.write_str("Err(")?;
17404 err.fmt(f)?;
17405 return f.write_str(")");
17406 }
17407 };
17408 match attr {
17409 StatsAttrs::Link64(val) => fmt.field("Link64", &val),
17410 StatsAttrs::LinkXstats(val) => fmt.field("LinkXstats", &val),
17411 StatsAttrs::LinkXstatsSlave(val) => fmt.field("LinkXstatsSlave", &val),
17412 StatsAttrs::LinkOffloadXstats(val) => fmt.field("LinkOffloadXstats", &val),
17413 StatsAttrs::AfSpec(val) => fmt.field("AfSpec", &val),
17414 };
17415 }
17416 fmt.finish()
17417 }
17418}
17419impl IterableStatsAttrs<'_> {
17420 pub fn lookup_attr(
17421 &self,
17422 offset: usize,
17423 missing_type: Option<u16>,
17424 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17425 let mut stack = Vec::new();
17426 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17427 if missing_type.is_some() && cur == offset {
17428 stack.push(("StatsAttrs", offset));
17429 return (
17430 stack,
17431 missing_type.and_then(|t| StatsAttrs::attr_from_type(t)),
17432 );
17433 }
17434 if cur > offset || cur + self.buf.len() < offset {
17435 return (stack, None);
17436 }
17437 let mut attrs = self.clone();
17438 let mut last_off = cur + attrs.pos;
17439 let mut missing = None;
17440 while let Some(attr) = attrs.next() {
17441 let Ok(attr) = attr else { break };
17442 match attr {
17443 StatsAttrs::Link64(val) => {
17444 if last_off == offset {
17445 stack.push(("Link64", last_off));
17446 break;
17447 }
17448 }
17449 StatsAttrs::LinkXstats(val) => {
17450 if last_off == offset {
17451 stack.push(("LinkXstats", last_off));
17452 break;
17453 }
17454 }
17455 StatsAttrs::LinkXstatsSlave(val) => {
17456 if last_off == offset {
17457 stack.push(("LinkXstatsSlave", last_off));
17458 break;
17459 }
17460 }
17461 StatsAttrs::LinkOffloadXstats(val) => {
17462 (stack, missing) = val.lookup_attr(offset, missing_type);
17463 if !stack.is_empty() {
17464 break;
17465 }
17466 }
17467 StatsAttrs::AfSpec(val) => {
17468 if last_off == offset {
17469 stack.push(("AfSpec", last_off));
17470 break;
17471 }
17472 }
17473 _ => {}
17474 };
17475 last_off = cur + attrs.pos;
17476 }
17477 if !stack.is_empty() {
17478 stack.push(("StatsAttrs", cur));
17479 }
17480 (stack, missing)
17481 }
17482}
17483#[derive(Clone)]
17484pub enum LinkOffloadXstats<'a> {
17485 CpuHit(&'a [u8]),
17486 HwSInfo(IterableArrayHwSInfoOne<'a>),
17487 L3Stats(&'a [u8]),
17488}
17489impl<'a> IterableLinkOffloadXstats<'a> {
17490 pub fn get_cpu_hit(&self) -> Result<&'a [u8], ErrorContext> {
17491 let mut iter = self.clone();
17492 iter.pos = 0;
17493 for attr in iter {
17494 if let Ok(LinkOffloadXstats::CpuHit(val)) = attr {
17495 return Ok(val);
17496 }
17497 }
17498 Err(ErrorContext::new_missing(
17499 "LinkOffloadXstats",
17500 "CpuHit",
17501 self.orig_loc,
17502 self.buf.as_ptr() as usize,
17503 ))
17504 }
17505 pub fn get_hw_s_info(
17506 &self,
17507 ) -> Result<ArrayIterable<IterableArrayHwSInfoOne<'a>, IterableHwSInfoOne<'a>>, ErrorContext>
17508 {
17509 for attr in self.clone() {
17510 if let Ok(LinkOffloadXstats::HwSInfo(val)) = attr {
17511 return Ok(ArrayIterable::new(val));
17512 }
17513 }
17514 Err(ErrorContext::new_missing(
17515 "LinkOffloadXstats",
17516 "HwSInfo",
17517 self.orig_loc,
17518 self.buf.as_ptr() as usize,
17519 ))
17520 }
17521 pub fn get_l3_stats(&self) -> Result<&'a [u8], ErrorContext> {
17522 let mut iter = self.clone();
17523 iter.pos = 0;
17524 for attr in iter {
17525 if let Ok(LinkOffloadXstats::L3Stats(val)) = attr {
17526 return Ok(val);
17527 }
17528 }
17529 Err(ErrorContext::new_missing(
17530 "LinkOffloadXstats",
17531 "L3Stats",
17532 self.orig_loc,
17533 self.buf.as_ptr() as usize,
17534 ))
17535 }
17536}
17537impl HwSInfoOne {
17538 pub fn new_array(buf: &[u8]) -> IterableArrayHwSInfoOne<'_> {
17539 IterableArrayHwSInfoOne::with_loc(buf, buf.as_ptr() as usize)
17540 }
17541}
17542#[derive(Clone, Copy, Default)]
17543pub struct IterableArrayHwSInfoOne<'a> {
17544 buf: &'a [u8],
17545 pos: usize,
17546 orig_loc: usize,
17547}
17548impl<'a> IterableArrayHwSInfoOne<'a> {
17549 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17550 Self {
17551 buf,
17552 pos: 0,
17553 orig_loc,
17554 }
17555 }
17556 pub fn get_buf(&self) -> &'a [u8] {
17557 self.buf
17558 }
17559}
17560impl<'a> Iterator for IterableArrayHwSInfoOne<'a> {
17561 type Item = Result<IterableHwSInfoOne<'a>, ErrorContext>;
17562 fn next(&mut self) -> Option<Self::Item> {
17563 if self.buf.len() == self.pos {
17564 return None;
17565 }
17566 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
17567 {
17568 return Some(Ok(IterableHwSInfoOne::with_loc(next, self.orig_loc)));
17569 }
17570 }
17571 let pos = self.pos;
17572 self.pos = self.buf.len();
17573 Some(Err(ErrorContext::new(
17574 "HwSInfoOne",
17575 None,
17576 self.orig_loc,
17577 self.buf.as_ptr().wrapping_add(pos) as usize,
17578 )))
17579 }
17580}
17581impl LinkOffloadXstats<'_> {
17582 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkOffloadXstats<'a> {
17583 IterableLinkOffloadXstats::with_loc(buf, buf.as_ptr() as usize)
17584 }
17585 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17586 let res = match r#type {
17587 1u16 => "CpuHit",
17588 2u16 => "HwSInfo",
17589 3u16 => "L3Stats",
17590 _ => return None,
17591 };
17592 Some(res)
17593 }
17594}
17595#[derive(Clone, Copy, Default)]
17596pub struct IterableLinkOffloadXstats<'a> {
17597 buf: &'a [u8],
17598 pos: usize,
17599 orig_loc: usize,
17600}
17601impl<'a> IterableLinkOffloadXstats<'a> {
17602 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17603 Self {
17604 buf,
17605 pos: 0,
17606 orig_loc,
17607 }
17608 }
17609 pub fn get_buf(&self) -> &'a [u8] {
17610 self.buf
17611 }
17612}
17613impl<'a> Iterator for IterableLinkOffloadXstats<'a> {
17614 type Item = Result<LinkOffloadXstats<'a>, ErrorContext>;
17615 fn next(&mut self) -> Option<Self::Item> {
17616 let mut pos;
17617 let mut r#type;
17618 loop {
17619 pos = self.pos;
17620 r#type = None;
17621 if self.buf.len() == self.pos {
17622 return None;
17623 }
17624 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17625 self.pos = self.buf.len();
17626 break;
17627 };
17628 r#type = Some(header.r#type);
17629 let res = match header.r#type {
17630 1u16 => LinkOffloadXstats::CpuHit({
17631 let res = Some(next);
17632 let Some(val) = res else { break };
17633 val
17634 }),
17635 2u16 => LinkOffloadXstats::HwSInfo({
17636 let res = Some(IterableArrayHwSInfoOne::with_loc(next, self.orig_loc));
17637 let Some(val) = res else { break };
17638 val
17639 }),
17640 3u16 => LinkOffloadXstats::L3Stats({
17641 let res = Some(next);
17642 let Some(val) = res else { break };
17643 val
17644 }),
17645 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17646 n => continue,
17647 };
17648 return Some(Ok(res));
17649 }
17650 Some(Err(ErrorContext::new(
17651 "LinkOffloadXstats",
17652 r#type.and_then(|t| LinkOffloadXstats::attr_from_type(t)),
17653 self.orig_loc,
17654 self.buf.as_ptr().wrapping_add(pos) as usize,
17655 )))
17656 }
17657}
17658impl std::fmt::Debug for IterableArrayHwSInfoOne<'_> {
17659 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17660 fmt.debug_list()
17661 .entries(self.clone().map(FlattenErrorContext))
17662 .finish()
17663 }
17664}
17665impl<'a> std::fmt::Debug for IterableLinkOffloadXstats<'_> {
17666 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17667 let mut fmt = f.debug_struct("LinkOffloadXstats");
17668 for attr in self.clone() {
17669 let attr = match attr {
17670 Ok(a) => a,
17671 Err(err) => {
17672 fmt.finish()?;
17673 f.write_str("Err(")?;
17674 err.fmt(f)?;
17675 return f.write_str(")");
17676 }
17677 };
17678 match attr {
17679 LinkOffloadXstats::CpuHit(val) => fmt.field("CpuHit", &val),
17680 LinkOffloadXstats::HwSInfo(val) => fmt.field("HwSInfo", &val),
17681 LinkOffloadXstats::L3Stats(val) => fmt.field("L3Stats", &val),
17682 };
17683 }
17684 fmt.finish()
17685 }
17686}
17687impl IterableLinkOffloadXstats<'_> {
17688 pub fn lookup_attr(
17689 &self,
17690 offset: usize,
17691 missing_type: Option<u16>,
17692 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17693 let mut stack = Vec::new();
17694 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17695 if missing_type.is_some() && cur == offset {
17696 stack.push(("LinkOffloadXstats", offset));
17697 return (
17698 stack,
17699 missing_type.and_then(|t| LinkOffloadXstats::attr_from_type(t)),
17700 );
17701 }
17702 if cur > offset || cur + self.buf.len() < offset {
17703 return (stack, None);
17704 }
17705 let mut attrs = self.clone();
17706 let mut last_off = cur + attrs.pos;
17707 let mut missing = None;
17708 while let Some(attr) = attrs.next() {
17709 let Ok(attr) = attr else { break };
17710 match attr {
17711 LinkOffloadXstats::CpuHit(val) => {
17712 if last_off == offset {
17713 stack.push(("CpuHit", last_off));
17714 break;
17715 }
17716 }
17717 LinkOffloadXstats::HwSInfo(val) => {
17718 for entry in val {
17719 let Ok(attr) = entry else { break };
17720 (stack, missing) = attr.lookup_attr(offset, missing_type);
17721 if !stack.is_empty() {
17722 break;
17723 }
17724 }
17725 if !stack.is_empty() {
17726 stack.push(("HwSInfo", last_off));
17727 break;
17728 }
17729 }
17730 LinkOffloadXstats::L3Stats(val) => {
17731 if last_off == offset {
17732 stack.push(("L3Stats", last_off));
17733 break;
17734 }
17735 }
17736 _ => {}
17737 };
17738 last_off = cur + attrs.pos;
17739 }
17740 if !stack.is_empty() {
17741 stack.push(("LinkOffloadXstats", cur));
17742 }
17743 (stack, missing)
17744 }
17745}
17746#[derive(Clone)]
17747pub enum HwSInfoOne {
17748 Request(u8),
17749 Used(u8),
17750}
17751impl<'a> IterableHwSInfoOne<'a> {
17752 pub fn get_request(&self) -> Result<u8, ErrorContext> {
17753 let mut iter = self.clone();
17754 iter.pos = 0;
17755 for attr in iter {
17756 if let Ok(HwSInfoOne::Request(val)) = attr {
17757 return Ok(val);
17758 }
17759 }
17760 Err(ErrorContext::new_missing(
17761 "HwSInfoOne",
17762 "Request",
17763 self.orig_loc,
17764 self.buf.as_ptr() as usize,
17765 ))
17766 }
17767 pub fn get_used(&self) -> Result<u8, ErrorContext> {
17768 let mut iter = self.clone();
17769 iter.pos = 0;
17770 for attr in iter {
17771 if let Ok(HwSInfoOne::Used(val)) = attr {
17772 return Ok(val);
17773 }
17774 }
17775 Err(ErrorContext::new_missing(
17776 "HwSInfoOne",
17777 "Used",
17778 self.orig_loc,
17779 self.buf.as_ptr() as usize,
17780 ))
17781 }
17782}
17783impl HwSInfoOne {
17784 pub fn new<'a>(buf: &'a [u8]) -> IterableHwSInfoOne<'a> {
17785 IterableHwSInfoOne::with_loc(buf, buf.as_ptr() as usize)
17786 }
17787 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17788 let res = match r#type {
17789 1u16 => "Request",
17790 2u16 => "Used",
17791 _ => return None,
17792 };
17793 Some(res)
17794 }
17795}
17796#[derive(Clone, Copy, Default)]
17797pub struct IterableHwSInfoOne<'a> {
17798 buf: &'a [u8],
17799 pos: usize,
17800 orig_loc: usize,
17801}
17802impl<'a> IterableHwSInfoOne<'a> {
17803 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17804 Self {
17805 buf,
17806 pos: 0,
17807 orig_loc,
17808 }
17809 }
17810 pub fn get_buf(&self) -> &'a [u8] {
17811 self.buf
17812 }
17813}
17814impl<'a> Iterator for IterableHwSInfoOne<'a> {
17815 type Item = Result<HwSInfoOne, ErrorContext>;
17816 fn next(&mut self) -> Option<Self::Item> {
17817 let mut pos;
17818 let mut r#type;
17819 loop {
17820 pos = self.pos;
17821 r#type = None;
17822 if self.buf.len() == self.pos {
17823 return None;
17824 }
17825 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17826 self.pos = self.buf.len();
17827 break;
17828 };
17829 r#type = Some(header.r#type);
17830 let res = match header.r#type {
17831 1u16 => HwSInfoOne::Request({
17832 let res = parse_u8(next);
17833 let Some(val) = res else { break };
17834 val
17835 }),
17836 2u16 => HwSInfoOne::Used({
17837 let res = parse_u8(next);
17838 let Some(val) = res else { break };
17839 val
17840 }),
17841 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17842 n => continue,
17843 };
17844 return Some(Ok(res));
17845 }
17846 Some(Err(ErrorContext::new(
17847 "HwSInfoOne",
17848 r#type.and_then(|t| HwSInfoOne::attr_from_type(t)),
17849 self.orig_loc,
17850 self.buf.as_ptr().wrapping_add(pos) as usize,
17851 )))
17852 }
17853}
17854impl std::fmt::Debug for IterableHwSInfoOne<'_> {
17855 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17856 let mut fmt = f.debug_struct("HwSInfoOne");
17857 for attr in self.clone() {
17858 let attr = match attr {
17859 Ok(a) => a,
17860 Err(err) => {
17861 fmt.finish()?;
17862 f.write_str("Err(")?;
17863 err.fmt(f)?;
17864 return f.write_str(")");
17865 }
17866 };
17867 match attr {
17868 HwSInfoOne::Request(val) => fmt.field("Request", &val),
17869 HwSInfoOne::Used(val) => fmt.field("Used", &val),
17870 };
17871 }
17872 fmt.finish()
17873 }
17874}
17875impl IterableHwSInfoOne<'_> {
17876 pub fn lookup_attr(
17877 &self,
17878 offset: usize,
17879 missing_type: Option<u16>,
17880 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17881 let mut stack = Vec::new();
17882 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17883 if missing_type.is_some() && cur == offset {
17884 stack.push(("HwSInfoOne", offset));
17885 return (
17886 stack,
17887 missing_type.and_then(|t| HwSInfoOne::attr_from_type(t)),
17888 );
17889 }
17890 if cur > offset || cur + self.buf.len() < offset {
17891 return (stack, None);
17892 }
17893 let mut attrs = self.clone();
17894 let mut last_off = cur + attrs.pos;
17895 while let Some(attr) = attrs.next() {
17896 let Ok(attr) = attr else { break };
17897 match attr {
17898 HwSInfoOne::Request(val) => {
17899 if last_off == offset {
17900 stack.push(("Request", last_off));
17901 break;
17902 }
17903 }
17904 HwSInfoOne::Used(val) => {
17905 if last_off == offset {
17906 stack.push(("Used", last_off));
17907 break;
17908 }
17909 }
17910 _ => {}
17911 };
17912 last_off = cur + attrs.pos;
17913 }
17914 if !stack.is_empty() {
17915 stack.push(("HwSInfoOne", cur));
17916 }
17917 (stack, None)
17918 }
17919}
17920#[derive(Clone)]
17921pub enum LinkDpllPinAttrs {
17922 Id(u32),
17923}
17924impl<'a> IterableLinkDpllPinAttrs<'a> {
17925 pub fn get_id(&self) -> Result<u32, ErrorContext> {
17926 let mut iter = self.clone();
17927 iter.pos = 0;
17928 for attr in iter {
17929 if let Ok(LinkDpllPinAttrs::Id(val)) = attr {
17930 return Ok(val);
17931 }
17932 }
17933 Err(ErrorContext::new_missing(
17934 "LinkDpllPinAttrs",
17935 "Id",
17936 self.orig_loc,
17937 self.buf.as_ptr() as usize,
17938 ))
17939 }
17940}
17941impl LinkDpllPinAttrs {
17942 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkDpllPinAttrs<'a> {
17943 IterableLinkDpllPinAttrs::with_loc(buf, buf.as_ptr() as usize)
17944 }
17945 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17946 let res = match r#type {
17947 1u16 => "Id",
17948 _ => return None,
17949 };
17950 Some(res)
17951 }
17952}
17953#[derive(Clone, Copy, Default)]
17954pub struct IterableLinkDpllPinAttrs<'a> {
17955 buf: &'a [u8],
17956 pos: usize,
17957 orig_loc: usize,
17958}
17959impl<'a> IterableLinkDpllPinAttrs<'a> {
17960 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17961 Self {
17962 buf,
17963 pos: 0,
17964 orig_loc,
17965 }
17966 }
17967 pub fn get_buf(&self) -> &'a [u8] {
17968 self.buf
17969 }
17970}
17971impl<'a> Iterator for IterableLinkDpllPinAttrs<'a> {
17972 type Item = Result<LinkDpllPinAttrs, ErrorContext>;
17973 fn next(&mut self) -> Option<Self::Item> {
17974 let mut pos;
17975 let mut r#type;
17976 loop {
17977 pos = self.pos;
17978 r#type = None;
17979 if self.buf.len() == self.pos {
17980 return None;
17981 }
17982 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17983 self.pos = self.buf.len();
17984 break;
17985 };
17986 r#type = Some(header.r#type);
17987 let res = match header.r#type {
17988 1u16 => LinkDpllPinAttrs::Id({
17989 let res = parse_u32(next);
17990 let Some(val) = res else { break };
17991 val
17992 }),
17993 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17994 n => continue,
17995 };
17996 return Some(Ok(res));
17997 }
17998 Some(Err(ErrorContext::new(
17999 "LinkDpllPinAttrs",
18000 r#type.and_then(|t| LinkDpllPinAttrs::attr_from_type(t)),
18001 self.orig_loc,
18002 self.buf.as_ptr().wrapping_add(pos) as usize,
18003 )))
18004 }
18005}
18006impl std::fmt::Debug for IterableLinkDpllPinAttrs<'_> {
18007 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18008 let mut fmt = f.debug_struct("LinkDpllPinAttrs");
18009 for attr in self.clone() {
18010 let attr = match attr {
18011 Ok(a) => a,
18012 Err(err) => {
18013 fmt.finish()?;
18014 f.write_str("Err(")?;
18015 err.fmt(f)?;
18016 return f.write_str(")");
18017 }
18018 };
18019 match attr {
18020 LinkDpllPinAttrs::Id(val) => fmt.field("Id", &val),
18021 };
18022 }
18023 fmt.finish()
18024 }
18025}
18026impl IterableLinkDpllPinAttrs<'_> {
18027 pub fn lookup_attr(
18028 &self,
18029 offset: usize,
18030 missing_type: Option<u16>,
18031 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
18032 let mut stack = Vec::new();
18033 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
18034 if missing_type.is_some() && cur == offset {
18035 stack.push(("LinkDpllPinAttrs", offset));
18036 return (
18037 stack,
18038 missing_type.and_then(|t| LinkDpllPinAttrs::attr_from_type(t)),
18039 );
18040 }
18041 if cur > offset || cur + self.buf.len() < offset {
18042 return (stack, None);
18043 }
18044 let mut attrs = self.clone();
18045 let mut last_off = cur + attrs.pos;
18046 while let Some(attr) = attrs.next() {
18047 let Ok(attr) = attr else { break };
18048 match attr {
18049 LinkDpllPinAttrs::Id(val) => {
18050 if last_off == offset {
18051 stack.push(("Id", last_off));
18052 break;
18053 }
18054 }
18055 _ => {}
18056 };
18057 last_off = cur + attrs.pos;
18058 }
18059 if !stack.is_empty() {
18060 stack.push(("LinkDpllPinAttrs", cur));
18061 }
18062 (stack, None)
18063 }
18064}
18065#[derive(Clone)]
18066pub enum LinkinfoNetkitAttrs<'a> {
18067 PeerInfo(&'a [u8]),
18068 Primary(u8),
18069 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
18070 Policy(u32),
18071 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
18072 PeerPolicy(u32),
18073 #[doc = "Associated type: [`NetkitMode`] (enum)"]
18074 Mode(u32),
18075 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
18076 Scrub(u32),
18077 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
18078 PeerScrub(u32),
18079 Headroom(u16),
18080 Tailroom(u16),
18081 #[doc = "Associated type: [`NetkitPairing`] (enum)"]
18082 Pairing(u32),
18083}
18084impl<'a> IterableLinkinfoNetkitAttrs<'a> {
18085 pub fn get_peer_info(&self) -> Result<&'a [u8], ErrorContext> {
18086 let mut iter = self.clone();
18087 iter.pos = 0;
18088 for attr in iter {
18089 if let Ok(LinkinfoNetkitAttrs::PeerInfo(val)) = attr {
18090 return Ok(val);
18091 }
18092 }
18093 Err(ErrorContext::new_missing(
18094 "LinkinfoNetkitAttrs",
18095 "PeerInfo",
18096 self.orig_loc,
18097 self.buf.as_ptr() as usize,
18098 ))
18099 }
18100 pub fn get_primary(&self) -> Result<u8, ErrorContext> {
18101 let mut iter = self.clone();
18102 iter.pos = 0;
18103 for attr in iter {
18104 if let Ok(LinkinfoNetkitAttrs::Primary(val)) = attr {
18105 return Ok(val);
18106 }
18107 }
18108 Err(ErrorContext::new_missing(
18109 "LinkinfoNetkitAttrs",
18110 "Primary",
18111 self.orig_loc,
18112 self.buf.as_ptr() as usize,
18113 ))
18114 }
18115 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
18116 pub fn get_policy(&self) -> Result<u32, ErrorContext> {
18117 let mut iter = self.clone();
18118 iter.pos = 0;
18119 for attr in iter {
18120 if let Ok(LinkinfoNetkitAttrs::Policy(val)) = attr {
18121 return Ok(val);
18122 }
18123 }
18124 Err(ErrorContext::new_missing(
18125 "LinkinfoNetkitAttrs",
18126 "Policy",
18127 self.orig_loc,
18128 self.buf.as_ptr() as usize,
18129 ))
18130 }
18131 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
18132 pub fn get_peer_policy(&self) -> Result<u32, ErrorContext> {
18133 let mut iter = self.clone();
18134 iter.pos = 0;
18135 for attr in iter {
18136 if let Ok(LinkinfoNetkitAttrs::PeerPolicy(val)) = attr {
18137 return Ok(val);
18138 }
18139 }
18140 Err(ErrorContext::new_missing(
18141 "LinkinfoNetkitAttrs",
18142 "PeerPolicy",
18143 self.orig_loc,
18144 self.buf.as_ptr() as usize,
18145 ))
18146 }
18147 #[doc = "Associated type: [`NetkitMode`] (enum)"]
18148 pub fn get_mode(&self) -> Result<u32, ErrorContext> {
18149 let mut iter = self.clone();
18150 iter.pos = 0;
18151 for attr in iter {
18152 if let Ok(LinkinfoNetkitAttrs::Mode(val)) = attr {
18153 return Ok(val);
18154 }
18155 }
18156 Err(ErrorContext::new_missing(
18157 "LinkinfoNetkitAttrs",
18158 "Mode",
18159 self.orig_loc,
18160 self.buf.as_ptr() as usize,
18161 ))
18162 }
18163 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
18164 pub fn get_scrub(&self) -> Result<u32, ErrorContext> {
18165 let mut iter = self.clone();
18166 iter.pos = 0;
18167 for attr in iter {
18168 if let Ok(LinkinfoNetkitAttrs::Scrub(val)) = attr {
18169 return Ok(val);
18170 }
18171 }
18172 Err(ErrorContext::new_missing(
18173 "LinkinfoNetkitAttrs",
18174 "Scrub",
18175 self.orig_loc,
18176 self.buf.as_ptr() as usize,
18177 ))
18178 }
18179 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
18180 pub fn get_peer_scrub(&self) -> Result<u32, ErrorContext> {
18181 let mut iter = self.clone();
18182 iter.pos = 0;
18183 for attr in iter {
18184 if let Ok(LinkinfoNetkitAttrs::PeerScrub(val)) = attr {
18185 return Ok(val);
18186 }
18187 }
18188 Err(ErrorContext::new_missing(
18189 "LinkinfoNetkitAttrs",
18190 "PeerScrub",
18191 self.orig_loc,
18192 self.buf.as_ptr() as usize,
18193 ))
18194 }
18195 pub fn get_headroom(&self) -> Result<u16, ErrorContext> {
18196 let mut iter = self.clone();
18197 iter.pos = 0;
18198 for attr in iter {
18199 if let Ok(LinkinfoNetkitAttrs::Headroom(val)) = attr {
18200 return Ok(val);
18201 }
18202 }
18203 Err(ErrorContext::new_missing(
18204 "LinkinfoNetkitAttrs",
18205 "Headroom",
18206 self.orig_loc,
18207 self.buf.as_ptr() as usize,
18208 ))
18209 }
18210 pub fn get_tailroom(&self) -> Result<u16, ErrorContext> {
18211 let mut iter = self.clone();
18212 iter.pos = 0;
18213 for attr in iter {
18214 if let Ok(LinkinfoNetkitAttrs::Tailroom(val)) = attr {
18215 return Ok(val);
18216 }
18217 }
18218 Err(ErrorContext::new_missing(
18219 "LinkinfoNetkitAttrs",
18220 "Tailroom",
18221 self.orig_loc,
18222 self.buf.as_ptr() as usize,
18223 ))
18224 }
18225 #[doc = "Associated type: [`NetkitPairing`] (enum)"]
18226 pub fn get_pairing(&self) -> Result<u32, ErrorContext> {
18227 let mut iter = self.clone();
18228 iter.pos = 0;
18229 for attr in iter {
18230 if let Ok(LinkinfoNetkitAttrs::Pairing(val)) = attr {
18231 return Ok(val);
18232 }
18233 }
18234 Err(ErrorContext::new_missing(
18235 "LinkinfoNetkitAttrs",
18236 "Pairing",
18237 self.orig_loc,
18238 self.buf.as_ptr() as usize,
18239 ))
18240 }
18241}
18242impl LinkinfoNetkitAttrs<'_> {
18243 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoNetkitAttrs<'a> {
18244 IterableLinkinfoNetkitAttrs::with_loc(buf, buf.as_ptr() as usize)
18245 }
18246 fn attr_from_type(r#type: u16) -> Option<&'static str> {
18247 let res = match r#type {
18248 1u16 => "PeerInfo",
18249 2u16 => "Primary",
18250 3u16 => "Policy",
18251 4u16 => "PeerPolicy",
18252 5u16 => "Mode",
18253 6u16 => "Scrub",
18254 7u16 => "PeerScrub",
18255 8u16 => "Headroom",
18256 9u16 => "Tailroom",
18257 10u16 => "Pairing",
18258 _ => return None,
18259 };
18260 Some(res)
18261 }
18262}
18263#[derive(Clone, Copy, Default)]
18264pub struct IterableLinkinfoNetkitAttrs<'a> {
18265 buf: &'a [u8],
18266 pos: usize,
18267 orig_loc: usize,
18268}
18269impl<'a> IterableLinkinfoNetkitAttrs<'a> {
18270 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
18271 Self {
18272 buf,
18273 pos: 0,
18274 orig_loc,
18275 }
18276 }
18277 pub fn get_buf(&self) -> &'a [u8] {
18278 self.buf
18279 }
18280}
18281impl<'a> Iterator for IterableLinkinfoNetkitAttrs<'a> {
18282 type Item = Result<LinkinfoNetkitAttrs<'a>, ErrorContext>;
18283 fn next(&mut self) -> Option<Self::Item> {
18284 let mut pos;
18285 let mut r#type;
18286 loop {
18287 pos = self.pos;
18288 r#type = None;
18289 if self.buf.len() == self.pos {
18290 return None;
18291 }
18292 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
18293 self.pos = self.buf.len();
18294 break;
18295 };
18296 r#type = Some(header.r#type);
18297 let res = match header.r#type {
18298 1u16 => LinkinfoNetkitAttrs::PeerInfo({
18299 let res = Some(next);
18300 let Some(val) = res else { break };
18301 val
18302 }),
18303 2u16 => LinkinfoNetkitAttrs::Primary({
18304 let res = parse_u8(next);
18305 let Some(val) = res else { break };
18306 val
18307 }),
18308 3u16 => LinkinfoNetkitAttrs::Policy({
18309 let res = parse_u32(next);
18310 let Some(val) = res else { break };
18311 val
18312 }),
18313 4u16 => LinkinfoNetkitAttrs::PeerPolicy({
18314 let res = parse_u32(next);
18315 let Some(val) = res else { break };
18316 val
18317 }),
18318 5u16 => LinkinfoNetkitAttrs::Mode({
18319 let res = parse_u32(next);
18320 let Some(val) = res else { break };
18321 val
18322 }),
18323 6u16 => LinkinfoNetkitAttrs::Scrub({
18324 let res = parse_u32(next);
18325 let Some(val) = res else { break };
18326 val
18327 }),
18328 7u16 => LinkinfoNetkitAttrs::PeerScrub({
18329 let res = parse_u32(next);
18330 let Some(val) = res else { break };
18331 val
18332 }),
18333 8u16 => LinkinfoNetkitAttrs::Headroom({
18334 let res = parse_u16(next);
18335 let Some(val) = res else { break };
18336 val
18337 }),
18338 9u16 => LinkinfoNetkitAttrs::Tailroom({
18339 let res = parse_u16(next);
18340 let Some(val) = res else { break };
18341 val
18342 }),
18343 10u16 => LinkinfoNetkitAttrs::Pairing({
18344 let res = parse_u32(next);
18345 let Some(val) = res else { break };
18346 val
18347 }),
18348 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
18349 n => continue,
18350 };
18351 return Some(Ok(res));
18352 }
18353 Some(Err(ErrorContext::new(
18354 "LinkinfoNetkitAttrs",
18355 r#type.and_then(|t| LinkinfoNetkitAttrs::attr_from_type(t)),
18356 self.orig_loc,
18357 self.buf.as_ptr().wrapping_add(pos) as usize,
18358 )))
18359 }
18360}
18361impl<'a> std::fmt::Debug for IterableLinkinfoNetkitAttrs<'_> {
18362 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18363 let mut fmt = f.debug_struct("LinkinfoNetkitAttrs");
18364 for attr in self.clone() {
18365 let attr = match attr {
18366 Ok(a) => a,
18367 Err(err) => {
18368 fmt.finish()?;
18369 f.write_str("Err(")?;
18370 err.fmt(f)?;
18371 return f.write_str(")");
18372 }
18373 };
18374 match attr {
18375 LinkinfoNetkitAttrs::PeerInfo(val) => fmt.field("PeerInfo", &val),
18376 LinkinfoNetkitAttrs::Primary(val) => fmt.field("Primary", &val),
18377 LinkinfoNetkitAttrs::Policy(val) => {
18378 fmt.field("Policy", &FormatEnum(val.into(), NetkitPolicy::from_value))
18379 }
18380 LinkinfoNetkitAttrs::PeerPolicy(val) => fmt.field(
18381 "PeerPolicy",
18382 &FormatEnum(val.into(), NetkitPolicy::from_value),
18383 ),
18384 LinkinfoNetkitAttrs::Mode(val) => {
18385 fmt.field("Mode", &FormatEnum(val.into(), NetkitMode::from_value))
18386 }
18387 LinkinfoNetkitAttrs::Scrub(val) => {
18388 fmt.field("Scrub", &FormatEnum(val.into(), NetkitScrub::from_value))
18389 }
18390 LinkinfoNetkitAttrs::PeerScrub(val) => fmt.field(
18391 "PeerScrub",
18392 &FormatEnum(val.into(), NetkitScrub::from_value),
18393 ),
18394 LinkinfoNetkitAttrs::Headroom(val) => fmt.field("Headroom", &val),
18395 LinkinfoNetkitAttrs::Tailroom(val) => fmt.field("Tailroom", &val),
18396 LinkinfoNetkitAttrs::Pairing(val) => fmt.field(
18397 "Pairing",
18398 &FormatEnum(val.into(), NetkitPairing::from_value),
18399 ),
18400 };
18401 }
18402 fmt.finish()
18403 }
18404}
18405impl IterableLinkinfoNetkitAttrs<'_> {
18406 pub fn lookup_attr(
18407 &self,
18408 offset: usize,
18409 missing_type: Option<u16>,
18410 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
18411 let mut stack = Vec::new();
18412 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
18413 if missing_type.is_some() && cur == offset {
18414 stack.push(("LinkinfoNetkitAttrs", offset));
18415 return (
18416 stack,
18417 missing_type.and_then(|t| LinkinfoNetkitAttrs::attr_from_type(t)),
18418 );
18419 }
18420 if cur > offset || cur + self.buf.len() < offset {
18421 return (stack, None);
18422 }
18423 let mut attrs = self.clone();
18424 let mut last_off = cur + attrs.pos;
18425 while let Some(attr) = attrs.next() {
18426 let Ok(attr) = attr else { break };
18427 match attr {
18428 LinkinfoNetkitAttrs::PeerInfo(val) => {
18429 if last_off == offset {
18430 stack.push(("PeerInfo", last_off));
18431 break;
18432 }
18433 }
18434 LinkinfoNetkitAttrs::Primary(val) => {
18435 if last_off == offset {
18436 stack.push(("Primary", last_off));
18437 break;
18438 }
18439 }
18440 LinkinfoNetkitAttrs::Policy(val) => {
18441 if last_off == offset {
18442 stack.push(("Policy", last_off));
18443 break;
18444 }
18445 }
18446 LinkinfoNetkitAttrs::PeerPolicy(val) => {
18447 if last_off == offset {
18448 stack.push(("PeerPolicy", last_off));
18449 break;
18450 }
18451 }
18452 LinkinfoNetkitAttrs::Mode(val) => {
18453 if last_off == offset {
18454 stack.push(("Mode", last_off));
18455 break;
18456 }
18457 }
18458 LinkinfoNetkitAttrs::Scrub(val) => {
18459 if last_off == offset {
18460 stack.push(("Scrub", last_off));
18461 break;
18462 }
18463 }
18464 LinkinfoNetkitAttrs::PeerScrub(val) => {
18465 if last_off == offset {
18466 stack.push(("PeerScrub", last_off));
18467 break;
18468 }
18469 }
18470 LinkinfoNetkitAttrs::Headroom(val) => {
18471 if last_off == offset {
18472 stack.push(("Headroom", last_off));
18473 break;
18474 }
18475 }
18476 LinkinfoNetkitAttrs::Tailroom(val) => {
18477 if last_off == offset {
18478 stack.push(("Tailroom", last_off));
18479 break;
18480 }
18481 }
18482 LinkinfoNetkitAttrs::Pairing(val) => {
18483 if last_off == offset {
18484 stack.push(("Pairing", last_off));
18485 break;
18486 }
18487 }
18488 _ => {}
18489 };
18490 last_off = cur + attrs.pos;
18491 }
18492 if !stack.is_empty() {
18493 stack.push(("LinkinfoNetkitAttrs", cur));
18494 }
18495 (stack, None)
18496 }
18497}
18498#[derive(Clone)]
18499pub enum LinkinfoOvpnAttrs {
18500 #[doc = "Associated type: [`OvpnMode`] (enum)"]
18501 Mode(u8),
18502}
18503impl<'a> IterableLinkinfoOvpnAttrs<'a> {
18504 #[doc = "Associated type: [`OvpnMode`] (enum)"]
18505 pub fn get_mode(&self) -> Result<u8, ErrorContext> {
18506 let mut iter = self.clone();
18507 iter.pos = 0;
18508 for attr in iter {
18509 if let Ok(LinkinfoOvpnAttrs::Mode(val)) = attr {
18510 return Ok(val);
18511 }
18512 }
18513 Err(ErrorContext::new_missing(
18514 "LinkinfoOvpnAttrs",
18515 "Mode",
18516 self.orig_loc,
18517 self.buf.as_ptr() as usize,
18518 ))
18519 }
18520}
18521impl LinkinfoOvpnAttrs {
18522 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoOvpnAttrs<'a> {
18523 IterableLinkinfoOvpnAttrs::with_loc(buf, buf.as_ptr() as usize)
18524 }
18525 fn attr_from_type(r#type: u16) -> Option<&'static str> {
18526 let res = match r#type {
18527 1u16 => "Mode",
18528 _ => return None,
18529 };
18530 Some(res)
18531 }
18532}
18533#[derive(Clone, Copy, Default)]
18534pub struct IterableLinkinfoOvpnAttrs<'a> {
18535 buf: &'a [u8],
18536 pos: usize,
18537 orig_loc: usize,
18538}
18539impl<'a> IterableLinkinfoOvpnAttrs<'a> {
18540 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
18541 Self {
18542 buf,
18543 pos: 0,
18544 orig_loc,
18545 }
18546 }
18547 pub fn get_buf(&self) -> &'a [u8] {
18548 self.buf
18549 }
18550}
18551impl<'a> Iterator for IterableLinkinfoOvpnAttrs<'a> {
18552 type Item = Result<LinkinfoOvpnAttrs, ErrorContext>;
18553 fn next(&mut self) -> Option<Self::Item> {
18554 let mut pos;
18555 let mut r#type;
18556 loop {
18557 pos = self.pos;
18558 r#type = None;
18559 if self.buf.len() == self.pos {
18560 return None;
18561 }
18562 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
18563 self.pos = self.buf.len();
18564 break;
18565 };
18566 r#type = Some(header.r#type);
18567 let res = match header.r#type {
18568 1u16 => LinkinfoOvpnAttrs::Mode({
18569 let res = parse_u8(next);
18570 let Some(val) = res else { break };
18571 val
18572 }),
18573 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
18574 n => continue,
18575 };
18576 return Some(Ok(res));
18577 }
18578 Some(Err(ErrorContext::new(
18579 "LinkinfoOvpnAttrs",
18580 r#type.and_then(|t| LinkinfoOvpnAttrs::attr_from_type(t)),
18581 self.orig_loc,
18582 self.buf.as_ptr().wrapping_add(pos) as usize,
18583 )))
18584 }
18585}
18586impl std::fmt::Debug for IterableLinkinfoOvpnAttrs<'_> {
18587 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18588 let mut fmt = f.debug_struct("LinkinfoOvpnAttrs");
18589 for attr in self.clone() {
18590 let attr = match attr {
18591 Ok(a) => a,
18592 Err(err) => {
18593 fmt.finish()?;
18594 f.write_str("Err(")?;
18595 err.fmt(f)?;
18596 return f.write_str(")");
18597 }
18598 };
18599 match attr {
18600 LinkinfoOvpnAttrs::Mode(val) => {
18601 fmt.field("Mode", &FormatEnum(val.into(), OvpnMode::from_value))
18602 }
18603 };
18604 }
18605 fmt.finish()
18606 }
18607}
18608impl IterableLinkinfoOvpnAttrs<'_> {
18609 pub fn lookup_attr(
18610 &self,
18611 offset: usize,
18612 missing_type: Option<u16>,
18613 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
18614 let mut stack = Vec::new();
18615 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
18616 if missing_type.is_some() && cur == offset {
18617 stack.push(("LinkinfoOvpnAttrs", offset));
18618 return (
18619 stack,
18620 missing_type.and_then(|t| LinkinfoOvpnAttrs::attr_from_type(t)),
18621 );
18622 }
18623 if cur > offset || cur + self.buf.len() < offset {
18624 return (stack, None);
18625 }
18626 let mut attrs = self.clone();
18627 let mut last_off = cur + attrs.pos;
18628 while let Some(attr) = attrs.next() {
18629 let Ok(attr) = attr else { break };
18630 match attr {
18631 LinkinfoOvpnAttrs::Mode(val) => {
18632 if last_off == offset {
18633 stack.push(("Mode", last_off));
18634 break;
18635 }
18636 }
18637 _ => {}
18638 };
18639 last_off = cur + attrs.pos;
18640 }
18641 if !stack.is_empty() {
18642 stack.push(("LinkinfoOvpnAttrs", cur));
18643 }
18644 (stack, None)
18645 }
18646}
18647pub struct PushLinkAttrs<Prev: Rec> {
18648 pub(crate) prev: Option<Prev>,
18649 pub(crate) header_offset: Option<usize>,
18650}
18651impl<Prev: Rec> Rec for PushLinkAttrs<Prev> {
18652 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
18653 self.prev.as_mut().unwrap().as_rec_mut()
18654 }
18655 fn as_rec(&self) -> &Vec<u8> {
18656 self.prev.as_ref().unwrap().as_rec()
18657 }
18658}
18659impl<Prev: Rec> PushLinkAttrs<Prev> {
18660 pub fn new(prev: Prev) -> Self {
18661 Self {
18662 prev: Some(prev),
18663 header_offset: None,
18664 }
18665 }
18666 pub fn end_nested(mut self) -> Prev {
18667 let mut prev = self.prev.take().unwrap();
18668 if let Some(header_offset) = &self.header_offset {
18669 finalize_nested_header(prev.as_rec_mut(), *header_offset);
18670 }
18671 prev
18672 }
18673 pub fn push_address(mut self, value: &[u8]) -> Self {
18674 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
18675 self.as_rec_mut().extend(value);
18676 self
18677 }
18678 pub fn push_broadcast(mut self, value: &[u8]) -> Self {
18679 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
18680 self.as_rec_mut().extend(value);
18681 self
18682 }
18683 pub fn push_ifname(mut self, value: &CStr) -> Self {
18684 push_header(
18685 self.as_rec_mut(),
18686 3u16,
18687 value.to_bytes_with_nul().len() as u16,
18688 );
18689 self.as_rec_mut().extend(value.to_bytes_with_nul());
18690 self
18691 }
18692 pub fn push_ifname_bytes(mut self, value: &[u8]) -> Self {
18693 push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
18694 self.as_rec_mut().extend(value);
18695 self.as_rec_mut().push(0);
18696 self
18697 }
18698 pub fn push_mtu(mut self, value: u32) -> Self {
18699 push_header(self.as_rec_mut(), 4u16, 4 as u16);
18700 self.as_rec_mut().extend(value.to_ne_bytes());
18701 self
18702 }
18703 pub fn push_link(mut self, value: u32) -> Self {
18704 push_header(self.as_rec_mut(), 5u16, 4 as u16);
18705 self.as_rec_mut().extend(value.to_ne_bytes());
18706 self
18707 }
18708 pub fn push_qdisc(mut self, value: &CStr) -> Self {
18709 push_header(
18710 self.as_rec_mut(),
18711 6u16,
18712 value.to_bytes_with_nul().len() as u16,
18713 );
18714 self.as_rec_mut().extend(value.to_bytes_with_nul());
18715 self
18716 }
18717 pub fn push_qdisc_bytes(mut self, value: &[u8]) -> Self {
18718 push_header(self.as_rec_mut(), 6u16, (value.len() + 1) as u16);
18719 self.as_rec_mut().extend(value);
18720 self.as_rec_mut().push(0);
18721 self
18722 }
18723 pub fn push_stats(mut self, value: RtnlLinkStats) -> Self {
18724 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
18725 self.as_rec_mut().extend(value.as_slice());
18726 self
18727 }
18728 pub fn push_master(mut self, value: u32) -> Self {
18729 push_header(self.as_rec_mut(), 10u16, 4 as u16);
18730 self.as_rec_mut().extend(value.to_ne_bytes());
18731 self
18732 }
18733 #[doc = "struct iw_event\n"]
18734 pub fn push_wireless(mut self, value: &[u8]) -> Self {
18735 push_header(self.as_rec_mut(), 11u16, value.len() as u16);
18736 self.as_rec_mut().extend(value);
18737 self
18738 }
18739 #[doc = "A nest of ifla6-attrs or linkinfo-brport-attrs\n"]
18740 pub fn push_protinfo(mut self, value: &[u8]) -> Self {
18741 push_header(self.as_rec_mut(), 12u16, value.len() as u16);
18742 self.as_rec_mut().extend(value);
18743 self
18744 }
18745 pub fn push_txqlen(mut self, value: u32) -> Self {
18746 push_header(self.as_rec_mut(), 13u16, 4 as u16);
18747 self.as_rec_mut().extend(value.to_ne_bytes());
18748 self
18749 }
18750 pub fn push_map(mut self, value: RtnlLinkIfmap) -> Self {
18751 push_header(self.as_rec_mut(), 14u16, value.as_slice().len() as u16);
18752 self.as_rec_mut().extend(value.as_slice());
18753 self
18754 }
18755 pub fn push_weight(mut self, value: u32) -> Self {
18756 push_header(self.as_rec_mut(), 15u16, 4 as u16);
18757 self.as_rec_mut().extend(value.to_ne_bytes());
18758 self
18759 }
18760 pub fn push_operstate(mut self, value: u8) -> Self {
18761 push_header(self.as_rec_mut(), 16u16, 1 as u16);
18762 self.as_rec_mut().extend(value.to_ne_bytes());
18763 self
18764 }
18765 pub fn push_linkmode(mut self, value: u8) -> Self {
18766 push_header(self.as_rec_mut(), 17u16, 1 as u16);
18767 self.as_rec_mut().extend(value.to_ne_bytes());
18768 self
18769 }
18770 pub fn nested_linkinfo(mut self) -> PushLinkinfoAttrs<Self> {
18771 let header_offset = push_nested_header(self.as_rec_mut(), 18u16);
18772 PushLinkinfoAttrs {
18773 prev: Some(self),
18774 header_offset: Some(header_offset),
18775 }
18776 }
18777 pub fn push_net_ns_pid(mut self, value: u32) -> Self {
18778 push_header(self.as_rec_mut(), 19u16, 4 as u16);
18779 self.as_rec_mut().extend(value.to_ne_bytes());
18780 self
18781 }
18782 pub fn push_ifalias(mut self, value: &CStr) -> Self {
18783 push_header(
18784 self.as_rec_mut(),
18785 20u16,
18786 value.to_bytes_with_nul().len() as u16,
18787 );
18788 self.as_rec_mut().extend(value.to_bytes_with_nul());
18789 self
18790 }
18791 pub fn push_ifalias_bytes(mut self, value: &[u8]) -> Self {
18792 push_header(self.as_rec_mut(), 20u16, (value.len() + 1) as u16);
18793 self.as_rec_mut().extend(value);
18794 self.as_rec_mut().push(0);
18795 self
18796 }
18797 pub fn push_num_vf(mut self, value: u32) -> Self {
18798 push_header(self.as_rec_mut(), 21u16, 4 as u16);
18799 self.as_rec_mut().extend(value.to_ne_bytes());
18800 self
18801 }
18802 pub fn nested_vfinfo_list(mut self) -> PushVfinfoListAttrs<Self> {
18803 let header_offset = push_nested_header(self.as_rec_mut(), 22u16);
18804 PushVfinfoListAttrs {
18805 prev: Some(self),
18806 header_offset: Some(header_offset),
18807 }
18808 }
18809 pub fn push_stats64(mut self, value: RtnlLinkStats64) -> Self {
18810 push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
18811 self.as_rec_mut().extend(value.as_slice());
18812 self
18813 }
18814 pub fn nested_vf_ports(mut self) -> PushVfPortsAttrs<Self> {
18815 let header_offset = push_nested_header(self.as_rec_mut(), 24u16);
18816 PushVfPortsAttrs {
18817 prev: Some(self),
18818 header_offset: Some(header_offset),
18819 }
18820 }
18821 pub fn nested_port_self(mut self) -> PushPortSelfAttrs<Self> {
18822 let header_offset = push_nested_header(self.as_rec_mut(), 25u16);
18823 PushPortSelfAttrs {
18824 prev: Some(self),
18825 header_offset: Some(header_offset),
18826 }
18827 }
18828 pub fn nested_af_spec(mut self) -> PushAfSpecAttrs<Self> {
18829 let header_offset = push_nested_header(self.as_rec_mut(), 26u16);
18830 PushAfSpecAttrs {
18831 prev: Some(self),
18832 header_offset: Some(header_offset),
18833 }
18834 }
18835 pub fn push_group(mut self, value: u32) -> Self {
18836 push_header(self.as_rec_mut(), 27u16, 4 as u16);
18837 self.as_rec_mut().extend(value.to_ne_bytes());
18838 self
18839 }
18840 pub fn push_net_ns_fd(mut self, value: u32) -> Self {
18841 push_header(self.as_rec_mut(), 28u16, 4 as u16);
18842 self.as_rec_mut().extend(value.to_ne_bytes());
18843 self
18844 }
18845 #[doc = "Associated type: [`RtextFilter`] (1 bit per enumeration)"]
18846 pub fn push_ext_mask(mut self, value: u32) -> Self {
18847 push_header(self.as_rec_mut(), 29u16, 4 as u16);
18848 self.as_rec_mut().extend(value.to_ne_bytes());
18849 self
18850 }
18851 pub fn push_promiscuity(mut self, value: u32) -> Self {
18852 push_header(self.as_rec_mut(), 30u16, 4 as u16);
18853 self.as_rec_mut().extend(value.to_ne_bytes());
18854 self
18855 }
18856 pub fn push_num_tx_queues(mut self, value: u32) -> Self {
18857 push_header(self.as_rec_mut(), 31u16, 4 as u16);
18858 self.as_rec_mut().extend(value.to_ne_bytes());
18859 self
18860 }
18861 pub fn push_num_rx_queues(mut self, value: u32) -> Self {
18862 push_header(self.as_rec_mut(), 32u16, 4 as u16);
18863 self.as_rec_mut().extend(value.to_ne_bytes());
18864 self
18865 }
18866 pub fn push_carrier(mut self, value: u8) -> Self {
18867 push_header(self.as_rec_mut(), 33u16, 1 as u16);
18868 self.as_rec_mut().extend(value.to_ne_bytes());
18869 self
18870 }
18871 pub fn push_phys_port_id(mut self, value: &[u8]) -> Self {
18872 push_header(self.as_rec_mut(), 34u16, value.len() as u16);
18873 self.as_rec_mut().extend(value);
18874 self
18875 }
18876 pub fn push_carrier_changes(mut self, value: u32) -> Self {
18877 push_header(self.as_rec_mut(), 35u16, 4 as u16);
18878 self.as_rec_mut().extend(value.to_ne_bytes());
18879 self
18880 }
18881 pub fn push_phys_switch_id(mut self, value: &[u8]) -> Self {
18882 push_header(self.as_rec_mut(), 36u16, value.len() as u16);
18883 self.as_rec_mut().extend(value);
18884 self
18885 }
18886 pub fn push_link_netnsid(mut self, value: i32) -> Self {
18887 push_header(self.as_rec_mut(), 37u16, 4 as u16);
18888 self.as_rec_mut().extend(value.to_ne_bytes());
18889 self
18890 }
18891 pub fn push_phys_port_name(mut self, value: &CStr) -> Self {
18892 push_header(
18893 self.as_rec_mut(),
18894 38u16,
18895 value.to_bytes_with_nul().len() as u16,
18896 );
18897 self.as_rec_mut().extend(value.to_bytes_with_nul());
18898 self
18899 }
18900 pub fn push_phys_port_name_bytes(mut self, value: &[u8]) -> Self {
18901 push_header(self.as_rec_mut(), 38u16, (value.len() + 1) as u16);
18902 self.as_rec_mut().extend(value);
18903 self.as_rec_mut().push(0);
18904 self
18905 }
18906 pub fn push_proto_down(mut self, value: u8) -> Self {
18907 push_header(self.as_rec_mut(), 39u16, 1 as u16);
18908 self.as_rec_mut().extend(value.to_ne_bytes());
18909 self
18910 }
18911 pub fn push_gso_max_segs(mut self, value: u32) -> Self {
18912 push_header(self.as_rec_mut(), 40u16, 4 as u16);
18913 self.as_rec_mut().extend(value.to_ne_bytes());
18914 self
18915 }
18916 pub fn push_gso_max_size(mut self, value: u32) -> Self {
18917 push_header(self.as_rec_mut(), 41u16, 4 as u16);
18918 self.as_rec_mut().extend(value.to_ne_bytes());
18919 self
18920 }
18921 pub fn push_pad(mut self, value: &[u8]) -> Self {
18922 push_header(self.as_rec_mut(), 42u16, value.len() as u16);
18923 self.as_rec_mut().extend(value);
18924 self
18925 }
18926 pub fn nested_xdp(mut self) -> PushXdpAttrs<Self> {
18927 let header_offset = push_nested_header(self.as_rec_mut(), 43u16);
18928 PushXdpAttrs {
18929 prev: Some(self),
18930 header_offset: Some(header_offset),
18931 }
18932 }
18933 pub fn push_event(mut self, value: u32) -> Self {
18934 push_header(self.as_rec_mut(), 44u16, 4 as u16);
18935 self.as_rec_mut().extend(value.to_ne_bytes());
18936 self
18937 }
18938 pub fn push_new_netnsid(mut self, value: i32) -> Self {
18939 push_header(self.as_rec_mut(), 45u16, 4 as u16);
18940 self.as_rec_mut().extend(value.to_ne_bytes());
18941 self
18942 }
18943 pub fn push_target_netnsid(mut self, value: i32) -> Self {
18944 push_header(self.as_rec_mut(), 46u16, 4 as u16);
18945 self.as_rec_mut().extend(value.to_ne_bytes());
18946 self
18947 }
18948 pub fn push_carrier_up_count(mut self, value: u32) -> Self {
18949 push_header(self.as_rec_mut(), 47u16, 4 as u16);
18950 self.as_rec_mut().extend(value.to_ne_bytes());
18951 self
18952 }
18953 pub fn push_carrier_down_count(mut self, value: u32) -> Self {
18954 push_header(self.as_rec_mut(), 48u16, 4 as u16);
18955 self.as_rec_mut().extend(value.to_ne_bytes());
18956 self
18957 }
18958 pub fn push_new_ifindex(mut self, value: i32) -> Self {
18959 push_header(self.as_rec_mut(), 49u16, 4 as u16);
18960 self.as_rec_mut().extend(value.to_ne_bytes());
18961 self
18962 }
18963 pub fn push_min_mtu(mut self, value: u32) -> Self {
18964 push_header(self.as_rec_mut(), 50u16, 4 as u16);
18965 self.as_rec_mut().extend(value.to_ne_bytes());
18966 self
18967 }
18968 pub fn push_max_mtu(mut self, value: u32) -> Self {
18969 push_header(self.as_rec_mut(), 51u16, 4 as u16);
18970 self.as_rec_mut().extend(value.to_ne_bytes());
18971 self
18972 }
18973 pub fn nested_prop_list(mut self) -> PushPropListLinkAttrs<Self> {
18974 let header_offset = push_nested_header(self.as_rec_mut(), 52u16);
18975 PushPropListLinkAttrs {
18976 prev: Some(self),
18977 header_offset: Some(header_offset),
18978 }
18979 }
18980 pub fn push_alt_ifname(mut self, value: &CStr) -> Self {
18981 push_header(
18982 self.as_rec_mut(),
18983 53u16,
18984 value.to_bytes_with_nul().len() as u16,
18985 );
18986 self.as_rec_mut().extend(value.to_bytes_with_nul());
18987 self
18988 }
18989 pub fn push_alt_ifname_bytes(mut self, value: &[u8]) -> Self {
18990 push_header(self.as_rec_mut(), 53u16, (value.len() + 1) as u16);
18991 self.as_rec_mut().extend(value);
18992 self.as_rec_mut().push(0);
18993 self
18994 }
18995 pub fn push_perm_address(mut self, value: &[u8]) -> Self {
18996 push_header(self.as_rec_mut(), 54u16, value.len() as u16);
18997 self.as_rec_mut().extend(value);
18998 self
18999 }
19000 pub fn push_proto_down_reason(mut self, value: &CStr) -> Self {
19001 push_header(
19002 self.as_rec_mut(),
19003 55u16,
19004 value.to_bytes_with_nul().len() as u16,
19005 );
19006 self.as_rec_mut().extend(value.to_bytes_with_nul());
19007 self
19008 }
19009 pub fn push_proto_down_reason_bytes(mut self, value: &[u8]) -> Self {
19010 push_header(self.as_rec_mut(), 55u16, (value.len() + 1) as u16);
19011 self.as_rec_mut().extend(value);
19012 self.as_rec_mut().push(0);
19013 self
19014 }
19015 pub fn push_parent_dev_name(mut self, value: &CStr) -> Self {
19016 push_header(
19017 self.as_rec_mut(),
19018 56u16,
19019 value.to_bytes_with_nul().len() as u16,
19020 );
19021 self.as_rec_mut().extend(value.to_bytes_with_nul());
19022 self
19023 }
19024 pub fn push_parent_dev_name_bytes(mut self, value: &[u8]) -> Self {
19025 push_header(self.as_rec_mut(), 56u16, (value.len() + 1) as u16);
19026 self.as_rec_mut().extend(value);
19027 self.as_rec_mut().push(0);
19028 self
19029 }
19030 pub fn push_parent_dev_bus_name(mut self, value: &CStr) -> Self {
19031 push_header(
19032 self.as_rec_mut(),
19033 57u16,
19034 value.to_bytes_with_nul().len() as u16,
19035 );
19036 self.as_rec_mut().extend(value.to_bytes_with_nul());
19037 self
19038 }
19039 pub fn push_parent_dev_bus_name_bytes(mut self, value: &[u8]) -> Self {
19040 push_header(self.as_rec_mut(), 57u16, (value.len() + 1) as u16);
19041 self.as_rec_mut().extend(value);
19042 self.as_rec_mut().push(0);
19043 self
19044 }
19045 pub fn push_gro_max_size(mut self, value: u32) -> Self {
19046 push_header(self.as_rec_mut(), 58u16, 4 as u16);
19047 self.as_rec_mut().extend(value.to_ne_bytes());
19048 self
19049 }
19050 pub fn push_tso_max_size(mut self, value: u32) -> Self {
19051 push_header(self.as_rec_mut(), 59u16, 4 as u16);
19052 self.as_rec_mut().extend(value.to_ne_bytes());
19053 self
19054 }
19055 pub fn push_tso_max_segs(mut self, value: u32) -> Self {
19056 push_header(self.as_rec_mut(), 60u16, 4 as u16);
19057 self.as_rec_mut().extend(value.to_ne_bytes());
19058 self
19059 }
19060 pub fn push_allmulti(mut self, value: u32) -> Self {
19061 push_header(self.as_rec_mut(), 61u16, 4 as u16);
19062 self.as_rec_mut().extend(value.to_ne_bytes());
19063 self
19064 }
19065 pub fn push_devlink_port(mut self, value: &[u8]) -> Self {
19066 push_header(self.as_rec_mut(), 62u16, value.len() as u16);
19067 self.as_rec_mut().extend(value);
19068 self
19069 }
19070 pub fn push_gso_ipv4_max_size(mut self, value: u32) -> Self {
19071 push_header(self.as_rec_mut(), 63u16, 4 as u16);
19072 self.as_rec_mut().extend(value.to_ne_bytes());
19073 self
19074 }
19075 pub fn push_gro_ipv4_max_size(mut self, value: u32) -> Self {
19076 push_header(self.as_rec_mut(), 64u16, 4 as u16);
19077 self.as_rec_mut().extend(value.to_ne_bytes());
19078 self
19079 }
19080 pub fn nested_dpll_pin(mut self) -> PushLinkDpllPinAttrs<Self> {
19081 let header_offset = push_nested_header(self.as_rec_mut(), 65u16);
19082 PushLinkDpllPinAttrs {
19083 prev: Some(self),
19084 header_offset: Some(header_offset),
19085 }
19086 }
19087 #[doc = "EDT offload horizon supported by the device (in nsec).\n"]
19088 pub fn push_max_pacing_offload_horizon(mut self, value: u32) -> Self {
19089 push_header(self.as_rec_mut(), 66u16, 4 as u16);
19090 self.as_rec_mut().extend(value.to_ne_bytes());
19091 self
19092 }
19093 pub fn push_netns_immutable(mut self, value: u8) -> Self {
19094 push_header(self.as_rec_mut(), 67u16, 1 as u16);
19095 self.as_rec_mut().extend(value.to_ne_bytes());
19096 self
19097 }
19098 pub fn push_headroom(mut self, value: u16) -> Self {
19099 push_header(self.as_rec_mut(), 68u16, 2 as u16);
19100 self.as_rec_mut().extend(value.to_ne_bytes());
19101 self
19102 }
19103 pub fn push_tailroom(mut self, value: u16) -> Self {
19104 push_header(self.as_rec_mut(), 69u16, 2 as u16);
19105 self.as_rec_mut().extend(value.to_ne_bytes());
19106 self
19107 }
19108}
19109impl<Prev: Rec> Drop for PushLinkAttrs<Prev> {
19110 fn drop(&mut self) {
19111 if let Some(prev) = &mut self.prev {
19112 if let Some(header_offset) = &self.header_offset {
19113 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19114 }
19115 }
19116 }
19117}
19118pub struct PushPropListLinkAttrs<Prev: Rec> {
19119 pub(crate) prev: Option<Prev>,
19120 pub(crate) header_offset: Option<usize>,
19121}
19122impl<Prev: Rec> Rec for PushPropListLinkAttrs<Prev> {
19123 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19124 self.prev.as_mut().unwrap().as_rec_mut()
19125 }
19126 fn as_rec(&self) -> &Vec<u8> {
19127 self.prev.as_ref().unwrap().as_rec()
19128 }
19129}
19130impl<Prev: Rec> PushPropListLinkAttrs<Prev> {
19131 pub fn new(prev: Prev) -> Self {
19132 Self {
19133 prev: Some(prev),
19134 header_offset: None,
19135 }
19136 }
19137 pub fn end_nested(mut self) -> Prev {
19138 let mut prev = self.prev.take().unwrap();
19139 if let Some(header_offset) = &self.header_offset {
19140 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19141 }
19142 prev
19143 }
19144 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19145 pub fn push_alt_ifname(mut self, value: &CStr) -> Self {
19146 push_header(
19147 self.as_rec_mut(),
19148 53u16,
19149 value.to_bytes_with_nul().len() as u16,
19150 );
19151 self.as_rec_mut().extend(value.to_bytes_with_nul());
19152 self
19153 }
19154 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19155 pub fn push_alt_ifname_bytes(mut self, value: &[u8]) -> Self {
19156 push_header(self.as_rec_mut(), 53u16, (value.len() + 1) as u16);
19157 self.as_rec_mut().extend(value);
19158 self.as_rec_mut().push(0);
19159 self
19160 }
19161}
19162impl<Prev: Rec> Drop for PushPropListLinkAttrs<Prev> {
19163 fn drop(&mut self) {
19164 if let Some(prev) = &mut self.prev {
19165 if let Some(header_offset) = &self.header_offset {
19166 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19167 }
19168 }
19169 }
19170}
19171pub struct PushAfSpecAttrs<Prev: Rec> {
19172 pub(crate) prev: Option<Prev>,
19173 pub(crate) header_offset: Option<usize>,
19174}
19175impl<Prev: Rec> Rec for PushAfSpecAttrs<Prev> {
19176 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19177 self.prev.as_mut().unwrap().as_rec_mut()
19178 }
19179 fn as_rec(&self) -> &Vec<u8> {
19180 self.prev.as_ref().unwrap().as_rec()
19181 }
19182}
19183impl<Prev: Rec> PushAfSpecAttrs<Prev> {
19184 pub fn new(prev: Prev) -> Self {
19185 Self {
19186 prev: Some(prev),
19187 header_offset: None,
19188 }
19189 }
19190 pub fn end_nested(mut self) -> Prev {
19191 let mut prev = self.prev.take().unwrap();
19192 if let Some(header_offset) = &self.header_offset {
19193 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19194 }
19195 prev
19196 }
19197 pub fn nested_inet(mut self) -> PushIflaAttrs<Self> {
19198 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19199 PushIflaAttrs {
19200 prev: Some(self),
19201 header_offset: Some(header_offset),
19202 }
19203 }
19204 pub fn nested_inet6(mut self) -> PushIfla6Attrs<Self> {
19205 let header_offset = push_nested_header(self.as_rec_mut(), 10u16);
19206 PushIfla6Attrs {
19207 prev: Some(self),
19208 header_offset: Some(header_offset),
19209 }
19210 }
19211 pub fn nested_mctp(mut self) -> PushMctpAttrs<Self> {
19212 let header_offset = push_nested_header(self.as_rec_mut(), 45u16);
19213 PushMctpAttrs {
19214 prev: Some(self),
19215 header_offset: Some(header_offset),
19216 }
19217 }
19218}
19219impl<Prev: Rec> Drop for PushAfSpecAttrs<Prev> {
19220 fn drop(&mut self) {
19221 if let Some(prev) = &mut self.prev {
19222 if let Some(header_offset) = &self.header_offset {
19223 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19224 }
19225 }
19226 }
19227}
19228pub struct PushVfinfoListAttrs<Prev: Rec> {
19229 pub(crate) prev: Option<Prev>,
19230 pub(crate) header_offset: Option<usize>,
19231}
19232impl<Prev: Rec> Rec for PushVfinfoListAttrs<Prev> {
19233 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19234 self.prev.as_mut().unwrap().as_rec_mut()
19235 }
19236 fn as_rec(&self) -> &Vec<u8> {
19237 self.prev.as_ref().unwrap().as_rec()
19238 }
19239}
19240impl<Prev: Rec> PushVfinfoListAttrs<Prev> {
19241 pub fn new(prev: Prev) -> Self {
19242 Self {
19243 prev: Some(prev),
19244 header_offset: None,
19245 }
19246 }
19247 pub fn end_nested(mut self) -> Prev {
19248 let mut prev = self.prev.take().unwrap();
19249 if let Some(header_offset) = &self.header_offset {
19250 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19251 }
19252 prev
19253 }
19254 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19255 pub fn nested_info(mut self) -> PushVfinfoAttrs<Self> {
19256 let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
19257 PushVfinfoAttrs {
19258 prev: Some(self),
19259 header_offset: Some(header_offset),
19260 }
19261 }
19262}
19263impl<Prev: Rec> Drop for PushVfinfoListAttrs<Prev> {
19264 fn drop(&mut self) {
19265 if let Some(prev) = &mut self.prev {
19266 if let Some(header_offset) = &self.header_offset {
19267 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19268 }
19269 }
19270 }
19271}
19272pub struct PushVfinfoAttrs<Prev: Rec> {
19273 pub(crate) prev: Option<Prev>,
19274 pub(crate) header_offset: Option<usize>,
19275}
19276impl<Prev: Rec> Rec for PushVfinfoAttrs<Prev> {
19277 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19278 self.prev.as_mut().unwrap().as_rec_mut()
19279 }
19280 fn as_rec(&self) -> &Vec<u8> {
19281 self.prev.as_ref().unwrap().as_rec()
19282 }
19283}
19284impl<Prev: Rec> PushVfinfoAttrs<Prev> {
19285 pub fn new(prev: Prev) -> Self {
19286 Self {
19287 prev: Some(prev),
19288 header_offset: None,
19289 }
19290 }
19291 pub fn end_nested(mut self) -> Prev {
19292 let mut prev = self.prev.take().unwrap();
19293 if let Some(header_offset) = &self.header_offset {
19294 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19295 }
19296 prev
19297 }
19298 pub fn push_mac(mut self, value: IflaVfMac) -> Self {
19299 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
19300 self.as_rec_mut().extend(value.as_slice());
19301 self
19302 }
19303 pub fn push_vlan(mut self, value: IflaVfVlan) -> Self {
19304 push_header(self.as_rec_mut(), 2u16, value.as_slice().len() as u16);
19305 self.as_rec_mut().extend(value.as_slice());
19306 self
19307 }
19308 pub fn push_tx_rate(mut self, value: IflaVfTxRate) -> Self {
19309 push_header(self.as_rec_mut(), 3u16, value.as_slice().len() as u16);
19310 self.as_rec_mut().extend(value.as_slice());
19311 self
19312 }
19313 pub fn push_spoofchk(mut self, value: IflaVfSpoofchk) -> Self {
19314 push_header(self.as_rec_mut(), 4u16, value.as_slice().len() as u16);
19315 self.as_rec_mut().extend(value.as_slice());
19316 self
19317 }
19318 pub fn push_link_state(mut self, value: IflaVfLinkState) -> Self {
19319 push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
19320 self.as_rec_mut().extend(value.as_slice());
19321 self
19322 }
19323 pub fn push_rate(mut self, value: IflaVfRate) -> Self {
19324 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
19325 self.as_rec_mut().extend(value.as_slice());
19326 self
19327 }
19328 pub fn push_rss_query_en(mut self, value: IflaVfRssQueryEn) -> Self {
19329 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
19330 self.as_rec_mut().extend(value.as_slice());
19331 self
19332 }
19333 pub fn nested_stats(mut self) -> PushVfStatsAttrs<Self> {
19334 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
19335 PushVfStatsAttrs {
19336 prev: Some(self),
19337 header_offset: Some(header_offset),
19338 }
19339 }
19340 pub fn push_trust(mut self, value: IflaVfTrust) -> Self {
19341 push_header(self.as_rec_mut(), 9u16, value.as_slice().len() as u16);
19342 self.as_rec_mut().extend(value.as_slice());
19343 self
19344 }
19345 pub fn push_ib_node_guid(mut self, value: IflaVfGuid) -> Self {
19346 push_header(self.as_rec_mut(), 10u16, value.as_slice().len() as u16);
19347 self.as_rec_mut().extend(value.as_slice());
19348 self
19349 }
19350 pub fn push_ib_port_guid(mut self, value: IflaVfGuid) -> Self {
19351 push_header(self.as_rec_mut(), 11u16, value.as_slice().len() as u16);
19352 self.as_rec_mut().extend(value.as_slice());
19353 self
19354 }
19355 pub fn nested_vlan_list(mut self) -> PushVfVlanAttrs<Self> {
19356 let header_offset = push_nested_header(self.as_rec_mut(), 12u16);
19357 PushVfVlanAttrs {
19358 prev: Some(self),
19359 header_offset: Some(header_offset),
19360 }
19361 }
19362 pub fn push_broadcast(mut self, value: &[u8]) -> Self {
19363 push_header(self.as_rec_mut(), 13u16, value.len() as u16);
19364 self.as_rec_mut().extend(value);
19365 self
19366 }
19367}
19368impl<Prev: Rec> Drop for PushVfinfoAttrs<Prev> {
19369 fn drop(&mut self) {
19370 if let Some(prev) = &mut self.prev {
19371 if let Some(header_offset) = &self.header_offset {
19372 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19373 }
19374 }
19375 }
19376}
19377pub struct PushVfStatsAttrs<Prev: Rec> {
19378 pub(crate) prev: Option<Prev>,
19379 pub(crate) header_offset: Option<usize>,
19380}
19381impl<Prev: Rec> Rec for PushVfStatsAttrs<Prev> {
19382 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19383 self.prev.as_mut().unwrap().as_rec_mut()
19384 }
19385 fn as_rec(&self) -> &Vec<u8> {
19386 self.prev.as_ref().unwrap().as_rec()
19387 }
19388}
19389impl<Prev: Rec> PushVfStatsAttrs<Prev> {
19390 pub fn new(prev: Prev) -> Self {
19391 Self {
19392 prev: Some(prev),
19393 header_offset: None,
19394 }
19395 }
19396 pub fn end_nested(mut self) -> Prev {
19397 let mut prev = self.prev.take().unwrap();
19398 if let Some(header_offset) = &self.header_offset {
19399 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19400 }
19401 prev
19402 }
19403 pub fn push_rx_packets(mut self, value: u64) -> Self {
19404 push_header(self.as_rec_mut(), 0u16, 8 as u16);
19405 self.as_rec_mut().extend(value.to_ne_bytes());
19406 self
19407 }
19408 pub fn push_tx_packets(mut self, value: u64) -> Self {
19409 push_header(self.as_rec_mut(), 1u16, 8 as u16);
19410 self.as_rec_mut().extend(value.to_ne_bytes());
19411 self
19412 }
19413 pub fn push_rx_bytes(mut self, value: u64) -> Self {
19414 push_header(self.as_rec_mut(), 2u16, 8 as u16);
19415 self.as_rec_mut().extend(value.to_ne_bytes());
19416 self
19417 }
19418 pub fn push_tx_bytes(mut self, value: u64) -> Self {
19419 push_header(self.as_rec_mut(), 3u16, 8 as u16);
19420 self.as_rec_mut().extend(value.to_ne_bytes());
19421 self
19422 }
19423 pub fn push_broadcast(mut self, value: u64) -> Self {
19424 push_header(self.as_rec_mut(), 4u16, 8 as u16);
19425 self.as_rec_mut().extend(value.to_ne_bytes());
19426 self
19427 }
19428 pub fn push_multicast(mut self, value: u64) -> Self {
19429 push_header(self.as_rec_mut(), 5u16, 8 as u16);
19430 self.as_rec_mut().extend(value.to_ne_bytes());
19431 self
19432 }
19433 pub fn push_pad(mut self, value: &[u8]) -> Self {
19434 push_header(self.as_rec_mut(), 6u16, value.len() as u16);
19435 self.as_rec_mut().extend(value);
19436 self
19437 }
19438 pub fn push_rx_dropped(mut self, value: u64) -> Self {
19439 push_header(self.as_rec_mut(), 7u16, 8 as u16);
19440 self.as_rec_mut().extend(value.to_ne_bytes());
19441 self
19442 }
19443 pub fn push_tx_dropped(mut self, value: u64) -> Self {
19444 push_header(self.as_rec_mut(), 8u16, 8 as u16);
19445 self.as_rec_mut().extend(value.to_ne_bytes());
19446 self
19447 }
19448}
19449impl<Prev: Rec> Drop for PushVfStatsAttrs<Prev> {
19450 fn drop(&mut self) {
19451 if let Some(prev) = &mut self.prev {
19452 if let Some(header_offset) = &self.header_offset {
19453 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19454 }
19455 }
19456 }
19457}
19458pub struct PushVfVlanAttrs<Prev: Rec> {
19459 pub(crate) prev: Option<Prev>,
19460 pub(crate) header_offset: Option<usize>,
19461}
19462impl<Prev: Rec> Rec for PushVfVlanAttrs<Prev> {
19463 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19464 self.prev.as_mut().unwrap().as_rec_mut()
19465 }
19466 fn as_rec(&self) -> &Vec<u8> {
19467 self.prev.as_ref().unwrap().as_rec()
19468 }
19469}
19470impl<Prev: Rec> PushVfVlanAttrs<Prev> {
19471 pub fn new(prev: Prev) -> Self {
19472 Self {
19473 prev: Some(prev),
19474 header_offset: None,
19475 }
19476 }
19477 pub fn end_nested(mut self) -> Prev {
19478 let mut prev = self.prev.take().unwrap();
19479 if let Some(header_offset) = &self.header_offset {
19480 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19481 }
19482 prev
19483 }
19484 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19485 pub fn push_info(mut self, value: IflaVfVlanInfo) -> Self {
19486 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
19487 self.as_rec_mut().extend(value.as_slice());
19488 self
19489 }
19490}
19491impl<Prev: Rec> Drop for PushVfVlanAttrs<Prev> {
19492 fn drop(&mut self) {
19493 if let Some(prev) = &mut self.prev {
19494 if let Some(header_offset) = &self.header_offset {
19495 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19496 }
19497 }
19498 }
19499}
19500pub struct PushVfPortsAttrs<Prev: Rec> {
19501 pub(crate) prev: Option<Prev>,
19502 pub(crate) header_offset: Option<usize>,
19503}
19504impl<Prev: Rec> Rec for PushVfPortsAttrs<Prev> {
19505 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19506 self.prev.as_mut().unwrap().as_rec_mut()
19507 }
19508 fn as_rec(&self) -> &Vec<u8> {
19509 self.prev.as_ref().unwrap().as_rec()
19510 }
19511}
19512impl<Prev: Rec> PushVfPortsAttrs<Prev> {
19513 pub fn new(prev: Prev) -> Self {
19514 Self {
19515 prev: Some(prev),
19516 header_offset: None,
19517 }
19518 }
19519 pub fn end_nested(mut self) -> Prev {
19520 let mut prev = self.prev.take().unwrap();
19521 if let Some(header_offset) = &self.header_offset {
19522 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19523 }
19524 prev
19525 }
19526}
19527impl<Prev: Rec> Drop for PushVfPortsAttrs<Prev> {
19528 fn drop(&mut self) {
19529 if let Some(prev) = &mut self.prev {
19530 if let Some(header_offset) = &self.header_offset {
19531 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19532 }
19533 }
19534 }
19535}
19536pub struct PushPortSelfAttrs<Prev: Rec> {
19537 pub(crate) prev: Option<Prev>,
19538 pub(crate) header_offset: Option<usize>,
19539}
19540impl<Prev: Rec> Rec for PushPortSelfAttrs<Prev> {
19541 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19542 self.prev.as_mut().unwrap().as_rec_mut()
19543 }
19544 fn as_rec(&self) -> &Vec<u8> {
19545 self.prev.as_ref().unwrap().as_rec()
19546 }
19547}
19548impl<Prev: Rec> PushPortSelfAttrs<Prev> {
19549 pub fn new(prev: Prev) -> Self {
19550 Self {
19551 prev: Some(prev),
19552 header_offset: None,
19553 }
19554 }
19555 pub fn end_nested(mut self) -> Prev {
19556 let mut prev = self.prev.take().unwrap();
19557 if let Some(header_offset) = &self.header_offset {
19558 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19559 }
19560 prev
19561 }
19562}
19563impl<Prev: Rec> Drop for PushPortSelfAttrs<Prev> {
19564 fn drop(&mut self) {
19565 if let Some(prev) = &mut self.prev {
19566 if let Some(header_offset) = &self.header_offset {
19567 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19568 }
19569 }
19570 }
19571}
19572pub struct PushLinkinfoAttrs<Prev: Rec> {
19573 pub(crate) prev: Option<Prev>,
19574 pub(crate) header_offset: Option<usize>,
19575}
19576impl<Prev: Rec> Rec for PushLinkinfoAttrs<Prev> {
19577 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19578 self.prev.as_mut().unwrap().as_rec_mut()
19579 }
19580 fn as_rec(&self) -> &Vec<u8> {
19581 self.prev.as_ref().unwrap().as_rec()
19582 }
19583}
19584impl<Prev: Rec> PushLinkinfoAttrs<Prev> {
19585 pub fn new(prev: Prev) -> Self {
19586 Self {
19587 prev: Some(prev),
19588 header_offset: None,
19589 }
19590 }
19591 pub fn end_nested(mut self) -> Prev {
19592 let mut prev = self.prev.take().unwrap();
19593 if let Some(header_offset) = &self.header_offset {
19594 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19595 }
19596 prev
19597 }
19598 pub fn push_kind(mut self, value: &CStr) -> Self {
19599 push_header(
19600 self.as_rec_mut(),
19601 1u16,
19602 value.to_bytes_with_nul().len() as u16,
19603 );
19604 self.as_rec_mut().extend(value.to_bytes_with_nul());
19605 self
19606 }
19607 pub fn push_kind_bytes(mut self, value: &[u8]) -> Self {
19608 push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
19609 self.as_rec_mut().extend(value);
19610 self.as_rec_mut().push(0);
19611 self
19612 }
19613 #[doc = "Selector attribute `kind` is inserted automatically."]
19614 #[doc = "At most one sub-message attribute is expected per attribute set."]
19615 pub fn nested_data_bond(mut self) -> PushLinkinfoBondAttrs<PushDummy<Prev>> {
19616 self = self.push_kind(c"bond");
19617 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19618 let dummy = PushDummy {
19619 prev: self.prev.take(),
19620 header_offset: self.header_offset.take(),
19621 };
19622 PushLinkinfoBondAttrs {
19623 prev: Some(dummy),
19624 header_offset: Some(new_header_offset),
19625 }
19626 }
19627 #[doc = "Selector attribute `kind` is inserted automatically."]
19628 #[doc = "At most one sub-message attribute is expected per attribute set."]
19629 pub fn nested_data_bridge(mut self) -> PushLinkinfoBridgeAttrs<PushDummy<Prev>> {
19630 self = self.push_kind(c"bridge");
19631 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19632 let dummy = PushDummy {
19633 prev: self.prev.take(),
19634 header_offset: self.header_offset.take(),
19635 };
19636 PushLinkinfoBridgeAttrs {
19637 prev: Some(dummy),
19638 header_offset: Some(new_header_offset),
19639 }
19640 }
19641 #[doc = "Selector attribute `kind` is inserted automatically."]
19642 #[doc = "At most one sub-message attribute is expected per attribute set."]
19643 pub fn nested_data_erspan(mut self) -> PushLinkinfoGreAttrs<PushDummy<Prev>> {
19644 self = self.push_kind(c"erspan");
19645 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19646 let dummy = PushDummy {
19647 prev: self.prev.take(),
19648 header_offset: self.header_offset.take(),
19649 };
19650 PushLinkinfoGreAttrs {
19651 prev: Some(dummy),
19652 header_offset: Some(new_header_offset),
19653 }
19654 }
19655 #[doc = "Selector attribute `kind` is inserted automatically."]
19656 #[doc = "At most one sub-message attribute is expected per attribute set."]
19657 pub fn nested_data_gre(mut self) -> PushLinkinfoGreAttrs<PushDummy<Prev>> {
19658 self = self.push_kind(c"gre");
19659 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19660 let dummy = PushDummy {
19661 prev: self.prev.take(),
19662 header_offset: self.header_offset.take(),
19663 };
19664 PushLinkinfoGreAttrs {
19665 prev: Some(dummy),
19666 header_offset: Some(new_header_offset),
19667 }
19668 }
19669 #[doc = "Selector attribute `kind` is inserted automatically."]
19670 #[doc = "At most one sub-message attribute is expected per attribute set."]
19671 pub fn nested_data_gretap(mut self) -> PushLinkinfoGreAttrs<PushDummy<Prev>> {
19672 self = self.push_kind(c"gretap");
19673 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19674 let dummy = PushDummy {
19675 prev: self.prev.take(),
19676 header_offset: self.header_offset.take(),
19677 };
19678 PushLinkinfoGreAttrs {
19679 prev: Some(dummy),
19680 header_offset: Some(new_header_offset),
19681 }
19682 }
19683 #[doc = "Selector attribute `kind` is inserted automatically."]
19684 #[doc = "At most one sub-message attribute is expected per attribute set."]
19685 pub fn nested_data_ip6gre(mut self) -> PushLinkinfoGre6Attrs<PushDummy<Prev>> {
19686 self = self.push_kind(c"ip6gre");
19687 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19688 let dummy = PushDummy {
19689 prev: self.prev.take(),
19690 header_offset: self.header_offset.take(),
19691 };
19692 PushLinkinfoGre6Attrs {
19693 prev: Some(dummy),
19694 header_offset: Some(new_header_offset),
19695 }
19696 }
19697 #[doc = "Selector attribute `kind` is inserted automatically."]
19698 #[doc = "At most one sub-message attribute is expected per attribute set."]
19699 pub fn nested_data_geneve(mut self) -> PushLinkinfoGeneveAttrs<PushDummy<Prev>> {
19700 self = self.push_kind(c"geneve");
19701 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19702 let dummy = PushDummy {
19703 prev: self.prev.take(),
19704 header_offset: self.header_offset.take(),
19705 };
19706 PushLinkinfoGeneveAttrs {
19707 prev: Some(dummy),
19708 header_offset: Some(new_header_offset),
19709 }
19710 }
19711 #[doc = "Selector attribute `kind` is inserted automatically."]
19712 #[doc = "At most one sub-message attribute is expected per attribute set."]
19713 pub fn nested_data_hsr(mut self) -> PushLinkinfoHsrAttrs<PushDummy<Prev>> {
19714 self = self.push_kind(c"hsr");
19715 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19716 let dummy = PushDummy {
19717 prev: self.prev.take(),
19718 header_offset: self.header_offset.take(),
19719 };
19720 PushLinkinfoHsrAttrs {
19721 prev: Some(dummy),
19722 header_offset: Some(new_header_offset),
19723 }
19724 }
19725 #[doc = "Selector attribute `kind` is inserted automatically."]
19726 #[doc = "At most one sub-message attribute is expected per attribute set."]
19727 pub fn nested_data_ipip(mut self) -> PushLinkinfoIptunAttrs<PushDummy<Prev>> {
19728 self = self.push_kind(c"ipip");
19729 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19730 let dummy = PushDummy {
19731 prev: self.prev.take(),
19732 header_offset: self.header_offset.take(),
19733 };
19734 PushLinkinfoIptunAttrs {
19735 prev: Some(dummy),
19736 header_offset: Some(new_header_offset),
19737 }
19738 }
19739 #[doc = "Selector attribute `kind` is inserted automatically."]
19740 #[doc = "At most one sub-message attribute is expected per attribute set."]
19741 pub fn nested_data_ip6tnl(mut self) -> PushLinkinfoIp6tnlAttrs<PushDummy<Prev>> {
19742 self = self.push_kind(c"ip6tnl");
19743 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19744 let dummy = PushDummy {
19745 prev: self.prev.take(),
19746 header_offset: self.header_offset.take(),
19747 };
19748 PushLinkinfoIp6tnlAttrs {
19749 prev: Some(dummy),
19750 header_offset: Some(new_header_offset),
19751 }
19752 }
19753 #[doc = "Selector attribute `kind` is inserted automatically."]
19754 #[doc = "At most one sub-message attribute is expected per attribute set."]
19755 pub fn nested_data_sit(mut self) -> PushLinkinfoIptunAttrs<PushDummy<Prev>> {
19756 self = self.push_kind(c"sit");
19757 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19758 let dummy = PushDummy {
19759 prev: self.prev.take(),
19760 header_offset: self.header_offset.take(),
19761 };
19762 PushLinkinfoIptunAttrs {
19763 prev: Some(dummy),
19764 header_offset: Some(new_header_offset),
19765 }
19766 }
19767 #[doc = "Selector attribute `kind` is inserted automatically."]
19768 #[doc = "At most one sub-message attribute is expected per attribute set."]
19769 pub fn nested_data_tun(mut self) -> PushLinkinfoTunAttrs<PushDummy<Prev>> {
19770 self = self.push_kind(c"tun");
19771 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19772 let dummy = PushDummy {
19773 prev: self.prev.take(),
19774 header_offset: self.header_offset.take(),
19775 };
19776 PushLinkinfoTunAttrs {
19777 prev: Some(dummy),
19778 header_offset: Some(new_header_offset),
19779 }
19780 }
19781 #[doc = "Selector attribute `kind` is inserted automatically."]
19782 #[doc = "At most one sub-message attribute is expected per attribute set."]
19783 pub fn nested_data_vlan(mut self) -> PushLinkinfoVlanAttrs<PushDummy<Prev>> {
19784 self = self.push_kind(c"vlan");
19785 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19786 let dummy = PushDummy {
19787 prev: self.prev.take(),
19788 header_offset: self.header_offset.take(),
19789 };
19790 PushLinkinfoVlanAttrs {
19791 prev: Some(dummy),
19792 header_offset: Some(new_header_offset),
19793 }
19794 }
19795 #[doc = "Selector attribute `kind` is inserted automatically."]
19796 #[doc = "At most one sub-message attribute is expected per attribute set."]
19797 pub fn nested_data_vrf(mut self) -> PushLinkinfoVrfAttrs<PushDummy<Prev>> {
19798 self = self.push_kind(c"vrf");
19799 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19800 let dummy = PushDummy {
19801 prev: self.prev.take(),
19802 header_offset: self.header_offset.take(),
19803 };
19804 PushLinkinfoVrfAttrs {
19805 prev: Some(dummy),
19806 header_offset: Some(new_header_offset),
19807 }
19808 }
19809 #[doc = "Selector attribute `kind` is inserted automatically."]
19810 #[doc = "At most one sub-message attribute is expected per attribute set."]
19811 pub fn nested_data_vti(mut self) -> PushLinkinfoVtiAttrs<PushDummy<Prev>> {
19812 self = self.push_kind(c"vti");
19813 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19814 let dummy = PushDummy {
19815 prev: self.prev.take(),
19816 header_offset: self.header_offset.take(),
19817 };
19818 PushLinkinfoVtiAttrs {
19819 prev: Some(dummy),
19820 header_offset: Some(new_header_offset),
19821 }
19822 }
19823 #[doc = "Selector attribute `kind` is inserted automatically."]
19824 #[doc = "At most one sub-message attribute is expected per attribute set."]
19825 pub fn nested_data_vti6(mut self) -> PushLinkinfoVti6Attrs<PushDummy<Prev>> {
19826 self = self.push_kind(c"vti6");
19827 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19828 let dummy = PushDummy {
19829 prev: self.prev.take(),
19830 header_offset: self.header_offset.take(),
19831 };
19832 PushLinkinfoVti6Attrs {
19833 prev: Some(dummy),
19834 header_offset: Some(new_header_offset),
19835 }
19836 }
19837 #[doc = "Selector attribute `kind` is inserted automatically."]
19838 #[doc = "At most one sub-message attribute is expected per attribute set."]
19839 pub fn nested_data_netkit(mut self) -> PushLinkinfoNetkitAttrs<PushDummy<Prev>> {
19840 self = self.push_kind(c"netkit");
19841 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19842 let dummy = PushDummy {
19843 prev: self.prev.take(),
19844 header_offset: self.header_offset.take(),
19845 };
19846 PushLinkinfoNetkitAttrs {
19847 prev: Some(dummy),
19848 header_offset: Some(new_header_offset),
19849 }
19850 }
19851 #[doc = "Selector attribute `kind` is inserted automatically."]
19852 #[doc = "At most one sub-message attribute is expected per attribute set."]
19853 pub fn nested_data_ovpn(mut self) -> PushLinkinfoOvpnAttrs<PushDummy<Prev>> {
19854 self = self.push_kind(c"ovpn");
19855 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19856 let dummy = PushDummy {
19857 prev: self.prev.take(),
19858 header_offset: self.header_offset.take(),
19859 };
19860 PushLinkinfoOvpnAttrs {
19861 prev: Some(dummy),
19862 header_offset: Some(new_header_offset),
19863 }
19864 }
19865 pub fn push_xstats(mut self, value: &[u8]) -> Self {
19866 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
19867 self.as_rec_mut().extend(value);
19868 self
19869 }
19870 pub fn push_slave_kind(mut self, value: &CStr) -> Self {
19871 push_header(
19872 self.as_rec_mut(),
19873 4u16,
19874 value.to_bytes_with_nul().len() as u16,
19875 );
19876 self.as_rec_mut().extend(value.to_bytes_with_nul());
19877 self
19878 }
19879 pub fn push_slave_kind_bytes(mut self, value: &[u8]) -> Self {
19880 push_header(self.as_rec_mut(), 4u16, (value.len() + 1) as u16);
19881 self.as_rec_mut().extend(value);
19882 self.as_rec_mut().push(0);
19883 self
19884 }
19885 #[doc = "Selector attribute `slave-kind` is inserted automatically."]
19886 #[doc = "At most one sub-message attribute is expected per attribute set."]
19887 pub fn nested_slave_data_bridge(mut self) -> PushLinkinfoBrportAttrs<PushDummy<Prev>> {
19888 self = self.push_slave_kind(c"bridge");
19889 let new_header_offset = push_nested_header(self.as_rec_mut(), 5u16);
19890 let dummy = PushDummy {
19891 prev: self.prev.take(),
19892 header_offset: self.header_offset.take(),
19893 };
19894 PushLinkinfoBrportAttrs {
19895 prev: Some(dummy),
19896 header_offset: Some(new_header_offset),
19897 }
19898 }
19899 #[doc = "Selector attribute `slave-kind` is inserted automatically."]
19900 #[doc = "At most one sub-message attribute is expected per attribute set."]
19901 pub fn nested_slave_data_bond(mut self) -> PushBondSlaveAttrs<PushDummy<Prev>> {
19902 self = self.push_slave_kind(c"bond");
19903 let new_header_offset = push_nested_header(self.as_rec_mut(), 5u16);
19904 let dummy = PushDummy {
19905 prev: self.prev.take(),
19906 header_offset: self.header_offset.take(),
19907 };
19908 PushBondSlaveAttrs {
19909 prev: Some(dummy),
19910 header_offset: Some(new_header_offset),
19911 }
19912 }
19913}
19914impl<Prev: Rec> Drop for PushLinkinfoAttrs<Prev> {
19915 fn drop(&mut self) {
19916 if let Some(prev) = &mut self.prev {
19917 if let Some(header_offset) = &self.header_offset {
19918 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19919 }
19920 }
19921 }
19922}
19923pub struct PushLinkinfoBondAttrs<Prev: Rec> {
19924 pub(crate) prev: Option<Prev>,
19925 pub(crate) header_offset: Option<usize>,
19926}
19927impl<Prev: Rec> Rec for PushLinkinfoBondAttrs<Prev> {
19928 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19929 self.prev.as_mut().unwrap().as_rec_mut()
19930 }
19931 fn as_rec(&self) -> &Vec<u8> {
19932 self.prev.as_ref().unwrap().as_rec()
19933 }
19934}
19935pub struct PushArrayU32<Prev: Rec> {
19936 pub(crate) prev: Option<Prev>,
19937 pub(crate) header_offset: Option<usize>,
19938 pub(crate) counter: u16,
19939}
19940impl<Prev: Rec> Rec for PushArrayU32<Prev> {
19941 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19942 self.prev.as_mut().unwrap().as_rec_mut()
19943 }
19944 fn as_rec(&self) -> &Vec<u8> {
19945 self.prev.as_ref().unwrap().as_rec()
19946 }
19947}
19948impl<Prev: Rec> PushArrayU32<Prev> {
19949 pub fn new(prev: Prev) -> Self {
19950 Self {
19951 prev: Some(prev),
19952 header_offset: None,
19953 counter: 0,
19954 }
19955 }
19956 pub fn end_array(mut self) -> Prev {
19957 let mut prev = self.prev.take().unwrap();
19958 if let Some(header_offset) = &self.header_offset {
19959 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19960 }
19961 prev
19962 }
19963 pub fn entry(mut self, value: std::net::Ipv4Addr) -> Self {
19964 let index = self.counter;
19965 self.counter += 1;
19966 push_header(self.as_rec_mut(), index, 4 as u16);
19967 self.as_rec_mut().extend(&value.to_bits().to_be_bytes());
19968 self
19969 }
19970}
19971impl<Prev: Rec> Drop for PushArrayU32<Prev> {
19972 fn drop(&mut self) {
19973 if let Some(prev) = &mut self.prev {
19974 if let Some(header_offset) = &self.header_offset {
19975 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19976 }
19977 }
19978 }
19979}
19980pub struct PushArrayBinary<Prev: Rec> {
19981 pub(crate) prev: Option<Prev>,
19982 pub(crate) header_offset: Option<usize>,
19983 pub(crate) counter: u16,
19984}
19985impl<Prev: Rec> Rec for PushArrayBinary<Prev> {
19986 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19987 self.prev.as_mut().unwrap().as_rec_mut()
19988 }
19989 fn as_rec(&self) -> &Vec<u8> {
19990 self.prev.as_ref().unwrap().as_rec()
19991 }
19992}
19993impl<Prev: Rec> PushArrayBinary<Prev> {
19994 pub fn new(prev: Prev) -> Self {
19995 Self {
19996 prev: Some(prev),
19997 header_offset: None,
19998 counter: 0,
19999 }
20000 }
20001 pub fn end_array(mut self) -> Prev {
20002 let mut prev = self.prev.take().unwrap();
20003 if let Some(header_offset) = &self.header_offset {
20004 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20005 }
20006 prev
20007 }
20008 pub fn entry(mut self, value: &[u8]) -> Self {
20009 let index = self.counter;
20010 self.counter += 1;
20011 push_header(self.as_rec_mut(), index, value.len() as u16);
20012 self.as_rec_mut().extend(value);
20013 self
20014 }
20015}
20016impl<Prev: Rec> Drop for PushArrayBinary<Prev> {
20017 fn drop(&mut self) {
20018 if let Some(prev) = &mut self.prev {
20019 if let Some(header_offset) = &self.header_offset {
20020 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20021 }
20022 }
20023 }
20024}
20025impl<Prev: Rec> PushLinkinfoBondAttrs<Prev> {
20026 pub fn new(prev: Prev) -> Self {
20027 Self {
20028 prev: Some(prev),
20029 header_offset: None,
20030 }
20031 }
20032 pub fn end_nested(mut self) -> Prev {
20033 let mut prev = self.prev.take().unwrap();
20034 if let Some(header_offset) = &self.header_offset {
20035 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20036 }
20037 prev
20038 }
20039 pub fn push_mode(mut self, value: u8) -> Self {
20040 push_header(self.as_rec_mut(), 1u16, 1 as u16);
20041 self.as_rec_mut().extend(value.to_ne_bytes());
20042 self
20043 }
20044 pub fn push_active_slave(mut self, value: u32) -> Self {
20045 push_header(self.as_rec_mut(), 2u16, 4 as u16);
20046 self.as_rec_mut().extend(value.to_ne_bytes());
20047 self
20048 }
20049 pub fn push_miimon(mut self, value: u32) -> Self {
20050 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20051 self.as_rec_mut().extend(value.to_ne_bytes());
20052 self
20053 }
20054 pub fn push_updelay(mut self, value: u32) -> Self {
20055 push_header(self.as_rec_mut(), 4u16, 4 as u16);
20056 self.as_rec_mut().extend(value.to_ne_bytes());
20057 self
20058 }
20059 pub fn push_downdelay(mut self, value: u32) -> Self {
20060 push_header(self.as_rec_mut(), 5u16, 4 as u16);
20061 self.as_rec_mut().extend(value.to_ne_bytes());
20062 self
20063 }
20064 pub fn push_use_carrier(mut self, value: u8) -> Self {
20065 push_header(self.as_rec_mut(), 6u16, 1 as u16);
20066 self.as_rec_mut().extend(value.to_ne_bytes());
20067 self
20068 }
20069 pub fn push_arp_interval(mut self, value: u32) -> Self {
20070 push_header(self.as_rec_mut(), 7u16, 4 as u16);
20071 self.as_rec_mut().extend(value.to_ne_bytes());
20072 self
20073 }
20074 pub fn array_arp_ip_target(mut self) -> PushArrayU32<Self> {
20075 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
20076 PushArrayU32 {
20077 prev: Some(self),
20078 header_offset: Some(header_offset),
20079 counter: 0,
20080 }
20081 }
20082 pub fn push_arp_validate(mut self, value: u32) -> Self {
20083 push_header(self.as_rec_mut(), 9u16, 4 as u16);
20084 self.as_rec_mut().extend(value.to_ne_bytes());
20085 self
20086 }
20087 pub fn push_arp_all_targets(mut self, value: u32) -> Self {
20088 push_header(self.as_rec_mut(), 10u16, 4 as u16);
20089 self.as_rec_mut().extend(value.to_ne_bytes());
20090 self
20091 }
20092 pub fn push_primary(mut self, value: u32) -> Self {
20093 push_header(self.as_rec_mut(), 11u16, 4 as u16);
20094 self.as_rec_mut().extend(value.to_ne_bytes());
20095 self
20096 }
20097 pub fn push_primary_reselect(mut self, value: u8) -> Self {
20098 push_header(self.as_rec_mut(), 12u16, 1 as u16);
20099 self.as_rec_mut().extend(value.to_ne_bytes());
20100 self
20101 }
20102 pub fn push_fail_over_mac(mut self, value: u8) -> Self {
20103 push_header(self.as_rec_mut(), 13u16, 1 as u16);
20104 self.as_rec_mut().extend(value.to_ne_bytes());
20105 self
20106 }
20107 pub fn push_xmit_hash_policy(mut self, value: u8) -> Self {
20108 push_header(self.as_rec_mut(), 14u16, 1 as u16);
20109 self.as_rec_mut().extend(value.to_ne_bytes());
20110 self
20111 }
20112 pub fn push_resend_igmp(mut self, value: u32) -> Self {
20113 push_header(self.as_rec_mut(), 15u16, 4 as u16);
20114 self.as_rec_mut().extend(value.to_ne_bytes());
20115 self
20116 }
20117 pub fn push_num_peer_notif(mut self, value: u8) -> Self {
20118 push_header(self.as_rec_mut(), 16u16, 1 as u16);
20119 self.as_rec_mut().extend(value.to_ne_bytes());
20120 self
20121 }
20122 pub fn push_all_slaves_active(mut self, value: u8) -> Self {
20123 push_header(self.as_rec_mut(), 17u16, 1 as u16);
20124 self.as_rec_mut().extend(value.to_ne_bytes());
20125 self
20126 }
20127 pub fn push_min_links(mut self, value: u32) -> Self {
20128 push_header(self.as_rec_mut(), 18u16, 4 as u16);
20129 self.as_rec_mut().extend(value.to_ne_bytes());
20130 self
20131 }
20132 pub fn push_lp_interval(mut self, value: u32) -> Self {
20133 push_header(self.as_rec_mut(), 19u16, 4 as u16);
20134 self.as_rec_mut().extend(value.to_ne_bytes());
20135 self
20136 }
20137 pub fn push_packets_per_slave(mut self, value: u32) -> Self {
20138 push_header(self.as_rec_mut(), 20u16, 4 as u16);
20139 self.as_rec_mut().extend(value.to_ne_bytes());
20140 self
20141 }
20142 pub fn push_ad_lacp_rate(mut self, value: u8) -> Self {
20143 push_header(self.as_rec_mut(), 21u16, 1 as u16);
20144 self.as_rec_mut().extend(value.to_ne_bytes());
20145 self
20146 }
20147 pub fn push_ad_select(mut self, value: u8) -> Self {
20148 push_header(self.as_rec_mut(), 22u16, 1 as u16);
20149 self.as_rec_mut().extend(value.to_ne_bytes());
20150 self
20151 }
20152 pub fn nested_ad_info(mut self) -> PushBondAdInfoAttrs<Self> {
20153 let header_offset = push_nested_header(self.as_rec_mut(), 23u16);
20154 PushBondAdInfoAttrs {
20155 prev: Some(self),
20156 header_offset: Some(header_offset),
20157 }
20158 }
20159 pub fn push_ad_actor_sys_prio(mut self, value: u16) -> Self {
20160 push_header(self.as_rec_mut(), 24u16, 2 as u16);
20161 self.as_rec_mut().extend(value.to_ne_bytes());
20162 self
20163 }
20164 pub fn push_ad_user_port_key(mut self, value: u16) -> Self {
20165 push_header(self.as_rec_mut(), 25u16, 2 as u16);
20166 self.as_rec_mut().extend(value.to_ne_bytes());
20167 self
20168 }
20169 pub fn push_ad_actor_system(mut self, value: &[u8]) -> Self {
20170 push_header(self.as_rec_mut(), 26u16, value.len() as u16);
20171 self.as_rec_mut().extend(value);
20172 self
20173 }
20174 pub fn push_tlb_dynamic_lb(mut self, value: u8) -> Self {
20175 push_header(self.as_rec_mut(), 27u16, 1 as u16);
20176 self.as_rec_mut().extend(value.to_ne_bytes());
20177 self
20178 }
20179 pub fn push_peer_notif_delay(mut self, value: u32) -> Self {
20180 push_header(self.as_rec_mut(), 28u16, 4 as u16);
20181 self.as_rec_mut().extend(value.to_ne_bytes());
20182 self
20183 }
20184 pub fn push_ad_lacp_active(mut self, value: u8) -> Self {
20185 push_header(self.as_rec_mut(), 29u16, 1 as u16);
20186 self.as_rec_mut().extend(value.to_ne_bytes());
20187 self
20188 }
20189 pub fn push_missed_max(mut self, value: u8) -> Self {
20190 push_header(self.as_rec_mut(), 30u16, 1 as u16);
20191 self.as_rec_mut().extend(value.to_ne_bytes());
20192 self
20193 }
20194 pub fn array_ns_ip6_target(mut self) -> PushArrayBinary<Self> {
20195 let header_offset = push_nested_header(self.as_rec_mut(), 31u16);
20196 PushArrayBinary {
20197 prev: Some(self),
20198 header_offset: Some(header_offset),
20199 counter: 0,
20200 }
20201 }
20202 pub fn push_coupled_control(mut self, value: u8) -> Self {
20203 push_header(self.as_rec_mut(), 32u16, 1 as u16);
20204 self.as_rec_mut().extend(value.to_ne_bytes());
20205 self
20206 }
20207}
20208impl<Prev: Rec> Drop for PushLinkinfoBondAttrs<Prev> {
20209 fn drop(&mut self) {
20210 if let Some(prev) = &mut self.prev {
20211 if let Some(header_offset) = &self.header_offset {
20212 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20213 }
20214 }
20215 }
20216}
20217pub struct PushBondAdInfoAttrs<Prev: Rec> {
20218 pub(crate) prev: Option<Prev>,
20219 pub(crate) header_offset: Option<usize>,
20220}
20221impl<Prev: Rec> Rec for PushBondAdInfoAttrs<Prev> {
20222 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20223 self.prev.as_mut().unwrap().as_rec_mut()
20224 }
20225 fn as_rec(&self) -> &Vec<u8> {
20226 self.prev.as_ref().unwrap().as_rec()
20227 }
20228}
20229impl<Prev: Rec> PushBondAdInfoAttrs<Prev> {
20230 pub fn new(prev: Prev) -> Self {
20231 Self {
20232 prev: Some(prev),
20233 header_offset: None,
20234 }
20235 }
20236 pub fn end_nested(mut self) -> Prev {
20237 let mut prev = self.prev.take().unwrap();
20238 if let Some(header_offset) = &self.header_offset {
20239 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20240 }
20241 prev
20242 }
20243 pub fn push_aggregator(mut self, value: u16) -> Self {
20244 push_header(self.as_rec_mut(), 1u16, 2 as u16);
20245 self.as_rec_mut().extend(value.to_ne_bytes());
20246 self
20247 }
20248 pub fn push_num_ports(mut self, value: u16) -> Self {
20249 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20250 self.as_rec_mut().extend(value.to_ne_bytes());
20251 self
20252 }
20253 pub fn push_actor_key(mut self, value: u16) -> Self {
20254 push_header(self.as_rec_mut(), 3u16, 2 as u16);
20255 self.as_rec_mut().extend(value.to_ne_bytes());
20256 self
20257 }
20258 pub fn push_partner_key(mut self, value: u16) -> Self {
20259 push_header(self.as_rec_mut(), 4u16, 2 as u16);
20260 self.as_rec_mut().extend(value.to_ne_bytes());
20261 self
20262 }
20263 pub fn push_partner_mac(mut self, value: &[u8]) -> Self {
20264 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
20265 self.as_rec_mut().extend(value);
20266 self
20267 }
20268}
20269impl<Prev: Rec> Drop for PushBondAdInfoAttrs<Prev> {
20270 fn drop(&mut self) {
20271 if let Some(prev) = &mut self.prev {
20272 if let Some(header_offset) = &self.header_offset {
20273 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20274 }
20275 }
20276 }
20277}
20278pub struct PushBondSlaveAttrs<Prev: Rec> {
20279 pub(crate) prev: Option<Prev>,
20280 pub(crate) header_offset: Option<usize>,
20281}
20282impl<Prev: Rec> Rec for PushBondSlaveAttrs<Prev> {
20283 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20284 self.prev.as_mut().unwrap().as_rec_mut()
20285 }
20286 fn as_rec(&self) -> &Vec<u8> {
20287 self.prev.as_ref().unwrap().as_rec()
20288 }
20289}
20290impl<Prev: Rec> PushBondSlaveAttrs<Prev> {
20291 pub fn new(prev: Prev) -> Self {
20292 Self {
20293 prev: Some(prev),
20294 header_offset: None,
20295 }
20296 }
20297 pub fn end_nested(mut self) -> Prev {
20298 let mut prev = self.prev.take().unwrap();
20299 if let Some(header_offset) = &self.header_offset {
20300 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20301 }
20302 prev
20303 }
20304 pub fn push_state(mut self, value: u8) -> Self {
20305 push_header(self.as_rec_mut(), 1u16, 1 as u16);
20306 self.as_rec_mut().extend(value.to_ne_bytes());
20307 self
20308 }
20309 pub fn push_mii_status(mut self, value: u8) -> Self {
20310 push_header(self.as_rec_mut(), 2u16, 1 as u16);
20311 self.as_rec_mut().extend(value.to_ne_bytes());
20312 self
20313 }
20314 pub fn push_link_failure_count(mut self, value: u32) -> Self {
20315 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20316 self.as_rec_mut().extend(value.to_ne_bytes());
20317 self
20318 }
20319 pub fn push_perm_hwaddr(mut self, value: &[u8]) -> Self {
20320 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
20321 self.as_rec_mut().extend(value);
20322 self
20323 }
20324 pub fn push_queue_id(mut self, value: u16) -> Self {
20325 push_header(self.as_rec_mut(), 5u16, 2 as u16);
20326 self.as_rec_mut().extend(value.to_ne_bytes());
20327 self
20328 }
20329 pub fn push_ad_aggregator_id(mut self, value: u16) -> Self {
20330 push_header(self.as_rec_mut(), 6u16, 2 as u16);
20331 self.as_rec_mut().extend(value.to_ne_bytes());
20332 self
20333 }
20334 pub fn push_ad_actor_oper_port_state(mut self, value: u8) -> Self {
20335 push_header(self.as_rec_mut(), 7u16, 1 as u16);
20336 self.as_rec_mut().extend(value.to_ne_bytes());
20337 self
20338 }
20339 pub fn push_ad_partner_oper_port_state(mut self, value: u16) -> Self {
20340 push_header(self.as_rec_mut(), 8u16, 2 as u16);
20341 self.as_rec_mut().extend(value.to_ne_bytes());
20342 self
20343 }
20344 pub fn push_prio(mut self, value: u32) -> Self {
20345 push_header(self.as_rec_mut(), 9u16, 4 as u16);
20346 self.as_rec_mut().extend(value.to_ne_bytes());
20347 self
20348 }
20349}
20350impl<Prev: Rec> Drop for PushBondSlaveAttrs<Prev> {
20351 fn drop(&mut self) {
20352 if let Some(prev) = &mut self.prev {
20353 if let Some(header_offset) = &self.header_offset {
20354 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20355 }
20356 }
20357 }
20358}
20359pub struct PushLinkinfoBridgeAttrs<Prev: Rec> {
20360 pub(crate) prev: Option<Prev>,
20361 pub(crate) header_offset: Option<usize>,
20362}
20363impl<Prev: Rec> Rec for PushLinkinfoBridgeAttrs<Prev> {
20364 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20365 self.prev.as_mut().unwrap().as_rec_mut()
20366 }
20367 fn as_rec(&self) -> &Vec<u8> {
20368 self.prev.as_ref().unwrap().as_rec()
20369 }
20370}
20371impl<Prev: Rec> PushLinkinfoBridgeAttrs<Prev> {
20372 pub fn new(prev: Prev) -> Self {
20373 Self {
20374 prev: Some(prev),
20375 header_offset: None,
20376 }
20377 }
20378 pub fn end_nested(mut self) -> Prev {
20379 let mut prev = self.prev.take().unwrap();
20380 if let Some(header_offset) = &self.header_offset {
20381 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20382 }
20383 prev
20384 }
20385 pub fn push_forward_delay(mut self, value: u32) -> Self {
20386 push_header(self.as_rec_mut(), 1u16, 4 as u16);
20387 self.as_rec_mut().extend(value.to_ne_bytes());
20388 self
20389 }
20390 pub fn push_hello_time(mut self, value: u32) -> Self {
20391 push_header(self.as_rec_mut(), 2u16, 4 as u16);
20392 self.as_rec_mut().extend(value.to_ne_bytes());
20393 self
20394 }
20395 pub fn push_max_age(mut self, value: u32) -> Self {
20396 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20397 self.as_rec_mut().extend(value.to_ne_bytes());
20398 self
20399 }
20400 pub fn push_ageing_time(mut self, value: u32) -> Self {
20401 push_header(self.as_rec_mut(), 4u16, 4 as u16);
20402 self.as_rec_mut().extend(value.to_ne_bytes());
20403 self
20404 }
20405 pub fn push_stp_state(mut self, value: u32) -> Self {
20406 push_header(self.as_rec_mut(), 5u16, 4 as u16);
20407 self.as_rec_mut().extend(value.to_ne_bytes());
20408 self
20409 }
20410 pub fn push_priority(mut self, value: u16) -> Self {
20411 push_header(self.as_rec_mut(), 6u16, 2 as u16);
20412 self.as_rec_mut().extend(value.to_ne_bytes());
20413 self
20414 }
20415 pub fn push_vlan_filtering(mut self, value: u8) -> Self {
20416 push_header(self.as_rec_mut(), 7u16, 1 as u16);
20417 self.as_rec_mut().extend(value.to_ne_bytes());
20418 self
20419 }
20420 pub fn push_vlan_protocol(mut self, value: u16) -> Self {
20421 push_header(self.as_rec_mut(), 8u16, 2 as u16);
20422 self.as_rec_mut().extend(value.to_ne_bytes());
20423 self
20424 }
20425 pub fn push_group_fwd_mask(mut self, value: u16) -> Self {
20426 push_header(self.as_rec_mut(), 9u16, 2 as u16);
20427 self.as_rec_mut().extend(value.to_ne_bytes());
20428 self
20429 }
20430 pub fn push_root_id(mut self, value: IflaBridgeId) -> Self {
20431 push_header(self.as_rec_mut(), 10u16, value.as_slice().len() as u16);
20432 self.as_rec_mut().extend(value.as_slice());
20433 self
20434 }
20435 pub fn push_bridge_id(mut self, value: IflaBridgeId) -> Self {
20436 push_header(self.as_rec_mut(), 11u16, value.as_slice().len() as u16);
20437 self.as_rec_mut().extend(value.as_slice());
20438 self
20439 }
20440 pub fn push_root_port(mut self, value: u16) -> Self {
20441 push_header(self.as_rec_mut(), 12u16, 2 as u16);
20442 self.as_rec_mut().extend(value.to_ne_bytes());
20443 self
20444 }
20445 pub fn push_root_path_cost(mut self, value: u32) -> Self {
20446 push_header(self.as_rec_mut(), 13u16, 4 as u16);
20447 self.as_rec_mut().extend(value.to_ne_bytes());
20448 self
20449 }
20450 pub fn push_topology_change(mut self, value: u8) -> Self {
20451 push_header(self.as_rec_mut(), 14u16, 1 as u16);
20452 self.as_rec_mut().extend(value.to_ne_bytes());
20453 self
20454 }
20455 pub fn push_topology_change_detected(mut self, value: u8) -> Self {
20456 push_header(self.as_rec_mut(), 15u16, 1 as u16);
20457 self.as_rec_mut().extend(value.to_ne_bytes());
20458 self
20459 }
20460 pub fn push_hello_timer(mut self, value: u64) -> Self {
20461 push_header(self.as_rec_mut(), 16u16, 8 as u16);
20462 self.as_rec_mut().extend(value.to_ne_bytes());
20463 self
20464 }
20465 pub fn push_tcn_timer(mut self, value: u64) -> Self {
20466 push_header(self.as_rec_mut(), 17u16, 8 as u16);
20467 self.as_rec_mut().extend(value.to_ne_bytes());
20468 self
20469 }
20470 pub fn push_topology_change_timer(mut self, value: u64) -> Self {
20471 push_header(self.as_rec_mut(), 18u16, 8 as u16);
20472 self.as_rec_mut().extend(value.to_ne_bytes());
20473 self
20474 }
20475 pub fn push_gc_timer(mut self, value: u64) -> Self {
20476 push_header(self.as_rec_mut(), 19u16, 8 as u16);
20477 self.as_rec_mut().extend(value.to_ne_bytes());
20478 self
20479 }
20480 pub fn push_group_addr(mut self, value: &[u8]) -> Self {
20481 push_header(self.as_rec_mut(), 20u16, value.len() as u16);
20482 self.as_rec_mut().extend(value);
20483 self
20484 }
20485 pub fn push_fdb_flush(mut self, value: &[u8]) -> Self {
20486 push_header(self.as_rec_mut(), 21u16, value.len() as u16);
20487 self.as_rec_mut().extend(value);
20488 self
20489 }
20490 pub fn push_mcast_router(mut self, value: u8) -> Self {
20491 push_header(self.as_rec_mut(), 22u16, 1 as u16);
20492 self.as_rec_mut().extend(value.to_ne_bytes());
20493 self
20494 }
20495 pub fn push_mcast_snooping(mut self, value: u8) -> Self {
20496 push_header(self.as_rec_mut(), 23u16, 1 as u16);
20497 self.as_rec_mut().extend(value.to_ne_bytes());
20498 self
20499 }
20500 pub fn push_mcast_query_use_ifaddr(mut self, value: u8) -> Self {
20501 push_header(self.as_rec_mut(), 24u16, 1 as u16);
20502 self.as_rec_mut().extend(value.to_ne_bytes());
20503 self
20504 }
20505 pub fn push_mcast_querier(mut self, value: u8) -> Self {
20506 push_header(self.as_rec_mut(), 25u16, 1 as u16);
20507 self.as_rec_mut().extend(value.to_ne_bytes());
20508 self
20509 }
20510 pub fn push_mcast_hash_elasticity(mut self, value: u32) -> Self {
20511 push_header(self.as_rec_mut(), 26u16, 4 as u16);
20512 self.as_rec_mut().extend(value.to_ne_bytes());
20513 self
20514 }
20515 pub fn push_mcast_hash_max(mut self, value: u32) -> Self {
20516 push_header(self.as_rec_mut(), 27u16, 4 as u16);
20517 self.as_rec_mut().extend(value.to_ne_bytes());
20518 self
20519 }
20520 pub fn push_mcast_last_member_cnt(mut self, value: u32) -> Self {
20521 push_header(self.as_rec_mut(), 28u16, 4 as u16);
20522 self.as_rec_mut().extend(value.to_ne_bytes());
20523 self
20524 }
20525 pub fn push_mcast_startup_query_cnt(mut self, value: u32) -> Self {
20526 push_header(self.as_rec_mut(), 29u16, 4 as u16);
20527 self.as_rec_mut().extend(value.to_ne_bytes());
20528 self
20529 }
20530 pub fn push_mcast_last_member_intvl(mut self, value: u64) -> Self {
20531 push_header(self.as_rec_mut(), 30u16, 8 as u16);
20532 self.as_rec_mut().extend(value.to_ne_bytes());
20533 self
20534 }
20535 pub fn push_mcast_membership_intvl(mut self, value: u64) -> Self {
20536 push_header(self.as_rec_mut(), 31u16, 8 as u16);
20537 self.as_rec_mut().extend(value.to_ne_bytes());
20538 self
20539 }
20540 pub fn push_mcast_querier_intvl(mut self, value: u64) -> Self {
20541 push_header(self.as_rec_mut(), 32u16, 8 as u16);
20542 self.as_rec_mut().extend(value.to_ne_bytes());
20543 self
20544 }
20545 pub fn push_mcast_query_intvl(mut self, value: u64) -> Self {
20546 push_header(self.as_rec_mut(), 33u16, 8 as u16);
20547 self.as_rec_mut().extend(value.to_ne_bytes());
20548 self
20549 }
20550 pub fn push_mcast_query_response_intvl(mut self, value: u64) -> Self {
20551 push_header(self.as_rec_mut(), 34u16, 8 as u16);
20552 self.as_rec_mut().extend(value.to_ne_bytes());
20553 self
20554 }
20555 pub fn push_mcast_startup_query_intvl(mut self, value: u64) -> Self {
20556 push_header(self.as_rec_mut(), 35u16, 8 as u16);
20557 self.as_rec_mut().extend(value.to_ne_bytes());
20558 self
20559 }
20560 pub fn push_nf_call_iptables(mut self, value: u8) -> Self {
20561 push_header(self.as_rec_mut(), 36u16, 1 as u16);
20562 self.as_rec_mut().extend(value.to_ne_bytes());
20563 self
20564 }
20565 pub fn push_nf_call_ip6tables(mut self, value: u8) -> Self {
20566 push_header(self.as_rec_mut(), 37u16, 1 as u16);
20567 self.as_rec_mut().extend(value.to_ne_bytes());
20568 self
20569 }
20570 pub fn push_nf_call_arptables(mut self, value: u8) -> Self {
20571 push_header(self.as_rec_mut(), 38u16, 1 as u16);
20572 self.as_rec_mut().extend(value.to_ne_bytes());
20573 self
20574 }
20575 pub fn push_vlan_default_pvid(mut self, value: u16) -> Self {
20576 push_header(self.as_rec_mut(), 39u16, 2 as u16);
20577 self.as_rec_mut().extend(value.to_ne_bytes());
20578 self
20579 }
20580 pub fn push_pad(mut self, value: &[u8]) -> Self {
20581 push_header(self.as_rec_mut(), 40u16, value.len() as u16);
20582 self.as_rec_mut().extend(value);
20583 self
20584 }
20585 pub fn push_vlan_stats_enabled(mut self, value: u8) -> Self {
20586 push_header(self.as_rec_mut(), 41u16, 1 as u16);
20587 self.as_rec_mut().extend(value.to_ne_bytes());
20588 self
20589 }
20590 pub fn push_mcast_stats_enabled(mut self, value: u8) -> Self {
20591 push_header(self.as_rec_mut(), 42u16, 1 as u16);
20592 self.as_rec_mut().extend(value.to_ne_bytes());
20593 self
20594 }
20595 pub fn push_mcast_igmp_version(mut self, value: u8) -> Self {
20596 push_header(self.as_rec_mut(), 43u16, 1 as u16);
20597 self.as_rec_mut().extend(value.to_ne_bytes());
20598 self
20599 }
20600 pub fn push_mcast_mld_version(mut self, value: u8) -> Self {
20601 push_header(self.as_rec_mut(), 44u16, 1 as u16);
20602 self.as_rec_mut().extend(value.to_ne_bytes());
20603 self
20604 }
20605 pub fn push_vlan_stats_per_port(mut self, value: u8) -> Self {
20606 push_header(self.as_rec_mut(), 45u16, 1 as u16);
20607 self.as_rec_mut().extend(value.to_ne_bytes());
20608 self
20609 }
20610 pub fn push_multi_boolopt(mut self, value: BrBooloptMulti) -> Self {
20611 push_header(self.as_rec_mut(), 46u16, value.as_slice().len() as u16);
20612 self.as_rec_mut().extend(value.as_slice());
20613 self
20614 }
20615 pub fn push_mcast_querier_state(mut self, value: &[u8]) -> Self {
20616 push_header(self.as_rec_mut(), 47u16, value.len() as u16);
20617 self.as_rec_mut().extend(value);
20618 self
20619 }
20620 pub fn push_fdb_n_learned(mut self, value: u32) -> Self {
20621 push_header(self.as_rec_mut(), 48u16, 4 as u16);
20622 self.as_rec_mut().extend(value.to_ne_bytes());
20623 self
20624 }
20625 pub fn push_fdb_max_learned(mut self, value: u32) -> Self {
20626 push_header(self.as_rec_mut(), 49u16, 4 as u16);
20627 self.as_rec_mut().extend(value.to_ne_bytes());
20628 self
20629 }
20630 #[doc = "Associated type: [`BrStpMode`] (enum)"]
20631 pub fn push_stp_mode(mut self, value: u32) -> Self {
20632 push_header(self.as_rec_mut(), 50u16, 4 as u16);
20633 self.as_rec_mut().extend(value.to_ne_bytes());
20634 self
20635 }
20636}
20637impl<Prev: Rec> Drop for PushLinkinfoBridgeAttrs<Prev> {
20638 fn drop(&mut self) {
20639 if let Some(prev) = &mut self.prev {
20640 if let Some(header_offset) = &self.header_offset {
20641 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20642 }
20643 }
20644 }
20645}
20646pub struct PushLinkinfoBrportAttrs<Prev: Rec> {
20647 pub(crate) prev: Option<Prev>,
20648 pub(crate) header_offset: Option<usize>,
20649}
20650impl<Prev: Rec> Rec for PushLinkinfoBrportAttrs<Prev> {
20651 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20652 self.prev.as_mut().unwrap().as_rec_mut()
20653 }
20654 fn as_rec(&self) -> &Vec<u8> {
20655 self.prev.as_ref().unwrap().as_rec()
20656 }
20657}
20658impl<Prev: Rec> PushLinkinfoBrportAttrs<Prev> {
20659 pub fn new(prev: Prev) -> Self {
20660 Self {
20661 prev: Some(prev),
20662 header_offset: None,
20663 }
20664 }
20665 pub fn end_nested(mut self) -> Prev {
20666 let mut prev = self.prev.take().unwrap();
20667 if let Some(header_offset) = &self.header_offset {
20668 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20669 }
20670 prev
20671 }
20672 pub fn push_state(mut self, value: u8) -> Self {
20673 push_header(self.as_rec_mut(), 1u16, 1 as u16);
20674 self.as_rec_mut().extend(value.to_ne_bytes());
20675 self
20676 }
20677 pub fn push_priority(mut self, value: u16) -> Self {
20678 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20679 self.as_rec_mut().extend(value.to_ne_bytes());
20680 self
20681 }
20682 pub fn push_cost(mut self, value: u32) -> Self {
20683 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20684 self.as_rec_mut().extend(value.to_ne_bytes());
20685 self
20686 }
20687 pub fn push_mode(mut self, value: ()) -> Self {
20688 push_header(self.as_rec_mut(), 4u16, 0 as u16);
20689 self
20690 }
20691 pub fn push_guard(mut self, value: ()) -> Self {
20692 push_header(self.as_rec_mut(), 5u16, 0 as u16);
20693 self
20694 }
20695 pub fn push_protect(mut self, value: ()) -> Self {
20696 push_header(self.as_rec_mut(), 6u16, 0 as u16);
20697 self
20698 }
20699 pub fn push_fast_leave(mut self, value: ()) -> Self {
20700 push_header(self.as_rec_mut(), 7u16, 0 as u16);
20701 self
20702 }
20703 pub fn push_learning(mut self, value: ()) -> Self {
20704 push_header(self.as_rec_mut(), 8u16, 0 as u16);
20705 self
20706 }
20707 pub fn push_unicast_flood(mut self, value: ()) -> Self {
20708 push_header(self.as_rec_mut(), 9u16, 0 as u16);
20709 self
20710 }
20711 pub fn push_proxyarp(mut self, value: ()) -> Self {
20712 push_header(self.as_rec_mut(), 10u16, 0 as u16);
20713 self
20714 }
20715 pub fn push_learning_sync(mut self, value: ()) -> Self {
20716 push_header(self.as_rec_mut(), 11u16, 0 as u16);
20717 self
20718 }
20719 pub fn push_proxyarp_wifi(mut self, value: ()) -> Self {
20720 push_header(self.as_rec_mut(), 12u16, 0 as u16);
20721 self
20722 }
20723 pub fn push_root_id(mut self, value: IflaBridgeId) -> Self {
20724 push_header(self.as_rec_mut(), 13u16, value.as_slice().len() as u16);
20725 self.as_rec_mut().extend(value.as_slice());
20726 self
20727 }
20728 pub fn push_bridge_id(mut self, value: IflaBridgeId) -> Self {
20729 push_header(self.as_rec_mut(), 14u16, value.as_slice().len() as u16);
20730 self.as_rec_mut().extend(value.as_slice());
20731 self
20732 }
20733 pub fn push_designated_port(mut self, value: u16) -> Self {
20734 push_header(self.as_rec_mut(), 15u16, 2 as u16);
20735 self.as_rec_mut().extend(value.to_ne_bytes());
20736 self
20737 }
20738 pub fn push_designated_cost(mut self, value: u16) -> Self {
20739 push_header(self.as_rec_mut(), 16u16, 2 as u16);
20740 self.as_rec_mut().extend(value.to_ne_bytes());
20741 self
20742 }
20743 pub fn push_id(mut self, value: u16) -> Self {
20744 push_header(self.as_rec_mut(), 17u16, 2 as u16);
20745 self.as_rec_mut().extend(value.to_ne_bytes());
20746 self
20747 }
20748 pub fn push_no(mut self, value: u16) -> Self {
20749 push_header(self.as_rec_mut(), 18u16, 2 as u16);
20750 self.as_rec_mut().extend(value.to_ne_bytes());
20751 self
20752 }
20753 pub fn push_topology_change_ack(mut self, value: u8) -> Self {
20754 push_header(self.as_rec_mut(), 19u16, 1 as u16);
20755 self.as_rec_mut().extend(value.to_ne_bytes());
20756 self
20757 }
20758 pub fn push_config_pending(mut self, value: u8) -> Self {
20759 push_header(self.as_rec_mut(), 20u16, 1 as u16);
20760 self.as_rec_mut().extend(value.to_ne_bytes());
20761 self
20762 }
20763 pub fn push_message_age_timer(mut self, value: u64) -> Self {
20764 push_header(self.as_rec_mut(), 21u16, 8 as u16);
20765 self.as_rec_mut().extend(value.to_ne_bytes());
20766 self
20767 }
20768 pub fn push_forward_delay_timer(mut self, value: u64) -> Self {
20769 push_header(self.as_rec_mut(), 22u16, 8 as u16);
20770 self.as_rec_mut().extend(value.to_ne_bytes());
20771 self
20772 }
20773 pub fn push_hold_timer(mut self, value: u64) -> Self {
20774 push_header(self.as_rec_mut(), 23u16, 8 as u16);
20775 self.as_rec_mut().extend(value.to_ne_bytes());
20776 self
20777 }
20778 pub fn push_flush(mut self, value: ()) -> Self {
20779 push_header(self.as_rec_mut(), 24u16, 0 as u16);
20780 self
20781 }
20782 pub fn push_multicast_router(mut self, value: u8) -> Self {
20783 push_header(self.as_rec_mut(), 25u16, 1 as u16);
20784 self.as_rec_mut().extend(value.to_ne_bytes());
20785 self
20786 }
20787 pub fn push_pad(mut self, value: &[u8]) -> Self {
20788 push_header(self.as_rec_mut(), 26u16, value.len() as u16);
20789 self.as_rec_mut().extend(value);
20790 self
20791 }
20792 pub fn push_mcast_flood(mut self, value: ()) -> Self {
20793 push_header(self.as_rec_mut(), 27u16, 0 as u16);
20794 self
20795 }
20796 pub fn push_mcast_to_ucast(mut self, value: ()) -> Self {
20797 push_header(self.as_rec_mut(), 28u16, 0 as u16);
20798 self
20799 }
20800 pub fn push_vlan_tunnel(mut self, value: ()) -> Self {
20801 push_header(self.as_rec_mut(), 29u16, 0 as u16);
20802 self
20803 }
20804 pub fn push_bcast_flood(mut self, value: ()) -> Self {
20805 push_header(self.as_rec_mut(), 30u16, 0 as u16);
20806 self
20807 }
20808 pub fn push_group_fwd_mask(mut self, value: u16) -> Self {
20809 push_header(self.as_rec_mut(), 31u16, 2 as u16);
20810 self.as_rec_mut().extend(value.to_ne_bytes());
20811 self
20812 }
20813 pub fn push_neigh_suppress(mut self, value: ()) -> Self {
20814 push_header(self.as_rec_mut(), 32u16, 0 as u16);
20815 self
20816 }
20817 pub fn push_isolated(mut self, value: ()) -> Self {
20818 push_header(self.as_rec_mut(), 33u16, 0 as u16);
20819 self
20820 }
20821 pub fn push_backup_port(mut self, value: u32) -> Self {
20822 push_header(self.as_rec_mut(), 34u16, 4 as u16);
20823 self.as_rec_mut().extend(value.to_ne_bytes());
20824 self
20825 }
20826 pub fn push_mrp_ring_open(mut self, value: ()) -> Self {
20827 push_header(self.as_rec_mut(), 35u16, 0 as u16);
20828 self
20829 }
20830 pub fn push_mrp_in_open(mut self, value: ()) -> Self {
20831 push_header(self.as_rec_mut(), 36u16, 0 as u16);
20832 self
20833 }
20834 pub fn push_mcast_eht_hosts_limit(mut self, value: u32) -> Self {
20835 push_header(self.as_rec_mut(), 37u16, 4 as u16);
20836 self.as_rec_mut().extend(value.to_ne_bytes());
20837 self
20838 }
20839 pub fn push_mcast_eht_hosts_cnt(mut self, value: u32) -> Self {
20840 push_header(self.as_rec_mut(), 38u16, 4 as u16);
20841 self.as_rec_mut().extend(value.to_ne_bytes());
20842 self
20843 }
20844 pub fn push_locked(mut self, value: ()) -> Self {
20845 push_header(self.as_rec_mut(), 39u16, 0 as u16);
20846 self
20847 }
20848 pub fn push_mab(mut self, value: ()) -> Self {
20849 push_header(self.as_rec_mut(), 40u16, 0 as u16);
20850 self
20851 }
20852 pub fn push_mcast_n_groups(mut self, value: u32) -> Self {
20853 push_header(self.as_rec_mut(), 41u16, 4 as u16);
20854 self.as_rec_mut().extend(value.to_ne_bytes());
20855 self
20856 }
20857 pub fn push_mcast_max_groups(mut self, value: u32) -> Self {
20858 push_header(self.as_rec_mut(), 42u16, 4 as u16);
20859 self.as_rec_mut().extend(value.to_ne_bytes());
20860 self
20861 }
20862 pub fn push_neigh_vlan_suppress(mut self, value: ()) -> Self {
20863 push_header(self.as_rec_mut(), 43u16, 0 as u16);
20864 self
20865 }
20866 pub fn push_backup_nhid(mut self, value: u32) -> Self {
20867 push_header(self.as_rec_mut(), 44u16, 4 as u16);
20868 self.as_rec_mut().extend(value.to_ne_bytes());
20869 self
20870 }
20871 pub fn push_neigh_forward_grat(mut self, value: u8) -> Self {
20872 push_header(self.as_rec_mut(), 45u16, 1 as u16);
20873 self.as_rec_mut().extend(value.to_ne_bytes());
20874 self
20875 }
20876}
20877impl<Prev: Rec> Drop for PushLinkinfoBrportAttrs<Prev> {
20878 fn drop(&mut self) {
20879 if let Some(prev) = &mut self.prev {
20880 if let Some(header_offset) = &self.header_offset {
20881 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20882 }
20883 }
20884 }
20885}
20886pub struct PushLinkinfoGreAttrs<Prev: Rec> {
20887 pub(crate) prev: Option<Prev>,
20888 pub(crate) header_offset: Option<usize>,
20889}
20890impl<Prev: Rec> Rec for PushLinkinfoGreAttrs<Prev> {
20891 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20892 self.prev.as_mut().unwrap().as_rec_mut()
20893 }
20894 fn as_rec(&self) -> &Vec<u8> {
20895 self.prev.as_ref().unwrap().as_rec()
20896 }
20897}
20898impl<Prev: Rec> PushLinkinfoGreAttrs<Prev> {
20899 pub fn new(prev: Prev) -> Self {
20900 Self {
20901 prev: Some(prev),
20902 header_offset: None,
20903 }
20904 }
20905 pub fn end_nested(mut self) -> Prev {
20906 let mut prev = self.prev.take().unwrap();
20907 if let Some(header_offset) = &self.header_offset {
20908 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20909 }
20910 prev
20911 }
20912 pub fn push_link(mut self, value: u32) -> Self {
20913 push_header(self.as_rec_mut(), 1u16, 4 as u16);
20914 self.as_rec_mut().extend(value.to_ne_bytes());
20915 self
20916 }
20917 pub fn push_iflags(mut self, value: u16) -> Self {
20918 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20919 self.as_rec_mut().extend(value.to_be_bytes());
20920 self
20921 }
20922 pub fn push_oflags(mut self, value: u16) -> Self {
20923 push_header(self.as_rec_mut(), 3u16, 2 as u16);
20924 self.as_rec_mut().extend(value.to_be_bytes());
20925 self
20926 }
20927 pub fn push_ikey(mut self, value: u32) -> Self {
20928 push_header(self.as_rec_mut(), 4u16, 4 as u16);
20929 self.as_rec_mut().extend(value.to_be_bytes());
20930 self
20931 }
20932 pub fn push_okey(mut self, value: u32) -> Self {
20933 push_header(self.as_rec_mut(), 5u16, 4 as u16);
20934 self.as_rec_mut().extend(value.to_be_bytes());
20935 self
20936 }
20937 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
20938 push_header(self.as_rec_mut(), 6u16, {
20939 match &value {
20940 IpAddr::V4(_) => 4,
20941 IpAddr::V6(_) => 16,
20942 }
20943 } as u16);
20944 encode_ip(self.as_rec_mut(), value);
20945 self
20946 }
20947 pub fn push_remote(mut self, value: std::net::IpAddr) -> Self {
20948 push_header(self.as_rec_mut(), 7u16, {
20949 match &value {
20950 IpAddr::V4(_) => 4,
20951 IpAddr::V6(_) => 16,
20952 }
20953 } as u16);
20954 encode_ip(self.as_rec_mut(), value);
20955 self
20956 }
20957 pub fn push_ttl(mut self, value: u8) -> Self {
20958 push_header(self.as_rec_mut(), 8u16, 1 as u16);
20959 self.as_rec_mut().extend(value.to_ne_bytes());
20960 self
20961 }
20962 pub fn push_tos(mut self, value: u8) -> Self {
20963 push_header(self.as_rec_mut(), 9u16, 1 as u16);
20964 self.as_rec_mut().extend(value.to_ne_bytes());
20965 self
20966 }
20967 pub fn push_pmtudisc(mut self, value: u8) -> Self {
20968 push_header(self.as_rec_mut(), 10u16, 1 as u16);
20969 self.as_rec_mut().extend(value.to_ne_bytes());
20970 self
20971 }
20972 pub fn push_encap_limit(mut self, value: u8) -> Self {
20973 push_header(self.as_rec_mut(), 11u16, 1 as u16);
20974 self.as_rec_mut().extend(value.to_ne_bytes());
20975 self
20976 }
20977 pub fn push_flowinfo(mut self, value: u32) -> Self {
20978 push_header(self.as_rec_mut(), 12u16, 4 as u16);
20979 self.as_rec_mut().extend(value.to_be_bytes());
20980 self
20981 }
20982 pub fn push_flags(mut self, value: u32) -> Self {
20983 push_header(self.as_rec_mut(), 13u16, 4 as u16);
20984 self.as_rec_mut().extend(value.to_ne_bytes());
20985 self
20986 }
20987 pub fn push_encap_type(mut self, value: u16) -> Self {
20988 push_header(self.as_rec_mut(), 14u16, 2 as u16);
20989 self.as_rec_mut().extend(value.to_ne_bytes());
20990 self
20991 }
20992 pub fn push_encap_flags(mut self, value: u16) -> Self {
20993 push_header(self.as_rec_mut(), 15u16, 2 as u16);
20994 self.as_rec_mut().extend(value.to_ne_bytes());
20995 self
20996 }
20997 pub fn push_encap_sport(mut self, value: u16) -> Self {
20998 push_header(self.as_rec_mut(), 16u16, 2 as u16);
20999 self.as_rec_mut().extend(value.to_be_bytes());
21000 self
21001 }
21002 pub fn push_encap_dport(mut self, value: u16) -> Self {
21003 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21004 self.as_rec_mut().extend(value.to_be_bytes());
21005 self
21006 }
21007 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21008 push_header(self.as_rec_mut(), 18u16, 0 as u16);
21009 self
21010 }
21011 pub fn push_ignore_df(mut self, value: u8) -> Self {
21012 push_header(self.as_rec_mut(), 19u16, 1 as u16);
21013 self.as_rec_mut().extend(value.to_ne_bytes());
21014 self
21015 }
21016 pub fn push_fwmark(mut self, value: u32) -> Self {
21017 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21018 self.as_rec_mut().extend(value.to_ne_bytes());
21019 self
21020 }
21021 pub fn push_erspan_index(mut self, value: u32) -> Self {
21022 push_header(self.as_rec_mut(), 21u16, 4 as u16);
21023 self.as_rec_mut().extend(value.to_ne_bytes());
21024 self
21025 }
21026 pub fn push_erspan_ver(mut self, value: u8) -> Self {
21027 push_header(self.as_rec_mut(), 22u16, 1 as u16);
21028 self.as_rec_mut().extend(value.to_ne_bytes());
21029 self
21030 }
21031 pub fn push_erspan_dir(mut self, value: u8) -> Self {
21032 push_header(self.as_rec_mut(), 23u16, 1 as u16);
21033 self.as_rec_mut().extend(value.to_ne_bytes());
21034 self
21035 }
21036 pub fn push_erspan_hwid(mut self, value: u16) -> Self {
21037 push_header(self.as_rec_mut(), 24u16, 2 as u16);
21038 self.as_rec_mut().extend(value.to_ne_bytes());
21039 self
21040 }
21041}
21042impl<Prev: Rec> Drop for PushLinkinfoGreAttrs<Prev> {
21043 fn drop(&mut self) {
21044 if let Some(prev) = &mut self.prev {
21045 if let Some(header_offset) = &self.header_offset {
21046 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21047 }
21048 }
21049 }
21050}
21051pub struct PushLinkinfoGre6Attrs<Prev: Rec> {
21052 pub(crate) prev: Option<Prev>,
21053 pub(crate) header_offset: Option<usize>,
21054}
21055impl<Prev: Rec> Rec for PushLinkinfoGre6Attrs<Prev> {
21056 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21057 self.prev.as_mut().unwrap().as_rec_mut()
21058 }
21059 fn as_rec(&self) -> &Vec<u8> {
21060 self.prev.as_ref().unwrap().as_rec()
21061 }
21062}
21063impl<Prev: Rec> PushLinkinfoGre6Attrs<Prev> {
21064 pub fn new(prev: Prev) -> Self {
21065 Self {
21066 prev: Some(prev),
21067 header_offset: None,
21068 }
21069 }
21070 pub fn end_nested(mut self) -> Prev {
21071 let mut prev = self.prev.take().unwrap();
21072 if let Some(header_offset) = &self.header_offset {
21073 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21074 }
21075 prev
21076 }
21077 pub fn push_link(mut self, value: u32) -> Self {
21078 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21079 self.as_rec_mut().extend(value.to_ne_bytes());
21080 self
21081 }
21082 pub fn push_iflags(mut self, value: u16) -> Self {
21083 push_header(self.as_rec_mut(), 2u16, 2 as u16);
21084 self.as_rec_mut().extend(value.to_be_bytes());
21085 self
21086 }
21087 pub fn push_oflags(mut self, value: u16) -> Self {
21088 push_header(self.as_rec_mut(), 3u16, 2 as u16);
21089 self.as_rec_mut().extend(value.to_be_bytes());
21090 self
21091 }
21092 pub fn push_ikey(mut self, value: u32) -> Self {
21093 push_header(self.as_rec_mut(), 4u16, 4 as u16);
21094 self.as_rec_mut().extend(value.to_be_bytes());
21095 self
21096 }
21097 pub fn push_okey(mut self, value: u32) -> Self {
21098 push_header(self.as_rec_mut(), 5u16, 4 as u16);
21099 self.as_rec_mut().extend(value.to_be_bytes());
21100 self
21101 }
21102 pub fn push_local(mut self, value: &[u8]) -> Self {
21103 push_header(self.as_rec_mut(), 6u16, value.len() as u16);
21104 self.as_rec_mut().extend(value);
21105 self
21106 }
21107 pub fn push_remote(mut self, value: &[u8]) -> Self {
21108 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
21109 self.as_rec_mut().extend(value);
21110 self
21111 }
21112 pub fn push_ttl(mut self, value: u8) -> Self {
21113 push_header(self.as_rec_mut(), 8u16, 1 as u16);
21114 self.as_rec_mut().extend(value.to_ne_bytes());
21115 self
21116 }
21117 pub fn push_encap_limit(mut self, value: u8) -> Self {
21118 push_header(self.as_rec_mut(), 11u16, 1 as u16);
21119 self.as_rec_mut().extend(value.to_ne_bytes());
21120 self
21121 }
21122 pub fn push_flowinfo(mut self, value: u32) -> Self {
21123 push_header(self.as_rec_mut(), 12u16, 4 as u16);
21124 self.as_rec_mut().extend(value.to_be_bytes());
21125 self
21126 }
21127 pub fn push_flags(mut self, value: u32) -> Self {
21128 push_header(self.as_rec_mut(), 13u16, 4 as u16);
21129 self.as_rec_mut().extend(value.to_ne_bytes());
21130 self
21131 }
21132 pub fn push_encap_type(mut self, value: u16) -> Self {
21133 push_header(self.as_rec_mut(), 14u16, 2 as u16);
21134 self.as_rec_mut().extend(value.to_ne_bytes());
21135 self
21136 }
21137 pub fn push_encap_flags(mut self, value: u16) -> Self {
21138 push_header(self.as_rec_mut(), 15u16, 2 as u16);
21139 self.as_rec_mut().extend(value.to_ne_bytes());
21140 self
21141 }
21142 pub fn push_encap_sport(mut self, value: u16) -> Self {
21143 push_header(self.as_rec_mut(), 16u16, 2 as u16);
21144 self.as_rec_mut().extend(value.to_be_bytes());
21145 self
21146 }
21147 pub fn push_encap_dport(mut self, value: u16) -> Self {
21148 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21149 self.as_rec_mut().extend(value.to_be_bytes());
21150 self
21151 }
21152 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21153 push_header(self.as_rec_mut(), 18u16, 0 as u16);
21154 self
21155 }
21156 pub fn push_fwmark(mut self, value: u32) -> Self {
21157 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21158 self.as_rec_mut().extend(value.to_ne_bytes());
21159 self
21160 }
21161 pub fn push_erspan_index(mut self, value: u32) -> Self {
21162 push_header(self.as_rec_mut(), 21u16, 4 as u16);
21163 self.as_rec_mut().extend(value.to_ne_bytes());
21164 self
21165 }
21166 pub fn push_erspan_ver(mut self, value: u8) -> Self {
21167 push_header(self.as_rec_mut(), 22u16, 1 as u16);
21168 self.as_rec_mut().extend(value.to_ne_bytes());
21169 self
21170 }
21171 pub fn push_erspan_dir(mut self, value: u8) -> Self {
21172 push_header(self.as_rec_mut(), 23u16, 1 as u16);
21173 self.as_rec_mut().extend(value.to_ne_bytes());
21174 self
21175 }
21176 pub fn push_erspan_hwid(mut self, value: u16) -> Self {
21177 push_header(self.as_rec_mut(), 24u16, 2 as u16);
21178 self.as_rec_mut().extend(value.to_ne_bytes());
21179 self
21180 }
21181}
21182impl<Prev: Rec> Drop for PushLinkinfoGre6Attrs<Prev> {
21183 fn drop(&mut self) {
21184 if let Some(prev) = &mut self.prev {
21185 if let Some(header_offset) = &self.header_offset {
21186 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21187 }
21188 }
21189 }
21190}
21191pub struct PushLinkinfoVtiAttrs<Prev: Rec> {
21192 pub(crate) prev: Option<Prev>,
21193 pub(crate) header_offset: Option<usize>,
21194}
21195impl<Prev: Rec> Rec for PushLinkinfoVtiAttrs<Prev> {
21196 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21197 self.prev.as_mut().unwrap().as_rec_mut()
21198 }
21199 fn as_rec(&self) -> &Vec<u8> {
21200 self.prev.as_ref().unwrap().as_rec()
21201 }
21202}
21203impl<Prev: Rec> PushLinkinfoVtiAttrs<Prev> {
21204 pub fn new(prev: Prev) -> Self {
21205 Self {
21206 prev: Some(prev),
21207 header_offset: None,
21208 }
21209 }
21210 pub fn end_nested(mut self) -> Prev {
21211 let mut prev = self.prev.take().unwrap();
21212 if let Some(header_offset) = &self.header_offset {
21213 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21214 }
21215 prev
21216 }
21217 pub fn push_link(mut self, value: u32) -> Self {
21218 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21219 self.as_rec_mut().extend(value.to_ne_bytes());
21220 self
21221 }
21222 pub fn push_ikey(mut self, value: u32) -> Self {
21223 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21224 self.as_rec_mut().extend(value.to_be_bytes());
21225 self
21226 }
21227 pub fn push_okey(mut self, value: u32) -> Self {
21228 push_header(self.as_rec_mut(), 3u16, 4 as u16);
21229 self.as_rec_mut().extend(value.to_be_bytes());
21230 self
21231 }
21232 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
21233 push_header(self.as_rec_mut(), 4u16, {
21234 match &value {
21235 IpAddr::V4(_) => 4,
21236 IpAddr::V6(_) => 16,
21237 }
21238 } as u16);
21239 encode_ip(self.as_rec_mut(), value);
21240 self
21241 }
21242 pub fn push_remote(mut self, value: std::net::IpAddr) -> Self {
21243 push_header(self.as_rec_mut(), 5u16, {
21244 match &value {
21245 IpAddr::V4(_) => 4,
21246 IpAddr::V6(_) => 16,
21247 }
21248 } as u16);
21249 encode_ip(self.as_rec_mut(), value);
21250 self
21251 }
21252 pub fn push_fwmark(mut self, value: u32) -> Self {
21253 push_header(self.as_rec_mut(), 6u16, 4 as u16);
21254 self.as_rec_mut().extend(value.to_ne_bytes());
21255 self
21256 }
21257}
21258impl<Prev: Rec> Drop for PushLinkinfoVtiAttrs<Prev> {
21259 fn drop(&mut self) {
21260 if let Some(prev) = &mut self.prev {
21261 if let Some(header_offset) = &self.header_offset {
21262 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21263 }
21264 }
21265 }
21266}
21267pub struct PushLinkinfoVti6Attrs<Prev: Rec> {
21268 pub(crate) prev: Option<Prev>,
21269 pub(crate) header_offset: Option<usize>,
21270}
21271impl<Prev: Rec> Rec for PushLinkinfoVti6Attrs<Prev> {
21272 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21273 self.prev.as_mut().unwrap().as_rec_mut()
21274 }
21275 fn as_rec(&self) -> &Vec<u8> {
21276 self.prev.as_ref().unwrap().as_rec()
21277 }
21278}
21279impl<Prev: Rec> PushLinkinfoVti6Attrs<Prev> {
21280 pub fn new(prev: Prev) -> Self {
21281 Self {
21282 prev: Some(prev),
21283 header_offset: None,
21284 }
21285 }
21286 pub fn end_nested(mut self) -> Prev {
21287 let mut prev = self.prev.take().unwrap();
21288 if let Some(header_offset) = &self.header_offset {
21289 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21290 }
21291 prev
21292 }
21293 pub fn push_link(mut self, value: u32) -> Self {
21294 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21295 self.as_rec_mut().extend(value.to_ne_bytes());
21296 self
21297 }
21298 pub fn push_ikey(mut self, value: u32) -> Self {
21299 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21300 self.as_rec_mut().extend(value.to_be_bytes());
21301 self
21302 }
21303 pub fn push_okey(mut self, value: u32) -> Self {
21304 push_header(self.as_rec_mut(), 3u16, 4 as u16);
21305 self.as_rec_mut().extend(value.to_be_bytes());
21306 self
21307 }
21308 pub fn push_local(mut self, value: &[u8]) -> Self {
21309 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
21310 self.as_rec_mut().extend(value);
21311 self
21312 }
21313 pub fn push_remote(mut self, value: &[u8]) -> Self {
21314 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
21315 self.as_rec_mut().extend(value);
21316 self
21317 }
21318 pub fn push_fwmark(mut self, value: u32) -> Self {
21319 push_header(self.as_rec_mut(), 6u16, 4 as u16);
21320 self.as_rec_mut().extend(value.to_ne_bytes());
21321 self
21322 }
21323}
21324impl<Prev: Rec> Drop for PushLinkinfoVti6Attrs<Prev> {
21325 fn drop(&mut self) {
21326 if let Some(prev) = &mut self.prev {
21327 if let Some(header_offset) = &self.header_offset {
21328 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21329 }
21330 }
21331 }
21332}
21333pub struct PushLinkinfoGeneveAttrs<Prev: Rec> {
21334 pub(crate) prev: Option<Prev>,
21335 pub(crate) header_offset: Option<usize>,
21336}
21337impl<Prev: Rec> Rec for PushLinkinfoGeneveAttrs<Prev> {
21338 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21339 self.prev.as_mut().unwrap().as_rec_mut()
21340 }
21341 fn as_rec(&self) -> &Vec<u8> {
21342 self.prev.as_ref().unwrap().as_rec()
21343 }
21344}
21345impl<Prev: Rec> PushLinkinfoGeneveAttrs<Prev> {
21346 pub fn new(prev: Prev) -> Self {
21347 Self {
21348 prev: Some(prev),
21349 header_offset: None,
21350 }
21351 }
21352 pub fn end_nested(mut self) -> Prev {
21353 let mut prev = self.prev.take().unwrap();
21354 if let Some(header_offset) = &self.header_offset {
21355 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21356 }
21357 prev
21358 }
21359 pub fn push_id(mut self, value: u32) -> Self {
21360 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21361 self.as_rec_mut().extend(value.to_ne_bytes());
21362 self
21363 }
21364 pub fn push_remote(mut self, value: std::net::Ipv4Addr) -> Self {
21365 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21366 self.as_rec_mut().extend(&value.to_bits().to_be_bytes());
21367 self
21368 }
21369 pub fn push_ttl(mut self, value: u8) -> Self {
21370 push_header(self.as_rec_mut(), 3u16, 1 as u16);
21371 self.as_rec_mut().extend(value.to_ne_bytes());
21372 self
21373 }
21374 pub fn push_tos(mut self, value: u8) -> Self {
21375 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21376 self.as_rec_mut().extend(value.to_ne_bytes());
21377 self
21378 }
21379 pub fn push_port(mut self, value: u16) -> Self {
21380 push_header(self.as_rec_mut(), 5u16, 2 as u16);
21381 self.as_rec_mut().extend(value.to_be_bytes());
21382 self
21383 }
21384 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21385 push_header(self.as_rec_mut(), 6u16, 0 as u16);
21386 self
21387 }
21388 pub fn push_remote6(mut self, value: &[u8]) -> Self {
21389 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
21390 self.as_rec_mut().extend(value);
21391 self
21392 }
21393 pub fn push_udp_csum(mut self, value: u8) -> Self {
21394 push_header(self.as_rec_mut(), 8u16, 1 as u16);
21395 self.as_rec_mut().extend(value.to_ne_bytes());
21396 self
21397 }
21398 pub fn push_udp_zero_csum6_tx(mut self, value: u8) -> Self {
21399 push_header(self.as_rec_mut(), 9u16, 1 as u16);
21400 self.as_rec_mut().extend(value.to_ne_bytes());
21401 self
21402 }
21403 pub fn push_udp_zero_csum6_rx(mut self, value: u8) -> Self {
21404 push_header(self.as_rec_mut(), 10u16, 1 as u16);
21405 self.as_rec_mut().extend(value.to_ne_bytes());
21406 self
21407 }
21408 pub fn push_label(mut self, value: u32) -> Self {
21409 push_header(self.as_rec_mut(), 11u16, 4 as u16);
21410 self.as_rec_mut().extend(value.to_be_bytes());
21411 self
21412 }
21413 pub fn push_ttl_inherit(mut self, value: u8) -> Self {
21414 push_header(self.as_rec_mut(), 12u16, 1 as u16);
21415 self.as_rec_mut().extend(value.to_ne_bytes());
21416 self
21417 }
21418 pub fn push_df(mut self, value: u8) -> Self {
21419 push_header(self.as_rec_mut(), 13u16, 1 as u16);
21420 self.as_rec_mut().extend(value.to_ne_bytes());
21421 self
21422 }
21423 pub fn push_inner_proto_inherit(mut self, value: ()) -> Self {
21424 push_header(self.as_rec_mut(), 14u16, 0 as u16);
21425 self
21426 }
21427 pub fn push_port_range(mut self, value: IflaGenevePortRange) -> Self {
21428 push_header(self.as_rec_mut(), 15u16, value.as_slice().len() as u16);
21429 self.as_rec_mut().extend(value.as_slice());
21430 self
21431 }
21432 pub fn push_gro_hint(mut self, value: ()) -> Self {
21433 push_header(self.as_rec_mut(), 16u16, 0 as u16);
21434 self
21435 }
21436}
21437impl<Prev: Rec> Drop for PushLinkinfoGeneveAttrs<Prev> {
21438 fn drop(&mut self) {
21439 if let Some(prev) = &mut self.prev {
21440 if let Some(header_offset) = &self.header_offset {
21441 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21442 }
21443 }
21444 }
21445}
21446pub struct PushLinkinfoHsrAttrs<Prev: Rec> {
21447 pub(crate) prev: Option<Prev>,
21448 pub(crate) header_offset: Option<usize>,
21449}
21450impl<Prev: Rec> Rec for PushLinkinfoHsrAttrs<Prev> {
21451 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21452 self.prev.as_mut().unwrap().as_rec_mut()
21453 }
21454 fn as_rec(&self) -> &Vec<u8> {
21455 self.prev.as_ref().unwrap().as_rec()
21456 }
21457}
21458impl<Prev: Rec> PushLinkinfoHsrAttrs<Prev> {
21459 pub fn new(prev: Prev) -> Self {
21460 Self {
21461 prev: Some(prev),
21462 header_offset: None,
21463 }
21464 }
21465 pub fn end_nested(mut self) -> Prev {
21466 let mut prev = self.prev.take().unwrap();
21467 if let Some(header_offset) = &self.header_offset {
21468 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21469 }
21470 prev
21471 }
21472 pub fn push_slave1(mut self, value: u32) -> Self {
21473 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21474 self.as_rec_mut().extend(value.to_ne_bytes());
21475 self
21476 }
21477 pub fn push_slave2(mut self, value: u32) -> Self {
21478 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21479 self.as_rec_mut().extend(value.to_ne_bytes());
21480 self
21481 }
21482 pub fn push_multicast_spec(mut self, value: u8) -> Self {
21483 push_header(self.as_rec_mut(), 3u16, 1 as u16);
21484 self.as_rec_mut().extend(value.to_ne_bytes());
21485 self
21486 }
21487 pub fn push_supervision_addr(mut self, value: &[u8]) -> Self {
21488 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
21489 self.as_rec_mut().extend(value);
21490 self
21491 }
21492 pub fn push_seq_nr(mut self, value: u16) -> Self {
21493 push_header(self.as_rec_mut(), 5u16, 2 as u16);
21494 self.as_rec_mut().extend(value.to_ne_bytes());
21495 self
21496 }
21497 pub fn push_version(mut self, value: u8) -> Self {
21498 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21499 self.as_rec_mut().extend(value.to_ne_bytes());
21500 self
21501 }
21502 pub fn push_protocol(mut self, value: u8) -> Self {
21503 push_header(self.as_rec_mut(), 7u16, 1 as u16);
21504 self.as_rec_mut().extend(value.to_ne_bytes());
21505 self
21506 }
21507 pub fn push_interlink(mut self, value: u32) -> Self {
21508 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21509 self.as_rec_mut().extend(value.to_ne_bytes());
21510 self
21511 }
21512}
21513impl<Prev: Rec> Drop for PushLinkinfoHsrAttrs<Prev> {
21514 fn drop(&mut self) {
21515 if let Some(prev) = &mut self.prev {
21516 if let Some(header_offset) = &self.header_offset {
21517 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21518 }
21519 }
21520 }
21521}
21522pub struct PushLinkinfoIptunAttrs<Prev: Rec> {
21523 pub(crate) prev: Option<Prev>,
21524 pub(crate) header_offset: Option<usize>,
21525}
21526impl<Prev: Rec> Rec for PushLinkinfoIptunAttrs<Prev> {
21527 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21528 self.prev.as_mut().unwrap().as_rec_mut()
21529 }
21530 fn as_rec(&self) -> &Vec<u8> {
21531 self.prev.as_ref().unwrap().as_rec()
21532 }
21533}
21534impl<Prev: Rec> PushLinkinfoIptunAttrs<Prev> {
21535 pub fn new(prev: Prev) -> Self {
21536 Self {
21537 prev: Some(prev),
21538 header_offset: None,
21539 }
21540 }
21541 pub fn end_nested(mut self) -> Prev {
21542 let mut prev = self.prev.take().unwrap();
21543 if let Some(header_offset) = &self.header_offset {
21544 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21545 }
21546 prev
21547 }
21548 pub fn push_link(mut self, value: u32) -> Self {
21549 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21550 self.as_rec_mut().extend(value.to_ne_bytes());
21551 self
21552 }
21553 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
21554 push_header(self.as_rec_mut(), 2u16, {
21555 match &value {
21556 IpAddr::V4(_) => 4,
21557 IpAddr::V6(_) => 16,
21558 }
21559 } as u16);
21560 encode_ip(self.as_rec_mut(), value);
21561 self
21562 }
21563 pub fn push_remote(mut self, value: std::net::IpAddr) -> Self {
21564 push_header(self.as_rec_mut(), 3u16, {
21565 match &value {
21566 IpAddr::V4(_) => 4,
21567 IpAddr::V6(_) => 16,
21568 }
21569 } as u16);
21570 encode_ip(self.as_rec_mut(), value);
21571 self
21572 }
21573 pub fn push_ttl(mut self, value: u8) -> Self {
21574 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21575 self.as_rec_mut().extend(value.to_ne_bytes());
21576 self
21577 }
21578 pub fn push_tos(mut self, value: u8) -> Self {
21579 push_header(self.as_rec_mut(), 5u16, 1 as u16);
21580 self.as_rec_mut().extend(value.to_ne_bytes());
21581 self
21582 }
21583 pub fn push_encap_limit(mut self, value: u8) -> Self {
21584 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21585 self.as_rec_mut().extend(value.to_ne_bytes());
21586 self
21587 }
21588 pub fn push_flowinfo(mut self, value: u32) -> Self {
21589 push_header(self.as_rec_mut(), 7u16, 4 as u16);
21590 self.as_rec_mut().extend(value.to_be_bytes());
21591 self
21592 }
21593 pub fn push_flags(mut self, value: u16) -> Self {
21594 push_header(self.as_rec_mut(), 8u16, 2 as u16);
21595 self.as_rec_mut().extend(value.to_be_bytes());
21596 self
21597 }
21598 pub fn push_proto(mut self, value: u8) -> Self {
21599 push_header(self.as_rec_mut(), 9u16, 1 as u16);
21600 self.as_rec_mut().extend(value.to_ne_bytes());
21601 self
21602 }
21603 pub fn push_pmtudisc(mut self, value: u8) -> Self {
21604 push_header(self.as_rec_mut(), 10u16, 1 as u16);
21605 self.as_rec_mut().extend(value.to_ne_bytes());
21606 self
21607 }
21608 pub fn push_6rd_prefix(mut self, value: &[u8]) -> Self {
21609 push_header(self.as_rec_mut(), 11u16, value.len() as u16);
21610 self.as_rec_mut().extend(value);
21611 self
21612 }
21613 pub fn push_6rd_relay_prefix(mut self, value: std::net::Ipv4Addr) -> Self {
21614 push_header(self.as_rec_mut(), 12u16, 4 as u16);
21615 self.as_rec_mut().extend(&value.to_bits().to_be_bytes());
21616 self
21617 }
21618 pub fn push_6rd_prefixlen(mut self, value: u16) -> Self {
21619 push_header(self.as_rec_mut(), 13u16, 2 as u16);
21620 self.as_rec_mut().extend(value.to_ne_bytes());
21621 self
21622 }
21623 pub fn push_6rd_relay_prefixlen(mut self, value: u16) -> Self {
21624 push_header(self.as_rec_mut(), 14u16, 2 as u16);
21625 self.as_rec_mut().extend(value.to_ne_bytes());
21626 self
21627 }
21628 pub fn push_encap_type(mut self, value: u16) -> Self {
21629 push_header(self.as_rec_mut(), 15u16, 2 as u16);
21630 self.as_rec_mut().extend(value.to_ne_bytes());
21631 self
21632 }
21633 pub fn push_encap_flags(mut self, value: u16) -> Self {
21634 push_header(self.as_rec_mut(), 16u16, 2 as u16);
21635 self.as_rec_mut().extend(value.to_ne_bytes());
21636 self
21637 }
21638 pub fn push_encap_sport(mut self, value: u16) -> Self {
21639 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21640 self.as_rec_mut().extend(value.to_be_bytes());
21641 self
21642 }
21643 pub fn push_encap_dport(mut self, value: u16) -> Self {
21644 push_header(self.as_rec_mut(), 18u16, 2 as u16);
21645 self.as_rec_mut().extend(value.to_be_bytes());
21646 self
21647 }
21648 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21649 push_header(self.as_rec_mut(), 19u16, 0 as u16);
21650 self
21651 }
21652 pub fn push_fwmark(mut self, value: u32) -> Self {
21653 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21654 self.as_rec_mut().extend(value.to_ne_bytes());
21655 self
21656 }
21657}
21658impl<Prev: Rec> Drop for PushLinkinfoIptunAttrs<Prev> {
21659 fn drop(&mut self) {
21660 if let Some(prev) = &mut self.prev {
21661 if let Some(header_offset) = &self.header_offset {
21662 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21663 }
21664 }
21665 }
21666}
21667pub struct PushLinkinfoIp6tnlAttrs<Prev: Rec> {
21668 pub(crate) prev: Option<Prev>,
21669 pub(crate) header_offset: Option<usize>,
21670}
21671impl<Prev: Rec> Rec for PushLinkinfoIp6tnlAttrs<Prev> {
21672 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21673 self.prev.as_mut().unwrap().as_rec_mut()
21674 }
21675 fn as_rec(&self) -> &Vec<u8> {
21676 self.prev.as_ref().unwrap().as_rec()
21677 }
21678}
21679impl<Prev: Rec> PushLinkinfoIp6tnlAttrs<Prev> {
21680 pub fn new(prev: Prev) -> Self {
21681 Self {
21682 prev: Some(prev),
21683 header_offset: None,
21684 }
21685 }
21686 pub fn end_nested(mut self) -> Prev {
21687 let mut prev = self.prev.take().unwrap();
21688 if let Some(header_offset) = &self.header_offset {
21689 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21690 }
21691 prev
21692 }
21693 pub fn push_link(mut self, value: u32) -> Self {
21694 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21695 self.as_rec_mut().extend(value.to_ne_bytes());
21696 self
21697 }
21698 pub fn push_local(mut self, value: &[u8]) -> Self {
21699 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
21700 self.as_rec_mut().extend(value);
21701 self
21702 }
21703 pub fn push_remote(mut self, value: &[u8]) -> Self {
21704 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
21705 self.as_rec_mut().extend(value);
21706 self
21707 }
21708 pub fn push_ttl(mut self, value: u8) -> Self {
21709 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21710 self.as_rec_mut().extend(value.to_ne_bytes());
21711 self
21712 }
21713 pub fn push_encap_limit(mut self, value: u8) -> Self {
21714 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21715 self.as_rec_mut().extend(value.to_ne_bytes());
21716 self
21717 }
21718 pub fn push_flowinfo(mut self, value: u32) -> Self {
21719 push_header(self.as_rec_mut(), 7u16, 4 as u16);
21720 self.as_rec_mut().extend(value.to_be_bytes());
21721 self
21722 }
21723 pub fn push_flags(mut self, value: u32) -> Self {
21724 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21725 self.as_rec_mut().extend(value.to_be_bytes());
21726 self
21727 }
21728 pub fn push_proto(mut self, value: u8) -> Self {
21729 push_header(self.as_rec_mut(), 9u16, 1 as u16);
21730 self.as_rec_mut().extend(value.to_ne_bytes());
21731 self
21732 }
21733 pub fn push_encap_type(mut self, value: u16) -> Self {
21734 push_header(self.as_rec_mut(), 15u16, 2 as u16);
21735 self.as_rec_mut().extend(value.to_ne_bytes());
21736 self
21737 }
21738 pub fn push_encap_flags(mut self, value: u16) -> Self {
21739 push_header(self.as_rec_mut(), 16u16, 2 as u16);
21740 self.as_rec_mut().extend(value.to_ne_bytes());
21741 self
21742 }
21743 pub fn push_encap_sport(mut self, value: u16) -> Self {
21744 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21745 self.as_rec_mut().extend(value.to_be_bytes());
21746 self
21747 }
21748 pub fn push_encap_dport(mut self, value: u16) -> Self {
21749 push_header(self.as_rec_mut(), 18u16, 2 as u16);
21750 self.as_rec_mut().extend(value.to_be_bytes());
21751 self
21752 }
21753 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21754 push_header(self.as_rec_mut(), 19u16, 0 as u16);
21755 self
21756 }
21757 pub fn push_fwmark(mut self, value: u32) -> Self {
21758 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21759 self.as_rec_mut().extend(value.to_ne_bytes());
21760 self
21761 }
21762}
21763impl<Prev: Rec> Drop for PushLinkinfoIp6tnlAttrs<Prev> {
21764 fn drop(&mut self) {
21765 if let Some(prev) = &mut self.prev {
21766 if let Some(header_offset) = &self.header_offset {
21767 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21768 }
21769 }
21770 }
21771}
21772pub struct PushLinkinfoTunAttrs<Prev: Rec> {
21773 pub(crate) prev: Option<Prev>,
21774 pub(crate) header_offset: Option<usize>,
21775}
21776impl<Prev: Rec> Rec for PushLinkinfoTunAttrs<Prev> {
21777 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21778 self.prev.as_mut().unwrap().as_rec_mut()
21779 }
21780 fn as_rec(&self) -> &Vec<u8> {
21781 self.prev.as_ref().unwrap().as_rec()
21782 }
21783}
21784impl<Prev: Rec> PushLinkinfoTunAttrs<Prev> {
21785 pub fn new(prev: Prev) -> Self {
21786 Self {
21787 prev: Some(prev),
21788 header_offset: None,
21789 }
21790 }
21791 pub fn end_nested(mut self) -> Prev {
21792 let mut prev = self.prev.take().unwrap();
21793 if let Some(header_offset) = &self.header_offset {
21794 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21795 }
21796 prev
21797 }
21798 pub fn push_owner(mut self, value: u32) -> Self {
21799 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21800 self.as_rec_mut().extend(value.to_ne_bytes());
21801 self
21802 }
21803 pub fn push_group(mut self, value: u32) -> Self {
21804 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21805 self.as_rec_mut().extend(value.to_ne_bytes());
21806 self
21807 }
21808 pub fn push_type(mut self, value: u8) -> Self {
21809 push_header(self.as_rec_mut(), 3u16, 1 as u16);
21810 self.as_rec_mut().extend(value.to_ne_bytes());
21811 self
21812 }
21813 pub fn push_pi(mut self, value: u8) -> Self {
21814 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21815 self.as_rec_mut().extend(value.to_ne_bytes());
21816 self
21817 }
21818 pub fn push_vnet_hdr(mut self, value: u8) -> Self {
21819 push_header(self.as_rec_mut(), 5u16, 1 as u16);
21820 self.as_rec_mut().extend(value.to_ne_bytes());
21821 self
21822 }
21823 pub fn push_persist(mut self, value: u8) -> Self {
21824 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21825 self.as_rec_mut().extend(value.to_ne_bytes());
21826 self
21827 }
21828 pub fn push_multi_queue(mut self, value: u8) -> Self {
21829 push_header(self.as_rec_mut(), 7u16, 1 as u16);
21830 self.as_rec_mut().extend(value.to_ne_bytes());
21831 self
21832 }
21833 pub fn push_num_queues(mut self, value: u32) -> Self {
21834 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21835 self.as_rec_mut().extend(value.to_ne_bytes());
21836 self
21837 }
21838 pub fn push_num_disabled_queues(mut self, value: u32) -> Self {
21839 push_header(self.as_rec_mut(), 9u16, 4 as u16);
21840 self.as_rec_mut().extend(value.to_ne_bytes());
21841 self
21842 }
21843}
21844impl<Prev: Rec> Drop for PushLinkinfoTunAttrs<Prev> {
21845 fn drop(&mut self) {
21846 if let Some(prev) = &mut self.prev {
21847 if let Some(header_offset) = &self.header_offset {
21848 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21849 }
21850 }
21851 }
21852}
21853pub struct PushLinkinfoVlanAttrs<Prev: Rec> {
21854 pub(crate) prev: Option<Prev>,
21855 pub(crate) header_offset: Option<usize>,
21856}
21857impl<Prev: Rec> Rec for PushLinkinfoVlanAttrs<Prev> {
21858 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21859 self.prev.as_mut().unwrap().as_rec_mut()
21860 }
21861 fn as_rec(&self) -> &Vec<u8> {
21862 self.prev.as_ref().unwrap().as_rec()
21863 }
21864}
21865impl<Prev: Rec> PushLinkinfoVlanAttrs<Prev> {
21866 pub fn new(prev: Prev) -> Self {
21867 Self {
21868 prev: Some(prev),
21869 header_offset: None,
21870 }
21871 }
21872 pub fn end_nested(mut self) -> Prev {
21873 let mut prev = self.prev.take().unwrap();
21874 if let Some(header_offset) = &self.header_offset {
21875 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21876 }
21877 prev
21878 }
21879 pub fn push_id(mut self, value: u16) -> Self {
21880 push_header(self.as_rec_mut(), 1u16, 2 as u16);
21881 self.as_rec_mut().extend(value.to_ne_bytes());
21882 self
21883 }
21884 pub fn push_flags(mut self, value: IflaVlanFlags) -> Self {
21885 push_header(self.as_rec_mut(), 2u16, value.as_slice().len() as u16);
21886 self.as_rec_mut().extend(value.as_slice());
21887 self
21888 }
21889 pub fn nested_egress_qos(mut self) -> PushIflaVlanQos<Self> {
21890 let header_offset = push_nested_header(self.as_rec_mut(), 3u16);
21891 PushIflaVlanQos {
21892 prev: Some(self),
21893 header_offset: Some(header_offset),
21894 }
21895 }
21896 pub fn nested_ingress_qos(mut self) -> PushIflaVlanQos<Self> {
21897 let header_offset = push_nested_header(self.as_rec_mut(), 4u16);
21898 PushIflaVlanQos {
21899 prev: Some(self),
21900 header_offset: Some(header_offset),
21901 }
21902 }
21903 #[doc = "Associated type: [`VlanProtocols`] (enum)"]
21904 pub fn push_protocol(mut self, value: u16) -> Self {
21905 push_header(self.as_rec_mut(), 5u16, 2 as u16);
21906 self.as_rec_mut().extend(value.to_be_bytes());
21907 self
21908 }
21909}
21910impl<Prev: Rec> Drop for PushLinkinfoVlanAttrs<Prev> {
21911 fn drop(&mut self) {
21912 if let Some(prev) = &mut self.prev {
21913 if let Some(header_offset) = &self.header_offset {
21914 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21915 }
21916 }
21917 }
21918}
21919pub struct PushIflaVlanQos<Prev: Rec> {
21920 pub(crate) prev: Option<Prev>,
21921 pub(crate) header_offset: Option<usize>,
21922}
21923impl<Prev: Rec> Rec for PushIflaVlanQos<Prev> {
21924 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21925 self.prev.as_mut().unwrap().as_rec_mut()
21926 }
21927 fn as_rec(&self) -> &Vec<u8> {
21928 self.prev.as_ref().unwrap().as_rec()
21929 }
21930}
21931impl<Prev: Rec> PushIflaVlanQos<Prev> {
21932 pub fn new(prev: Prev) -> Self {
21933 Self {
21934 prev: Some(prev),
21935 header_offset: None,
21936 }
21937 }
21938 pub fn end_nested(mut self) -> Prev {
21939 let mut prev = self.prev.take().unwrap();
21940 if let Some(header_offset) = &self.header_offset {
21941 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21942 }
21943 prev
21944 }
21945 #[doc = "Attribute may repeat multiple times (treat it as array)"]
21946 pub fn push_mapping(mut self, value: IflaVlanQosMapping) -> Self {
21947 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
21948 self.as_rec_mut().extend(value.as_slice());
21949 self
21950 }
21951}
21952impl<Prev: Rec> Drop for PushIflaVlanQos<Prev> {
21953 fn drop(&mut self) {
21954 if let Some(prev) = &mut self.prev {
21955 if let Some(header_offset) = &self.header_offset {
21956 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21957 }
21958 }
21959 }
21960}
21961pub struct PushLinkinfoVrfAttrs<Prev: Rec> {
21962 pub(crate) prev: Option<Prev>,
21963 pub(crate) header_offset: Option<usize>,
21964}
21965impl<Prev: Rec> Rec for PushLinkinfoVrfAttrs<Prev> {
21966 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21967 self.prev.as_mut().unwrap().as_rec_mut()
21968 }
21969 fn as_rec(&self) -> &Vec<u8> {
21970 self.prev.as_ref().unwrap().as_rec()
21971 }
21972}
21973impl<Prev: Rec> PushLinkinfoVrfAttrs<Prev> {
21974 pub fn new(prev: Prev) -> Self {
21975 Self {
21976 prev: Some(prev),
21977 header_offset: None,
21978 }
21979 }
21980 pub fn end_nested(mut self) -> Prev {
21981 let mut prev = self.prev.take().unwrap();
21982 if let Some(header_offset) = &self.header_offset {
21983 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21984 }
21985 prev
21986 }
21987 pub fn push_table(mut self, value: u32) -> Self {
21988 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21989 self.as_rec_mut().extend(value.to_ne_bytes());
21990 self
21991 }
21992}
21993impl<Prev: Rec> Drop for PushLinkinfoVrfAttrs<Prev> {
21994 fn drop(&mut self) {
21995 if let Some(prev) = &mut self.prev {
21996 if let Some(header_offset) = &self.header_offset {
21997 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21998 }
21999 }
22000 }
22001}
22002pub struct PushXdpAttrs<Prev: Rec> {
22003 pub(crate) prev: Option<Prev>,
22004 pub(crate) header_offset: Option<usize>,
22005}
22006impl<Prev: Rec> Rec for PushXdpAttrs<Prev> {
22007 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22008 self.prev.as_mut().unwrap().as_rec_mut()
22009 }
22010 fn as_rec(&self) -> &Vec<u8> {
22011 self.prev.as_ref().unwrap().as_rec()
22012 }
22013}
22014impl<Prev: Rec> PushXdpAttrs<Prev> {
22015 pub fn new(prev: Prev) -> Self {
22016 Self {
22017 prev: Some(prev),
22018 header_offset: None,
22019 }
22020 }
22021 pub fn end_nested(mut self) -> Prev {
22022 let mut prev = self.prev.take().unwrap();
22023 if let Some(header_offset) = &self.header_offset {
22024 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22025 }
22026 prev
22027 }
22028 pub fn push_fd(mut self, value: i32) -> Self {
22029 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22030 self.as_rec_mut().extend(value.to_ne_bytes());
22031 self
22032 }
22033 pub fn push_attached(mut self, value: u8) -> Self {
22034 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22035 self.as_rec_mut().extend(value.to_ne_bytes());
22036 self
22037 }
22038 pub fn push_flags(mut self, value: u32) -> Self {
22039 push_header(self.as_rec_mut(), 3u16, 4 as u16);
22040 self.as_rec_mut().extend(value.to_ne_bytes());
22041 self
22042 }
22043 pub fn push_prog_id(mut self, value: u32) -> Self {
22044 push_header(self.as_rec_mut(), 4u16, 4 as u16);
22045 self.as_rec_mut().extend(value.to_ne_bytes());
22046 self
22047 }
22048 pub fn push_drv_prog_id(mut self, value: u32) -> Self {
22049 push_header(self.as_rec_mut(), 5u16, 4 as u16);
22050 self.as_rec_mut().extend(value.to_ne_bytes());
22051 self
22052 }
22053 pub fn push_skb_prog_id(mut self, value: u32) -> Self {
22054 push_header(self.as_rec_mut(), 6u16, 4 as u16);
22055 self.as_rec_mut().extend(value.to_ne_bytes());
22056 self
22057 }
22058 pub fn push_hw_prog_id(mut self, value: u32) -> Self {
22059 push_header(self.as_rec_mut(), 7u16, 4 as u16);
22060 self.as_rec_mut().extend(value.to_ne_bytes());
22061 self
22062 }
22063 pub fn push_expected_fd(mut self, value: i32) -> Self {
22064 push_header(self.as_rec_mut(), 8u16, 4 as u16);
22065 self.as_rec_mut().extend(value.to_ne_bytes());
22066 self
22067 }
22068}
22069impl<Prev: Rec> Drop for PushXdpAttrs<Prev> {
22070 fn drop(&mut self) {
22071 if let Some(prev) = &mut self.prev {
22072 if let Some(header_offset) = &self.header_offset {
22073 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22074 }
22075 }
22076 }
22077}
22078pub struct PushIflaAttrs<Prev: Rec> {
22079 pub(crate) prev: Option<Prev>,
22080 pub(crate) header_offset: Option<usize>,
22081}
22082impl<Prev: Rec> Rec for PushIflaAttrs<Prev> {
22083 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22084 self.prev.as_mut().unwrap().as_rec_mut()
22085 }
22086 fn as_rec(&self) -> &Vec<u8> {
22087 self.prev.as_ref().unwrap().as_rec()
22088 }
22089}
22090impl<Prev: Rec> PushIflaAttrs<Prev> {
22091 pub fn new(prev: Prev) -> Self {
22092 Self {
22093 prev: Some(prev),
22094 header_offset: None,
22095 }
22096 }
22097 pub fn end_nested(mut self) -> Prev {
22098 let mut prev = self.prev.take().unwrap();
22099 if let Some(header_offset) = &self.header_offset {
22100 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22101 }
22102 prev
22103 }
22104 #[doc = "u32 indexed by ipv4-devconf - 1 on output, on input it\\'s a nest\n"]
22105 pub fn push_conf(mut self, value: &[u8]) -> Self {
22106 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
22107 self.as_rec_mut().extend(value);
22108 self
22109 }
22110}
22111impl<Prev: Rec> Drop for PushIflaAttrs<Prev> {
22112 fn drop(&mut self) {
22113 if let Some(prev) = &mut self.prev {
22114 if let Some(header_offset) = &self.header_offset {
22115 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22116 }
22117 }
22118 }
22119}
22120pub struct PushIfla6Attrs<Prev: Rec> {
22121 pub(crate) prev: Option<Prev>,
22122 pub(crate) header_offset: Option<usize>,
22123}
22124impl<Prev: Rec> Rec for PushIfla6Attrs<Prev> {
22125 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22126 self.prev.as_mut().unwrap().as_rec_mut()
22127 }
22128 fn as_rec(&self) -> &Vec<u8> {
22129 self.prev.as_ref().unwrap().as_rec()
22130 }
22131}
22132impl<Prev: Rec> PushIfla6Attrs<Prev> {
22133 pub fn new(prev: Prev) -> Self {
22134 Self {
22135 prev: Some(prev),
22136 header_offset: None,
22137 }
22138 }
22139 pub fn end_nested(mut self) -> Prev {
22140 let mut prev = self.prev.take().unwrap();
22141 if let Some(header_offset) = &self.header_offset {
22142 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22143 }
22144 prev
22145 }
22146 pub fn push_flags(mut self, value: u32) -> Self {
22147 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22148 self.as_rec_mut().extend(value.to_ne_bytes());
22149 self
22150 }
22151 #[doc = "u32 indexed by ipv6-devconf - 1 on output, on input it\\'s a nest\n"]
22152 pub fn push_conf(mut self, value: &[u8]) -> Self {
22153 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
22154 self.as_rec_mut().extend(value);
22155 self
22156 }
22157 pub fn push_stats(mut self, value: &[u8]) -> Self {
22158 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
22159 self.as_rec_mut().extend(value);
22160 self
22161 }
22162 pub fn push_mcast(mut self, value: &[u8]) -> Self {
22163 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
22164 self.as_rec_mut().extend(value);
22165 self
22166 }
22167 pub fn push_cacheinfo(mut self, value: IflaCacheinfo) -> Self {
22168 push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
22169 self.as_rec_mut().extend(value.as_slice());
22170 self
22171 }
22172 pub fn push_icmp6stats(mut self, value: &[u8]) -> Self {
22173 push_header(self.as_rec_mut(), 6u16, value.len() as u16);
22174 self.as_rec_mut().extend(value);
22175 self
22176 }
22177 pub fn push_token(mut self, value: &[u8]) -> Self {
22178 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
22179 self.as_rec_mut().extend(value);
22180 self
22181 }
22182 pub fn push_addr_gen_mode(mut self, value: u8) -> Self {
22183 push_header(self.as_rec_mut(), 8u16, 1 as u16);
22184 self.as_rec_mut().extend(value.to_ne_bytes());
22185 self
22186 }
22187 pub fn push_ra_mtu(mut self, value: u32) -> Self {
22188 push_header(self.as_rec_mut(), 9u16, 4 as u16);
22189 self.as_rec_mut().extend(value.to_ne_bytes());
22190 self
22191 }
22192}
22193impl<Prev: Rec> Drop for PushIfla6Attrs<Prev> {
22194 fn drop(&mut self) {
22195 if let Some(prev) = &mut self.prev {
22196 if let Some(header_offset) = &self.header_offset {
22197 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22198 }
22199 }
22200 }
22201}
22202pub struct PushMctpAttrs<Prev: Rec> {
22203 pub(crate) prev: Option<Prev>,
22204 pub(crate) header_offset: Option<usize>,
22205}
22206impl<Prev: Rec> Rec for PushMctpAttrs<Prev> {
22207 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22208 self.prev.as_mut().unwrap().as_rec_mut()
22209 }
22210 fn as_rec(&self) -> &Vec<u8> {
22211 self.prev.as_ref().unwrap().as_rec()
22212 }
22213}
22214impl<Prev: Rec> PushMctpAttrs<Prev> {
22215 pub fn new(prev: Prev) -> Self {
22216 Self {
22217 prev: Some(prev),
22218 header_offset: None,
22219 }
22220 }
22221 pub fn end_nested(mut self) -> Prev {
22222 let mut prev = self.prev.take().unwrap();
22223 if let Some(header_offset) = &self.header_offset {
22224 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22225 }
22226 prev
22227 }
22228 pub fn push_net(mut self, value: u32) -> Self {
22229 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22230 self.as_rec_mut().extend(value.to_ne_bytes());
22231 self
22232 }
22233 pub fn push_phys_binding(mut self, value: u8) -> Self {
22234 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22235 self.as_rec_mut().extend(value.to_ne_bytes());
22236 self
22237 }
22238}
22239impl<Prev: Rec> Drop for PushMctpAttrs<Prev> {
22240 fn drop(&mut self) {
22241 if let Some(prev) = &mut self.prev {
22242 if let Some(header_offset) = &self.header_offset {
22243 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22244 }
22245 }
22246 }
22247}
22248pub struct PushStatsAttrs<Prev: Rec> {
22249 pub(crate) prev: Option<Prev>,
22250 pub(crate) header_offset: Option<usize>,
22251}
22252impl<Prev: Rec> Rec for PushStatsAttrs<Prev> {
22253 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22254 self.prev.as_mut().unwrap().as_rec_mut()
22255 }
22256 fn as_rec(&self) -> &Vec<u8> {
22257 self.prev.as_ref().unwrap().as_rec()
22258 }
22259}
22260impl<Prev: Rec> PushStatsAttrs<Prev> {
22261 pub fn new(prev: Prev) -> Self {
22262 Self {
22263 prev: Some(prev),
22264 header_offset: None,
22265 }
22266 }
22267 pub fn end_nested(mut self) -> Prev {
22268 let mut prev = self.prev.take().unwrap();
22269 if let Some(header_offset) = &self.header_offset {
22270 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22271 }
22272 prev
22273 }
22274 pub fn push_link_64(mut self, value: RtnlLinkStats64) -> Self {
22275 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
22276 self.as_rec_mut().extend(value.as_slice());
22277 self
22278 }
22279 pub fn push_link_xstats(mut self, value: &[u8]) -> Self {
22280 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
22281 self.as_rec_mut().extend(value);
22282 self
22283 }
22284 pub fn push_link_xstats_slave(mut self, value: &[u8]) -> Self {
22285 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
22286 self.as_rec_mut().extend(value);
22287 self
22288 }
22289 pub fn nested_link_offload_xstats(mut self) -> PushLinkOffloadXstats<Self> {
22290 let header_offset = push_nested_header(self.as_rec_mut(), 4u16);
22291 PushLinkOffloadXstats {
22292 prev: Some(self),
22293 header_offset: Some(header_offset),
22294 }
22295 }
22296 pub fn push_af_spec(mut self, value: &[u8]) -> Self {
22297 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
22298 self.as_rec_mut().extend(value);
22299 self
22300 }
22301}
22302impl<Prev: Rec> Drop for PushStatsAttrs<Prev> {
22303 fn drop(&mut self) {
22304 if let Some(prev) = &mut self.prev {
22305 if let Some(header_offset) = &self.header_offset {
22306 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22307 }
22308 }
22309 }
22310}
22311pub struct PushLinkOffloadXstats<Prev: Rec> {
22312 pub(crate) prev: Option<Prev>,
22313 pub(crate) header_offset: Option<usize>,
22314}
22315impl<Prev: Rec> Rec for PushLinkOffloadXstats<Prev> {
22316 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22317 self.prev.as_mut().unwrap().as_rec_mut()
22318 }
22319 fn as_rec(&self) -> &Vec<u8> {
22320 self.prev.as_ref().unwrap().as_rec()
22321 }
22322}
22323pub struct PushArrayHwSInfoOne<Prev: Rec> {
22324 pub(crate) prev: Option<Prev>,
22325 pub(crate) header_offset: Option<usize>,
22326 pub(crate) counter: u16,
22327}
22328impl<Prev: Rec> Rec for PushArrayHwSInfoOne<Prev> {
22329 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22330 self.prev.as_mut().unwrap().as_rec_mut()
22331 }
22332 fn as_rec(&self) -> &Vec<u8> {
22333 self.prev.as_ref().unwrap().as_rec()
22334 }
22335}
22336impl<Prev: Rec> PushArrayHwSInfoOne<Prev> {
22337 pub fn new(prev: Prev) -> Self {
22338 Self {
22339 prev: Some(prev),
22340 header_offset: None,
22341 counter: 0,
22342 }
22343 }
22344 pub fn end_array(mut self) -> Prev {
22345 let mut prev = self.prev.take().unwrap();
22346 if let Some(header_offset) = &self.header_offset {
22347 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22348 }
22349 prev
22350 }
22351 pub fn entry_nested(mut self) -> PushHwSInfoOne<Self> {
22352 let index = self.counter;
22353 self.counter += 1;
22354 let header_offset = push_nested_header(self.as_rec_mut(), index);
22355 PushHwSInfoOne {
22356 prev: Some(self),
22357 header_offset: Some(header_offset),
22358 }
22359 }
22360}
22361impl<Prev: Rec> Drop for PushArrayHwSInfoOne<Prev> {
22362 fn drop(&mut self) {
22363 if let Some(prev) = &mut self.prev {
22364 if let Some(header_offset) = &self.header_offset {
22365 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22366 }
22367 }
22368 }
22369}
22370impl<Prev: Rec> PushLinkOffloadXstats<Prev> {
22371 pub fn new(prev: Prev) -> Self {
22372 Self {
22373 prev: Some(prev),
22374 header_offset: None,
22375 }
22376 }
22377 pub fn end_nested(mut self) -> Prev {
22378 let mut prev = self.prev.take().unwrap();
22379 if let Some(header_offset) = &self.header_offset {
22380 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22381 }
22382 prev
22383 }
22384 pub fn push_cpu_hit(mut self, value: &[u8]) -> Self {
22385 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
22386 self.as_rec_mut().extend(value);
22387 self
22388 }
22389 pub fn array_hw_s_info(mut self) -> PushArrayHwSInfoOne<Self> {
22390 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
22391 PushArrayHwSInfoOne {
22392 prev: Some(self),
22393 header_offset: Some(header_offset),
22394 counter: 0,
22395 }
22396 }
22397 pub fn push_l3_stats(mut self, value: &[u8]) -> Self {
22398 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
22399 self.as_rec_mut().extend(value);
22400 self
22401 }
22402}
22403impl<Prev: Rec> Drop for PushLinkOffloadXstats<Prev> {
22404 fn drop(&mut self) {
22405 if let Some(prev) = &mut self.prev {
22406 if let Some(header_offset) = &self.header_offset {
22407 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22408 }
22409 }
22410 }
22411}
22412pub struct PushHwSInfoOne<Prev: Rec> {
22413 pub(crate) prev: Option<Prev>,
22414 pub(crate) header_offset: Option<usize>,
22415}
22416impl<Prev: Rec> Rec for PushHwSInfoOne<Prev> {
22417 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22418 self.prev.as_mut().unwrap().as_rec_mut()
22419 }
22420 fn as_rec(&self) -> &Vec<u8> {
22421 self.prev.as_ref().unwrap().as_rec()
22422 }
22423}
22424impl<Prev: Rec> PushHwSInfoOne<Prev> {
22425 pub fn new(prev: Prev) -> Self {
22426 Self {
22427 prev: Some(prev),
22428 header_offset: None,
22429 }
22430 }
22431 pub fn end_nested(mut self) -> Prev {
22432 let mut prev = self.prev.take().unwrap();
22433 if let Some(header_offset) = &self.header_offset {
22434 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22435 }
22436 prev
22437 }
22438 pub fn push_request(mut self, value: u8) -> Self {
22439 push_header(self.as_rec_mut(), 1u16, 1 as u16);
22440 self.as_rec_mut().extend(value.to_ne_bytes());
22441 self
22442 }
22443 pub fn push_used(mut self, value: u8) -> Self {
22444 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22445 self.as_rec_mut().extend(value.to_ne_bytes());
22446 self
22447 }
22448}
22449impl<Prev: Rec> Drop for PushHwSInfoOne<Prev> {
22450 fn drop(&mut self) {
22451 if let Some(prev) = &mut self.prev {
22452 if let Some(header_offset) = &self.header_offset {
22453 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22454 }
22455 }
22456 }
22457}
22458pub struct PushLinkDpllPinAttrs<Prev: Rec> {
22459 pub(crate) prev: Option<Prev>,
22460 pub(crate) header_offset: Option<usize>,
22461}
22462impl<Prev: Rec> Rec for PushLinkDpllPinAttrs<Prev> {
22463 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22464 self.prev.as_mut().unwrap().as_rec_mut()
22465 }
22466 fn as_rec(&self) -> &Vec<u8> {
22467 self.prev.as_ref().unwrap().as_rec()
22468 }
22469}
22470impl<Prev: Rec> PushLinkDpllPinAttrs<Prev> {
22471 pub fn new(prev: Prev) -> Self {
22472 Self {
22473 prev: Some(prev),
22474 header_offset: None,
22475 }
22476 }
22477 pub fn end_nested(mut self) -> Prev {
22478 let mut prev = self.prev.take().unwrap();
22479 if let Some(header_offset) = &self.header_offset {
22480 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22481 }
22482 prev
22483 }
22484 pub fn push_id(mut self, value: u32) -> Self {
22485 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22486 self.as_rec_mut().extend(value.to_ne_bytes());
22487 self
22488 }
22489}
22490impl<Prev: Rec> Drop for PushLinkDpllPinAttrs<Prev> {
22491 fn drop(&mut self) {
22492 if let Some(prev) = &mut self.prev {
22493 if let Some(header_offset) = &self.header_offset {
22494 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22495 }
22496 }
22497 }
22498}
22499pub struct PushLinkinfoNetkitAttrs<Prev: Rec> {
22500 pub(crate) prev: Option<Prev>,
22501 pub(crate) header_offset: Option<usize>,
22502}
22503impl<Prev: Rec> Rec for PushLinkinfoNetkitAttrs<Prev> {
22504 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22505 self.prev.as_mut().unwrap().as_rec_mut()
22506 }
22507 fn as_rec(&self) -> &Vec<u8> {
22508 self.prev.as_ref().unwrap().as_rec()
22509 }
22510}
22511impl<Prev: Rec> PushLinkinfoNetkitAttrs<Prev> {
22512 pub fn new(prev: Prev) -> Self {
22513 Self {
22514 prev: Some(prev),
22515 header_offset: None,
22516 }
22517 }
22518 pub fn end_nested(mut self) -> Prev {
22519 let mut prev = self.prev.take().unwrap();
22520 if let Some(header_offset) = &self.header_offset {
22521 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22522 }
22523 prev
22524 }
22525 pub fn push_peer_info(mut self, value: &[u8]) -> Self {
22526 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
22527 self.as_rec_mut().extend(value);
22528 self
22529 }
22530 pub fn push_primary(mut self, value: u8) -> Self {
22531 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22532 self.as_rec_mut().extend(value.to_ne_bytes());
22533 self
22534 }
22535 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
22536 pub fn push_policy(mut self, value: u32) -> Self {
22537 push_header(self.as_rec_mut(), 3u16, 4 as u16);
22538 self.as_rec_mut().extend(value.to_ne_bytes());
22539 self
22540 }
22541 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
22542 pub fn push_peer_policy(mut self, value: u32) -> Self {
22543 push_header(self.as_rec_mut(), 4u16, 4 as u16);
22544 self.as_rec_mut().extend(value.to_ne_bytes());
22545 self
22546 }
22547 #[doc = "Associated type: [`NetkitMode`] (enum)"]
22548 pub fn push_mode(mut self, value: u32) -> Self {
22549 push_header(self.as_rec_mut(), 5u16, 4 as u16);
22550 self.as_rec_mut().extend(value.to_ne_bytes());
22551 self
22552 }
22553 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
22554 pub fn push_scrub(mut self, value: u32) -> Self {
22555 push_header(self.as_rec_mut(), 6u16, 4 as u16);
22556 self.as_rec_mut().extend(value.to_ne_bytes());
22557 self
22558 }
22559 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
22560 pub fn push_peer_scrub(mut self, value: u32) -> Self {
22561 push_header(self.as_rec_mut(), 7u16, 4 as u16);
22562 self.as_rec_mut().extend(value.to_ne_bytes());
22563 self
22564 }
22565 pub fn push_headroom(mut self, value: u16) -> Self {
22566 push_header(self.as_rec_mut(), 8u16, 2 as u16);
22567 self.as_rec_mut().extend(value.to_ne_bytes());
22568 self
22569 }
22570 pub fn push_tailroom(mut self, value: u16) -> Self {
22571 push_header(self.as_rec_mut(), 9u16, 2 as u16);
22572 self.as_rec_mut().extend(value.to_ne_bytes());
22573 self
22574 }
22575 #[doc = "Associated type: [`NetkitPairing`] (enum)"]
22576 pub fn push_pairing(mut self, value: u32) -> Self {
22577 push_header(self.as_rec_mut(), 10u16, 4 as u16);
22578 self.as_rec_mut().extend(value.to_ne_bytes());
22579 self
22580 }
22581}
22582impl<Prev: Rec> Drop for PushLinkinfoNetkitAttrs<Prev> {
22583 fn drop(&mut self) {
22584 if let Some(prev) = &mut self.prev {
22585 if let Some(header_offset) = &self.header_offset {
22586 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22587 }
22588 }
22589 }
22590}
22591pub struct PushLinkinfoOvpnAttrs<Prev: Rec> {
22592 pub(crate) prev: Option<Prev>,
22593 pub(crate) header_offset: Option<usize>,
22594}
22595impl<Prev: Rec> Rec for PushLinkinfoOvpnAttrs<Prev> {
22596 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22597 self.prev.as_mut().unwrap().as_rec_mut()
22598 }
22599 fn as_rec(&self) -> &Vec<u8> {
22600 self.prev.as_ref().unwrap().as_rec()
22601 }
22602}
22603impl<Prev: Rec> PushLinkinfoOvpnAttrs<Prev> {
22604 pub fn new(prev: Prev) -> Self {
22605 Self {
22606 prev: Some(prev),
22607 header_offset: None,
22608 }
22609 }
22610 pub fn end_nested(mut self) -> Prev {
22611 let mut prev = self.prev.take().unwrap();
22612 if let Some(header_offset) = &self.header_offset {
22613 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22614 }
22615 prev
22616 }
22617 #[doc = "Associated type: [`OvpnMode`] (enum)"]
22618 pub fn push_mode(mut self, value: u8) -> Self {
22619 push_header(self.as_rec_mut(), 1u16, 1 as u16);
22620 self.as_rec_mut().extend(value.to_ne_bytes());
22621 self
22622 }
22623}
22624impl<Prev: Rec> Drop for PushLinkinfoOvpnAttrs<Prev> {
22625 fn drop(&mut self) {
22626 if let Some(prev) = &mut self.prev {
22627 if let Some(header_offset) = &self.header_offset {
22628 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22629 }
22630 }
22631 }
22632}
22633#[doc = "Create a new link.\n\nRequest attributes:\n- [.push_address()](PushLinkAttrs::push_address)\n- [.push_broadcast()](PushLinkAttrs::push_broadcast)\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n- [.push_mtu()](PushLinkAttrs::push_mtu)\n- [.push_txqlen()](PushLinkAttrs::push_txqlen)\n- [.push_operstate()](PushLinkAttrs::push_operstate)\n- [.push_linkmode()](PushLinkAttrs::push_linkmode)\n- [.nested_linkinfo()](PushLinkAttrs::nested_linkinfo)\n- [.push_net_ns_pid()](PushLinkAttrs::push_net_ns_pid)\n- [.nested_af_spec()](PushLinkAttrs::nested_af_spec)\n- [.push_group()](PushLinkAttrs::push_group)\n- [.push_net_ns_fd()](PushLinkAttrs::push_net_ns_fd)\n- [.push_num_tx_queues()](PushLinkAttrs::push_num_tx_queues)\n- [.push_num_rx_queues()](PushLinkAttrs::push_num_rx_queues)\n- [.push_link_netnsid()](PushLinkAttrs::push_link_netnsid)\n- [.push_gso_max_segs()](PushLinkAttrs::push_gso_max_segs)\n- [.push_gso_max_size()](PushLinkAttrs::push_gso_max_size)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n- [.push_gro_max_size()](PushLinkAttrs::push_gro_max_size)\n- [.push_gso_ipv4_max_size()](PushLinkAttrs::push_gso_ipv4_max_size)\n- [.push_gro_ipv4_max_size()](PushLinkAttrs::push_gro_ipv4_max_size)\n\n"]
22634#[derive(Debug)]
22635pub struct OpNewlinkDo<'r> {
22636 request: Request<'r>,
22637}
22638impl<'r> OpNewlinkDo<'r> {
22639 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22640 Self::write_header(request.buf_mut(), header);
22641 Self { request: request }
22642 }
22643 pub fn encode_request<'buf>(
22644 buf: &'buf mut Vec<u8>,
22645 header: &Ifinfomsg,
22646 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22647 Self::write_header(buf, header);
22648 PushLinkAttrs::new(buf)
22649 }
22650 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22651 PushLinkAttrs::new(self.request.buf_mut())
22652 }
22653 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22654 PushLinkAttrs::new(self.request.buf)
22655 }
22656 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22657 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22658 (
22659 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22660 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22661 )
22662 }
22663 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22664 prev.as_rec_mut().extend(header.as_slice());
22665 }
22666}
22667impl NetlinkRequest for OpNewlinkDo<'_> {
22668 fn protocol(&self) -> Protocol {
22669 Protocol::Raw {
22670 protonum: 0u16,
22671 request_type: 16u16,
22672 }
22673 }
22674 fn flags(&self) -> u16 {
22675 self.request.flags
22676 }
22677 fn payload(&self) -> &[u8] {
22678 self.request.buf()
22679 }
22680 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22681 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22682 Self::decode_request(buf)
22683 }
22684 fn lookup(
22685 buf: &[u8],
22686 offset: usize,
22687 missing_type: Option<u16>,
22688 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22689 Self::decode_request(buf)
22690 .1
22691 .lookup_attr(offset, missing_type)
22692 }
22693}
22694#[doc = "Delete an existing link.\n\nRequest attributes:\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n\n"]
22695#[derive(Debug)]
22696pub struct OpDellinkDo<'r> {
22697 request: Request<'r>,
22698}
22699impl<'r> OpDellinkDo<'r> {
22700 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22701 Self::write_header(request.buf_mut(), header);
22702 Self { request: request }
22703 }
22704 pub fn encode_request<'buf>(
22705 buf: &'buf mut Vec<u8>,
22706 header: &Ifinfomsg,
22707 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22708 Self::write_header(buf, header);
22709 PushLinkAttrs::new(buf)
22710 }
22711 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22712 PushLinkAttrs::new(self.request.buf_mut())
22713 }
22714 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22715 PushLinkAttrs::new(self.request.buf)
22716 }
22717 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22718 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22719 (
22720 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22721 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22722 )
22723 }
22724 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22725 prev.as_rec_mut().extend(header.as_slice());
22726 }
22727}
22728impl NetlinkRequest for OpDellinkDo<'_> {
22729 fn protocol(&self) -> Protocol {
22730 Protocol::Raw {
22731 protonum: 0u16,
22732 request_type: 17u16,
22733 }
22734 }
22735 fn flags(&self) -> u16 {
22736 self.request.flags
22737 }
22738 fn payload(&self) -> &[u8] {
22739 self.request.buf()
22740 }
22741 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22742 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22743 Self::decode_request(buf)
22744 }
22745 fn lookup(
22746 buf: &[u8],
22747 offset: usize,
22748 missing_type: Option<u16>,
22749 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22750 Self::decode_request(buf)
22751 .1
22752 .lookup_attr(offset, missing_type)
22753 }
22754}
22755#[doc = "Get / dump information about a link.\n\nRequest attributes:\n- [.push_master()](PushLinkAttrs::push_master)\n- [.nested_linkinfo()](PushLinkAttrs::nested_linkinfo)\n- [.push_ext_mask()](PushLinkAttrs::push_ext_mask)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n\nReply attributes:\n- [.get_address()](IterableLinkAttrs::get_address)\n- [.get_broadcast()](IterableLinkAttrs::get_broadcast)\n- [.get_ifname()](IterableLinkAttrs::get_ifname)\n- [.get_mtu()](IterableLinkAttrs::get_mtu)\n- [.get_link()](IterableLinkAttrs::get_link)\n- [.get_qdisc()](IterableLinkAttrs::get_qdisc)\n- [.get_stats()](IterableLinkAttrs::get_stats)\n- [.get_master()](IterableLinkAttrs::get_master)\n- [.get_wireless()](IterableLinkAttrs::get_wireless)\n- [.get_protinfo()](IterableLinkAttrs::get_protinfo)\n- [.get_txqlen()](IterableLinkAttrs::get_txqlen)\n- [.get_map()](IterableLinkAttrs::get_map)\n- [.get_weight()](IterableLinkAttrs::get_weight)\n- [.get_operstate()](IterableLinkAttrs::get_operstate)\n- [.get_linkmode()](IterableLinkAttrs::get_linkmode)\n- [.get_linkinfo()](IterableLinkAttrs::get_linkinfo)\n- [.get_net_ns_pid()](IterableLinkAttrs::get_net_ns_pid)\n- [.get_ifalias()](IterableLinkAttrs::get_ifalias)\n- [.get_num_vf()](IterableLinkAttrs::get_num_vf)\n- [.get_vfinfo_list()](IterableLinkAttrs::get_vfinfo_list)\n- [.get_stats64()](IterableLinkAttrs::get_stats64)\n- [.get_vf_ports()](IterableLinkAttrs::get_vf_ports)\n- [.get_port_self()](IterableLinkAttrs::get_port_self)\n- [.get_af_spec()](IterableLinkAttrs::get_af_spec)\n- [.get_group()](IterableLinkAttrs::get_group)\n- [.get_net_ns_fd()](IterableLinkAttrs::get_net_ns_fd)\n- [.get_ext_mask()](IterableLinkAttrs::get_ext_mask)\n- [.get_promiscuity()](IterableLinkAttrs::get_promiscuity)\n- [.get_num_tx_queues()](IterableLinkAttrs::get_num_tx_queues)\n- [.get_num_rx_queues()](IterableLinkAttrs::get_num_rx_queues)\n- [.get_carrier()](IterableLinkAttrs::get_carrier)\n- [.get_phys_port_id()](IterableLinkAttrs::get_phys_port_id)\n- [.get_carrier_changes()](IterableLinkAttrs::get_carrier_changes)\n- [.get_phys_switch_id()](IterableLinkAttrs::get_phys_switch_id)\n- [.get_link_netnsid()](IterableLinkAttrs::get_link_netnsid)\n- [.get_phys_port_name()](IterableLinkAttrs::get_phys_port_name)\n- [.get_proto_down()](IterableLinkAttrs::get_proto_down)\n- [.get_gso_max_segs()](IterableLinkAttrs::get_gso_max_segs)\n- [.get_gso_max_size()](IterableLinkAttrs::get_gso_max_size)\n- [.get_xdp()](IterableLinkAttrs::get_xdp)\n- [.get_event()](IterableLinkAttrs::get_event)\n- [.get_new_netnsid()](IterableLinkAttrs::get_new_netnsid)\n- [.get_target_netnsid()](IterableLinkAttrs::get_target_netnsid)\n- [.get_carrier_up_count()](IterableLinkAttrs::get_carrier_up_count)\n- [.get_carrier_down_count()](IterableLinkAttrs::get_carrier_down_count)\n- [.get_new_ifindex()](IterableLinkAttrs::get_new_ifindex)\n- [.get_min_mtu()](IterableLinkAttrs::get_min_mtu)\n- [.get_max_mtu()](IterableLinkAttrs::get_max_mtu)\n- [.get_prop_list()](IterableLinkAttrs::get_prop_list)\n- [.get_perm_address()](IterableLinkAttrs::get_perm_address)\n- [.get_proto_down_reason()](IterableLinkAttrs::get_proto_down_reason)\n- [.get_parent_dev_name()](IterableLinkAttrs::get_parent_dev_name)\n- [.get_parent_dev_bus_name()](IterableLinkAttrs::get_parent_dev_bus_name)\n- [.get_gro_max_size()](IterableLinkAttrs::get_gro_max_size)\n- [.get_tso_max_size()](IterableLinkAttrs::get_tso_max_size)\n- [.get_tso_max_segs()](IterableLinkAttrs::get_tso_max_segs)\n- [.get_allmulti()](IterableLinkAttrs::get_allmulti)\n- [.get_devlink_port()](IterableLinkAttrs::get_devlink_port)\n- [.get_gso_ipv4_max_size()](IterableLinkAttrs::get_gso_ipv4_max_size)\n- [.get_gro_ipv4_max_size()](IterableLinkAttrs::get_gro_ipv4_max_size)\n\n"]
22756#[derive(Debug)]
22757pub struct OpGetlinkDump<'r> {
22758 request: Request<'r>,
22759}
22760impl<'r> OpGetlinkDump<'r> {
22761 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22762 Self::write_header(request.buf_mut(), header);
22763 Self {
22764 request: request.set_dump(),
22765 }
22766 }
22767 pub fn encode_request<'buf>(
22768 buf: &'buf mut Vec<u8>,
22769 header: &Ifinfomsg,
22770 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22771 Self::write_header(buf, header);
22772 PushLinkAttrs::new(buf)
22773 }
22774 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22775 PushLinkAttrs::new(self.request.buf_mut())
22776 }
22777 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22778 PushLinkAttrs::new(self.request.buf)
22779 }
22780 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22781 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22782 (
22783 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22784 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22785 )
22786 }
22787 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22788 prev.as_rec_mut().extend(header.as_slice());
22789 }
22790}
22791impl NetlinkRequest for OpGetlinkDump<'_> {
22792 fn protocol(&self) -> Protocol {
22793 Protocol::Raw {
22794 protonum: 0u16,
22795 request_type: 18u16,
22796 }
22797 }
22798 fn flags(&self) -> u16 {
22799 self.request.flags
22800 }
22801 fn payload(&self) -> &[u8] {
22802 self.request.buf()
22803 }
22804 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22805 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22806 Self::decode_request(buf)
22807 }
22808 fn lookup(
22809 buf: &[u8],
22810 offset: usize,
22811 missing_type: Option<u16>,
22812 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22813 Self::decode_request(buf)
22814 .1
22815 .lookup_attr(offset, missing_type)
22816 }
22817}
22818#[doc = "Get / dump information about a link.\n\nRequest attributes:\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n- [.push_ext_mask()](PushLinkAttrs::push_ext_mask)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n- [.push_alt_ifname()](PushLinkAttrs::push_alt_ifname)\n\nReply attributes:\n- [.get_address()](IterableLinkAttrs::get_address)\n- [.get_broadcast()](IterableLinkAttrs::get_broadcast)\n- [.get_ifname()](IterableLinkAttrs::get_ifname)\n- [.get_mtu()](IterableLinkAttrs::get_mtu)\n- [.get_link()](IterableLinkAttrs::get_link)\n- [.get_qdisc()](IterableLinkAttrs::get_qdisc)\n- [.get_stats()](IterableLinkAttrs::get_stats)\n- [.get_master()](IterableLinkAttrs::get_master)\n- [.get_wireless()](IterableLinkAttrs::get_wireless)\n- [.get_protinfo()](IterableLinkAttrs::get_protinfo)\n- [.get_txqlen()](IterableLinkAttrs::get_txqlen)\n- [.get_map()](IterableLinkAttrs::get_map)\n- [.get_weight()](IterableLinkAttrs::get_weight)\n- [.get_operstate()](IterableLinkAttrs::get_operstate)\n- [.get_linkmode()](IterableLinkAttrs::get_linkmode)\n- [.get_linkinfo()](IterableLinkAttrs::get_linkinfo)\n- [.get_net_ns_pid()](IterableLinkAttrs::get_net_ns_pid)\n- [.get_ifalias()](IterableLinkAttrs::get_ifalias)\n- [.get_num_vf()](IterableLinkAttrs::get_num_vf)\n- [.get_vfinfo_list()](IterableLinkAttrs::get_vfinfo_list)\n- [.get_stats64()](IterableLinkAttrs::get_stats64)\n- [.get_vf_ports()](IterableLinkAttrs::get_vf_ports)\n- [.get_port_self()](IterableLinkAttrs::get_port_self)\n- [.get_af_spec()](IterableLinkAttrs::get_af_spec)\n- [.get_group()](IterableLinkAttrs::get_group)\n- [.get_net_ns_fd()](IterableLinkAttrs::get_net_ns_fd)\n- [.get_ext_mask()](IterableLinkAttrs::get_ext_mask)\n- [.get_promiscuity()](IterableLinkAttrs::get_promiscuity)\n- [.get_num_tx_queues()](IterableLinkAttrs::get_num_tx_queues)\n- [.get_num_rx_queues()](IterableLinkAttrs::get_num_rx_queues)\n- [.get_carrier()](IterableLinkAttrs::get_carrier)\n- [.get_phys_port_id()](IterableLinkAttrs::get_phys_port_id)\n- [.get_carrier_changes()](IterableLinkAttrs::get_carrier_changes)\n- [.get_phys_switch_id()](IterableLinkAttrs::get_phys_switch_id)\n- [.get_link_netnsid()](IterableLinkAttrs::get_link_netnsid)\n- [.get_phys_port_name()](IterableLinkAttrs::get_phys_port_name)\n- [.get_proto_down()](IterableLinkAttrs::get_proto_down)\n- [.get_gso_max_segs()](IterableLinkAttrs::get_gso_max_segs)\n- [.get_gso_max_size()](IterableLinkAttrs::get_gso_max_size)\n- [.get_xdp()](IterableLinkAttrs::get_xdp)\n- [.get_event()](IterableLinkAttrs::get_event)\n- [.get_new_netnsid()](IterableLinkAttrs::get_new_netnsid)\n- [.get_target_netnsid()](IterableLinkAttrs::get_target_netnsid)\n- [.get_carrier_up_count()](IterableLinkAttrs::get_carrier_up_count)\n- [.get_carrier_down_count()](IterableLinkAttrs::get_carrier_down_count)\n- [.get_new_ifindex()](IterableLinkAttrs::get_new_ifindex)\n- [.get_min_mtu()](IterableLinkAttrs::get_min_mtu)\n- [.get_max_mtu()](IterableLinkAttrs::get_max_mtu)\n- [.get_prop_list()](IterableLinkAttrs::get_prop_list)\n- [.get_perm_address()](IterableLinkAttrs::get_perm_address)\n- [.get_proto_down_reason()](IterableLinkAttrs::get_proto_down_reason)\n- [.get_parent_dev_name()](IterableLinkAttrs::get_parent_dev_name)\n- [.get_parent_dev_bus_name()](IterableLinkAttrs::get_parent_dev_bus_name)\n- [.get_gro_max_size()](IterableLinkAttrs::get_gro_max_size)\n- [.get_tso_max_size()](IterableLinkAttrs::get_tso_max_size)\n- [.get_tso_max_segs()](IterableLinkAttrs::get_tso_max_segs)\n- [.get_allmulti()](IterableLinkAttrs::get_allmulti)\n- [.get_devlink_port()](IterableLinkAttrs::get_devlink_port)\n- [.get_gso_ipv4_max_size()](IterableLinkAttrs::get_gso_ipv4_max_size)\n- [.get_gro_ipv4_max_size()](IterableLinkAttrs::get_gro_ipv4_max_size)\n\n"]
22819#[derive(Debug)]
22820pub struct OpGetlinkDo<'r> {
22821 request: Request<'r>,
22822}
22823impl<'r> OpGetlinkDo<'r> {
22824 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22825 Self::write_header(request.buf_mut(), header);
22826 Self { request: request }
22827 }
22828 pub fn encode_request<'buf>(
22829 buf: &'buf mut Vec<u8>,
22830 header: &Ifinfomsg,
22831 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22832 Self::write_header(buf, header);
22833 PushLinkAttrs::new(buf)
22834 }
22835 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22836 PushLinkAttrs::new(self.request.buf_mut())
22837 }
22838 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22839 PushLinkAttrs::new(self.request.buf)
22840 }
22841 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22842 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22843 (
22844 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22845 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22846 )
22847 }
22848 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22849 prev.as_rec_mut().extend(header.as_slice());
22850 }
22851}
22852impl NetlinkRequest for OpGetlinkDo<'_> {
22853 fn protocol(&self) -> Protocol {
22854 Protocol::Raw {
22855 protonum: 0u16,
22856 request_type: 18u16,
22857 }
22858 }
22859 fn flags(&self) -> u16 {
22860 self.request.flags
22861 }
22862 fn payload(&self) -> &[u8] {
22863 self.request.buf()
22864 }
22865 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22866 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22867 Self::decode_request(buf)
22868 }
22869 fn lookup(
22870 buf: &[u8],
22871 offset: usize,
22872 missing_type: Option<u16>,
22873 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22874 Self::decode_request(buf)
22875 .1
22876 .lookup_attr(offset, missing_type)
22877 }
22878}
22879#[doc = "Set information about a link.\n\nRequest attributes:\n- [.push_address()](PushLinkAttrs::push_address)\n- [.push_broadcast()](PushLinkAttrs::push_broadcast)\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n- [.push_mtu()](PushLinkAttrs::push_mtu)\n- [.push_link()](PushLinkAttrs::push_link)\n- [.push_qdisc()](PushLinkAttrs::push_qdisc)\n- [.push_stats()](PushLinkAttrs::push_stats)\n- [.push_master()](PushLinkAttrs::push_master)\n- [.push_wireless()](PushLinkAttrs::push_wireless)\n- [.push_protinfo()](PushLinkAttrs::push_protinfo)\n- [.push_txqlen()](PushLinkAttrs::push_txqlen)\n- [.push_map()](PushLinkAttrs::push_map)\n- [.push_weight()](PushLinkAttrs::push_weight)\n- [.push_operstate()](PushLinkAttrs::push_operstate)\n- [.push_linkmode()](PushLinkAttrs::push_linkmode)\n- [.nested_linkinfo()](PushLinkAttrs::nested_linkinfo)\n- [.push_net_ns_pid()](PushLinkAttrs::push_net_ns_pid)\n- [.push_ifalias()](PushLinkAttrs::push_ifalias)\n- [.push_num_vf()](PushLinkAttrs::push_num_vf)\n- [.nested_vfinfo_list()](PushLinkAttrs::nested_vfinfo_list)\n- [.push_stats64()](PushLinkAttrs::push_stats64)\n- [.nested_vf_ports()](PushLinkAttrs::nested_vf_ports)\n- [.nested_port_self()](PushLinkAttrs::nested_port_self)\n- [.nested_af_spec()](PushLinkAttrs::nested_af_spec)\n- [.push_group()](PushLinkAttrs::push_group)\n- [.push_net_ns_fd()](PushLinkAttrs::push_net_ns_fd)\n- [.push_ext_mask()](PushLinkAttrs::push_ext_mask)\n- [.push_promiscuity()](PushLinkAttrs::push_promiscuity)\n- [.push_num_tx_queues()](PushLinkAttrs::push_num_tx_queues)\n- [.push_num_rx_queues()](PushLinkAttrs::push_num_rx_queues)\n- [.push_carrier()](PushLinkAttrs::push_carrier)\n- [.push_phys_port_id()](PushLinkAttrs::push_phys_port_id)\n- [.push_carrier_changes()](PushLinkAttrs::push_carrier_changes)\n- [.push_phys_switch_id()](PushLinkAttrs::push_phys_switch_id)\n- [.push_link_netnsid()](PushLinkAttrs::push_link_netnsid)\n- [.push_phys_port_name()](PushLinkAttrs::push_phys_port_name)\n- [.push_proto_down()](PushLinkAttrs::push_proto_down)\n- [.push_gso_max_segs()](PushLinkAttrs::push_gso_max_segs)\n- [.push_gso_max_size()](PushLinkAttrs::push_gso_max_size)\n- [.nested_xdp()](PushLinkAttrs::nested_xdp)\n- [.push_event()](PushLinkAttrs::push_event)\n- [.push_new_netnsid()](PushLinkAttrs::push_new_netnsid)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n- [.push_carrier_up_count()](PushLinkAttrs::push_carrier_up_count)\n- [.push_carrier_down_count()](PushLinkAttrs::push_carrier_down_count)\n- [.push_new_ifindex()](PushLinkAttrs::push_new_ifindex)\n- [.push_min_mtu()](PushLinkAttrs::push_min_mtu)\n- [.push_max_mtu()](PushLinkAttrs::push_max_mtu)\n- [.nested_prop_list()](PushLinkAttrs::nested_prop_list)\n- [.push_perm_address()](PushLinkAttrs::push_perm_address)\n- [.push_proto_down_reason()](PushLinkAttrs::push_proto_down_reason)\n- [.push_parent_dev_name()](PushLinkAttrs::push_parent_dev_name)\n- [.push_parent_dev_bus_name()](PushLinkAttrs::push_parent_dev_bus_name)\n- [.push_gro_max_size()](PushLinkAttrs::push_gro_max_size)\n- [.push_tso_max_size()](PushLinkAttrs::push_tso_max_size)\n- [.push_tso_max_segs()](PushLinkAttrs::push_tso_max_segs)\n- [.push_allmulti()](PushLinkAttrs::push_allmulti)\n- [.push_devlink_port()](PushLinkAttrs::push_devlink_port)\n- [.push_gso_ipv4_max_size()](PushLinkAttrs::push_gso_ipv4_max_size)\n- [.push_gro_ipv4_max_size()](PushLinkAttrs::push_gro_ipv4_max_size)\n\n"]
22880#[derive(Debug)]
22881pub struct OpSetlinkDo<'r> {
22882 request: Request<'r>,
22883}
22884impl<'r> OpSetlinkDo<'r> {
22885 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22886 Self::write_header(request.buf_mut(), header);
22887 Self { request: request }
22888 }
22889 pub fn encode_request<'buf>(
22890 buf: &'buf mut Vec<u8>,
22891 header: &Ifinfomsg,
22892 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22893 Self::write_header(buf, header);
22894 PushLinkAttrs::new(buf)
22895 }
22896 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22897 PushLinkAttrs::new(self.request.buf_mut())
22898 }
22899 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22900 PushLinkAttrs::new(self.request.buf)
22901 }
22902 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22903 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22904 (
22905 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22906 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22907 )
22908 }
22909 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22910 prev.as_rec_mut().extend(header.as_slice());
22911 }
22912}
22913impl NetlinkRequest for OpSetlinkDo<'_> {
22914 fn protocol(&self) -> Protocol {
22915 Protocol::Raw {
22916 protonum: 0u16,
22917 request_type: 19u16,
22918 }
22919 }
22920 fn flags(&self) -> u16 {
22921 self.request.flags
22922 }
22923 fn payload(&self) -> &[u8] {
22924 self.request.buf()
22925 }
22926 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22927 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22928 Self::decode_request(buf)
22929 }
22930 fn lookup(
22931 buf: &[u8],
22932 offset: usize,
22933 missing_type: Option<u16>,
22934 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22935 Self::decode_request(buf)
22936 .1
22937 .lookup_attr(offset, missing_type)
22938 }
22939}
22940#[doc = "Get / dump link stats.\n\nReply attributes:\n- [.get_link_64()](IterableStatsAttrs::get_link_64)\n- [.get_link_xstats()](IterableStatsAttrs::get_link_xstats)\n- [.get_link_xstats_slave()](IterableStatsAttrs::get_link_xstats_slave)\n- [.get_link_offload_xstats()](IterableStatsAttrs::get_link_offload_xstats)\n- [.get_af_spec()](IterableStatsAttrs::get_af_spec)\n\n"]
22941#[derive(Debug)]
22942pub struct OpGetstatsDump<'r> {
22943 request: Request<'r>,
22944}
22945impl<'r> OpGetstatsDump<'r> {
22946 pub fn new(mut request: Request<'r>, header: &IfStatsMsg) -> Self {
22947 Self::write_header(request.buf_mut(), header);
22948 Self {
22949 request: request.set_dump(),
22950 }
22951 }
22952 pub fn encode_request<'buf>(
22953 buf: &'buf mut Vec<u8>,
22954 header: &IfStatsMsg,
22955 ) -> PushStatsAttrs<&'buf mut Vec<u8>> {
22956 Self::write_header(buf, header);
22957 PushStatsAttrs::new(buf)
22958 }
22959 pub fn encode(&mut self) -> PushStatsAttrs<&mut Vec<u8>> {
22960 PushStatsAttrs::new(self.request.buf_mut())
22961 }
22962 pub fn into_encoder(self) -> PushStatsAttrs<RequestBuf<'r>> {
22963 PushStatsAttrs::new(self.request.buf)
22964 }
22965 pub fn decode_request<'a>(buf: &'a [u8]) -> (IfStatsMsg, IterableStatsAttrs<'a>) {
22966 let (header, attrs) = buf.split_at(buf.len().min(IfStatsMsg::len()));
22967 (
22968 IfStatsMsg::new_from_slice(header).unwrap_or_default(),
22969 IterableStatsAttrs::with_loc(attrs, buf.as_ptr() as usize),
22970 )
22971 }
22972 fn write_header<Prev: Rec>(prev: &mut Prev, header: &IfStatsMsg) {
22973 prev.as_rec_mut().extend(header.as_slice());
22974 }
22975}
22976impl NetlinkRequest for OpGetstatsDump<'_> {
22977 fn protocol(&self) -> Protocol {
22978 Protocol::Raw {
22979 protonum: 0u16,
22980 request_type: 94u16,
22981 }
22982 }
22983 fn flags(&self) -> u16 {
22984 self.request.flags
22985 }
22986 fn payload(&self) -> &[u8] {
22987 self.request.buf()
22988 }
22989 type ReplyType<'buf> = (IfStatsMsg, IterableStatsAttrs<'buf>);
22990 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22991 Self::decode_request(buf)
22992 }
22993 fn lookup(
22994 buf: &[u8],
22995 offset: usize,
22996 missing_type: Option<u16>,
22997 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22998 Self::decode_request(buf)
22999 .1
23000 .lookup_attr(offset, missing_type)
23001 }
23002}
23003#[doc = "Get / dump link stats.\n\nReply attributes:\n- [.get_link_64()](IterableStatsAttrs::get_link_64)\n- [.get_link_xstats()](IterableStatsAttrs::get_link_xstats)\n- [.get_link_xstats_slave()](IterableStatsAttrs::get_link_xstats_slave)\n- [.get_link_offload_xstats()](IterableStatsAttrs::get_link_offload_xstats)\n- [.get_af_spec()](IterableStatsAttrs::get_af_spec)\n\n"]
23004#[derive(Debug)]
23005pub struct OpGetstatsDo<'r> {
23006 request: Request<'r>,
23007}
23008impl<'r> OpGetstatsDo<'r> {
23009 pub fn new(mut request: Request<'r>, header: &IfStatsMsg) -> Self {
23010 Self::write_header(request.buf_mut(), header);
23011 Self { request: request }
23012 }
23013 pub fn encode_request<'buf>(
23014 buf: &'buf mut Vec<u8>,
23015 header: &IfStatsMsg,
23016 ) -> PushStatsAttrs<&'buf mut Vec<u8>> {
23017 Self::write_header(buf, header);
23018 PushStatsAttrs::new(buf)
23019 }
23020 pub fn encode(&mut self) -> PushStatsAttrs<&mut Vec<u8>> {
23021 PushStatsAttrs::new(self.request.buf_mut())
23022 }
23023 pub fn into_encoder(self) -> PushStatsAttrs<RequestBuf<'r>> {
23024 PushStatsAttrs::new(self.request.buf)
23025 }
23026 pub fn decode_request<'a>(buf: &'a [u8]) -> (IfStatsMsg, IterableStatsAttrs<'a>) {
23027 let (header, attrs) = buf.split_at(buf.len().min(IfStatsMsg::len()));
23028 (
23029 IfStatsMsg::new_from_slice(header).unwrap_or_default(),
23030 IterableStatsAttrs::with_loc(attrs, buf.as_ptr() as usize),
23031 )
23032 }
23033 fn write_header<Prev: Rec>(prev: &mut Prev, header: &IfStatsMsg) {
23034 prev.as_rec_mut().extend(header.as_slice());
23035 }
23036}
23037impl NetlinkRequest for OpGetstatsDo<'_> {
23038 fn protocol(&self) -> Protocol {
23039 Protocol::Raw {
23040 protonum: 0u16,
23041 request_type: 94u16,
23042 }
23043 }
23044 fn flags(&self) -> u16 {
23045 self.request.flags
23046 }
23047 fn payload(&self) -> &[u8] {
23048 self.request.buf()
23049 }
23050 type ReplyType<'buf> = (IfStatsMsg, IterableStatsAttrs<'buf>);
23051 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
23052 Self::decode_request(buf)
23053 }
23054 fn lookup(
23055 buf: &[u8],
23056 offset: usize,
23057 missing_type: Option<u16>,
23058 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
23059 Self::decode_request(buf)
23060 .1
23061 .lookup_attr(offset, missing_type)
23062 }
23063}
23064#[derive(Debug)]
23065pub struct ChainedFinal<'a> {
23066 inner: Chained<'a>,
23067}
23068#[derive(Debug)]
23069pub struct Chained<'a> {
23070 buf: RequestBuf<'a>,
23071 first_seq: u32,
23072 lookups: Vec<(&'static str, LookupFn)>,
23073 last_header_offset: usize,
23074 last_kind: Option<RequestInfo>,
23075}
23076impl<'a> ChainedFinal<'a> {
23077 pub fn into_chained(self) -> Chained<'a> {
23078 self.inner
23079 }
23080 pub fn buf(&self) -> &Vec<u8> {
23081 self.inner.buf()
23082 }
23083 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
23084 self.inner.buf_mut()
23085 }
23086 fn get_index(&self, seq: u32) -> Option<u32> {
23087 let min = self.inner.first_seq;
23088 let max = min.wrapping_add(self.inner.lookups.len() as u32);
23089 return if min <= max {
23090 (min..max).contains(&seq).then(|| seq - min)
23091 } else if min <= seq {
23092 Some(seq - min)
23093 } else if seq < max {
23094 Some(u32::MAX - min + seq)
23095 } else {
23096 None
23097 };
23098 }
23099}
23100impl crate::traits::NetlinkChained for ChainedFinal<'_> {
23101 fn protonum(&self) -> u16 {
23102 PROTONUM
23103 }
23104 fn payload(&self) -> &[u8] {
23105 self.buf()
23106 }
23107 fn chain_len(&self) -> usize {
23108 self.inner.lookups.len()
23109 }
23110 fn get_index(&self, seq: u32) -> Option<usize> {
23111 self.get_index(seq).map(|n| n as usize)
23112 }
23113 fn name(&self, index: usize) -> &'static str {
23114 self.inner.lookups[index].0
23115 }
23116 fn lookup(&self, index: usize) -> LookupFn {
23117 self.inner.lookups[index].1
23118 }
23119}
23120impl Chained<'static> {
23121 pub fn new(first_seq: u32) -> Self {
23122 Self::new_from_buf(Vec::new(), first_seq)
23123 }
23124 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
23125 Self {
23126 buf: RequestBuf::Own(buf),
23127 first_seq,
23128 lookups: Vec::new(),
23129 last_header_offset: 0,
23130 last_kind: None,
23131 }
23132 }
23133 pub fn into_buf(self) -> Vec<u8> {
23134 match self.buf {
23135 RequestBuf::Own(buf) => buf,
23136 _ => unreachable!(),
23137 }
23138 }
23139}
23140impl<'a> Chained<'a> {
23141 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
23142 Self {
23143 buf: RequestBuf::Ref(buf),
23144 first_seq,
23145 lookups: Vec::new(),
23146 last_header_offset: 0,
23147 last_kind: None,
23148 }
23149 }
23150 pub fn finalize(mut self) -> ChainedFinal<'a> {
23151 self.update_header();
23152 ChainedFinal { inner: self }
23153 }
23154 pub fn request(&mut self) -> Request<'_> {
23155 self.update_header();
23156 self.last_header_offset = self.buf().len();
23157 self.buf_mut().extend_from_slice(Nlmsghdr::new().as_slice());
23158 let mut request = Request::new_extend(self.buf.buf_mut());
23159 self.last_kind = None;
23160 request.writeback = Some(&mut self.last_kind);
23161 request
23162 }
23163 pub fn buf(&self) -> &Vec<u8> {
23164 self.buf.buf()
23165 }
23166 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
23167 self.buf.buf_mut()
23168 }
23169 fn update_header(&mut self) {
23170 let Some(RequestInfo {
23171 protocol,
23172 flags,
23173 name,
23174 lookup,
23175 }) = self.last_kind
23176 else {
23177 if !self.buf().is_empty() {
23178 assert_eq!(self.last_header_offset + Nlmsghdr::len(), self.buf().len());
23179 self.buf.buf_mut().truncate(self.last_header_offset);
23180 }
23181 return;
23182 };
23183 let header_offset = self.last_header_offset;
23184 let request_type = match protocol {
23185 Protocol::Raw { request_type, .. } => request_type,
23186 Protocol::Generic(_) => unreachable!(),
23187 };
23188 let index = self.lookups.len();
23189 let seq = self.first_seq.wrapping_add(index as u32);
23190 self.lookups.push((name, lookup));
23191 let buf = self.buf_mut();
23192 align(buf);
23193 let header = Nlmsghdr {
23194 len: (buf.len() - header_offset) as u32,
23195 r#type: request_type,
23196 flags: flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16,
23197 seq,
23198 pid: 0,
23199 };
23200 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
23201 }
23202}
23203use crate::traits::LookupFn;
23204use crate::utils::RequestBuf;
23205#[derive(Debug)]
23206pub struct Request<'buf> {
23207 buf: RequestBuf<'buf>,
23208 flags: u16,
23209 writeback: Option<&'buf mut Option<RequestInfo>>,
23210}
23211#[allow(unused)]
23212#[derive(Debug, Clone)]
23213pub struct RequestInfo {
23214 protocol: Protocol,
23215 flags: u16,
23216 name: &'static str,
23217 lookup: LookupFn,
23218}
23219impl Request<'static> {
23220 pub fn new() -> Self {
23221 Self::new_from_buf(Vec::new())
23222 }
23223 pub fn new_from_buf(buf: Vec<u8>) -> Self {
23224 Self {
23225 flags: 0,
23226 buf: RequestBuf::Own(buf),
23227 writeback: None,
23228 }
23229 }
23230 pub fn into_buf(self) -> Vec<u8> {
23231 match self.buf {
23232 RequestBuf::Own(buf) => buf,
23233 _ => unreachable!(),
23234 }
23235 }
23236}
23237impl<'buf> Request<'buf> {
23238 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
23239 buf.clear();
23240 Self::new_extend(buf)
23241 }
23242 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
23243 Self {
23244 flags: 0,
23245 buf: RequestBuf::Ref(buf),
23246 writeback: None,
23247 }
23248 }
23249 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
23250 let Some(writeback) = &mut self.writeback else {
23251 return;
23252 };
23253 **writeback = Some(RequestInfo {
23254 protocol,
23255 flags: self.flags,
23256 name,
23257 lookup,
23258 })
23259 }
23260 pub fn buf(&self) -> &Vec<u8> {
23261 self.buf.buf()
23262 }
23263 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
23264 self.buf.buf_mut()
23265 }
23266 #[doc = "Set `NLM_F_CREATE` flag"]
23267 pub fn set_create(mut self) -> Self {
23268 self.flags |= consts::NLM_F_CREATE as u16;
23269 self
23270 }
23271 #[doc = "Set `NLM_F_EXCL` flag"]
23272 pub fn set_excl(mut self) -> Self {
23273 self.flags |= consts::NLM_F_EXCL as u16;
23274 self
23275 }
23276 #[doc = "Set `NLM_F_REPLACE` flag"]
23277 pub fn set_replace(mut self) -> Self {
23278 self.flags |= consts::NLM_F_REPLACE as u16;
23279 self
23280 }
23281 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
23282 pub fn set_change(self) -> Self {
23283 self.set_create().set_replace()
23284 }
23285 #[doc = "Set `NLM_F_APPEND` flag"]
23286 pub fn set_append(mut self) -> Self {
23287 self.flags |= consts::NLM_F_APPEND as u16;
23288 self
23289 }
23290 #[doc = "Set `self.flags |= flags`"]
23291 pub fn set_flags(mut self, flags: u16) -> Self {
23292 self.flags |= flags;
23293 self
23294 }
23295 #[doc = "Set `self.flags ^= self.flags & flags`"]
23296 pub fn unset_flags(mut self, flags: u16) -> Self {
23297 self.flags ^= self.flags & flags;
23298 self
23299 }
23300 #[doc = "Set `NLM_F_DUMP` flag"]
23301 fn set_dump(mut self) -> Self {
23302 self.flags |= consts::NLM_F_DUMP as u16;
23303 self
23304 }
23305 #[doc = "Create a new link.\n\nRequest attributes:\n- [.push_address()](PushLinkAttrs::push_address)\n- [.push_broadcast()](PushLinkAttrs::push_broadcast)\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n- [.push_mtu()](PushLinkAttrs::push_mtu)\n- [.push_txqlen()](PushLinkAttrs::push_txqlen)\n- [.push_operstate()](PushLinkAttrs::push_operstate)\n- [.push_linkmode()](PushLinkAttrs::push_linkmode)\n- [.nested_linkinfo()](PushLinkAttrs::nested_linkinfo)\n- [.push_net_ns_pid()](PushLinkAttrs::push_net_ns_pid)\n- [.nested_af_spec()](PushLinkAttrs::nested_af_spec)\n- [.push_group()](PushLinkAttrs::push_group)\n- [.push_net_ns_fd()](PushLinkAttrs::push_net_ns_fd)\n- [.push_num_tx_queues()](PushLinkAttrs::push_num_tx_queues)\n- [.push_num_rx_queues()](PushLinkAttrs::push_num_rx_queues)\n- [.push_link_netnsid()](PushLinkAttrs::push_link_netnsid)\n- [.push_gso_max_segs()](PushLinkAttrs::push_gso_max_segs)\n- [.push_gso_max_size()](PushLinkAttrs::push_gso_max_size)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n- [.push_gro_max_size()](PushLinkAttrs::push_gro_max_size)\n- [.push_gso_ipv4_max_size()](PushLinkAttrs::push_gso_ipv4_max_size)\n- [.push_gro_ipv4_max_size()](PushLinkAttrs::push_gro_ipv4_max_size)\n\n"]
23306 pub fn op_newlink_do(self, header: &Ifinfomsg) -> OpNewlinkDo<'buf> {
23307 let mut res = OpNewlinkDo::new(self, header);
23308 res.request
23309 .do_writeback(res.protocol(), "op-newlink-do", OpNewlinkDo::lookup);
23310 res
23311 }
23312 #[doc = "Delete an existing link.\n\nRequest attributes:\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n\n"]
23313 pub fn op_dellink_do(self, header: &Ifinfomsg) -> OpDellinkDo<'buf> {
23314 let mut res = OpDellinkDo::new(self, header);
23315 res.request
23316 .do_writeback(res.protocol(), "op-dellink-do", OpDellinkDo::lookup);
23317 res
23318 }
23319 #[doc = "Get / dump information about a link.\n\nRequest attributes:\n- [.push_master()](PushLinkAttrs::push_master)\n- [.nested_linkinfo()](PushLinkAttrs::nested_linkinfo)\n- [.push_ext_mask()](PushLinkAttrs::push_ext_mask)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n\nReply attributes:\n- [.get_address()](IterableLinkAttrs::get_address)\n- [.get_broadcast()](IterableLinkAttrs::get_broadcast)\n- [.get_ifname()](IterableLinkAttrs::get_ifname)\n- [.get_mtu()](IterableLinkAttrs::get_mtu)\n- [.get_link()](IterableLinkAttrs::get_link)\n- [.get_qdisc()](IterableLinkAttrs::get_qdisc)\n- [.get_stats()](IterableLinkAttrs::get_stats)\n- [.get_master()](IterableLinkAttrs::get_master)\n- [.get_wireless()](IterableLinkAttrs::get_wireless)\n- [.get_protinfo()](IterableLinkAttrs::get_protinfo)\n- [.get_txqlen()](IterableLinkAttrs::get_txqlen)\n- [.get_map()](IterableLinkAttrs::get_map)\n- [.get_weight()](IterableLinkAttrs::get_weight)\n- [.get_operstate()](IterableLinkAttrs::get_operstate)\n- [.get_linkmode()](IterableLinkAttrs::get_linkmode)\n- [.get_linkinfo()](IterableLinkAttrs::get_linkinfo)\n- [.get_net_ns_pid()](IterableLinkAttrs::get_net_ns_pid)\n- [.get_ifalias()](IterableLinkAttrs::get_ifalias)\n- [.get_num_vf()](IterableLinkAttrs::get_num_vf)\n- [.get_vfinfo_list()](IterableLinkAttrs::get_vfinfo_list)\n- [.get_stats64()](IterableLinkAttrs::get_stats64)\n- [.get_vf_ports()](IterableLinkAttrs::get_vf_ports)\n- [.get_port_self()](IterableLinkAttrs::get_port_self)\n- [.get_af_spec()](IterableLinkAttrs::get_af_spec)\n- [.get_group()](IterableLinkAttrs::get_group)\n- [.get_net_ns_fd()](IterableLinkAttrs::get_net_ns_fd)\n- [.get_ext_mask()](IterableLinkAttrs::get_ext_mask)\n- [.get_promiscuity()](IterableLinkAttrs::get_promiscuity)\n- [.get_num_tx_queues()](IterableLinkAttrs::get_num_tx_queues)\n- [.get_num_rx_queues()](IterableLinkAttrs::get_num_rx_queues)\n- [.get_carrier()](IterableLinkAttrs::get_carrier)\n- [.get_phys_port_id()](IterableLinkAttrs::get_phys_port_id)\n- [.get_carrier_changes()](IterableLinkAttrs::get_carrier_changes)\n- [.get_phys_switch_id()](IterableLinkAttrs::get_phys_switch_id)\n- [.get_link_netnsid()](IterableLinkAttrs::get_link_netnsid)\n- [.get_phys_port_name()](IterableLinkAttrs::get_phys_port_name)\n- [.get_proto_down()](IterableLinkAttrs::get_proto_down)\n- [.get_gso_max_segs()](IterableLinkAttrs::get_gso_max_segs)\n- [.get_gso_max_size()](IterableLinkAttrs::get_gso_max_size)\n- [.get_xdp()](IterableLinkAttrs::get_xdp)\n- [.get_event()](IterableLinkAttrs::get_event)\n- [.get_new_netnsid()](IterableLinkAttrs::get_new_netnsid)\n- [.get_target_netnsid()](IterableLinkAttrs::get_target_netnsid)\n- [.get_carrier_up_count()](IterableLinkAttrs::get_carrier_up_count)\n- [.get_carrier_down_count()](IterableLinkAttrs::get_carrier_down_count)\n- [.get_new_ifindex()](IterableLinkAttrs::get_new_ifindex)\n- [.get_min_mtu()](IterableLinkAttrs::get_min_mtu)\n- [.get_max_mtu()](IterableLinkAttrs::get_max_mtu)\n- [.get_prop_list()](IterableLinkAttrs::get_prop_list)\n- [.get_perm_address()](IterableLinkAttrs::get_perm_address)\n- [.get_proto_down_reason()](IterableLinkAttrs::get_proto_down_reason)\n- [.get_parent_dev_name()](IterableLinkAttrs::get_parent_dev_name)\n- [.get_parent_dev_bus_name()](IterableLinkAttrs::get_parent_dev_bus_name)\n- [.get_gro_max_size()](IterableLinkAttrs::get_gro_max_size)\n- [.get_tso_max_size()](IterableLinkAttrs::get_tso_max_size)\n- [.get_tso_max_segs()](IterableLinkAttrs::get_tso_max_segs)\n- [.get_allmulti()](IterableLinkAttrs::get_allmulti)\n- [.get_devlink_port()](IterableLinkAttrs::get_devlink_port)\n- [.get_gso_ipv4_max_size()](IterableLinkAttrs::get_gso_ipv4_max_size)\n- [.get_gro_ipv4_max_size()](IterableLinkAttrs::get_gro_ipv4_max_size)\n\n"]
23320 pub fn op_getlink_dump(self, header: &Ifinfomsg) -> OpGetlinkDump<'buf> {
23321 let mut res = OpGetlinkDump::new(self, header);
23322 res.request
23323 .do_writeback(res.protocol(), "op-getlink-dump", OpGetlinkDump::lookup);
23324 res
23325 }
23326 #[doc = "Get / dump information about a link.\n\nRequest attributes:\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n- [.push_ext_mask()](PushLinkAttrs::push_ext_mask)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n- [.push_alt_ifname()](PushLinkAttrs::push_alt_ifname)\n\nReply attributes:\n- [.get_address()](IterableLinkAttrs::get_address)\n- [.get_broadcast()](IterableLinkAttrs::get_broadcast)\n- [.get_ifname()](IterableLinkAttrs::get_ifname)\n- [.get_mtu()](IterableLinkAttrs::get_mtu)\n- [.get_link()](IterableLinkAttrs::get_link)\n- [.get_qdisc()](IterableLinkAttrs::get_qdisc)\n- [.get_stats()](IterableLinkAttrs::get_stats)\n- [.get_master()](IterableLinkAttrs::get_master)\n- [.get_wireless()](IterableLinkAttrs::get_wireless)\n- [.get_protinfo()](IterableLinkAttrs::get_protinfo)\n- [.get_txqlen()](IterableLinkAttrs::get_txqlen)\n- [.get_map()](IterableLinkAttrs::get_map)\n- [.get_weight()](IterableLinkAttrs::get_weight)\n- [.get_operstate()](IterableLinkAttrs::get_operstate)\n- [.get_linkmode()](IterableLinkAttrs::get_linkmode)\n- [.get_linkinfo()](IterableLinkAttrs::get_linkinfo)\n- [.get_net_ns_pid()](IterableLinkAttrs::get_net_ns_pid)\n- [.get_ifalias()](IterableLinkAttrs::get_ifalias)\n- [.get_num_vf()](IterableLinkAttrs::get_num_vf)\n- [.get_vfinfo_list()](IterableLinkAttrs::get_vfinfo_list)\n- [.get_stats64()](IterableLinkAttrs::get_stats64)\n- [.get_vf_ports()](IterableLinkAttrs::get_vf_ports)\n- [.get_port_self()](IterableLinkAttrs::get_port_self)\n- [.get_af_spec()](IterableLinkAttrs::get_af_spec)\n- [.get_group()](IterableLinkAttrs::get_group)\n- [.get_net_ns_fd()](IterableLinkAttrs::get_net_ns_fd)\n- [.get_ext_mask()](IterableLinkAttrs::get_ext_mask)\n- [.get_promiscuity()](IterableLinkAttrs::get_promiscuity)\n- [.get_num_tx_queues()](IterableLinkAttrs::get_num_tx_queues)\n- [.get_num_rx_queues()](IterableLinkAttrs::get_num_rx_queues)\n- [.get_carrier()](IterableLinkAttrs::get_carrier)\n- [.get_phys_port_id()](IterableLinkAttrs::get_phys_port_id)\n- [.get_carrier_changes()](IterableLinkAttrs::get_carrier_changes)\n- [.get_phys_switch_id()](IterableLinkAttrs::get_phys_switch_id)\n- [.get_link_netnsid()](IterableLinkAttrs::get_link_netnsid)\n- [.get_phys_port_name()](IterableLinkAttrs::get_phys_port_name)\n- [.get_proto_down()](IterableLinkAttrs::get_proto_down)\n- [.get_gso_max_segs()](IterableLinkAttrs::get_gso_max_segs)\n- [.get_gso_max_size()](IterableLinkAttrs::get_gso_max_size)\n- [.get_xdp()](IterableLinkAttrs::get_xdp)\n- [.get_event()](IterableLinkAttrs::get_event)\n- [.get_new_netnsid()](IterableLinkAttrs::get_new_netnsid)\n- [.get_target_netnsid()](IterableLinkAttrs::get_target_netnsid)\n- [.get_carrier_up_count()](IterableLinkAttrs::get_carrier_up_count)\n- [.get_carrier_down_count()](IterableLinkAttrs::get_carrier_down_count)\n- [.get_new_ifindex()](IterableLinkAttrs::get_new_ifindex)\n- [.get_min_mtu()](IterableLinkAttrs::get_min_mtu)\n- [.get_max_mtu()](IterableLinkAttrs::get_max_mtu)\n- [.get_prop_list()](IterableLinkAttrs::get_prop_list)\n- [.get_perm_address()](IterableLinkAttrs::get_perm_address)\n- [.get_proto_down_reason()](IterableLinkAttrs::get_proto_down_reason)\n- [.get_parent_dev_name()](IterableLinkAttrs::get_parent_dev_name)\n- [.get_parent_dev_bus_name()](IterableLinkAttrs::get_parent_dev_bus_name)\n- [.get_gro_max_size()](IterableLinkAttrs::get_gro_max_size)\n- [.get_tso_max_size()](IterableLinkAttrs::get_tso_max_size)\n- [.get_tso_max_segs()](IterableLinkAttrs::get_tso_max_segs)\n- [.get_allmulti()](IterableLinkAttrs::get_allmulti)\n- [.get_devlink_port()](IterableLinkAttrs::get_devlink_port)\n- [.get_gso_ipv4_max_size()](IterableLinkAttrs::get_gso_ipv4_max_size)\n- [.get_gro_ipv4_max_size()](IterableLinkAttrs::get_gro_ipv4_max_size)\n\n"]
23327 pub fn op_getlink_do(self, header: &Ifinfomsg) -> OpGetlinkDo<'buf> {
23328 let mut res = OpGetlinkDo::new(self, header);
23329 res.request
23330 .do_writeback(res.protocol(), "op-getlink-do", OpGetlinkDo::lookup);
23331 res
23332 }
23333 #[doc = "Set information about a link.\n\nRequest attributes:\n- [.push_address()](PushLinkAttrs::push_address)\n- [.push_broadcast()](PushLinkAttrs::push_broadcast)\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n- [.push_mtu()](PushLinkAttrs::push_mtu)\n- [.push_link()](PushLinkAttrs::push_link)\n- [.push_qdisc()](PushLinkAttrs::push_qdisc)\n- [.push_stats()](PushLinkAttrs::push_stats)\n- [.push_master()](PushLinkAttrs::push_master)\n- [.push_wireless()](PushLinkAttrs::push_wireless)\n- [.push_protinfo()](PushLinkAttrs::push_protinfo)\n- [.push_txqlen()](PushLinkAttrs::push_txqlen)\n- [.push_map()](PushLinkAttrs::push_map)\n- [.push_weight()](PushLinkAttrs::push_weight)\n- [.push_operstate()](PushLinkAttrs::push_operstate)\n- [.push_linkmode()](PushLinkAttrs::push_linkmode)\n- [.nested_linkinfo()](PushLinkAttrs::nested_linkinfo)\n- [.push_net_ns_pid()](PushLinkAttrs::push_net_ns_pid)\n- [.push_ifalias()](PushLinkAttrs::push_ifalias)\n- [.push_num_vf()](PushLinkAttrs::push_num_vf)\n- [.nested_vfinfo_list()](PushLinkAttrs::nested_vfinfo_list)\n- [.push_stats64()](PushLinkAttrs::push_stats64)\n- [.nested_vf_ports()](PushLinkAttrs::nested_vf_ports)\n- [.nested_port_self()](PushLinkAttrs::nested_port_self)\n- [.nested_af_spec()](PushLinkAttrs::nested_af_spec)\n- [.push_group()](PushLinkAttrs::push_group)\n- [.push_net_ns_fd()](PushLinkAttrs::push_net_ns_fd)\n- [.push_ext_mask()](PushLinkAttrs::push_ext_mask)\n- [.push_promiscuity()](PushLinkAttrs::push_promiscuity)\n- [.push_num_tx_queues()](PushLinkAttrs::push_num_tx_queues)\n- [.push_num_rx_queues()](PushLinkAttrs::push_num_rx_queues)\n- [.push_carrier()](PushLinkAttrs::push_carrier)\n- [.push_phys_port_id()](PushLinkAttrs::push_phys_port_id)\n- [.push_carrier_changes()](PushLinkAttrs::push_carrier_changes)\n- [.push_phys_switch_id()](PushLinkAttrs::push_phys_switch_id)\n- [.push_link_netnsid()](PushLinkAttrs::push_link_netnsid)\n- [.push_phys_port_name()](PushLinkAttrs::push_phys_port_name)\n- [.push_proto_down()](PushLinkAttrs::push_proto_down)\n- [.push_gso_max_segs()](PushLinkAttrs::push_gso_max_segs)\n- [.push_gso_max_size()](PushLinkAttrs::push_gso_max_size)\n- [.nested_xdp()](PushLinkAttrs::nested_xdp)\n- [.push_event()](PushLinkAttrs::push_event)\n- [.push_new_netnsid()](PushLinkAttrs::push_new_netnsid)\n- [.push_target_netnsid()](PushLinkAttrs::push_target_netnsid)\n- [.push_carrier_up_count()](PushLinkAttrs::push_carrier_up_count)\n- [.push_carrier_down_count()](PushLinkAttrs::push_carrier_down_count)\n- [.push_new_ifindex()](PushLinkAttrs::push_new_ifindex)\n- [.push_min_mtu()](PushLinkAttrs::push_min_mtu)\n- [.push_max_mtu()](PushLinkAttrs::push_max_mtu)\n- [.nested_prop_list()](PushLinkAttrs::nested_prop_list)\n- [.push_perm_address()](PushLinkAttrs::push_perm_address)\n- [.push_proto_down_reason()](PushLinkAttrs::push_proto_down_reason)\n- [.push_parent_dev_name()](PushLinkAttrs::push_parent_dev_name)\n- [.push_parent_dev_bus_name()](PushLinkAttrs::push_parent_dev_bus_name)\n- [.push_gro_max_size()](PushLinkAttrs::push_gro_max_size)\n- [.push_tso_max_size()](PushLinkAttrs::push_tso_max_size)\n- [.push_tso_max_segs()](PushLinkAttrs::push_tso_max_segs)\n- [.push_allmulti()](PushLinkAttrs::push_allmulti)\n- [.push_devlink_port()](PushLinkAttrs::push_devlink_port)\n- [.push_gso_ipv4_max_size()](PushLinkAttrs::push_gso_ipv4_max_size)\n- [.push_gro_ipv4_max_size()](PushLinkAttrs::push_gro_ipv4_max_size)\n\n"]
23334 pub fn op_setlink_do(self, header: &Ifinfomsg) -> OpSetlinkDo<'buf> {
23335 let mut res = OpSetlinkDo::new(self, header);
23336 res.request
23337 .do_writeback(res.protocol(), "op-setlink-do", OpSetlinkDo::lookup);
23338 res
23339 }
23340 #[doc = "Get / dump link stats.\n\nReply attributes:\n- [.get_link_64()](IterableStatsAttrs::get_link_64)\n- [.get_link_xstats()](IterableStatsAttrs::get_link_xstats)\n- [.get_link_xstats_slave()](IterableStatsAttrs::get_link_xstats_slave)\n- [.get_link_offload_xstats()](IterableStatsAttrs::get_link_offload_xstats)\n- [.get_af_spec()](IterableStatsAttrs::get_af_spec)\n\n"]
23341 pub fn op_getstats_dump(self, header: &IfStatsMsg) -> OpGetstatsDump<'buf> {
23342 let mut res = OpGetstatsDump::new(self, header);
23343 res.request
23344 .do_writeback(res.protocol(), "op-getstats-dump", OpGetstatsDump::lookup);
23345 res
23346 }
23347 #[doc = "Get / dump link stats.\n\nReply attributes:\n- [.get_link_64()](IterableStatsAttrs::get_link_64)\n- [.get_link_xstats()](IterableStatsAttrs::get_link_xstats)\n- [.get_link_xstats_slave()](IterableStatsAttrs::get_link_xstats_slave)\n- [.get_link_offload_xstats()](IterableStatsAttrs::get_link_offload_xstats)\n- [.get_af_spec()](IterableStatsAttrs::get_af_spec)\n\n"]
23348 pub fn op_getstats_do(self, header: &IfStatsMsg) -> OpGetstatsDo<'buf> {
23349 let mut res = OpGetstatsDo::new(self, header);
23350 res.request
23351 .do_writeback(res.protocol(), "op-getstats-do", OpGetstatsDo::lookup);
23352 res
23353 }
23354}
23355#[cfg(test)]
23356mod generated_tests {
23357 use super::*;
23358 #[test]
23359 fn tests() {
23360 let _ = IterableLinkAttrs::get_address;
23361 let _ = IterableLinkAttrs::get_af_spec;
23362 let _ = IterableLinkAttrs::get_allmulti;
23363 let _ = IterableLinkAttrs::get_broadcast;
23364 let _ = IterableLinkAttrs::get_carrier;
23365 let _ = IterableLinkAttrs::get_carrier_changes;
23366 let _ = IterableLinkAttrs::get_carrier_down_count;
23367 let _ = IterableLinkAttrs::get_carrier_up_count;
23368 let _ = IterableLinkAttrs::get_devlink_port;
23369 let _ = IterableLinkAttrs::get_event;
23370 let _ = IterableLinkAttrs::get_ext_mask;
23371 let _ = IterableLinkAttrs::get_gro_ipv4_max_size;
23372 let _ = IterableLinkAttrs::get_gro_max_size;
23373 let _ = IterableLinkAttrs::get_group;
23374 let _ = IterableLinkAttrs::get_gso_ipv4_max_size;
23375 let _ = IterableLinkAttrs::get_gso_max_segs;
23376 let _ = IterableLinkAttrs::get_gso_max_size;
23377 let _ = IterableLinkAttrs::get_ifalias;
23378 let _ = IterableLinkAttrs::get_ifname;
23379 let _ = IterableLinkAttrs::get_link;
23380 let _ = IterableLinkAttrs::get_link_netnsid;
23381 let _ = IterableLinkAttrs::get_linkinfo;
23382 let _ = IterableLinkAttrs::get_linkmode;
23383 let _ = IterableLinkAttrs::get_map;
23384 let _ = IterableLinkAttrs::get_master;
23385 let _ = IterableLinkAttrs::get_max_mtu;
23386 let _ = IterableLinkAttrs::get_min_mtu;
23387 let _ = IterableLinkAttrs::get_mtu;
23388 let _ = IterableLinkAttrs::get_net_ns_fd;
23389 let _ = IterableLinkAttrs::get_net_ns_pid;
23390 let _ = IterableLinkAttrs::get_new_ifindex;
23391 let _ = IterableLinkAttrs::get_new_netnsid;
23392 let _ = IterableLinkAttrs::get_num_rx_queues;
23393 let _ = IterableLinkAttrs::get_num_tx_queues;
23394 let _ = IterableLinkAttrs::get_num_vf;
23395 let _ = IterableLinkAttrs::get_operstate;
23396 let _ = IterableLinkAttrs::get_parent_dev_bus_name;
23397 let _ = IterableLinkAttrs::get_parent_dev_name;
23398 let _ = IterableLinkAttrs::get_perm_address;
23399 let _ = IterableLinkAttrs::get_phys_port_id;
23400 let _ = IterableLinkAttrs::get_phys_port_name;
23401 let _ = IterableLinkAttrs::get_phys_switch_id;
23402 let _ = IterableLinkAttrs::get_port_self;
23403 let _ = IterableLinkAttrs::get_promiscuity;
23404 let _ = IterableLinkAttrs::get_prop_list;
23405 let _ = IterableLinkAttrs::get_protinfo;
23406 let _ = IterableLinkAttrs::get_proto_down;
23407 let _ = IterableLinkAttrs::get_proto_down_reason;
23408 let _ = IterableLinkAttrs::get_qdisc;
23409 let _ = IterableLinkAttrs::get_stats64;
23410 let _ = IterableLinkAttrs::get_stats;
23411 let _ = IterableLinkAttrs::get_target_netnsid;
23412 let _ = IterableLinkAttrs::get_tso_max_segs;
23413 let _ = IterableLinkAttrs::get_tso_max_size;
23414 let _ = IterableLinkAttrs::get_txqlen;
23415 let _ = IterableLinkAttrs::get_vf_ports;
23416 let _ = IterableLinkAttrs::get_vfinfo_list;
23417 let _ = IterableLinkAttrs::get_weight;
23418 let _ = IterableLinkAttrs::get_wireless;
23419 let _ = IterableLinkAttrs::get_xdp;
23420 let _ = IterableStatsAttrs::get_af_spec;
23421 let _ = IterableStatsAttrs::get_link_64;
23422 let _ = IterableStatsAttrs::get_link_offload_xstats;
23423 let _ = IterableStatsAttrs::get_link_xstats;
23424 let _ = IterableStatsAttrs::get_link_xstats_slave;
23425 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_af_spec;
23426 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_linkinfo;
23427 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_port_self;
23428 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_prop_list;
23429 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_vf_ports;
23430 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_vfinfo_list;
23431 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_xdp;
23432 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_address;
23433 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_allmulti;
23434 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_alt_ifname;
23435 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_broadcast;
23436 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier;
23437 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier_changes;
23438 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier_down_count;
23439 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier_up_count;
23440 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_devlink_port;
23441 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_event;
23442 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_ext_mask;
23443 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gro_ipv4_max_size;
23444 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gro_max_size;
23445 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_group;
23446 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gso_ipv4_max_size;
23447 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gso_max_segs;
23448 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gso_max_size;
23449 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_ifalias;
23450 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_ifname;
23451 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_link;
23452 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_link_netnsid;
23453 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_linkmode;
23454 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_map;
23455 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_master;
23456 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_max_mtu;
23457 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_min_mtu;
23458 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_mtu;
23459 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_net_ns_fd;
23460 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_net_ns_pid;
23461 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_new_ifindex;
23462 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_new_netnsid;
23463 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_num_rx_queues;
23464 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_num_tx_queues;
23465 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_num_vf;
23466 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_operstate;
23467 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_parent_dev_bus_name;
23468 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_parent_dev_name;
23469 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_perm_address;
23470 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_phys_port_id;
23471 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_phys_port_name;
23472 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_phys_switch_id;
23473 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_promiscuity;
23474 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_protinfo;
23475 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_proto_down;
23476 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_proto_down_reason;
23477 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_qdisc;
23478 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_stats64;
23479 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_stats;
23480 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_target_netnsid;
23481 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_tso_max_segs;
23482 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_tso_max_size;
23483 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_txqlen;
23484 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_weight;
23485 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_wireless;
23486 }
23487}