1#![doc = "Link configuration over rtnetlink\\."]
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 OvpnMode {
510 P2p = 0,
511 Mp = 1,
512}
513impl OvpnMode {
514 pub fn from_value(value: u64) -> Option<Self> {
515 Some(match value {
516 0 => Self::P2p,
517 1 => Self::Mp,
518 _ => return None,
519 })
520 }
521}
522#[derive(Debug)]
523#[repr(C, packed(4))]
524pub struct Rtgenmsg {
525 pub family: u8,
526}
527impl Clone for Rtgenmsg {
528 fn clone(&self) -> Self {
529 Self::new_from_array(*self.as_array())
530 }
531}
532#[doc = "Create zero-initialized struct"]
533impl Default for Rtgenmsg {
534 fn default() -> Self {
535 Self::new()
536 }
537}
538impl Rtgenmsg {
539 #[doc = "Create zero-initialized struct"]
540 pub fn new() -> Self {
541 Self::new_from_array([0u8; Self::len()])
542 }
543 #[doc = "Copy from contents from slice"]
544 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
545 if other.len() != Self::len() {
546 return None;
547 }
548 let mut buf = [0u8; Self::len()];
549 buf.clone_from_slice(other);
550 Some(Self::new_from_array(buf))
551 }
552 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
553 pub fn new_from_zeroed(other: &[u8]) -> Self {
554 let mut buf = [0u8; Self::len()];
555 let len = buf.len().min(other.len());
556 buf[..len].clone_from_slice(&other[..len]);
557 Self::new_from_array(buf)
558 }
559 pub fn new_from_array(buf: [u8; 1usize]) -> Self {
560 unsafe { std::mem::transmute(buf) }
561 }
562 pub fn as_slice(&self) -> &[u8] {
563 unsafe {
564 let ptr: *const u8 = std::mem::transmute(self as *const Self);
565 std::slice::from_raw_parts(ptr, Self::len())
566 }
567 }
568 pub fn from_slice(buf: &[u8]) -> &Self {
569 assert!(buf.len() >= Self::len());
570 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
571 unsafe { std::mem::transmute(buf.as_ptr()) }
572 }
573 pub fn as_array(&self) -> &[u8; 1usize] {
574 unsafe { std::mem::transmute(self) }
575 }
576 pub fn from_array(buf: &[u8; 1usize]) -> &Self {
577 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
578 unsafe { std::mem::transmute(buf) }
579 }
580 pub fn into_array(self) -> [u8; 1usize] {
581 unsafe { std::mem::transmute(self) }
582 }
583 pub const fn len() -> usize {
584 const _: () = assert!(std::mem::size_of::<Rtgenmsg>() == 1usize);
585 1usize
586 }
587}
588#[repr(C, packed(4))]
589pub struct Ifinfomsg {
590 pub ifi_family: u8,
591 pub _pad: [u8; 1usize],
592 pub ifi_type: u16,
593 pub ifi_index: i32,
594 #[doc = "Associated type: [`IfinfoFlags`] (1 bit per enumeration)"]
595 pub ifi_flags: u32,
596 pub ifi_change: u32,
597}
598impl Clone for Ifinfomsg {
599 fn clone(&self) -> Self {
600 Self::new_from_array(*self.as_array())
601 }
602}
603#[doc = "Create zero-initialized struct"]
604impl Default for Ifinfomsg {
605 fn default() -> Self {
606 Self::new()
607 }
608}
609impl Ifinfomsg {
610 #[doc = "Create zero-initialized struct"]
611 pub fn new() -> Self {
612 Self::new_from_array([0u8; Self::len()])
613 }
614 #[doc = "Copy from contents from slice"]
615 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
616 if other.len() != Self::len() {
617 return None;
618 }
619 let mut buf = [0u8; Self::len()];
620 buf.clone_from_slice(other);
621 Some(Self::new_from_array(buf))
622 }
623 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
624 pub fn new_from_zeroed(other: &[u8]) -> Self {
625 let mut buf = [0u8; Self::len()];
626 let len = buf.len().min(other.len());
627 buf[..len].clone_from_slice(&other[..len]);
628 Self::new_from_array(buf)
629 }
630 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
631 unsafe { std::mem::transmute(buf) }
632 }
633 pub fn as_slice(&self) -> &[u8] {
634 unsafe {
635 let ptr: *const u8 = std::mem::transmute(self as *const Self);
636 std::slice::from_raw_parts(ptr, Self::len())
637 }
638 }
639 pub fn from_slice(buf: &[u8]) -> &Self {
640 assert!(buf.len() >= Self::len());
641 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
642 unsafe { std::mem::transmute(buf.as_ptr()) }
643 }
644 pub fn as_array(&self) -> &[u8; 16usize] {
645 unsafe { std::mem::transmute(self) }
646 }
647 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
648 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
649 unsafe { std::mem::transmute(buf) }
650 }
651 pub fn into_array(self) -> [u8; 16usize] {
652 unsafe { std::mem::transmute(self) }
653 }
654 pub const fn len() -> usize {
655 const _: () = assert!(std::mem::size_of::<Ifinfomsg>() == 16usize);
656 16usize
657 }
658}
659impl std::fmt::Debug for Ifinfomsg {
660 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
661 fmt.debug_struct("Ifinfomsg")
662 .field("ifi_family", &self.ifi_family)
663 .field("ifi_type", &self.ifi_type)
664 .field("ifi_index", &self.ifi_index)
665 .field(
666 "ifi_flags",
667 &FormatFlags(self.ifi_flags.into(), IfinfoFlags::from_value),
668 )
669 .field("ifi_change", &self.ifi_change)
670 .finish()
671 }
672}
673#[derive(Debug)]
674#[repr(C, packed(4))]
675pub struct IflaBridgeId {
676 pub prio: u16,
677 pub addr: [u8; 6usize],
678}
679impl Clone for IflaBridgeId {
680 fn clone(&self) -> Self {
681 Self::new_from_array(*self.as_array())
682 }
683}
684#[doc = "Create zero-initialized struct"]
685impl Default for IflaBridgeId {
686 fn default() -> Self {
687 Self::new()
688 }
689}
690impl IflaBridgeId {
691 #[doc = "Create zero-initialized struct"]
692 pub fn new() -> Self {
693 Self::new_from_array([0u8; Self::len()])
694 }
695 #[doc = "Copy from contents from slice"]
696 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
697 if other.len() != Self::len() {
698 return None;
699 }
700 let mut buf = [0u8; Self::len()];
701 buf.clone_from_slice(other);
702 Some(Self::new_from_array(buf))
703 }
704 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
705 pub fn new_from_zeroed(other: &[u8]) -> Self {
706 let mut buf = [0u8; Self::len()];
707 let len = buf.len().min(other.len());
708 buf[..len].clone_from_slice(&other[..len]);
709 Self::new_from_array(buf)
710 }
711 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
712 unsafe { std::mem::transmute(buf) }
713 }
714 pub fn as_slice(&self) -> &[u8] {
715 unsafe {
716 let ptr: *const u8 = std::mem::transmute(self as *const Self);
717 std::slice::from_raw_parts(ptr, Self::len())
718 }
719 }
720 pub fn from_slice(buf: &[u8]) -> &Self {
721 assert!(buf.len() >= Self::len());
722 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
723 unsafe { std::mem::transmute(buf.as_ptr()) }
724 }
725 pub fn as_array(&self) -> &[u8; 8usize] {
726 unsafe { std::mem::transmute(self) }
727 }
728 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
729 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
730 unsafe { std::mem::transmute(buf) }
731 }
732 pub fn into_array(self) -> [u8; 8usize] {
733 unsafe { std::mem::transmute(self) }
734 }
735 pub const fn len() -> usize {
736 const _: () = assert!(std::mem::size_of::<IflaBridgeId>() == 8usize);
737 8usize
738 }
739}
740#[derive(Debug)]
741#[repr(C, packed(4))]
742pub struct IflaCacheinfo {
743 pub max_reasm_len: u32,
744 pub tstamp: u32,
745 pub reachable_time: i32,
746 pub retrans_time: u32,
747}
748impl Clone for IflaCacheinfo {
749 fn clone(&self) -> Self {
750 Self::new_from_array(*self.as_array())
751 }
752}
753#[doc = "Create zero-initialized struct"]
754impl Default for IflaCacheinfo {
755 fn default() -> Self {
756 Self::new()
757 }
758}
759impl IflaCacheinfo {
760 #[doc = "Create zero-initialized struct"]
761 pub fn new() -> Self {
762 Self::new_from_array([0u8; Self::len()])
763 }
764 #[doc = "Copy from contents from slice"]
765 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
766 if other.len() != Self::len() {
767 return None;
768 }
769 let mut buf = [0u8; Self::len()];
770 buf.clone_from_slice(other);
771 Some(Self::new_from_array(buf))
772 }
773 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
774 pub fn new_from_zeroed(other: &[u8]) -> Self {
775 let mut buf = [0u8; Self::len()];
776 let len = buf.len().min(other.len());
777 buf[..len].clone_from_slice(&other[..len]);
778 Self::new_from_array(buf)
779 }
780 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
781 unsafe { std::mem::transmute(buf) }
782 }
783 pub fn as_slice(&self) -> &[u8] {
784 unsafe {
785 let ptr: *const u8 = std::mem::transmute(self as *const Self);
786 std::slice::from_raw_parts(ptr, Self::len())
787 }
788 }
789 pub fn from_slice(buf: &[u8]) -> &Self {
790 assert!(buf.len() >= Self::len());
791 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
792 unsafe { std::mem::transmute(buf.as_ptr()) }
793 }
794 pub fn as_array(&self) -> &[u8; 16usize] {
795 unsafe { std::mem::transmute(self) }
796 }
797 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
798 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
799 unsafe { std::mem::transmute(buf) }
800 }
801 pub fn into_array(self) -> [u8; 16usize] {
802 unsafe { std::mem::transmute(self) }
803 }
804 pub const fn len() -> usize {
805 const _: () = assert!(std::mem::size_of::<IflaCacheinfo>() == 16usize);
806 16usize
807 }
808}
809#[derive(Debug)]
810#[repr(C, packed(4))]
811pub struct RtnlLinkStats {
812 pub rx_packets: u32,
813 pub tx_packets: u32,
814 pub rx_bytes: u32,
815 pub tx_bytes: u32,
816 pub rx_errors: u32,
817 pub tx_errors: u32,
818 pub rx_dropped: u32,
819 pub tx_dropped: u32,
820 pub multicast: u32,
821 pub collisions: u32,
822 pub rx_length_errors: u32,
823 pub rx_over_errors: u32,
824 pub rx_crc_errors: u32,
825 pub rx_frame_errors: u32,
826 pub rx_fifo_errors: u32,
827 pub rx_missed_errors: u32,
828 pub tx_aborted_errors: u32,
829 pub tx_carrier_errors: u32,
830 pub tx_fifo_errors: u32,
831 pub tx_heartbeat_errors: u32,
832 pub tx_window_errors: u32,
833 pub rx_compressed: u32,
834 pub tx_compressed: u32,
835 pub rx_nohandler: u32,
836}
837impl Clone for RtnlLinkStats {
838 fn clone(&self) -> Self {
839 Self::new_from_array(*self.as_array())
840 }
841}
842#[doc = "Create zero-initialized struct"]
843impl Default for RtnlLinkStats {
844 fn default() -> Self {
845 Self::new()
846 }
847}
848impl RtnlLinkStats {
849 #[doc = "Create zero-initialized struct"]
850 pub fn new() -> Self {
851 Self::new_from_array([0u8; Self::len()])
852 }
853 #[doc = "Copy from contents from slice"]
854 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
855 if other.len() != Self::len() {
856 return None;
857 }
858 let mut buf = [0u8; Self::len()];
859 buf.clone_from_slice(other);
860 Some(Self::new_from_array(buf))
861 }
862 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
863 pub fn new_from_zeroed(other: &[u8]) -> Self {
864 let mut buf = [0u8; Self::len()];
865 let len = buf.len().min(other.len());
866 buf[..len].clone_from_slice(&other[..len]);
867 Self::new_from_array(buf)
868 }
869 pub fn new_from_array(buf: [u8; 96usize]) -> Self {
870 unsafe { std::mem::transmute(buf) }
871 }
872 pub fn as_slice(&self) -> &[u8] {
873 unsafe {
874 let ptr: *const u8 = std::mem::transmute(self as *const Self);
875 std::slice::from_raw_parts(ptr, Self::len())
876 }
877 }
878 pub fn from_slice(buf: &[u8]) -> &Self {
879 assert!(buf.len() >= Self::len());
880 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
881 unsafe { std::mem::transmute(buf.as_ptr()) }
882 }
883 pub fn as_array(&self) -> &[u8; 96usize] {
884 unsafe { std::mem::transmute(self) }
885 }
886 pub fn from_array(buf: &[u8; 96usize]) -> &Self {
887 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
888 unsafe { std::mem::transmute(buf) }
889 }
890 pub fn into_array(self) -> [u8; 96usize] {
891 unsafe { std::mem::transmute(self) }
892 }
893 pub const fn len() -> usize {
894 const _: () = assert!(std::mem::size_of::<RtnlLinkStats>() == 96usize);
895 96usize
896 }
897}
898#[repr(C, packed(4))]
899pub struct RtnlLinkStats64 {
900 pub rx_packets: u64,
901 pub tx_packets: u64,
902 pub rx_bytes: u64,
903 pub tx_bytes: u64,
904 pub rx_errors: u64,
905 pub tx_errors: u64,
906 pub rx_dropped: u64,
907 pub tx_dropped: u64,
908 pub multicast: u64,
909 pub collisions: u64,
910 pub rx_length_errors: u64,
911 pub rx_over_errors: u64,
912 pub rx_crc_errors: u64,
913 pub rx_frame_errors: u64,
914 pub rx_fifo_errors: u64,
915 pub rx_missed_errors: u64,
916 pub tx_aborted_errors: u64,
917 pub tx_carrier_errors: u64,
918 pub tx_fifo_errors: u64,
919 pub tx_heartbeat_errors: u64,
920 pub tx_window_errors: u64,
921 pub rx_compressed: u64,
922 pub tx_compressed: u64,
923 pub rx_nohandler: u64,
924 pub rx_otherhost_dropped: u64,
925}
926impl Clone for RtnlLinkStats64 {
927 fn clone(&self) -> Self {
928 Self::new_from_array(*self.as_array())
929 }
930}
931#[doc = "Create zero-initialized struct"]
932impl Default for RtnlLinkStats64 {
933 fn default() -> Self {
934 Self::new()
935 }
936}
937impl RtnlLinkStats64 {
938 #[doc = "Create zero-initialized struct"]
939 pub fn new() -> Self {
940 Self::new_from_array([0u8; Self::len()])
941 }
942 #[doc = "Copy from contents from slice"]
943 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
944 if other.len() != Self::len() {
945 return None;
946 }
947 let mut buf = [0u8; Self::len()];
948 buf.clone_from_slice(other);
949 Some(Self::new_from_array(buf))
950 }
951 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
952 pub fn new_from_zeroed(other: &[u8]) -> Self {
953 let mut buf = [0u8; Self::len()];
954 let len = buf.len().min(other.len());
955 buf[..len].clone_from_slice(&other[..len]);
956 Self::new_from_array(buf)
957 }
958 pub fn new_from_array(buf: [u8; 200usize]) -> Self {
959 unsafe { std::mem::transmute(buf) }
960 }
961 pub fn as_slice(&self) -> &[u8] {
962 unsafe {
963 let ptr: *const u8 = std::mem::transmute(self as *const Self);
964 std::slice::from_raw_parts(ptr, Self::len())
965 }
966 }
967 pub fn from_slice(buf: &[u8]) -> &Self {
968 assert!(buf.len() >= Self::len());
969 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
970 unsafe { std::mem::transmute(buf.as_ptr()) }
971 }
972 pub fn as_array(&self) -> &[u8; 200usize] {
973 unsafe { std::mem::transmute(self) }
974 }
975 pub fn from_array(buf: &[u8; 200usize]) -> &Self {
976 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
977 unsafe { std::mem::transmute(buf) }
978 }
979 pub fn into_array(self) -> [u8; 200usize] {
980 unsafe { std::mem::transmute(self) }
981 }
982 pub const fn len() -> usize {
983 const _: () = assert!(std::mem::size_of::<RtnlLinkStats64>() == 200usize);
984 200usize
985 }
986}
987impl std::fmt::Debug for RtnlLinkStats64 {
988 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
989 fmt.debug_struct("RtnlLinkStats64")
990 .field("rx_packets", &{ self.rx_packets })
991 .field("tx_packets", &{ self.tx_packets })
992 .field("rx_bytes", &{ self.rx_bytes })
993 .field("tx_bytes", &{ self.tx_bytes })
994 .field("rx_errors", &{ self.rx_errors })
995 .field("tx_errors", &{ self.tx_errors })
996 .field("rx_dropped", &{ self.rx_dropped })
997 .field("tx_dropped", &{ self.tx_dropped })
998 .field("multicast", &{ self.multicast })
999 .field("collisions", &{ self.collisions })
1000 .field("rx_length_errors", &{ self.rx_length_errors })
1001 .field("rx_over_errors", &{ self.rx_over_errors })
1002 .field("rx_crc_errors", &{ self.rx_crc_errors })
1003 .field("rx_frame_errors", &{ self.rx_frame_errors })
1004 .field("rx_fifo_errors", &{ self.rx_fifo_errors })
1005 .field("rx_missed_errors", &{ self.rx_missed_errors })
1006 .field("tx_aborted_errors", &{ self.tx_aborted_errors })
1007 .field("tx_carrier_errors", &{ self.tx_carrier_errors })
1008 .field("tx_fifo_errors", &{ self.tx_fifo_errors })
1009 .field("tx_heartbeat_errors", &{ self.tx_heartbeat_errors })
1010 .field("tx_window_errors", &{ self.tx_window_errors })
1011 .field("rx_compressed", &{ self.rx_compressed })
1012 .field("tx_compressed", &{ self.tx_compressed })
1013 .field("rx_nohandler", &{ self.rx_nohandler })
1014 .field("rx_otherhost_dropped", &{ self.rx_otherhost_dropped })
1015 .finish()
1016 }
1017}
1018#[repr(C, packed(4))]
1019pub struct RtnlLinkIfmap {
1020 pub mem_start: u64,
1021 pub mem_end: u64,
1022 pub base_addr: u64,
1023 pub irq: u16,
1024 pub dma: u8,
1025 pub port: u8,
1026 pub _pad_28: [u8; 4usize],
1027}
1028impl Clone for RtnlLinkIfmap {
1029 fn clone(&self) -> Self {
1030 Self::new_from_array(*self.as_array())
1031 }
1032}
1033#[doc = "Create zero-initialized struct"]
1034impl Default for RtnlLinkIfmap {
1035 fn default() -> Self {
1036 Self::new()
1037 }
1038}
1039impl RtnlLinkIfmap {
1040 #[doc = "Create zero-initialized struct"]
1041 pub fn new() -> Self {
1042 Self::new_from_array([0u8; Self::len()])
1043 }
1044 #[doc = "Copy from contents from slice"]
1045 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1046 if other.len() != Self::len() {
1047 return None;
1048 }
1049 let mut buf = [0u8; Self::len()];
1050 buf.clone_from_slice(other);
1051 Some(Self::new_from_array(buf))
1052 }
1053 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1054 pub fn new_from_zeroed(other: &[u8]) -> Self {
1055 let mut buf = [0u8; Self::len()];
1056 let len = buf.len().min(other.len());
1057 buf[..len].clone_from_slice(&other[..len]);
1058 Self::new_from_array(buf)
1059 }
1060 pub fn new_from_array(buf: [u8; 32usize]) -> Self {
1061 unsafe { std::mem::transmute(buf) }
1062 }
1063 pub fn as_slice(&self) -> &[u8] {
1064 unsafe {
1065 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1066 std::slice::from_raw_parts(ptr, Self::len())
1067 }
1068 }
1069 pub fn from_slice(buf: &[u8]) -> &Self {
1070 assert!(buf.len() >= Self::len());
1071 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1072 unsafe { std::mem::transmute(buf.as_ptr()) }
1073 }
1074 pub fn as_array(&self) -> &[u8; 32usize] {
1075 unsafe { std::mem::transmute(self) }
1076 }
1077 pub fn from_array(buf: &[u8; 32usize]) -> &Self {
1078 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1079 unsafe { std::mem::transmute(buf) }
1080 }
1081 pub fn into_array(self) -> [u8; 32usize] {
1082 unsafe { std::mem::transmute(self) }
1083 }
1084 pub const fn len() -> usize {
1085 const _: () = assert!(std::mem::size_of::<RtnlLinkIfmap>() == 32usize);
1086 32usize
1087 }
1088}
1089impl std::fmt::Debug for RtnlLinkIfmap {
1090 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1091 fmt.debug_struct("RtnlLinkIfmap")
1092 .field("mem_start", &{ self.mem_start })
1093 .field("mem_end", &{ self.mem_end })
1094 .field("base_addr", &{ self.base_addr })
1095 .field("irq", &self.irq)
1096 .field("dma", &self.dma)
1097 .field("port", &self.port)
1098 .finish()
1099 }
1100}
1101#[derive(Debug)]
1102#[repr(C, packed(4))]
1103pub struct BrBooloptMulti {
1104 pub optval: u32,
1105 pub optmask: u32,
1106}
1107impl Clone for BrBooloptMulti {
1108 fn clone(&self) -> Self {
1109 Self::new_from_array(*self.as_array())
1110 }
1111}
1112#[doc = "Create zero-initialized struct"]
1113impl Default for BrBooloptMulti {
1114 fn default() -> Self {
1115 Self::new()
1116 }
1117}
1118impl BrBooloptMulti {
1119 #[doc = "Create zero-initialized struct"]
1120 pub fn new() -> Self {
1121 Self::new_from_array([0u8; Self::len()])
1122 }
1123 #[doc = "Copy from contents from slice"]
1124 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1125 if other.len() != Self::len() {
1126 return None;
1127 }
1128 let mut buf = [0u8; Self::len()];
1129 buf.clone_from_slice(other);
1130 Some(Self::new_from_array(buf))
1131 }
1132 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1133 pub fn new_from_zeroed(other: &[u8]) -> Self {
1134 let mut buf = [0u8; Self::len()];
1135 let len = buf.len().min(other.len());
1136 buf[..len].clone_from_slice(&other[..len]);
1137 Self::new_from_array(buf)
1138 }
1139 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1140 unsafe { std::mem::transmute(buf) }
1141 }
1142 pub fn as_slice(&self) -> &[u8] {
1143 unsafe {
1144 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1145 std::slice::from_raw_parts(ptr, Self::len())
1146 }
1147 }
1148 pub fn from_slice(buf: &[u8]) -> &Self {
1149 assert!(buf.len() >= Self::len());
1150 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1151 unsafe { std::mem::transmute(buf.as_ptr()) }
1152 }
1153 pub fn as_array(&self) -> &[u8; 8usize] {
1154 unsafe { std::mem::transmute(self) }
1155 }
1156 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1157 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1158 unsafe { std::mem::transmute(buf) }
1159 }
1160 pub fn into_array(self) -> [u8; 8usize] {
1161 unsafe { std::mem::transmute(self) }
1162 }
1163 pub const fn len() -> usize {
1164 const _: () = assert!(std::mem::size_of::<BrBooloptMulti>() == 8usize);
1165 8usize
1166 }
1167}
1168#[repr(C, packed(4))]
1169pub struct IfStatsMsg {
1170 pub family: u8,
1171 pub _pad: [u8; 3usize],
1172 pub ifindex: u32,
1173 pub filter_mask: u32,
1174}
1175impl Clone for IfStatsMsg {
1176 fn clone(&self) -> Self {
1177 Self::new_from_array(*self.as_array())
1178 }
1179}
1180#[doc = "Create zero-initialized struct"]
1181impl Default for IfStatsMsg {
1182 fn default() -> Self {
1183 Self::new()
1184 }
1185}
1186impl IfStatsMsg {
1187 #[doc = "Create zero-initialized struct"]
1188 pub fn new() -> Self {
1189 Self::new_from_array([0u8; Self::len()])
1190 }
1191 #[doc = "Copy from contents from slice"]
1192 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1193 if other.len() != Self::len() {
1194 return None;
1195 }
1196 let mut buf = [0u8; Self::len()];
1197 buf.clone_from_slice(other);
1198 Some(Self::new_from_array(buf))
1199 }
1200 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1201 pub fn new_from_zeroed(other: &[u8]) -> Self {
1202 let mut buf = [0u8; Self::len()];
1203 let len = buf.len().min(other.len());
1204 buf[..len].clone_from_slice(&other[..len]);
1205 Self::new_from_array(buf)
1206 }
1207 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1208 unsafe { std::mem::transmute(buf) }
1209 }
1210 pub fn as_slice(&self) -> &[u8] {
1211 unsafe {
1212 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1213 std::slice::from_raw_parts(ptr, Self::len())
1214 }
1215 }
1216 pub fn from_slice(buf: &[u8]) -> &Self {
1217 assert!(buf.len() >= Self::len());
1218 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1219 unsafe { std::mem::transmute(buf.as_ptr()) }
1220 }
1221 pub fn as_array(&self) -> &[u8; 12usize] {
1222 unsafe { std::mem::transmute(self) }
1223 }
1224 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1225 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1226 unsafe { std::mem::transmute(buf) }
1227 }
1228 pub fn into_array(self) -> [u8; 12usize] {
1229 unsafe { std::mem::transmute(self) }
1230 }
1231 pub const fn len() -> usize {
1232 const _: () = assert!(std::mem::size_of::<IfStatsMsg>() == 12usize);
1233 12usize
1234 }
1235}
1236impl std::fmt::Debug for IfStatsMsg {
1237 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1238 fmt.debug_struct("IfStatsMsg")
1239 .field("family", &self.family)
1240 .field("ifindex", &self.ifindex)
1241 .field("filter_mask", &self.filter_mask)
1242 .finish()
1243 }
1244}
1245#[repr(C, packed(4))]
1246pub struct IflaVlanFlags {
1247 #[doc = "Associated type: [`VlanFlags`] (1 bit per enumeration)"]
1248 pub flags: u32,
1249 pub mask: u32,
1250}
1251impl Clone for IflaVlanFlags {
1252 fn clone(&self) -> Self {
1253 Self::new_from_array(*self.as_array())
1254 }
1255}
1256#[doc = "Create zero-initialized struct"]
1257impl Default for IflaVlanFlags {
1258 fn default() -> Self {
1259 Self::new()
1260 }
1261}
1262impl IflaVlanFlags {
1263 #[doc = "Create zero-initialized struct"]
1264 pub fn new() -> Self {
1265 Self::new_from_array([0u8; Self::len()])
1266 }
1267 #[doc = "Copy from contents from slice"]
1268 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1269 if other.len() != Self::len() {
1270 return None;
1271 }
1272 let mut buf = [0u8; Self::len()];
1273 buf.clone_from_slice(other);
1274 Some(Self::new_from_array(buf))
1275 }
1276 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1277 pub fn new_from_zeroed(other: &[u8]) -> Self {
1278 let mut buf = [0u8; Self::len()];
1279 let len = buf.len().min(other.len());
1280 buf[..len].clone_from_slice(&other[..len]);
1281 Self::new_from_array(buf)
1282 }
1283 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1284 unsafe { std::mem::transmute(buf) }
1285 }
1286 pub fn as_slice(&self) -> &[u8] {
1287 unsafe {
1288 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1289 std::slice::from_raw_parts(ptr, Self::len())
1290 }
1291 }
1292 pub fn from_slice(buf: &[u8]) -> &Self {
1293 assert!(buf.len() >= Self::len());
1294 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1295 unsafe { std::mem::transmute(buf.as_ptr()) }
1296 }
1297 pub fn as_array(&self) -> &[u8; 8usize] {
1298 unsafe { std::mem::transmute(self) }
1299 }
1300 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1301 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1302 unsafe { std::mem::transmute(buf) }
1303 }
1304 pub fn into_array(self) -> [u8; 8usize] {
1305 unsafe { std::mem::transmute(self) }
1306 }
1307 pub const fn len() -> usize {
1308 const _: () = assert!(std::mem::size_of::<IflaVlanFlags>() == 8usize);
1309 8usize
1310 }
1311}
1312impl std::fmt::Debug for IflaVlanFlags {
1313 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1314 fmt.debug_struct("IflaVlanFlags")
1315 .field(
1316 "flags",
1317 &FormatFlags(self.flags.into(), VlanFlags::from_value),
1318 )
1319 .field("mask", &FormatHex(self.mask.to_ne_bytes()))
1320 .finish()
1321 }
1322}
1323#[derive(Debug)]
1324#[repr(C, packed(4))]
1325pub struct IflaVlanQosMapping {
1326 pub from: u32,
1327 pub to: u32,
1328}
1329impl Clone for IflaVlanQosMapping {
1330 fn clone(&self) -> Self {
1331 Self::new_from_array(*self.as_array())
1332 }
1333}
1334#[doc = "Create zero-initialized struct"]
1335impl Default for IflaVlanQosMapping {
1336 fn default() -> Self {
1337 Self::new()
1338 }
1339}
1340impl IflaVlanQosMapping {
1341 #[doc = "Create zero-initialized struct"]
1342 pub fn new() -> Self {
1343 Self::new_from_array([0u8; Self::len()])
1344 }
1345 #[doc = "Copy from contents from slice"]
1346 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1347 if other.len() != Self::len() {
1348 return None;
1349 }
1350 let mut buf = [0u8; Self::len()];
1351 buf.clone_from_slice(other);
1352 Some(Self::new_from_array(buf))
1353 }
1354 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1355 pub fn new_from_zeroed(other: &[u8]) -> Self {
1356 let mut buf = [0u8; Self::len()];
1357 let len = buf.len().min(other.len());
1358 buf[..len].clone_from_slice(&other[..len]);
1359 Self::new_from_array(buf)
1360 }
1361 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1362 unsafe { std::mem::transmute(buf) }
1363 }
1364 pub fn as_slice(&self) -> &[u8] {
1365 unsafe {
1366 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1367 std::slice::from_raw_parts(ptr, Self::len())
1368 }
1369 }
1370 pub fn from_slice(buf: &[u8]) -> &Self {
1371 assert!(buf.len() >= Self::len());
1372 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1373 unsafe { std::mem::transmute(buf.as_ptr()) }
1374 }
1375 pub fn as_array(&self) -> &[u8; 8usize] {
1376 unsafe { std::mem::transmute(self) }
1377 }
1378 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1379 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1380 unsafe { std::mem::transmute(buf) }
1381 }
1382 pub fn into_array(self) -> [u8; 8usize] {
1383 unsafe { std::mem::transmute(self) }
1384 }
1385 pub const fn len() -> usize {
1386 const _: () = assert!(std::mem::size_of::<IflaVlanQosMapping>() == 8usize);
1387 8usize
1388 }
1389}
1390#[repr(C, packed(4))]
1391pub struct IflaGenevePortRange {
1392 pub _low_be: u16,
1393 pub _high_be: u16,
1394}
1395impl Clone for IflaGenevePortRange {
1396 fn clone(&self) -> Self {
1397 Self::new_from_array(*self.as_array())
1398 }
1399}
1400#[doc = "Create zero-initialized struct"]
1401impl Default for IflaGenevePortRange {
1402 fn default() -> Self {
1403 Self::new()
1404 }
1405}
1406impl IflaGenevePortRange {
1407 #[doc = "Create zero-initialized struct"]
1408 pub fn new() -> Self {
1409 Self::new_from_array([0u8; Self::len()])
1410 }
1411 #[doc = "Copy from contents from slice"]
1412 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1413 if other.len() != Self::len() {
1414 return None;
1415 }
1416 let mut buf = [0u8; Self::len()];
1417 buf.clone_from_slice(other);
1418 Some(Self::new_from_array(buf))
1419 }
1420 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1421 pub fn new_from_zeroed(other: &[u8]) -> Self {
1422 let mut buf = [0u8; Self::len()];
1423 let len = buf.len().min(other.len());
1424 buf[..len].clone_from_slice(&other[..len]);
1425 Self::new_from_array(buf)
1426 }
1427 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
1428 unsafe { std::mem::transmute(buf) }
1429 }
1430 pub fn as_slice(&self) -> &[u8] {
1431 unsafe {
1432 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1433 std::slice::from_raw_parts(ptr, Self::len())
1434 }
1435 }
1436 pub fn from_slice(buf: &[u8]) -> &Self {
1437 assert!(buf.len() >= Self::len());
1438 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1439 unsafe { std::mem::transmute(buf.as_ptr()) }
1440 }
1441 pub fn as_array(&self) -> &[u8; 4usize] {
1442 unsafe { std::mem::transmute(self) }
1443 }
1444 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
1445 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1446 unsafe { std::mem::transmute(buf) }
1447 }
1448 pub fn into_array(self) -> [u8; 4usize] {
1449 unsafe { std::mem::transmute(self) }
1450 }
1451 pub const fn len() -> usize {
1452 const _: () = assert!(std::mem::size_of::<IflaGenevePortRange>() == 4usize);
1453 4usize
1454 }
1455 pub fn low(&self) -> u16 {
1456 u16::from_be(self._low_be)
1457 }
1458 pub fn set_low(&mut self, value: u16) {
1459 self._low_be = value.to_be();
1460 }
1461 pub fn high(&self) -> u16 {
1462 u16::from_be(self._high_be)
1463 }
1464 pub fn set_high(&mut self, value: u16) {
1465 self._high_be = value.to_be();
1466 }
1467}
1468impl std::fmt::Debug for IflaGenevePortRange {
1469 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1470 fmt.debug_struct("IflaGenevePortRange")
1471 .field("low", &self.low())
1472 .field("high", &self.high())
1473 .finish()
1474 }
1475}
1476#[derive(Debug)]
1477#[repr(C, packed(4))]
1478pub struct IflaVfMac {
1479 pub vf: u32,
1480 pub mac: [u8; 32usize],
1481}
1482impl Clone for IflaVfMac {
1483 fn clone(&self) -> Self {
1484 Self::new_from_array(*self.as_array())
1485 }
1486}
1487#[doc = "Create zero-initialized struct"]
1488impl Default for IflaVfMac {
1489 fn default() -> Self {
1490 Self::new()
1491 }
1492}
1493impl IflaVfMac {
1494 #[doc = "Create zero-initialized struct"]
1495 pub fn new() -> Self {
1496 Self::new_from_array([0u8; Self::len()])
1497 }
1498 #[doc = "Copy from contents from slice"]
1499 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1500 if other.len() != Self::len() {
1501 return None;
1502 }
1503 let mut buf = [0u8; Self::len()];
1504 buf.clone_from_slice(other);
1505 Some(Self::new_from_array(buf))
1506 }
1507 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1508 pub fn new_from_zeroed(other: &[u8]) -> Self {
1509 let mut buf = [0u8; Self::len()];
1510 let len = buf.len().min(other.len());
1511 buf[..len].clone_from_slice(&other[..len]);
1512 Self::new_from_array(buf)
1513 }
1514 pub fn new_from_array(buf: [u8; 36usize]) -> Self {
1515 unsafe { std::mem::transmute(buf) }
1516 }
1517 pub fn as_slice(&self) -> &[u8] {
1518 unsafe {
1519 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1520 std::slice::from_raw_parts(ptr, Self::len())
1521 }
1522 }
1523 pub fn from_slice(buf: &[u8]) -> &Self {
1524 assert!(buf.len() >= Self::len());
1525 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1526 unsafe { std::mem::transmute(buf.as_ptr()) }
1527 }
1528 pub fn as_array(&self) -> &[u8; 36usize] {
1529 unsafe { std::mem::transmute(self) }
1530 }
1531 pub fn from_array(buf: &[u8; 36usize]) -> &Self {
1532 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1533 unsafe { std::mem::transmute(buf) }
1534 }
1535 pub fn into_array(self) -> [u8; 36usize] {
1536 unsafe { std::mem::transmute(self) }
1537 }
1538 pub const fn len() -> usize {
1539 const _: () = assert!(std::mem::size_of::<IflaVfMac>() == 36usize);
1540 36usize
1541 }
1542}
1543#[derive(Debug)]
1544#[repr(C, packed(4))]
1545pub struct IflaVfVlan {
1546 pub vf: u32,
1547 pub vlan: u32,
1548 pub qos: u32,
1549}
1550impl Clone for IflaVfVlan {
1551 fn clone(&self) -> Self {
1552 Self::new_from_array(*self.as_array())
1553 }
1554}
1555#[doc = "Create zero-initialized struct"]
1556impl Default for IflaVfVlan {
1557 fn default() -> Self {
1558 Self::new()
1559 }
1560}
1561impl IflaVfVlan {
1562 #[doc = "Create zero-initialized struct"]
1563 pub fn new() -> Self {
1564 Self::new_from_array([0u8; Self::len()])
1565 }
1566 #[doc = "Copy from contents from slice"]
1567 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1568 if other.len() != Self::len() {
1569 return None;
1570 }
1571 let mut buf = [0u8; Self::len()];
1572 buf.clone_from_slice(other);
1573 Some(Self::new_from_array(buf))
1574 }
1575 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1576 pub fn new_from_zeroed(other: &[u8]) -> Self {
1577 let mut buf = [0u8; Self::len()];
1578 let len = buf.len().min(other.len());
1579 buf[..len].clone_from_slice(&other[..len]);
1580 Self::new_from_array(buf)
1581 }
1582 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1583 unsafe { std::mem::transmute(buf) }
1584 }
1585 pub fn as_slice(&self) -> &[u8] {
1586 unsafe {
1587 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1588 std::slice::from_raw_parts(ptr, Self::len())
1589 }
1590 }
1591 pub fn from_slice(buf: &[u8]) -> &Self {
1592 assert!(buf.len() >= Self::len());
1593 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1594 unsafe { std::mem::transmute(buf.as_ptr()) }
1595 }
1596 pub fn as_array(&self) -> &[u8; 12usize] {
1597 unsafe { std::mem::transmute(self) }
1598 }
1599 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1600 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1601 unsafe { std::mem::transmute(buf) }
1602 }
1603 pub fn into_array(self) -> [u8; 12usize] {
1604 unsafe { std::mem::transmute(self) }
1605 }
1606 pub const fn len() -> usize {
1607 const _: () = assert!(std::mem::size_of::<IflaVfVlan>() == 12usize);
1608 12usize
1609 }
1610}
1611#[derive(Debug)]
1612#[repr(C, packed(4))]
1613pub struct IflaVfTxRate {
1614 pub vf: u32,
1615 pub rate: u32,
1616}
1617impl Clone for IflaVfTxRate {
1618 fn clone(&self) -> Self {
1619 Self::new_from_array(*self.as_array())
1620 }
1621}
1622#[doc = "Create zero-initialized struct"]
1623impl Default for IflaVfTxRate {
1624 fn default() -> Self {
1625 Self::new()
1626 }
1627}
1628impl IflaVfTxRate {
1629 #[doc = "Create zero-initialized struct"]
1630 pub fn new() -> Self {
1631 Self::new_from_array([0u8; Self::len()])
1632 }
1633 #[doc = "Copy from contents from slice"]
1634 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1635 if other.len() != Self::len() {
1636 return None;
1637 }
1638 let mut buf = [0u8; Self::len()];
1639 buf.clone_from_slice(other);
1640 Some(Self::new_from_array(buf))
1641 }
1642 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1643 pub fn new_from_zeroed(other: &[u8]) -> Self {
1644 let mut buf = [0u8; Self::len()];
1645 let len = buf.len().min(other.len());
1646 buf[..len].clone_from_slice(&other[..len]);
1647 Self::new_from_array(buf)
1648 }
1649 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1650 unsafe { std::mem::transmute(buf) }
1651 }
1652 pub fn as_slice(&self) -> &[u8] {
1653 unsafe {
1654 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1655 std::slice::from_raw_parts(ptr, Self::len())
1656 }
1657 }
1658 pub fn from_slice(buf: &[u8]) -> &Self {
1659 assert!(buf.len() >= Self::len());
1660 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1661 unsafe { std::mem::transmute(buf.as_ptr()) }
1662 }
1663 pub fn as_array(&self) -> &[u8; 8usize] {
1664 unsafe { std::mem::transmute(self) }
1665 }
1666 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1667 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1668 unsafe { std::mem::transmute(buf) }
1669 }
1670 pub fn into_array(self) -> [u8; 8usize] {
1671 unsafe { std::mem::transmute(self) }
1672 }
1673 pub const fn len() -> usize {
1674 const _: () = assert!(std::mem::size_of::<IflaVfTxRate>() == 8usize);
1675 8usize
1676 }
1677}
1678#[derive(Debug)]
1679#[repr(C, packed(4))]
1680pub struct IflaVfSpoofchk {
1681 pub vf: u32,
1682 pub setting: u32,
1683}
1684impl Clone for IflaVfSpoofchk {
1685 fn clone(&self) -> Self {
1686 Self::new_from_array(*self.as_array())
1687 }
1688}
1689#[doc = "Create zero-initialized struct"]
1690impl Default for IflaVfSpoofchk {
1691 fn default() -> Self {
1692 Self::new()
1693 }
1694}
1695impl IflaVfSpoofchk {
1696 #[doc = "Create zero-initialized struct"]
1697 pub fn new() -> Self {
1698 Self::new_from_array([0u8; Self::len()])
1699 }
1700 #[doc = "Copy from contents from slice"]
1701 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1702 if other.len() != Self::len() {
1703 return None;
1704 }
1705 let mut buf = [0u8; Self::len()];
1706 buf.clone_from_slice(other);
1707 Some(Self::new_from_array(buf))
1708 }
1709 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1710 pub fn new_from_zeroed(other: &[u8]) -> Self {
1711 let mut buf = [0u8; Self::len()];
1712 let len = buf.len().min(other.len());
1713 buf[..len].clone_from_slice(&other[..len]);
1714 Self::new_from_array(buf)
1715 }
1716 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1717 unsafe { std::mem::transmute(buf) }
1718 }
1719 pub fn as_slice(&self) -> &[u8] {
1720 unsafe {
1721 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1722 std::slice::from_raw_parts(ptr, Self::len())
1723 }
1724 }
1725 pub fn from_slice(buf: &[u8]) -> &Self {
1726 assert!(buf.len() >= Self::len());
1727 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1728 unsafe { std::mem::transmute(buf.as_ptr()) }
1729 }
1730 pub fn as_array(&self) -> &[u8; 8usize] {
1731 unsafe { std::mem::transmute(self) }
1732 }
1733 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1734 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1735 unsafe { std::mem::transmute(buf) }
1736 }
1737 pub fn into_array(self) -> [u8; 8usize] {
1738 unsafe { std::mem::transmute(self) }
1739 }
1740 pub const fn len() -> usize {
1741 const _: () = assert!(std::mem::size_of::<IflaVfSpoofchk>() == 8usize);
1742 8usize
1743 }
1744}
1745#[repr(C, packed(4))]
1746pub struct IflaVfLinkState {
1747 pub vf: u32,
1748 #[doc = "Associated type: [`IflaVfLinkStateEnum`] (enum)"]
1749 pub link_state: u32,
1750}
1751impl Clone for IflaVfLinkState {
1752 fn clone(&self) -> Self {
1753 Self::new_from_array(*self.as_array())
1754 }
1755}
1756#[doc = "Create zero-initialized struct"]
1757impl Default for IflaVfLinkState {
1758 fn default() -> Self {
1759 Self::new()
1760 }
1761}
1762impl IflaVfLinkState {
1763 #[doc = "Create zero-initialized struct"]
1764 pub fn new() -> Self {
1765 Self::new_from_array([0u8; Self::len()])
1766 }
1767 #[doc = "Copy from contents from slice"]
1768 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1769 if other.len() != Self::len() {
1770 return None;
1771 }
1772 let mut buf = [0u8; Self::len()];
1773 buf.clone_from_slice(other);
1774 Some(Self::new_from_array(buf))
1775 }
1776 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1777 pub fn new_from_zeroed(other: &[u8]) -> Self {
1778 let mut buf = [0u8; Self::len()];
1779 let len = buf.len().min(other.len());
1780 buf[..len].clone_from_slice(&other[..len]);
1781 Self::new_from_array(buf)
1782 }
1783 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1784 unsafe { std::mem::transmute(buf) }
1785 }
1786 pub fn as_slice(&self) -> &[u8] {
1787 unsafe {
1788 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1789 std::slice::from_raw_parts(ptr, Self::len())
1790 }
1791 }
1792 pub fn from_slice(buf: &[u8]) -> &Self {
1793 assert!(buf.len() >= Self::len());
1794 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1795 unsafe { std::mem::transmute(buf.as_ptr()) }
1796 }
1797 pub fn as_array(&self) -> &[u8; 8usize] {
1798 unsafe { std::mem::transmute(self) }
1799 }
1800 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1801 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1802 unsafe { std::mem::transmute(buf) }
1803 }
1804 pub fn into_array(self) -> [u8; 8usize] {
1805 unsafe { std::mem::transmute(self) }
1806 }
1807 pub const fn len() -> usize {
1808 const _: () = assert!(std::mem::size_of::<IflaVfLinkState>() == 8usize);
1809 8usize
1810 }
1811}
1812impl std::fmt::Debug for IflaVfLinkState {
1813 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1814 fmt.debug_struct("IflaVfLinkState")
1815 .field("vf", &self.vf)
1816 .field(
1817 "link_state",
1818 &FormatEnum(self.link_state.into(), IflaVfLinkStateEnum::from_value),
1819 )
1820 .finish()
1821 }
1822}
1823#[derive(Debug)]
1824#[repr(C, packed(4))]
1825pub struct IflaVfRate {
1826 pub vf: u32,
1827 pub min_tx_rate: u32,
1828 pub max_tx_rate: u32,
1829}
1830impl Clone for IflaVfRate {
1831 fn clone(&self) -> Self {
1832 Self::new_from_array(*self.as_array())
1833 }
1834}
1835#[doc = "Create zero-initialized struct"]
1836impl Default for IflaVfRate {
1837 fn default() -> Self {
1838 Self::new()
1839 }
1840}
1841impl IflaVfRate {
1842 #[doc = "Create zero-initialized struct"]
1843 pub fn new() -> Self {
1844 Self::new_from_array([0u8; Self::len()])
1845 }
1846 #[doc = "Copy from contents from slice"]
1847 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1848 if other.len() != Self::len() {
1849 return None;
1850 }
1851 let mut buf = [0u8; Self::len()];
1852 buf.clone_from_slice(other);
1853 Some(Self::new_from_array(buf))
1854 }
1855 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1856 pub fn new_from_zeroed(other: &[u8]) -> Self {
1857 let mut buf = [0u8; Self::len()];
1858 let len = buf.len().min(other.len());
1859 buf[..len].clone_from_slice(&other[..len]);
1860 Self::new_from_array(buf)
1861 }
1862 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
1863 unsafe { std::mem::transmute(buf) }
1864 }
1865 pub fn as_slice(&self) -> &[u8] {
1866 unsafe {
1867 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1868 std::slice::from_raw_parts(ptr, Self::len())
1869 }
1870 }
1871 pub fn from_slice(buf: &[u8]) -> &Self {
1872 assert!(buf.len() >= Self::len());
1873 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1874 unsafe { std::mem::transmute(buf.as_ptr()) }
1875 }
1876 pub fn as_array(&self) -> &[u8; 12usize] {
1877 unsafe { std::mem::transmute(self) }
1878 }
1879 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
1880 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1881 unsafe { std::mem::transmute(buf) }
1882 }
1883 pub fn into_array(self) -> [u8; 12usize] {
1884 unsafe { std::mem::transmute(self) }
1885 }
1886 pub const fn len() -> usize {
1887 const _: () = assert!(std::mem::size_of::<IflaVfRate>() == 12usize);
1888 12usize
1889 }
1890}
1891#[derive(Debug)]
1892#[repr(C, packed(4))]
1893pub struct IflaVfRssQueryEn {
1894 pub vf: u32,
1895 pub setting: u32,
1896}
1897impl Clone for IflaVfRssQueryEn {
1898 fn clone(&self) -> Self {
1899 Self::new_from_array(*self.as_array())
1900 }
1901}
1902#[doc = "Create zero-initialized struct"]
1903impl Default for IflaVfRssQueryEn {
1904 fn default() -> Self {
1905 Self::new()
1906 }
1907}
1908impl IflaVfRssQueryEn {
1909 #[doc = "Create zero-initialized struct"]
1910 pub fn new() -> Self {
1911 Self::new_from_array([0u8; Self::len()])
1912 }
1913 #[doc = "Copy from contents from slice"]
1914 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1915 if other.len() != Self::len() {
1916 return None;
1917 }
1918 let mut buf = [0u8; Self::len()];
1919 buf.clone_from_slice(other);
1920 Some(Self::new_from_array(buf))
1921 }
1922 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1923 pub fn new_from_zeroed(other: &[u8]) -> Self {
1924 let mut buf = [0u8; Self::len()];
1925 let len = buf.len().min(other.len());
1926 buf[..len].clone_from_slice(&other[..len]);
1927 Self::new_from_array(buf)
1928 }
1929 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1930 unsafe { std::mem::transmute(buf) }
1931 }
1932 pub fn as_slice(&self) -> &[u8] {
1933 unsafe {
1934 let ptr: *const u8 = std::mem::transmute(self as *const Self);
1935 std::slice::from_raw_parts(ptr, Self::len())
1936 }
1937 }
1938 pub fn from_slice(buf: &[u8]) -> &Self {
1939 assert!(buf.len() >= Self::len());
1940 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1941 unsafe { std::mem::transmute(buf.as_ptr()) }
1942 }
1943 pub fn as_array(&self) -> &[u8; 8usize] {
1944 unsafe { std::mem::transmute(self) }
1945 }
1946 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
1947 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
1948 unsafe { std::mem::transmute(buf) }
1949 }
1950 pub fn into_array(self) -> [u8; 8usize] {
1951 unsafe { std::mem::transmute(self) }
1952 }
1953 pub const fn len() -> usize {
1954 const _: () = assert!(std::mem::size_of::<IflaVfRssQueryEn>() == 8usize);
1955 8usize
1956 }
1957}
1958#[derive(Debug)]
1959#[repr(C, packed(4))]
1960pub struct IflaVfTrust {
1961 pub vf: u32,
1962 pub setting: u32,
1963}
1964impl Clone for IflaVfTrust {
1965 fn clone(&self) -> Self {
1966 Self::new_from_array(*self.as_array())
1967 }
1968}
1969#[doc = "Create zero-initialized struct"]
1970impl Default for IflaVfTrust {
1971 fn default() -> Self {
1972 Self::new()
1973 }
1974}
1975impl IflaVfTrust {
1976 #[doc = "Create zero-initialized struct"]
1977 pub fn new() -> Self {
1978 Self::new_from_array([0u8; Self::len()])
1979 }
1980 #[doc = "Copy from contents from slice"]
1981 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1982 if other.len() != Self::len() {
1983 return None;
1984 }
1985 let mut buf = [0u8; Self::len()];
1986 buf.clone_from_slice(other);
1987 Some(Self::new_from_array(buf))
1988 }
1989 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1990 pub fn new_from_zeroed(other: &[u8]) -> Self {
1991 let mut buf = [0u8; Self::len()];
1992 let len = buf.len().min(other.len());
1993 buf[..len].clone_from_slice(&other[..len]);
1994 Self::new_from_array(buf)
1995 }
1996 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
1997 unsafe { std::mem::transmute(buf) }
1998 }
1999 pub fn as_slice(&self) -> &[u8] {
2000 unsafe {
2001 let ptr: *const u8 = std::mem::transmute(self as *const Self);
2002 std::slice::from_raw_parts(ptr, Self::len())
2003 }
2004 }
2005 pub fn from_slice(buf: &[u8]) -> &Self {
2006 assert!(buf.len() >= Self::len());
2007 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2008 unsafe { std::mem::transmute(buf.as_ptr()) }
2009 }
2010 pub fn as_array(&self) -> &[u8; 8usize] {
2011 unsafe { std::mem::transmute(self) }
2012 }
2013 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
2014 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2015 unsafe { std::mem::transmute(buf) }
2016 }
2017 pub fn into_array(self) -> [u8; 8usize] {
2018 unsafe { std::mem::transmute(self) }
2019 }
2020 pub const fn len() -> usize {
2021 const _: () = assert!(std::mem::size_of::<IflaVfTrust>() == 8usize);
2022 8usize
2023 }
2024}
2025#[repr(C, packed(4))]
2026pub struct IflaVfGuid {
2027 pub vf: u32,
2028 pub _pad_4: [u8; 4usize],
2029 pub guid: u64,
2030}
2031impl Clone for IflaVfGuid {
2032 fn clone(&self) -> Self {
2033 Self::new_from_array(*self.as_array())
2034 }
2035}
2036#[doc = "Create zero-initialized struct"]
2037impl Default for IflaVfGuid {
2038 fn default() -> Self {
2039 Self::new()
2040 }
2041}
2042impl IflaVfGuid {
2043 #[doc = "Create zero-initialized struct"]
2044 pub fn new() -> Self {
2045 Self::new_from_array([0u8; Self::len()])
2046 }
2047 #[doc = "Copy from contents from slice"]
2048 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2049 if other.len() != Self::len() {
2050 return None;
2051 }
2052 let mut buf = [0u8; Self::len()];
2053 buf.clone_from_slice(other);
2054 Some(Self::new_from_array(buf))
2055 }
2056 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2057 pub fn new_from_zeroed(other: &[u8]) -> Self {
2058 let mut buf = [0u8; Self::len()];
2059 let len = buf.len().min(other.len());
2060 buf[..len].clone_from_slice(&other[..len]);
2061 Self::new_from_array(buf)
2062 }
2063 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
2064 unsafe { std::mem::transmute(buf) }
2065 }
2066 pub fn as_slice(&self) -> &[u8] {
2067 unsafe {
2068 let ptr: *const u8 = std::mem::transmute(self as *const Self);
2069 std::slice::from_raw_parts(ptr, Self::len())
2070 }
2071 }
2072 pub fn from_slice(buf: &[u8]) -> &Self {
2073 assert!(buf.len() >= Self::len());
2074 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2075 unsafe { std::mem::transmute(buf.as_ptr()) }
2076 }
2077 pub fn as_array(&self) -> &[u8; 16usize] {
2078 unsafe { std::mem::transmute(self) }
2079 }
2080 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
2081 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2082 unsafe { std::mem::transmute(buf) }
2083 }
2084 pub fn into_array(self) -> [u8; 16usize] {
2085 unsafe { std::mem::transmute(self) }
2086 }
2087 pub const fn len() -> usize {
2088 const _: () = assert!(std::mem::size_of::<IflaVfGuid>() == 16usize);
2089 16usize
2090 }
2091}
2092impl std::fmt::Debug for IflaVfGuid {
2093 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2094 fmt.debug_struct("IflaVfGuid")
2095 .field("vf", &self.vf)
2096 .field("guid", &{ self.guid })
2097 .finish()
2098 }
2099}
2100#[derive(Debug)]
2101#[repr(C, packed(4))]
2102pub struct IflaVfVlanInfo {
2103 pub vf: u32,
2104 pub vlan: u32,
2105 pub qos: u32,
2106 pub vlan_proto: u32,
2107}
2108impl Clone for IflaVfVlanInfo {
2109 fn clone(&self) -> Self {
2110 Self::new_from_array(*self.as_array())
2111 }
2112}
2113#[doc = "Create zero-initialized struct"]
2114impl Default for IflaVfVlanInfo {
2115 fn default() -> Self {
2116 Self::new()
2117 }
2118}
2119impl IflaVfVlanInfo {
2120 #[doc = "Create zero-initialized struct"]
2121 pub fn new() -> Self {
2122 Self::new_from_array([0u8; Self::len()])
2123 }
2124 #[doc = "Copy from contents from slice"]
2125 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2126 if other.len() != Self::len() {
2127 return None;
2128 }
2129 let mut buf = [0u8; Self::len()];
2130 buf.clone_from_slice(other);
2131 Some(Self::new_from_array(buf))
2132 }
2133 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2134 pub fn new_from_zeroed(other: &[u8]) -> Self {
2135 let mut buf = [0u8; Self::len()];
2136 let len = buf.len().min(other.len());
2137 buf[..len].clone_from_slice(&other[..len]);
2138 Self::new_from_array(buf)
2139 }
2140 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
2141 unsafe { std::mem::transmute(buf) }
2142 }
2143 pub fn as_slice(&self) -> &[u8] {
2144 unsafe {
2145 let ptr: *const u8 = std::mem::transmute(self as *const Self);
2146 std::slice::from_raw_parts(ptr, Self::len())
2147 }
2148 }
2149 pub fn from_slice(buf: &[u8]) -> &Self {
2150 assert!(buf.len() >= Self::len());
2151 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2152 unsafe { std::mem::transmute(buf.as_ptr()) }
2153 }
2154 pub fn as_array(&self) -> &[u8; 16usize] {
2155 unsafe { std::mem::transmute(self) }
2156 }
2157 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
2158 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
2159 unsafe { std::mem::transmute(buf) }
2160 }
2161 pub fn into_array(self) -> [u8; 16usize] {
2162 unsafe { std::mem::transmute(self) }
2163 }
2164 pub const fn len() -> usize {
2165 const _: () = assert!(std::mem::size_of::<IflaVfVlanInfo>() == 16usize);
2166 16usize
2167 }
2168}
2169#[derive(Clone)]
2170pub enum LinkAttrs<'a> {
2171 Address(&'a [u8]),
2172 Broadcast(&'a [u8]),
2173 Ifname(&'a CStr),
2174 Mtu(u32),
2175 Link(u32),
2176 Qdisc(&'a CStr),
2177 Stats(RtnlLinkStats),
2178 Cost(&'a CStr),
2179 Priority(&'a CStr),
2180 Master(u32),
2181 Wireless(&'a CStr),
2182 Protinfo(&'a CStr),
2183 Txqlen(u32),
2184 Map(RtnlLinkIfmap),
2185 Weight(u32),
2186 Operstate(u8),
2187 Linkmode(u8),
2188 Linkinfo(IterableLinkinfoAttrs<'a>),
2189 NetNsPid(u32),
2190 Ifalias(&'a CStr),
2191 NumVf(u32),
2192 VfinfoList(IterableVfinfoListAttrs<'a>),
2193 Stats64(RtnlLinkStats64),
2194 VfPorts(IterableVfPortsAttrs<'a>),
2195 PortSelf(IterablePortSelfAttrs<'a>),
2196 AfSpec(IterableAfSpecAttrs<'a>),
2197 Group(u32),
2198 NetNsFd(u32),
2199 #[doc = "Associated type: [`RtextFilter`] (1 bit per enumeration)"]
2200 ExtMask(u32),
2201 Promiscuity(u32),
2202 NumTxQueues(u32),
2203 NumRxQueues(u32),
2204 Carrier(u8),
2205 PhysPortId(&'a [u8]),
2206 CarrierChanges(u32),
2207 PhysSwitchId(&'a [u8]),
2208 LinkNetnsid(i32),
2209 PhysPortName(&'a CStr),
2210 ProtoDown(u8),
2211 GsoMaxSegs(u32),
2212 GsoMaxSize(u32),
2213 Pad(&'a [u8]),
2214 Xdp(IterableXdpAttrs<'a>),
2215 Event(u32),
2216 NewNetnsid(i32),
2217 TargetNetnsid(i32),
2218 CarrierUpCount(u32),
2219 CarrierDownCount(u32),
2220 NewIfindex(i32),
2221 MinMtu(u32),
2222 MaxMtu(u32),
2223 PropList(IterablePropListLinkAttrs<'a>),
2224 AltIfname(&'a CStr),
2225 PermAddress(&'a [u8]),
2226 ProtoDownReason(&'a CStr),
2227 ParentDevName(&'a CStr),
2228 ParentDevBusName(&'a CStr),
2229 GroMaxSize(u32),
2230 TsoMaxSize(u32),
2231 TsoMaxSegs(u32),
2232 Allmulti(u32),
2233 DevlinkPort(&'a [u8]),
2234 GsoIpv4MaxSize(u32),
2235 GroIpv4MaxSize(u32),
2236 DpllPin(IterableLinkDpllPinAttrs<'a>),
2237 #[doc = "EDT offload horizon supported by the device (in nsec)\\."]
2238 MaxPacingOffloadHorizon(u32),
2239 NetnsImmutable(u8),
2240 Headroom(u16),
2241 Tailroom(u16),
2242}
2243impl<'a> IterableLinkAttrs<'a> {
2244 pub fn get_address(&self) -> Result<&'a [u8], ErrorContext> {
2245 let mut iter = self.clone();
2246 iter.pos = 0;
2247 for attr in iter {
2248 if let LinkAttrs::Address(val) = attr? {
2249 return Ok(val);
2250 }
2251 }
2252 Err(ErrorContext::new_missing(
2253 "LinkAttrs",
2254 "Address",
2255 self.orig_loc,
2256 self.buf.as_ptr() as usize,
2257 ))
2258 }
2259 pub fn get_broadcast(&self) -> Result<&'a [u8], ErrorContext> {
2260 let mut iter = self.clone();
2261 iter.pos = 0;
2262 for attr in iter {
2263 if let LinkAttrs::Broadcast(val) = attr? {
2264 return Ok(val);
2265 }
2266 }
2267 Err(ErrorContext::new_missing(
2268 "LinkAttrs",
2269 "Broadcast",
2270 self.orig_loc,
2271 self.buf.as_ptr() as usize,
2272 ))
2273 }
2274 pub fn get_ifname(&self) -> Result<&'a CStr, ErrorContext> {
2275 let mut iter = self.clone();
2276 iter.pos = 0;
2277 for attr in iter {
2278 if let LinkAttrs::Ifname(val) = attr? {
2279 return Ok(val);
2280 }
2281 }
2282 Err(ErrorContext::new_missing(
2283 "LinkAttrs",
2284 "Ifname",
2285 self.orig_loc,
2286 self.buf.as_ptr() as usize,
2287 ))
2288 }
2289 pub fn get_mtu(&self) -> Result<u32, ErrorContext> {
2290 let mut iter = self.clone();
2291 iter.pos = 0;
2292 for attr in iter {
2293 if let LinkAttrs::Mtu(val) = attr? {
2294 return Ok(val);
2295 }
2296 }
2297 Err(ErrorContext::new_missing(
2298 "LinkAttrs",
2299 "Mtu",
2300 self.orig_loc,
2301 self.buf.as_ptr() as usize,
2302 ))
2303 }
2304 pub fn get_link(&self) -> Result<u32, ErrorContext> {
2305 let mut iter = self.clone();
2306 iter.pos = 0;
2307 for attr in iter {
2308 if let LinkAttrs::Link(val) = attr? {
2309 return Ok(val);
2310 }
2311 }
2312 Err(ErrorContext::new_missing(
2313 "LinkAttrs",
2314 "Link",
2315 self.orig_loc,
2316 self.buf.as_ptr() as usize,
2317 ))
2318 }
2319 pub fn get_qdisc(&self) -> Result<&'a CStr, ErrorContext> {
2320 let mut iter = self.clone();
2321 iter.pos = 0;
2322 for attr in iter {
2323 if let LinkAttrs::Qdisc(val) = attr? {
2324 return Ok(val);
2325 }
2326 }
2327 Err(ErrorContext::new_missing(
2328 "LinkAttrs",
2329 "Qdisc",
2330 self.orig_loc,
2331 self.buf.as_ptr() as usize,
2332 ))
2333 }
2334 pub fn get_stats(&self) -> Result<RtnlLinkStats, ErrorContext> {
2335 let mut iter = self.clone();
2336 iter.pos = 0;
2337 for attr in iter {
2338 if let LinkAttrs::Stats(val) = attr? {
2339 return Ok(val);
2340 }
2341 }
2342 Err(ErrorContext::new_missing(
2343 "LinkAttrs",
2344 "Stats",
2345 self.orig_loc,
2346 self.buf.as_ptr() as usize,
2347 ))
2348 }
2349 pub fn get_cost(&self) -> Result<&'a CStr, ErrorContext> {
2350 let mut iter = self.clone();
2351 iter.pos = 0;
2352 for attr in iter {
2353 if let LinkAttrs::Cost(val) = attr? {
2354 return Ok(val);
2355 }
2356 }
2357 Err(ErrorContext::new_missing(
2358 "LinkAttrs",
2359 "Cost",
2360 self.orig_loc,
2361 self.buf.as_ptr() as usize,
2362 ))
2363 }
2364 pub fn get_priority(&self) -> Result<&'a CStr, ErrorContext> {
2365 let mut iter = self.clone();
2366 iter.pos = 0;
2367 for attr in iter {
2368 if let LinkAttrs::Priority(val) = attr? {
2369 return Ok(val);
2370 }
2371 }
2372 Err(ErrorContext::new_missing(
2373 "LinkAttrs",
2374 "Priority",
2375 self.orig_loc,
2376 self.buf.as_ptr() as usize,
2377 ))
2378 }
2379 pub fn get_master(&self) -> Result<u32, ErrorContext> {
2380 let mut iter = self.clone();
2381 iter.pos = 0;
2382 for attr in iter {
2383 if let LinkAttrs::Master(val) = attr? {
2384 return Ok(val);
2385 }
2386 }
2387 Err(ErrorContext::new_missing(
2388 "LinkAttrs",
2389 "Master",
2390 self.orig_loc,
2391 self.buf.as_ptr() as usize,
2392 ))
2393 }
2394 pub fn get_wireless(&self) -> Result<&'a CStr, ErrorContext> {
2395 let mut iter = self.clone();
2396 iter.pos = 0;
2397 for attr in iter {
2398 if let LinkAttrs::Wireless(val) = attr? {
2399 return Ok(val);
2400 }
2401 }
2402 Err(ErrorContext::new_missing(
2403 "LinkAttrs",
2404 "Wireless",
2405 self.orig_loc,
2406 self.buf.as_ptr() as usize,
2407 ))
2408 }
2409 pub fn get_protinfo(&self) -> Result<&'a CStr, ErrorContext> {
2410 let mut iter = self.clone();
2411 iter.pos = 0;
2412 for attr in iter {
2413 if let LinkAttrs::Protinfo(val) = attr? {
2414 return Ok(val);
2415 }
2416 }
2417 Err(ErrorContext::new_missing(
2418 "LinkAttrs",
2419 "Protinfo",
2420 self.orig_loc,
2421 self.buf.as_ptr() as usize,
2422 ))
2423 }
2424 pub fn get_txqlen(&self) -> Result<u32, ErrorContext> {
2425 let mut iter = self.clone();
2426 iter.pos = 0;
2427 for attr in iter {
2428 if let LinkAttrs::Txqlen(val) = attr? {
2429 return Ok(val);
2430 }
2431 }
2432 Err(ErrorContext::new_missing(
2433 "LinkAttrs",
2434 "Txqlen",
2435 self.orig_loc,
2436 self.buf.as_ptr() as usize,
2437 ))
2438 }
2439 pub fn get_map(&self) -> Result<RtnlLinkIfmap, ErrorContext> {
2440 let mut iter = self.clone();
2441 iter.pos = 0;
2442 for attr in iter {
2443 if let LinkAttrs::Map(val) = attr? {
2444 return Ok(val);
2445 }
2446 }
2447 Err(ErrorContext::new_missing(
2448 "LinkAttrs",
2449 "Map",
2450 self.orig_loc,
2451 self.buf.as_ptr() as usize,
2452 ))
2453 }
2454 pub fn get_weight(&self) -> Result<u32, ErrorContext> {
2455 let mut iter = self.clone();
2456 iter.pos = 0;
2457 for attr in iter {
2458 if let LinkAttrs::Weight(val) = attr? {
2459 return Ok(val);
2460 }
2461 }
2462 Err(ErrorContext::new_missing(
2463 "LinkAttrs",
2464 "Weight",
2465 self.orig_loc,
2466 self.buf.as_ptr() as usize,
2467 ))
2468 }
2469 pub fn get_operstate(&self) -> Result<u8, ErrorContext> {
2470 let mut iter = self.clone();
2471 iter.pos = 0;
2472 for attr in iter {
2473 if let LinkAttrs::Operstate(val) = attr? {
2474 return Ok(val);
2475 }
2476 }
2477 Err(ErrorContext::new_missing(
2478 "LinkAttrs",
2479 "Operstate",
2480 self.orig_loc,
2481 self.buf.as_ptr() as usize,
2482 ))
2483 }
2484 pub fn get_linkmode(&self) -> Result<u8, ErrorContext> {
2485 let mut iter = self.clone();
2486 iter.pos = 0;
2487 for attr in iter {
2488 if let LinkAttrs::Linkmode(val) = attr? {
2489 return Ok(val);
2490 }
2491 }
2492 Err(ErrorContext::new_missing(
2493 "LinkAttrs",
2494 "Linkmode",
2495 self.orig_loc,
2496 self.buf.as_ptr() as usize,
2497 ))
2498 }
2499 pub fn get_linkinfo(&self) -> Result<IterableLinkinfoAttrs<'a>, ErrorContext> {
2500 let mut iter = self.clone();
2501 iter.pos = 0;
2502 for attr in iter {
2503 if let LinkAttrs::Linkinfo(val) = attr? {
2504 return Ok(val);
2505 }
2506 }
2507 Err(ErrorContext::new_missing(
2508 "LinkAttrs",
2509 "Linkinfo",
2510 self.orig_loc,
2511 self.buf.as_ptr() as usize,
2512 ))
2513 }
2514 pub fn get_net_ns_pid(&self) -> Result<u32, ErrorContext> {
2515 let mut iter = self.clone();
2516 iter.pos = 0;
2517 for attr in iter {
2518 if let LinkAttrs::NetNsPid(val) = attr? {
2519 return Ok(val);
2520 }
2521 }
2522 Err(ErrorContext::new_missing(
2523 "LinkAttrs",
2524 "NetNsPid",
2525 self.orig_loc,
2526 self.buf.as_ptr() as usize,
2527 ))
2528 }
2529 pub fn get_ifalias(&self) -> Result<&'a CStr, ErrorContext> {
2530 let mut iter = self.clone();
2531 iter.pos = 0;
2532 for attr in iter {
2533 if let LinkAttrs::Ifalias(val) = attr? {
2534 return Ok(val);
2535 }
2536 }
2537 Err(ErrorContext::new_missing(
2538 "LinkAttrs",
2539 "Ifalias",
2540 self.orig_loc,
2541 self.buf.as_ptr() as usize,
2542 ))
2543 }
2544 pub fn get_num_vf(&self) -> Result<u32, ErrorContext> {
2545 let mut iter = self.clone();
2546 iter.pos = 0;
2547 for attr in iter {
2548 if let LinkAttrs::NumVf(val) = attr? {
2549 return Ok(val);
2550 }
2551 }
2552 Err(ErrorContext::new_missing(
2553 "LinkAttrs",
2554 "NumVf",
2555 self.orig_loc,
2556 self.buf.as_ptr() as usize,
2557 ))
2558 }
2559 pub fn get_vfinfo_list(&self) -> Result<IterableVfinfoListAttrs<'a>, ErrorContext> {
2560 let mut iter = self.clone();
2561 iter.pos = 0;
2562 for attr in iter {
2563 if let LinkAttrs::VfinfoList(val) = attr? {
2564 return Ok(val);
2565 }
2566 }
2567 Err(ErrorContext::new_missing(
2568 "LinkAttrs",
2569 "VfinfoList",
2570 self.orig_loc,
2571 self.buf.as_ptr() as usize,
2572 ))
2573 }
2574 pub fn get_stats64(&self) -> Result<RtnlLinkStats64, ErrorContext> {
2575 let mut iter = self.clone();
2576 iter.pos = 0;
2577 for attr in iter {
2578 if let LinkAttrs::Stats64(val) = attr? {
2579 return Ok(val);
2580 }
2581 }
2582 Err(ErrorContext::new_missing(
2583 "LinkAttrs",
2584 "Stats64",
2585 self.orig_loc,
2586 self.buf.as_ptr() as usize,
2587 ))
2588 }
2589 pub fn get_vf_ports(&self) -> Result<IterableVfPortsAttrs<'a>, ErrorContext> {
2590 let mut iter = self.clone();
2591 iter.pos = 0;
2592 for attr in iter {
2593 if let LinkAttrs::VfPorts(val) = attr? {
2594 return Ok(val);
2595 }
2596 }
2597 Err(ErrorContext::new_missing(
2598 "LinkAttrs",
2599 "VfPorts",
2600 self.orig_loc,
2601 self.buf.as_ptr() as usize,
2602 ))
2603 }
2604 pub fn get_port_self(&self) -> Result<IterablePortSelfAttrs<'a>, ErrorContext> {
2605 let mut iter = self.clone();
2606 iter.pos = 0;
2607 for attr in iter {
2608 if let LinkAttrs::PortSelf(val) = attr? {
2609 return Ok(val);
2610 }
2611 }
2612 Err(ErrorContext::new_missing(
2613 "LinkAttrs",
2614 "PortSelf",
2615 self.orig_loc,
2616 self.buf.as_ptr() as usize,
2617 ))
2618 }
2619 pub fn get_af_spec(&self) -> Result<IterableAfSpecAttrs<'a>, ErrorContext> {
2620 let mut iter = self.clone();
2621 iter.pos = 0;
2622 for attr in iter {
2623 if let LinkAttrs::AfSpec(val) = attr? {
2624 return Ok(val);
2625 }
2626 }
2627 Err(ErrorContext::new_missing(
2628 "LinkAttrs",
2629 "AfSpec",
2630 self.orig_loc,
2631 self.buf.as_ptr() as usize,
2632 ))
2633 }
2634 pub fn get_group(&self) -> Result<u32, ErrorContext> {
2635 let mut iter = self.clone();
2636 iter.pos = 0;
2637 for attr in iter {
2638 if let LinkAttrs::Group(val) = attr? {
2639 return Ok(val);
2640 }
2641 }
2642 Err(ErrorContext::new_missing(
2643 "LinkAttrs",
2644 "Group",
2645 self.orig_loc,
2646 self.buf.as_ptr() as usize,
2647 ))
2648 }
2649 pub fn get_net_ns_fd(&self) -> Result<u32, ErrorContext> {
2650 let mut iter = self.clone();
2651 iter.pos = 0;
2652 for attr in iter {
2653 if let LinkAttrs::NetNsFd(val) = attr? {
2654 return Ok(val);
2655 }
2656 }
2657 Err(ErrorContext::new_missing(
2658 "LinkAttrs",
2659 "NetNsFd",
2660 self.orig_loc,
2661 self.buf.as_ptr() as usize,
2662 ))
2663 }
2664 #[doc = "Associated type: [`RtextFilter`] (1 bit per enumeration)"]
2665 pub fn get_ext_mask(&self) -> Result<u32, ErrorContext> {
2666 let mut iter = self.clone();
2667 iter.pos = 0;
2668 for attr in iter {
2669 if let LinkAttrs::ExtMask(val) = attr? {
2670 return Ok(val);
2671 }
2672 }
2673 Err(ErrorContext::new_missing(
2674 "LinkAttrs",
2675 "ExtMask",
2676 self.orig_loc,
2677 self.buf.as_ptr() as usize,
2678 ))
2679 }
2680 pub fn get_promiscuity(&self) -> Result<u32, ErrorContext> {
2681 let mut iter = self.clone();
2682 iter.pos = 0;
2683 for attr in iter {
2684 if let LinkAttrs::Promiscuity(val) = attr? {
2685 return Ok(val);
2686 }
2687 }
2688 Err(ErrorContext::new_missing(
2689 "LinkAttrs",
2690 "Promiscuity",
2691 self.orig_loc,
2692 self.buf.as_ptr() as usize,
2693 ))
2694 }
2695 pub fn get_num_tx_queues(&self) -> Result<u32, ErrorContext> {
2696 let mut iter = self.clone();
2697 iter.pos = 0;
2698 for attr in iter {
2699 if let LinkAttrs::NumTxQueues(val) = attr? {
2700 return Ok(val);
2701 }
2702 }
2703 Err(ErrorContext::new_missing(
2704 "LinkAttrs",
2705 "NumTxQueues",
2706 self.orig_loc,
2707 self.buf.as_ptr() as usize,
2708 ))
2709 }
2710 pub fn get_num_rx_queues(&self) -> Result<u32, ErrorContext> {
2711 let mut iter = self.clone();
2712 iter.pos = 0;
2713 for attr in iter {
2714 if let LinkAttrs::NumRxQueues(val) = attr? {
2715 return Ok(val);
2716 }
2717 }
2718 Err(ErrorContext::new_missing(
2719 "LinkAttrs",
2720 "NumRxQueues",
2721 self.orig_loc,
2722 self.buf.as_ptr() as usize,
2723 ))
2724 }
2725 pub fn get_carrier(&self) -> Result<u8, ErrorContext> {
2726 let mut iter = self.clone();
2727 iter.pos = 0;
2728 for attr in iter {
2729 if let LinkAttrs::Carrier(val) = attr? {
2730 return Ok(val);
2731 }
2732 }
2733 Err(ErrorContext::new_missing(
2734 "LinkAttrs",
2735 "Carrier",
2736 self.orig_loc,
2737 self.buf.as_ptr() as usize,
2738 ))
2739 }
2740 pub fn get_phys_port_id(&self) -> Result<&'a [u8], ErrorContext> {
2741 let mut iter = self.clone();
2742 iter.pos = 0;
2743 for attr in iter {
2744 if let LinkAttrs::PhysPortId(val) = attr? {
2745 return Ok(val);
2746 }
2747 }
2748 Err(ErrorContext::new_missing(
2749 "LinkAttrs",
2750 "PhysPortId",
2751 self.orig_loc,
2752 self.buf.as_ptr() as usize,
2753 ))
2754 }
2755 pub fn get_carrier_changes(&self) -> Result<u32, ErrorContext> {
2756 let mut iter = self.clone();
2757 iter.pos = 0;
2758 for attr in iter {
2759 if let LinkAttrs::CarrierChanges(val) = attr? {
2760 return Ok(val);
2761 }
2762 }
2763 Err(ErrorContext::new_missing(
2764 "LinkAttrs",
2765 "CarrierChanges",
2766 self.orig_loc,
2767 self.buf.as_ptr() as usize,
2768 ))
2769 }
2770 pub fn get_phys_switch_id(&self) -> Result<&'a [u8], ErrorContext> {
2771 let mut iter = self.clone();
2772 iter.pos = 0;
2773 for attr in iter {
2774 if let LinkAttrs::PhysSwitchId(val) = attr? {
2775 return Ok(val);
2776 }
2777 }
2778 Err(ErrorContext::new_missing(
2779 "LinkAttrs",
2780 "PhysSwitchId",
2781 self.orig_loc,
2782 self.buf.as_ptr() as usize,
2783 ))
2784 }
2785 pub fn get_link_netnsid(&self) -> Result<i32, ErrorContext> {
2786 let mut iter = self.clone();
2787 iter.pos = 0;
2788 for attr in iter {
2789 if let LinkAttrs::LinkNetnsid(val) = attr? {
2790 return Ok(val);
2791 }
2792 }
2793 Err(ErrorContext::new_missing(
2794 "LinkAttrs",
2795 "LinkNetnsid",
2796 self.orig_loc,
2797 self.buf.as_ptr() as usize,
2798 ))
2799 }
2800 pub fn get_phys_port_name(&self) -> Result<&'a CStr, ErrorContext> {
2801 let mut iter = self.clone();
2802 iter.pos = 0;
2803 for attr in iter {
2804 if let LinkAttrs::PhysPortName(val) = attr? {
2805 return Ok(val);
2806 }
2807 }
2808 Err(ErrorContext::new_missing(
2809 "LinkAttrs",
2810 "PhysPortName",
2811 self.orig_loc,
2812 self.buf.as_ptr() as usize,
2813 ))
2814 }
2815 pub fn get_proto_down(&self) -> Result<u8, ErrorContext> {
2816 let mut iter = self.clone();
2817 iter.pos = 0;
2818 for attr in iter {
2819 if let LinkAttrs::ProtoDown(val) = attr? {
2820 return Ok(val);
2821 }
2822 }
2823 Err(ErrorContext::new_missing(
2824 "LinkAttrs",
2825 "ProtoDown",
2826 self.orig_loc,
2827 self.buf.as_ptr() as usize,
2828 ))
2829 }
2830 pub fn get_gso_max_segs(&self) -> Result<u32, ErrorContext> {
2831 let mut iter = self.clone();
2832 iter.pos = 0;
2833 for attr in iter {
2834 if let LinkAttrs::GsoMaxSegs(val) = attr? {
2835 return Ok(val);
2836 }
2837 }
2838 Err(ErrorContext::new_missing(
2839 "LinkAttrs",
2840 "GsoMaxSegs",
2841 self.orig_loc,
2842 self.buf.as_ptr() as usize,
2843 ))
2844 }
2845 pub fn get_gso_max_size(&self) -> Result<u32, ErrorContext> {
2846 let mut iter = self.clone();
2847 iter.pos = 0;
2848 for attr in iter {
2849 if let LinkAttrs::GsoMaxSize(val) = attr? {
2850 return Ok(val);
2851 }
2852 }
2853 Err(ErrorContext::new_missing(
2854 "LinkAttrs",
2855 "GsoMaxSize",
2856 self.orig_loc,
2857 self.buf.as_ptr() as usize,
2858 ))
2859 }
2860 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
2861 let mut iter = self.clone();
2862 iter.pos = 0;
2863 for attr in iter {
2864 if let LinkAttrs::Pad(val) = attr? {
2865 return Ok(val);
2866 }
2867 }
2868 Err(ErrorContext::new_missing(
2869 "LinkAttrs",
2870 "Pad",
2871 self.orig_loc,
2872 self.buf.as_ptr() as usize,
2873 ))
2874 }
2875 pub fn get_xdp(&self) -> Result<IterableXdpAttrs<'a>, ErrorContext> {
2876 let mut iter = self.clone();
2877 iter.pos = 0;
2878 for attr in iter {
2879 if let LinkAttrs::Xdp(val) = attr? {
2880 return Ok(val);
2881 }
2882 }
2883 Err(ErrorContext::new_missing(
2884 "LinkAttrs",
2885 "Xdp",
2886 self.orig_loc,
2887 self.buf.as_ptr() as usize,
2888 ))
2889 }
2890 pub fn get_event(&self) -> Result<u32, ErrorContext> {
2891 let mut iter = self.clone();
2892 iter.pos = 0;
2893 for attr in iter {
2894 if let LinkAttrs::Event(val) = attr? {
2895 return Ok(val);
2896 }
2897 }
2898 Err(ErrorContext::new_missing(
2899 "LinkAttrs",
2900 "Event",
2901 self.orig_loc,
2902 self.buf.as_ptr() as usize,
2903 ))
2904 }
2905 pub fn get_new_netnsid(&self) -> Result<i32, ErrorContext> {
2906 let mut iter = self.clone();
2907 iter.pos = 0;
2908 for attr in iter {
2909 if let LinkAttrs::NewNetnsid(val) = attr? {
2910 return Ok(val);
2911 }
2912 }
2913 Err(ErrorContext::new_missing(
2914 "LinkAttrs",
2915 "NewNetnsid",
2916 self.orig_loc,
2917 self.buf.as_ptr() as usize,
2918 ))
2919 }
2920 pub fn get_target_netnsid(&self) -> Result<i32, ErrorContext> {
2921 let mut iter = self.clone();
2922 iter.pos = 0;
2923 for attr in iter {
2924 if let LinkAttrs::TargetNetnsid(val) = attr? {
2925 return Ok(val);
2926 }
2927 }
2928 Err(ErrorContext::new_missing(
2929 "LinkAttrs",
2930 "TargetNetnsid",
2931 self.orig_loc,
2932 self.buf.as_ptr() as usize,
2933 ))
2934 }
2935 pub fn get_carrier_up_count(&self) -> Result<u32, ErrorContext> {
2936 let mut iter = self.clone();
2937 iter.pos = 0;
2938 for attr in iter {
2939 if let LinkAttrs::CarrierUpCount(val) = attr? {
2940 return Ok(val);
2941 }
2942 }
2943 Err(ErrorContext::new_missing(
2944 "LinkAttrs",
2945 "CarrierUpCount",
2946 self.orig_loc,
2947 self.buf.as_ptr() as usize,
2948 ))
2949 }
2950 pub fn get_carrier_down_count(&self) -> Result<u32, ErrorContext> {
2951 let mut iter = self.clone();
2952 iter.pos = 0;
2953 for attr in iter {
2954 if let LinkAttrs::CarrierDownCount(val) = attr? {
2955 return Ok(val);
2956 }
2957 }
2958 Err(ErrorContext::new_missing(
2959 "LinkAttrs",
2960 "CarrierDownCount",
2961 self.orig_loc,
2962 self.buf.as_ptr() as usize,
2963 ))
2964 }
2965 pub fn get_new_ifindex(&self) -> Result<i32, ErrorContext> {
2966 let mut iter = self.clone();
2967 iter.pos = 0;
2968 for attr in iter {
2969 if let LinkAttrs::NewIfindex(val) = attr? {
2970 return Ok(val);
2971 }
2972 }
2973 Err(ErrorContext::new_missing(
2974 "LinkAttrs",
2975 "NewIfindex",
2976 self.orig_loc,
2977 self.buf.as_ptr() as usize,
2978 ))
2979 }
2980 pub fn get_min_mtu(&self) -> Result<u32, ErrorContext> {
2981 let mut iter = self.clone();
2982 iter.pos = 0;
2983 for attr in iter {
2984 if let LinkAttrs::MinMtu(val) = attr? {
2985 return Ok(val);
2986 }
2987 }
2988 Err(ErrorContext::new_missing(
2989 "LinkAttrs",
2990 "MinMtu",
2991 self.orig_loc,
2992 self.buf.as_ptr() as usize,
2993 ))
2994 }
2995 pub fn get_max_mtu(&self) -> Result<u32, ErrorContext> {
2996 let mut iter = self.clone();
2997 iter.pos = 0;
2998 for attr in iter {
2999 if let LinkAttrs::MaxMtu(val) = attr? {
3000 return Ok(val);
3001 }
3002 }
3003 Err(ErrorContext::new_missing(
3004 "LinkAttrs",
3005 "MaxMtu",
3006 self.orig_loc,
3007 self.buf.as_ptr() as usize,
3008 ))
3009 }
3010 pub fn get_prop_list(&self) -> Result<IterablePropListLinkAttrs<'a>, ErrorContext> {
3011 let mut iter = self.clone();
3012 iter.pos = 0;
3013 for attr in iter {
3014 if let LinkAttrs::PropList(val) = attr? {
3015 return Ok(val);
3016 }
3017 }
3018 Err(ErrorContext::new_missing(
3019 "LinkAttrs",
3020 "PropList",
3021 self.orig_loc,
3022 self.buf.as_ptr() as usize,
3023 ))
3024 }
3025 pub fn get_alt_ifname(&self) -> Result<&'a CStr, ErrorContext> {
3026 let mut iter = self.clone();
3027 iter.pos = 0;
3028 for attr in iter {
3029 if let LinkAttrs::AltIfname(val) = attr? {
3030 return Ok(val);
3031 }
3032 }
3033 Err(ErrorContext::new_missing(
3034 "LinkAttrs",
3035 "AltIfname",
3036 self.orig_loc,
3037 self.buf.as_ptr() as usize,
3038 ))
3039 }
3040 pub fn get_perm_address(&self) -> Result<&'a [u8], ErrorContext> {
3041 let mut iter = self.clone();
3042 iter.pos = 0;
3043 for attr in iter {
3044 if let LinkAttrs::PermAddress(val) = attr? {
3045 return Ok(val);
3046 }
3047 }
3048 Err(ErrorContext::new_missing(
3049 "LinkAttrs",
3050 "PermAddress",
3051 self.orig_loc,
3052 self.buf.as_ptr() as usize,
3053 ))
3054 }
3055 pub fn get_proto_down_reason(&self) -> Result<&'a CStr, ErrorContext> {
3056 let mut iter = self.clone();
3057 iter.pos = 0;
3058 for attr in iter {
3059 if let LinkAttrs::ProtoDownReason(val) = attr? {
3060 return Ok(val);
3061 }
3062 }
3063 Err(ErrorContext::new_missing(
3064 "LinkAttrs",
3065 "ProtoDownReason",
3066 self.orig_loc,
3067 self.buf.as_ptr() as usize,
3068 ))
3069 }
3070 pub fn get_parent_dev_name(&self) -> Result<&'a CStr, ErrorContext> {
3071 let mut iter = self.clone();
3072 iter.pos = 0;
3073 for attr in iter {
3074 if let LinkAttrs::ParentDevName(val) = attr? {
3075 return Ok(val);
3076 }
3077 }
3078 Err(ErrorContext::new_missing(
3079 "LinkAttrs",
3080 "ParentDevName",
3081 self.orig_loc,
3082 self.buf.as_ptr() as usize,
3083 ))
3084 }
3085 pub fn get_parent_dev_bus_name(&self) -> Result<&'a CStr, ErrorContext> {
3086 let mut iter = self.clone();
3087 iter.pos = 0;
3088 for attr in iter {
3089 if let LinkAttrs::ParentDevBusName(val) = attr? {
3090 return Ok(val);
3091 }
3092 }
3093 Err(ErrorContext::new_missing(
3094 "LinkAttrs",
3095 "ParentDevBusName",
3096 self.orig_loc,
3097 self.buf.as_ptr() as usize,
3098 ))
3099 }
3100 pub fn get_gro_max_size(&self) -> Result<u32, ErrorContext> {
3101 let mut iter = self.clone();
3102 iter.pos = 0;
3103 for attr in iter {
3104 if let LinkAttrs::GroMaxSize(val) = attr? {
3105 return Ok(val);
3106 }
3107 }
3108 Err(ErrorContext::new_missing(
3109 "LinkAttrs",
3110 "GroMaxSize",
3111 self.orig_loc,
3112 self.buf.as_ptr() as usize,
3113 ))
3114 }
3115 pub fn get_tso_max_size(&self) -> Result<u32, ErrorContext> {
3116 let mut iter = self.clone();
3117 iter.pos = 0;
3118 for attr in iter {
3119 if let LinkAttrs::TsoMaxSize(val) = attr? {
3120 return Ok(val);
3121 }
3122 }
3123 Err(ErrorContext::new_missing(
3124 "LinkAttrs",
3125 "TsoMaxSize",
3126 self.orig_loc,
3127 self.buf.as_ptr() as usize,
3128 ))
3129 }
3130 pub fn get_tso_max_segs(&self) -> Result<u32, ErrorContext> {
3131 let mut iter = self.clone();
3132 iter.pos = 0;
3133 for attr in iter {
3134 if let LinkAttrs::TsoMaxSegs(val) = attr? {
3135 return Ok(val);
3136 }
3137 }
3138 Err(ErrorContext::new_missing(
3139 "LinkAttrs",
3140 "TsoMaxSegs",
3141 self.orig_loc,
3142 self.buf.as_ptr() as usize,
3143 ))
3144 }
3145 pub fn get_allmulti(&self) -> Result<u32, ErrorContext> {
3146 let mut iter = self.clone();
3147 iter.pos = 0;
3148 for attr in iter {
3149 if let LinkAttrs::Allmulti(val) = attr? {
3150 return Ok(val);
3151 }
3152 }
3153 Err(ErrorContext::new_missing(
3154 "LinkAttrs",
3155 "Allmulti",
3156 self.orig_loc,
3157 self.buf.as_ptr() as usize,
3158 ))
3159 }
3160 pub fn get_devlink_port(&self) -> Result<&'a [u8], ErrorContext> {
3161 let mut iter = self.clone();
3162 iter.pos = 0;
3163 for attr in iter {
3164 if let LinkAttrs::DevlinkPort(val) = attr? {
3165 return Ok(val);
3166 }
3167 }
3168 Err(ErrorContext::new_missing(
3169 "LinkAttrs",
3170 "DevlinkPort",
3171 self.orig_loc,
3172 self.buf.as_ptr() as usize,
3173 ))
3174 }
3175 pub fn get_gso_ipv4_max_size(&self) -> Result<u32, ErrorContext> {
3176 let mut iter = self.clone();
3177 iter.pos = 0;
3178 for attr in iter {
3179 if let LinkAttrs::GsoIpv4MaxSize(val) = attr? {
3180 return Ok(val);
3181 }
3182 }
3183 Err(ErrorContext::new_missing(
3184 "LinkAttrs",
3185 "GsoIpv4MaxSize",
3186 self.orig_loc,
3187 self.buf.as_ptr() as usize,
3188 ))
3189 }
3190 pub fn get_gro_ipv4_max_size(&self) -> Result<u32, ErrorContext> {
3191 let mut iter = self.clone();
3192 iter.pos = 0;
3193 for attr in iter {
3194 if let LinkAttrs::GroIpv4MaxSize(val) = attr? {
3195 return Ok(val);
3196 }
3197 }
3198 Err(ErrorContext::new_missing(
3199 "LinkAttrs",
3200 "GroIpv4MaxSize",
3201 self.orig_loc,
3202 self.buf.as_ptr() as usize,
3203 ))
3204 }
3205 pub fn get_dpll_pin(&self) -> Result<IterableLinkDpllPinAttrs<'a>, ErrorContext> {
3206 let mut iter = self.clone();
3207 iter.pos = 0;
3208 for attr in iter {
3209 if let LinkAttrs::DpllPin(val) = attr? {
3210 return Ok(val);
3211 }
3212 }
3213 Err(ErrorContext::new_missing(
3214 "LinkAttrs",
3215 "DpllPin",
3216 self.orig_loc,
3217 self.buf.as_ptr() as usize,
3218 ))
3219 }
3220 #[doc = "EDT offload horizon supported by the device (in nsec)\\."]
3221 pub fn get_max_pacing_offload_horizon(&self) -> Result<u32, ErrorContext> {
3222 let mut iter = self.clone();
3223 iter.pos = 0;
3224 for attr in iter {
3225 if let LinkAttrs::MaxPacingOffloadHorizon(val) = attr? {
3226 return Ok(val);
3227 }
3228 }
3229 Err(ErrorContext::new_missing(
3230 "LinkAttrs",
3231 "MaxPacingOffloadHorizon",
3232 self.orig_loc,
3233 self.buf.as_ptr() as usize,
3234 ))
3235 }
3236 pub fn get_netns_immutable(&self) -> Result<u8, ErrorContext> {
3237 let mut iter = self.clone();
3238 iter.pos = 0;
3239 for attr in iter {
3240 if let LinkAttrs::NetnsImmutable(val) = attr? {
3241 return Ok(val);
3242 }
3243 }
3244 Err(ErrorContext::new_missing(
3245 "LinkAttrs",
3246 "NetnsImmutable",
3247 self.orig_loc,
3248 self.buf.as_ptr() as usize,
3249 ))
3250 }
3251 pub fn get_headroom(&self) -> Result<u16, ErrorContext> {
3252 let mut iter = self.clone();
3253 iter.pos = 0;
3254 for attr in iter {
3255 if let LinkAttrs::Headroom(val) = attr? {
3256 return Ok(val);
3257 }
3258 }
3259 Err(ErrorContext::new_missing(
3260 "LinkAttrs",
3261 "Headroom",
3262 self.orig_loc,
3263 self.buf.as_ptr() as usize,
3264 ))
3265 }
3266 pub fn get_tailroom(&self) -> Result<u16, ErrorContext> {
3267 let mut iter = self.clone();
3268 iter.pos = 0;
3269 for attr in iter {
3270 if let LinkAttrs::Tailroom(val) = attr? {
3271 return Ok(val);
3272 }
3273 }
3274 Err(ErrorContext::new_missing(
3275 "LinkAttrs",
3276 "Tailroom",
3277 self.orig_loc,
3278 self.buf.as_ptr() as usize,
3279 ))
3280 }
3281}
3282impl LinkAttrs<'_> {
3283 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkAttrs<'a> {
3284 IterableLinkAttrs::with_loc(buf, buf.as_ptr() as usize)
3285 }
3286 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3287 let res = match r#type {
3288 1u16 => "Address",
3289 2u16 => "Broadcast",
3290 3u16 => "Ifname",
3291 4u16 => "Mtu",
3292 5u16 => "Link",
3293 6u16 => "Qdisc",
3294 7u16 => "Stats",
3295 8u16 => "Cost",
3296 9u16 => "Priority",
3297 10u16 => "Master",
3298 11u16 => "Wireless",
3299 12u16 => "Protinfo",
3300 13u16 => "Txqlen",
3301 14u16 => "Map",
3302 15u16 => "Weight",
3303 16u16 => "Operstate",
3304 17u16 => "Linkmode",
3305 18u16 => "Linkinfo",
3306 19u16 => "NetNsPid",
3307 20u16 => "Ifalias",
3308 21u16 => "NumVf",
3309 22u16 => "VfinfoList",
3310 23u16 => "Stats64",
3311 24u16 => "VfPorts",
3312 25u16 => "PortSelf",
3313 26u16 => "AfSpec",
3314 27u16 => "Group",
3315 28u16 => "NetNsFd",
3316 29u16 => "ExtMask",
3317 30u16 => "Promiscuity",
3318 31u16 => "NumTxQueues",
3319 32u16 => "NumRxQueues",
3320 33u16 => "Carrier",
3321 34u16 => "PhysPortId",
3322 35u16 => "CarrierChanges",
3323 36u16 => "PhysSwitchId",
3324 37u16 => "LinkNetnsid",
3325 38u16 => "PhysPortName",
3326 39u16 => "ProtoDown",
3327 40u16 => "GsoMaxSegs",
3328 41u16 => "GsoMaxSize",
3329 42u16 => "Pad",
3330 43u16 => "Xdp",
3331 44u16 => "Event",
3332 45u16 => "NewNetnsid",
3333 46u16 => "TargetNetnsid",
3334 47u16 => "CarrierUpCount",
3335 48u16 => "CarrierDownCount",
3336 49u16 => "NewIfindex",
3337 50u16 => "MinMtu",
3338 51u16 => "MaxMtu",
3339 52u16 => "PropList",
3340 53u16 => "AltIfname",
3341 54u16 => "PermAddress",
3342 55u16 => "ProtoDownReason",
3343 56u16 => "ParentDevName",
3344 57u16 => "ParentDevBusName",
3345 58u16 => "GroMaxSize",
3346 59u16 => "TsoMaxSize",
3347 60u16 => "TsoMaxSegs",
3348 61u16 => "Allmulti",
3349 62u16 => "DevlinkPort",
3350 63u16 => "GsoIpv4MaxSize",
3351 64u16 => "GroIpv4MaxSize",
3352 65u16 => "DpllPin",
3353 66u16 => "MaxPacingOffloadHorizon",
3354 67u16 => "NetnsImmutable",
3355 68u16 => "Headroom",
3356 69u16 => "Tailroom",
3357 _ => return None,
3358 };
3359 Some(res)
3360 }
3361}
3362#[derive(Clone, Copy, Default)]
3363pub struct IterableLinkAttrs<'a> {
3364 buf: &'a [u8],
3365 pos: usize,
3366 orig_loc: usize,
3367}
3368impl<'a> IterableLinkAttrs<'a> {
3369 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3370 Self {
3371 buf,
3372 pos: 0,
3373 orig_loc,
3374 }
3375 }
3376 pub fn get_buf(&self) -> &'a [u8] {
3377 self.buf
3378 }
3379}
3380impl<'a> Iterator for IterableLinkAttrs<'a> {
3381 type Item = Result<LinkAttrs<'a>, ErrorContext>;
3382 fn next(&mut self) -> Option<Self::Item> {
3383 let pos = self.pos;
3384 let mut r#type;
3385 loop {
3386 r#type = None;
3387 if self.buf.len() == self.pos {
3388 return None;
3389 }
3390 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3391 break;
3392 };
3393 r#type = Some(header.r#type);
3394 let res = match header.r#type {
3395 1u16 => LinkAttrs::Address({
3396 let res = Some(next);
3397 let Some(val) = res else { break };
3398 val
3399 }),
3400 2u16 => LinkAttrs::Broadcast({
3401 let res = Some(next);
3402 let Some(val) = res else { break };
3403 val
3404 }),
3405 3u16 => LinkAttrs::Ifname({
3406 let res = CStr::from_bytes_with_nul(next).ok();
3407 let Some(val) = res else { break };
3408 val
3409 }),
3410 4u16 => LinkAttrs::Mtu({
3411 let res = parse_u32(next);
3412 let Some(val) = res else { break };
3413 val
3414 }),
3415 5u16 => LinkAttrs::Link({
3416 let res = parse_u32(next);
3417 let Some(val) = res else { break };
3418 val
3419 }),
3420 6u16 => LinkAttrs::Qdisc({
3421 let res = CStr::from_bytes_with_nul(next).ok();
3422 let Some(val) = res else { break };
3423 val
3424 }),
3425 7u16 => LinkAttrs::Stats({
3426 let res = Some(RtnlLinkStats::new_from_zeroed(next));
3427 let Some(val) = res else { break };
3428 val
3429 }),
3430 8u16 => LinkAttrs::Cost({
3431 let res = CStr::from_bytes_with_nul(next).ok();
3432 let Some(val) = res else { break };
3433 val
3434 }),
3435 9u16 => LinkAttrs::Priority({
3436 let res = CStr::from_bytes_with_nul(next).ok();
3437 let Some(val) = res else { break };
3438 val
3439 }),
3440 10u16 => LinkAttrs::Master({
3441 let res = parse_u32(next);
3442 let Some(val) = res else { break };
3443 val
3444 }),
3445 11u16 => LinkAttrs::Wireless({
3446 let res = CStr::from_bytes_with_nul(next).ok();
3447 let Some(val) = res else { break };
3448 val
3449 }),
3450 12u16 => LinkAttrs::Protinfo({
3451 let res = CStr::from_bytes_with_nul(next).ok();
3452 let Some(val) = res else { break };
3453 val
3454 }),
3455 13u16 => LinkAttrs::Txqlen({
3456 let res = parse_u32(next);
3457 let Some(val) = res else { break };
3458 val
3459 }),
3460 14u16 => LinkAttrs::Map({
3461 let res = Some(RtnlLinkIfmap::new_from_zeroed(next));
3462 let Some(val) = res else { break };
3463 val
3464 }),
3465 15u16 => LinkAttrs::Weight({
3466 let res = parse_u32(next);
3467 let Some(val) = res else { break };
3468 val
3469 }),
3470 16u16 => LinkAttrs::Operstate({
3471 let res = parse_u8(next);
3472 let Some(val) = res else { break };
3473 val
3474 }),
3475 17u16 => LinkAttrs::Linkmode({
3476 let res = parse_u8(next);
3477 let Some(val) = res else { break };
3478 val
3479 }),
3480 18u16 => LinkAttrs::Linkinfo({
3481 let res = Some(IterableLinkinfoAttrs::with_loc(next, self.orig_loc));
3482 let Some(val) = res else { break };
3483 val
3484 }),
3485 19u16 => LinkAttrs::NetNsPid({
3486 let res = parse_u32(next);
3487 let Some(val) = res else { break };
3488 val
3489 }),
3490 20u16 => LinkAttrs::Ifalias({
3491 let res = CStr::from_bytes_with_nul(next).ok();
3492 let Some(val) = res else { break };
3493 val
3494 }),
3495 21u16 => LinkAttrs::NumVf({
3496 let res = parse_u32(next);
3497 let Some(val) = res else { break };
3498 val
3499 }),
3500 22u16 => LinkAttrs::VfinfoList({
3501 let res = Some(IterableVfinfoListAttrs::with_loc(next, self.orig_loc));
3502 let Some(val) = res else { break };
3503 val
3504 }),
3505 23u16 => LinkAttrs::Stats64({
3506 let res = Some(RtnlLinkStats64::new_from_zeroed(next));
3507 let Some(val) = res else { break };
3508 val
3509 }),
3510 24u16 => LinkAttrs::VfPorts({
3511 let res = Some(IterableVfPortsAttrs::with_loc(next, self.orig_loc));
3512 let Some(val) = res else { break };
3513 val
3514 }),
3515 25u16 => LinkAttrs::PortSelf({
3516 let res = Some(IterablePortSelfAttrs::with_loc(next, self.orig_loc));
3517 let Some(val) = res else { break };
3518 val
3519 }),
3520 26u16 => LinkAttrs::AfSpec({
3521 let res = Some(IterableAfSpecAttrs::with_loc(next, self.orig_loc));
3522 let Some(val) = res else { break };
3523 val
3524 }),
3525 27u16 => LinkAttrs::Group({
3526 let res = parse_u32(next);
3527 let Some(val) = res else { break };
3528 val
3529 }),
3530 28u16 => LinkAttrs::NetNsFd({
3531 let res = parse_u32(next);
3532 let Some(val) = res else { break };
3533 val
3534 }),
3535 29u16 => LinkAttrs::ExtMask({
3536 let res = parse_u32(next);
3537 let Some(val) = res else { break };
3538 val
3539 }),
3540 30u16 => LinkAttrs::Promiscuity({
3541 let res = parse_u32(next);
3542 let Some(val) = res else { break };
3543 val
3544 }),
3545 31u16 => LinkAttrs::NumTxQueues({
3546 let res = parse_u32(next);
3547 let Some(val) = res else { break };
3548 val
3549 }),
3550 32u16 => LinkAttrs::NumRxQueues({
3551 let res = parse_u32(next);
3552 let Some(val) = res else { break };
3553 val
3554 }),
3555 33u16 => LinkAttrs::Carrier({
3556 let res = parse_u8(next);
3557 let Some(val) = res else { break };
3558 val
3559 }),
3560 34u16 => LinkAttrs::PhysPortId({
3561 let res = Some(next);
3562 let Some(val) = res else { break };
3563 val
3564 }),
3565 35u16 => LinkAttrs::CarrierChanges({
3566 let res = parse_u32(next);
3567 let Some(val) = res else { break };
3568 val
3569 }),
3570 36u16 => LinkAttrs::PhysSwitchId({
3571 let res = Some(next);
3572 let Some(val) = res else { break };
3573 val
3574 }),
3575 37u16 => LinkAttrs::LinkNetnsid({
3576 let res = parse_i32(next);
3577 let Some(val) = res else { break };
3578 val
3579 }),
3580 38u16 => LinkAttrs::PhysPortName({
3581 let res = CStr::from_bytes_with_nul(next).ok();
3582 let Some(val) = res else { break };
3583 val
3584 }),
3585 39u16 => LinkAttrs::ProtoDown({
3586 let res = parse_u8(next);
3587 let Some(val) = res else { break };
3588 val
3589 }),
3590 40u16 => LinkAttrs::GsoMaxSegs({
3591 let res = parse_u32(next);
3592 let Some(val) = res else { break };
3593 val
3594 }),
3595 41u16 => LinkAttrs::GsoMaxSize({
3596 let res = parse_u32(next);
3597 let Some(val) = res else { break };
3598 val
3599 }),
3600 42u16 => LinkAttrs::Pad({
3601 let res = Some(next);
3602 let Some(val) = res else { break };
3603 val
3604 }),
3605 43u16 => LinkAttrs::Xdp({
3606 let res = Some(IterableXdpAttrs::with_loc(next, self.orig_loc));
3607 let Some(val) = res else { break };
3608 val
3609 }),
3610 44u16 => LinkAttrs::Event({
3611 let res = parse_u32(next);
3612 let Some(val) = res else { break };
3613 val
3614 }),
3615 45u16 => LinkAttrs::NewNetnsid({
3616 let res = parse_i32(next);
3617 let Some(val) = res else { break };
3618 val
3619 }),
3620 46u16 => LinkAttrs::TargetNetnsid({
3621 let res = parse_i32(next);
3622 let Some(val) = res else { break };
3623 val
3624 }),
3625 47u16 => LinkAttrs::CarrierUpCount({
3626 let res = parse_u32(next);
3627 let Some(val) = res else { break };
3628 val
3629 }),
3630 48u16 => LinkAttrs::CarrierDownCount({
3631 let res = parse_u32(next);
3632 let Some(val) = res else { break };
3633 val
3634 }),
3635 49u16 => LinkAttrs::NewIfindex({
3636 let res = parse_i32(next);
3637 let Some(val) = res else { break };
3638 val
3639 }),
3640 50u16 => LinkAttrs::MinMtu({
3641 let res = parse_u32(next);
3642 let Some(val) = res else { break };
3643 val
3644 }),
3645 51u16 => LinkAttrs::MaxMtu({
3646 let res = parse_u32(next);
3647 let Some(val) = res else { break };
3648 val
3649 }),
3650 52u16 => LinkAttrs::PropList({
3651 let res = Some(IterablePropListLinkAttrs::with_loc(next, self.orig_loc));
3652 let Some(val) = res else { break };
3653 val
3654 }),
3655 53u16 => LinkAttrs::AltIfname({
3656 let res = CStr::from_bytes_with_nul(next).ok();
3657 let Some(val) = res else { break };
3658 val
3659 }),
3660 54u16 => LinkAttrs::PermAddress({
3661 let res = Some(next);
3662 let Some(val) = res else { break };
3663 val
3664 }),
3665 55u16 => LinkAttrs::ProtoDownReason({
3666 let res = CStr::from_bytes_with_nul(next).ok();
3667 let Some(val) = res else { break };
3668 val
3669 }),
3670 56u16 => LinkAttrs::ParentDevName({
3671 let res = CStr::from_bytes_with_nul(next).ok();
3672 let Some(val) = res else { break };
3673 val
3674 }),
3675 57u16 => LinkAttrs::ParentDevBusName({
3676 let res = CStr::from_bytes_with_nul(next).ok();
3677 let Some(val) = res else { break };
3678 val
3679 }),
3680 58u16 => LinkAttrs::GroMaxSize({
3681 let res = parse_u32(next);
3682 let Some(val) = res else { break };
3683 val
3684 }),
3685 59u16 => LinkAttrs::TsoMaxSize({
3686 let res = parse_u32(next);
3687 let Some(val) = res else { break };
3688 val
3689 }),
3690 60u16 => LinkAttrs::TsoMaxSegs({
3691 let res = parse_u32(next);
3692 let Some(val) = res else { break };
3693 val
3694 }),
3695 61u16 => LinkAttrs::Allmulti({
3696 let res = parse_u32(next);
3697 let Some(val) = res else { break };
3698 val
3699 }),
3700 62u16 => LinkAttrs::DevlinkPort({
3701 let res = Some(next);
3702 let Some(val) = res else { break };
3703 val
3704 }),
3705 63u16 => LinkAttrs::GsoIpv4MaxSize({
3706 let res = parse_u32(next);
3707 let Some(val) = res else { break };
3708 val
3709 }),
3710 64u16 => LinkAttrs::GroIpv4MaxSize({
3711 let res = parse_u32(next);
3712 let Some(val) = res else { break };
3713 val
3714 }),
3715 65u16 => LinkAttrs::DpllPin({
3716 let res = Some(IterableLinkDpllPinAttrs::with_loc(next, self.orig_loc));
3717 let Some(val) = res else { break };
3718 val
3719 }),
3720 66u16 => LinkAttrs::MaxPacingOffloadHorizon({
3721 let res = parse_u32(next);
3722 let Some(val) = res else { break };
3723 val
3724 }),
3725 67u16 => LinkAttrs::NetnsImmutable({
3726 let res = parse_u8(next);
3727 let Some(val) = res else { break };
3728 val
3729 }),
3730 68u16 => LinkAttrs::Headroom({
3731 let res = parse_u16(next);
3732 let Some(val) = res else { break };
3733 val
3734 }),
3735 69u16 => LinkAttrs::Tailroom({
3736 let res = parse_u16(next);
3737 let Some(val) = res else { break };
3738 val
3739 }),
3740 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3741 n => continue,
3742 };
3743 return Some(Ok(res));
3744 }
3745 Some(Err(ErrorContext::new(
3746 "LinkAttrs",
3747 r#type.and_then(|t| LinkAttrs::attr_from_type(t)),
3748 self.orig_loc,
3749 self.buf.as_ptr().wrapping_add(pos) as usize,
3750 )))
3751 }
3752}
3753impl<'a> std::fmt::Debug for IterableLinkAttrs<'_> {
3754 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3755 let mut fmt = f.debug_struct("LinkAttrs");
3756 for attr in self.clone() {
3757 let attr = match attr {
3758 Ok(a) => a,
3759 Err(err) => {
3760 fmt.finish()?;
3761 f.write_str("Err(")?;
3762 err.fmt(f)?;
3763 return f.write_str(")");
3764 }
3765 };
3766 match attr {
3767 LinkAttrs::Address(val) => fmt.field("Address", &FormatMac(val)),
3768 LinkAttrs::Broadcast(val) => fmt.field("Broadcast", &FormatMac(val)),
3769 LinkAttrs::Ifname(val) => fmt.field("Ifname", &val),
3770 LinkAttrs::Mtu(val) => fmt.field("Mtu", &val),
3771 LinkAttrs::Link(val) => fmt.field("Link", &val),
3772 LinkAttrs::Qdisc(val) => fmt.field("Qdisc", &val),
3773 LinkAttrs::Stats(val) => fmt.field("Stats", &val),
3774 LinkAttrs::Cost(val) => fmt.field("Cost", &val),
3775 LinkAttrs::Priority(val) => fmt.field("Priority", &val),
3776 LinkAttrs::Master(val) => fmt.field("Master", &val),
3777 LinkAttrs::Wireless(val) => fmt.field("Wireless", &val),
3778 LinkAttrs::Protinfo(val) => fmt.field("Protinfo", &val),
3779 LinkAttrs::Txqlen(val) => fmt.field("Txqlen", &val),
3780 LinkAttrs::Map(val) => fmt.field("Map", &val),
3781 LinkAttrs::Weight(val) => fmt.field("Weight", &val),
3782 LinkAttrs::Operstate(val) => fmt.field("Operstate", &val),
3783 LinkAttrs::Linkmode(val) => fmt.field("Linkmode", &val),
3784 LinkAttrs::Linkinfo(val) => fmt.field("Linkinfo", &val),
3785 LinkAttrs::NetNsPid(val) => fmt.field("NetNsPid", &val),
3786 LinkAttrs::Ifalias(val) => fmt.field("Ifalias", &val),
3787 LinkAttrs::NumVf(val) => fmt.field("NumVf", &val),
3788 LinkAttrs::VfinfoList(val) => fmt.field("VfinfoList", &val),
3789 LinkAttrs::Stats64(val) => fmt.field("Stats64", &val),
3790 LinkAttrs::VfPorts(val) => fmt.field("VfPorts", &val),
3791 LinkAttrs::PortSelf(val) => fmt.field("PortSelf", &val),
3792 LinkAttrs::AfSpec(val) => fmt.field("AfSpec", &val),
3793 LinkAttrs::Group(val) => fmt.field("Group", &val),
3794 LinkAttrs::NetNsFd(val) => fmt.field("NetNsFd", &val),
3795 LinkAttrs::ExtMask(val) => {
3796 fmt.field("ExtMask", &FormatFlags(val.into(), RtextFilter::from_value))
3797 }
3798 LinkAttrs::Promiscuity(val) => fmt.field("Promiscuity", &val),
3799 LinkAttrs::NumTxQueues(val) => fmt.field("NumTxQueues", &val),
3800 LinkAttrs::NumRxQueues(val) => fmt.field("NumRxQueues", &val),
3801 LinkAttrs::Carrier(val) => fmt.field("Carrier", &val),
3802 LinkAttrs::PhysPortId(val) => fmt.field("PhysPortId", &val),
3803 LinkAttrs::CarrierChanges(val) => fmt.field("CarrierChanges", &val),
3804 LinkAttrs::PhysSwitchId(val) => fmt.field("PhysSwitchId", &val),
3805 LinkAttrs::LinkNetnsid(val) => fmt.field("LinkNetnsid", &val),
3806 LinkAttrs::PhysPortName(val) => fmt.field("PhysPortName", &val),
3807 LinkAttrs::ProtoDown(val) => fmt.field("ProtoDown", &val),
3808 LinkAttrs::GsoMaxSegs(val) => fmt.field("GsoMaxSegs", &val),
3809 LinkAttrs::GsoMaxSize(val) => fmt.field("GsoMaxSize", &val),
3810 LinkAttrs::Pad(val) => fmt.field("Pad", &val),
3811 LinkAttrs::Xdp(val) => fmt.field("Xdp", &val),
3812 LinkAttrs::Event(val) => fmt.field("Event", &val),
3813 LinkAttrs::NewNetnsid(val) => fmt.field("NewNetnsid", &val),
3814 LinkAttrs::TargetNetnsid(val) => fmt.field("TargetNetnsid", &val),
3815 LinkAttrs::CarrierUpCount(val) => fmt.field("CarrierUpCount", &val),
3816 LinkAttrs::CarrierDownCount(val) => fmt.field("CarrierDownCount", &val),
3817 LinkAttrs::NewIfindex(val) => fmt.field("NewIfindex", &val),
3818 LinkAttrs::MinMtu(val) => fmt.field("MinMtu", &val),
3819 LinkAttrs::MaxMtu(val) => fmt.field("MaxMtu", &val),
3820 LinkAttrs::PropList(val) => fmt.field("PropList", &val),
3821 LinkAttrs::AltIfname(val) => fmt.field("AltIfname", &val),
3822 LinkAttrs::PermAddress(val) => fmt.field("PermAddress", &FormatMac(val)),
3823 LinkAttrs::ProtoDownReason(val) => fmt.field("ProtoDownReason", &val),
3824 LinkAttrs::ParentDevName(val) => fmt.field("ParentDevName", &val),
3825 LinkAttrs::ParentDevBusName(val) => fmt.field("ParentDevBusName", &val),
3826 LinkAttrs::GroMaxSize(val) => fmt.field("GroMaxSize", &val),
3827 LinkAttrs::TsoMaxSize(val) => fmt.field("TsoMaxSize", &val),
3828 LinkAttrs::TsoMaxSegs(val) => fmt.field("TsoMaxSegs", &val),
3829 LinkAttrs::Allmulti(val) => fmt.field("Allmulti", &val),
3830 LinkAttrs::DevlinkPort(val) => fmt.field("DevlinkPort", &val),
3831 LinkAttrs::GsoIpv4MaxSize(val) => fmt.field("GsoIpv4MaxSize", &val),
3832 LinkAttrs::GroIpv4MaxSize(val) => fmt.field("GroIpv4MaxSize", &val),
3833 LinkAttrs::DpllPin(val) => fmt.field("DpllPin", &val),
3834 LinkAttrs::MaxPacingOffloadHorizon(val) => {
3835 fmt.field("MaxPacingOffloadHorizon", &val)
3836 }
3837 LinkAttrs::NetnsImmutable(val) => fmt.field("NetnsImmutable", &val),
3838 LinkAttrs::Headroom(val) => fmt.field("Headroom", &val),
3839 LinkAttrs::Tailroom(val) => fmt.field("Tailroom", &val),
3840 };
3841 }
3842 fmt.finish()
3843 }
3844}
3845impl IterableLinkAttrs<'_> {
3846 pub fn lookup_attr(
3847 &self,
3848 offset: usize,
3849 missing_type: Option<u16>,
3850 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3851 let mut stack = Vec::new();
3852 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3853 if missing_type.is_some() && cur == offset {
3854 stack.push(("LinkAttrs", offset));
3855 return (
3856 stack,
3857 missing_type.and_then(|t| LinkAttrs::attr_from_type(t)),
3858 );
3859 }
3860 if cur > offset || cur + self.buf.len() < offset {
3861 return (stack, None);
3862 }
3863 let mut attrs = self.clone();
3864 let mut last_off = cur + attrs.pos;
3865 let mut missing = None;
3866 while let Some(attr) = attrs.next() {
3867 let Ok(attr) = attr else { break };
3868 match attr {
3869 LinkAttrs::Address(val) => {
3870 if last_off == offset {
3871 stack.push(("Address", last_off));
3872 break;
3873 }
3874 }
3875 LinkAttrs::Broadcast(val) => {
3876 if last_off == offset {
3877 stack.push(("Broadcast", last_off));
3878 break;
3879 }
3880 }
3881 LinkAttrs::Ifname(val) => {
3882 if last_off == offset {
3883 stack.push(("Ifname", last_off));
3884 break;
3885 }
3886 }
3887 LinkAttrs::Mtu(val) => {
3888 if last_off == offset {
3889 stack.push(("Mtu", last_off));
3890 break;
3891 }
3892 }
3893 LinkAttrs::Link(val) => {
3894 if last_off == offset {
3895 stack.push(("Link", last_off));
3896 break;
3897 }
3898 }
3899 LinkAttrs::Qdisc(val) => {
3900 if last_off == offset {
3901 stack.push(("Qdisc", last_off));
3902 break;
3903 }
3904 }
3905 LinkAttrs::Stats(val) => {
3906 if last_off == offset {
3907 stack.push(("Stats", last_off));
3908 break;
3909 }
3910 }
3911 LinkAttrs::Cost(val) => {
3912 if last_off == offset {
3913 stack.push(("Cost", last_off));
3914 break;
3915 }
3916 }
3917 LinkAttrs::Priority(val) => {
3918 if last_off == offset {
3919 stack.push(("Priority", last_off));
3920 break;
3921 }
3922 }
3923 LinkAttrs::Master(val) => {
3924 if last_off == offset {
3925 stack.push(("Master", last_off));
3926 break;
3927 }
3928 }
3929 LinkAttrs::Wireless(val) => {
3930 if last_off == offset {
3931 stack.push(("Wireless", last_off));
3932 break;
3933 }
3934 }
3935 LinkAttrs::Protinfo(val) => {
3936 if last_off == offset {
3937 stack.push(("Protinfo", last_off));
3938 break;
3939 }
3940 }
3941 LinkAttrs::Txqlen(val) => {
3942 if last_off == offset {
3943 stack.push(("Txqlen", last_off));
3944 break;
3945 }
3946 }
3947 LinkAttrs::Map(val) => {
3948 if last_off == offset {
3949 stack.push(("Map", last_off));
3950 break;
3951 }
3952 }
3953 LinkAttrs::Weight(val) => {
3954 if last_off == offset {
3955 stack.push(("Weight", last_off));
3956 break;
3957 }
3958 }
3959 LinkAttrs::Operstate(val) => {
3960 if last_off == offset {
3961 stack.push(("Operstate", last_off));
3962 break;
3963 }
3964 }
3965 LinkAttrs::Linkmode(val) => {
3966 if last_off == offset {
3967 stack.push(("Linkmode", last_off));
3968 break;
3969 }
3970 }
3971 LinkAttrs::Linkinfo(val) => {
3972 (stack, missing) = val.lookup_attr(offset, missing_type);
3973 if !stack.is_empty() {
3974 break;
3975 }
3976 }
3977 LinkAttrs::NetNsPid(val) => {
3978 if last_off == offset {
3979 stack.push(("NetNsPid", last_off));
3980 break;
3981 }
3982 }
3983 LinkAttrs::Ifalias(val) => {
3984 if last_off == offset {
3985 stack.push(("Ifalias", last_off));
3986 break;
3987 }
3988 }
3989 LinkAttrs::NumVf(val) => {
3990 if last_off == offset {
3991 stack.push(("NumVf", last_off));
3992 break;
3993 }
3994 }
3995 LinkAttrs::VfinfoList(val) => {
3996 (stack, missing) = val.lookup_attr(offset, missing_type);
3997 if !stack.is_empty() {
3998 break;
3999 }
4000 }
4001 LinkAttrs::Stats64(val) => {
4002 if last_off == offset {
4003 stack.push(("Stats64", last_off));
4004 break;
4005 }
4006 }
4007 LinkAttrs::VfPorts(val) => {
4008 (stack, missing) = val.lookup_attr(offset, missing_type);
4009 if !stack.is_empty() {
4010 break;
4011 }
4012 }
4013 LinkAttrs::PortSelf(val) => {
4014 (stack, missing) = val.lookup_attr(offset, missing_type);
4015 if !stack.is_empty() {
4016 break;
4017 }
4018 }
4019 LinkAttrs::AfSpec(val) => {
4020 (stack, missing) = val.lookup_attr(offset, missing_type);
4021 if !stack.is_empty() {
4022 break;
4023 }
4024 }
4025 LinkAttrs::Group(val) => {
4026 if last_off == offset {
4027 stack.push(("Group", last_off));
4028 break;
4029 }
4030 }
4031 LinkAttrs::NetNsFd(val) => {
4032 if last_off == offset {
4033 stack.push(("NetNsFd", last_off));
4034 break;
4035 }
4036 }
4037 LinkAttrs::ExtMask(val) => {
4038 if last_off == offset {
4039 stack.push(("ExtMask", last_off));
4040 break;
4041 }
4042 }
4043 LinkAttrs::Promiscuity(val) => {
4044 if last_off == offset {
4045 stack.push(("Promiscuity", last_off));
4046 break;
4047 }
4048 }
4049 LinkAttrs::NumTxQueues(val) => {
4050 if last_off == offset {
4051 stack.push(("NumTxQueues", last_off));
4052 break;
4053 }
4054 }
4055 LinkAttrs::NumRxQueues(val) => {
4056 if last_off == offset {
4057 stack.push(("NumRxQueues", last_off));
4058 break;
4059 }
4060 }
4061 LinkAttrs::Carrier(val) => {
4062 if last_off == offset {
4063 stack.push(("Carrier", last_off));
4064 break;
4065 }
4066 }
4067 LinkAttrs::PhysPortId(val) => {
4068 if last_off == offset {
4069 stack.push(("PhysPortId", last_off));
4070 break;
4071 }
4072 }
4073 LinkAttrs::CarrierChanges(val) => {
4074 if last_off == offset {
4075 stack.push(("CarrierChanges", last_off));
4076 break;
4077 }
4078 }
4079 LinkAttrs::PhysSwitchId(val) => {
4080 if last_off == offset {
4081 stack.push(("PhysSwitchId", last_off));
4082 break;
4083 }
4084 }
4085 LinkAttrs::LinkNetnsid(val) => {
4086 if last_off == offset {
4087 stack.push(("LinkNetnsid", last_off));
4088 break;
4089 }
4090 }
4091 LinkAttrs::PhysPortName(val) => {
4092 if last_off == offset {
4093 stack.push(("PhysPortName", last_off));
4094 break;
4095 }
4096 }
4097 LinkAttrs::ProtoDown(val) => {
4098 if last_off == offset {
4099 stack.push(("ProtoDown", last_off));
4100 break;
4101 }
4102 }
4103 LinkAttrs::GsoMaxSegs(val) => {
4104 if last_off == offset {
4105 stack.push(("GsoMaxSegs", last_off));
4106 break;
4107 }
4108 }
4109 LinkAttrs::GsoMaxSize(val) => {
4110 if last_off == offset {
4111 stack.push(("GsoMaxSize", last_off));
4112 break;
4113 }
4114 }
4115 LinkAttrs::Pad(val) => {
4116 if last_off == offset {
4117 stack.push(("Pad", last_off));
4118 break;
4119 }
4120 }
4121 LinkAttrs::Xdp(val) => {
4122 (stack, missing) = val.lookup_attr(offset, missing_type);
4123 if !stack.is_empty() {
4124 break;
4125 }
4126 }
4127 LinkAttrs::Event(val) => {
4128 if last_off == offset {
4129 stack.push(("Event", last_off));
4130 break;
4131 }
4132 }
4133 LinkAttrs::NewNetnsid(val) => {
4134 if last_off == offset {
4135 stack.push(("NewNetnsid", last_off));
4136 break;
4137 }
4138 }
4139 LinkAttrs::TargetNetnsid(val) => {
4140 if last_off == offset {
4141 stack.push(("TargetNetnsid", last_off));
4142 break;
4143 }
4144 }
4145 LinkAttrs::CarrierUpCount(val) => {
4146 if last_off == offset {
4147 stack.push(("CarrierUpCount", last_off));
4148 break;
4149 }
4150 }
4151 LinkAttrs::CarrierDownCount(val) => {
4152 if last_off == offset {
4153 stack.push(("CarrierDownCount", last_off));
4154 break;
4155 }
4156 }
4157 LinkAttrs::NewIfindex(val) => {
4158 if last_off == offset {
4159 stack.push(("NewIfindex", last_off));
4160 break;
4161 }
4162 }
4163 LinkAttrs::MinMtu(val) => {
4164 if last_off == offset {
4165 stack.push(("MinMtu", last_off));
4166 break;
4167 }
4168 }
4169 LinkAttrs::MaxMtu(val) => {
4170 if last_off == offset {
4171 stack.push(("MaxMtu", last_off));
4172 break;
4173 }
4174 }
4175 LinkAttrs::PropList(val) => {
4176 (stack, missing) = val.lookup_attr(offset, missing_type);
4177 if !stack.is_empty() {
4178 break;
4179 }
4180 }
4181 LinkAttrs::AltIfname(val) => {
4182 if last_off == offset {
4183 stack.push(("AltIfname", last_off));
4184 break;
4185 }
4186 }
4187 LinkAttrs::PermAddress(val) => {
4188 if last_off == offset {
4189 stack.push(("PermAddress", last_off));
4190 break;
4191 }
4192 }
4193 LinkAttrs::ProtoDownReason(val) => {
4194 if last_off == offset {
4195 stack.push(("ProtoDownReason", last_off));
4196 break;
4197 }
4198 }
4199 LinkAttrs::ParentDevName(val) => {
4200 if last_off == offset {
4201 stack.push(("ParentDevName", last_off));
4202 break;
4203 }
4204 }
4205 LinkAttrs::ParentDevBusName(val) => {
4206 if last_off == offset {
4207 stack.push(("ParentDevBusName", last_off));
4208 break;
4209 }
4210 }
4211 LinkAttrs::GroMaxSize(val) => {
4212 if last_off == offset {
4213 stack.push(("GroMaxSize", last_off));
4214 break;
4215 }
4216 }
4217 LinkAttrs::TsoMaxSize(val) => {
4218 if last_off == offset {
4219 stack.push(("TsoMaxSize", last_off));
4220 break;
4221 }
4222 }
4223 LinkAttrs::TsoMaxSegs(val) => {
4224 if last_off == offset {
4225 stack.push(("TsoMaxSegs", last_off));
4226 break;
4227 }
4228 }
4229 LinkAttrs::Allmulti(val) => {
4230 if last_off == offset {
4231 stack.push(("Allmulti", last_off));
4232 break;
4233 }
4234 }
4235 LinkAttrs::DevlinkPort(val) => {
4236 if last_off == offset {
4237 stack.push(("DevlinkPort", last_off));
4238 break;
4239 }
4240 }
4241 LinkAttrs::GsoIpv4MaxSize(val) => {
4242 if last_off == offset {
4243 stack.push(("GsoIpv4MaxSize", last_off));
4244 break;
4245 }
4246 }
4247 LinkAttrs::GroIpv4MaxSize(val) => {
4248 if last_off == offset {
4249 stack.push(("GroIpv4MaxSize", last_off));
4250 break;
4251 }
4252 }
4253 LinkAttrs::DpllPin(val) => {
4254 (stack, missing) = val.lookup_attr(offset, missing_type);
4255 if !stack.is_empty() {
4256 break;
4257 }
4258 }
4259 LinkAttrs::MaxPacingOffloadHorizon(val) => {
4260 if last_off == offset {
4261 stack.push(("MaxPacingOffloadHorizon", last_off));
4262 break;
4263 }
4264 }
4265 LinkAttrs::NetnsImmutable(val) => {
4266 if last_off == offset {
4267 stack.push(("NetnsImmutable", last_off));
4268 break;
4269 }
4270 }
4271 LinkAttrs::Headroom(val) => {
4272 if last_off == offset {
4273 stack.push(("Headroom", last_off));
4274 break;
4275 }
4276 }
4277 LinkAttrs::Tailroom(val) => {
4278 if last_off == offset {
4279 stack.push(("Tailroom", last_off));
4280 break;
4281 }
4282 }
4283 _ => {}
4284 };
4285 last_off = cur + attrs.pos;
4286 }
4287 if !stack.is_empty() {
4288 stack.push(("LinkAttrs", cur));
4289 }
4290 (stack, missing)
4291 }
4292}
4293#[derive(Clone)]
4294pub enum PropListLinkAttrs<'a> {
4295 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4296 AltIfname(&'a CStr),
4297}
4298impl<'a> IterablePropListLinkAttrs<'a> {
4299 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4300 pub fn get_alt_ifname(&self) -> MultiAttrIterable<Self, PropListLinkAttrs<'a>, &'a CStr> {
4301 MultiAttrIterable::new(self.clone(), |variant| {
4302 if let PropListLinkAttrs::AltIfname(val) = variant {
4303 Some(val)
4304 } else {
4305 None
4306 }
4307 })
4308 }
4309}
4310impl PropListLinkAttrs<'_> {
4311 pub fn new<'a>(buf: &'a [u8]) -> IterablePropListLinkAttrs<'a> {
4312 IterablePropListLinkAttrs::with_loc(buf, buf.as_ptr() as usize)
4313 }
4314 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4315 LinkAttrs::attr_from_type(r#type)
4316 }
4317}
4318#[derive(Clone, Copy, Default)]
4319pub struct IterablePropListLinkAttrs<'a> {
4320 buf: &'a [u8],
4321 pos: usize,
4322 orig_loc: usize,
4323}
4324impl<'a> IterablePropListLinkAttrs<'a> {
4325 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4326 Self {
4327 buf,
4328 pos: 0,
4329 orig_loc,
4330 }
4331 }
4332 pub fn get_buf(&self) -> &'a [u8] {
4333 self.buf
4334 }
4335}
4336impl<'a> Iterator for IterablePropListLinkAttrs<'a> {
4337 type Item = Result<PropListLinkAttrs<'a>, ErrorContext>;
4338 fn next(&mut self) -> Option<Self::Item> {
4339 let pos = self.pos;
4340 let mut r#type;
4341 loop {
4342 r#type = None;
4343 if self.buf.len() == self.pos {
4344 return None;
4345 }
4346 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4347 break;
4348 };
4349 r#type = Some(header.r#type);
4350 let res = match header.r#type {
4351 53u16 => PropListLinkAttrs::AltIfname({
4352 let res = CStr::from_bytes_with_nul(next).ok();
4353 let Some(val) = res else { break };
4354 val
4355 }),
4356 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4357 n => continue,
4358 };
4359 return Some(Ok(res));
4360 }
4361 Some(Err(ErrorContext::new(
4362 "PropListLinkAttrs",
4363 r#type.and_then(|t| PropListLinkAttrs::attr_from_type(t)),
4364 self.orig_loc,
4365 self.buf.as_ptr().wrapping_add(pos) as usize,
4366 )))
4367 }
4368}
4369impl<'a> std::fmt::Debug for IterablePropListLinkAttrs<'_> {
4370 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4371 let mut fmt = f.debug_struct("PropListLinkAttrs");
4372 for attr in self.clone() {
4373 let attr = match attr {
4374 Ok(a) => a,
4375 Err(err) => {
4376 fmt.finish()?;
4377 f.write_str("Err(")?;
4378 err.fmt(f)?;
4379 return f.write_str(")");
4380 }
4381 };
4382 match attr {
4383 PropListLinkAttrs::AltIfname(val) => fmt.field("AltIfname", &val),
4384 };
4385 }
4386 fmt.finish()
4387 }
4388}
4389impl IterablePropListLinkAttrs<'_> {
4390 pub fn lookup_attr(
4391 &self,
4392 offset: usize,
4393 missing_type: Option<u16>,
4394 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4395 let mut stack = Vec::new();
4396 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4397 if missing_type.is_some() && cur == offset {
4398 stack.push(("PropListLinkAttrs", offset));
4399 return (
4400 stack,
4401 missing_type.and_then(|t| PropListLinkAttrs::attr_from_type(t)),
4402 );
4403 }
4404 if cur > offset || cur + self.buf.len() < offset {
4405 return (stack, None);
4406 }
4407 let mut attrs = self.clone();
4408 let mut last_off = cur + attrs.pos;
4409 while let Some(attr) = attrs.next() {
4410 let Ok(attr) = attr else { break };
4411 match attr {
4412 PropListLinkAttrs::AltIfname(val) => {
4413 if last_off == offset {
4414 stack.push(("AltIfname", last_off));
4415 break;
4416 }
4417 }
4418 _ => {}
4419 };
4420 last_off = cur + attrs.pos;
4421 }
4422 if !stack.is_empty() {
4423 stack.push(("PropListLinkAttrs", cur));
4424 }
4425 (stack, None)
4426 }
4427}
4428#[derive(Clone)]
4429pub enum AfSpecAttrs<'a> {
4430 Inet(IterableIflaAttrs<'a>),
4431 Inet6(IterableIfla6Attrs<'a>),
4432 Mctp(IterableMctpAttrs<'a>),
4433}
4434impl<'a> IterableAfSpecAttrs<'a> {
4435 pub fn get_inet(&self) -> Result<IterableIflaAttrs<'a>, ErrorContext> {
4436 let mut iter = self.clone();
4437 iter.pos = 0;
4438 for attr in iter {
4439 if let AfSpecAttrs::Inet(val) = attr? {
4440 return Ok(val);
4441 }
4442 }
4443 Err(ErrorContext::new_missing(
4444 "AfSpecAttrs",
4445 "Inet",
4446 self.orig_loc,
4447 self.buf.as_ptr() as usize,
4448 ))
4449 }
4450 pub fn get_inet6(&self) -> Result<IterableIfla6Attrs<'a>, ErrorContext> {
4451 let mut iter = self.clone();
4452 iter.pos = 0;
4453 for attr in iter {
4454 if let AfSpecAttrs::Inet6(val) = attr? {
4455 return Ok(val);
4456 }
4457 }
4458 Err(ErrorContext::new_missing(
4459 "AfSpecAttrs",
4460 "Inet6",
4461 self.orig_loc,
4462 self.buf.as_ptr() as usize,
4463 ))
4464 }
4465 pub fn get_mctp(&self) -> Result<IterableMctpAttrs<'a>, ErrorContext> {
4466 let mut iter = self.clone();
4467 iter.pos = 0;
4468 for attr in iter {
4469 if let AfSpecAttrs::Mctp(val) = attr? {
4470 return Ok(val);
4471 }
4472 }
4473 Err(ErrorContext::new_missing(
4474 "AfSpecAttrs",
4475 "Mctp",
4476 self.orig_loc,
4477 self.buf.as_ptr() as usize,
4478 ))
4479 }
4480}
4481impl AfSpecAttrs<'_> {
4482 pub fn new<'a>(buf: &'a [u8]) -> IterableAfSpecAttrs<'a> {
4483 IterableAfSpecAttrs::with_loc(buf, buf.as_ptr() as usize)
4484 }
4485 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4486 let res = match r#type {
4487 2u16 => "Inet",
4488 10u16 => "Inet6",
4489 45u16 => "Mctp",
4490 _ => return None,
4491 };
4492 Some(res)
4493 }
4494}
4495#[derive(Clone, Copy, Default)]
4496pub struct IterableAfSpecAttrs<'a> {
4497 buf: &'a [u8],
4498 pos: usize,
4499 orig_loc: usize,
4500}
4501impl<'a> IterableAfSpecAttrs<'a> {
4502 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4503 Self {
4504 buf,
4505 pos: 0,
4506 orig_loc,
4507 }
4508 }
4509 pub fn get_buf(&self) -> &'a [u8] {
4510 self.buf
4511 }
4512}
4513impl<'a> Iterator for IterableAfSpecAttrs<'a> {
4514 type Item = Result<AfSpecAttrs<'a>, ErrorContext>;
4515 fn next(&mut self) -> Option<Self::Item> {
4516 let pos = self.pos;
4517 let mut r#type;
4518 loop {
4519 r#type = None;
4520 if self.buf.len() == self.pos {
4521 return None;
4522 }
4523 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4524 break;
4525 };
4526 r#type = Some(header.r#type);
4527 let res = match header.r#type {
4528 2u16 => AfSpecAttrs::Inet({
4529 let res = Some(IterableIflaAttrs::with_loc(next, self.orig_loc));
4530 let Some(val) = res else { break };
4531 val
4532 }),
4533 10u16 => AfSpecAttrs::Inet6({
4534 let res = Some(IterableIfla6Attrs::with_loc(next, self.orig_loc));
4535 let Some(val) = res else { break };
4536 val
4537 }),
4538 45u16 => AfSpecAttrs::Mctp({
4539 let res = Some(IterableMctpAttrs::with_loc(next, self.orig_loc));
4540 let Some(val) = res else { break };
4541 val
4542 }),
4543 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4544 n => continue,
4545 };
4546 return Some(Ok(res));
4547 }
4548 Some(Err(ErrorContext::new(
4549 "AfSpecAttrs",
4550 r#type.and_then(|t| AfSpecAttrs::attr_from_type(t)),
4551 self.orig_loc,
4552 self.buf.as_ptr().wrapping_add(pos) as usize,
4553 )))
4554 }
4555}
4556impl<'a> std::fmt::Debug for IterableAfSpecAttrs<'_> {
4557 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4558 let mut fmt = f.debug_struct("AfSpecAttrs");
4559 for attr in self.clone() {
4560 let attr = match attr {
4561 Ok(a) => a,
4562 Err(err) => {
4563 fmt.finish()?;
4564 f.write_str("Err(")?;
4565 err.fmt(f)?;
4566 return f.write_str(")");
4567 }
4568 };
4569 match attr {
4570 AfSpecAttrs::Inet(val) => fmt.field("Inet", &val),
4571 AfSpecAttrs::Inet6(val) => fmt.field("Inet6", &val),
4572 AfSpecAttrs::Mctp(val) => fmt.field("Mctp", &val),
4573 };
4574 }
4575 fmt.finish()
4576 }
4577}
4578impl IterableAfSpecAttrs<'_> {
4579 pub fn lookup_attr(
4580 &self,
4581 offset: usize,
4582 missing_type: Option<u16>,
4583 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4584 let mut stack = Vec::new();
4585 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4586 if missing_type.is_some() && cur == offset {
4587 stack.push(("AfSpecAttrs", offset));
4588 return (
4589 stack,
4590 missing_type.and_then(|t| AfSpecAttrs::attr_from_type(t)),
4591 );
4592 }
4593 if cur > offset || cur + self.buf.len() < offset {
4594 return (stack, None);
4595 }
4596 let mut attrs = self.clone();
4597 let mut last_off = cur + attrs.pos;
4598 let mut missing = None;
4599 while let Some(attr) = attrs.next() {
4600 let Ok(attr) = attr else { break };
4601 match attr {
4602 AfSpecAttrs::Inet(val) => {
4603 (stack, missing) = val.lookup_attr(offset, missing_type);
4604 if !stack.is_empty() {
4605 break;
4606 }
4607 }
4608 AfSpecAttrs::Inet6(val) => {
4609 (stack, missing) = val.lookup_attr(offset, missing_type);
4610 if !stack.is_empty() {
4611 break;
4612 }
4613 }
4614 AfSpecAttrs::Mctp(val) => {
4615 (stack, missing) = val.lookup_attr(offset, missing_type);
4616 if !stack.is_empty() {
4617 break;
4618 }
4619 }
4620 _ => {}
4621 };
4622 last_off = cur + attrs.pos;
4623 }
4624 if !stack.is_empty() {
4625 stack.push(("AfSpecAttrs", cur));
4626 }
4627 (stack, missing)
4628 }
4629}
4630#[derive(Clone)]
4631pub enum VfinfoListAttrs<'a> {
4632 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4633 Info(IterableVfinfoAttrs<'a>),
4634}
4635impl<'a> IterableVfinfoListAttrs<'a> {
4636 #[doc = "Attribute may repeat multiple times (treat it as array)"]
4637 pub fn get_info(
4638 &self,
4639 ) -> MultiAttrIterable<Self, VfinfoListAttrs<'a>, IterableVfinfoAttrs<'a>> {
4640 MultiAttrIterable::new(self.clone(), |variant| {
4641 if let VfinfoListAttrs::Info(val) = variant {
4642 Some(val)
4643 } else {
4644 None
4645 }
4646 })
4647 }
4648}
4649impl VfinfoListAttrs<'_> {
4650 pub fn new<'a>(buf: &'a [u8]) -> IterableVfinfoListAttrs<'a> {
4651 IterableVfinfoListAttrs::with_loc(buf, buf.as_ptr() as usize)
4652 }
4653 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4654 let res = match r#type {
4655 1u16 => "Info",
4656 _ => return None,
4657 };
4658 Some(res)
4659 }
4660}
4661#[derive(Clone, Copy, Default)]
4662pub struct IterableVfinfoListAttrs<'a> {
4663 buf: &'a [u8],
4664 pos: usize,
4665 orig_loc: usize,
4666}
4667impl<'a> IterableVfinfoListAttrs<'a> {
4668 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4669 Self {
4670 buf,
4671 pos: 0,
4672 orig_loc,
4673 }
4674 }
4675 pub fn get_buf(&self) -> &'a [u8] {
4676 self.buf
4677 }
4678}
4679impl<'a> Iterator for IterableVfinfoListAttrs<'a> {
4680 type Item = Result<VfinfoListAttrs<'a>, ErrorContext>;
4681 fn next(&mut self) -> Option<Self::Item> {
4682 let pos = self.pos;
4683 let mut r#type;
4684 loop {
4685 r#type = None;
4686 if self.buf.len() == self.pos {
4687 return None;
4688 }
4689 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4690 break;
4691 };
4692 r#type = Some(header.r#type);
4693 let res = match header.r#type {
4694 1u16 => VfinfoListAttrs::Info({
4695 let res = Some(IterableVfinfoAttrs::with_loc(next, self.orig_loc));
4696 let Some(val) = res else { break };
4697 val
4698 }),
4699 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4700 n => continue,
4701 };
4702 return Some(Ok(res));
4703 }
4704 Some(Err(ErrorContext::new(
4705 "VfinfoListAttrs",
4706 r#type.and_then(|t| VfinfoListAttrs::attr_from_type(t)),
4707 self.orig_loc,
4708 self.buf.as_ptr().wrapping_add(pos) as usize,
4709 )))
4710 }
4711}
4712impl<'a> std::fmt::Debug for IterableVfinfoListAttrs<'_> {
4713 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4714 let mut fmt = f.debug_struct("VfinfoListAttrs");
4715 for attr in self.clone() {
4716 let attr = match attr {
4717 Ok(a) => a,
4718 Err(err) => {
4719 fmt.finish()?;
4720 f.write_str("Err(")?;
4721 err.fmt(f)?;
4722 return f.write_str(")");
4723 }
4724 };
4725 match attr {
4726 VfinfoListAttrs::Info(val) => fmt.field("Info", &val),
4727 };
4728 }
4729 fmt.finish()
4730 }
4731}
4732impl IterableVfinfoListAttrs<'_> {
4733 pub fn lookup_attr(
4734 &self,
4735 offset: usize,
4736 missing_type: Option<u16>,
4737 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4738 let mut stack = Vec::new();
4739 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4740 if missing_type.is_some() && cur == offset {
4741 stack.push(("VfinfoListAttrs", offset));
4742 return (
4743 stack,
4744 missing_type.and_then(|t| VfinfoListAttrs::attr_from_type(t)),
4745 );
4746 }
4747 if cur > offset || cur + self.buf.len() < offset {
4748 return (stack, None);
4749 }
4750 let mut attrs = self.clone();
4751 let mut last_off = cur + attrs.pos;
4752 let mut missing = None;
4753 while let Some(attr) = attrs.next() {
4754 let Ok(attr) = attr else { break };
4755 match attr {
4756 VfinfoListAttrs::Info(val) => {
4757 (stack, missing) = val.lookup_attr(offset, missing_type);
4758 if !stack.is_empty() {
4759 break;
4760 }
4761 }
4762 _ => {}
4763 };
4764 last_off = cur + attrs.pos;
4765 }
4766 if !stack.is_empty() {
4767 stack.push(("VfinfoListAttrs", cur));
4768 }
4769 (stack, missing)
4770 }
4771}
4772#[derive(Clone)]
4773pub enum VfinfoAttrs<'a> {
4774 Mac(IflaVfMac),
4775 Vlan(IflaVfVlan),
4776 TxRate(IflaVfTxRate),
4777 Spoofchk(IflaVfSpoofchk),
4778 LinkState(IflaVfLinkState),
4779 Rate(IflaVfRate),
4780 RssQueryEn(IflaVfRssQueryEn),
4781 Stats(IterableVfStatsAttrs<'a>),
4782 Trust(IflaVfTrust),
4783 IbNodeGuid(IflaVfGuid),
4784 IbPortGuid(IflaVfGuid),
4785 VlanList(IterableVfVlanAttrs<'a>),
4786 Broadcast(&'a [u8]),
4787}
4788impl<'a> IterableVfinfoAttrs<'a> {
4789 pub fn get_mac(&self) -> Result<IflaVfMac, ErrorContext> {
4790 let mut iter = self.clone();
4791 iter.pos = 0;
4792 for attr in iter {
4793 if let VfinfoAttrs::Mac(val) = attr? {
4794 return Ok(val);
4795 }
4796 }
4797 Err(ErrorContext::new_missing(
4798 "VfinfoAttrs",
4799 "Mac",
4800 self.orig_loc,
4801 self.buf.as_ptr() as usize,
4802 ))
4803 }
4804 pub fn get_vlan(&self) -> Result<IflaVfVlan, ErrorContext> {
4805 let mut iter = self.clone();
4806 iter.pos = 0;
4807 for attr in iter {
4808 if let VfinfoAttrs::Vlan(val) = attr? {
4809 return Ok(val);
4810 }
4811 }
4812 Err(ErrorContext::new_missing(
4813 "VfinfoAttrs",
4814 "Vlan",
4815 self.orig_loc,
4816 self.buf.as_ptr() as usize,
4817 ))
4818 }
4819 pub fn get_tx_rate(&self) -> Result<IflaVfTxRate, ErrorContext> {
4820 let mut iter = self.clone();
4821 iter.pos = 0;
4822 for attr in iter {
4823 if let VfinfoAttrs::TxRate(val) = attr? {
4824 return Ok(val);
4825 }
4826 }
4827 Err(ErrorContext::new_missing(
4828 "VfinfoAttrs",
4829 "TxRate",
4830 self.orig_loc,
4831 self.buf.as_ptr() as usize,
4832 ))
4833 }
4834 pub fn get_spoofchk(&self) -> Result<IflaVfSpoofchk, ErrorContext> {
4835 let mut iter = self.clone();
4836 iter.pos = 0;
4837 for attr in iter {
4838 if let VfinfoAttrs::Spoofchk(val) = attr? {
4839 return Ok(val);
4840 }
4841 }
4842 Err(ErrorContext::new_missing(
4843 "VfinfoAttrs",
4844 "Spoofchk",
4845 self.orig_loc,
4846 self.buf.as_ptr() as usize,
4847 ))
4848 }
4849 pub fn get_link_state(&self) -> Result<IflaVfLinkState, ErrorContext> {
4850 let mut iter = self.clone();
4851 iter.pos = 0;
4852 for attr in iter {
4853 if let VfinfoAttrs::LinkState(val) = attr? {
4854 return Ok(val);
4855 }
4856 }
4857 Err(ErrorContext::new_missing(
4858 "VfinfoAttrs",
4859 "LinkState",
4860 self.orig_loc,
4861 self.buf.as_ptr() as usize,
4862 ))
4863 }
4864 pub fn get_rate(&self) -> Result<IflaVfRate, ErrorContext> {
4865 let mut iter = self.clone();
4866 iter.pos = 0;
4867 for attr in iter {
4868 if let VfinfoAttrs::Rate(val) = attr? {
4869 return Ok(val);
4870 }
4871 }
4872 Err(ErrorContext::new_missing(
4873 "VfinfoAttrs",
4874 "Rate",
4875 self.orig_loc,
4876 self.buf.as_ptr() as usize,
4877 ))
4878 }
4879 pub fn get_rss_query_en(&self) -> Result<IflaVfRssQueryEn, ErrorContext> {
4880 let mut iter = self.clone();
4881 iter.pos = 0;
4882 for attr in iter {
4883 if let VfinfoAttrs::RssQueryEn(val) = attr? {
4884 return Ok(val);
4885 }
4886 }
4887 Err(ErrorContext::new_missing(
4888 "VfinfoAttrs",
4889 "RssQueryEn",
4890 self.orig_loc,
4891 self.buf.as_ptr() as usize,
4892 ))
4893 }
4894 pub fn get_stats(&self) -> Result<IterableVfStatsAttrs<'a>, ErrorContext> {
4895 let mut iter = self.clone();
4896 iter.pos = 0;
4897 for attr in iter {
4898 if let VfinfoAttrs::Stats(val) = attr? {
4899 return Ok(val);
4900 }
4901 }
4902 Err(ErrorContext::new_missing(
4903 "VfinfoAttrs",
4904 "Stats",
4905 self.orig_loc,
4906 self.buf.as_ptr() as usize,
4907 ))
4908 }
4909 pub fn get_trust(&self) -> Result<IflaVfTrust, ErrorContext> {
4910 let mut iter = self.clone();
4911 iter.pos = 0;
4912 for attr in iter {
4913 if let VfinfoAttrs::Trust(val) = attr? {
4914 return Ok(val);
4915 }
4916 }
4917 Err(ErrorContext::new_missing(
4918 "VfinfoAttrs",
4919 "Trust",
4920 self.orig_loc,
4921 self.buf.as_ptr() as usize,
4922 ))
4923 }
4924 pub fn get_ib_node_guid(&self) -> Result<IflaVfGuid, ErrorContext> {
4925 let mut iter = self.clone();
4926 iter.pos = 0;
4927 for attr in iter {
4928 if let VfinfoAttrs::IbNodeGuid(val) = attr? {
4929 return Ok(val);
4930 }
4931 }
4932 Err(ErrorContext::new_missing(
4933 "VfinfoAttrs",
4934 "IbNodeGuid",
4935 self.orig_loc,
4936 self.buf.as_ptr() as usize,
4937 ))
4938 }
4939 pub fn get_ib_port_guid(&self) -> Result<IflaVfGuid, ErrorContext> {
4940 let mut iter = self.clone();
4941 iter.pos = 0;
4942 for attr in iter {
4943 if let VfinfoAttrs::IbPortGuid(val) = attr? {
4944 return Ok(val);
4945 }
4946 }
4947 Err(ErrorContext::new_missing(
4948 "VfinfoAttrs",
4949 "IbPortGuid",
4950 self.orig_loc,
4951 self.buf.as_ptr() as usize,
4952 ))
4953 }
4954 pub fn get_vlan_list(&self) -> Result<IterableVfVlanAttrs<'a>, ErrorContext> {
4955 let mut iter = self.clone();
4956 iter.pos = 0;
4957 for attr in iter {
4958 if let VfinfoAttrs::VlanList(val) = attr? {
4959 return Ok(val);
4960 }
4961 }
4962 Err(ErrorContext::new_missing(
4963 "VfinfoAttrs",
4964 "VlanList",
4965 self.orig_loc,
4966 self.buf.as_ptr() as usize,
4967 ))
4968 }
4969 pub fn get_broadcast(&self) -> Result<&'a [u8], ErrorContext> {
4970 let mut iter = self.clone();
4971 iter.pos = 0;
4972 for attr in iter {
4973 if let VfinfoAttrs::Broadcast(val) = attr? {
4974 return Ok(val);
4975 }
4976 }
4977 Err(ErrorContext::new_missing(
4978 "VfinfoAttrs",
4979 "Broadcast",
4980 self.orig_loc,
4981 self.buf.as_ptr() as usize,
4982 ))
4983 }
4984}
4985impl VfinfoAttrs<'_> {
4986 pub fn new<'a>(buf: &'a [u8]) -> IterableVfinfoAttrs<'a> {
4987 IterableVfinfoAttrs::with_loc(buf, buf.as_ptr() as usize)
4988 }
4989 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4990 let res = match r#type {
4991 1u16 => "Mac",
4992 2u16 => "Vlan",
4993 3u16 => "TxRate",
4994 4u16 => "Spoofchk",
4995 5u16 => "LinkState",
4996 6u16 => "Rate",
4997 7u16 => "RssQueryEn",
4998 8u16 => "Stats",
4999 9u16 => "Trust",
5000 10u16 => "IbNodeGuid",
5001 11u16 => "IbPortGuid",
5002 12u16 => "VlanList",
5003 13u16 => "Broadcast",
5004 _ => return None,
5005 };
5006 Some(res)
5007 }
5008}
5009#[derive(Clone, Copy, Default)]
5010pub struct IterableVfinfoAttrs<'a> {
5011 buf: &'a [u8],
5012 pos: usize,
5013 orig_loc: usize,
5014}
5015impl<'a> IterableVfinfoAttrs<'a> {
5016 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5017 Self {
5018 buf,
5019 pos: 0,
5020 orig_loc,
5021 }
5022 }
5023 pub fn get_buf(&self) -> &'a [u8] {
5024 self.buf
5025 }
5026}
5027impl<'a> Iterator for IterableVfinfoAttrs<'a> {
5028 type Item = Result<VfinfoAttrs<'a>, ErrorContext>;
5029 fn next(&mut self) -> Option<Self::Item> {
5030 let pos = self.pos;
5031 let mut r#type;
5032 loop {
5033 r#type = None;
5034 if self.buf.len() == self.pos {
5035 return None;
5036 }
5037 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5038 break;
5039 };
5040 r#type = Some(header.r#type);
5041 let res = match header.r#type {
5042 1u16 => VfinfoAttrs::Mac({
5043 let res = Some(IflaVfMac::new_from_zeroed(next));
5044 let Some(val) = res else { break };
5045 val
5046 }),
5047 2u16 => VfinfoAttrs::Vlan({
5048 let res = Some(IflaVfVlan::new_from_zeroed(next));
5049 let Some(val) = res else { break };
5050 val
5051 }),
5052 3u16 => VfinfoAttrs::TxRate({
5053 let res = Some(IflaVfTxRate::new_from_zeroed(next));
5054 let Some(val) = res else { break };
5055 val
5056 }),
5057 4u16 => VfinfoAttrs::Spoofchk({
5058 let res = Some(IflaVfSpoofchk::new_from_zeroed(next));
5059 let Some(val) = res else { break };
5060 val
5061 }),
5062 5u16 => VfinfoAttrs::LinkState({
5063 let res = Some(IflaVfLinkState::new_from_zeroed(next));
5064 let Some(val) = res else { break };
5065 val
5066 }),
5067 6u16 => VfinfoAttrs::Rate({
5068 let res = Some(IflaVfRate::new_from_zeroed(next));
5069 let Some(val) = res else { break };
5070 val
5071 }),
5072 7u16 => VfinfoAttrs::RssQueryEn({
5073 let res = Some(IflaVfRssQueryEn::new_from_zeroed(next));
5074 let Some(val) = res else { break };
5075 val
5076 }),
5077 8u16 => VfinfoAttrs::Stats({
5078 let res = Some(IterableVfStatsAttrs::with_loc(next, self.orig_loc));
5079 let Some(val) = res else { break };
5080 val
5081 }),
5082 9u16 => VfinfoAttrs::Trust({
5083 let res = Some(IflaVfTrust::new_from_zeroed(next));
5084 let Some(val) = res else { break };
5085 val
5086 }),
5087 10u16 => VfinfoAttrs::IbNodeGuid({
5088 let res = Some(IflaVfGuid::new_from_zeroed(next));
5089 let Some(val) = res else { break };
5090 val
5091 }),
5092 11u16 => VfinfoAttrs::IbPortGuid({
5093 let res = Some(IflaVfGuid::new_from_zeroed(next));
5094 let Some(val) = res else { break };
5095 val
5096 }),
5097 12u16 => VfinfoAttrs::VlanList({
5098 let res = Some(IterableVfVlanAttrs::with_loc(next, self.orig_loc));
5099 let Some(val) = res else { break };
5100 val
5101 }),
5102 13u16 => VfinfoAttrs::Broadcast({
5103 let res = Some(next);
5104 let Some(val) = res else { break };
5105 val
5106 }),
5107 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5108 n => continue,
5109 };
5110 return Some(Ok(res));
5111 }
5112 Some(Err(ErrorContext::new(
5113 "VfinfoAttrs",
5114 r#type.and_then(|t| VfinfoAttrs::attr_from_type(t)),
5115 self.orig_loc,
5116 self.buf.as_ptr().wrapping_add(pos) as usize,
5117 )))
5118 }
5119}
5120impl<'a> std::fmt::Debug for IterableVfinfoAttrs<'_> {
5121 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5122 let mut fmt = f.debug_struct("VfinfoAttrs");
5123 for attr in self.clone() {
5124 let attr = match attr {
5125 Ok(a) => a,
5126 Err(err) => {
5127 fmt.finish()?;
5128 f.write_str("Err(")?;
5129 err.fmt(f)?;
5130 return f.write_str(")");
5131 }
5132 };
5133 match attr {
5134 VfinfoAttrs::Mac(val) => fmt.field("Mac", &val),
5135 VfinfoAttrs::Vlan(val) => fmt.field("Vlan", &val),
5136 VfinfoAttrs::TxRate(val) => fmt.field("TxRate", &val),
5137 VfinfoAttrs::Spoofchk(val) => fmt.field("Spoofchk", &val),
5138 VfinfoAttrs::LinkState(val) => fmt.field("LinkState", &val),
5139 VfinfoAttrs::Rate(val) => fmt.field("Rate", &val),
5140 VfinfoAttrs::RssQueryEn(val) => fmt.field("RssQueryEn", &val),
5141 VfinfoAttrs::Stats(val) => fmt.field("Stats", &val),
5142 VfinfoAttrs::Trust(val) => fmt.field("Trust", &val),
5143 VfinfoAttrs::IbNodeGuid(val) => fmt.field("IbNodeGuid", &val),
5144 VfinfoAttrs::IbPortGuid(val) => fmt.field("IbPortGuid", &val),
5145 VfinfoAttrs::VlanList(val) => fmt.field("VlanList", &val),
5146 VfinfoAttrs::Broadcast(val) => fmt.field("Broadcast", &val),
5147 };
5148 }
5149 fmt.finish()
5150 }
5151}
5152impl IterableVfinfoAttrs<'_> {
5153 pub fn lookup_attr(
5154 &self,
5155 offset: usize,
5156 missing_type: Option<u16>,
5157 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5158 let mut stack = Vec::new();
5159 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5160 if missing_type.is_some() && cur == offset {
5161 stack.push(("VfinfoAttrs", offset));
5162 return (
5163 stack,
5164 missing_type.and_then(|t| VfinfoAttrs::attr_from_type(t)),
5165 );
5166 }
5167 if cur > offset || cur + self.buf.len() < offset {
5168 return (stack, None);
5169 }
5170 let mut attrs = self.clone();
5171 let mut last_off = cur + attrs.pos;
5172 let mut missing = None;
5173 while let Some(attr) = attrs.next() {
5174 let Ok(attr) = attr else { break };
5175 match attr {
5176 VfinfoAttrs::Mac(val) => {
5177 if last_off == offset {
5178 stack.push(("Mac", last_off));
5179 break;
5180 }
5181 }
5182 VfinfoAttrs::Vlan(val) => {
5183 if last_off == offset {
5184 stack.push(("Vlan", last_off));
5185 break;
5186 }
5187 }
5188 VfinfoAttrs::TxRate(val) => {
5189 if last_off == offset {
5190 stack.push(("TxRate", last_off));
5191 break;
5192 }
5193 }
5194 VfinfoAttrs::Spoofchk(val) => {
5195 if last_off == offset {
5196 stack.push(("Spoofchk", last_off));
5197 break;
5198 }
5199 }
5200 VfinfoAttrs::LinkState(val) => {
5201 if last_off == offset {
5202 stack.push(("LinkState", last_off));
5203 break;
5204 }
5205 }
5206 VfinfoAttrs::Rate(val) => {
5207 if last_off == offset {
5208 stack.push(("Rate", last_off));
5209 break;
5210 }
5211 }
5212 VfinfoAttrs::RssQueryEn(val) => {
5213 if last_off == offset {
5214 stack.push(("RssQueryEn", last_off));
5215 break;
5216 }
5217 }
5218 VfinfoAttrs::Stats(val) => {
5219 (stack, missing) = val.lookup_attr(offset, missing_type);
5220 if !stack.is_empty() {
5221 break;
5222 }
5223 }
5224 VfinfoAttrs::Trust(val) => {
5225 if last_off == offset {
5226 stack.push(("Trust", last_off));
5227 break;
5228 }
5229 }
5230 VfinfoAttrs::IbNodeGuid(val) => {
5231 if last_off == offset {
5232 stack.push(("IbNodeGuid", last_off));
5233 break;
5234 }
5235 }
5236 VfinfoAttrs::IbPortGuid(val) => {
5237 if last_off == offset {
5238 stack.push(("IbPortGuid", last_off));
5239 break;
5240 }
5241 }
5242 VfinfoAttrs::VlanList(val) => {
5243 (stack, missing) = val.lookup_attr(offset, missing_type);
5244 if !stack.is_empty() {
5245 break;
5246 }
5247 }
5248 VfinfoAttrs::Broadcast(val) => {
5249 if last_off == offset {
5250 stack.push(("Broadcast", last_off));
5251 break;
5252 }
5253 }
5254 _ => {}
5255 };
5256 last_off = cur + attrs.pos;
5257 }
5258 if !stack.is_empty() {
5259 stack.push(("VfinfoAttrs", cur));
5260 }
5261 (stack, missing)
5262 }
5263}
5264#[derive(Clone)]
5265pub enum VfStatsAttrs<'a> {
5266 RxPackets(u64),
5267 TxPackets(u64),
5268 RxBytes(u64),
5269 TxBytes(u64),
5270 Broadcast(u64),
5271 Multicast(u64),
5272 Pad(&'a [u8]),
5273 RxDropped(u64),
5274 TxDropped(u64),
5275}
5276impl<'a> IterableVfStatsAttrs<'a> {
5277 pub fn get_rx_packets(&self) -> Result<u64, ErrorContext> {
5278 let mut iter = self.clone();
5279 iter.pos = 0;
5280 for attr in iter {
5281 if let VfStatsAttrs::RxPackets(val) = attr? {
5282 return Ok(val);
5283 }
5284 }
5285 Err(ErrorContext::new_missing(
5286 "VfStatsAttrs",
5287 "RxPackets",
5288 self.orig_loc,
5289 self.buf.as_ptr() as usize,
5290 ))
5291 }
5292 pub fn get_tx_packets(&self) -> Result<u64, ErrorContext> {
5293 let mut iter = self.clone();
5294 iter.pos = 0;
5295 for attr in iter {
5296 if let VfStatsAttrs::TxPackets(val) = attr? {
5297 return Ok(val);
5298 }
5299 }
5300 Err(ErrorContext::new_missing(
5301 "VfStatsAttrs",
5302 "TxPackets",
5303 self.orig_loc,
5304 self.buf.as_ptr() as usize,
5305 ))
5306 }
5307 pub fn get_rx_bytes(&self) -> Result<u64, ErrorContext> {
5308 let mut iter = self.clone();
5309 iter.pos = 0;
5310 for attr in iter {
5311 if let VfStatsAttrs::RxBytes(val) = attr? {
5312 return Ok(val);
5313 }
5314 }
5315 Err(ErrorContext::new_missing(
5316 "VfStatsAttrs",
5317 "RxBytes",
5318 self.orig_loc,
5319 self.buf.as_ptr() as usize,
5320 ))
5321 }
5322 pub fn get_tx_bytes(&self) -> Result<u64, ErrorContext> {
5323 let mut iter = self.clone();
5324 iter.pos = 0;
5325 for attr in iter {
5326 if let VfStatsAttrs::TxBytes(val) = attr? {
5327 return Ok(val);
5328 }
5329 }
5330 Err(ErrorContext::new_missing(
5331 "VfStatsAttrs",
5332 "TxBytes",
5333 self.orig_loc,
5334 self.buf.as_ptr() as usize,
5335 ))
5336 }
5337 pub fn get_broadcast(&self) -> Result<u64, ErrorContext> {
5338 let mut iter = self.clone();
5339 iter.pos = 0;
5340 for attr in iter {
5341 if let VfStatsAttrs::Broadcast(val) = attr? {
5342 return Ok(val);
5343 }
5344 }
5345 Err(ErrorContext::new_missing(
5346 "VfStatsAttrs",
5347 "Broadcast",
5348 self.orig_loc,
5349 self.buf.as_ptr() as usize,
5350 ))
5351 }
5352 pub fn get_multicast(&self) -> Result<u64, ErrorContext> {
5353 let mut iter = self.clone();
5354 iter.pos = 0;
5355 for attr in iter {
5356 if let VfStatsAttrs::Multicast(val) = attr? {
5357 return Ok(val);
5358 }
5359 }
5360 Err(ErrorContext::new_missing(
5361 "VfStatsAttrs",
5362 "Multicast",
5363 self.orig_loc,
5364 self.buf.as_ptr() as usize,
5365 ))
5366 }
5367 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
5368 let mut iter = self.clone();
5369 iter.pos = 0;
5370 for attr in iter {
5371 if let VfStatsAttrs::Pad(val) = attr? {
5372 return Ok(val);
5373 }
5374 }
5375 Err(ErrorContext::new_missing(
5376 "VfStatsAttrs",
5377 "Pad",
5378 self.orig_loc,
5379 self.buf.as_ptr() as usize,
5380 ))
5381 }
5382 pub fn get_rx_dropped(&self) -> Result<u64, ErrorContext> {
5383 let mut iter = self.clone();
5384 iter.pos = 0;
5385 for attr in iter {
5386 if let VfStatsAttrs::RxDropped(val) = attr? {
5387 return Ok(val);
5388 }
5389 }
5390 Err(ErrorContext::new_missing(
5391 "VfStatsAttrs",
5392 "RxDropped",
5393 self.orig_loc,
5394 self.buf.as_ptr() as usize,
5395 ))
5396 }
5397 pub fn get_tx_dropped(&self) -> Result<u64, ErrorContext> {
5398 let mut iter = self.clone();
5399 iter.pos = 0;
5400 for attr in iter {
5401 if let VfStatsAttrs::TxDropped(val) = attr? {
5402 return Ok(val);
5403 }
5404 }
5405 Err(ErrorContext::new_missing(
5406 "VfStatsAttrs",
5407 "TxDropped",
5408 self.orig_loc,
5409 self.buf.as_ptr() as usize,
5410 ))
5411 }
5412}
5413impl VfStatsAttrs<'_> {
5414 pub fn new<'a>(buf: &'a [u8]) -> IterableVfStatsAttrs<'a> {
5415 IterableVfStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
5416 }
5417 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5418 let res = match r#type {
5419 0u16 => "RxPackets",
5420 1u16 => "TxPackets",
5421 2u16 => "RxBytes",
5422 3u16 => "TxBytes",
5423 4u16 => "Broadcast",
5424 5u16 => "Multicast",
5425 6u16 => "Pad",
5426 7u16 => "RxDropped",
5427 8u16 => "TxDropped",
5428 _ => return None,
5429 };
5430 Some(res)
5431 }
5432}
5433#[derive(Clone, Copy, Default)]
5434pub struct IterableVfStatsAttrs<'a> {
5435 buf: &'a [u8],
5436 pos: usize,
5437 orig_loc: usize,
5438}
5439impl<'a> IterableVfStatsAttrs<'a> {
5440 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5441 Self {
5442 buf,
5443 pos: 0,
5444 orig_loc,
5445 }
5446 }
5447 pub fn get_buf(&self) -> &'a [u8] {
5448 self.buf
5449 }
5450}
5451impl<'a> Iterator for IterableVfStatsAttrs<'a> {
5452 type Item = Result<VfStatsAttrs<'a>, ErrorContext>;
5453 fn next(&mut self) -> Option<Self::Item> {
5454 let pos = self.pos;
5455 let mut r#type;
5456 loop {
5457 r#type = None;
5458 if self.buf.len() == self.pos {
5459 return None;
5460 }
5461 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5462 break;
5463 };
5464 r#type = Some(header.r#type);
5465 let res = match header.r#type {
5466 0u16 => VfStatsAttrs::RxPackets({
5467 let res = parse_u64(next);
5468 let Some(val) = res else { break };
5469 val
5470 }),
5471 1u16 => VfStatsAttrs::TxPackets({
5472 let res = parse_u64(next);
5473 let Some(val) = res else { break };
5474 val
5475 }),
5476 2u16 => VfStatsAttrs::RxBytes({
5477 let res = parse_u64(next);
5478 let Some(val) = res else { break };
5479 val
5480 }),
5481 3u16 => VfStatsAttrs::TxBytes({
5482 let res = parse_u64(next);
5483 let Some(val) = res else { break };
5484 val
5485 }),
5486 4u16 => VfStatsAttrs::Broadcast({
5487 let res = parse_u64(next);
5488 let Some(val) = res else { break };
5489 val
5490 }),
5491 5u16 => VfStatsAttrs::Multicast({
5492 let res = parse_u64(next);
5493 let Some(val) = res else { break };
5494 val
5495 }),
5496 6u16 => VfStatsAttrs::Pad({
5497 let res = Some(next);
5498 let Some(val) = res else { break };
5499 val
5500 }),
5501 7u16 => VfStatsAttrs::RxDropped({
5502 let res = parse_u64(next);
5503 let Some(val) = res else { break };
5504 val
5505 }),
5506 8u16 => VfStatsAttrs::TxDropped({
5507 let res = parse_u64(next);
5508 let Some(val) = res else { break };
5509 val
5510 }),
5511 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5512 n => continue,
5513 };
5514 return Some(Ok(res));
5515 }
5516 Some(Err(ErrorContext::new(
5517 "VfStatsAttrs",
5518 r#type.and_then(|t| VfStatsAttrs::attr_from_type(t)),
5519 self.orig_loc,
5520 self.buf.as_ptr().wrapping_add(pos) as usize,
5521 )))
5522 }
5523}
5524impl<'a> std::fmt::Debug for IterableVfStatsAttrs<'_> {
5525 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5526 let mut fmt = f.debug_struct("VfStatsAttrs");
5527 for attr in self.clone() {
5528 let attr = match attr {
5529 Ok(a) => a,
5530 Err(err) => {
5531 fmt.finish()?;
5532 f.write_str("Err(")?;
5533 err.fmt(f)?;
5534 return f.write_str(")");
5535 }
5536 };
5537 match attr {
5538 VfStatsAttrs::RxPackets(val) => fmt.field("RxPackets", &val),
5539 VfStatsAttrs::TxPackets(val) => fmt.field("TxPackets", &val),
5540 VfStatsAttrs::RxBytes(val) => fmt.field("RxBytes", &val),
5541 VfStatsAttrs::TxBytes(val) => fmt.field("TxBytes", &val),
5542 VfStatsAttrs::Broadcast(val) => fmt.field("Broadcast", &val),
5543 VfStatsAttrs::Multicast(val) => fmt.field("Multicast", &val),
5544 VfStatsAttrs::Pad(val) => fmt.field("Pad", &val),
5545 VfStatsAttrs::RxDropped(val) => fmt.field("RxDropped", &val),
5546 VfStatsAttrs::TxDropped(val) => fmt.field("TxDropped", &val),
5547 };
5548 }
5549 fmt.finish()
5550 }
5551}
5552impl IterableVfStatsAttrs<'_> {
5553 pub fn lookup_attr(
5554 &self,
5555 offset: usize,
5556 missing_type: Option<u16>,
5557 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5558 let mut stack = Vec::new();
5559 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5560 if missing_type.is_some() && cur == offset {
5561 stack.push(("VfStatsAttrs", offset));
5562 return (
5563 stack,
5564 missing_type.and_then(|t| VfStatsAttrs::attr_from_type(t)),
5565 );
5566 }
5567 if cur > offset || cur + self.buf.len() < offset {
5568 return (stack, None);
5569 }
5570 let mut attrs = self.clone();
5571 let mut last_off = cur + attrs.pos;
5572 while let Some(attr) = attrs.next() {
5573 let Ok(attr) = attr else { break };
5574 match attr {
5575 VfStatsAttrs::RxPackets(val) => {
5576 if last_off == offset {
5577 stack.push(("RxPackets", last_off));
5578 break;
5579 }
5580 }
5581 VfStatsAttrs::TxPackets(val) => {
5582 if last_off == offset {
5583 stack.push(("TxPackets", last_off));
5584 break;
5585 }
5586 }
5587 VfStatsAttrs::RxBytes(val) => {
5588 if last_off == offset {
5589 stack.push(("RxBytes", last_off));
5590 break;
5591 }
5592 }
5593 VfStatsAttrs::TxBytes(val) => {
5594 if last_off == offset {
5595 stack.push(("TxBytes", last_off));
5596 break;
5597 }
5598 }
5599 VfStatsAttrs::Broadcast(val) => {
5600 if last_off == offset {
5601 stack.push(("Broadcast", last_off));
5602 break;
5603 }
5604 }
5605 VfStatsAttrs::Multicast(val) => {
5606 if last_off == offset {
5607 stack.push(("Multicast", last_off));
5608 break;
5609 }
5610 }
5611 VfStatsAttrs::Pad(val) => {
5612 if last_off == offset {
5613 stack.push(("Pad", last_off));
5614 break;
5615 }
5616 }
5617 VfStatsAttrs::RxDropped(val) => {
5618 if last_off == offset {
5619 stack.push(("RxDropped", last_off));
5620 break;
5621 }
5622 }
5623 VfStatsAttrs::TxDropped(val) => {
5624 if last_off == offset {
5625 stack.push(("TxDropped", last_off));
5626 break;
5627 }
5628 }
5629 _ => {}
5630 };
5631 last_off = cur + attrs.pos;
5632 }
5633 if !stack.is_empty() {
5634 stack.push(("VfStatsAttrs", cur));
5635 }
5636 (stack, None)
5637 }
5638}
5639#[derive(Clone)]
5640pub enum VfVlanAttrs {
5641 #[doc = "Attribute may repeat multiple times (treat it as array)"]
5642 Info(IflaVfVlanInfo),
5643}
5644impl<'a> IterableVfVlanAttrs<'a> {
5645 #[doc = "Attribute may repeat multiple times (treat it as array)"]
5646 pub fn get_info(&self) -> MultiAttrIterable<Self, VfVlanAttrs, IflaVfVlanInfo> {
5647 MultiAttrIterable::new(self.clone(), |variant| {
5648 if let VfVlanAttrs::Info(val) = variant {
5649 Some(val)
5650 } else {
5651 None
5652 }
5653 })
5654 }
5655}
5656impl VfVlanAttrs {
5657 pub fn new<'a>(buf: &'a [u8]) -> IterableVfVlanAttrs<'a> {
5658 IterableVfVlanAttrs::with_loc(buf, buf.as_ptr() as usize)
5659 }
5660 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5661 let res = match r#type {
5662 1u16 => "Info",
5663 _ => return None,
5664 };
5665 Some(res)
5666 }
5667}
5668#[derive(Clone, Copy, Default)]
5669pub struct IterableVfVlanAttrs<'a> {
5670 buf: &'a [u8],
5671 pos: usize,
5672 orig_loc: usize,
5673}
5674impl<'a> IterableVfVlanAttrs<'a> {
5675 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5676 Self {
5677 buf,
5678 pos: 0,
5679 orig_loc,
5680 }
5681 }
5682 pub fn get_buf(&self) -> &'a [u8] {
5683 self.buf
5684 }
5685}
5686impl<'a> Iterator for IterableVfVlanAttrs<'a> {
5687 type Item = Result<VfVlanAttrs, ErrorContext>;
5688 fn next(&mut self) -> Option<Self::Item> {
5689 let pos = self.pos;
5690 let mut r#type;
5691 loop {
5692 r#type = None;
5693 if self.buf.len() == self.pos {
5694 return None;
5695 }
5696 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5697 break;
5698 };
5699 r#type = Some(header.r#type);
5700 let res = match header.r#type {
5701 1u16 => VfVlanAttrs::Info({
5702 let res = Some(IflaVfVlanInfo::new_from_zeroed(next));
5703 let Some(val) = res else { break };
5704 val
5705 }),
5706 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5707 n => continue,
5708 };
5709 return Some(Ok(res));
5710 }
5711 Some(Err(ErrorContext::new(
5712 "VfVlanAttrs",
5713 r#type.and_then(|t| VfVlanAttrs::attr_from_type(t)),
5714 self.orig_loc,
5715 self.buf.as_ptr().wrapping_add(pos) as usize,
5716 )))
5717 }
5718}
5719impl std::fmt::Debug for IterableVfVlanAttrs<'_> {
5720 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5721 let mut fmt = f.debug_struct("VfVlanAttrs");
5722 for attr in self.clone() {
5723 let attr = match attr {
5724 Ok(a) => a,
5725 Err(err) => {
5726 fmt.finish()?;
5727 f.write_str("Err(")?;
5728 err.fmt(f)?;
5729 return f.write_str(")");
5730 }
5731 };
5732 match attr {
5733 VfVlanAttrs::Info(val) => fmt.field("Info", &val),
5734 };
5735 }
5736 fmt.finish()
5737 }
5738}
5739impl IterableVfVlanAttrs<'_> {
5740 pub fn lookup_attr(
5741 &self,
5742 offset: usize,
5743 missing_type: Option<u16>,
5744 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5745 let mut stack = Vec::new();
5746 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5747 if missing_type.is_some() && cur == offset {
5748 stack.push(("VfVlanAttrs", offset));
5749 return (
5750 stack,
5751 missing_type.and_then(|t| VfVlanAttrs::attr_from_type(t)),
5752 );
5753 }
5754 if cur > offset || cur + self.buf.len() < offset {
5755 return (stack, None);
5756 }
5757 let mut attrs = self.clone();
5758 let mut last_off = cur + attrs.pos;
5759 while let Some(attr) = attrs.next() {
5760 let Ok(attr) = attr else { break };
5761 match attr {
5762 VfVlanAttrs::Info(val) => {
5763 if last_off == offset {
5764 stack.push(("Info", last_off));
5765 break;
5766 }
5767 }
5768 _ => {}
5769 };
5770 last_off = cur + attrs.pos;
5771 }
5772 if !stack.is_empty() {
5773 stack.push(("VfVlanAttrs", cur));
5774 }
5775 (stack, None)
5776 }
5777}
5778#[derive(Clone)]
5779pub enum VfPortsAttrs {}
5780impl<'a> IterableVfPortsAttrs<'a> {}
5781impl VfPortsAttrs {
5782 pub fn new<'a>(buf: &'a [u8]) -> IterableVfPortsAttrs<'a> {
5783 IterableVfPortsAttrs::with_loc(buf, buf.as_ptr() as usize)
5784 }
5785 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5786 None
5787 }
5788}
5789#[derive(Clone, Copy, Default)]
5790pub struct IterableVfPortsAttrs<'a> {
5791 buf: &'a [u8],
5792 pos: usize,
5793 orig_loc: usize,
5794}
5795impl<'a> IterableVfPortsAttrs<'a> {
5796 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5797 Self {
5798 buf,
5799 pos: 0,
5800 orig_loc,
5801 }
5802 }
5803 pub fn get_buf(&self) -> &'a [u8] {
5804 self.buf
5805 }
5806}
5807impl<'a> Iterator for IterableVfPortsAttrs<'a> {
5808 type Item = Result<VfPortsAttrs, ErrorContext>;
5809 fn next(&mut self) -> Option<Self::Item> {
5810 let pos = self.pos;
5811 let mut r#type;
5812 loop {
5813 r#type = None;
5814 if self.buf.len() == self.pos {
5815 return None;
5816 }
5817 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5818 break;
5819 };
5820 r#type = Some(header.r#type);
5821 let res = match header.r#type {
5822 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5823 n => continue,
5824 };
5825 return Some(Ok(res));
5826 }
5827 Some(Err(ErrorContext::new(
5828 "VfPortsAttrs",
5829 r#type.and_then(|t| VfPortsAttrs::attr_from_type(t)),
5830 self.orig_loc,
5831 self.buf.as_ptr().wrapping_add(pos) as usize,
5832 )))
5833 }
5834}
5835impl std::fmt::Debug for IterableVfPortsAttrs<'_> {
5836 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5837 let mut fmt = f.debug_struct("VfPortsAttrs");
5838 for attr in self.clone() {
5839 let attr = match attr {
5840 Ok(a) => a,
5841 Err(err) => {
5842 fmt.finish()?;
5843 f.write_str("Err(")?;
5844 err.fmt(f)?;
5845 return f.write_str(")");
5846 }
5847 };
5848 match attr {};
5849 }
5850 fmt.finish()
5851 }
5852}
5853impl IterableVfPortsAttrs<'_> {
5854 pub fn lookup_attr(
5855 &self,
5856 offset: usize,
5857 missing_type: Option<u16>,
5858 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5859 let mut stack = Vec::new();
5860 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5861 if missing_type.is_some() && cur == offset {
5862 stack.push(("VfPortsAttrs", offset));
5863 return (
5864 stack,
5865 missing_type.and_then(|t| VfPortsAttrs::attr_from_type(t)),
5866 );
5867 }
5868 (stack, None)
5869 }
5870}
5871#[derive(Clone)]
5872pub enum PortSelfAttrs {}
5873impl<'a> IterablePortSelfAttrs<'a> {}
5874impl PortSelfAttrs {
5875 pub fn new<'a>(buf: &'a [u8]) -> IterablePortSelfAttrs<'a> {
5876 IterablePortSelfAttrs::with_loc(buf, buf.as_ptr() as usize)
5877 }
5878 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5879 None
5880 }
5881}
5882#[derive(Clone, Copy, Default)]
5883pub struct IterablePortSelfAttrs<'a> {
5884 buf: &'a [u8],
5885 pos: usize,
5886 orig_loc: usize,
5887}
5888impl<'a> IterablePortSelfAttrs<'a> {
5889 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5890 Self {
5891 buf,
5892 pos: 0,
5893 orig_loc,
5894 }
5895 }
5896 pub fn get_buf(&self) -> &'a [u8] {
5897 self.buf
5898 }
5899}
5900impl<'a> Iterator for IterablePortSelfAttrs<'a> {
5901 type Item = Result<PortSelfAttrs, ErrorContext>;
5902 fn next(&mut self) -> Option<Self::Item> {
5903 let pos = self.pos;
5904 let mut r#type;
5905 loop {
5906 r#type = None;
5907 if self.buf.len() == self.pos {
5908 return None;
5909 }
5910 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5911 break;
5912 };
5913 r#type = Some(header.r#type);
5914 let res = match header.r#type {
5915 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5916 n => continue,
5917 };
5918 return Some(Ok(res));
5919 }
5920 Some(Err(ErrorContext::new(
5921 "PortSelfAttrs",
5922 r#type.and_then(|t| PortSelfAttrs::attr_from_type(t)),
5923 self.orig_loc,
5924 self.buf.as_ptr().wrapping_add(pos) as usize,
5925 )))
5926 }
5927}
5928impl std::fmt::Debug for IterablePortSelfAttrs<'_> {
5929 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5930 let mut fmt = f.debug_struct("PortSelfAttrs");
5931 for attr in self.clone() {
5932 let attr = match attr {
5933 Ok(a) => a,
5934 Err(err) => {
5935 fmt.finish()?;
5936 f.write_str("Err(")?;
5937 err.fmt(f)?;
5938 return f.write_str(")");
5939 }
5940 };
5941 match attr {};
5942 }
5943 fmt.finish()
5944 }
5945}
5946impl IterablePortSelfAttrs<'_> {
5947 pub fn lookup_attr(
5948 &self,
5949 offset: usize,
5950 missing_type: Option<u16>,
5951 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5952 let mut stack = Vec::new();
5953 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5954 if missing_type.is_some() && cur == offset {
5955 stack.push(("PortSelfAttrs", offset));
5956 return (
5957 stack,
5958 missing_type.and_then(|t| PortSelfAttrs::attr_from_type(t)),
5959 );
5960 }
5961 (stack, None)
5962 }
5963}
5964#[derive(Clone)]
5965pub enum LinkinfoAttrs<'a> {
5966 Kind(&'a CStr),
5967 Data(LinkinfoDataMsg<'a>),
5968 Xstats(&'a [u8]),
5969 SlaveKind(&'a CStr),
5970 SlaveData(LinkinfoMemberDataMsg<'a>),
5971}
5972impl<'a> IterableLinkinfoAttrs<'a> {
5973 pub fn get_kind(&self) -> Result<&'a CStr, ErrorContext> {
5974 let mut iter = self.clone();
5975 iter.pos = 0;
5976 for attr in iter {
5977 if let LinkinfoAttrs::Kind(val) = attr? {
5978 return Ok(val);
5979 }
5980 }
5981 Err(ErrorContext::new_missing(
5982 "LinkinfoAttrs",
5983 "Kind",
5984 self.orig_loc,
5985 self.buf.as_ptr() as usize,
5986 ))
5987 }
5988 pub fn get_data(&self) -> Result<LinkinfoDataMsg<'a>, ErrorContext> {
5989 let mut iter = self.clone();
5990 iter.pos = 0;
5991 for attr in iter {
5992 if let LinkinfoAttrs::Data(val) = attr? {
5993 return Ok(val);
5994 }
5995 }
5996 Err(ErrorContext::new_missing(
5997 "LinkinfoAttrs",
5998 "Data",
5999 self.orig_loc,
6000 self.buf.as_ptr() as usize,
6001 ))
6002 }
6003 pub fn get_xstats(&self) -> Result<&'a [u8], ErrorContext> {
6004 let mut iter = self.clone();
6005 iter.pos = 0;
6006 for attr in iter {
6007 if let LinkinfoAttrs::Xstats(val) = attr? {
6008 return Ok(val);
6009 }
6010 }
6011 Err(ErrorContext::new_missing(
6012 "LinkinfoAttrs",
6013 "Xstats",
6014 self.orig_loc,
6015 self.buf.as_ptr() as usize,
6016 ))
6017 }
6018 pub fn get_slave_kind(&self) -> Result<&'a CStr, ErrorContext> {
6019 let mut iter = self.clone();
6020 iter.pos = 0;
6021 for attr in iter {
6022 if let LinkinfoAttrs::SlaveKind(val) = attr? {
6023 return Ok(val);
6024 }
6025 }
6026 Err(ErrorContext::new_missing(
6027 "LinkinfoAttrs",
6028 "SlaveKind",
6029 self.orig_loc,
6030 self.buf.as_ptr() as usize,
6031 ))
6032 }
6033 pub fn get_slave_data(&self) -> Result<LinkinfoMemberDataMsg<'a>, ErrorContext> {
6034 let mut iter = self.clone();
6035 iter.pos = 0;
6036 for attr in iter {
6037 if let LinkinfoAttrs::SlaveData(val) = attr? {
6038 return Ok(val);
6039 }
6040 }
6041 Err(ErrorContext::new_missing(
6042 "LinkinfoAttrs",
6043 "SlaveData",
6044 self.orig_loc,
6045 self.buf.as_ptr() as usize,
6046 ))
6047 }
6048}
6049#[derive(Debug, Clone)]
6050pub enum LinkinfoDataMsg<'a> {
6051 Bond(IterableLinkinfoBondAttrs<'a>),
6052 Bridge(IterableLinkinfoBridgeAttrs<'a>),
6053 Erspan(IterableLinkinfoGreAttrs<'a>),
6054 Gre(IterableLinkinfoGreAttrs<'a>),
6055 Gretap(IterableLinkinfoGreAttrs<'a>),
6056 Ip6gre(IterableLinkinfoGre6Attrs<'a>),
6057 Geneve(IterableLinkinfoGeneveAttrs<'a>),
6058 Hsr(IterableLinkinfoHsrAttrs<'a>),
6059 Ipip(IterableLinkinfoIptunAttrs<'a>),
6060 Ip6tnl(IterableLinkinfoIp6tnlAttrs<'a>),
6061 Sit(IterableLinkinfoIptunAttrs<'a>),
6062 Tun(IterableLinkinfoTunAttrs<'a>),
6063 Vlan(IterableLinkinfoVlanAttrs<'a>),
6064 Vrf(IterableLinkinfoVrfAttrs<'a>),
6065 Vti(IterableLinkinfoVtiAttrs<'a>),
6066 Vti6(IterableLinkinfoVti6Attrs<'a>),
6067 Netkit(IterableLinkinfoNetkitAttrs<'a>),
6068 Ovpn(IterableLinkinfoOvpnAttrs<'a>),
6069}
6070impl<'a> LinkinfoDataMsg<'a> {
6071 fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
6072 match selector.to_bytes() {
6073 b"bond" => Some(LinkinfoDataMsg::Bond(IterableLinkinfoBondAttrs::with_loc(
6074 buf, loc,
6075 ))),
6076 b"bridge" => Some(LinkinfoDataMsg::Bridge(
6077 IterableLinkinfoBridgeAttrs::with_loc(buf, loc),
6078 )),
6079 b"erspan" => Some(LinkinfoDataMsg::Erspan(IterableLinkinfoGreAttrs::with_loc(
6080 buf, loc,
6081 ))),
6082 b"gre" => Some(LinkinfoDataMsg::Gre(IterableLinkinfoGreAttrs::with_loc(
6083 buf, loc,
6084 ))),
6085 b"gretap" => Some(LinkinfoDataMsg::Gretap(IterableLinkinfoGreAttrs::with_loc(
6086 buf, loc,
6087 ))),
6088 b"ip6gre" => Some(LinkinfoDataMsg::Ip6gre(
6089 IterableLinkinfoGre6Attrs::with_loc(buf, loc),
6090 )),
6091 b"geneve" => Some(LinkinfoDataMsg::Geneve(
6092 IterableLinkinfoGeneveAttrs::with_loc(buf, loc),
6093 )),
6094 b"hsr" => Some(LinkinfoDataMsg::Hsr(IterableLinkinfoHsrAttrs::with_loc(
6095 buf, loc,
6096 ))),
6097 b"ipip" => Some(LinkinfoDataMsg::Ipip(IterableLinkinfoIptunAttrs::with_loc(
6098 buf, loc,
6099 ))),
6100 b"ip6tnl" => Some(LinkinfoDataMsg::Ip6tnl(
6101 IterableLinkinfoIp6tnlAttrs::with_loc(buf, loc),
6102 )),
6103 b"sit" => Some(LinkinfoDataMsg::Sit(IterableLinkinfoIptunAttrs::with_loc(
6104 buf, loc,
6105 ))),
6106 b"tun" => Some(LinkinfoDataMsg::Tun(IterableLinkinfoTunAttrs::with_loc(
6107 buf, loc,
6108 ))),
6109 b"vlan" => Some(LinkinfoDataMsg::Vlan(IterableLinkinfoVlanAttrs::with_loc(
6110 buf, loc,
6111 ))),
6112 b"vrf" => Some(LinkinfoDataMsg::Vrf(IterableLinkinfoVrfAttrs::with_loc(
6113 buf, loc,
6114 ))),
6115 b"vti" => Some(LinkinfoDataMsg::Vti(IterableLinkinfoVtiAttrs::with_loc(
6116 buf, loc,
6117 ))),
6118 b"vti6" => Some(LinkinfoDataMsg::Vti6(IterableLinkinfoVti6Attrs::with_loc(
6119 buf, loc,
6120 ))),
6121 b"netkit" => Some(LinkinfoDataMsg::Netkit(
6122 IterableLinkinfoNetkitAttrs::with_loc(buf, loc),
6123 )),
6124 b"ovpn" => Some(LinkinfoDataMsg::Ovpn(IterableLinkinfoOvpnAttrs::with_loc(
6125 buf, loc,
6126 ))),
6127 _ => None,
6128 }
6129 }
6130}
6131#[derive(Debug, Clone)]
6132pub enum LinkinfoMemberDataMsg<'a> {
6133 Bridge(IterableLinkinfoBrportAttrs<'a>),
6134 Bond(IterableBondSlaveAttrs<'a>),
6135}
6136impl<'a> LinkinfoMemberDataMsg<'a> {
6137 fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
6138 match selector.to_bytes() {
6139 b"bridge" => Some(LinkinfoMemberDataMsg::Bridge(
6140 IterableLinkinfoBrportAttrs::with_loc(buf, loc),
6141 )),
6142 b"bond" => Some(LinkinfoMemberDataMsg::Bond(
6143 IterableBondSlaveAttrs::with_loc(buf, loc),
6144 )),
6145 _ => None,
6146 }
6147 }
6148}
6149impl LinkinfoAttrs<'_> {
6150 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoAttrs<'a> {
6151 IterableLinkinfoAttrs::with_loc(buf, buf.as_ptr() as usize)
6152 }
6153 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6154 let res = match r#type {
6155 1u16 => "Kind",
6156 2u16 => "Data",
6157 3u16 => "Xstats",
6158 4u16 => "SlaveKind",
6159 5u16 => "SlaveData",
6160 _ => return None,
6161 };
6162 Some(res)
6163 }
6164}
6165#[derive(Clone, Copy, Default)]
6166pub struct IterableLinkinfoAttrs<'a> {
6167 buf: &'a [u8],
6168 pos: usize,
6169 orig_loc: usize,
6170}
6171impl<'a> IterableLinkinfoAttrs<'a> {
6172 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6173 Self {
6174 buf,
6175 pos: 0,
6176 orig_loc,
6177 }
6178 }
6179 pub fn get_buf(&self) -> &'a [u8] {
6180 self.buf
6181 }
6182}
6183impl<'a> Iterator for IterableLinkinfoAttrs<'a> {
6184 type Item = Result<LinkinfoAttrs<'a>, ErrorContext>;
6185 fn next(&mut self) -> Option<Self::Item> {
6186 let pos = self.pos;
6187 let mut r#type;
6188 loop {
6189 r#type = None;
6190 if self.buf.len() == self.pos {
6191 return None;
6192 }
6193 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 Some(Err(ErrorContext::new(
6890 "Ipv4Addr",
6891 None,
6892 self.orig_loc,
6893 self.buf.as_ptr().wrapping_add(self.pos) as usize,
6894 )))
6895 }
6896}
6897#[derive(Clone, Copy, Default)]
6898pub struct IterableArrayBinary<'a> {
6899 buf: &'a [u8],
6900 pos: usize,
6901 orig_loc: usize,
6902}
6903impl<'a> IterableArrayBinary<'a> {
6904 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6905 Self {
6906 buf,
6907 pos: 0,
6908 orig_loc,
6909 }
6910 }
6911 pub fn get_buf(&self) -> &'a [u8] {
6912 self.buf
6913 }
6914}
6915impl<'a> Iterator for IterableArrayBinary<'a> {
6916 type Item = Result<&'a [u8], ErrorContext>;
6917 fn next(&mut self) -> Option<Self::Item> {
6918 if self.buf.len() == self.pos {
6919 return None;
6920 }
6921 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
6922 {
6923 let Some(res) = Some(next) else { break };
6924 return Some(Ok(res));
6925 }
6926 }
6927 Some(Err(ErrorContext::new(
6928 "Binary",
6929 None,
6930 self.orig_loc,
6931 self.buf.as_ptr().wrapping_add(self.pos) as usize,
6932 )))
6933 }
6934}
6935impl LinkinfoBondAttrs<'_> {
6936 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoBondAttrs<'a> {
6937 IterableLinkinfoBondAttrs::with_loc(buf, buf.as_ptr() as usize)
6938 }
6939 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6940 let res = match r#type {
6941 1u16 => "Mode",
6942 2u16 => "ActiveSlave",
6943 3u16 => "Miimon",
6944 4u16 => "Updelay",
6945 5u16 => "Downdelay",
6946 6u16 => "UseCarrier",
6947 7u16 => "ArpInterval",
6948 8u16 => "ArpIpTarget",
6949 9u16 => "ArpValidate",
6950 10u16 => "ArpAllTargets",
6951 11u16 => "Primary",
6952 12u16 => "PrimaryReselect",
6953 13u16 => "FailOverMac",
6954 14u16 => "XmitHashPolicy",
6955 15u16 => "ResendIgmp",
6956 16u16 => "NumPeerNotif",
6957 17u16 => "AllSlavesActive",
6958 18u16 => "MinLinks",
6959 19u16 => "LpInterval",
6960 20u16 => "PacketsPerSlave",
6961 21u16 => "AdLacpRate",
6962 22u16 => "AdSelect",
6963 23u16 => "AdInfo",
6964 24u16 => "AdActorSysPrio",
6965 25u16 => "AdUserPortKey",
6966 26u16 => "AdActorSystem",
6967 27u16 => "TlbDynamicLb",
6968 28u16 => "PeerNotifDelay",
6969 29u16 => "AdLacpActive",
6970 30u16 => "MissedMax",
6971 31u16 => "NsIp6Target",
6972 32u16 => "CoupledControl",
6973 _ => return None,
6974 };
6975 Some(res)
6976 }
6977}
6978#[derive(Clone, Copy, Default)]
6979pub struct IterableLinkinfoBondAttrs<'a> {
6980 buf: &'a [u8],
6981 pos: usize,
6982 orig_loc: usize,
6983}
6984impl<'a> IterableLinkinfoBondAttrs<'a> {
6985 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6986 Self {
6987 buf,
6988 pos: 0,
6989 orig_loc,
6990 }
6991 }
6992 pub fn get_buf(&self) -> &'a [u8] {
6993 self.buf
6994 }
6995}
6996impl<'a> Iterator for IterableLinkinfoBondAttrs<'a> {
6997 type Item = Result<LinkinfoBondAttrs<'a>, ErrorContext>;
6998 fn next(&mut self) -> Option<Self::Item> {
6999 let pos = self.pos;
7000 let mut r#type;
7001 loop {
7002 r#type = None;
7003 if self.buf.len() == self.pos {
7004 return None;
7005 }
7006 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
7007 break;
7008 };
7009 r#type = Some(header.r#type);
7010 let res = match header.r#type {
7011 1u16 => LinkinfoBondAttrs::Mode({
7012 let res = parse_u8(next);
7013 let Some(val) = res else { break };
7014 val
7015 }),
7016 2u16 => LinkinfoBondAttrs::ActiveSlave({
7017 let res = parse_u32(next);
7018 let Some(val) = res else { break };
7019 val
7020 }),
7021 3u16 => LinkinfoBondAttrs::Miimon({
7022 let res = parse_u32(next);
7023 let Some(val) = res else { break };
7024 val
7025 }),
7026 4u16 => LinkinfoBondAttrs::Updelay({
7027 let res = parse_u32(next);
7028 let Some(val) = res else { break };
7029 val
7030 }),
7031 5u16 => LinkinfoBondAttrs::Downdelay({
7032 let res = parse_u32(next);
7033 let Some(val) = res else { break };
7034 val
7035 }),
7036 6u16 => LinkinfoBondAttrs::UseCarrier({
7037 let res = parse_u8(next);
7038 let Some(val) = res else { break };
7039 val
7040 }),
7041 7u16 => LinkinfoBondAttrs::ArpInterval({
7042 let res = parse_u32(next);
7043 let Some(val) = res else { break };
7044 val
7045 }),
7046 8u16 => LinkinfoBondAttrs::ArpIpTarget({
7047 let res = Some(IterableArrayIpv4Addr::with_loc(next, self.orig_loc));
7048 let Some(val) = res else { break };
7049 val
7050 }),
7051 9u16 => LinkinfoBondAttrs::ArpValidate({
7052 let res = parse_u32(next);
7053 let Some(val) = res else { break };
7054 val
7055 }),
7056 10u16 => LinkinfoBondAttrs::ArpAllTargets({
7057 let res = parse_u32(next);
7058 let Some(val) = res else { break };
7059 val
7060 }),
7061 11u16 => LinkinfoBondAttrs::Primary({
7062 let res = parse_u32(next);
7063 let Some(val) = res else { break };
7064 val
7065 }),
7066 12u16 => LinkinfoBondAttrs::PrimaryReselect({
7067 let res = parse_u8(next);
7068 let Some(val) = res else { break };
7069 val
7070 }),
7071 13u16 => LinkinfoBondAttrs::FailOverMac({
7072 let res = parse_u8(next);
7073 let Some(val) = res else { break };
7074 val
7075 }),
7076 14u16 => LinkinfoBondAttrs::XmitHashPolicy({
7077 let res = parse_u8(next);
7078 let Some(val) = res else { break };
7079 val
7080 }),
7081 15u16 => LinkinfoBondAttrs::ResendIgmp({
7082 let res = parse_u32(next);
7083 let Some(val) = res else { break };
7084 val
7085 }),
7086 16u16 => LinkinfoBondAttrs::NumPeerNotif({
7087 let res = parse_u8(next);
7088 let Some(val) = res else { break };
7089 val
7090 }),
7091 17u16 => LinkinfoBondAttrs::AllSlavesActive({
7092 let res = parse_u8(next);
7093 let Some(val) = res else { break };
7094 val
7095 }),
7096 18u16 => LinkinfoBondAttrs::MinLinks({
7097 let res = parse_u32(next);
7098 let Some(val) = res else { break };
7099 val
7100 }),
7101 19u16 => LinkinfoBondAttrs::LpInterval({
7102 let res = parse_u32(next);
7103 let Some(val) = res else { break };
7104 val
7105 }),
7106 20u16 => LinkinfoBondAttrs::PacketsPerSlave({
7107 let res = parse_u32(next);
7108 let Some(val) = res else { break };
7109 val
7110 }),
7111 21u16 => LinkinfoBondAttrs::AdLacpRate({
7112 let res = parse_u8(next);
7113 let Some(val) = res else { break };
7114 val
7115 }),
7116 22u16 => LinkinfoBondAttrs::AdSelect({
7117 let res = parse_u8(next);
7118 let Some(val) = res else { break };
7119 val
7120 }),
7121 23u16 => LinkinfoBondAttrs::AdInfo({
7122 let res = Some(IterableBondAdInfoAttrs::with_loc(next, self.orig_loc));
7123 let Some(val) = res else { break };
7124 val
7125 }),
7126 24u16 => LinkinfoBondAttrs::AdActorSysPrio({
7127 let res = parse_u16(next);
7128 let Some(val) = res else { break };
7129 val
7130 }),
7131 25u16 => LinkinfoBondAttrs::AdUserPortKey({
7132 let res = parse_u16(next);
7133 let Some(val) = res else { break };
7134 val
7135 }),
7136 26u16 => LinkinfoBondAttrs::AdActorSystem({
7137 let res = Some(next);
7138 let Some(val) = res else { break };
7139 val
7140 }),
7141 27u16 => LinkinfoBondAttrs::TlbDynamicLb({
7142 let res = parse_u8(next);
7143 let Some(val) = res else { break };
7144 val
7145 }),
7146 28u16 => LinkinfoBondAttrs::PeerNotifDelay({
7147 let res = parse_u32(next);
7148 let Some(val) = res else { break };
7149 val
7150 }),
7151 29u16 => LinkinfoBondAttrs::AdLacpActive({
7152 let res = parse_u8(next);
7153 let Some(val) = res else { break };
7154 val
7155 }),
7156 30u16 => LinkinfoBondAttrs::MissedMax({
7157 let res = parse_u8(next);
7158 let Some(val) = res else { break };
7159 val
7160 }),
7161 31u16 => LinkinfoBondAttrs::NsIp6Target({
7162 let res = Some(IterableArrayBinary::with_loc(next, self.orig_loc));
7163 let Some(val) = res else { break };
7164 val
7165 }),
7166 32u16 => LinkinfoBondAttrs::CoupledControl({
7167 let res = parse_u8(next);
7168 let Some(val) = res else { break };
7169 val
7170 }),
7171 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
7172 n => continue,
7173 };
7174 return Some(Ok(res));
7175 }
7176 Some(Err(ErrorContext::new(
7177 "LinkinfoBondAttrs",
7178 r#type.and_then(|t| LinkinfoBondAttrs::attr_from_type(t)),
7179 self.orig_loc,
7180 self.buf.as_ptr().wrapping_add(pos) as usize,
7181 )))
7182 }
7183}
7184impl std::fmt::Debug for IterableArrayIpv4Addr<'_> {
7185 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7186 fmt.debug_list()
7187 .entries(self.clone().map(FlattenErrorContext))
7188 .finish()
7189 }
7190}
7191impl std::fmt::Debug for IterableArrayBinary<'_> {
7192 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7193 fmt.debug_list()
7194 .entries(self.clone().map(FlattenErrorContext))
7195 .finish()
7196 }
7197}
7198impl<'a> std::fmt::Debug for IterableLinkinfoBondAttrs<'_> {
7199 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7200 let mut fmt = f.debug_struct("LinkinfoBondAttrs");
7201 for attr in self.clone() {
7202 let attr = match attr {
7203 Ok(a) => a,
7204 Err(err) => {
7205 fmt.finish()?;
7206 f.write_str("Err(")?;
7207 err.fmt(f)?;
7208 return f.write_str(")");
7209 }
7210 };
7211 match attr {
7212 LinkinfoBondAttrs::Mode(val) => fmt.field("Mode", &val),
7213 LinkinfoBondAttrs::ActiveSlave(val) => fmt.field("ActiveSlave", &val),
7214 LinkinfoBondAttrs::Miimon(val) => fmt.field("Miimon", &val),
7215 LinkinfoBondAttrs::Updelay(val) => fmt.field("Updelay", &val),
7216 LinkinfoBondAttrs::Downdelay(val) => fmt.field("Downdelay", &val),
7217 LinkinfoBondAttrs::UseCarrier(val) => fmt.field("UseCarrier", &val),
7218 LinkinfoBondAttrs::ArpInterval(val) => fmt.field("ArpInterval", &val),
7219 LinkinfoBondAttrs::ArpIpTarget(val) => fmt.field("ArpIpTarget", &val),
7220 LinkinfoBondAttrs::ArpValidate(val) => fmt.field("ArpValidate", &val),
7221 LinkinfoBondAttrs::ArpAllTargets(val) => fmt.field("ArpAllTargets", &val),
7222 LinkinfoBondAttrs::Primary(val) => fmt.field("Primary", &val),
7223 LinkinfoBondAttrs::PrimaryReselect(val) => fmt.field("PrimaryReselect", &val),
7224 LinkinfoBondAttrs::FailOverMac(val) => fmt.field("FailOverMac", &val),
7225 LinkinfoBondAttrs::XmitHashPolicy(val) => fmt.field("XmitHashPolicy", &val),
7226 LinkinfoBondAttrs::ResendIgmp(val) => fmt.field("ResendIgmp", &val),
7227 LinkinfoBondAttrs::NumPeerNotif(val) => fmt.field("NumPeerNotif", &val),
7228 LinkinfoBondAttrs::AllSlavesActive(val) => fmt.field("AllSlavesActive", &val),
7229 LinkinfoBondAttrs::MinLinks(val) => fmt.field("MinLinks", &val),
7230 LinkinfoBondAttrs::LpInterval(val) => fmt.field("LpInterval", &val),
7231 LinkinfoBondAttrs::PacketsPerSlave(val) => fmt.field("PacketsPerSlave", &val),
7232 LinkinfoBondAttrs::AdLacpRate(val) => fmt.field("AdLacpRate", &val),
7233 LinkinfoBondAttrs::AdSelect(val) => fmt.field("AdSelect", &val),
7234 LinkinfoBondAttrs::AdInfo(val) => fmt.field("AdInfo", &val),
7235 LinkinfoBondAttrs::AdActorSysPrio(val) => fmt.field("AdActorSysPrio", &val),
7236 LinkinfoBondAttrs::AdUserPortKey(val) => fmt.field("AdUserPortKey", &val),
7237 LinkinfoBondAttrs::AdActorSystem(val) => {
7238 fmt.field("AdActorSystem", &FormatMac(val))
7239 }
7240 LinkinfoBondAttrs::TlbDynamicLb(val) => fmt.field("TlbDynamicLb", &val),
7241 LinkinfoBondAttrs::PeerNotifDelay(val) => fmt.field("PeerNotifDelay", &val),
7242 LinkinfoBondAttrs::AdLacpActive(val) => fmt.field("AdLacpActive", &val),
7243 LinkinfoBondAttrs::MissedMax(val) => fmt.field("MissedMax", &val),
7244 LinkinfoBondAttrs::NsIp6Target(val) => fmt.field("NsIp6Target", &val),
7245 LinkinfoBondAttrs::CoupledControl(val) => fmt.field("CoupledControl", &val),
7246 };
7247 }
7248 fmt.finish()
7249 }
7250}
7251impl IterableLinkinfoBondAttrs<'_> {
7252 pub fn lookup_attr(
7253 &self,
7254 offset: usize,
7255 missing_type: Option<u16>,
7256 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7257 let mut stack = Vec::new();
7258 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
7259 if missing_type.is_some() && cur == offset {
7260 stack.push(("LinkinfoBondAttrs", offset));
7261 return (
7262 stack,
7263 missing_type.and_then(|t| LinkinfoBondAttrs::attr_from_type(t)),
7264 );
7265 }
7266 if cur > offset || cur + self.buf.len() < offset {
7267 return (stack, None);
7268 }
7269 let mut attrs = self.clone();
7270 let mut last_off = cur + attrs.pos;
7271 let mut missing = None;
7272 while let Some(attr) = attrs.next() {
7273 let Ok(attr) = attr else { break };
7274 match attr {
7275 LinkinfoBondAttrs::Mode(val) => {
7276 if last_off == offset {
7277 stack.push(("Mode", last_off));
7278 break;
7279 }
7280 }
7281 LinkinfoBondAttrs::ActiveSlave(val) => {
7282 if last_off == offset {
7283 stack.push(("ActiveSlave", last_off));
7284 break;
7285 }
7286 }
7287 LinkinfoBondAttrs::Miimon(val) => {
7288 if last_off == offset {
7289 stack.push(("Miimon", last_off));
7290 break;
7291 }
7292 }
7293 LinkinfoBondAttrs::Updelay(val) => {
7294 if last_off == offset {
7295 stack.push(("Updelay", last_off));
7296 break;
7297 }
7298 }
7299 LinkinfoBondAttrs::Downdelay(val) => {
7300 if last_off == offset {
7301 stack.push(("Downdelay", last_off));
7302 break;
7303 }
7304 }
7305 LinkinfoBondAttrs::UseCarrier(val) => {
7306 if last_off == offset {
7307 stack.push(("UseCarrier", last_off));
7308 break;
7309 }
7310 }
7311 LinkinfoBondAttrs::ArpInterval(val) => {
7312 if last_off == offset {
7313 stack.push(("ArpInterval", last_off));
7314 break;
7315 }
7316 }
7317 LinkinfoBondAttrs::ArpIpTarget(val) => {
7318 if last_off == offset {
7319 stack.push(("ArpIpTarget", last_off));
7320 break;
7321 }
7322 }
7323 LinkinfoBondAttrs::ArpValidate(val) => {
7324 if last_off == offset {
7325 stack.push(("ArpValidate", last_off));
7326 break;
7327 }
7328 }
7329 LinkinfoBondAttrs::ArpAllTargets(val) => {
7330 if last_off == offset {
7331 stack.push(("ArpAllTargets", last_off));
7332 break;
7333 }
7334 }
7335 LinkinfoBondAttrs::Primary(val) => {
7336 if last_off == offset {
7337 stack.push(("Primary", last_off));
7338 break;
7339 }
7340 }
7341 LinkinfoBondAttrs::PrimaryReselect(val) => {
7342 if last_off == offset {
7343 stack.push(("PrimaryReselect", last_off));
7344 break;
7345 }
7346 }
7347 LinkinfoBondAttrs::FailOverMac(val) => {
7348 if last_off == offset {
7349 stack.push(("FailOverMac", last_off));
7350 break;
7351 }
7352 }
7353 LinkinfoBondAttrs::XmitHashPolicy(val) => {
7354 if last_off == offset {
7355 stack.push(("XmitHashPolicy", last_off));
7356 break;
7357 }
7358 }
7359 LinkinfoBondAttrs::ResendIgmp(val) => {
7360 if last_off == offset {
7361 stack.push(("ResendIgmp", last_off));
7362 break;
7363 }
7364 }
7365 LinkinfoBondAttrs::NumPeerNotif(val) => {
7366 if last_off == offset {
7367 stack.push(("NumPeerNotif", last_off));
7368 break;
7369 }
7370 }
7371 LinkinfoBondAttrs::AllSlavesActive(val) => {
7372 if last_off == offset {
7373 stack.push(("AllSlavesActive", last_off));
7374 break;
7375 }
7376 }
7377 LinkinfoBondAttrs::MinLinks(val) => {
7378 if last_off == offset {
7379 stack.push(("MinLinks", last_off));
7380 break;
7381 }
7382 }
7383 LinkinfoBondAttrs::LpInterval(val) => {
7384 if last_off == offset {
7385 stack.push(("LpInterval", last_off));
7386 break;
7387 }
7388 }
7389 LinkinfoBondAttrs::PacketsPerSlave(val) => {
7390 if last_off == offset {
7391 stack.push(("PacketsPerSlave", last_off));
7392 break;
7393 }
7394 }
7395 LinkinfoBondAttrs::AdLacpRate(val) => {
7396 if last_off == offset {
7397 stack.push(("AdLacpRate", last_off));
7398 break;
7399 }
7400 }
7401 LinkinfoBondAttrs::AdSelect(val) => {
7402 if last_off == offset {
7403 stack.push(("AdSelect", last_off));
7404 break;
7405 }
7406 }
7407 LinkinfoBondAttrs::AdInfo(val) => {
7408 (stack, missing) = val.lookup_attr(offset, missing_type);
7409 if !stack.is_empty() {
7410 break;
7411 }
7412 }
7413 LinkinfoBondAttrs::AdActorSysPrio(val) => {
7414 if last_off == offset {
7415 stack.push(("AdActorSysPrio", last_off));
7416 break;
7417 }
7418 }
7419 LinkinfoBondAttrs::AdUserPortKey(val) => {
7420 if last_off == offset {
7421 stack.push(("AdUserPortKey", last_off));
7422 break;
7423 }
7424 }
7425 LinkinfoBondAttrs::AdActorSystem(val) => {
7426 if last_off == offset {
7427 stack.push(("AdActorSystem", last_off));
7428 break;
7429 }
7430 }
7431 LinkinfoBondAttrs::TlbDynamicLb(val) => {
7432 if last_off == offset {
7433 stack.push(("TlbDynamicLb", last_off));
7434 break;
7435 }
7436 }
7437 LinkinfoBondAttrs::PeerNotifDelay(val) => {
7438 if last_off == offset {
7439 stack.push(("PeerNotifDelay", last_off));
7440 break;
7441 }
7442 }
7443 LinkinfoBondAttrs::AdLacpActive(val) => {
7444 if last_off == offset {
7445 stack.push(("AdLacpActive", last_off));
7446 break;
7447 }
7448 }
7449 LinkinfoBondAttrs::MissedMax(val) => {
7450 if last_off == offset {
7451 stack.push(("MissedMax", last_off));
7452 break;
7453 }
7454 }
7455 LinkinfoBondAttrs::NsIp6Target(val) => {
7456 if last_off == offset {
7457 stack.push(("NsIp6Target", last_off));
7458 break;
7459 }
7460 }
7461 LinkinfoBondAttrs::CoupledControl(val) => {
7462 if last_off == offset {
7463 stack.push(("CoupledControl", last_off));
7464 break;
7465 }
7466 }
7467 _ => {}
7468 };
7469 last_off = cur + attrs.pos;
7470 }
7471 if !stack.is_empty() {
7472 stack.push(("LinkinfoBondAttrs", cur));
7473 }
7474 (stack, missing)
7475 }
7476}
7477#[derive(Clone)]
7478pub enum BondAdInfoAttrs<'a> {
7479 Aggregator(u16),
7480 NumPorts(u16),
7481 ActorKey(u16),
7482 PartnerKey(u16),
7483 PartnerMac(&'a [u8]),
7484}
7485impl<'a> IterableBondAdInfoAttrs<'a> {
7486 pub fn get_aggregator(&self) -> Result<u16, ErrorContext> {
7487 let mut iter = self.clone();
7488 iter.pos = 0;
7489 for attr in iter {
7490 if let BondAdInfoAttrs::Aggregator(val) = attr? {
7491 return Ok(val);
7492 }
7493 }
7494 Err(ErrorContext::new_missing(
7495 "BondAdInfoAttrs",
7496 "Aggregator",
7497 self.orig_loc,
7498 self.buf.as_ptr() as usize,
7499 ))
7500 }
7501 pub fn get_num_ports(&self) -> Result<u16, ErrorContext> {
7502 let mut iter = self.clone();
7503 iter.pos = 0;
7504 for attr in iter {
7505 if let BondAdInfoAttrs::NumPorts(val) = attr? {
7506 return Ok(val);
7507 }
7508 }
7509 Err(ErrorContext::new_missing(
7510 "BondAdInfoAttrs",
7511 "NumPorts",
7512 self.orig_loc,
7513 self.buf.as_ptr() as usize,
7514 ))
7515 }
7516 pub fn get_actor_key(&self) -> Result<u16, ErrorContext> {
7517 let mut iter = self.clone();
7518 iter.pos = 0;
7519 for attr in iter {
7520 if let BondAdInfoAttrs::ActorKey(val) = attr? {
7521 return Ok(val);
7522 }
7523 }
7524 Err(ErrorContext::new_missing(
7525 "BondAdInfoAttrs",
7526 "ActorKey",
7527 self.orig_loc,
7528 self.buf.as_ptr() as usize,
7529 ))
7530 }
7531 pub fn get_partner_key(&self) -> Result<u16, ErrorContext> {
7532 let mut iter = self.clone();
7533 iter.pos = 0;
7534 for attr in iter {
7535 if let BondAdInfoAttrs::PartnerKey(val) = attr? {
7536 return Ok(val);
7537 }
7538 }
7539 Err(ErrorContext::new_missing(
7540 "BondAdInfoAttrs",
7541 "PartnerKey",
7542 self.orig_loc,
7543 self.buf.as_ptr() as usize,
7544 ))
7545 }
7546 pub fn get_partner_mac(&self) -> Result<&'a [u8], ErrorContext> {
7547 let mut iter = self.clone();
7548 iter.pos = 0;
7549 for attr in iter {
7550 if let BondAdInfoAttrs::PartnerMac(val) = attr? {
7551 return Ok(val);
7552 }
7553 }
7554 Err(ErrorContext::new_missing(
7555 "BondAdInfoAttrs",
7556 "PartnerMac",
7557 self.orig_loc,
7558 self.buf.as_ptr() as usize,
7559 ))
7560 }
7561}
7562impl BondAdInfoAttrs<'_> {
7563 pub fn new<'a>(buf: &'a [u8]) -> IterableBondAdInfoAttrs<'a> {
7564 IterableBondAdInfoAttrs::with_loc(buf, buf.as_ptr() as usize)
7565 }
7566 fn attr_from_type(r#type: u16) -> Option<&'static str> {
7567 let res = match r#type {
7568 1u16 => "Aggregator",
7569 2u16 => "NumPorts",
7570 3u16 => "ActorKey",
7571 4u16 => "PartnerKey",
7572 5u16 => "PartnerMac",
7573 _ => return None,
7574 };
7575 Some(res)
7576 }
7577}
7578#[derive(Clone, Copy, Default)]
7579pub struct IterableBondAdInfoAttrs<'a> {
7580 buf: &'a [u8],
7581 pos: usize,
7582 orig_loc: usize,
7583}
7584impl<'a> IterableBondAdInfoAttrs<'a> {
7585 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
7586 Self {
7587 buf,
7588 pos: 0,
7589 orig_loc,
7590 }
7591 }
7592 pub fn get_buf(&self) -> &'a [u8] {
7593 self.buf
7594 }
7595}
7596impl<'a> Iterator for IterableBondAdInfoAttrs<'a> {
7597 type Item = Result<BondAdInfoAttrs<'a>, ErrorContext>;
7598 fn next(&mut self) -> Option<Self::Item> {
7599 let pos = self.pos;
7600 let mut r#type;
7601 loop {
7602 r#type = None;
7603 if self.buf.len() == self.pos {
7604 return None;
7605 }
7606 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
7607 break;
7608 };
7609 r#type = Some(header.r#type);
7610 let res = match header.r#type {
7611 1u16 => BondAdInfoAttrs::Aggregator({
7612 let res = parse_u16(next);
7613 let Some(val) = res else { break };
7614 val
7615 }),
7616 2u16 => BondAdInfoAttrs::NumPorts({
7617 let res = parse_u16(next);
7618 let Some(val) = res else { break };
7619 val
7620 }),
7621 3u16 => BondAdInfoAttrs::ActorKey({
7622 let res = parse_u16(next);
7623 let Some(val) = res else { break };
7624 val
7625 }),
7626 4u16 => BondAdInfoAttrs::PartnerKey({
7627 let res = parse_u16(next);
7628 let Some(val) = res else { break };
7629 val
7630 }),
7631 5u16 => BondAdInfoAttrs::PartnerMac({
7632 let res = Some(next);
7633 let Some(val) = res else { break };
7634 val
7635 }),
7636 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
7637 n => continue,
7638 };
7639 return Some(Ok(res));
7640 }
7641 Some(Err(ErrorContext::new(
7642 "BondAdInfoAttrs",
7643 r#type.and_then(|t| BondAdInfoAttrs::attr_from_type(t)),
7644 self.orig_loc,
7645 self.buf.as_ptr().wrapping_add(pos) as usize,
7646 )))
7647 }
7648}
7649impl<'a> std::fmt::Debug for IterableBondAdInfoAttrs<'_> {
7650 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7651 let mut fmt = f.debug_struct("BondAdInfoAttrs");
7652 for attr in self.clone() {
7653 let attr = match attr {
7654 Ok(a) => a,
7655 Err(err) => {
7656 fmt.finish()?;
7657 f.write_str("Err(")?;
7658 err.fmt(f)?;
7659 return f.write_str(")");
7660 }
7661 };
7662 match attr {
7663 BondAdInfoAttrs::Aggregator(val) => fmt.field("Aggregator", &val),
7664 BondAdInfoAttrs::NumPorts(val) => fmt.field("NumPorts", &val),
7665 BondAdInfoAttrs::ActorKey(val) => fmt.field("ActorKey", &val),
7666 BondAdInfoAttrs::PartnerKey(val) => fmt.field("PartnerKey", &val),
7667 BondAdInfoAttrs::PartnerMac(val) => fmt.field("PartnerMac", &FormatMac(val)),
7668 };
7669 }
7670 fmt.finish()
7671 }
7672}
7673impl IterableBondAdInfoAttrs<'_> {
7674 pub fn lookup_attr(
7675 &self,
7676 offset: usize,
7677 missing_type: Option<u16>,
7678 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7679 let mut stack = Vec::new();
7680 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
7681 if missing_type.is_some() && cur == offset {
7682 stack.push(("BondAdInfoAttrs", offset));
7683 return (
7684 stack,
7685 missing_type.and_then(|t| BondAdInfoAttrs::attr_from_type(t)),
7686 );
7687 }
7688 if cur > offset || cur + self.buf.len() < offset {
7689 return (stack, None);
7690 }
7691 let mut attrs = self.clone();
7692 let mut last_off = cur + attrs.pos;
7693 while let Some(attr) = attrs.next() {
7694 let Ok(attr) = attr else { break };
7695 match attr {
7696 BondAdInfoAttrs::Aggregator(val) => {
7697 if last_off == offset {
7698 stack.push(("Aggregator", last_off));
7699 break;
7700 }
7701 }
7702 BondAdInfoAttrs::NumPorts(val) => {
7703 if last_off == offset {
7704 stack.push(("NumPorts", last_off));
7705 break;
7706 }
7707 }
7708 BondAdInfoAttrs::ActorKey(val) => {
7709 if last_off == offset {
7710 stack.push(("ActorKey", last_off));
7711 break;
7712 }
7713 }
7714 BondAdInfoAttrs::PartnerKey(val) => {
7715 if last_off == offset {
7716 stack.push(("PartnerKey", last_off));
7717 break;
7718 }
7719 }
7720 BondAdInfoAttrs::PartnerMac(val) => {
7721 if last_off == offset {
7722 stack.push(("PartnerMac", last_off));
7723 break;
7724 }
7725 }
7726 _ => {}
7727 };
7728 last_off = cur + attrs.pos;
7729 }
7730 if !stack.is_empty() {
7731 stack.push(("BondAdInfoAttrs", cur));
7732 }
7733 (stack, None)
7734 }
7735}
7736#[derive(Clone)]
7737pub enum BondSlaveAttrs<'a> {
7738 State(u8),
7739 MiiStatus(u8),
7740 LinkFailureCount(u32),
7741 PermHwaddr(&'a [u8]),
7742 QueueId(u16),
7743 AdAggregatorId(u16),
7744 AdActorOperPortState(u8),
7745 AdPartnerOperPortState(u16),
7746 Prio(u32),
7747}
7748impl<'a> IterableBondSlaveAttrs<'a> {
7749 pub fn get_state(&self) -> Result<u8, ErrorContext> {
7750 let mut iter = self.clone();
7751 iter.pos = 0;
7752 for attr in iter {
7753 if let BondSlaveAttrs::State(val) = attr? {
7754 return Ok(val);
7755 }
7756 }
7757 Err(ErrorContext::new_missing(
7758 "BondSlaveAttrs",
7759 "State",
7760 self.orig_loc,
7761 self.buf.as_ptr() as usize,
7762 ))
7763 }
7764 pub fn get_mii_status(&self) -> Result<u8, ErrorContext> {
7765 let mut iter = self.clone();
7766 iter.pos = 0;
7767 for attr in iter {
7768 if let BondSlaveAttrs::MiiStatus(val) = attr? {
7769 return Ok(val);
7770 }
7771 }
7772 Err(ErrorContext::new_missing(
7773 "BondSlaveAttrs",
7774 "MiiStatus",
7775 self.orig_loc,
7776 self.buf.as_ptr() as usize,
7777 ))
7778 }
7779 pub fn get_link_failure_count(&self) -> Result<u32, ErrorContext> {
7780 let mut iter = self.clone();
7781 iter.pos = 0;
7782 for attr in iter {
7783 if let BondSlaveAttrs::LinkFailureCount(val) = attr? {
7784 return Ok(val);
7785 }
7786 }
7787 Err(ErrorContext::new_missing(
7788 "BondSlaveAttrs",
7789 "LinkFailureCount",
7790 self.orig_loc,
7791 self.buf.as_ptr() as usize,
7792 ))
7793 }
7794 pub fn get_perm_hwaddr(&self) -> Result<&'a [u8], ErrorContext> {
7795 let mut iter = self.clone();
7796 iter.pos = 0;
7797 for attr in iter {
7798 if let BondSlaveAttrs::PermHwaddr(val) = attr? {
7799 return Ok(val);
7800 }
7801 }
7802 Err(ErrorContext::new_missing(
7803 "BondSlaveAttrs",
7804 "PermHwaddr",
7805 self.orig_loc,
7806 self.buf.as_ptr() as usize,
7807 ))
7808 }
7809 pub fn get_queue_id(&self) -> Result<u16, ErrorContext> {
7810 let mut iter = self.clone();
7811 iter.pos = 0;
7812 for attr in iter {
7813 if let BondSlaveAttrs::QueueId(val) = attr? {
7814 return Ok(val);
7815 }
7816 }
7817 Err(ErrorContext::new_missing(
7818 "BondSlaveAttrs",
7819 "QueueId",
7820 self.orig_loc,
7821 self.buf.as_ptr() as usize,
7822 ))
7823 }
7824 pub fn get_ad_aggregator_id(&self) -> Result<u16, ErrorContext> {
7825 let mut iter = self.clone();
7826 iter.pos = 0;
7827 for attr in iter {
7828 if let BondSlaveAttrs::AdAggregatorId(val) = attr? {
7829 return Ok(val);
7830 }
7831 }
7832 Err(ErrorContext::new_missing(
7833 "BondSlaveAttrs",
7834 "AdAggregatorId",
7835 self.orig_loc,
7836 self.buf.as_ptr() as usize,
7837 ))
7838 }
7839 pub fn get_ad_actor_oper_port_state(&self) -> Result<u8, ErrorContext> {
7840 let mut iter = self.clone();
7841 iter.pos = 0;
7842 for attr in iter {
7843 if let BondSlaveAttrs::AdActorOperPortState(val) = attr? {
7844 return Ok(val);
7845 }
7846 }
7847 Err(ErrorContext::new_missing(
7848 "BondSlaveAttrs",
7849 "AdActorOperPortState",
7850 self.orig_loc,
7851 self.buf.as_ptr() as usize,
7852 ))
7853 }
7854 pub fn get_ad_partner_oper_port_state(&self) -> Result<u16, ErrorContext> {
7855 let mut iter = self.clone();
7856 iter.pos = 0;
7857 for attr in iter {
7858 if let BondSlaveAttrs::AdPartnerOperPortState(val) = attr? {
7859 return Ok(val);
7860 }
7861 }
7862 Err(ErrorContext::new_missing(
7863 "BondSlaveAttrs",
7864 "AdPartnerOperPortState",
7865 self.orig_loc,
7866 self.buf.as_ptr() as usize,
7867 ))
7868 }
7869 pub fn get_prio(&self) -> Result<u32, ErrorContext> {
7870 let mut iter = self.clone();
7871 iter.pos = 0;
7872 for attr in iter {
7873 if let BondSlaveAttrs::Prio(val) = attr? {
7874 return Ok(val);
7875 }
7876 }
7877 Err(ErrorContext::new_missing(
7878 "BondSlaveAttrs",
7879 "Prio",
7880 self.orig_loc,
7881 self.buf.as_ptr() as usize,
7882 ))
7883 }
7884}
7885impl BondSlaveAttrs<'_> {
7886 pub fn new<'a>(buf: &'a [u8]) -> IterableBondSlaveAttrs<'a> {
7887 IterableBondSlaveAttrs::with_loc(buf, buf.as_ptr() as usize)
7888 }
7889 fn attr_from_type(r#type: u16) -> Option<&'static str> {
7890 let res = match r#type {
7891 1u16 => "State",
7892 2u16 => "MiiStatus",
7893 3u16 => "LinkFailureCount",
7894 4u16 => "PermHwaddr",
7895 5u16 => "QueueId",
7896 6u16 => "AdAggregatorId",
7897 7u16 => "AdActorOperPortState",
7898 8u16 => "AdPartnerOperPortState",
7899 9u16 => "Prio",
7900 _ => return None,
7901 };
7902 Some(res)
7903 }
7904}
7905#[derive(Clone, Copy, Default)]
7906pub struct IterableBondSlaveAttrs<'a> {
7907 buf: &'a [u8],
7908 pos: usize,
7909 orig_loc: usize,
7910}
7911impl<'a> IterableBondSlaveAttrs<'a> {
7912 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
7913 Self {
7914 buf,
7915 pos: 0,
7916 orig_loc,
7917 }
7918 }
7919 pub fn get_buf(&self) -> &'a [u8] {
7920 self.buf
7921 }
7922}
7923impl<'a> Iterator for IterableBondSlaveAttrs<'a> {
7924 type Item = Result<BondSlaveAttrs<'a>, ErrorContext>;
7925 fn next(&mut self) -> Option<Self::Item> {
7926 let pos = self.pos;
7927 let mut r#type;
7928 loop {
7929 r#type = None;
7930 if self.buf.len() == self.pos {
7931 return None;
7932 }
7933 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
7934 break;
7935 };
7936 r#type = Some(header.r#type);
7937 let res = match header.r#type {
7938 1u16 => BondSlaveAttrs::State({
7939 let res = parse_u8(next);
7940 let Some(val) = res else { break };
7941 val
7942 }),
7943 2u16 => BondSlaveAttrs::MiiStatus({
7944 let res = parse_u8(next);
7945 let Some(val) = res else { break };
7946 val
7947 }),
7948 3u16 => BondSlaveAttrs::LinkFailureCount({
7949 let res = parse_u32(next);
7950 let Some(val) = res else { break };
7951 val
7952 }),
7953 4u16 => BondSlaveAttrs::PermHwaddr({
7954 let res = Some(next);
7955 let Some(val) = res else { break };
7956 val
7957 }),
7958 5u16 => BondSlaveAttrs::QueueId({
7959 let res = parse_u16(next);
7960 let Some(val) = res else { break };
7961 val
7962 }),
7963 6u16 => BondSlaveAttrs::AdAggregatorId({
7964 let res = parse_u16(next);
7965 let Some(val) = res else { break };
7966 val
7967 }),
7968 7u16 => BondSlaveAttrs::AdActorOperPortState({
7969 let res = parse_u8(next);
7970 let Some(val) = res else { break };
7971 val
7972 }),
7973 8u16 => BondSlaveAttrs::AdPartnerOperPortState({
7974 let res = parse_u16(next);
7975 let Some(val) = res else { break };
7976 val
7977 }),
7978 9u16 => BondSlaveAttrs::Prio({
7979 let res = parse_u32(next);
7980 let Some(val) = res else { break };
7981 val
7982 }),
7983 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
7984 n => continue,
7985 };
7986 return Some(Ok(res));
7987 }
7988 Some(Err(ErrorContext::new(
7989 "BondSlaveAttrs",
7990 r#type.and_then(|t| BondSlaveAttrs::attr_from_type(t)),
7991 self.orig_loc,
7992 self.buf.as_ptr().wrapping_add(pos) as usize,
7993 )))
7994 }
7995}
7996impl<'a> std::fmt::Debug for IterableBondSlaveAttrs<'_> {
7997 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7998 let mut fmt = f.debug_struct("BondSlaveAttrs");
7999 for attr in self.clone() {
8000 let attr = match attr {
8001 Ok(a) => a,
8002 Err(err) => {
8003 fmt.finish()?;
8004 f.write_str("Err(")?;
8005 err.fmt(f)?;
8006 return f.write_str(")");
8007 }
8008 };
8009 match attr {
8010 BondSlaveAttrs::State(val) => fmt.field("State", &val),
8011 BondSlaveAttrs::MiiStatus(val) => fmt.field("MiiStatus", &val),
8012 BondSlaveAttrs::LinkFailureCount(val) => fmt.field("LinkFailureCount", &val),
8013 BondSlaveAttrs::PermHwaddr(val) => fmt.field("PermHwaddr", &FormatMac(val)),
8014 BondSlaveAttrs::QueueId(val) => fmt.field("QueueId", &val),
8015 BondSlaveAttrs::AdAggregatorId(val) => fmt.field("AdAggregatorId", &val),
8016 BondSlaveAttrs::AdActorOperPortState(val) => {
8017 fmt.field("AdActorOperPortState", &val)
8018 }
8019 BondSlaveAttrs::AdPartnerOperPortState(val) => {
8020 fmt.field("AdPartnerOperPortState", &val)
8021 }
8022 BondSlaveAttrs::Prio(val) => fmt.field("Prio", &val),
8023 };
8024 }
8025 fmt.finish()
8026 }
8027}
8028impl IterableBondSlaveAttrs<'_> {
8029 pub fn lookup_attr(
8030 &self,
8031 offset: usize,
8032 missing_type: Option<u16>,
8033 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
8034 let mut stack = Vec::new();
8035 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
8036 if missing_type.is_some() && cur == offset {
8037 stack.push(("BondSlaveAttrs", offset));
8038 return (
8039 stack,
8040 missing_type.and_then(|t| BondSlaveAttrs::attr_from_type(t)),
8041 );
8042 }
8043 if cur > offset || cur + self.buf.len() < offset {
8044 return (stack, None);
8045 }
8046 let mut attrs = self.clone();
8047 let mut last_off = cur + attrs.pos;
8048 while let Some(attr) = attrs.next() {
8049 let Ok(attr) = attr else { break };
8050 match attr {
8051 BondSlaveAttrs::State(val) => {
8052 if last_off == offset {
8053 stack.push(("State", last_off));
8054 break;
8055 }
8056 }
8057 BondSlaveAttrs::MiiStatus(val) => {
8058 if last_off == offset {
8059 stack.push(("MiiStatus", last_off));
8060 break;
8061 }
8062 }
8063 BondSlaveAttrs::LinkFailureCount(val) => {
8064 if last_off == offset {
8065 stack.push(("LinkFailureCount", last_off));
8066 break;
8067 }
8068 }
8069 BondSlaveAttrs::PermHwaddr(val) => {
8070 if last_off == offset {
8071 stack.push(("PermHwaddr", last_off));
8072 break;
8073 }
8074 }
8075 BondSlaveAttrs::QueueId(val) => {
8076 if last_off == offset {
8077 stack.push(("QueueId", last_off));
8078 break;
8079 }
8080 }
8081 BondSlaveAttrs::AdAggregatorId(val) => {
8082 if last_off == offset {
8083 stack.push(("AdAggregatorId", last_off));
8084 break;
8085 }
8086 }
8087 BondSlaveAttrs::AdActorOperPortState(val) => {
8088 if last_off == offset {
8089 stack.push(("AdActorOperPortState", last_off));
8090 break;
8091 }
8092 }
8093 BondSlaveAttrs::AdPartnerOperPortState(val) => {
8094 if last_off == offset {
8095 stack.push(("AdPartnerOperPortState", last_off));
8096 break;
8097 }
8098 }
8099 BondSlaveAttrs::Prio(val) => {
8100 if last_off == offset {
8101 stack.push(("Prio", last_off));
8102 break;
8103 }
8104 }
8105 _ => {}
8106 };
8107 last_off = cur + attrs.pos;
8108 }
8109 if !stack.is_empty() {
8110 stack.push(("BondSlaveAttrs", cur));
8111 }
8112 (stack, None)
8113 }
8114}
8115#[derive(Clone)]
8116pub enum LinkinfoBridgeAttrs<'a> {
8117 ForwardDelay(u32),
8118 HelloTime(u32),
8119 MaxAge(u32),
8120 AgeingTime(u32),
8121 StpState(u32),
8122 Priority(u16),
8123 VlanFiltering(u8),
8124 VlanProtocol(u16),
8125 GroupFwdMask(u16),
8126 RootId(IflaBridgeId),
8127 BridgeId(IflaBridgeId),
8128 RootPort(u16),
8129 RootPathCost(u32),
8130 TopologyChange(u8),
8131 TopologyChangeDetected(u8),
8132 HelloTimer(u64),
8133 TcnTimer(u64),
8134 TopologyChangeTimer(u64),
8135 GcTimer(u64),
8136 GroupAddr(&'a [u8]),
8137 FdbFlush(&'a [u8]),
8138 McastRouter(u8),
8139 McastSnooping(u8),
8140 McastQueryUseIfaddr(u8),
8141 McastQuerier(u8),
8142 McastHashElasticity(u32),
8143 McastHashMax(u32),
8144 McastLastMemberCnt(u32),
8145 McastStartupQueryCnt(u32),
8146 McastLastMemberIntvl(u64),
8147 McastMembershipIntvl(u64),
8148 McastQuerierIntvl(u64),
8149 McastQueryIntvl(u64),
8150 McastQueryResponseIntvl(u64),
8151 McastStartupQueryIntvl(u64),
8152 NfCallIptables(u8),
8153 NfCallIp6tables(u8),
8154 NfCallArptables(u8),
8155 VlanDefaultPvid(u16),
8156 Pad(&'a [u8]),
8157 VlanStatsEnabled(u8),
8158 McastStatsEnabled(u8),
8159 McastIgmpVersion(u8),
8160 McastMldVersion(u8),
8161 VlanStatsPerPort(u8),
8162 MultiBoolopt(BrBooloptMulti),
8163 McastQuerierState(&'a [u8]),
8164 FdbNLearned(u32),
8165 FdbMaxLearned(u32),
8166}
8167impl<'a> IterableLinkinfoBridgeAttrs<'a> {
8168 pub fn get_forward_delay(&self) -> Result<u32, ErrorContext> {
8169 let mut iter = self.clone();
8170 iter.pos = 0;
8171 for attr in iter {
8172 if let LinkinfoBridgeAttrs::ForwardDelay(val) = attr? {
8173 return Ok(val);
8174 }
8175 }
8176 Err(ErrorContext::new_missing(
8177 "LinkinfoBridgeAttrs",
8178 "ForwardDelay",
8179 self.orig_loc,
8180 self.buf.as_ptr() as usize,
8181 ))
8182 }
8183 pub fn get_hello_time(&self) -> Result<u32, ErrorContext> {
8184 let mut iter = self.clone();
8185 iter.pos = 0;
8186 for attr in iter {
8187 if let LinkinfoBridgeAttrs::HelloTime(val) = attr? {
8188 return Ok(val);
8189 }
8190 }
8191 Err(ErrorContext::new_missing(
8192 "LinkinfoBridgeAttrs",
8193 "HelloTime",
8194 self.orig_loc,
8195 self.buf.as_ptr() as usize,
8196 ))
8197 }
8198 pub fn get_max_age(&self) -> Result<u32, ErrorContext> {
8199 let mut iter = self.clone();
8200 iter.pos = 0;
8201 for attr in iter {
8202 if let LinkinfoBridgeAttrs::MaxAge(val) = attr? {
8203 return Ok(val);
8204 }
8205 }
8206 Err(ErrorContext::new_missing(
8207 "LinkinfoBridgeAttrs",
8208 "MaxAge",
8209 self.orig_loc,
8210 self.buf.as_ptr() as usize,
8211 ))
8212 }
8213 pub fn get_ageing_time(&self) -> Result<u32, ErrorContext> {
8214 let mut iter = self.clone();
8215 iter.pos = 0;
8216 for attr in iter {
8217 if let LinkinfoBridgeAttrs::AgeingTime(val) = attr? {
8218 return Ok(val);
8219 }
8220 }
8221 Err(ErrorContext::new_missing(
8222 "LinkinfoBridgeAttrs",
8223 "AgeingTime",
8224 self.orig_loc,
8225 self.buf.as_ptr() as usize,
8226 ))
8227 }
8228 pub fn get_stp_state(&self) -> Result<u32, ErrorContext> {
8229 let mut iter = self.clone();
8230 iter.pos = 0;
8231 for attr in iter {
8232 if let LinkinfoBridgeAttrs::StpState(val) = attr? {
8233 return Ok(val);
8234 }
8235 }
8236 Err(ErrorContext::new_missing(
8237 "LinkinfoBridgeAttrs",
8238 "StpState",
8239 self.orig_loc,
8240 self.buf.as_ptr() as usize,
8241 ))
8242 }
8243 pub fn get_priority(&self) -> Result<u16, ErrorContext> {
8244 let mut iter = self.clone();
8245 iter.pos = 0;
8246 for attr in iter {
8247 if let LinkinfoBridgeAttrs::Priority(val) = attr? {
8248 return Ok(val);
8249 }
8250 }
8251 Err(ErrorContext::new_missing(
8252 "LinkinfoBridgeAttrs",
8253 "Priority",
8254 self.orig_loc,
8255 self.buf.as_ptr() as usize,
8256 ))
8257 }
8258 pub fn get_vlan_filtering(&self) -> Result<u8, ErrorContext> {
8259 let mut iter = self.clone();
8260 iter.pos = 0;
8261 for attr in iter {
8262 if let LinkinfoBridgeAttrs::VlanFiltering(val) = attr? {
8263 return Ok(val);
8264 }
8265 }
8266 Err(ErrorContext::new_missing(
8267 "LinkinfoBridgeAttrs",
8268 "VlanFiltering",
8269 self.orig_loc,
8270 self.buf.as_ptr() as usize,
8271 ))
8272 }
8273 pub fn get_vlan_protocol(&self) -> Result<u16, ErrorContext> {
8274 let mut iter = self.clone();
8275 iter.pos = 0;
8276 for attr in iter {
8277 if let LinkinfoBridgeAttrs::VlanProtocol(val) = attr? {
8278 return Ok(val);
8279 }
8280 }
8281 Err(ErrorContext::new_missing(
8282 "LinkinfoBridgeAttrs",
8283 "VlanProtocol",
8284 self.orig_loc,
8285 self.buf.as_ptr() as usize,
8286 ))
8287 }
8288 pub fn get_group_fwd_mask(&self) -> Result<u16, ErrorContext> {
8289 let mut iter = self.clone();
8290 iter.pos = 0;
8291 for attr in iter {
8292 if let LinkinfoBridgeAttrs::GroupFwdMask(val) = attr? {
8293 return Ok(val);
8294 }
8295 }
8296 Err(ErrorContext::new_missing(
8297 "LinkinfoBridgeAttrs",
8298 "GroupFwdMask",
8299 self.orig_loc,
8300 self.buf.as_ptr() as usize,
8301 ))
8302 }
8303 pub fn get_root_id(&self) -> Result<IflaBridgeId, ErrorContext> {
8304 let mut iter = self.clone();
8305 iter.pos = 0;
8306 for attr in iter {
8307 if let LinkinfoBridgeAttrs::RootId(val) = attr? {
8308 return Ok(val);
8309 }
8310 }
8311 Err(ErrorContext::new_missing(
8312 "LinkinfoBridgeAttrs",
8313 "RootId",
8314 self.orig_loc,
8315 self.buf.as_ptr() as usize,
8316 ))
8317 }
8318 pub fn get_bridge_id(&self) -> Result<IflaBridgeId, ErrorContext> {
8319 let mut iter = self.clone();
8320 iter.pos = 0;
8321 for attr in iter {
8322 if let LinkinfoBridgeAttrs::BridgeId(val) = attr? {
8323 return Ok(val);
8324 }
8325 }
8326 Err(ErrorContext::new_missing(
8327 "LinkinfoBridgeAttrs",
8328 "BridgeId",
8329 self.orig_loc,
8330 self.buf.as_ptr() as usize,
8331 ))
8332 }
8333 pub fn get_root_port(&self) -> Result<u16, ErrorContext> {
8334 let mut iter = self.clone();
8335 iter.pos = 0;
8336 for attr in iter {
8337 if let LinkinfoBridgeAttrs::RootPort(val) = attr? {
8338 return Ok(val);
8339 }
8340 }
8341 Err(ErrorContext::new_missing(
8342 "LinkinfoBridgeAttrs",
8343 "RootPort",
8344 self.orig_loc,
8345 self.buf.as_ptr() as usize,
8346 ))
8347 }
8348 pub fn get_root_path_cost(&self) -> Result<u32, ErrorContext> {
8349 let mut iter = self.clone();
8350 iter.pos = 0;
8351 for attr in iter {
8352 if let LinkinfoBridgeAttrs::RootPathCost(val) = attr? {
8353 return Ok(val);
8354 }
8355 }
8356 Err(ErrorContext::new_missing(
8357 "LinkinfoBridgeAttrs",
8358 "RootPathCost",
8359 self.orig_loc,
8360 self.buf.as_ptr() as usize,
8361 ))
8362 }
8363 pub fn get_topology_change(&self) -> Result<u8, ErrorContext> {
8364 let mut iter = self.clone();
8365 iter.pos = 0;
8366 for attr in iter {
8367 if let LinkinfoBridgeAttrs::TopologyChange(val) = attr? {
8368 return Ok(val);
8369 }
8370 }
8371 Err(ErrorContext::new_missing(
8372 "LinkinfoBridgeAttrs",
8373 "TopologyChange",
8374 self.orig_loc,
8375 self.buf.as_ptr() as usize,
8376 ))
8377 }
8378 pub fn get_topology_change_detected(&self) -> Result<u8, ErrorContext> {
8379 let mut iter = self.clone();
8380 iter.pos = 0;
8381 for attr in iter {
8382 if let LinkinfoBridgeAttrs::TopologyChangeDetected(val) = attr? {
8383 return Ok(val);
8384 }
8385 }
8386 Err(ErrorContext::new_missing(
8387 "LinkinfoBridgeAttrs",
8388 "TopologyChangeDetected",
8389 self.orig_loc,
8390 self.buf.as_ptr() as usize,
8391 ))
8392 }
8393 pub fn get_hello_timer(&self) -> Result<u64, ErrorContext> {
8394 let mut iter = self.clone();
8395 iter.pos = 0;
8396 for attr in iter {
8397 if let LinkinfoBridgeAttrs::HelloTimer(val) = attr? {
8398 return Ok(val);
8399 }
8400 }
8401 Err(ErrorContext::new_missing(
8402 "LinkinfoBridgeAttrs",
8403 "HelloTimer",
8404 self.orig_loc,
8405 self.buf.as_ptr() as usize,
8406 ))
8407 }
8408 pub fn get_tcn_timer(&self) -> Result<u64, ErrorContext> {
8409 let mut iter = self.clone();
8410 iter.pos = 0;
8411 for attr in iter {
8412 if let LinkinfoBridgeAttrs::TcnTimer(val) = attr? {
8413 return Ok(val);
8414 }
8415 }
8416 Err(ErrorContext::new_missing(
8417 "LinkinfoBridgeAttrs",
8418 "TcnTimer",
8419 self.orig_loc,
8420 self.buf.as_ptr() as usize,
8421 ))
8422 }
8423 pub fn get_topology_change_timer(&self) -> Result<u64, ErrorContext> {
8424 let mut iter = self.clone();
8425 iter.pos = 0;
8426 for attr in iter {
8427 if let LinkinfoBridgeAttrs::TopologyChangeTimer(val) = attr? {
8428 return Ok(val);
8429 }
8430 }
8431 Err(ErrorContext::new_missing(
8432 "LinkinfoBridgeAttrs",
8433 "TopologyChangeTimer",
8434 self.orig_loc,
8435 self.buf.as_ptr() as usize,
8436 ))
8437 }
8438 pub fn get_gc_timer(&self) -> Result<u64, ErrorContext> {
8439 let mut iter = self.clone();
8440 iter.pos = 0;
8441 for attr in iter {
8442 if let LinkinfoBridgeAttrs::GcTimer(val) = attr? {
8443 return Ok(val);
8444 }
8445 }
8446 Err(ErrorContext::new_missing(
8447 "LinkinfoBridgeAttrs",
8448 "GcTimer",
8449 self.orig_loc,
8450 self.buf.as_ptr() as usize,
8451 ))
8452 }
8453 pub fn get_group_addr(&self) -> Result<&'a [u8], ErrorContext> {
8454 let mut iter = self.clone();
8455 iter.pos = 0;
8456 for attr in iter {
8457 if let LinkinfoBridgeAttrs::GroupAddr(val) = attr? {
8458 return Ok(val);
8459 }
8460 }
8461 Err(ErrorContext::new_missing(
8462 "LinkinfoBridgeAttrs",
8463 "GroupAddr",
8464 self.orig_loc,
8465 self.buf.as_ptr() as usize,
8466 ))
8467 }
8468 pub fn get_fdb_flush(&self) -> Result<&'a [u8], ErrorContext> {
8469 let mut iter = self.clone();
8470 iter.pos = 0;
8471 for attr in iter {
8472 if let LinkinfoBridgeAttrs::FdbFlush(val) = attr? {
8473 return Ok(val);
8474 }
8475 }
8476 Err(ErrorContext::new_missing(
8477 "LinkinfoBridgeAttrs",
8478 "FdbFlush",
8479 self.orig_loc,
8480 self.buf.as_ptr() as usize,
8481 ))
8482 }
8483 pub fn get_mcast_router(&self) -> Result<u8, ErrorContext> {
8484 let mut iter = self.clone();
8485 iter.pos = 0;
8486 for attr in iter {
8487 if let LinkinfoBridgeAttrs::McastRouter(val) = attr? {
8488 return Ok(val);
8489 }
8490 }
8491 Err(ErrorContext::new_missing(
8492 "LinkinfoBridgeAttrs",
8493 "McastRouter",
8494 self.orig_loc,
8495 self.buf.as_ptr() as usize,
8496 ))
8497 }
8498 pub fn get_mcast_snooping(&self) -> Result<u8, ErrorContext> {
8499 let mut iter = self.clone();
8500 iter.pos = 0;
8501 for attr in iter {
8502 if let LinkinfoBridgeAttrs::McastSnooping(val) = attr? {
8503 return Ok(val);
8504 }
8505 }
8506 Err(ErrorContext::new_missing(
8507 "LinkinfoBridgeAttrs",
8508 "McastSnooping",
8509 self.orig_loc,
8510 self.buf.as_ptr() as usize,
8511 ))
8512 }
8513 pub fn get_mcast_query_use_ifaddr(&self) -> Result<u8, ErrorContext> {
8514 let mut iter = self.clone();
8515 iter.pos = 0;
8516 for attr in iter {
8517 if let LinkinfoBridgeAttrs::McastQueryUseIfaddr(val) = attr? {
8518 return Ok(val);
8519 }
8520 }
8521 Err(ErrorContext::new_missing(
8522 "LinkinfoBridgeAttrs",
8523 "McastQueryUseIfaddr",
8524 self.orig_loc,
8525 self.buf.as_ptr() as usize,
8526 ))
8527 }
8528 pub fn get_mcast_querier(&self) -> Result<u8, ErrorContext> {
8529 let mut iter = self.clone();
8530 iter.pos = 0;
8531 for attr in iter {
8532 if let LinkinfoBridgeAttrs::McastQuerier(val) = attr? {
8533 return Ok(val);
8534 }
8535 }
8536 Err(ErrorContext::new_missing(
8537 "LinkinfoBridgeAttrs",
8538 "McastQuerier",
8539 self.orig_loc,
8540 self.buf.as_ptr() as usize,
8541 ))
8542 }
8543 pub fn get_mcast_hash_elasticity(&self) -> Result<u32, ErrorContext> {
8544 let mut iter = self.clone();
8545 iter.pos = 0;
8546 for attr in iter {
8547 if let LinkinfoBridgeAttrs::McastHashElasticity(val) = attr? {
8548 return Ok(val);
8549 }
8550 }
8551 Err(ErrorContext::new_missing(
8552 "LinkinfoBridgeAttrs",
8553 "McastHashElasticity",
8554 self.orig_loc,
8555 self.buf.as_ptr() as usize,
8556 ))
8557 }
8558 pub fn get_mcast_hash_max(&self) -> Result<u32, ErrorContext> {
8559 let mut iter = self.clone();
8560 iter.pos = 0;
8561 for attr in iter {
8562 if let LinkinfoBridgeAttrs::McastHashMax(val) = attr? {
8563 return Ok(val);
8564 }
8565 }
8566 Err(ErrorContext::new_missing(
8567 "LinkinfoBridgeAttrs",
8568 "McastHashMax",
8569 self.orig_loc,
8570 self.buf.as_ptr() as usize,
8571 ))
8572 }
8573 pub fn get_mcast_last_member_cnt(&self) -> Result<u32, ErrorContext> {
8574 let mut iter = self.clone();
8575 iter.pos = 0;
8576 for attr in iter {
8577 if let LinkinfoBridgeAttrs::McastLastMemberCnt(val) = attr? {
8578 return Ok(val);
8579 }
8580 }
8581 Err(ErrorContext::new_missing(
8582 "LinkinfoBridgeAttrs",
8583 "McastLastMemberCnt",
8584 self.orig_loc,
8585 self.buf.as_ptr() as usize,
8586 ))
8587 }
8588 pub fn get_mcast_startup_query_cnt(&self) -> Result<u32, ErrorContext> {
8589 let mut iter = self.clone();
8590 iter.pos = 0;
8591 for attr in iter {
8592 if let LinkinfoBridgeAttrs::McastStartupQueryCnt(val) = attr? {
8593 return Ok(val);
8594 }
8595 }
8596 Err(ErrorContext::new_missing(
8597 "LinkinfoBridgeAttrs",
8598 "McastStartupQueryCnt",
8599 self.orig_loc,
8600 self.buf.as_ptr() as usize,
8601 ))
8602 }
8603 pub fn get_mcast_last_member_intvl(&self) -> Result<u64, ErrorContext> {
8604 let mut iter = self.clone();
8605 iter.pos = 0;
8606 for attr in iter {
8607 if let LinkinfoBridgeAttrs::McastLastMemberIntvl(val) = attr? {
8608 return Ok(val);
8609 }
8610 }
8611 Err(ErrorContext::new_missing(
8612 "LinkinfoBridgeAttrs",
8613 "McastLastMemberIntvl",
8614 self.orig_loc,
8615 self.buf.as_ptr() as usize,
8616 ))
8617 }
8618 pub fn get_mcast_membership_intvl(&self) -> Result<u64, ErrorContext> {
8619 let mut iter = self.clone();
8620 iter.pos = 0;
8621 for attr in iter {
8622 if let LinkinfoBridgeAttrs::McastMembershipIntvl(val) = attr? {
8623 return Ok(val);
8624 }
8625 }
8626 Err(ErrorContext::new_missing(
8627 "LinkinfoBridgeAttrs",
8628 "McastMembershipIntvl",
8629 self.orig_loc,
8630 self.buf.as_ptr() as usize,
8631 ))
8632 }
8633 pub fn get_mcast_querier_intvl(&self) -> Result<u64, ErrorContext> {
8634 let mut iter = self.clone();
8635 iter.pos = 0;
8636 for attr in iter {
8637 if let LinkinfoBridgeAttrs::McastQuerierIntvl(val) = attr? {
8638 return Ok(val);
8639 }
8640 }
8641 Err(ErrorContext::new_missing(
8642 "LinkinfoBridgeAttrs",
8643 "McastQuerierIntvl",
8644 self.orig_loc,
8645 self.buf.as_ptr() as usize,
8646 ))
8647 }
8648 pub fn get_mcast_query_intvl(&self) -> Result<u64, ErrorContext> {
8649 let mut iter = self.clone();
8650 iter.pos = 0;
8651 for attr in iter {
8652 if let LinkinfoBridgeAttrs::McastQueryIntvl(val) = attr? {
8653 return Ok(val);
8654 }
8655 }
8656 Err(ErrorContext::new_missing(
8657 "LinkinfoBridgeAttrs",
8658 "McastQueryIntvl",
8659 self.orig_loc,
8660 self.buf.as_ptr() as usize,
8661 ))
8662 }
8663 pub fn get_mcast_query_response_intvl(&self) -> Result<u64, ErrorContext> {
8664 let mut iter = self.clone();
8665 iter.pos = 0;
8666 for attr in iter {
8667 if let LinkinfoBridgeAttrs::McastQueryResponseIntvl(val) = attr? {
8668 return Ok(val);
8669 }
8670 }
8671 Err(ErrorContext::new_missing(
8672 "LinkinfoBridgeAttrs",
8673 "McastQueryResponseIntvl",
8674 self.orig_loc,
8675 self.buf.as_ptr() as usize,
8676 ))
8677 }
8678 pub fn get_mcast_startup_query_intvl(&self) -> Result<u64, ErrorContext> {
8679 let mut iter = self.clone();
8680 iter.pos = 0;
8681 for attr in iter {
8682 if let LinkinfoBridgeAttrs::McastStartupQueryIntvl(val) = attr? {
8683 return Ok(val);
8684 }
8685 }
8686 Err(ErrorContext::new_missing(
8687 "LinkinfoBridgeAttrs",
8688 "McastStartupQueryIntvl",
8689 self.orig_loc,
8690 self.buf.as_ptr() as usize,
8691 ))
8692 }
8693 pub fn get_nf_call_iptables(&self) -> Result<u8, ErrorContext> {
8694 let mut iter = self.clone();
8695 iter.pos = 0;
8696 for attr in iter {
8697 if let LinkinfoBridgeAttrs::NfCallIptables(val) = attr? {
8698 return Ok(val);
8699 }
8700 }
8701 Err(ErrorContext::new_missing(
8702 "LinkinfoBridgeAttrs",
8703 "NfCallIptables",
8704 self.orig_loc,
8705 self.buf.as_ptr() as usize,
8706 ))
8707 }
8708 pub fn get_nf_call_ip6tables(&self) -> Result<u8, ErrorContext> {
8709 let mut iter = self.clone();
8710 iter.pos = 0;
8711 for attr in iter {
8712 if let LinkinfoBridgeAttrs::NfCallIp6tables(val) = attr? {
8713 return Ok(val);
8714 }
8715 }
8716 Err(ErrorContext::new_missing(
8717 "LinkinfoBridgeAttrs",
8718 "NfCallIp6tables",
8719 self.orig_loc,
8720 self.buf.as_ptr() as usize,
8721 ))
8722 }
8723 pub fn get_nf_call_arptables(&self) -> Result<u8, ErrorContext> {
8724 let mut iter = self.clone();
8725 iter.pos = 0;
8726 for attr in iter {
8727 if let LinkinfoBridgeAttrs::NfCallArptables(val) = attr? {
8728 return Ok(val);
8729 }
8730 }
8731 Err(ErrorContext::new_missing(
8732 "LinkinfoBridgeAttrs",
8733 "NfCallArptables",
8734 self.orig_loc,
8735 self.buf.as_ptr() as usize,
8736 ))
8737 }
8738 pub fn get_vlan_default_pvid(&self) -> Result<u16, ErrorContext> {
8739 let mut iter = self.clone();
8740 iter.pos = 0;
8741 for attr in iter {
8742 if let LinkinfoBridgeAttrs::VlanDefaultPvid(val) = attr? {
8743 return Ok(val);
8744 }
8745 }
8746 Err(ErrorContext::new_missing(
8747 "LinkinfoBridgeAttrs",
8748 "VlanDefaultPvid",
8749 self.orig_loc,
8750 self.buf.as_ptr() as usize,
8751 ))
8752 }
8753 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
8754 let mut iter = self.clone();
8755 iter.pos = 0;
8756 for attr in iter {
8757 if let LinkinfoBridgeAttrs::Pad(val) = attr? {
8758 return Ok(val);
8759 }
8760 }
8761 Err(ErrorContext::new_missing(
8762 "LinkinfoBridgeAttrs",
8763 "Pad",
8764 self.orig_loc,
8765 self.buf.as_ptr() as usize,
8766 ))
8767 }
8768 pub fn get_vlan_stats_enabled(&self) -> Result<u8, ErrorContext> {
8769 let mut iter = self.clone();
8770 iter.pos = 0;
8771 for attr in iter {
8772 if let LinkinfoBridgeAttrs::VlanStatsEnabled(val) = attr? {
8773 return Ok(val);
8774 }
8775 }
8776 Err(ErrorContext::new_missing(
8777 "LinkinfoBridgeAttrs",
8778 "VlanStatsEnabled",
8779 self.orig_loc,
8780 self.buf.as_ptr() as usize,
8781 ))
8782 }
8783 pub fn get_mcast_stats_enabled(&self) -> Result<u8, ErrorContext> {
8784 let mut iter = self.clone();
8785 iter.pos = 0;
8786 for attr in iter {
8787 if let LinkinfoBridgeAttrs::McastStatsEnabled(val) = attr? {
8788 return Ok(val);
8789 }
8790 }
8791 Err(ErrorContext::new_missing(
8792 "LinkinfoBridgeAttrs",
8793 "McastStatsEnabled",
8794 self.orig_loc,
8795 self.buf.as_ptr() as usize,
8796 ))
8797 }
8798 pub fn get_mcast_igmp_version(&self) -> Result<u8, ErrorContext> {
8799 let mut iter = self.clone();
8800 iter.pos = 0;
8801 for attr in iter {
8802 if let LinkinfoBridgeAttrs::McastIgmpVersion(val) = attr? {
8803 return Ok(val);
8804 }
8805 }
8806 Err(ErrorContext::new_missing(
8807 "LinkinfoBridgeAttrs",
8808 "McastIgmpVersion",
8809 self.orig_loc,
8810 self.buf.as_ptr() as usize,
8811 ))
8812 }
8813 pub fn get_mcast_mld_version(&self) -> Result<u8, ErrorContext> {
8814 let mut iter = self.clone();
8815 iter.pos = 0;
8816 for attr in iter {
8817 if let LinkinfoBridgeAttrs::McastMldVersion(val) = attr? {
8818 return Ok(val);
8819 }
8820 }
8821 Err(ErrorContext::new_missing(
8822 "LinkinfoBridgeAttrs",
8823 "McastMldVersion",
8824 self.orig_loc,
8825 self.buf.as_ptr() as usize,
8826 ))
8827 }
8828 pub fn get_vlan_stats_per_port(&self) -> Result<u8, ErrorContext> {
8829 let mut iter = self.clone();
8830 iter.pos = 0;
8831 for attr in iter {
8832 if let LinkinfoBridgeAttrs::VlanStatsPerPort(val) = attr? {
8833 return Ok(val);
8834 }
8835 }
8836 Err(ErrorContext::new_missing(
8837 "LinkinfoBridgeAttrs",
8838 "VlanStatsPerPort",
8839 self.orig_loc,
8840 self.buf.as_ptr() as usize,
8841 ))
8842 }
8843 pub fn get_multi_boolopt(&self) -> Result<BrBooloptMulti, ErrorContext> {
8844 let mut iter = self.clone();
8845 iter.pos = 0;
8846 for attr in iter {
8847 if let LinkinfoBridgeAttrs::MultiBoolopt(val) = attr? {
8848 return Ok(val);
8849 }
8850 }
8851 Err(ErrorContext::new_missing(
8852 "LinkinfoBridgeAttrs",
8853 "MultiBoolopt",
8854 self.orig_loc,
8855 self.buf.as_ptr() as usize,
8856 ))
8857 }
8858 pub fn get_mcast_querier_state(&self) -> Result<&'a [u8], ErrorContext> {
8859 let mut iter = self.clone();
8860 iter.pos = 0;
8861 for attr in iter {
8862 if let LinkinfoBridgeAttrs::McastQuerierState(val) = attr? {
8863 return Ok(val);
8864 }
8865 }
8866 Err(ErrorContext::new_missing(
8867 "LinkinfoBridgeAttrs",
8868 "McastQuerierState",
8869 self.orig_loc,
8870 self.buf.as_ptr() as usize,
8871 ))
8872 }
8873 pub fn get_fdb_n_learned(&self) -> Result<u32, ErrorContext> {
8874 let mut iter = self.clone();
8875 iter.pos = 0;
8876 for attr in iter {
8877 if let LinkinfoBridgeAttrs::FdbNLearned(val) = attr? {
8878 return Ok(val);
8879 }
8880 }
8881 Err(ErrorContext::new_missing(
8882 "LinkinfoBridgeAttrs",
8883 "FdbNLearned",
8884 self.orig_loc,
8885 self.buf.as_ptr() as usize,
8886 ))
8887 }
8888 pub fn get_fdb_max_learned(&self) -> Result<u32, ErrorContext> {
8889 let mut iter = self.clone();
8890 iter.pos = 0;
8891 for attr in iter {
8892 if let LinkinfoBridgeAttrs::FdbMaxLearned(val) = attr? {
8893 return Ok(val);
8894 }
8895 }
8896 Err(ErrorContext::new_missing(
8897 "LinkinfoBridgeAttrs",
8898 "FdbMaxLearned",
8899 self.orig_loc,
8900 self.buf.as_ptr() as usize,
8901 ))
8902 }
8903}
8904impl LinkinfoBridgeAttrs<'_> {
8905 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoBridgeAttrs<'a> {
8906 IterableLinkinfoBridgeAttrs::with_loc(buf, buf.as_ptr() as usize)
8907 }
8908 fn attr_from_type(r#type: u16) -> Option<&'static str> {
8909 let res = match r#type {
8910 1u16 => "ForwardDelay",
8911 2u16 => "HelloTime",
8912 3u16 => "MaxAge",
8913 4u16 => "AgeingTime",
8914 5u16 => "StpState",
8915 6u16 => "Priority",
8916 7u16 => "VlanFiltering",
8917 8u16 => "VlanProtocol",
8918 9u16 => "GroupFwdMask",
8919 10u16 => "RootId",
8920 11u16 => "BridgeId",
8921 12u16 => "RootPort",
8922 13u16 => "RootPathCost",
8923 14u16 => "TopologyChange",
8924 15u16 => "TopologyChangeDetected",
8925 16u16 => "HelloTimer",
8926 17u16 => "TcnTimer",
8927 18u16 => "TopologyChangeTimer",
8928 19u16 => "GcTimer",
8929 20u16 => "GroupAddr",
8930 21u16 => "FdbFlush",
8931 22u16 => "McastRouter",
8932 23u16 => "McastSnooping",
8933 24u16 => "McastQueryUseIfaddr",
8934 25u16 => "McastQuerier",
8935 26u16 => "McastHashElasticity",
8936 27u16 => "McastHashMax",
8937 28u16 => "McastLastMemberCnt",
8938 29u16 => "McastStartupQueryCnt",
8939 30u16 => "McastLastMemberIntvl",
8940 31u16 => "McastMembershipIntvl",
8941 32u16 => "McastQuerierIntvl",
8942 33u16 => "McastQueryIntvl",
8943 34u16 => "McastQueryResponseIntvl",
8944 35u16 => "McastStartupQueryIntvl",
8945 36u16 => "NfCallIptables",
8946 37u16 => "NfCallIp6tables",
8947 38u16 => "NfCallArptables",
8948 39u16 => "VlanDefaultPvid",
8949 40u16 => "Pad",
8950 41u16 => "VlanStatsEnabled",
8951 42u16 => "McastStatsEnabled",
8952 43u16 => "McastIgmpVersion",
8953 44u16 => "McastMldVersion",
8954 45u16 => "VlanStatsPerPort",
8955 46u16 => "MultiBoolopt",
8956 47u16 => "McastQuerierState",
8957 48u16 => "FdbNLearned",
8958 49u16 => "FdbMaxLearned",
8959 _ => return None,
8960 };
8961 Some(res)
8962 }
8963}
8964#[derive(Clone, Copy, Default)]
8965pub struct IterableLinkinfoBridgeAttrs<'a> {
8966 buf: &'a [u8],
8967 pos: usize,
8968 orig_loc: usize,
8969}
8970impl<'a> IterableLinkinfoBridgeAttrs<'a> {
8971 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
8972 Self {
8973 buf,
8974 pos: 0,
8975 orig_loc,
8976 }
8977 }
8978 pub fn get_buf(&self) -> &'a [u8] {
8979 self.buf
8980 }
8981}
8982impl<'a> Iterator for IterableLinkinfoBridgeAttrs<'a> {
8983 type Item = Result<LinkinfoBridgeAttrs<'a>, ErrorContext>;
8984 fn next(&mut self) -> Option<Self::Item> {
8985 let pos = self.pos;
8986 let mut r#type;
8987 loop {
8988 r#type = None;
8989 if self.buf.len() == self.pos {
8990 return None;
8991 }
8992 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
8993 break;
8994 };
8995 r#type = Some(header.r#type);
8996 let res = match header.r#type {
8997 1u16 => LinkinfoBridgeAttrs::ForwardDelay({
8998 let res = parse_u32(next);
8999 let Some(val) = res else { break };
9000 val
9001 }),
9002 2u16 => LinkinfoBridgeAttrs::HelloTime({
9003 let res = parse_u32(next);
9004 let Some(val) = res else { break };
9005 val
9006 }),
9007 3u16 => LinkinfoBridgeAttrs::MaxAge({
9008 let res = parse_u32(next);
9009 let Some(val) = res else { break };
9010 val
9011 }),
9012 4u16 => LinkinfoBridgeAttrs::AgeingTime({
9013 let res = parse_u32(next);
9014 let Some(val) = res else { break };
9015 val
9016 }),
9017 5u16 => LinkinfoBridgeAttrs::StpState({
9018 let res = parse_u32(next);
9019 let Some(val) = res else { break };
9020 val
9021 }),
9022 6u16 => LinkinfoBridgeAttrs::Priority({
9023 let res = parse_u16(next);
9024 let Some(val) = res else { break };
9025 val
9026 }),
9027 7u16 => LinkinfoBridgeAttrs::VlanFiltering({
9028 let res = parse_u8(next);
9029 let Some(val) = res else { break };
9030 val
9031 }),
9032 8u16 => LinkinfoBridgeAttrs::VlanProtocol({
9033 let res = parse_u16(next);
9034 let Some(val) = res else { break };
9035 val
9036 }),
9037 9u16 => LinkinfoBridgeAttrs::GroupFwdMask({
9038 let res = parse_u16(next);
9039 let Some(val) = res else { break };
9040 val
9041 }),
9042 10u16 => LinkinfoBridgeAttrs::RootId({
9043 let res = Some(IflaBridgeId::new_from_zeroed(next));
9044 let Some(val) = res else { break };
9045 val
9046 }),
9047 11u16 => LinkinfoBridgeAttrs::BridgeId({
9048 let res = Some(IflaBridgeId::new_from_zeroed(next));
9049 let Some(val) = res else { break };
9050 val
9051 }),
9052 12u16 => LinkinfoBridgeAttrs::RootPort({
9053 let res = parse_u16(next);
9054 let Some(val) = res else { break };
9055 val
9056 }),
9057 13u16 => LinkinfoBridgeAttrs::RootPathCost({
9058 let res = parse_u32(next);
9059 let Some(val) = res else { break };
9060 val
9061 }),
9062 14u16 => LinkinfoBridgeAttrs::TopologyChange({
9063 let res = parse_u8(next);
9064 let Some(val) = res else { break };
9065 val
9066 }),
9067 15u16 => LinkinfoBridgeAttrs::TopologyChangeDetected({
9068 let res = parse_u8(next);
9069 let Some(val) = res else { break };
9070 val
9071 }),
9072 16u16 => LinkinfoBridgeAttrs::HelloTimer({
9073 let res = parse_u64(next);
9074 let Some(val) = res else { break };
9075 val
9076 }),
9077 17u16 => LinkinfoBridgeAttrs::TcnTimer({
9078 let res = parse_u64(next);
9079 let Some(val) = res else { break };
9080 val
9081 }),
9082 18u16 => LinkinfoBridgeAttrs::TopologyChangeTimer({
9083 let res = parse_u64(next);
9084 let Some(val) = res else { break };
9085 val
9086 }),
9087 19u16 => LinkinfoBridgeAttrs::GcTimer({
9088 let res = parse_u64(next);
9089 let Some(val) = res else { break };
9090 val
9091 }),
9092 20u16 => LinkinfoBridgeAttrs::GroupAddr({
9093 let res = Some(next);
9094 let Some(val) = res else { break };
9095 val
9096 }),
9097 21u16 => LinkinfoBridgeAttrs::FdbFlush({
9098 let res = Some(next);
9099 let Some(val) = res else { break };
9100 val
9101 }),
9102 22u16 => LinkinfoBridgeAttrs::McastRouter({
9103 let res = parse_u8(next);
9104 let Some(val) = res else { break };
9105 val
9106 }),
9107 23u16 => LinkinfoBridgeAttrs::McastSnooping({
9108 let res = parse_u8(next);
9109 let Some(val) = res else { break };
9110 val
9111 }),
9112 24u16 => LinkinfoBridgeAttrs::McastQueryUseIfaddr({
9113 let res = parse_u8(next);
9114 let Some(val) = res else { break };
9115 val
9116 }),
9117 25u16 => LinkinfoBridgeAttrs::McastQuerier({
9118 let res = parse_u8(next);
9119 let Some(val) = res else { break };
9120 val
9121 }),
9122 26u16 => LinkinfoBridgeAttrs::McastHashElasticity({
9123 let res = parse_u32(next);
9124 let Some(val) = res else { break };
9125 val
9126 }),
9127 27u16 => LinkinfoBridgeAttrs::McastHashMax({
9128 let res = parse_u32(next);
9129 let Some(val) = res else { break };
9130 val
9131 }),
9132 28u16 => LinkinfoBridgeAttrs::McastLastMemberCnt({
9133 let res = parse_u32(next);
9134 let Some(val) = res else { break };
9135 val
9136 }),
9137 29u16 => LinkinfoBridgeAttrs::McastStartupQueryCnt({
9138 let res = parse_u32(next);
9139 let Some(val) = res else { break };
9140 val
9141 }),
9142 30u16 => LinkinfoBridgeAttrs::McastLastMemberIntvl({
9143 let res = parse_u64(next);
9144 let Some(val) = res else { break };
9145 val
9146 }),
9147 31u16 => LinkinfoBridgeAttrs::McastMembershipIntvl({
9148 let res = parse_u64(next);
9149 let Some(val) = res else { break };
9150 val
9151 }),
9152 32u16 => LinkinfoBridgeAttrs::McastQuerierIntvl({
9153 let res = parse_u64(next);
9154 let Some(val) = res else { break };
9155 val
9156 }),
9157 33u16 => LinkinfoBridgeAttrs::McastQueryIntvl({
9158 let res = parse_u64(next);
9159 let Some(val) = res else { break };
9160 val
9161 }),
9162 34u16 => LinkinfoBridgeAttrs::McastQueryResponseIntvl({
9163 let res = parse_u64(next);
9164 let Some(val) = res else { break };
9165 val
9166 }),
9167 35u16 => LinkinfoBridgeAttrs::McastStartupQueryIntvl({
9168 let res = parse_u64(next);
9169 let Some(val) = res else { break };
9170 val
9171 }),
9172 36u16 => LinkinfoBridgeAttrs::NfCallIptables({
9173 let res = parse_u8(next);
9174 let Some(val) = res else { break };
9175 val
9176 }),
9177 37u16 => LinkinfoBridgeAttrs::NfCallIp6tables({
9178 let res = parse_u8(next);
9179 let Some(val) = res else { break };
9180 val
9181 }),
9182 38u16 => LinkinfoBridgeAttrs::NfCallArptables({
9183 let res = parse_u8(next);
9184 let Some(val) = res else { break };
9185 val
9186 }),
9187 39u16 => LinkinfoBridgeAttrs::VlanDefaultPvid({
9188 let res = parse_u16(next);
9189 let Some(val) = res else { break };
9190 val
9191 }),
9192 40u16 => LinkinfoBridgeAttrs::Pad({
9193 let res = Some(next);
9194 let Some(val) = res else { break };
9195 val
9196 }),
9197 41u16 => LinkinfoBridgeAttrs::VlanStatsEnabled({
9198 let res = parse_u8(next);
9199 let Some(val) = res else { break };
9200 val
9201 }),
9202 42u16 => LinkinfoBridgeAttrs::McastStatsEnabled({
9203 let res = parse_u8(next);
9204 let Some(val) = res else { break };
9205 val
9206 }),
9207 43u16 => LinkinfoBridgeAttrs::McastIgmpVersion({
9208 let res = parse_u8(next);
9209 let Some(val) = res else { break };
9210 val
9211 }),
9212 44u16 => LinkinfoBridgeAttrs::McastMldVersion({
9213 let res = parse_u8(next);
9214 let Some(val) = res else { break };
9215 val
9216 }),
9217 45u16 => LinkinfoBridgeAttrs::VlanStatsPerPort({
9218 let res = parse_u8(next);
9219 let Some(val) = res else { break };
9220 val
9221 }),
9222 46u16 => LinkinfoBridgeAttrs::MultiBoolopt({
9223 let res = Some(BrBooloptMulti::new_from_zeroed(next));
9224 let Some(val) = res else { break };
9225 val
9226 }),
9227 47u16 => LinkinfoBridgeAttrs::McastQuerierState({
9228 let res = Some(next);
9229 let Some(val) = res else { break };
9230 val
9231 }),
9232 48u16 => LinkinfoBridgeAttrs::FdbNLearned({
9233 let res = parse_u32(next);
9234 let Some(val) = res else { break };
9235 val
9236 }),
9237 49u16 => LinkinfoBridgeAttrs::FdbMaxLearned({
9238 let res = parse_u32(next);
9239 let Some(val) = res else { break };
9240 val
9241 }),
9242 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
9243 n => continue,
9244 };
9245 return Some(Ok(res));
9246 }
9247 Some(Err(ErrorContext::new(
9248 "LinkinfoBridgeAttrs",
9249 r#type.and_then(|t| LinkinfoBridgeAttrs::attr_from_type(t)),
9250 self.orig_loc,
9251 self.buf.as_ptr().wrapping_add(pos) as usize,
9252 )))
9253 }
9254}
9255impl<'a> std::fmt::Debug for IterableLinkinfoBridgeAttrs<'_> {
9256 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9257 let mut fmt = f.debug_struct("LinkinfoBridgeAttrs");
9258 for attr in self.clone() {
9259 let attr = match attr {
9260 Ok(a) => a,
9261 Err(err) => {
9262 fmt.finish()?;
9263 f.write_str("Err(")?;
9264 err.fmt(f)?;
9265 return f.write_str(")");
9266 }
9267 };
9268 match attr {
9269 LinkinfoBridgeAttrs::ForwardDelay(val) => fmt.field("ForwardDelay", &val),
9270 LinkinfoBridgeAttrs::HelloTime(val) => fmt.field("HelloTime", &val),
9271 LinkinfoBridgeAttrs::MaxAge(val) => fmt.field("MaxAge", &val),
9272 LinkinfoBridgeAttrs::AgeingTime(val) => fmt.field("AgeingTime", &val),
9273 LinkinfoBridgeAttrs::StpState(val) => fmt.field("StpState", &val),
9274 LinkinfoBridgeAttrs::Priority(val) => fmt.field("Priority", &val),
9275 LinkinfoBridgeAttrs::VlanFiltering(val) => fmt.field("VlanFiltering", &val),
9276 LinkinfoBridgeAttrs::VlanProtocol(val) => fmt.field("VlanProtocol", &val),
9277 LinkinfoBridgeAttrs::GroupFwdMask(val) => fmt.field("GroupFwdMask", &val),
9278 LinkinfoBridgeAttrs::RootId(val) => fmt.field("RootId", &val),
9279 LinkinfoBridgeAttrs::BridgeId(val) => fmt.field("BridgeId", &val),
9280 LinkinfoBridgeAttrs::RootPort(val) => fmt.field("RootPort", &val),
9281 LinkinfoBridgeAttrs::RootPathCost(val) => fmt.field("RootPathCost", &val),
9282 LinkinfoBridgeAttrs::TopologyChange(val) => fmt.field("TopologyChange", &val),
9283 LinkinfoBridgeAttrs::TopologyChangeDetected(val) => {
9284 fmt.field("TopologyChangeDetected", &val)
9285 }
9286 LinkinfoBridgeAttrs::HelloTimer(val) => fmt.field("HelloTimer", &val),
9287 LinkinfoBridgeAttrs::TcnTimer(val) => fmt.field("TcnTimer", &val),
9288 LinkinfoBridgeAttrs::TopologyChangeTimer(val) => {
9289 fmt.field("TopologyChangeTimer", &val)
9290 }
9291 LinkinfoBridgeAttrs::GcTimer(val) => fmt.field("GcTimer", &val),
9292 LinkinfoBridgeAttrs::GroupAddr(val) => fmt.field("GroupAddr", &FormatMac(val)),
9293 LinkinfoBridgeAttrs::FdbFlush(val) => fmt.field("FdbFlush", &val),
9294 LinkinfoBridgeAttrs::McastRouter(val) => fmt.field("McastRouter", &val),
9295 LinkinfoBridgeAttrs::McastSnooping(val) => fmt.field("McastSnooping", &val),
9296 LinkinfoBridgeAttrs::McastQueryUseIfaddr(val) => {
9297 fmt.field("McastQueryUseIfaddr", &val)
9298 }
9299 LinkinfoBridgeAttrs::McastQuerier(val) => fmt.field("McastQuerier", &val),
9300 LinkinfoBridgeAttrs::McastHashElasticity(val) => {
9301 fmt.field("McastHashElasticity", &val)
9302 }
9303 LinkinfoBridgeAttrs::McastHashMax(val) => fmt.field("McastHashMax", &val),
9304 LinkinfoBridgeAttrs::McastLastMemberCnt(val) => {
9305 fmt.field("McastLastMemberCnt", &val)
9306 }
9307 LinkinfoBridgeAttrs::McastStartupQueryCnt(val) => {
9308 fmt.field("McastStartupQueryCnt", &val)
9309 }
9310 LinkinfoBridgeAttrs::McastLastMemberIntvl(val) => {
9311 fmt.field("McastLastMemberIntvl", &val)
9312 }
9313 LinkinfoBridgeAttrs::McastMembershipIntvl(val) => {
9314 fmt.field("McastMembershipIntvl", &val)
9315 }
9316 LinkinfoBridgeAttrs::McastQuerierIntvl(val) => fmt.field("McastQuerierIntvl", &val),
9317 LinkinfoBridgeAttrs::McastQueryIntvl(val) => fmt.field("McastQueryIntvl", &val),
9318 LinkinfoBridgeAttrs::McastQueryResponseIntvl(val) => {
9319 fmt.field("McastQueryResponseIntvl", &val)
9320 }
9321 LinkinfoBridgeAttrs::McastStartupQueryIntvl(val) => {
9322 fmt.field("McastStartupQueryIntvl", &val)
9323 }
9324 LinkinfoBridgeAttrs::NfCallIptables(val) => fmt.field("NfCallIptables", &val),
9325 LinkinfoBridgeAttrs::NfCallIp6tables(val) => fmt.field("NfCallIp6tables", &val),
9326 LinkinfoBridgeAttrs::NfCallArptables(val) => fmt.field("NfCallArptables", &val),
9327 LinkinfoBridgeAttrs::VlanDefaultPvid(val) => fmt.field("VlanDefaultPvid", &val),
9328 LinkinfoBridgeAttrs::Pad(val) => fmt.field("Pad", &val),
9329 LinkinfoBridgeAttrs::VlanStatsEnabled(val) => fmt.field("VlanStatsEnabled", &val),
9330 LinkinfoBridgeAttrs::McastStatsEnabled(val) => fmt.field("McastStatsEnabled", &val),
9331 LinkinfoBridgeAttrs::McastIgmpVersion(val) => fmt.field("McastIgmpVersion", &val),
9332 LinkinfoBridgeAttrs::McastMldVersion(val) => fmt.field("McastMldVersion", &val),
9333 LinkinfoBridgeAttrs::VlanStatsPerPort(val) => fmt.field("VlanStatsPerPort", &val),
9334 LinkinfoBridgeAttrs::MultiBoolopt(val) => fmt.field("MultiBoolopt", &val),
9335 LinkinfoBridgeAttrs::McastQuerierState(val) => fmt.field("McastQuerierState", &val),
9336 LinkinfoBridgeAttrs::FdbNLearned(val) => fmt.field("FdbNLearned", &val),
9337 LinkinfoBridgeAttrs::FdbMaxLearned(val) => fmt.field("FdbMaxLearned", &val),
9338 };
9339 }
9340 fmt.finish()
9341 }
9342}
9343impl IterableLinkinfoBridgeAttrs<'_> {
9344 pub fn lookup_attr(
9345 &self,
9346 offset: usize,
9347 missing_type: Option<u16>,
9348 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
9349 let mut stack = Vec::new();
9350 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
9351 if missing_type.is_some() && cur == offset {
9352 stack.push(("LinkinfoBridgeAttrs", offset));
9353 return (
9354 stack,
9355 missing_type.and_then(|t| LinkinfoBridgeAttrs::attr_from_type(t)),
9356 );
9357 }
9358 if cur > offset || cur + self.buf.len() < offset {
9359 return (stack, None);
9360 }
9361 let mut attrs = self.clone();
9362 let mut last_off = cur + attrs.pos;
9363 while let Some(attr) = attrs.next() {
9364 let Ok(attr) = attr else { break };
9365 match attr {
9366 LinkinfoBridgeAttrs::ForwardDelay(val) => {
9367 if last_off == offset {
9368 stack.push(("ForwardDelay", last_off));
9369 break;
9370 }
9371 }
9372 LinkinfoBridgeAttrs::HelloTime(val) => {
9373 if last_off == offset {
9374 stack.push(("HelloTime", last_off));
9375 break;
9376 }
9377 }
9378 LinkinfoBridgeAttrs::MaxAge(val) => {
9379 if last_off == offset {
9380 stack.push(("MaxAge", last_off));
9381 break;
9382 }
9383 }
9384 LinkinfoBridgeAttrs::AgeingTime(val) => {
9385 if last_off == offset {
9386 stack.push(("AgeingTime", last_off));
9387 break;
9388 }
9389 }
9390 LinkinfoBridgeAttrs::StpState(val) => {
9391 if last_off == offset {
9392 stack.push(("StpState", last_off));
9393 break;
9394 }
9395 }
9396 LinkinfoBridgeAttrs::Priority(val) => {
9397 if last_off == offset {
9398 stack.push(("Priority", last_off));
9399 break;
9400 }
9401 }
9402 LinkinfoBridgeAttrs::VlanFiltering(val) => {
9403 if last_off == offset {
9404 stack.push(("VlanFiltering", last_off));
9405 break;
9406 }
9407 }
9408 LinkinfoBridgeAttrs::VlanProtocol(val) => {
9409 if last_off == offset {
9410 stack.push(("VlanProtocol", last_off));
9411 break;
9412 }
9413 }
9414 LinkinfoBridgeAttrs::GroupFwdMask(val) => {
9415 if last_off == offset {
9416 stack.push(("GroupFwdMask", last_off));
9417 break;
9418 }
9419 }
9420 LinkinfoBridgeAttrs::RootId(val) => {
9421 if last_off == offset {
9422 stack.push(("RootId", last_off));
9423 break;
9424 }
9425 }
9426 LinkinfoBridgeAttrs::BridgeId(val) => {
9427 if last_off == offset {
9428 stack.push(("BridgeId", last_off));
9429 break;
9430 }
9431 }
9432 LinkinfoBridgeAttrs::RootPort(val) => {
9433 if last_off == offset {
9434 stack.push(("RootPort", last_off));
9435 break;
9436 }
9437 }
9438 LinkinfoBridgeAttrs::RootPathCost(val) => {
9439 if last_off == offset {
9440 stack.push(("RootPathCost", last_off));
9441 break;
9442 }
9443 }
9444 LinkinfoBridgeAttrs::TopologyChange(val) => {
9445 if last_off == offset {
9446 stack.push(("TopologyChange", last_off));
9447 break;
9448 }
9449 }
9450 LinkinfoBridgeAttrs::TopologyChangeDetected(val) => {
9451 if last_off == offset {
9452 stack.push(("TopologyChangeDetected", last_off));
9453 break;
9454 }
9455 }
9456 LinkinfoBridgeAttrs::HelloTimer(val) => {
9457 if last_off == offset {
9458 stack.push(("HelloTimer", last_off));
9459 break;
9460 }
9461 }
9462 LinkinfoBridgeAttrs::TcnTimer(val) => {
9463 if last_off == offset {
9464 stack.push(("TcnTimer", last_off));
9465 break;
9466 }
9467 }
9468 LinkinfoBridgeAttrs::TopologyChangeTimer(val) => {
9469 if last_off == offset {
9470 stack.push(("TopologyChangeTimer", last_off));
9471 break;
9472 }
9473 }
9474 LinkinfoBridgeAttrs::GcTimer(val) => {
9475 if last_off == offset {
9476 stack.push(("GcTimer", last_off));
9477 break;
9478 }
9479 }
9480 LinkinfoBridgeAttrs::GroupAddr(val) => {
9481 if last_off == offset {
9482 stack.push(("GroupAddr", last_off));
9483 break;
9484 }
9485 }
9486 LinkinfoBridgeAttrs::FdbFlush(val) => {
9487 if last_off == offset {
9488 stack.push(("FdbFlush", last_off));
9489 break;
9490 }
9491 }
9492 LinkinfoBridgeAttrs::McastRouter(val) => {
9493 if last_off == offset {
9494 stack.push(("McastRouter", last_off));
9495 break;
9496 }
9497 }
9498 LinkinfoBridgeAttrs::McastSnooping(val) => {
9499 if last_off == offset {
9500 stack.push(("McastSnooping", last_off));
9501 break;
9502 }
9503 }
9504 LinkinfoBridgeAttrs::McastQueryUseIfaddr(val) => {
9505 if last_off == offset {
9506 stack.push(("McastQueryUseIfaddr", last_off));
9507 break;
9508 }
9509 }
9510 LinkinfoBridgeAttrs::McastQuerier(val) => {
9511 if last_off == offset {
9512 stack.push(("McastQuerier", last_off));
9513 break;
9514 }
9515 }
9516 LinkinfoBridgeAttrs::McastHashElasticity(val) => {
9517 if last_off == offset {
9518 stack.push(("McastHashElasticity", last_off));
9519 break;
9520 }
9521 }
9522 LinkinfoBridgeAttrs::McastHashMax(val) => {
9523 if last_off == offset {
9524 stack.push(("McastHashMax", last_off));
9525 break;
9526 }
9527 }
9528 LinkinfoBridgeAttrs::McastLastMemberCnt(val) => {
9529 if last_off == offset {
9530 stack.push(("McastLastMemberCnt", last_off));
9531 break;
9532 }
9533 }
9534 LinkinfoBridgeAttrs::McastStartupQueryCnt(val) => {
9535 if last_off == offset {
9536 stack.push(("McastStartupQueryCnt", last_off));
9537 break;
9538 }
9539 }
9540 LinkinfoBridgeAttrs::McastLastMemberIntvl(val) => {
9541 if last_off == offset {
9542 stack.push(("McastLastMemberIntvl", last_off));
9543 break;
9544 }
9545 }
9546 LinkinfoBridgeAttrs::McastMembershipIntvl(val) => {
9547 if last_off == offset {
9548 stack.push(("McastMembershipIntvl", last_off));
9549 break;
9550 }
9551 }
9552 LinkinfoBridgeAttrs::McastQuerierIntvl(val) => {
9553 if last_off == offset {
9554 stack.push(("McastQuerierIntvl", last_off));
9555 break;
9556 }
9557 }
9558 LinkinfoBridgeAttrs::McastQueryIntvl(val) => {
9559 if last_off == offset {
9560 stack.push(("McastQueryIntvl", last_off));
9561 break;
9562 }
9563 }
9564 LinkinfoBridgeAttrs::McastQueryResponseIntvl(val) => {
9565 if last_off == offset {
9566 stack.push(("McastQueryResponseIntvl", last_off));
9567 break;
9568 }
9569 }
9570 LinkinfoBridgeAttrs::McastStartupQueryIntvl(val) => {
9571 if last_off == offset {
9572 stack.push(("McastStartupQueryIntvl", last_off));
9573 break;
9574 }
9575 }
9576 LinkinfoBridgeAttrs::NfCallIptables(val) => {
9577 if last_off == offset {
9578 stack.push(("NfCallIptables", last_off));
9579 break;
9580 }
9581 }
9582 LinkinfoBridgeAttrs::NfCallIp6tables(val) => {
9583 if last_off == offset {
9584 stack.push(("NfCallIp6tables", last_off));
9585 break;
9586 }
9587 }
9588 LinkinfoBridgeAttrs::NfCallArptables(val) => {
9589 if last_off == offset {
9590 stack.push(("NfCallArptables", last_off));
9591 break;
9592 }
9593 }
9594 LinkinfoBridgeAttrs::VlanDefaultPvid(val) => {
9595 if last_off == offset {
9596 stack.push(("VlanDefaultPvid", last_off));
9597 break;
9598 }
9599 }
9600 LinkinfoBridgeAttrs::Pad(val) => {
9601 if last_off == offset {
9602 stack.push(("Pad", last_off));
9603 break;
9604 }
9605 }
9606 LinkinfoBridgeAttrs::VlanStatsEnabled(val) => {
9607 if last_off == offset {
9608 stack.push(("VlanStatsEnabled", last_off));
9609 break;
9610 }
9611 }
9612 LinkinfoBridgeAttrs::McastStatsEnabled(val) => {
9613 if last_off == offset {
9614 stack.push(("McastStatsEnabled", last_off));
9615 break;
9616 }
9617 }
9618 LinkinfoBridgeAttrs::McastIgmpVersion(val) => {
9619 if last_off == offset {
9620 stack.push(("McastIgmpVersion", last_off));
9621 break;
9622 }
9623 }
9624 LinkinfoBridgeAttrs::McastMldVersion(val) => {
9625 if last_off == offset {
9626 stack.push(("McastMldVersion", last_off));
9627 break;
9628 }
9629 }
9630 LinkinfoBridgeAttrs::VlanStatsPerPort(val) => {
9631 if last_off == offset {
9632 stack.push(("VlanStatsPerPort", last_off));
9633 break;
9634 }
9635 }
9636 LinkinfoBridgeAttrs::MultiBoolopt(val) => {
9637 if last_off == offset {
9638 stack.push(("MultiBoolopt", last_off));
9639 break;
9640 }
9641 }
9642 LinkinfoBridgeAttrs::McastQuerierState(val) => {
9643 if last_off == offset {
9644 stack.push(("McastQuerierState", last_off));
9645 break;
9646 }
9647 }
9648 LinkinfoBridgeAttrs::FdbNLearned(val) => {
9649 if last_off == offset {
9650 stack.push(("FdbNLearned", last_off));
9651 break;
9652 }
9653 }
9654 LinkinfoBridgeAttrs::FdbMaxLearned(val) => {
9655 if last_off == offset {
9656 stack.push(("FdbMaxLearned", last_off));
9657 break;
9658 }
9659 }
9660 _ => {}
9661 };
9662 last_off = cur + attrs.pos;
9663 }
9664 if !stack.is_empty() {
9665 stack.push(("LinkinfoBridgeAttrs", cur));
9666 }
9667 (stack, None)
9668 }
9669}
9670#[derive(Clone)]
9671pub enum LinkinfoBrportAttrs<'a> {
9672 State(u8),
9673 Priority(u16),
9674 Cost(u32),
9675 Mode(()),
9676 Guard(()),
9677 Protect(()),
9678 FastLeave(()),
9679 Learning(()),
9680 UnicastFlood(()),
9681 Proxyarp(()),
9682 LearningSync(()),
9683 ProxyarpWifi(()),
9684 RootId(IflaBridgeId),
9685 BridgeId(IflaBridgeId),
9686 DesignatedPort(u16),
9687 DesignatedCost(u16),
9688 Id(u16),
9689 No(u16),
9690 TopologyChangeAck(u8),
9691 ConfigPending(u8),
9692 MessageAgeTimer(u64),
9693 ForwardDelayTimer(u64),
9694 HoldTimer(u64),
9695 Flush(()),
9696 MulticastRouter(u8),
9697 Pad(&'a [u8]),
9698 McastFlood(()),
9699 McastToUcast(()),
9700 VlanTunnel(()),
9701 BcastFlood(()),
9702 GroupFwdMask(u16),
9703 NeighSuppress(()),
9704 Isolated(()),
9705 BackupPort(u32),
9706 MrpRingOpen(()),
9707 MrpInOpen(()),
9708 McastEhtHostsLimit(u32),
9709 McastEhtHostsCnt(u32),
9710 Locked(()),
9711 Mab(()),
9712 McastNGroups(u32),
9713 McastMaxGroups(u32),
9714 NeighVlanSuppress(()),
9715 BackupNhid(u32),
9716}
9717impl<'a> IterableLinkinfoBrportAttrs<'a> {
9718 pub fn get_state(&self) -> Result<u8, ErrorContext> {
9719 let mut iter = self.clone();
9720 iter.pos = 0;
9721 for attr in iter {
9722 if let LinkinfoBrportAttrs::State(val) = attr? {
9723 return Ok(val);
9724 }
9725 }
9726 Err(ErrorContext::new_missing(
9727 "LinkinfoBrportAttrs",
9728 "State",
9729 self.orig_loc,
9730 self.buf.as_ptr() as usize,
9731 ))
9732 }
9733 pub fn get_priority(&self) -> Result<u16, ErrorContext> {
9734 let mut iter = self.clone();
9735 iter.pos = 0;
9736 for attr in iter {
9737 if let LinkinfoBrportAttrs::Priority(val) = attr? {
9738 return Ok(val);
9739 }
9740 }
9741 Err(ErrorContext::new_missing(
9742 "LinkinfoBrportAttrs",
9743 "Priority",
9744 self.orig_loc,
9745 self.buf.as_ptr() as usize,
9746 ))
9747 }
9748 pub fn get_cost(&self) -> Result<u32, ErrorContext> {
9749 let mut iter = self.clone();
9750 iter.pos = 0;
9751 for attr in iter {
9752 if let LinkinfoBrportAttrs::Cost(val) = attr? {
9753 return Ok(val);
9754 }
9755 }
9756 Err(ErrorContext::new_missing(
9757 "LinkinfoBrportAttrs",
9758 "Cost",
9759 self.orig_loc,
9760 self.buf.as_ptr() as usize,
9761 ))
9762 }
9763 pub fn get_mode(&self) -> Result<(), ErrorContext> {
9764 let mut iter = self.clone();
9765 iter.pos = 0;
9766 for attr in iter {
9767 if let LinkinfoBrportAttrs::Mode(val) = attr? {
9768 return Ok(val);
9769 }
9770 }
9771 Err(ErrorContext::new_missing(
9772 "LinkinfoBrportAttrs",
9773 "Mode",
9774 self.orig_loc,
9775 self.buf.as_ptr() as usize,
9776 ))
9777 }
9778 pub fn get_guard(&self) -> Result<(), ErrorContext> {
9779 let mut iter = self.clone();
9780 iter.pos = 0;
9781 for attr in iter {
9782 if let LinkinfoBrportAttrs::Guard(val) = attr? {
9783 return Ok(val);
9784 }
9785 }
9786 Err(ErrorContext::new_missing(
9787 "LinkinfoBrportAttrs",
9788 "Guard",
9789 self.orig_loc,
9790 self.buf.as_ptr() as usize,
9791 ))
9792 }
9793 pub fn get_protect(&self) -> Result<(), ErrorContext> {
9794 let mut iter = self.clone();
9795 iter.pos = 0;
9796 for attr in iter {
9797 if let LinkinfoBrportAttrs::Protect(val) = attr? {
9798 return Ok(val);
9799 }
9800 }
9801 Err(ErrorContext::new_missing(
9802 "LinkinfoBrportAttrs",
9803 "Protect",
9804 self.orig_loc,
9805 self.buf.as_ptr() as usize,
9806 ))
9807 }
9808 pub fn get_fast_leave(&self) -> Result<(), ErrorContext> {
9809 let mut iter = self.clone();
9810 iter.pos = 0;
9811 for attr in iter {
9812 if let LinkinfoBrportAttrs::FastLeave(val) = attr? {
9813 return Ok(val);
9814 }
9815 }
9816 Err(ErrorContext::new_missing(
9817 "LinkinfoBrportAttrs",
9818 "FastLeave",
9819 self.orig_loc,
9820 self.buf.as_ptr() as usize,
9821 ))
9822 }
9823 pub fn get_learning(&self) -> Result<(), ErrorContext> {
9824 let mut iter = self.clone();
9825 iter.pos = 0;
9826 for attr in iter {
9827 if let LinkinfoBrportAttrs::Learning(val) = attr? {
9828 return Ok(val);
9829 }
9830 }
9831 Err(ErrorContext::new_missing(
9832 "LinkinfoBrportAttrs",
9833 "Learning",
9834 self.orig_loc,
9835 self.buf.as_ptr() as usize,
9836 ))
9837 }
9838 pub fn get_unicast_flood(&self) -> Result<(), ErrorContext> {
9839 let mut iter = self.clone();
9840 iter.pos = 0;
9841 for attr in iter {
9842 if let LinkinfoBrportAttrs::UnicastFlood(val) = attr? {
9843 return Ok(val);
9844 }
9845 }
9846 Err(ErrorContext::new_missing(
9847 "LinkinfoBrportAttrs",
9848 "UnicastFlood",
9849 self.orig_loc,
9850 self.buf.as_ptr() as usize,
9851 ))
9852 }
9853 pub fn get_proxyarp(&self) -> Result<(), ErrorContext> {
9854 let mut iter = self.clone();
9855 iter.pos = 0;
9856 for attr in iter {
9857 if let LinkinfoBrportAttrs::Proxyarp(val) = attr? {
9858 return Ok(val);
9859 }
9860 }
9861 Err(ErrorContext::new_missing(
9862 "LinkinfoBrportAttrs",
9863 "Proxyarp",
9864 self.orig_loc,
9865 self.buf.as_ptr() as usize,
9866 ))
9867 }
9868 pub fn get_learning_sync(&self) -> Result<(), ErrorContext> {
9869 let mut iter = self.clone();
9870 iter.pos = 0;
9871 for attr in iter {
9872 if let LinkinfoBrportAttrs::LearningSync(val) = attr? {
9873 return Ok(val);
9874 }
9875 }
9876 Err(ErrorContext::new_missing(
9877 "LinkinfoBrportAttrs",
9878 "LearningSync",
9879 self.orig_loc,
9880 self.buf.as_ptr() as usize,
9881 ))
9882 }
9883 pub fn get_proxyarp_wifi(&self) -> Result<(), ErrorContext> {
9884 let mut iter = self.clone();
9885 iter.pos = 0;
9886 for attr in iter {
9887 if let LinkinfoBrportAttrs::ProxyarpWifi(val) = attr? {
9888 return Ok(val);
9889 }
9890 }
9891 Err(ErrorContext::new_missing(
9892 "LinkinfoBrportAttrs",
9893 "ProxyarpWifi",
9894 self.orig_loc,
9895 self.buf.as_ptr() as usize,
9896 ))
9897 }
9898 pub fn get_root_id(&self) -> Result<IflaBridgeId, ErrorContext> {
9899 let mut iter = self.clone();
9900 iter.pos = 0;
9901 for attr in iter {
9902 if let LinkinfoBrportAttrs::RootId(val) = attr? {
9903 return Ok(val);
9904 }
9905 }
9906 Err(ErrorContext::new_missing(
9907 "LinkinfoBrportAttrs",
9908 "RootId",
9909 self.orig_loc,
9910 self.buf.as_ptr() as usize,
9911 ))
9912 }
9913 pub fn get_bridge_id(&self) -> Result<IflaBridgeId, ErrorContext> {
9914 let mut iter = self.clone();
9915 iter.pos = 0;
9916 for attr in iter {
9917 if let LinkinfoBrportAttrs::BridgeId(val) = attr? {
9918 return Ok(val);
9919 }
9920 }
9921 Err(ErrorContext::new_missing(
9922 "LinkinfoBrportAttrs",
9923 "BridgeId",
9924 self.orig_loc,
9925 self.buf.as_ptr() as usize,
9926 ))
9927 }
9928 pub fn get_designated_port(&self) -> Result<u16, ErrorContext> {
9929 let mut iter = self.clone();
9930 iter.pos = 0;
9931 for attr in iter {
9932 if let LinkinfoBrportAttrs::DesignatedPort(val) = attr? {
9933 return Ok(val);
9934 }
9935 }
9936 Err(ErrorContext::new_missing(
9937 "LinkinfoBrportAttrs",
9938 "DesignatedPort",
9939 self.orig_loc,
9940 self.buf.as_ptr() as usize,
9941 ))
9942 }
9943 pub fn get_designated_cost(&self) -> Result<u16, ErrorContext> {
9944 let mut iter = self.clone();
9945 iter.pos = 0;
9946 for attr in iter {
9947 if let LinkinfoBrportAttrs::DesignatedCost(val) = attr? {
9948 return Ok(val);
9949 }
9950 }
9951 Err(ErrorContext::new_missing(
9952 "LinkinfoBrportAttrs",
9953 "DesignatedCost",
9954 self.orig_loc,
9955 self.buf.as_ptr() as usize,
9956 ))
9957 }
9958 pub fn get_id(&self) -> Result<u16, ErrorContext> {
9959 let mut iter = self.clone();
9960 iter.pos = 0;
9961 for attr in iter {
9962 if let LinkinfoBrportAttrs::Id(val) = attr? {
9963 return Ok(val);
9964 }
9965 }
9966 Err(ErrorContext::new_missing(
9967 "LinkinfoBrportAttrs",
9968 "Id",
9969 self.orig_loc,
9970 self.buf.as_ptr() as usize,
9971 ))
9972 }
9973 pub fn get_no(&self) -> Result<u16, ErrorContext> {
9974 let mut iter = self.clone();
9975 iter.pos = 0;
9976 for attr in iter {
9977 if let LinkinfoBrportAttrs::No(val) = attr? {
9978 return Ok(val);
9979 }
9980 }
9981 Err(ErrorContext::new_missing(
9982 "LinkinfoBrportAttrs",
9983 "No",
9984 self.orig_loc,
9985 self.buf.as_ptr() as usize,
9986 ))
9987 }
9988 pub fn get_topology_change_ack(&self) -> Result<u8, ErrorContext> {
9989 let mut iter = self.clone();
9990 iter.pos = 0;
9991 for attr in iter {
9992 if let LinkinfoBrportAttrs::TopologyChangeAck(val) = attr? {
9993 return Ok(val);
9994 }
9995 }
9996 Err(ErrorContext::new_missing(
9997 "LinkinfoBrportAttrs",
9998 "TopologyChangeAck",
9999 self.orig_loc,
10000 self.buf.as_ptr() as usize,
10001 ))
10002 }
10003 pub fn get_config_pending(&self) -> Result<u8, ErrorContext> {
10004 let mut iter = self.clone();
10005 iter.pos = 0;
10006 for attr in iter {
10007 if let LinkinfoBrportAttrs::ConfigPending(val) = attr? {
10008 return Ok(val);
10009 }
10010 }
10011 Err(ErrorContext::new_missing(
10012 "LinkinfoBrportAttrs",
10013 "ConfigPending",
10014 self.orig_loc,
10015 self.buf.as_ptr() as usize,
10016 ))
10017 }
10018 pub fn get_message_age_timer(&self) -> Result<u64, ErrorContext> {
10019 let mut iter = self.clone();
10020 iter.pos = 0;
10021 for attr in iter {
10022 if let LinkinfoBrportAttrs::MessageAgeTimer(val) = attr? {
10023 return Ok(val);
10024 }
10025 }
10026 Err(ErrorContext::new_missing(
10027 "LinkinfoBrportAttrs",
10028 "MessageAgeTimer",
10029 self.orig_loc,
10030 self.buf.as_ptr() as usize,
10031 ))
10032 }
10033 pub fn get_forward_delay_timer(&self) -> Result<u64, ErrorContext> {
10034 let mut iter = self.clone();
10035 iter.pos = 0;
10036 for attr in iter {
10037 if let LinkinfoBrportAttrs::ForwardDelayTimer(val) = attr? {
10038 return Ok(val);
10039 }
10040 }
10041 Err(ErrorContext::new_missing(
10042 "LinkinfoBrportAttrs",
10043 "ForwardDelayTimer",
10044 self.orig_loc,
10045 self.buf.as_ptr() as usize,
10046 ))
10047 }
10048 pub fn get_hold_timer(&self) -> Result<u64, ErrorContext> {
10049 let mut iter = self.clone();
10050 iter.pos = 0;
10051 for attr in iter {
10052 if let LinkinfoBrportAttrs::HoldTimer(val) = attr? {
10053 return Ok(val);
10054 }
10055 }
10056 Err(ErrorContext::new_missing(
10057 "LinkinfoBrportAttrs",
10058 "HoldTimer",
10059 self.orig_loc,
10060 self.buf.as_ptr() as usize,
10061 ))
10062 }
10063 pub fn get_flush(&self) -> Result<(), ErrorContext> {
10064 let mut iter = self.clone();
10065 iter.pos = 0;
10066 for attr in iter {
10067 if let LinkinfoBrportAttrs::Flush(val) = attr? {
10068 return Ok(val);
10069 }
10070 }
10071 Err(ErrorContext::new_missing(
10072 "LinkinfoBrportAttrs",
10073 "Flush",
10074 self.orig_loc,
10075 self.buf.as_ptr() as usize,
10076 ))
10077 }
10078 pub fn get_multicast_router(&self) -> Result<u8, ErrorContext> {
10079 let mut iter = self.clone();
10080 iter.pos = 0;
10081 for attr in iter {
10082 if let LinkinfoBrportAttrs::MulticastRouter(val) = attr? {
10083 return Ok(val);
10084 }
10085 }
10086 Err(ErrorContext::new_missing(
10087 "LinkinfoBrportAttrs",
10088 "MulticastRouter",
10089 self.orig_loc,
10090 self.buf.as_ptr() as usize,
10091 ))
10092 }
10093 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
10094 let mut iter = self.clone();
10095 iter.pos = 0;
10096 for attr in iter {
10097 if let LinkinfoBrportAttrs::Pad(val) = attr? {
10098 return Ok(val);
10099 }
10100 }
10101 Err(ErrorContext::new_missing(
10102 "LinkinfoBrportAttrs",
10103 "Pad",
10104 self.orig_loc,
10105 self.buf.as_ptr() as usize,
10106 ))
10107 }
10108 pub fn get_mcast_flood(&self) -> Result<(), ErrorContext> {
10109 let mut iter = self.clone();
10110 iter.pos = 0;
10111 for attr in iter {
10112 if let LinkinfoBrportAttrs::McastFlood(val) = attr? {
10113 return Ok(val);
10114 }
10115 }
10116 Err(ErrorContext::new_missing(
10117 "LinkinfoBrportAttrs",
10118 "McastFlood",
10119 self.orig_loc,
10120 self.buf.as_ptr() as usize,
10121 ))
10122 }
10123 pub fn get_mcast_to_ucast(&self) -> Result<(), ErrorContext> {
10124 let mut iter = self.clone();
10125 iter.pos = 0;
10126 for attr in iter {
10127 if let LinkinfoBrportAttrs::McastToUcast(val) = attr? {
10128 return Ok(val);
10129 }
10130 }
10131 Err(ErrorContext::new_missing(
10132 "LinkinfoBrportAttrs",
10133 "McastToUcast",
10134 self.orig_loc,
10135 self.buf.as_ptr() as usize,
10136 ))
10137 }
10138 pub fn get_vlan_tunnel(&self) -> Result<(), ErrorContext> {
10139 let mut iter = self.clone();
10140 iter.pos = 0;
10141 for attr in iter {
10142 if let LinkinfoBrportAttrs::VlanTunnel(val) = attr? {
10143 return Ok(val);
10144 }
10145 }
10146 Err(ErrorContext::new_missing(
10147 "LinkinfoBrportAttrs",
10148 "VlanTunnel",
10149 self.orig_loc,
10150 self.buf.as_ptr() as usize,
10151 ))
10152 }
10153 pub fn get_bcast_flood(&self) -> Result<(), ErrorContext> {
10154 let mut iter = self.clone();
10155 iter.pos = 0;
10156 for attr in iter {
10157 if let LinkinfoBrportAttrs::BcastFlood(val) = attr? {
10158 return Ok(val);
10159 }
10160 }
10161 Err(ErrorContext::new_missing(
10162 "LinkinfoBrportAttrs",
10163 "BcastFlood",
10164 self.orig_loc,
10165 self.buf.as_ptr() as usize,
10166 ))
10167 }
10168 pub fn get_group_fwd_mask(&self) -> Result<u16, ErrorContext> {
10169 let mut iter = self.clone();
10170 iter.pos = 0;
10171 for attr in iter {
10172 if let LinkinfoBrportAttrs::GroupFwdMask(val) = attr? {
10173 return Ok(val);
10174 }
10175 }
10176 Err(ErrorContext::new_missing(
10177 "LinkinfoBrportAttrs",
10178 "GroupFwdMask",
10179 self.orig_loc,
10180 self.buf.as_ptr() as usize,
10181 ))
10182 }
10183 pub fn get_neigh_suppress(&self) -> Result<(), ErrorContext> {
10184 let mut iter = self.clone();
10185 iter.pos = 0;
10186 for attr in iter {
10187 if let LinkinfoBrportAttrs::NeighSuppress(val) = attr? {
10188 return Ok(val);
10189 }
10190 }
10191 Err(ErrorContext::new_missing(
10192 "LinkinfoBrportAttrs",
10193 "NeighSuppress",
10194 self.orig_loc,
10195 self.buf.as_ptr() as usize,
10196 ))
10197 }
10198 pub fn get_isolated(&self) -> Result<(), ErrorContext> {
10199 let mut iter = self.clone();
10200 iter.pos = 0;
10201 for attr in iter {
10202 if let LinkinfoBrportAttrs::Isolated(val) = attr? {
10203 return Ok(val);
10204 }
10205 }
10206 Err(ErrorContext::new_missing(
10207 "LinkinfoBrportAttrs",
10208 "Isolated",
10209 self.orig_loc,
10210 self.buf.as_ptr() as usize,
10211 ))
10212 }
10213 pub fn get_backup_port(&self) -> Result<u32, ErrorContext> {
10214 let mut iter = self.clone();
10215 iter.pos = 0;
10216 for attr in iter {
10217 if let LinkinfoBrportAttrs::BackupPort(val) = attr? {
10218 return Ok(val);
10219 }
10220 }
10221 Err(ErrorContext::new_missing(
10222 "LinkinfoBrportAttrs",
10223 "BackupPort",
10224 self.orig_loc,
10225 self.buf.as_ptr() as usize,
10226 ))
10227 }
10228 pub fn get_mrp_ring_open(&self) -> Result<(), ErrorContext> {
10229 let mut iter = self.clone();
10230 iter.pos = 0;
10231 for attr in iter {
10232 if let LinkinfoBrportAttrs::MrpRingOpen(val) = attr? {
10233 return Ok(val);
10234 }
10235 }
10236 Err(ErrorContext::new_missing(
10237 "LinkinfoBrportAttrs",
10238 "MrpRingOpen",
10239 self.orig_loc,
10240 self.buf.as_ptr() as usize,
10241 ))
10242 }
10243 pub fn get_mrp_in_open(&self) -> Result<(), ErrorContext> {
10244 let mut iter = self.clone();
10245 iter.pos = 0;
10246 for attr in iter {
10247 if let LinkinfoBrportAttrs::MrpInOpen(val) = attr? {
10248 return Ok(val);
10249 }
10250 }
10251 Err(ErrorContext::new_missing(
10252 "LinkinfoBrportAttrs",
10253 "MrpInOpen",
10254 self.orig_loc,
10255 self.buf.as_ptr() as usize,
10256 ))
10257 }
10258 pub fn get_mcast_eht_hosts_limit(&self) -> Result<u32, ErrorContext> {
10259 let mut iter = self.clone();
10260 iter.pos = 0;
10261 for attr in iter {
10262 if let LinkinfoBrportAttrs::McastEhtHostsLimit(val) = attr? {
10263 return Ok(val);
10264 }
10265 }
10266 Err(ErrorContext::new_missing(
10267 "LinkinfoBrportAttrs",
10268 "McastEhtHostsLimit",
10269 self.orig_loc,
10270 self.buf.as_ptr() as usize,
10271 ))
10272 }
10273 pub fn get_mcast_eht_hosts_cnt(&self) -> Result<u32, ErrorContext> {
10274 let mut iter = self.clone();
10275 iter.pos = 0;
10276 for attr in iter {
10277 if let LinkinfoBrportAttrs::McastEhtHostsCnt(val) = attr? {
10278 return Ok(val);
10279 }
10280 }
10281 Err(ErrorContext::new_missing(
10282 "LinkinfoBrportAttrs",
10283 "McastEhtHostsCnt",
10284 self.orig_loc,
10285 self.buf.as_ptr() as usize,
10286 ))
10287 }
10288 pub fn get_locked(&self) -> Result<(), ErrorContext> {
10289 let mut iter = self.clone();
10290 iter.pos = 0;
10291 for attr in iter {
10292 if let LinkinfoBrportAttrs::Locked(val) = attr? {
10293 return Ok(val);
10294 }
10295 }
10296 Err(ErrorContext::new_missing(
10297 "LinkinfoBrportAttrs",
10298 "Locked",
10299 self.orig_loc,
10300 self.buf.as_ptr() as usize,
10301 ))
10302 }
10303 pub fn get_mab(&self) -> Result<(), ErrorContext> {
10304 let mut iter = self.clone();
10305 iter.pos = 0;
10306 for attr in iter {
10307 if let LinkinfoBrportAttrs::Mab(val) = attr? {
10308 return Ok(val);
10309 }
10310 }
10311 Err(ErrorContext::new_missing(
10312 "LinkinfoBrportAttrs",
10313 "Mab",
10314 self.orig_loc,
10315 self.buf.as_ptr() as usize,
10316 ))
10317 }
10318 pub fn get_mcast_n_groups(&self) -> Result<u32, ErrorContext> {
10319 let mut iter = self.clone();
10320 iter.pos = 0;
10321 for attr in iter {
10322 if let LinkinfoBrportAttrs::McastNGroups(val) = attr? {
10323 return Ok(val);
10324 }
10325 }
10326 Err(ErrorContext::new_missing(
10327 "LinkinfoBrportAttrs",
10328 "McastNGroups",
10329 self.orig_loc,
10330 self.buf.as_ptr() as usize,
10331 ))
10332 }
10333 pub fn get_mcast_max_groups(&self) -> Result<u32, ErrorContext> {
10334 let mut iter = self.clone();
10335 iter.pos = 0;
10336 for attr in iter {
10337 if let LinkinfoBrportAttrs::McastMaxGroups(val) = attr? {
10338 return Ok(val);
10339 }
10340 }
10341 Err(ErrorContext::new_missing(
10342 "LinkinfoBrportAttrs",
10343 "McastMaxGroups",
10344 self.orig_loc,
10345 self.buf.as_ptr() as usize,
10346 ))
10347 }
10348 pub fn get_neigh_vlan_suppress(&self) -> Result<(), ErrorContext> {
10349 let mut iter = self.clone();
10350 iter.pos = 0;
10351 for attr in iter {
10352 if let LinkinfoBrportAttrs::NeighVlanSuppress(val) = attr? {
10353 return Ok(val);
10354 }
10355 }
10356 Err(ErrorContext::new_missing(
10357 "LinkinfoBrportAttrs",
10358 "NeighVlanSuppress",
10359 self.orig_loc,
10360 self.buf.as_ptr() as usize,
10361 ))
10362 }
10363 pub fn get_backup_nhid(&self) -> Result<u32, ErrorContext> {
10364 let mut iter = self.clone();
10365 iter.pos = 0;
10366 for attr in iter {
10367 if let LinkinfoBrportAttrs::BackupNhid(val) = attr? {
10368 return Ok(val);
10369 }
10370 }
10371 Err(ErrorContext::new_missing(
10372 "LinkinfoBrportAttrs",
10373 "BackupNhid",
10374 self.orig_loc,
10375 self.buf.as_ptr() as usize,
10376 ))
10377 }
10378}
10379impl LinkinfoBrportAttrs<'_> {
10380 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoBrportAttrs<'a> {
10381 IterableLinkinfoBrportAttrs::with_loc(buf, buf.as_ptr() as usize)
10382 }
10383 fn attr_from_type(r#type: u16) -> Option<&'static str> {
10384 let res = match r#type {
10385 1u16 => "State",
10386 2u16 => "Priority",
10387 3u16 => "Cost",
10388 4u16 => "Mode",
10389 5u16 => "Guard",
10390 6u16 => "Protect",
10391 7u16 => "FastLeave",
10392 8u16 => "Learning",
10393 9u16 => "UnicastFlood",
10394 10u16 => "Proxyarp",
10395 11u16 => "LearningSync",
10396 12u16 => "ProxyarpWifi",
10397 13u16 => "RootId",
10398 14u16 => "BridgeId",
10399 15u16 => "DesignatedPort",
10400 16u16 => "DesignatedCost",
10401 17u16 => "Id",
10402 18u16 => "No",
10403 19u16 => "TopologyChangeAck",
10404 20u16 => "ConfigPending",
10405 21u16 => "MessageAgeTimer",
10406 22u16 => "ForwardDelayTimer",
10407 23u16 => "HoldTimer",
10408 24u16 => "Flush",
10409 25u16 => "MulticastRouter",
10410 26u16 => "Pad",
10411 27u16 => "McastFlood",
10412 28u16 => "McastToUcast",
10413 29u16 => "VlanTunnel",
10414 30u16 => "BcastFlood",
10415 31u16 => "GroupFwdMask",
10416 32u16 => "NeighSuppress",
10417 33u16 => "Isolated",
10418 34u16 => "BackupPort",
10419 35u16 => "MrpRingOpen",
10420 36u16 => "MrpInOpen",
10421 37u16 => "McastEhtHostsLimit",
10422 38u16 => "McastEhtHostsCnt",
10423 39u16 => "Locked",
10424 40u16 => "Mab",
10425 41u16 => "McastNGroups",
10426 42u16 => "McastMaxGroups",
10427 43u16 => "NeighVlanSuppress",
10428 44u16 => "BackupNhid",
10429 _ => return None,
10430 };
10431 Some(res)
10432 }
10433}
10434#[derive(Clone, Copy, Default)]
10435pub struct IterableLinkinfoBrportAttrs<'a> {
10436 buf: &'a [u8],
10437 pos: usize,
10438 orig_loc: usize,
10439}
10440impl<'a> IterableLinkinfoBrportAttrs<'a> {
10441 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
10442 Self {
10443 buf,
10444 pos: 0,
10445 orig_loc,
10446 }
10447 }
10448 pub fn get_buf(&self) -> &'a [u8] {
10449 self.buf
10450 }
10451}
10452impl<'a> Iterator for IterableLinkinfoBrportAttrs<'a> {
10453 type Item = Result<LinkinfoBrportAttrs<'a>, ErrorContext>;
10454 fn next(&mut self) -> Option<Self::Item> {
10455 let pos = self.pos;
10456 let mut r#type;
10457 loop {
10458 r#type = None;
10459 if self.buf.len() == self.pos {
10460 return None;
10461 }
10462 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
10463 break;
10464 };
10465 r#type = Some(header.r#type);
10466 let res = match header.r#type {
10467 1u16 => LinkinfoBrportAttrs::State({
10468 let res = parse_u8(next);
10469 let Some(val) = res else { break };
10470 val
10471 }),
10472 2u16 => LinkinfoBrportAttrs::Priority({
10473 let res = parse_u16(next);
10474 let Some(val) = res else { break };
10475 val
10476 }),
10477 3u16 => LinkinfoBrportAttrs::Cost({
10478 let res = parse_u32(next);
10479 let Some(val) = res else { break };
10480 val
10481 }),
10482 4u16 => LinkinfoBrportAttrs::Mode(()),
10483 5u16 => LinkinfoBrportAttrs::Guard(()),
10484 6u16 => LinkinfoBrportAttrs::Protect(()),
10485 7u16 => LinkinfoBrportAttrs::FastLeave(()),
10486 8u16 => LinkinfoBrportAttrs::Learning(()),
10487 9u16 => LinkinfoBrportAttrs::UnicastFlood(()),
10488 10u16 => LinkinfoBrportAttrs::Proxyarp(()),
10489 11u16 => LinkinfoBrportAttrs::LearningSync(()),
10490 12u16 => LinkinfoBrportAttrs::ProxyarpWifi(()),
10491 13u16 => LinkinfoBrportAttrs::RootId({
10492 let res = Some(IflaBridgeId::new_from_zeroed(next));
10493 let Some(val) = res else { break };
10494 val
10495 }),
10496 14u16 => LinkinfoBrportAttrs::BridgeId({
10497 let res = Some(IflaBridgeId::new_from_zeroed(next));
10498 let Some(val) = res else { break };
10499 val
10500 }),
10501 15u16 => LinkinfoBrportAttrs::DesignatedPort({
10502 let res = parse_u16(next);
10503 let Some(val) = res else { break };
10504 val
10505 }),
10506 16u16 => LinkinfoBrportAttrs::DesignatedCost({
10507 let res = parse_u16(next);
10508 let Some(val) = res else { break };
10509 val
10510 }),
10511 17u16 => LinkinfoBrportAttrs::Id({
10512 let res = parse_u16(next);
10513 let Some(val) = res else { break };
10514 val
10515 }),
10516 18u16 => LinkinfoBrportAttrs::No({
10517 let res = parse_u16(next);
10518 let Some(val) = res else { break };
10519 val
10520 }),
10521 19u16 => LinkinfoBrportAttrs::TopologyChangeAck({
10522 let res = parse_u8(next);
10523 let Some(val) = res else { break };
10524 val
10525 }),
10526 20u16 => LinkinfoBrportAttrs::ConfigPending({
10527 let res = parse_u8(next);
10528 let Some(val) = res else { break };
10529 val
10530 }),
10531 21u16 => LinkinfoBrportAttrs::MessageAgeTimer({
10532 let res = parse_u64(next);
10533 let Some(val) = res else { break };
10534 val
10535 }),
10536 22u16 => LinkinfoBrportAttrs::ForwardDelayTimer({
10537 let res = parse_u64(next);
10538 let Some(val) = res else { break };
10539 val
10540 }),
10541 23u16 => LinkinfoBrportAttrs::HoldTimer({
10542 let res = parse_u64(next);
10543 let Some(val) = res else { break };
10544 val
10545 }),
10546 24u16 => LinkinfoBrportAttrs::Flush(()),
10547 25u16 => LinkinfoBrportAttrs::MulticastRouter({
10548 let res = parse_u8(next);
10549 let Some(val) = res else { break };
10550 val
10551 }),
10552 26u16 => LinkinfoBrportAttrs::Pad({
10553 let res = Some(next);
10554 let Some(val) = res else { break };
10555 val
10556 }),
10557 27u16 => LinkinfoBrportAttrs::McastFlood(()),
10558 28u16 => LinkinfoBrportAttrs::McastToUcast(()),
10559 29u16 => LinkinfoBrportAttrs::VlanTunnel(()),
10560 30u16 => LinkinfoBrportAttrs::BcastFlood(()),
10561 31u16 => LinkinfoBrportAttrs::GroupFwdMask({
10562 let res = parse_u16(next);
10563 let Some(val) = res else { break };
10564 val
10565 }),
10566 32u16 => LinkinfoBrportAttrs::NeighSuppress(()),
10567 33u16 => LinkinfoBrportAttrs::Isolated(()),
10568 34u16 => LinkinfoBrportAttrs::BackupPort({
10569 let res = parse_u32(next);
10570 let Some(val) = res else { break };
10571 val
10572 }),
10573 35u16 => LinkinfoBrportAttrs::MrpRingOpen(()),
10574 36u16 => LinkinfoBrportAttrs::MrpInOpen(()),
10575 37u16 => LinkinfoBrportAttrs::McastEhtHostsLimit({
10576 let res = parse_u32(next);
10577 let Some(val) = res else { break };
10578 val
10579 }),
10580 38u16 => LinkinfoBrportAttrs::McastEhtHostsCnt({
10581 let res = parse_u32(next);
10582 let Some(val) = res else { break };
10583 val
10584 }),
10585 39u16 => LinkinfoBrportAttrs::Locked(()),
10586 40u16 => LinkinfoBrportAttrs::Mab(()),
10587 41u16 => LinkinfoBrportAttrs::McastNGroups({
10588 let res = parse_u32(next);
10589 let Some(val) = res else { break };
10590 val
10591 }),
10592 42u16 => LinkinfoBrportAttrs::McastMaxGroups({
10593 let res = parse_u32(next);
10594 let Some(val) = res else { break };
10595 val
10596 }),
10597 43u16 => LinkinfoBrportAttrs::NeighVlanSuppress(()),
10598 44u16 => LinkinfoBrportAttrs::BackupNhid({
10599 let res = parse_u32(next);
10600 let Some(val) = res else { break };
10601 val
10602 }),
10603 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
10604 n => continue,
10605 };
10606 return Some(Ok(res));
10607 }
10608 Some(Err(ErrorContext::new(
10609 "LinkinfoBrportAttrs",
10610 r#type.and_then(|t| LinkinfoBrportAttrs::attr_from_type(t)),
10611 self.orig_loc,
10612 self.buf.as_ptr().wrapping_add(pos) as usize,
10613 )))
10614 }
10615}
10616impl<'a> std::fmt::Debug for IterableLinkinfoBrportAttrs<'_> {
10617 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
10618 let mut fmt = f.debug_struct("LinkinfoBrportAttrs");
10619 for attr in self.clone() {
10620 let attr = match attr {
10621 Ok(a) => a,
10622 Err(err) => {
10623 fmt.finish()?;
10624 f.write_str("Err(")?;
10625 err.fmt(f)?;
10626 return f.write_str(")");
10627 }
10628 };
10629 match attr {
10630 LinkinfoBrportAttrs::State(val) => fmt.field("State", &val),
10631 LinkinfoBrportAttrs::Priority(val) => fmt.field("Priority", &val),
10632 LinkinfoBrportAttrs::Cost(val) => fmt.field("Cost", &val),
10633 LinkinfoBrportAttrs::Mode(val) => fmt.field("Mode", &val),
10634 LinkinfoBrportAttrs::Guard(val) => fmt.field("Guard", &val),
10635 LinkinfoBrportAttrs::Protect(val) => fmt.field("Protect", &val),
10636 LinkinfoBrportAttrs::FastLeave(val) => fmt.field("FastLeave", &val),
10637 LinkinfoBrportAttrs::Learning(val) => fmt.field("Learning", &val),
10638 LinkinfoBrportAttrs::UnicastFlood(val) => fmt.field("UnicastFlood", &val),
10639 LinkinfoBrportAttrs::Proxyarp(val) => fmt.field("Proxyarp", &val),
10640 LinkinfoBrportAttrs::LearningSync(val) => fmt.field("LearningSync", &val),
10641 LinkinfoBrportAttrs::ProxyarpWifi(val) => fmt.field("ProxyarpWifi", &val),
10642 LinkinfoBrportAttrs::RootId(val) => fmt.field("RootId", &val),
10643 LinkinfoBrportAttrs::BridgeId(val) => fmt.field("BridgeId", &val),
10644 LinkinfoBrportAttrs::DesignatedPort(val) => fmt.field("DesignatedPort", &val),
10645 LinkinfoBrportAttrs::DesignatedCost(val) => fmt.field("DesignatedCost", &val),
10646 LinkinfoBrportAttrs::Id(val) => fmt.field("Id", &val),
10647 LinkinfoBrportAttrs::No(val) => fmt.field("No", &val),
10648 LinkinfoBrportAttrs::TopologyChangeAck(val) => fmt.field("TopologyChangeAck", &val),
10649 LinkinfoBrportAttrs::ConfigPending(val) => fmt.field("ConfigPending", &val),
10650 LinkinfoBrportAttrs::MessageAgeTimer(val) => fmt.field("MessageAgeTimer", &val),
10651 LinkinfoBrportAttrs::ForwardDelayTimer(val) => fmt.field("ForwardDelayTimer", &val),
10652 LinkinfoBrportAttrs::HoldTimer(val) => fmt.field("HoldTimer", &val),
10653 LinkinfoBrportAttrs::Flush(val) => fmt.field("Flush", &val),
10654 LinkinfoBrportAttrs::MulticastRouter(val) => fmt.field("MulticastRouter", &val),
10655 LinkinfoBrportAttrs::Pad(val) => fmt.field("Pad", &val),
10656 LinkinfoBrportAttrs::McastFlood(val) => fmt.field("McastFlood", &val),
10657 LinkinfoBrportAttrs::McastToUcast(val) => fmt.field("McastToUcast", &val),
10658 LinkinfoBrportAttrs::VlanTunnel(val) => fmt.field("VlanTunnel", &val),
10659 LinkinfoBrportAttrs::BcastFlood(val) => fmt.field("BcastFlood", &val),
10660 LinkinfoBrportAttrs::GroupFwdMask(val) => fmt.field("GroupFwdMask", &val),
10661 LinkinfoBrportAttrs::NeighSuppress(val) => fmt.field("NeighSuppress", &val),
10662 LinkinfoBrportAttrs::Isolated(val) => fmt.field("Isolated", &val),
10663 LinkinfoBrportAttrs::BackupPort(val) => fmt.field("BackupPort", &val),
10664 LinkinfoBrportAttrs::MrpRingOpen(val) => fmt.field("MrpRingOpen", &val),
10665 LinkinfoBrportAttrs::MrpInOpen(val) => fmt.field("MrpInOpen", &val),
10666 LinkinfoBrportAttrs::McastEhtHostsLimit(val) => {
10667 fmt.field("McastEhtHostsLimit", &val)
10668 }
10669 LinkinfoBrportAttrs::McastEhtHostsCnt(val) => fmt.field("McastEhtHostsCnt", &val),
10670 LinkinfoBrportAttrs::Locked(val) => fmt.field("Locked", &val),
10671 LinkinfoBrportAttrs::Mab(val) => fmt.field("Mab", &val),
10672 LinkinfoBrportAttrs::McastNGroups(val) => fmt.field("McastNGroups", &val),
10673 LinkinfoBrportAttrs::McastMaxGroups(val) => fmt.field("McastMaxGroups", &val),
10674 LinkinfoBrportAttrs::NeighVlanSuppress(val) => fmt.field("NeighVlanSuppress", &val),
10675 LinkinfoBrportAttrs::BackupNhid(val) => fmt.field("BackupNhid", &val),
10676 };
10677 }
10678 fmt.finish()
10679 }
10680}
10681impl IterableLinkinfoBrportAttrs<'_> {
10682 pub fn lookup_attr(
10683 &self,
10684 offset: usize,
10685 missing_type: Option<u16>,
10686 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
10687 let mut stack = Vec::new();
10688 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
10689 if missing_type.is_some() && cur == offset {
10690 stack.push(("LinkinfoBrportAttrs", offset));
10691 return (
10692 stack,
10693 missing_type.and_then(|t| LinkinfoBrportAttrs::attr_from_type(t)),
10694 );
10695 }
10696 if cur > offset || cur + self.buf.len() < offset {
10697 return (stack, None);
10698 }
10699 let mut attrs = self.clone();
10700 let mut last_off = cur + attrs.pos;
10701 while let Some(attr) = attrs.next() {
10702 let Ok(attr) = attr else { break };
10703 match attr {
10704 LinkinfoBrportAttrs::State(val) => {
10705 if last_off == offset {
10706 stack.push(("State", last_off));
10707 break;
10708 }
10709 }
10710 LinkinfoBrportAttrs::Priority(val) => {
10711 if last_off == offset {
10712 stack.push(("Priority", last_off));
10713 break;
10714 }
10715 }
10716 LinkinfoBrportAttrs::Cost(val) => {
10717 if last_off == offset {
10718 stack.push(("Cost", last_off));
10719 break;
10720 }
10721 }
10722 LinkinfoBrportAttrs::Mode(val) => {
10723 if last_off == offset {
10724 stack.push(("Mode", last_off));
10725 break;
10726 }
10727 }
10728 LinkinfoBrportAttrs::Guard(val) => {
10729 if last_off == offset {
10730 stack.push(("Guard", last_off));
10731 break;
10732 }
10733 }
10734 LinkinfoBrportAttrs::Protect(val) => {
10735 if last_off == offset {
10736 stack.push(("Protect", last_off));
10737 break;
10738 }
10739 }
10740 LinkinfoBrportAttrs::FastLeave(val) => {
10741 if last_off == offset {
10742 stack.push(("FastLeave", last_off));
10743 break;
10744 }
10745 }
10746 LinkinfoBrportAttrs::Learning(val) => {
10747 if last_off == offset {
10748 stack.push(("Learning", last_off));
10749 break;
10750 }
10751 }
10752 LinkinfoBrportAttrs::UnicastFlood(val) => {
10753 if last_off == offset {
10754 stack.push(("UnicastFlood", last_off));
10755 break;
10756 }
10757 }
10758 LinkinfoBrportAttrs::Proxyarp(val) => {
10759 if last_off == offset {
10760 stack.push(("Proxyarp", last_off));
10761 break;
10762 }
10763 }
10764 LinkinfoBrportAttrs::LearningSync(val) => {
10765 if last_off == offset {
10766 stack.push(("LearningSync", last_off));
10767 break;
10768 }
10769 }
10770 LinkinfoBrportAttrs::ProxyarpWifi(val) => {
10771 if last_off == offset {
10772 stack.push(("ProxyarpWifi", last_off));
10773 break;
10774 }
10775 }
10776 LinkinfoBrportAttrs::RootId(val) => {
10777 if last_off == offset {
10778 stack.push(("RootId", last_off));
10779 break;
10780 }
10781 }
10782 LinkinfoBrportAttrs::BridgeId(val) => {
10783 if last_off == offset {
10784 stack.push(("BridgeId", last_off));
10785 break;
10786 }
10787 }
10788 LinkinfoBrportAttrs::DesignatedPort(val) => {
10789 if last_off == offset {
10790 stack.push(("DesignatedPort", last_off));
10791 break;
10792 }
10793 }
10794 LinkinfoBrportAttrs::DesignatedCost(val) => {
10795 if last_off == offset {
10796 stack.push(("DesignatedCost", last_off));
10797 break;
10798 }
10799 }
10800 LinkinfoBrportAttrs::Id(val) => {
10801 if last_off == offset {
10802 stack.push(("Id", last_off));
10803 break;
10804 }
10805 }
10806 LinkinfoBrportAttrs::No(val) => {
10807 if last_off == offset {
10808 stack.push(("No", last_off));
10809 break;
10810 }
10811 }
10812 LinkinfoBrportAttrs::TopologyChangeAck(val) => {
10813 if last_off == offset {
10814 stack.push(("TopologyChangeAck", last_off));
10815 break;
10816 }
10817 }
10818 LinkinfoBrportAttrs::ConfigPending(val) => {
10819 if last_off == offset {
10820 stack.push(("ConfigPending", last_off));
10821 break;
10822 }
10823 }
10824 LinkinfoBrportAttrs::MessageAgeTimer(val) => {
10825 if last_off == offset {
10826 stack.push(("MessageAgeTimer", last_off));
10827 break;
10828 }
10829 }
10830 LinkinfoBrportAttrs::ForwardDelayTimer(val) => {
10831 if last_off == offset {
10832 stack.push(("ForwardDelayTimer", last_off));
10833 break;
10834 }
10835 }
10836 LinkinfoBrportAttrs::HoldTimer(val) => {
10837 if last_off == offset {
10838 stack.push(("HoldTimer", last_off));
10839 break;
10840 }
10841 }
10842 LinkinfoBrportAttrs::Flush(val) => {
10843 if last_off == offset {
10844 stack.push(("Flush", last_off));
10845 break;
10846 }
10847 }
10848 LinkinfoBrportAttrs::MulticastRouter(val) => {
10849 if last_off == offset {
10850 stack.push(("MulticastRouter", last_off));
10851 break;
10852 }
10853 }
10854 LinkinfoBrportAttrs::Pad(val) => {
10855 if last_off == offset {
10856 stack.push(("Pad", last_off));
10857 break;
10858 }
10859 }
10860 LinkinfoBrportAttrs::McastFlood(val) => {
10861 if last_off == offset {
10862 stack.push(("McastFlood", last_off));
10863 break;
10864 }
10865 }
10866 LinkinfoBrportAttrs::McastToUcast(val) => {
10867 if last_off == offset {
10868 stack.push(("McastToUcast", last_off));
10869 break;
10870 }
10871 }
10872 LinkinfoBrportAttrs::VlanTunnel(val) => {
10873 if last_off == offset {
10874 stack.push(("VlanTunnel", last_off));
10875 break;
10876 }
10877 }
10878 LinkinfoBrportAttrs::BcastFlood(val) => {
10879 if last_off == offset {
10880 stack.push(("BcastFlood", last_off));
10881 break;
10882 }
10883 }
10884 LinkinfoBrportAttrs::GroupFwdMask(val) => {
10885 if last_off == offset {
10886 stack.push(("GroupFwdMask", last_off));
10887 break;
10888 }
10889 }
10890 LinkinfoBrportAttrs::NeighSuppress(val) => {
10891 if last_off == offset {
10892 stack.push(("NeighSuppress", last_off));
10893 break;
10894 }
10895 }
10896 LinkinfoBrportAttrs::Isolated(val) => {
10897 if last_off == offset {
10898 stack.push(("Isolated", last_off));
10899 break;
10900 }
10901 }
10902 LinkinfoBrportAttrs::BackupPort(val) => {
10903 if last_off == offset {
10904 stack.push(("BackupPort", last_off));
10905 break;
10906 }
10907 }
10908 LinkinfoBrportAttrs::MrpRingOpen(val) => {
10909 if last_off == offset {
10910 stack.push(("MrpRingOpen", last_off));
10911 break;
10912 }
10913 }
10914 LinkinfoBrportAttrs::MrpInOpen(val) => {
10915 if last_off == offset {
10916 stack.push(("MrpInOpen", last_off));
10917 break;
10918 }
10919 }
10920 LinkinfoBrportAttrs::McastEhtHostsLimit(val) => {
10921 if last_off == offset {
10922 stack.push(("McastEhtHostsLimit", last_off));
10923 break;
10924 }
10925 }
10926 LinkinfoBrportAttrs::McastEhtHostsCnt(val) => {
10927 if last_off == offset {
10928 stack.push(("McastEhtHostsCnt", last_off));
10929 break;
10930 }
10931 }
10932 LinkinfoBrportAttrs::Locked(val) => {
10933 if last_off == offset {
10934 stack.push(("Locked", last_off));
10935 break;
10936 }
10937 }
10938 LinkinfoBrportAttrs::Mab(val) => {
10939 if last_off == offset {
10940 stack.push(("Mab", last_off));
10941 break;
10942 }
10943 }
10944 LinkinfoBrportAttrs::McastNGroups(val) => {
10945 if last_off == offset {
10946 stack.push(("McastNGroups", last_off));
10947 break;
10948 }
10949 }
10950 LinkinfoBrportAttrs::McastMaxGroups(val) => {
10951 if last_off == offset {
10952 stack.push(("McastMaxGroups", last_off));
10953 break;
10954 }
10955 }
10956 LinkinfoBrportAttrs::NeighVlanSuppress(val) => {
10957 if last_off == offset {
10958 stack.push(("NeighVlanSuppress", last_off));
10959 break;
10960 }
10961 }
10962 LinkinfoBrportAttrs::BackupNhid(val) => {
10963 if last_off == offset {
10964 stack.push(("BackupNhid", last_off));
10965 break;
10966 }
10967 }
10968 _ => {}
10969 };
10970 last_off = cur + attrs.pos;
10971 }
10972 if !stack.is_empty() {
10973 stack.push(("LinkinfoBrportAttrs", cur));
10974 }
10975 (stack, None)
10976 }
10977}
10978#[derive(Clone)]
10979pub enum LinkinfoGreAttrs {
10980 Link(u32),
10981 Iflags(u16),
10982 Oflags(u16),
10983 Ikey(u32),
10984 Okey(u32),
10985 Local(std::net::IpAddr),
10986 Remote(std::net::IpAddr),
10987 Ttl(u8),
10988 Tos(u8),
10989 Pmtudisc(u8),
10990 EncapLimit(u8),
10991 Flowinfo(u32),
10992 Flags(u32),
10993 EncapType(u16),
10994 EncapFlags(u16),
10995 EncapSport(u16),
10996 EncapDport(u16),
10997 CollectMetadata(()),
10998 IgnoreDf(u8),
10999 Fwmark(u32),
11000 ErspanIndex(u32),
11001 ErspanVer(u8),
11002 ErspanDir(u8),
11003 ErspanHwid(u16),
11004}
11005impl<'a> IterableLinkinfoGreAttrs<'a> {
11006 pub fn get_link(&self) -> Result<u32, ErrorContext> {
11007 let mut iter = self.clone();
11008 iter.pos = 0;
11009 for attr in iter {
11010 if let LinkinfoGreAttrs::Link(val) = attr? {
11011 return Ok(val);
11012 }
11013 }
11014 Err(ErrorContext::new_missing(
11015 "LinkinfoGreAttrs",
11016 "Link",
11017 self.orig_loc,
11018 self.buf.as_ptr() as usize,
11019 ))
11020 }
11021 pub fn get_iflags(&self) -> Result<u16, ErrorContext> {
11022 let mut iter = self.clone();
11023 iter.pos = 0;
11024 for attr in iter {
11025 if let LinkinfoGreAttrs::Iflags(val) = attr? {
11026 return Ok(val);
11027 }
11028 }
11029 Err(ErrorContext::new_missing(
11030 "LinkinfoGreAttrs",
11031 "Iflags",
11032 self.orig_loc,
11033 self.buf.as_ptr() as usize,
11034 ))
11035 }
11036 pub fn get_oflags(&self) -> Result<u16, ErrorContext> {
11037 let mut iter = self.clone();
11038 iter.pos = 0;
11039 for attr in iter {
11040 if let LinkinfoGreAttrs::Oflags(val) = attr? {
11041 return Ok(val);
11042 }
11043 }
11044 Err(ErrorContext::new_missing(
11045 "LinkinfoGreAttrs",
11046 "Oflags",
11047 self.orig_loc,
11048 self.buf.as_ptr() as usize,
11049 ))
11050 }
11051 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
11052 let mut iter = self.clone();
11053 iter.pos = 0;
11054 for attr in iter {
11055 if let LinkinfoGreAttrs::Ikey(val) = attr? {
11056 return Ok(val);
11057 }
11058 }
11059 Err(ErrorContext::new_missing(
11060 "LinkinfoGreAttrs",
11061 "Ikey",
11062 self.orig_loc,
11063 self.buf.as_ptr() as usize,
11064 ))
11065 }
11066 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
11067 let mut iter = self.clone();
11068 iter.pos = 0;
11069 for attr in iter {
11070 if let LinkinfoGreAttrs::Okey(val) = attr? {
11071 return Ok(val);
11072 }
11073 }
11074 Err(ErrorContext::new_missing(
11075 "LinkinfoGreAttrs",
11076 "Okey",
11077 self.orig_loc,
11078 self.buf.as_ptr() as usize,
11079 ))
11080 }
11081 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
11082 let mut iter = self.clone();
11083 iter.pos = 0;
11084 for attr in iter {
11085 if let LinkinfoGreAttrs::Local(val) = attr? {
11086 return Ok(val);
11087 }
11088 }
11089 Err(ErrorContext::new_missing(
11090 "LinkinfoGreAttrs",
11091 "Local",
11092 self.orig_loc,
11093 self.buf.as_ptr() as usize,
11094 ))
11095 }
11096 pub fn get_remote(&self) -> Result<std::net::IpAddr, ErrorContext> {
11097 let mut iter = self.clone();
11098 iter.pos = 0;
11099 for attr in iter {
11100 if let LinkinfoGreAttrs::Remote(val) = attr? {
11101 return Ok(val);
11102 }
11103 }
11104 Err(ErrorContext::new_missing(
11105 "LinkinfoGreAttrs",
11106 "Remote",
11107 self.orig_loc,
11108 self.buf.as_ptr() as usize,
11109 ))
11110 }
11111 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
11112 let mut iter = self.clone();
11113 iter.pos = 0;
11114 for attr in iter {
11115 if let LinkinfoGreAttrs::Ttl(val) = attr? {
11116 return Ok(val);
11117 }
11118 }
11119 Err(ErrorContext::new_missing(
11120 "LinkinfoGreAttrs",
11121 "Ttl",
11122 self.orig_loc,
11123 self.buf.as_ptr() as usize,
11124 ))
11125 }
11126 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
11127 let mut iter = self.clone();
11128 iter.pos = 0;
11129 for attr in iter {
11130 if let LinkinfoGreAttrs::Tos(val) = attr? {
11131 return Ok(val);
11132 }
11133 }
11134 Err(ErrorContext::new_missing(
11135 "LinkinfoGreAttrs",
11136 "Tos",
11137 self.orig_loc,
11138 self.buf.as_ptr() as usize,
11139 ))
11140 }
11141 pub fn get_pmtudisc(&self) -> Result<u8, ErrorContext> {
11142 let mut iter = self.clone();
11143 iter.pos = 0;
11144 for attr in iter {
11145 if let LinkinfoGreAttrs::Pmtudisc(val) = attr? {
11146 return Ok(val);
11147 }
11148 }
11149 Err(ErrorContext::new_missing(
11150 "LinkinfoGreAttrs",
11151 "Pmtudisc",
11152 self.orig_loc,
11153 self.buf.as_ptr() as usize,
11154 ))
11155 }
11156 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
11157 let mut iter = self.clone();
11158 iter.pos = 0;
11159 for attr in iter {
11160 if let LinkinfoGreAttrs::EncapLimit(val) = attr? {
11161 return Ok(val);
11162 }
11163 }
11164 Err(ErrorContext::new_missing(
11165 "LinkinfoGreAttrs",
11166 "EncapLimit",
11167 self.orig_loc,
11168 self.buf.as_ptr() as usize,
11169 ))
11170 }
11171 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
11172 let mut iter = self.clone();
11173 iter.pos = 0;
11174 for attr in iter {
11175 if let LinkinfoGreAttrs::Flowinfo(val) = attr? {
11176 return Ok(val);
11177 }
11178 }
11179 Err(ErrorContext::new_missing(
11180 "LinkinfoGreAttrs",
11181 "Flowinfo",
11182 self.orig_loc,
11183 self.buf.as_ptr() as usize,
11184 ))
11185 }
11186 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
11187 let mut iter = self.clone();
11188 iter.pos = 0;
11189 for attr in iter {
11190 if let LinkinfoGreAttrs::Flags(val) = attr? {
11191 return Ok(val);
11192 }
11193 }
11194 Err(ErrorContext::new_missing(
11195 "LinkinfoGreAttrs",
11196 "Flags",
11197 self.orig_loc,
11198 self.buf.as_ptr() as usize,
11199 ))
11200 }
11201 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
11202 let mut iter = self.clone();
11203 iter.pos = 0;
11204 for attr in iter {
11205 if let LinkinfoGreAttrs::EncapType(val) = attr? {
11206 return Ok(val);
11207 }
11208 }
11209 Err(ErrorContext::new_missing(
11210 "LinkinfoGreAttrs",
11211 "EncapType",
11212 self.orig_loc,
11213 self.buf.as_ptr() as usize,
11214 ))
11215 }
11216 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
11217 let mut iter = self.clone();
11218 iter.pos = 0;
11219 for attr in iter {
11220 if let LinkinfoGreAttrs::EncapFlags(val) = attr? {
11221 return Ok(val);
11222 }
11223 }
11224 Err(ErrorContext::new_missing(
11225 "LinkinfoGreAttrs",
11226 "EncapFlags",
11227 self.orig_loc,
11228 self.buf.as_ptr() as usize,
11229 ))
11230 }
11231 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
11232 let mut iter = self.clone();
11233 iter.pos = 0;
11234 for attr in iter {
11235 if let LinkinfoGreAttrs::EncapSport(val) = attr? {
11236 return Ok(val);
11237 }
11238 }
11239 Err(ErrorContext::new_missing(
11240 "LinkinfoGreAttrs",
11241 "EncapSport",
11242 self.orig_loc,
11243 self.buf.as_ptr() as usize,
11244 ))
11245 }
11246 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
11247 let mut iter = self.clone();
11248 iter.pos = 0;
11249 for attr in iter {
11250 if let LinkinfoGreAttrs::EncapDport(val) = attr? {
11251 return Ok(val);
11252 }
11253 }
11254 Err(ErrorContext::new_missing(
11255 "LinkinfoGreAttrs",
11256 "EncapDport",
11257 self.orig_loc,
11258 self.buf.as_ptr() as usize,
11259 ))
11260 }
11261 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
11262 let mut iter = self.clone();
11263 iter.pos = 0;
11264 for attr in iter {
11265 if let LinkinfoGreAttrs::CollectMetadata(val) = attr? {
11266 return Ok(val);
11267 }
11268 }
11269 Err(ErrorContext::new_missing(
11270 "LinkinfoGreAttrs",
11271 "CollectMetadata",
11272 self.orig_loc,
11273 self.buf.as_ptr() as usize,
11274 ))
11275 }
11276 pub fn get_ignore_df(&self) -> Result<u8, ErrorContext> {
11277 let mut iter = self.clone();
11278 iter.pos = 0;
11279 for attr in iter {
11280 if let LinkinfoGreAttrs::IgnoreDf(val) = attr? {
11281 return Ok(val);
11282 }
11283 }
11284 Err(ErrorContext::new_missing(
11285 "LinkinfoGreAttrs",
11286 "IgnoreDf",
11287 self.orig_loc,
11288 self.buf.as_ptr() as usize,
11289 ))
11290 }
11291 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
11292 let mut iter = self.clone();
11293 iter.pos = 0;
11294 for attr in iter {
11295 if let LinkinfoGreAttrs::Fwmark(val) = attr? {
11296 return Ok(val);
11297 }
11298 }
11299 Err(ErrorContext::new_missing(
11300 "LinkinfoGreAttrs",
11301 "Fwmark",
11302 self.orig_loc,
11303 self.buf.as_ptr() as usize,
11304 ))
11305 }
11306 pub fn get_erspan_index(&self) -> Result<u32, ErrorContext> {
11307 let mut iter = self.clone();
11308 iter.pos = 0;
11309 for attr in iter {
11310 if let LinkinfoGreAttrs::ErspanIndex(val) = attr? {
11311 return Ok(val);
11312 }
11313 }
11314 Err(ErrorContext::new_missing(
11315 "LinkinfoGreAttrs",
11316 "ErspanIndex",
11317 self.orig_loc,
11318 self.buf.as_ptr() as usize,
11319 ))
11320 }
11321 pub fn get_erspan_ver(&self) -> Result<u8, ErrorContext> {
11322 let mut iter = self.clone();
11323 iter.pos = 0;
11324 for attr in iter {
11325 if let LinkinfoGreAttrs::ErspanVer(val) = attr? {
11326 return Ok(val);
11327 }
11328 }
11329 Err(ErrorContext::new_missing(
11330 "LinkinfoGreAttrs",
11331 "ErspanVer",
11332 self.orig_loc,
11333 self.buf.as_ptr() as usize,
11334 ))
11335 }
11336 pub fn get_erspan_dir(&self) -> Result<u8, ErrorContext> {
11337 let mut iter = self.clone();
11338 iter.pos = 0;
11339 for attr in iter {
11340 if let LinkinfoGreAttrs::ErspanDir(val) = attr? {
11341 return Ok(val);
11342 }
11343 }
11344 Err(ErrorContext::new_missing(
11345 "LinkinfoGreAttrs",
11346 "ErspanDir",
11347 self.orig_loc,
11348 self.buf.as_ptr() as usize,
11349 ))
11350 }
11351 pub fn get_erspan_hwid(&self) -> Result<u16, ErrorContext> {
11352 let mut iter = self.clone();
11353 iter.pos = 0;
11354 for attr in iter {
11355 if let LinkinfoGreAttrs::ErspanHwid(val) = attr? {
11356 return Ok(val);
11357 }
11358 }
11359 Err(ErrorContext::new_missing(
11360 "LinkinfoGreAttrs",
11361 "ErspanHwid",
11362 self.orig_loc,
11363 self.buf.as_ptr() as usize,
11364 ))
11365 }
11366}
11367impl LinkinfoGreAttrs {
11368 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoGreAttrs<'a> {
11369 IterableLinkinfoGreAttrs::with_loc(buf, buf.as_ptr() as usize)
11370 }
11371 fn attr_from_type(r#type: u16) -> Option<&'static str> {
11372 let res = match r#type {
11373 1u16 => "Link",
11374 2u16 => "Iflags",
11375 3u16 => "Oflags",
11376 4u16 => "Ikey",
11377 5u16 => "Okey",
11378 6u16 => "Local",
11379 7u16 => "Remote",
11380 8u16 => "Ttl",
11381 9u16 => "Tos",
11382 10u16 => "Pmtudisc",
11383 11u16 => "EncapLimit",
11384 12u16 => "Flowinfo",
11385 13u16 => "Flags",
11386 14u16 => "EncapType",
11387 15u16 => "EncapFlags",
11388 16u16 => "EncapSport",
11389 17u16 => "EncapDport",
11390 18u16 => "CollectMetadata",
11391 19u16 => "IgnoreDf",
11392 20u16 => "Fwmark",
11393 21u16 => "ErspanIndex",
11394 22u16 => "ErspanVer",
11395 23u16 => "ErspanDir",
11396 24u16 => "ErspanHwid",
11397 _ => return None,
11398 };
11399 Some(res)
11400 }
11401}
11402#[derive(Clone, Copy, Default)]
11403pub struct IterableLinkinfoGreAttrs<'a> {
11404 buf: &'a [u8],
11405 pos: usize,
11406 orig_loc: usize,
11407}
11408impl<'a> IterableLinkinfoGreAttrs<'a> {
11409 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
11410 Self {
11411 buf,
11412 pos: 0,
11413 orig_loc,
11414 }
11415 }
11416 pub fn get_buf(&self) -> &'a [u8] {
11417 self.buf
11418 }
11419}
11420impl<'a> Iterator for IterableLinkinfoGreAttrs<'a> {
11421 type Item = Result<LinkinfoGreAttrs, ErrorContext>;
11422 fn next(&mut self) -> Option<Self::Item> {
11423 let pos = self.pos;
11424 let mut r#type;
11425 loop {
11426 r#type = None;
11427 if self.buf.len() == self.pos {
11428 return None;
11429 }
11430 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
11431 break;
11432 };
11433 r#type = Some(header.r#type);
11434 let res = match header.r#type {
11435 1u16 => LinkinfoGreAttrs::Link({
11436 let res = parse_u32(next);
11437 let Some(val) = res else { break };
11438 val
11439 }),
11440 2u16 => LinkinfoGreAttrs::Iflags({
11441 let res = parse_be_u16(next);
11442 let Some(val) = res else { break };
11443 val
11444 }),
11445 3u16 => LinkinfoGreAttrs::Oflags({
11446 let res = parse_be_u16(next);
11447 let Some(val) = res else { break };
11448 val
11449 }),
11450 4u16 => LinkinfoGreAttrs::Ikey({
11451 let res = parse_be_u32(next);
11452 let Some(val) = res else { break };
11453 val
11454 }),
11455 5u16 => LinkinfoGreAttrs::Okey({
11456 let res = parse_be_u32(next);
11457 let Some(val) = res else { break };
11458 val
11459 }),
11460 6u16 => LinkinfoGreAttrs::Local({
11461 let res = parse_ip(next);
11462 let Some(val) = res else { break };
11463 val
11464 }),
11465 7u16 => LinkinfoGreAttrs::Remote({
11466 let res = parse_ip(next);
11467 let Some(val) = res else { break };
11468 val
11469 }),
11470 8u16 => LinkinfoGreAttrs::Ttl({
11471 let res = parse_u8(next);
11472 let Some(val) = res else { break };
11473 val
11474 }),
11475 9u16 => LinkinfoGreAttrs::Tos({
11476 let res = parse_u8(next);
11477 let Some(val) = res else { break };
11478 val
11479 }),
11480 10u16 => LinkinfoGreAttrs::Pmtudisc({
11481 let res = parse_u8(next);
11482 let Some(val) = res else { break };
11483 val
11484 }),
11485 11u16 => LinkinfoGreAttrs::EncapLimit({
11486 let res = parse_u8(next);
11487 let Some(val) = res else { break };
11488 val
11489 }),
11490 12u16 => LinkinfoGreAttrs::Flowinfo({
11491 let res = parse_be_u32(next);
11492 let Some(val) = res else { break };
11493 val
11494 }),
11495 13u16 => LinkinfoGreAttrs::Flags({
11496 let res = parse_u32(next);
11497 let Some(val) = res else { break };
11498 val
11499 }),
11500 14u16 => LinkinfoGreAttrs::EncapType({
11501 let res = parse_u16(next);
11502 let Some(val) = res else { break };
11503 val
11504 }),
11505 15u16 => LinkinfoGreAttrs::EncapFlags({
11506 let res = parse_u16(next);
11507 let Some(val) = res else { break };
11508 val
11509 }),
11510 16u16 => LinkinfoGreAttrs::EncapSport({
11511 let res = parse_be_u16(next);
11512 let Some(val) = res else { break };
11513 val
11514 }),
11515 17u16 => LinkinfoGreAttrs::EncapDport({
11516 let res = parse_be_u16(next);
11517 let Some(val) = res else { break };
11518 val
11519 }),
11520 18u16 => LinkinfoGreAttrs::CollectMetadata(()),
11521 19u16 => LinkinfoGreAttrs::IgnoreDf({
11522 let res = parse_u8(next);
11523 let Some(val) = res else { break };
11524 val
11525 }),
11526 20u16 => LinkinfoGreAttrs::Fwmark({
11527 let res = parse_u32(next);
11528 let Some(val) = res else { break };
11529 val
11530 }),
11531 21u16 => LinkinfoGreAttrs::ErspanIndex({
11532 let res = parse_u32(next);
11533 let Some(val) = res else { break };
11534 val
11535 }),
11536 22u16 => LinkinfoGreAttrs::ErspanVer({
11537 let res = parse_u8(next);
11538 let Some(val) = res else { break };
11539 val
11540 }),
11541 23u16 => LinkinfoGreAttrs::ErspanDir({
11542 let res = parse_u8(next);
11543 let Some(val) = res else { break };
11544 val
11545 }),
11546 24u16 => LinkinfoGreAttrs::ErspanHwid({
11547 let res = parse_u16(next);
11548 let Some(val) = res else { break };
11549 val
11550 }),
11551 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
11552 n => continue,
11553 };
11554 return Some(Ok(res));
11555 }
11556 Some(Err(ErrorContext::new(
11557 "LinkinfoGreAttrs",
11558 r#type.and_then(|t| LinkinfoGreAttrs::attr_from_type(t)),
11559 self.orig_loc,
11560 self.buf.as_ptr().wrapping_add(pos) as usize,
11561 )))
11562 }
11563}
11564impl std::fmt::Debug for IterableLinkinfoGreAttrs<'_> {
11565 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11566 let mut fmt = f.debug_struct("LinkinfoGreAttrs");
11567 for attr in self.clone() {
11568 let attr = match attr {
11569 Ok(a) => a,
11570 Err(err) => {
11571 fmt.finish()?;
11572 f.write_str("Err(")?;
11573 err.fmt(f)?;
11574 return f.write_str(")");
11575 }
11576 };
11577 match attr {
11578 LinkinfoGreAttrs::Link(val) => fmt.field("Link", &val),
11579 LinkinfoGreAttrs::Iflags(val) => fmt.field("Iflags", &val),
11580 LinkinfoGreAttrs::Oflags(val) => fmt.field("Oflags", &val),
11581 LinkinfoGreAttrs::Ikey(val) => fmt.field("Ikey", &val),
11582 LinkinfoGreAttrs::Okey(val) => fmt.field("Okey", &val),
11583 LinkinfoGreAttrs::Local(val) => fmt.field("Local", &val),
11584 LinkinfoGreAttrs::Remote(val) => fmt.field("Remote", &val),
11585 LinkinfoGreAttrs::Ttl(val) => fmt.field("Ttl", &val),
11586 LinkinfoGreAttrs::Tos(val) => fmt.field("Tos", &val),
11587 LinkinfoGreAttrs::Pmtudisc(val) => fmt.field("Pmtudisc", &val),
11588 LinkinfoGreAttrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
11589 LinkinfoGreAttrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
11590 LinkinfoGreAttrs::Flags(val) => fmt.field("Flags", &val),
11591 LinkinfoGreAttrs::EncapType(val) => fmt.field("EncapType", &val),
11592 LinkinfoGreAttrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
11593 LinkinfoGreAttrs::EncapSport(val) => fmt.field("EncapSport", &val),
11594 LinkinfoGreAttrs::EncapDport(val) => fmt.field("EncapDport", &val),
11595 LinkinfoGreAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
11596 LinkinfoGreAttrs::IgnoreDf(val) => fmt.field("IgnoreDf", &val),
11597 LinkinfoGreAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
11598 LinkinfoGreAttrs::ErspanIndex(val) => fmt.field("ErspanIndex", &val),
11599 LinkinfoGreAttrs::ErspanVer(val) => fmt.field("ErspanVer", &val),
11600 LinkinfoGreAttrs::ErspanDir(val) => fmt.field("ErspanDir", &val),
11601 LinkinfoGreAttrs::ErspanHwid(val) => fmt.field("ErspanHwid", &val),
11602 };
11603 }
11604 fmt.finish()
11605 }
11606}
11607impl IterableLinkinfoGreAttrs<'_> {
11608 pub fn lookup_attr(
11609 &self,
11610 offset: usize,
11611 missing_type: Option<u16>,
11612 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
11613 let mut stack = Vec::new();
11614 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
11615 if missing_type.is_some() && cur == offset {
11616 stack.push(("LinkinfoGreAttrs", offset));
11617 return (
11618 stack,
11619 missing_type.and_then(|t| LinkinfoGreAttrs::attr_from_type(t)),
11620 );
11621 }
11622 if cur > offset || cur + self.buf.len() < offset {
11623 return (stack, None);
11624 }
11625 let mut attrs = self.clone();
11626 let mut last_off = cur + attrs.pos;
11627 while let Some(attr) = attrs.next() {
11628 let Ok(attr) = attr else { break };
11629 match attr {
11630 LinkinfoGreAttrs::Link(val) => {
11631 if last_off == offset {
11632 stack.push(("Link", last_off));
11633 break;
11634 }
11635 }
11636 LinkinfoGreAttrs::Iflags(val) => {
11637 if last_off == offset {
11638 stack.push(("Iflags", last_off));
11639 break;
11640 }
11641 }
11642 LinkinfoGreAttrs::Oflags(val) => {
11643 if last_off == offset {
11644 stack.push(("Oflags", last_off));
11645 break;
11646 }
11647 }
11648 LinkinfoGreAttrs::Ikey(val) => {
11649 if last_off == offset {
11650 stack.push(("Ikey", last_off));
11651 break;
11652 }
11653 }
11654 LinkinfoGreAttrs::Okey(val) => {
11655 if last_off == offset {
11656 stack.push(("Okey", last_off));
11657 break;
11658 }
11659 }
11660 LinkinfoGreAttrs::Local(val) => {
11661 if last_off == offset {
11662 stack.push(("Local", last_off));
11663 break;
11664 }
11665 }
11666 LinkinfoGreAttrs::Remote(val) => {
11667 if last_off == offset {
11668 stack.push(("Remote", last_off));
11669 break;
11670 }
11671 }
11672 LinkinfoGreAttrs::Ttl(val) => {
11673 if last_off == offset {
11674 stack.push(("Ttl", last_off));
11675 break;
11676 }
11677 }
11678 LinkinfoGreAttrs::Tos(val) => {
11679 if last_off == offset {
11680 stack.push(("Tos", last_off));
11681 break;
11682 }
11683 }
11684 LinkinfoGreAttrs::Pmtudisc(val) => {
11685 if last_off == offset {
11686 stack.push(("Pmtudisc", last_off));
11687 break;
11688 }
11689 }
11690 LinkinfoGreAttrs::EncapLimit(val) => {
11691 if last_off == offset {
11692 stack.push(("EncapLimit", last_off));
11693 break;
11694 }
11695 }
11696 LinkinfoGreAttrs::Flowinfo(val) => {
11697 if last_off == offset {
11698 stack.push(("Flowinfo", last_off));
11699 break;
11700 }
11701 }
11702 LinkinfoGreAttrs::Flags(val) => {
11703 if last_off == offset {
11704 stack.push(("Flags", last_off));
11705 break;
11706 }
11707 }
11708 LinkinfoGreAttrs::EncapType(val) => {
11709 if last_off == offset {
11710 stack.push(("EncapType", last_off));
11711 break;
11712 }
11713 }
11714 LinkinfoGreAttrs::EncapFlags(val) => {
11715 if last_off == offset {
11716 stack.push(("EncapFlags", last_off));
11717 break;
11718 }
11719 }
11720 LinkinfoGreAttrs::EncapSport(val) => {
11721 if last_off == offset {
11722 stack.push(("EncapSport", last_off));
11723 break;
11724 }
11725 }
11726 LinkinfoGreAttrs::EncapDport(val) => {
11727 if last_off == offset {
11728 stack.push(("EncapDport", last_off));
11729 break;
11730 }
11731 }
11732 LinkinfoGreAttrs::CollectMetadata(val) => {
11733 if last_off == offset {
11734 stack.push(("CollectMetadata", last_off));
11735 break;
11736 }
11737 }
11738 LinkinfoGreAttrs::IgnoreDf(val) => {
11739 if last_off == offset {
11740 stack.push(("IgnoreDf", last_off));
11741 break;
11742 }
11743 }
11744 LinkinfoGreAttrs::Fwmark(val) => {
11745 if last_off == offset {
11746 stack.push(("Fwmark", last_off));
11747 break;
11748 }
11749 }
11750 LinkinfoGreAttrs::ErspanIndex(val) => {
11751 if last_off == offset {
11752 stack.push(("ErspanIndex", last_off));
11753 break;
11754 }
11755 }
11756 LinkinfoGreAttrs::ErspanVer(val) => {
11757 if last_off == offset {
11758 stack.push(("ErspanVer", last_off));
11759 break;
11760 }
11761 }
11762 LinkinfoGreAttrs::ErspanDir(val) => {
11763 if last_off == offset {
11764 stack.push(("ErspanDir", last_off));
11765 break;
11766 }
11767 }
11768 LinkinfoGreAttrs::ErspanHwid(val) => {
11769 if last_off == offset {
11770 stack.push(("ErspanHwid", last_off));
11771 break;
11772 }
11773 }
11774 _ => {}
11775 };
11776 last_off = cur + attrs.pos;
11777 }
11778 if !stack.is_empty() {
11779 stack.push(("LinkinfoGreAttrs", cur));
11780 }
11781 (stack, None)
11782 }
11783}
11784#[derive(Clone)]
11785pub enum LinkinfoGre6Attrs<'a> {
11786 Link(u32),
11787 Iflags(u16),
11788 Oflags(u16),
11789 Ikey(u32),
11790 Okey(u32),
11791 Local(&'a [u8]),
11792 Remote(&'a [u8]),
11793 Ttl(u8),
11794 EncapLimit(u8),
11795 Flowinfo(u32),
11796 Flags(u32),
11797 EncapType(u16),
11798 EncapFlags(u16),
11799 EncapSport(u16),
11800 EncapDport(u16),
11801 CollectMetadata(()),
11802 Fwmark(u32),
11803 ErspanIndex(u32),
11804 ErspanVer(u8),
11805 ErspanDir(u8),
11806 ErspanHwid(u16),
11807}
11808impl<'a> IterableLinkinfoGre6Attrs<'a> {
11809 pub fn get_link(&self) -> Result<u32, ErrorContext> {
11810 let mut iter = self.clone();
11811 iter.pos = 0;
11812 for attr in iter {
11813 if let LinkinfoGre6Attrs::Link(val) = attr? {
11814 return Ok(val);
11815 }
11816 }
11817 Err(ErrorContext::new_missing(
11818 "LinkinfoGre6Attrs",
11819 "Link",
11820 self.orig_loc,
11821 self.buf.as_ptr() as usize,
11822 ))
11823 }
11824 pub fn get_iflags(&self) -> Result<u16, ErrorContext> {
11825 let mut iter = self.clone();
11826 iter.pos = 0;
11827 for attr in iter {
11828 if let LinkinfoGre6Attrs::Iflags(val) = attr? {
11829 return Ok(val);
11830 }
11831 }
11832 Err(ErrorContext::new_missing(
11833 "LinkinfoGre6Attrs",
11834 "Iflags",
11835 self.orig_loc,
11836 self.buf.as_ptr() as usize,
11837 ))
11838 }
11839 pub fn get_oflags(&self) -> Result<u16, ErrorContext> {
11840 let mut iter = self.clone();
11841 iter.pos = 0;
11842 for attr in iter {
11843 if let LinkinfoGre6Attrs::Oflags(val) = attr? {
11844 return Ok(val);
11845 }
11846 }
11847 Err(ErrorContext::new_missing(
11848 "LinkinfoGre6Attrs",
11849 "Oflags",
11850 self.orig_loc,
11851 self.buf.as_ptr() as usize,
11852 ))
11853 }
11854 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
11855 let mut iter = self.clone();
11856 iter.pos = 0;
11857 for attr in iter {
11858 if let LinkinfoGre6Attrs::Ikey(val) = attr? {
11859 return Ok(val);
11860 }
11861 }
11862 Err(ErrorContext::new_missing(
11863 "LinkinfoGre6Attrs",
11864 "Ikey",
11865 self.orig_loc,
11866 self.buf.as_ptr() as usize,
11867 ))
11868 }
11869 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
11870 let mut iter = self.clone();
11871 iter.pos = 0;
11872 for attr in iter {
11873 if let LinkinfoGre6Attrs::Okey(val) = attr? {
11874 return Ok(val);
11875 }
11876 }
11877 Err(ErrorContext::new_missing(
11878 "LinkinfoGre6Attrs",
11879 "Okey",
11880 self.orig_loc,
11881 self.buf.as_ptr() as usize,
11882 ))
11883 }
11884 pub fn get_local(&self) -> Result<&'a [u8], ErrorContext> {
11885 let mut iter = self.clone();
11886 iter.pos = 0;
11887 for attr in iter {
11888 if let LinkinfoGre6Attrs::Local(val) = attr? {
11889 return Ok(val);
11890 }
11891 }
11892 Err(ErrorContext::new_missing(
11893 "LinkinfoGre6Attrs",
11894 "Local",
11895 self.orig_loc,
11896 self.buf.as_ptr() as usize,
11897 ))
11898 }
11899 pub fn get_remote(&self) -> Result<&'a [u8], ErrorContext> {
11900 let mut iter = self.clone();
11901 iter.pos = 0;
11902 for attr in iter {
11903 if let LinkinfoGre6Attrs::Remote(val) = attr? {
11904 return Ok(val);
11905 }
11906 }
11907 Err(ErrorContext::new_missing(
11908 "LinkinfoGre6Attrs",
11909 "Remote",
11910 self.orig_loc,
11911 self.buf.as_ptr() as usize,
11912 ))
11913 }
11914 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
11915 let mut iter = self.clone();
11916 iter.pos = 0;
11917 for attr in iter {
11918 if let LinkinfoGre6Attrs::Ttl(val) = attr? {
11919 return Ok(val);
11920 }
11921 }
11922 Err(ErrorContext::new_missing(
11923 "LinkinfoGre6Attrs",
11924 "Ttl",
11925 self.orig_loc,
11926 self.buf.as_ptr() as usize,
11927 ))
11928 }
11929 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
11930 let mut iter = self.clone();
11931 iter.pos = 0;
11932 for attr in iter {
11933 if let LinkinfoGre6Attrs::EncapLimit(val) = attr? {
11934 return Ok(val);
11935 }
11936 }
11937 Err(ErrorContext::new_missing(
11938 "LinkinfoGre6Attrs",
11939 "EncapLimit",
11940 self.orig_loc,
11941 self.buf.as_ptr() as usize,
11942 ))
11943 }
11944 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
11945 let mut iter = self.clone();
11946 iter.pos = 0;
11947 for attr in iter {
11948 if let LinkinfoGre6Attrs::Flowinfo(val) = attr? {
11949 return Ok(val);
11950 }
11951 }
11952 Err(ErrorContext::new_missing(
11953 "LinkinfoGre6Attrs",
11954 "Flowinfo",
11955 self.orig_loc,
11956 self.buf.as_ptr() as usize,
11957 ))
11958 }
11959 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
11960 let mut iter = self.clone();
11961 iter.pos = 0;
11962 for attr in iter {
11963 if let LinkinfoGre6Attrs::Flags(val) = attr? {
11964 return Ok(val);
11965 }
11966 }
11967 Err(ErrorContext::new_missing(
11968 "LinkinfoGre6Attrs",
11969 "Flags",
11970 self.orig_loc,
11971 self.buf.as_ptr() as usize,
11972 ))
11973 }
11974 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
11975 let mut iter = self.clone();
11976 iter.pos = 0;
11977 for attr in iter {
11978 if let LinkinfoGre6Attrs::EncapType(val) = attr? {
11979 return Ok(val);
11980 }
11981 }
11982 Err(ErrorContext::new_missing(
11983 "LinkinfoGre6Attrs",
11984 "EncapType",
11985 self.orig_loc,
11986 self.buf.as_ptr() as usize,
11987 ))
11988 }
11989 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
11990 let mut iter = self.clone();
11991 iter.pos = 0;
11992 for attr in iter {
11993 if let LinkinfoGre6Attrs::EncapFlags(val) = attr? {
11994 return Ok(val);
11995 }
11996 }
11997 Err(ErrorContext::new_missing(
11998 "LinkinfoGre6Attrs",
11999 "EncapFlags",
12000 self.orig_loc,
12001 self.buf.as_ptr() as usize,
12002 ))
12003 }
12004 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
12005 let mut iter = self.clone();
12006 iter.pos = 0;
12007 for attr in iter {
12008 if let LinkinfoGre6Attrs::EncapSport(val) = attr? {
12009 return Ok(val);
12010 }
12011 }
12012 Err(ErrorContext::new_missing(
12013 "LinkinfoGre6Attrs",
12014 "EncapSport",
12015 self.orig_loc,
12016 self.buf.as_ptr() as usize,
12017 ))
12018 }
12019 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
12020 let mut iter = self.clone();
12021 iter.pos = 0;
12022 for attr in iter {
12023 if let LinkinfoGre6Attrs::EncapDport(val) = attr? {
12024 return Ok(val);
12025 }
12026 }
12027 Err(ErrorContext::new_missing(
12028 "LinkinfoGre6Attrs",
12029 "EncapDport",
12030 self.orig_loc,
12031 self.buf.as_ptr() as usize,
12032 ))
12033 }
12034 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
12035 let mut iter = self.clone();
12036 iter.pos = 0;
12037 for attr in iter {
12038 if let LinkinfoGre6Attrs::CollectMetadata(val) = attr? {
12039 return Ok(val);
12040 }
12041 }
12042 Err(ErrorContext::new_missing(
12043 "LinkinfoGre6Attrs",
12044 "CollectMetadata",
12045 self.orig_loc,
12046 self.buf.as_ptr() as usize,
12047 ))
12048 }
12049 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
12050 let mut iter = self.clone();
12051 iter.pos = 0;
12052 for attr in iter {
12053 if let LinkinfoGre6Attrs::Fwmark(val) = attr? {
12054 return Ok(val);
12055 }
12056 }
12057 Err(ErrorContext::new_missing(
12058 "LinkinfoGre6Attrs",
12059 "Fwmark",
12060 self.orig_loc,
12061 self.buf.as_ptr() as usize,
12062 ))
12063 }
12064 pub fn get_erspan_index(&self) -> Result<u32, ErrorContext> {
12065 let mut iter = self.clone();
12066 iter.pos = 0;
12067 for attr in iter {
12068 if let LinkinfoGre6Attrs::ErspanIndex(val) = attr? {
12069 return Ok(val);
12070 }
12071 }
12072 Err(ErrorContext::new_missing(
12073 "LinkinfoGre6Attrs",
12074 "ErspanIndex",
12075 self.orig_loc,
12076 self.buf.as_ptr() as usize,
12077 ))
12078 }
12079 pub fn get_erspan_ver(&self) -> Result<u8, ErrorContext> {
12080 let mut iter = self.clone();
12081 iter.pos = 0;
12082 for attr in iter {
12083 if let LinkinfoGre6Attrs::ErspanVer(val) = attr? {
12084 return Ok(val);
12085 }
12086 }
12087 Err(ErrorContext::new_missing(
12088 "LinkinfoGre6Attrs",
12089 "ErspanVer",
12090 self.orig_loc,
12091 self.buf.as_ptr() as usize,
12092 ))
12093 }
12094 pub fn get_erspan_dir(&self) -> Result<u8, ErrorContext> {
12095 let mut iter = self.clone();
12096 iter.pos = 0;
12097 for attr in iter {
12098 if let LinkinfoGre6Attrs::ErspanDir(val) = attr? {
12099 return Ok(val);
12100 }
12101 }
12102 Err(ErrorContext::new_missing(
12103 "LinkinfoGre6Attrs",
12104 "ErspanDir",
12105 self.orig_loc,
12106 self.buf.as_ptr() as usize,
12107 ))
12108 }
12109 pub fn get_erspan_hwid(&self) -> Result<u16, ErrorContext> {
12110 let mut iter = self.clone();
12111 iter.pos = 0;
12112 for attr in iter {
12113 if let LinkinfoGre6Attrs::ErspanHwid(val) = attr? {
12114 return Ok(val);
12115 }
12116 }
12117 Err(ErrorContext::new_missing(
12118 "LinkinfoGre6Attrs",
12119 "ErspanHwid",
12120 self.orig_loc,
12121 self.buf.as_ptr() as usize,
12122 ))
12123 }
12124}
12125impl LinkinfoGre6Attrs<'_> {
12126 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoGre6Attrs<'a> {
12127 IterableLinkinfoGre6Attrs::with_loc(buf, buf.as_ptr() as usize)
12128 }
12129 fn attr_from_type(r#type: u16) -> Option<&'static str> {
12130 LinkinfoGreAttrs::attr_from_type(r#type)
12131 }
12132}
12133#[derive(Clone, Copy, Default)]
12134pub struct IterableLinkinfoGre6Attrs<'a> {
12135 buf: &'a [u8],
12136 pos: usize,
12137 orig_loc: usize,
12138}
12139impl<'a> IterableLinkinfoGre6Attrs<'a> {
12140 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
12141 Self {
12142 buf,
12143 pos: 0,
12144 orig_loc,
12145 }
12146 }
12147 pub fn get_buf(&self) -> &'a [u8] {
12148 self.buf
12149 }
12150}
12151impl<'a> Iterator for IterableLinkinfoGre6Attrs<'a> {
12152 type Item = Result<LinkinfoGre6Attrs<'a>, ErrorContext>;
12153 fn next(&mut self) -> Option<Self::Item> {
12154 let pos = self.pos;
12155 let mut r#type;
12156 loop {
12157 r#type = None;
12158 if self.buf.len() == self.pos {
12159 return None;
12160 }
12161 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
12162 break;
12163 };
12164 r#type = Some(header.r#type);
12165 let res = match header.r#type {
12166 1u16 => LinkinfoGre6Attrs::Link({
12167 let res = parse_u32(next);
12168 let Some(val) = res else { break };
12169 val
12170 }),
12171 2u16 => LinkinfoGre6Attrs::Iflags({
12172 let res = parse_be_u16(next);
12173 let Some(val) = res else { break };
12174 val
12175 }),
12176 3u16 => LinkinfoGre6Attrs::Oflags({
12177 let res = parse_be_u16(next);
12178 let Some(val) = res else { break };
12179 val
12180 }),
12181 4u16 => LinkinfoGre6Attrs::Ikey({
12182 let res = parse_be_u32(next);
12183 let Some(val) = res else { break };
12184 val
12185 }),
12186 5u16 => LinkinfoGre6Attrs::Okey({
12187 let res = parse_be_u32(next);
12188 let Some(val) = res else { break };
12189 val
12190 }),
12191 6u16 => LinkinfoGre6Attrs::Local({
12192 let res = Some(next);
12193 let Some(val) = res else { break };
12194 val
12195 }),
12196 7u16 => LinkinfoGre6Attrs::Remote({
12197 let res = Some(next);
12198 let Some(val) = res else { break };
12199 val
12200 }),
12201 8u16 => LinkinfoGre6Attrs::Ttl({
12202 let res = parse_u8(next);
12203 let Some(val) = res else { break };
12204 val
12205 }),
12206 11u16 => LinkinfoGre6Attrs::EncapLimit({
12207 let res = parse_u8(next);
12208 let Some(val) = res else { break };
12209 val
12210 }),
12211 12u16 => LinkinfoGre6Attrs::Flowinfo({
12212 let res = parse_be_u32(next);
12213 let Some(val) = res else { break };
12214 val
12215 }),
12216 13u16 => LinkinfoGre6Attrs::Flags({
12217 let res = parse_u32(next);
12218 let Some(val) = res else { break };
12219 val
12220 }),
12221 14u16 => LinkinfoGre6Attrs::EncapType({
12222 let res = parse_u16(next);
12223 let Some(val) = res else { break };
12224 val
12225 }),
12226 15u16 => LinkinfoGre6Attrs::EncapFlags({
12227 let res = parse_u16(next);
12228 let Some(val) = res else { break };
12229 val
12230 }),
12231 16u16 => LinkinfoGre6Attrs::EncapSport({
12232 let res = parse_be_u16(next);
12233 let Some(val) = res else { break };
12234 val
12235 }),
12236 17u16 => LinkinfoGre6Attrs::EncapDport({
12237 let res = parse_be_u16(next);
12238 let Some(val) = res else { break };
12239 val
12240 }),
12241 18u16 => LinkinfoGre6Attrs::CollectMetadata(()),
12242 20u16 => LinkinfoGre6Attrs::Fwmark({
12243 let res = parse_u32(next);
12244 let Some(val) = res else { break };
12245 val
12246 }),
12247 21u16 => LinkinfoGre6Attrs::ErspanIndex({
12248 let res = parse_u32(next);
12249 let Some(val) = res else { break };
12250 val
12251 }),
12252 22u16 => LinkinfoGre6Attrs::ErspanVer({
12253 let res = parse_u8(next);
12254 let Some(val) = res else { break };
12255 val
12256 }),
12257 23u16 => LinkinfoGre6Attrs::ErspanDir({
12258 let res = parse_u8(next);
12259 let Some(val) = res else { break };
12260 val
12261 }),
12262 24u16 => LinkinfoGre6Attrs::ErspanHwid({
12263 let res = parse_u16(next);
12264 let Some(val) = res else { break };
12265 val
12266 }),
12267 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
12268 n => continue,
12269 };
12270 return Some(Ok(res));
12271 }
12272 Some(Err(ErrorContext::new(
12273 "LinkinfoGre6Attrs",
12274 r#type.and_then(|t| LinkinfoGre6Attrs::attr_from_type(t)),
12275 self.orig_loc,
12276 self.buf.as_ptr().wrapping_add(pos) as usize,
12277 )))
12278 }
12279}
12280impl<'a> std::fmt::Debug for IterableLinkinfoGre6Attrs<'_> {
12281 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12282 let mut fmt = f.debug_struct("LinkinfoGre6Attrs");
12283 for attr in self.clone() {
12284 let attr = match attr {
12285 Ok(a) => a,
12286 Err(err) => {
12287 fmt.finish()?;
12288 f.write_str("Err(")?;
12289 err.fmt(f)?;
12290 return f.write_str(")");
12291 }
12292 };
12293 match attr {
12294 LinkinfoGre6Attrs::Link(val) => fmt.field("Link", &val),
12295 LinkinfoGre6Attrs::Iflags(val) => fmt.field("Iflags", &val),
12296 LinkinfoGre6Attrs::Oflags(val) => fmt.field("Oflags", &val),
12297 LinkinfoGre6Attrs::Ikey(val) => fmt.field("Ikey", &val),
12298 LinkinfoGre6Attrs::Okey(val) => fmt.field("Okey", &val),
12299 LinkinfoGre6Attrs::Local(val) => fmt.field("Local", &val),
12300 LinkinfoGre6Attrs::Remote(val) => fmt.field("Remote", &val),
12301 LinkinfoGre6Attrs::Ttl(val) => fmt.field("Ttl", &val),
12302 LinkinfoGre6Attrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
12303 LinkinfoGre6Attrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
12304 LinkinfoGre6Attrs::Flags(val) => fmt.field("Flags", &val),
12305 LinkinfoGre6Attrs::EncapType(val) => fmt.field("EncapType", &val),
12306 LinkinfoGre6Attrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
12307 LinkinfoGre6Attrs::EncapSport(val) => fmt.field("EncapSport", &val),
12308 LinkinfoGre6Attrs::EncapDport(val) => fmt.field("EncapDport", &val),
12309 LinkinfoGre6Attrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
12310 LinkinfoGre6Attrs::Fwmark(val) => fmt.field("Fwmark", &val),
12311 LinkinfoGre6Attrs::ErspanIndex(val) => fmt.field("ErspanIndex", &val),
12312 LinkinfoGre6Attrs::ErspanVer(val) => fmt.field("ErspanVer", &val),
12313 LinkinfoGre6Attrs::ErspanDir(val) => fmt.field("ErspanDir", &val),
12314 LinkinfoGre6Attrs::ErspanHwid(val) => fmt.field("ErspanHwid", &val),
12315 };
12316 }
12317 fmt.finish()
12318 }
12319}
12320impl IterableLinkinfoGre6Attrs<'_> {
12321 pub fn lookup_attr(
12322 &self,
12323 offset: usize,
12324 missing_type: Option<u16>,
12325 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
12326 let mut stack = Vec::new();
12327 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
12328 if missing_type.is_some() && cur == offset {
12329 stack.push(("LinkinfoGre6Attrs", offset));
12330 return (
12331 stack,
12332 missing_type.and_then(|t| LinkinfoGre6Attrs::attr_from_type(t)),
12333 );
12334 }
12335 if cur > offset || cur + self.buf.len() < offset {
12336 return (stack, None);
12337 }
12338 let mut attrs = self.clone();
12339 let mut last_off = cur + attrs.pos;
12340 while let Some(attr) = attrs.next() {
12341 let Ok(attr) = attr else { break };
12342 match attr {
12343 LinkinfoGre6Attrs::Link(val) => {
12344 if last_off == offset {
12345 stack.push(("Link", last_off));
12346 break;
12347 }
12348 }
12349 LinkinfoGre6Attrs::Iflags(val) => {
12350 if last_off == offset {
12351 stack.push(("Iflags", last_off));
12352 break;
12353 }
12354 }
12355 LinkinfoGre6Attrs::Oflags(val) => {
12356 if last_off == offset {
12357 stack.push(("Oflags", last_off));
12358 break;
12359 }
12360 }
12361 LinkinfoGre6Attrs::Ikey(val) => {
12362 if last_off == offset {
12363 stack.push(("Ikey", last_off));
12364 break;
12365 }
12366 }
12367 LinkinfoGre6Attrs::Okey(val) => {
12368 if last_off == offset {
12369 stack.push(("Okey", last_off));
12370 break;
12371 }
12372 }
12373 LinkinfoGre6Attrs::Local(val) => {
12374 if last_off == offset {
12375 stack.push(("Local", last_off));
12376 break;
12377 }
12378 }
12379 LinkinfoGre6Attrs::Remote(val) => {
12380 if last_off == offset {
12381 stack.push(("Remote", last_off));
12382 break;
12383 }
12384 }
12385 LinkinfoGre6Attrs::Ttl(val) => {
12386 if last_off == offset {
12387 stack.push(("Ttl", last_off));
12388 break;
12389 }
12390 }
12391 LinkinfoGre6Attrs::EncapLimit(val) => {
12392 if last_off == offset {
12393 stack.push(("EncapLimit", last_off));
12394 break;
12395 }
12396 }
12397 LinkinfoGre6Attrs::Flowinfo(val) => {
12398 if last_off == offset {
12399 stack.push(("Flowinfo", last_off));
12400 break;
12401 }
12402 }
12403 LinkinfoGre6Attrs::Flags(val) => {
12404 if last_off == offset {
12405 stack.push(("Flags", last_off));
12406 break;
12407 }
12408 }
12409 LinkinfoGre6Attrs::EncapType(val) => {
12410 if last_off == offset {
12411 stack.push(("EncapType", last_off));
12412 break;
12413 }
12414 }
12415 LinkinfoGre6Attrs::EncapFlags(val) => {
12416 if last_off == offset {
12417 stack.push(("EncapFlags", last_off));
12418 break;
12419 }
12420 }
12421 LinkinfoGre6Attrs::EncapSport(val) => {
12422 if last_off == offset {
12423 stack.push(("EncapSport", last_off));
12424 break;
12425 }
12426 }
12427 LinkinfoGre6Attrs::EncapDport(val) => {
12428 if last_off == offset {
12429 stack.push(("EncapDport", last_off));
12430 break;
12431 }
12432 }
12433 LinkinfoGre6Attrs::CollectMetadata(val) => {
12434 if last_off == offset {
12435 stack.push(("CollectMetadata", last_off));
12436 break;
12437 }
12438 }
12439 LinkinfoGre6Attrs::Fwmark(val) => {
12440 if last_off == offset {
12441 stack.push(("Fwmark", last_off));
12442 break;
12443 }
12444 }
12445 LinkinfoGre6Attrs::ErspanIndex(val) => {
12446 if last_off == offset {
12447 stack.push(("ErspanIndex", last_off));
12448 break;
12449 }
12450 }
12451 LinkinfoGre6Attrs::ErspanVer(val) => {
12452 if last_off == offset {
12453 stack.push(("ErspanVer", last_off));
12454 break;
12455 }
12456 }
12457 LinkinfoGre6Attrs::ErspanDir(val) => {
12458 if last_off == offset {
12459 stack.push(("ErspanDir", last_off));
12460 break;
12461 }
12462 }
12463 LinkinfoGre6Attrs::ErspanHwid(val) => {
12464 if last_off == offset {
12465 stack.push(("ErspanHwid", last_off));
12466 break;
12467 }
12468 }
12469 _ => {}
12470 };
12471 last_off = cur + attrs.pos;
12472 }
12473 if !stack.is_empty() {
12474 stack.push(("LinkinfoGre6Attrs", cur));
12475 }
12476 (stack, None)
12477 }
12478}
12479#[derive(Clone)]
12480pub enum LinkinfoVtiAttrs {
12481 Link(u32),
12482 Ikey(u32),
12483 Okey(u32),
12484 Local(std::net::IpAddr),
12485 Remote(std::net::IpAddr),
12486 Fwmark(u32),
12487}
12488impl<'a> IterableLinkinfoVtiAttrs<'a> {
12489 pub fn get_link(&self) -> Result<u32, ErrorContext> {
12490 let mut iter = self.clone();
12491 iter.pos = 0;
12492 for attr in iter {
12493 if let LinkinfoVtiAttrs::Link(val) = attr? {
12494 return Ok(val);
12495 }
12496 }
12497 Err(ErrorContext::new_missing(
12498 "LinkinfoVtiAttrs",
12499 "Link",
12500 self.orig_loc,
12501 self.buf.as_ptr() as usize,
12502 ))
12503 }
12504 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
12505 let mut iter = self.clone();
12506 iter.pos = 0;
12507 for attr in iter {
12508 if let LinkinfoVtiAttrs::Ikey(val) = attr? {
12509 return Ok(val);
12510 }
12511 }
12512 Err(ErrorContext::new_missing(
12513 "LinkinfoVtiAttrs",
12514 "Ikey",
12515 self.orig_loc,
12516 self.buf.as_ptr() as usize,
12517 ))
12518 }
12519 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
12520 let mut iter = self.clone();
12521 iter.pos = 0;
12522 for attr in iter {
12523 if let LinkinfoVtiAttrs::Okey(val) = attr? {
12524 return Ok(val);
12525 }
12526 }
12527 Err(ErrorContext::new_missing(
12528 "LinkinfoVtiAttrs",
12529 "Okey",
12530 self.orig_loc,
12531 self.buf.as_ptr() as usize,
12532 ))
12533 }
12534 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
12535 let mut iter = self.clone();
12536 iter.pos = 0;
12537 for attr in iter {
12538 if let LinkinfoVtiAttrs::Local(val) = attr? {
12539 return Ok(val);
12540 }
12541 }
12542 Err(ErrorContext::new_missing(
12543 "LinkinfoVtiAttrs",
12544 "Local",
12545 self.orig_loc,
12546 self.buf.as_ptr() as usize,
12547 ))
12548 }
12549 pub fn get_remote(&self) -> Result<std::net::IpAddr, ErrorContext> {
12550 let mut iter = self.clone();
12551 iter.pos = 0;
12552 for attr in iter {
12553 if let LinkinfoVtiAttrs::Remote(val) = attr? {
12554 return Ok(val);
12555 }
12556 }
12557 Err(ErrorContext::new_missing(
12558 "LinkinfoVtiAttrs",
12559 "Remote",
12560 self.orig_loc,
12561 self.buf.as_ptr() as usize,
12562 ))
12563 }
12564 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
12565 let mut iter = self.clone();
12566 iter.pos = 0;
12567 for attr in iter {
12568 if let LinkinfoVtiAttrs::Fwmark(val) = attr? {
12569 return Ok(val);
12570 }
12571 }
12572 Err(ErrorContext::new_missing(
12573 "LinkinfoVtiAttrs",
12574 "Fwmark",
12575 self.orig_loc,
12576 self.buf.as_ptr() as usize,
12577 ))
12578 }
12579}
12580impl LinkinfoVtiAttrs {
12581 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVtiAttrs<'a> {
12582 IterableLinkinfoVtiAttrs::with_loc(buf, buf.as_ptr() as usize)
12583 }
12584 fn attr_from_type(r#type: u16) -> Option<&'static str> {
12585 let res = match r#type {
12586 1u16 => "Link",
12587 2u16 => "Ikey",
12588 3u16 => "Okey",
12589 4u16 => "Local",
12590 5u16 => "Remote",
12591 6u16 => "Fwmark",
12592 _ => return None,
12593 };
12594 Some(res)
12595 }
12596}
12597#[derive(Clone, Copy, Default)]
12598pub struct IterableLinkinfoVtiAttrs<'a> {
12599 buf: &'a [u8],
12600 pos: usize,
12601 orig_loc: usize,
12602}
12603impl<'a> IterableLinkinfoVtiAttrs<'a> {
12604 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
12605 Self {
12606 buf,
12607 pos: 0,
12608 orig_loc,
12609 }
12610 }
12611 pub fn get_buf(&self) -> &'a [u8] {
12612 self.buf
12613 }
12614}
12615impl<'a> Iterator for IterableLinkinfoVtiAttrs<'a> {
12616 type Item = Result<LinkinfoVtiAttrs, ErrorContext>;
12617 fn next(&mut self) -> Option<Self::Item> {
12618 let pos = self.pos;
12619 let mut r#type;
12620 loop {
12621 r#type = None;
12622 if self.buf.len() == self.pos {
12623 return None;
12624 }
12625 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
12626 break;
12627 };
12628 r#type = Some(header.r#type);
12629 let res = match header.r#type {
12630 1u16 => LinkinfoVtiAttrs::Link({
12631 let res = parse_u32(next);
12632 let Some(val) = res else { break };
12633 val
12634 }),
12635 2u16 => LinkinfoVtiAttrs::Ikey({
12636 let res = parse_be_u32(next);
12637 let Some(val) = res else { break };
12638 val
12639 }),
12640 3u16 => LinkinfoVtiAttrs::Okey({
12641 let res = parse_be_u32(next);
12642 let Some(val) = res else { break };
12643 val
12644 }),
12645 4u16 => LinkinfoVtiAttrs::Local({
12646 let res = parse_ip(next);
12647 let Some(val) = res else { break };
12648 val
12649 }),
12650 5u16 => LinkinfoVtiAttrs::Remote({
12651 let res = parse_ip(next);
12652 let Some(val) = res else { break };
12653 val
12654 }),
12655 6u16 => LinkinfoVtiAttrs::Fwmark({
12656 let res = parse_u32(next);
12657 let Some(val) = res else { break };
12658 val
12659 }),
12660 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
12661 n => continue,
12662 };
12663 return Some(Ok(res));
12664 }
12665 Some(Err(ErrorContext::new(
12666 "LinkinfoVtiAttrs",
12667 r#type.and_then(|t| LinkinfoVtiAttrs::attr_from_type(t)),
12668 self.orig_loc,
12669 self.buf.as_ptr().wrapping_add(pos) as usize,
12670 )))
12671 }
12672}
12673impl std::fmt::Debug for IterableLinkinfoVtiAttrs<'_> {
12674 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12675 let mut fmt = f.debug_struct("LinkinfoVtiAttrs");
12676 for attr in self.clone() {
12677 let attr = match attr {
12678 Ok(a) => a,
12679 Err(err) => {
12680 fmt.finish()?;
12681 f.write_str("Err(")?;
12682 err.fmt(f)?;
12683 return f.write_str(")");
12684 }
12685 };
12686 match attr {
12687 LinkinfoVtiAttrs::Link(val) => fmt.field("Link", &val),
12688 LinkinfoVtiAttrs::Ikey(val) => fmt.field("Ikey", &val),
12689 LinkinfoVtiAttrs::Okey(val) => fmt.field("Okey", &val),
12690 LinkinfoVtiAttrs::Local(val) => fmt.field("Local", &val),
12691 LinkinfoVtiAttrs::Remote(val) => fmt.field("Remote", &val),
12692 LinkinfoVtiAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
12693 };
12694 }
12695 fmt.finish()
12696 }
12697}
12698impl IterableLinkinfoVtiAttrs<'_> {
12699 pub fn lookup_attr(
12700 &self,
12701 offset: usize,
12702 missing_type: Option<u16>,
12703 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
12704 let mut stack = Vec::new();
12705 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
12706 if missing_type.is_some() && cur == offset {
12707 stack.push(("LinkinfoVtiAttrs", offset));
12708 return (
12709 stack,
12710 missing_type.and_then(|t| LinkinfoVtiAttrs::attr_from_type(t)),
12711 );
12712 }
12713 if cur > offset || cur + self.buf.len() < offset {
12714 return (stack, None);
12715 }
12716 let mut attrs = self.clone();
12717 let mut last_off = cur + attrs.pos;
12718 while let Some(attr) = attrs.next() {
12719 let Ok(attr) = attr else { break };
12720 match attr {
12721 LinkinfoVtiAttrs::Link(val) => {
12722 if last_off == offset {
12723 stack.push(("Link", last_off));
12724 break;
12725 }
12726 }
12727 LinkinfoVtiAttrs::Ikey(val) => {
12728 if last_off == offset {
12729 stack.push(("Ikey", last_off));
12730 break;
12731 }
12732 }
12733 LinkinfoVtiAttrs::Okey(val) => {
12734 if last_off == offset {
12735 stack.push(("Okey", last_off));
12736 break;
12737 }
12738 }
12739 LinkinfoVtiAttrs::Local(val) => {
12740 if last_off == offset {
12741 stack.push(("Local", last_off));
12742 break;
12743 }
12744 }
12745 LinkinfoVtiAttrs::Remote(val) => {
12746 if last_off == offset {
12747 stack.push(("Remote", last_off));
12748 break;
12749 }
12750 }
12751 LinkinfoVtiAttrs::Fwmark(val) => {
12752 if last_off == offset {
12753 stack.push(("Fwmark", last_off));
12754 break;
12755 }
12756 }
12757 _ => {}
12758 };
12759 last_off = cur + attrs.pos;
12760 }
12761 if !stack.is_empty() {
12762 stack.push(("LinkinfoVtiAttrs", cur));
12763 }
12764 (stack, None)
12765 }
12766}
12767#[derive(Clone)]
12768pub enum LinkinfoVti6Attrs<'a> {
12769 Link(u32),
12770 Ikey(u32),
12771 Okey(u32),
12772 Local(&'a [u8]),
12773 Remote(&'a [u8]),
12774 Fwmark(u32),
12775}
12776impl<'a> IterableLinkinfoVti6Attrs<'a> {
12777 pub fn get_link(&self) -> Result<u32, ErrorContext> {
12778 let mut iter = self.clone();
12779 iter.pos = 0;
12780 for attr in iter {
12781 if let LinkinfoVti6Attrs::Link(val) = attr? {
12782 return Ok(val);
12783 }
12784 }
12785 Err(ErrorContext::new_missing(
12786 "LinkinfoVti6Attrs",
12787 "Link",
12788 self.orig_loc,
12789 self.buf.as_ptr() as usize,
12790 ))
12791 }
12792 pub fn get_ikey(&self) -> Result<u32, ErrorContext> {
12793 let mut iter = self.clone();
12794 iter.pos = 0;
12795 for attr in iter {
12796 if let LinkinfoVti6Attrs::Ikey(val) = attr? {
12797 return Ok(val);
12798 }
12799 }
12800 Err(ErrorContext::new_missing(
12801 "LinkinfoVti6Attrs",
12802 "Ikey",
12803 self.orig_loc,
12804 self.buf.as_ptr() as usize,
12805 ))
12806 }
12807 pub fn get_okey(&self) -> Result<u32, ErrorContext> {
12808 let mut iter = self.clone();
12809 iter.pos = 0;
12810 for attr in iter {
12811 if let LinkinfoVti6Attrs::Okey(val) = attr? {
12812 return Ok(val);
12813 }
12814 }
12815 Err(ErrorContext::new_missing(
12816 "LinkinfoVti6Attrs",
12817 "Okey",
12818 self.orig_loc,
12819 self.buf.as_ptr() as usize,
12820 ))
12821 }
12822 pub fn get_local(&self) -> Result<&'a [u8], ErrorContext> {
12823 let mut iter = self.clone();
12824 iter.pos = 0;
12825 for attr in iter {
12826 if let LinkinfoVti6Attrs::Local(val) = attr? {
12827 return Ok(val);
12828 }
12829 }
12830 Err(ErrorContext::new_missing(
12831 "LinkinfoVti6Attrs",
12832 "Local",
12833 self.orig_loc,
12834 self.buf.as_ptr() as usize,
12835 ))
12836 }
12837 pub fn get_remote(&self) -> Result<&'a [u8], ErrorContext> {
12838 let mut iter = self.clone();
12839 iter.pos = 0;
12840 for attr in iter {
12841 if let LinkinfoVti6Attrs::Remote(val) = attr? {
12842 return Ok(val);
12843 }
12844 }
12845 Err(ErrorContext::new_missing(
12846 "LinkinfoVti6Attrs",
12847 "Remote",
12848 self.orig_loc,
12849 self.buf.as_ptr() as usize,
12850 ))
12851 }
12852 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
12853 let mut iter = self.clone();
12854 iter.pos = 0;
12855 for attr in iter {
12856 if let LinkinfoVti6Attrs::Fwmark(val) = attr? {
12857 return Ok(val);
12858 }
12859 }
12860 Err(ErrorContext::new_missing(
12861 "LinkinfoVti6Attrs",
12862 "Fwmark",
12863 self.orig_loc,
12864 self.buf.as_ptr() as usize,
12865 ))
12866 }
12867}
12868impl LinkinfoVti6Attrs<'_> {
12869 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVti6Attrs<'a> {
12870 IterableLinkinfoVti6Attrs::with_loc(buf, buf.as_ptr() as usize)
12871 }
12872 fn attr_from_type(r#type: u16) -> Option<&'static str> {
12873 LinkinfoVtiAttrs::attr_from_type(r#type)
12874 }
12875}
12876#[derive(Clone, Copy, Default)]
12877pub struct IterableLinkinfoVti6Attrs<'a> {
12878 buf: &'a [u8],
12879 pos: usize,
12880 orig_loc: usize,
12881}
12882impl<'a> IterableLinkinfoVti6Attrs<'a> {
12883 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
12884 Self {
12885 buf,
12886 pos: 0,
12887 orig_loc,
12888 }
12889 }
12890 pub fn get_buf(&self) -> &'a [u8] {
12891 self.buf
12892 }
12893}
12894impl<'a> Iterator for IterableLinkinfoVti6Attrs<'a> {
12895 type Item = Result<LinkinfoVti6Attrs<'a>, ErrorContext>;
12896 fn next(&mut self) -> Option<Self::Item> {
12897 let pos = self.pos;
12898 let mut r#type;
12899 loop {
12900 r#type = None;
12901 if self.buf.len() == self.pos {
12902 return None;
12903 }
12904 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
12905 break;
12906 };
12907 r#type = Some(header.r#type);
12908 let res = match header.r#type {
12909 1u16 => LinkinfoVti6Attrs::Link({
12910 let res = parse_u32(next);
12911 let Some(val) = res else { break };
12912 val
12913 }),
12914 2u16 => LinkinfoVti6Attrs::Ikey({
12915 let res = parse_be_u32(next);
12916 let Some(val) = res else { break };
12917 val
12918 }),
12919 3u16 => LinkinfoVti6Attrs::Okey({
12920 let res = parse_be_u32(next);
12921 let Some(val) = res else { break };
12922 val
12923 }),
12924 4u16 => LinkinfoVti6Attrs::Local({
12925 let res = Some(next);
12926 let Some(val) = res else { break };
12927 val
12928 }),
12929 5u16 => LinkinfoVti6Attrs::Remote({
12930 let res = Some(next);
12931 let Some(val) = res else { break };
12932 val
12933 }),
12934 6u16 => LinkinfoVti6Attrs::Fwmark({
12935 let res = parse_u32(next);
12936 let Some(val) = res else { break };
12937 val
12938 }),
12939 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
12940 n => continue,
12941 };
12942 return Some(Ok(res));
12943 }
12944 Some(Err(ErrorContext::new(
12945 "LinkinfoVti6Attrs",
12946 r#type.and_then(|t| LinkinfoVti6Attrs::attr_from_type(t)),
12947 self.orig_loc,
12948 self.buf.as_ptr().wrapping_add(pos) as usize,
12949 )))
12950 }
12951}
12952impl<'a> std::fmt::Debug for IterableLinkinfoVti6Attrs<'_> {
12953 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12954 let mut fmt = f.debug_struct("LinkinfoVti6Attrs");
12955 for attr in self.clone() {
12956 let attr = match attr {
12957 Ok(a) => a,
12958 Err(err) => {
12959 fmt.finish()?;
12960 f.write_str("Err(")?;
12961 err.fmt(f)?;
12962 return f.write_str(")");
12963 }
12964 };
12965 match attr {
12966 LinkinfoVti6Attrs::Link(val) => fmt.field("Link", &val),
12967 LinkinfoVti6Attrs::Ikey(val) => fmt.field("Ikey", &val),
12968 LinkinfoVti6Attrs::Okey(val) => fmt.field("Okey", &val),
12969 LinkinfoVti6Attrs::Local(val) => fmt.field("Local", &val),
12970 LinkinfoVti6Attrs::Remote(val) => fmt.field("Remote", &val),
12971 LinkinfoVti6Attrs::Fwmark(val) => fmt.field("Fwmark", &val),
12972 };
12973 }
12974 fmt.finish()
12975 }
12976}
12977impl IterableLinkinfoVti6Attrs<'_> {
12978 pub fn lookup_attr(
12979 &self,
12980 offset: usize,
12981 missing_type: Option<u16>,
12982 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
12983 let mut stack = Vec::new();
12984 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
12985 if missing_type.is_some() && cur == offset {
12986 stack.push(("LinkinfoVti6Attrs", offset));
12987 return (
12988 stack,
12989 missing_type.and_then(|t| LinkinfoVti6Attrs::attr_from_type(t)),
12990 );
12991 }
12992 if cur > offset || cur + self.buf.len() < offset {
12993 return (stack, None);
12994 }
12995 let mut attrs = self.clone();
12996 let mut last_off = cur + attrs.pos;
12997 while let Some(attr) = attrs.next() {
12998 let Ok(attr) = attr else { break };
12999 match attr {
13000 LinkinfoVti6Attrs::Link(val) => {
13001 if last_off == offset {
13002 stack.push(("Link", last_off));
13003 break;
13004 }
13005 }
13006 LinkinfoVti6Attrs::Ikey(val) => {
13007 if last_off == offset {
13008 stack.push(("Ikey", last_off));
13009 break;
13010 }
13011 }
13012 LinkinfoVti6Attrs::Okey(val) => {
13013 if last_off == offset {
13014 stack.push(("Okey", last_off));
13015 break;
13016 }
13017 }
13018 LinkinfoVti6Attrs::Local(val) => {
13019 if last_off == offset {
13020 stack.push(("Local", last_off));
13021 break;
13022 }
13023 }
13024 LinkinfoVti6Attrs::Remote(val) => {
13025 if last_off == offset {
13026 stack.push(("Remote", last_off));
13027 break;
13028 }
13029 }
13030 LinkinfoVti6Attrs::Fwmark(val) => {
13031 if last_off == offset {
13032 stack.push(("Fwmark", last_off));
13033 break;
13034 }
13035 }
13036 _ => {}
13037 };
13038 last_off = cur + attrs.pos;
13039 }
13040 if !stack.is_empty() {
13041 stack.push(("LinkinfoVti6Attrs", cur));
13042 }
13043 (stack, None)
13044 }
13045}
13046#[derive(Clone)]
13047pub enum LinkinfoGeneveAttrs<'a> {
13048 Id(u32),
13049 Remote(std::net::Ipv4Addr),
13050 Ttl(u8),
13051 Tos(u8),
13052 Port(u16),
13053 CollectMetadata(()),
13054 Remote6(&'a [u8]),
13055 UdpCsum(u8),
13056 UdpZeroCsum6Tx(u8),
13057 UdpZeroCsum6Rx(u8),
13058 Label(u32),
13059 TtlInherit(u8),
13060 Df(u8),
13061 InnerProtoInherit(()),
13062 PortRange(IflaGenevePortRange),
13063 GroHint(()),
13064}
13065impl<'a> IterableLinkinfoGeneveAttrs<'a> {
13066 pub fn get_id(&self) -> Result<u32, ErrorContext> {
13067 let mut iter = self.clone();
13068 iter.pos = 0;
13069 for attr in iter {
13070 if let LinkinfoGeneveAttrs::Id(val) = attr? {
13071 return Ok(val);
13072 }
13073 }
13074 Err(ErrorContext::new_missing(
13075 "LinkinfoGeneveAttrs",
13076 "Id",
13077 self.orig_loc,
13078 self.buf.as_ptr() as usize,
13079 ))
13080 }
13081 pub fn get_remote(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
13082 let mut iter = self.clone();
13083 iter.pos = 0;
13084 for attr in iter {
13085 if let LinkinfoGeneveAttrs::Remote(val) = attr? {
13086 return Ok(val);
13087 }
13088 }
13089 Err(ErrorContext::new_missing(
13090 "LinkinfoGeneveAttrs",
13091 "Remote",
13092 self.orig_loc,
13093 self.buf.as_ptr() as usize,
13094 ))
13095 }
13096 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
13097 let mut iter = self.clone();
13098 iter.pos = 0;
13099 for attr in iter {
13100 if let LinkinfoGeneveAttrs::Ttl(val) = attr? {
13101 return Ok(val);
13102 }
13103 }
13104 Err(ErrorContext::new_missing(
13105 "LinkinfoGeneveAttrs",
13106 "Ttl",
13107 self.orig_loc,
13108 self.buf.as_ptr() as usize,
13109 ))
13110 }
13111 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
13112 let mut iter = self.clone();
13113 iter.pos = 0;
13114 for attr in iter {
13115 if let LinkinfoGeneveAttrs::Tos(val) = attr? {
13116 return Ok(val);
13117 }
13118 }
13119 Err(ErrorContext::new_missing(
13120 "LinkinfoGeneveAttrs",
13121 "Tos",
13122 self.orig_loc,
13123 self.buf.as_ptr() as usize,
13124 ))
13125 }
13126 pub fn get_port(&self) -> Result<u16, ErrorContext> {
13127 let mut iter = self.clone();
13128 iter.pos = 0;
13129 for attr in iter {
13130 if let LinkinfoGeneveAttrs::Port(val) = attr? {
13131 return Ok(val);
13132 }
13133 }
13134 Err(ErrorContext::new_missing(
13135 "LinkinfoGeneveAttrs",
13136 "Port",
13137 self.orig_loc,
13138 self.buf.as_ptr() as usize,
13139 ))
13140 }
13141 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
13142 let mut iter = self.clone();
13143 iter.pos = 0;
13144 for attr in iter {
13145 if let LinkinfoGeneveAttrs::CollectMetadata(val) = attr? {
13146 return Ok(val);
13147 }
13148 }
13149 Err(ErrorContext::new_missing(
13150 "LinkinfoGeneveAttrs",
13151 "CollectMetadata",
13152 self.orig_loc,
13153 self.buf.as_ptr() as usize,
13154 ))
13155 }
13156 pub fn get_remote6(&self) -> Result<&'a [u8], ErrorContext> {
13157 let mut iter = self.clone();
13158 iter.pos = 0;
13159 for attr in iter {
13160 if let LinkinfoGeneveAttrs::Remote6(val) = attr? {
13161 return Ok(val);
13162 }
13163 }
13164 Err(ErrorContext::new_missing(
13165 "LinkinfoGeneveAttrs",
13166 "Remote6",
13167 self.orig_loc,
13168 self.buf.as_ptr() as usize,
13169 ))
13170 }
13171 pub fn get_udp_csum(&self) -> Result<u8, ErrorContext> {
13172 let mut iter = self.clone();
13173 iter.pos = 0;
13174 for attr in iter {
13175 if let LinkinfoGeneveAttrs::UdpCsum(val) = attr? {
13176 return Ok(val);
13177 }
13178 }
13179 Err(ErrorContext::new_missing(
13180 "LinkinfoGeneveAttrs",
13181 "UdpCsum",
13182 self.orig_loc,
13183 self.buf.as_ptr() as usize,
13184 ))
13185 }
13186 pub fn get_udp_zero_csum6_tx(&self) -> Result<u8, ErrorContext> {
13187 let mut iter = self.clone();
13188 iter.pos = 0;
13189 for attr in iter {
13190 if let LinkinfoGeneveAttrs::UdpZeroCsum6Tx(val) = attr? {
13191 return Ok(val);
13192 }
13193 }
13194 Err(ErrorContext::new_missing(
13195 "LinkinfoGeneveAttrs",
13196 "UdpZeroCsum6Tx",
13197 self.orig_loc,
13198 self.buf.as_ptr() as usize,
13199 ))
13200 }
13201 pub fn get_udp_zero_csum6_rx(&self) -> Result<u8, ErrorContext> {
13202 let mut iter = self.clone();
13203 iter.pos = 0;
13204 for attr in iter {
13205 if let LinkinfoGeneveAttrs::UdpZeroCsum6Rx(val) = attr? {
13206 return Ok(val);
13207 }
13208 }
13209 Err(ErrorContext::new_missing(
13210 "LinkinfoGeneveAttrs",
13211 "UdpZeroCsum6Rx",
13212 self.orig_loc,
13213 self.buf.as_ptr() as usize,
13214 ))
13215 }
13216 pub fn get_label(&self) -> Result<u32, ErrorContext> {
13217 let mut iter = self.clone();
13218 iter.pos = 0;
13219 for attr in iter {
13220 if let LinkinfoGeneveAttrs::Label(val) = attr? {
13221 return Ok(val);
13222 }
13223 }
13224 Err(ErrorContext::new_missing(
13225 "LinkinfoGeneveAttrs",
13226 "Label",
13227 self.orig_loc,
13228 self.buf.as_ptr() as usize,
13229 ))
13230 }
13231 pub fn get_ttl_inherit(&self) -> Result<u8, ErrorContext> {
13232 let mut iter = self.clone();
13233 iter.pos = 0;
13234 for attr in iter {
13235 if let LinkinfoGeneveAttrs::TtlInherit(val) = attr? {
13236 return Ok(val);
13237 }
13238 }
13239 Err(ErrorContext::new_missing(
13240 "LinkinfoGeneveAttrs",
13241 "TtlInherit",
13242 self.orig_loc,
13243 self.buf.as_ptr() as usize,
13244 ))
13245 }
13246 pub fn get_df(&self) -> Result<u8, ErrorContext> {
13247 let mut iter = self.clone();
13248 iter.pos = 0;
13249 for attr in iter {
13250 if let LinkinfoGeneveAttrs::Df(val) = attr? {
13251 return Ok(val);
13252 }
13253 }
13254 Err(ErrorContext::new_missing(
13255 "LinkinfoGeneveAttrs",
13256 "Df",
13257 self.orig_loc,
13258 self.buf.as_ptr() as usize,
13259 ))
13260 }
13261 pub fn get_inner_proto_inherit(&self) -> Result<(), ErrorContext> {
13262 let mut iter = self.clone();
13263 iter.pos = 0;
13264 for attr in iter {
13265 if let LinkinfoGeneveAttrs::InnerProtoInherit(val) = attr? {
13266 return Ok(val);
13267 }
13268 }
13269 Err(ErrorContext::new_missing(
13270 "LinkinfoGeneveAttrs",
13271 "InnerProtoInherit",
13272 self.orig_loc,
13273 self.buf.as_ptr() as usize,
13274 ))
13275 }
13276 pub fn get_port_range(&self) -> Result<IflaGenevePortRange, ErrorContext> {
13277 let mut iter = self.clone();
13278 iter.pos = 0;
13279 for attr in iter {
13280 if let LinkinfoGeneveAttrs::PortRange(val) = attr? {
13281 return Ok(val);
13282 }
13283 }
13284 Err(ErrorContext::new_missing(
13285 "LinkinfoGeneveAttrs",
13286 "PortRange",
13287 self.orig_loc,
13288 self.buf.as_ptr() as usize,
13289 ))
13290 }
13291 pub fn get_gro_hint(&self) -> Result<(), ErrorContext> {
13292 let mut iter = self.clone();
13293 iter.pos = 0;
13294 for attr in iter {
13295 if let LinkinfoGeneveAttrs::GroHint(val) = attr? {
13296 return Ok(val);
13297 }
13298 }
13299 Err(ErrorContext::new_missing(
13300 "LinkinfoGeneveAttrs",
13301 "GroHint",
13302 self.orig_loc,
13303 self.buf.as_ptr() as usize,
13304 ))
13305 }
13306}
13307impl LinkinfoGeneveAttrs<'_> {
13308 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoGeneveAttrs<'a> {
13309 IterableLinkinfoGeneveAttrs::with_loc(buf, buf.as_ptr() as usize)
13310 }
13311 fn attr_from_type(r#type: u16) -> Option<&'static str> {
13312 let res = match r#type {
13313 1u16 => "Id",
13314 2u16 => "Remote",
13315 3u16 => "Ttl",
13316 4u16 => "Tos",
13317 5u16 => "Port",
13318 6u16 => "CollectMetadata",
13319 7u16 => "Remote6",
13320 8u16 => "UdpCsum",
13321 9u16 => "UdpZeroCsum6Tx",
13322 10u16 => "UdpZeroCsum6Rx",
13323 11u16 => "Label",
13324 12u16 => "TtlInherit",
13325 13u16 => "Df",
13326 14u16 => "InnerProtoInherit",
13327 15u16 => "PortRange",
13328 16u16 => "GroHint",
13329 _ => return None,
13330 };
13331 Some(res)
13332 }
13333}
13334#[derive(Clone, Copy, Default)]
13335pub struct IterableLinkinfoGeneveAttrs<'a> {
13336 buf: &'a [u8],
13337 pos: usize,
13338 orig_loc: usize,
13339}
13340impl<'a> IterableLinkinfoGeneveAttrs<'a> {
13341 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
13342 Self {
13343 buf,
13344 pos: 0,
13345 orig_loc,
13346 }
13347 }
13348 pub fn get_buf(&self) -> &'a [u8] {
13349 self.buf
13350 }
13351}
13352impl<'a> Iterator for IterableLinkinfoGeneveAttrs<'a> {
13353 type Item = Result<LinkinfoGeneveAttrs<'a>, ErrorContext>;
13354 fn next(&mut self) -> Option<Self::Item> {
13355 let pos = self.pos;
13356 let mut r#type;
13357 loop {
13358 r#type = None;
13359 if self.buf.len() == self.pos {
13360 return None;
13361 }
13362 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
13363 break;
13364 };
13365 r#type = Some(header.r#type);
13366 let res = match header.r#type {
13367 1u16 => LinkinfoGeneveAttrs::Id({
13368 let res = parse_u32(next);
13369 let Some(val) = res else { break };
13370 val
13371 }),
13372 2u16 => LinkinfoGeneveAttrs::Remote({
13373 let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
13374 let Some(val) = res else { break };
13375 val
13376 }),
13377 3u16 => LinkinfoGeneveAttrs::Ttl({
13378 let res = parse_u8(next);
13379 let Some(val) = res else { break };
13380 val
13381 }),
13382 4u16 => LinkinfoGeneveAttrs::Tos({
13383 let res = parse_u8(next);
13384 let Some(val) = res else { break };
13385 val
13386 }),
13387 5u16 => LinkinfoGeneveAttrs::Port({
13388 let res = parse_be_u16(next);
13389 let Some(val) = res else { break };
13390 val
13391 }),
13392 6u16 => LinkinfoGeneveAttrs::CollectMetadata(()),
13393 7u16 => LinkinfoGeneveAttrs::Remote6({
13394 let res = Some(next);
13395 let Some(val) = res else { break };
13396 val
13397 }),
13398 8u16 => LinkinfoGeneveAttrs::UdpCsum({
13399 let res = parse_u8(next);
13400 let Some(val) = res else { break };
13401 val
13402 }),
13403 9u16 => LinkinfoGeneveAttrs::UdpZeroCsum6Tx({
13404 let res = parse_u8(next);
13405 let Some(val) = res else { break };
13406 val
13407 }),
13408 10u16 => LinkinfoGeneveAttrs::UdpZeroCsum6Rx({
13409 let res = parse_u8(next);
13410 let Some(val) = res else { break };
13411 val
13412 }),
13413 11u16 => LinkinfoGeneveAttrs::Label({
13414 let res = parse_be_u32(next);
13415 let Some(val) = res else { break };
13416 val
13417 }),
13418 12u16 => LinkinfoGeneveAttrs::TtlInherit({
13419 let res = parse_u8(next);
13420 let Some(val) = res else { break };
13421 val
13422 }),
13423 13u16 => LinkinfoGeneveAttrs::Df({
13424 let res = parse_u8(next);
13425 let Some(val) = res else { break };
13426 val
13427 }),
13428 14u16 => LinkinfoGeneveAttrs::InnerProtoInherit(()),
13429 15u16 => LinkinfoGeneveAttrs::PortRange({
13430 let res = Some(IflaGenevePortRange::new_from_zeroed(next));
13431 let Some(val) = res else { break };
13432 val
13433 }),
13434 16u16 => LinkinfoGeneveAttrs::GroHint(()),
13435 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
13436 n => continue,
13437 };
13438 return Some(Ok(res));
13439 }
13440 Some(Err(ErrorContext::new(
13441 "LinkinfoGeneveAttrs",
13442 r#type.and_then(|t| LinkinfoGeneveAttrs::attr_from_type(t)),
13443 self.orig_loc,
13444 self.buf.as_ptr().wrapping_add(pos) as usize,
13445 )))
13446 }
13447}
13448impl<'a> std::fmt::Debug for IterableLinkinfoGeneveAttrs<'_> {
13449 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13450 let mut fmt = f.debug_struct("LinkinfoGeneveAttrs");
13451 for attr in self.clone() {
13452 let attr = match attr {
13453 Ok(a) => a,
13454 Err(err) => {
13455 fmt.finish()?;
13456 f.write_str("Err(")?;
13457 err.fmt(f)?;
13458 return f.write_str(")");
13459 }
13460 };
13461 match attr {
13462 LinkinfoGeneveAttrs::Id(val) => fmt.field("Id", &val),
13463 LinkinfoGeneveAttrs::Remote(val) => fmt.field("Remote", &val),
13464 LinkinfoGeneveAttrs::Ttl(val) => fmt.field("Ttl", &val),
13465 LinkinfoGeneveAttrs::Tos(val) => fmt.field("Tos", &val),
13466 LinkinfoGeneveAttrs::Port(val) => fmt.field("Port", &val),
13467 LinkinfoGeneveAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
13468 LinkinfoGeneveAttrs::Remote6(val) => fmt.field("Remote6", &val),
13469 LinkinfoGeneveAttrs::UdpCsum(val) => fmt.field("UdpCsum", &val),
13470 LinkinfoGeneveAttrs::UdpZeroCsum6Tx(val) => fmt.field("UdpZeroCsum6Tx", &val),
13471 LinkinfoGeneveAttrs::UdpZeroCsum6Rx(val) => fmt.field("UdpZeroCsum6Rx", &val),
13472 LinkinfoGeneveAttrs::Label(val) => fmt.field("Label", &val),
13473 LinkinfoGeneveAttrs::TtlInherit(val) => fmt.field("TtlInherit", &val),
13474 LinkinfoGeneveAttrs::Df(val) => fmt.field("Df", &val),
13475 LinkinfoGeneveAttrs::InnerProtoInherit(val) => fmt.field("InnerProtoInherit", &val),
13476 LinkinfoGeneveAttrs::PortRange(val) => fmt.field("PortRange", &val),
13477 LinkinfoGeneveAttrs::GroHint(val) => fmt.field("GroHint", &val),
13478 };
13479 }
13480 fmt.finish()
13481 }
13482}
13483impl IterableLinkinfoGeneveAttrs<'_> {
13484 pub fn lookup_attr(
13485 &self,
13486 offset: usize,
13487 missing_type: Option<u16>,
13488 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
13489 let mut stack = Vec::new();
13490 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
13491 if missing_type.is_some() && cur == offset {
13492 stack.push(("LinkinfoGeneveAttrs", offset));
13493 return (
13494 stack,
13495 missing_type.and_then(|t| LinkinfoGeneveAttrs::attr_from_type(t)),
13496 );
13497 }
13498 if cur > offset || cur + self.buf.len() < offset {
13499 return (stack, None);
13500 }
13501 let mut attrs = self.clone();
13502 let mut last_off = cur + attrs.pos;
13503 while let Some(attr) = attrs.next() {
13504 let Ok(attr) = attr else { break };
13505 match attr {
13506 LinkinfoGeneveAttrs::Id(val) => {
13507 if last_off == offset {
13508 stack.push(("Id", last_off));
13509 break;
13510 }
13511 }
13512 LinkinfoGeneveAttrs::Remote(val) => {
13513 if last_off == offset {
13514 stack.push(("Remote", last_off));
13515 break;
13516 }
13517 }
13518 LinkinfoGeneveAttrs::Ttl(val) => {
13519 if last_off == offset {
13520 stack.push(("Ttl", last_off));
13521 break;
13522 }
13523 }
13524 LinkinfoGeneveAttrs::Tos(val) => {
13525 if last_off == offset {
13526 stack.push(("Tos", last_off));
13527 break;
13528 }
13529 }
13530 LinkinfoGeneveAttrs::Port(val) => {
13531 if last_off == offset {
13532 stack.push(("Port", last_off));
13533 break;
13534 }
13535 }
13536 LinkinfoGeneveAttrs::CollectMetadata(val) => {
13537 if last_off == offset {
13538 stack.push(("CollectMetadata", last_off));
13539 break;
13540 }
13541 }
13542 LinkinfoGeneveAttrs::Remote6(val) => {
13543 if last_off == offset {
13544 stack.push(("Remote6", last_off));
13545 break;
13546 }
13547 }
13548 LinkinfoGeneveAttrs::UdpCsum(val) => {
13549 if last_off == offset {
13550 stack.push(("UdpCsum", last_off));
13551 break;
13552 }
13553 }
13554 LinkinfoGeneveAttrs::UdpZeroCsum6Tx(val) => {
13555 if last_off == offset {
13556 stack.push(("UdpZeroCsum6Tx", last_off));
13557 break;
13558 }
13559 }
13560 LinkinfoGeneveAttrs::UdpZeroCsum6Rx(val) => {
13561 if last_off == offset {
13562 stack.push(("UdpZeroCsum6Rx", last_off));
13563 break;
13564 }
13565 }
13566 LinkinfoGeneveAttrs::Label(val) => {
13567 if last_off == offset {
13568 stack.push(("Label", last_off));
13569 break;
13570 }
13571 }
13572 LinkinfoGeneveAttrs::TtlInherit(val) => {
13573 if last_off == offset {
13574 stack.push(("TtlInherit", last_off));
13575 break;
13576 }
13577 }
13578 LinkinfoGeneveAttrs::Df(val) => {
13579 if last_off == offset {
13580 stack.push(("Df", last_off));
13581 break;
13582 }
13583 }
13584 LinkinfoGeneveAttrs::InnerProtoInherit(val) => {
13585 if last_off == offset {
13586 stack.push(("InnerProtoInherit", last_off));
13587 break;
13588 }
13589 }
13590 LinkinfoGeneveAttrs::PortRange(val) => {
13591 if last_off == offset {
13592 stack.push(("PortRange", last_off));
13593 break;
13594 }
13595 }
13596 LinkinfoGeneveAttrs::GroHint(val) => {
13597 if last_off == offset {
13598 stack.push(("GroHint", last_off));
13599 break;
13600 }
13601 }
13602 _ => {}
13603 };
13604 last_off = cur + attrs.pos;
13605 }
13606 if !stack.is_empty() {
13607 stack.push(("LinkinfoGeneveAttrs", cur));
13608 }
13609 (stack, None)
13610 }
13611}
13612#[derive(Clone)]
13613pub enum LinkinfoHsrAttrs<'a> {
13614 Slave1(u32),
13615 Slave2(u32),
13616 MulticastSpec(u8),
13617 SupervisionAddr(&'a [u8]),
13618 SeqNr(u16),
13619 Version(u8),
13620 Protocol(u8),
13621 Interlink(u32),
13622}
13623impl<'a> IterableLinkinfoHsrAttrs<'a> {
13624 pub fn get_slave1(&self) -> Result<u32, ErrorContext> {
13625 let mut iter = self.clone();
13626 iter.pos = 0;
13627 for attr in iter {
13628 if let LinkinfoHsrAttrs::Slave1(val) = attr? {
13629 return Ok(val);
13630 }
13631 }
13632 Err(ErrorContext::new_missing(
13633 "LinkinfoHsrAttrs",
13634 "Slave1",
13635 self.orig_loc,
13636 self.buf.as_ptr() as usize,
13637 ))
13638 }
13639 pub fn get_slave2(&self) -> Result<u32, ErrorContext> {
13640 let mut iter = self.clone();
13641 iter.pos = 0;
13642 for attr in iter {
13643 if let LinkinfoHsrAttrs::Slave2(val) = attr? {
13644 return Ok(val);
13645 }
13646 }
13647 Err(ErrorContext::new_missing(
13648 "LinkinfoHsrAttrs",
13649 "Slave2",
13650 self.orig_loc,
13651 self.buf.as_ptr() as usize,
13652 ))
13653 }
13654 pub fn get_multicast_spec(&self) -> Result<u8, ErrorContext> {
13655 let mut iter = self.clone();
13656 iter.pos = 0;
13657 for attr in iter {
13658 if let LinkinfoHsrAttrs::MulticastSpec(val) = attr? {
13659 return Ok(val);
13660 }
13661 }
13662 Err(ErrorContext::new_missing(
13663 "LinkinfoHsrAttrs",
13664 "MulticastSpec",
13665 self.orig_loc,
13666 self.buf.as_ptr() as usize,
13667 ))
13668 }
13669 pub fn get_supervision_addr(&self) -> Result<&'a [u8], ErrorContext> {
13670 let mut iter = self.clone();
13671 iter.pos = 0;
13672 for attr in iter {
13673 if let LinkinfoHsrAttrs::SupervisionAddr(val) = attr? {
13674 return Ok(val);
13675 }
13676 }
13677 Err(ErrorContext::new_missing(
13678 "LinkinfoHsrAttrs",
13679 "SupervisionAddr",
13680 self.orig_loc,
13681 self.buf.as_ptr() as usize,
13682 ))
13683 }
13684 pub fn get_seq_nr(&self) -> Result<u16, ErrorContext> {
13685 let mut iter = self.clone();
13686 iter.pos = 0;
13687 for attr in iter {
13688 if let LinkinfoHsrAttrs::SeqNr(val) = attr? {
13689 return Ok(val);
13690 }
13691 }
13692 Err(ErrorContext::new_missing(
13693 "LinkinfoHsrAttrs",
13694 "SeqNr",
13695 self.orig_loc,
13696 self.buf.as_ptr() as usize,
13697 ))
13698 }
13699 pub fn get_version(&self) -> Result<u8, ErrorContext> {
13700 let mut iter = self.clone();
13701 iter.pos = 0;
13702 for attr in iter {
13703 if let LinkinfoHsrAttrs::Version(val) = attr? {
13704 return Ok(val);
13705 }
13706 }
13707 Err(ErrorContext::new_missing(
13708 "LinkinfoHsrAttrs",
13709 "Version",
13710 self.orig_loc,
13711 self.buf.as_ptr() as usize,
13712 ))
13713 }
13714 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
13715 let mut iter = self.clone();
13716 iter.pos = 0;
13717 for attr in iter {
13718 if let LinkinfoHsrAttrs::Protocol(val) = attr? {
13719 return Ok(val);
13720 }
13721 }
13722 Err(ErrorContext::new_missing(
13723 "LinkinfoHsrAttrs",
13724 "Protocol",
13725 self.orig_loc,
13726 self.buf.as_ptr() as usize,
13727 ))
13728 }
13729 pub fn get_interlink(&self) -> Result<u32, ErrorContext> {
13730 let mut iter = self.clone();
13731 iter.pos = 0;
13732 for attr in iter {
13733 if let LinkinfoHsrAttrs::Interlink(val) = attr? {
13734 return Ok(val);
13735 }
13736 }
13737 Err(ErrorContext::new_missing(
13738 "LinkinfoHsrAttrs",
13739 "Interlink",
13740 self.orig_loc,
13741 self.buf.as_ptr() as usize,
13742 ))
13743 }
13744}
13745impl LinkinfoHsrAttrs<'_> {
13746 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoHsrAttrs<'a> {
13747 IterableLinkinfoHsrAttrs::with_loc(buf, buf.as_ptr() as usize)
13748 }
13749 fn attr_from_type(r#type: u16) -> Option<&'static str> {
13750 let res = match r#type {
13751 1u16 => "Slave1",
13752 2u16 => "Slave2",
13753 3u16 => "MulticastSpec",
13754 4u16 => "SupervisionAddr",
13755 5u16 => "SeqNr",
13756 6u16 => "Version",
13757 7u16 => "Protocol",
13758 8u16 => "Interlink",
13759 _ => return None,
13760 };
13761 Some(res)
13762 }
13763}
13764#[derive(Clone, Copy, Default)]
13765pub struct IterableLinkinfoHsrAttrs<'a> {
13766 buf: &'a [u8],
13767 pos: usize,
13768 orig_loc: usize,
13769}
13770impl<'a> IterableLinkinfoHsrAttrs<'a> {
13771 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
13772 Self {
13773 buf,
13774 pos: 0,
13775 orig_loc,
13776 }
13777 }
13778 pub fn get_buf(&self) -> &'a [u8] {
13779 self.buf
13780 }
13781}
13782impl<'a> Iterator for IterableLinkinfoHsrAttrs<'a> {
13783 type Item = Result<LinkinfoHsrAttrs<'a>, ErrorContext>;
13784 fn next(&mut self) -> Option<Self::Item> {
13785 let pos = self.pos;
13786 let mut r#type;
13787 loop {
13788 r#type = None;
13789 if self.buf.len() == self.pos {
13790 return None;
13791 }
13792 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
13793 break;
13794 };
13795 r#type = Some(header.r#type);
13796 let res = match header.r#type {
13797 1u16 => LinkinfoHsrAttrs::Slave1({
13798 let res = parse_u32(next);
13799 let Some(val) = res else { break };
13800 val
13801 }),
13802 2u16 => LinkinfoHsrAttrs::Slave2({
13803 let res = parse_u32(next);
13804 let Some(val) = res else { break };
13805 val
13806 }),
13807 3u16 => LinkinfoHsrAttrs::MulticastSpec({
13808 let res = parse_u8(next);
13809 let Some(val) = res else { break };
13810 val
13811 }),
13812 4u16 => LinkinfoHsrAttrs::SupervisionAddr({
13813 let res = Some(next);
13814 let Some(val) = res else { break };
13815 val
13816 }),
13817 5u16 => LinkinfoHsrAttrs::SeqNr({
13818 let res = parse_u16(next);
13819 let Some(val) = res else { break };
13820 val
13821 }),
13822 6u16 => LinkinfoHsrAttrs::Version({
13823 let res = parse_u8(next);
13824 let Some(val) = res else { break };
13825 val
13826 }),
13827 7u16 => LinkinfoHsrAttrs::Protocol({
13828 let res = parse_u8(next);
13829 let Some(val) = res else { break };
13830 val
13831 }),
13832 8u16 => LinkinfoHsrAttrs::Interlink({
13833 let res = parse_u32(next);
13834 let Some(val) = res else { break };
13835 val
13836 }),
13837 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
13838 n => continue,
13839 };
13840 return Some(Ok(res));
13841 }
13842 Some(Err(ErrorContext::new(
13843 "LinkinfoHsrAttrs",
13844 r#type.and_then(|t| LinkinfoHsrAttrs::attr_from_type(t)),
13845 self.orig_loc,
13846 self.buf.as_ptr().wrapping_add(pos) as usize,
13847 )))
13848 }
13849}
13850impl<'a> std::fmt::Debug for IterableLinkinfoHsrAttrs<'_> {
13851 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13852 let mut fmt = f.debug_struct("LinkinfoHsrAttrs");
13853 for attr in self.clone() {
13854 let attr = match attr {
13855 Ok(a) => a,
13856 Err(err) => {
13857 fmt.finish()?;
13858 f.write_str("Err(")?;
13859 err.fmt(f)?;
13860 return f.write_str(")");
13861 }
13862 };
13863 match attr {
13864 LinkinfoHsrAttrs::Slave1(val) => fmt.field("Slave1", &val),
13865 LinkinfoHsrAttrs::Slave2(val) => fmt.field("Slave2", &val),
13866 LinkinfoHsrAttrs::MulticastSpec(val) => fmt.field("MulticastSpec", &val),
13867 LinkinfoHsrAttrs::SupervisionAddr(val) => {
13868 fmt.field("SupervisionAddr", &FormatMac(val))
13869 }
13870 LinkinfoHsrAttrs::SeqNr(val) => fmt.field("SeqNr", &val),
13871 LinkinfoHsrAttrs::Version(val) => fmt.field("Version", &val),
13872 LinkinfoHsrAttrs::Protocol(val) => fmt.field("Protocol", &val),
13873 LinkinfoHsrAttrs::Interlink(val) => fmt.field("Interlink", &val),
13874 };
13875 }
13876 fmt.finish()
13877 }
13878}
13879impl IterableLinkinfoHsrAttrs<'_> {
13880 pub fn lookup_attr(
13881 &self,
13882 offset: usize,
13883 missing_type: Option<u16>,
13884 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
13885 let mut stack = Vec::new();
13886 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
13887 if missing_type.is_some() && cur == offset {
13888 stack.push(("LinkinfoHsrAttrs", offset));
13889 return (
13890 stack,
13891 missing_type.and_then(|t| LinkinfoHsrAttrs::attr_from_type(t)),
13892 );
13893 }
13894 if cur > offset || cur + self.buf.len() < offset {
13895 return (stack, None);
13896 }
13897 let mut attrs = self.clone();
13898 let mut last_off = cur + attrs.pos;
13899 while let Some(attr) = attrs.next() {
13900 let Ok(attr) = attr else { break };
13901 match attr {
13902 LinkinfoHsrAttrs::Slave1(val) => {
13903 if last_off == offset {
13904 stack.push(("Slave1", last_off));
13905 break;
13906 }
13907 }
13908 LinkinfoHsrAttrs::Slave2(val) => {
13909 if last_off == offset {
13910 stack.push(("Slave2", last_off));
13911 break;
13912 }
13913 }
13914 LinkinfoHsrAttrs::MulticastSpec(val) => {
13915 if last_off == offset {
13916 stack.push(("MulticastSpec", last_off));
13917 break;
13918 }
13919 }
13920 LinkinfoHsrAttrs::SupervisionAddr(val) => {
13921 if last_off == offset {
13922 stack.push(("SupervisionAddr", last_off));
13923 break;
13924 }
13925 }
13926 LinkinfoHsrAttrs::SeqNr(val) => {
13927 if last_off == offset {
13928 stack.push(("SeqNr", last_off));
13929 break;
13930 }
13931 }
13932 LinkinfoHsrAttrs::Version(val) => {
13933 if last_off == offset {
13934 stack.push(("Version", last_off));
13935 break;
13936 }
13937 }
13938 LinkinfoHsrAttrs::Protocol(val) => {
13939 if last_off == offset {
13940 stack.push(("Protocol", last_off));
13941 break;
13942 }
13943 }
13944 LinkinfoHsrAttrs::Interlink(val) => {
13945 if last_off == offset {
13946 stack.push(("Interlink", last_off));
13947 break;
13948 }
13949 }
13950 _ => {}
13951 };
13952 last_off = cur + attrs.pos;
13953 }
13954 if !stack.is_empty() {
13955 stack.push(("LinkinfoHsrAttrs", cur));
13956 }
13957 (stack, None)
13958 }
13959}
13960#[derive(Clone)]
13961pub enum LinkinfoIptunAttrs<'a> {
13962 Link(u32),
13963 Local(std::net::IpAddr),
13964 Remote(std::net::IpAddr),
13965 Ttl(u8),
13966 Tos(u8),
13967 EncapLimit(u8),
13968 Flowinfo(u32),
13969 Flags(u16),
13970 Proto(u8),
13971 Pmtudisc(u8),
13972 _6rdPrefix(&'a [u8]),
13973 _6rdRelayPrefix(std::net::Ipv4Addr),
13974 _6rdPrefixlen(u16),
13975 _6rdRelayPrefixlen(u16),
13976 EncapType(u16),
13977 EncapFlags(u16),
13978 EncapSport(u16),
13979 EncapDport(u16),
13980 CollectMetadata(()),
13981 Fwmark(u32),
13982}
13983impl<'a> IterableLinkinfoIptunAttrs<'a> {
13984 pub fn get_link(&self) -> Result<u32, ErrorContext> {
13985 let mut iter = self.clone();
13986 iter.pos = 0;
13987 for attr in iter {
13988 if let LinkinfoIptunAttrs::Link(val) = attr? {
13989 return Ok(val);
13990 }
13991 }
13992 Err(ErrorContext::new_missing(
13993 "LinkinfoIptunAttrs",
13994 "Link",
13995 self.orig_loc,
13996 self.buf.as_ptr() as usize,
13997 ))
13998 }
13999 pub fn get_local(&self) -> Result<std::net::IpAddr, ErrorContext> {
14000 let mut iter = self.clone();
14001 iter.pos = 0;
14002 for attr in iter {
14003 if let LinkinfoIptunAttrs::Local(val) = attr? {
14004 return Ok(val);
14005 }
14006 }
14007 Err(ErrorContext::new_missing(
14008 "LinkinfoIptunAttrs",
14009 "Local",
14010 self.orig_loc,
14011 self.buf.as_ptr() as usize,
14012 ))
14013 }
14014 pub fn get_remote(&self) -> Result<std::net::IpAddr, ErrorContext> {
14015 let mut iter = self.clone();
14016 iter.pos = 0;
14017 for attr in iter {
14018 if let LinkinfoIptunAttrs::Remote(val) = attr? {
14019 return Ok(val);
14020 }
14021 }
14022 Err(ErrorContext::new_missing(
14023 "LinkinfoIptunAttrs",
14024 "Remote",
14025 self.orig_loc,
14026 self.buf.as_ptr() as usize,
14027 ))
14028 }
14029 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
14030 let mut iter = self.clone();
14031 iter.pos = 0;
14032 for attr in iter {
14033 if let LinkinfoIptunAttrs::Ttl(val) = attr? {
14034 return Ok(val);
14035 }
14036 }
14037 Err(ErrorContext::new_missing(
14038 "LinkinfoIptunAttrs",
14039 "Ttl",
14040 self.orig_loc,
14041 self.buf.as_ptr() as usize,
14042 ))
14043 }
14044 pub fn get_tos(&self) -> Result<u8, ErrorContext> {
14045 let mut iter = self.clone();
14046 iter.pos = 0;
14047 for attr in iter {
14048 if let LinkinfoIptunAttrs::Tos(val) = attr? {
14049 return Ok(val);
14050 }
14051 }
14052 Err(ErrorContext::new_missing(
14053 "LinkinfoIptunAttrs",
14054 "Tos",
14055 self.orig_loc,
14056 self.buf.as_ptr() as usize,
14057 ))
14058 }
14059 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
14060 let mut iter = self.clone();
14061 iter.pos = 0;
14062 for attr in iter {
14063 if let LinkinfoIptunAttrs::EncapLimit(val) = attr? {
14064 return Ok(val);
14065 }
14066 }
14067 Err(ErrorContext::new_missing(
14068 "LinkinfoIptunAttrs",
14069 "EncapLimit",
14070 self.orig_loc,
14071 self.buf.as_ptr() as usize,
14072 ))
14073 }
14074 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
14075 let mut iter = self.clone();
14076 iter.pos = 0;
14077 for attr in iter {
14078 if let LinkinfoIptunAttrs::Flowinfo(val) = attr? {
14079 return Ok(val);
14080 }
14081 }
14082 Err(ErrorContext::new_missing(
14083 "LinkinfoIptunAttrs",
14084 "Flowinfo",
14085 self.orig_loc,
14086 self.buf.as_ptr() as usize,
14087 ))
14088 }
14089 pub fn get_flags(&self) -> Result<u16, ErrorContext> {
14090 let mut iter = self.clone();
14091 iter.pos = 0;
14092 for attr in iter {
14093 if let LinkinfoIptunAttrs::Flags(val) = attr? {
14094 return Ok(val);
14095 }
14096 }
14097 Err(ErrorContext::new_missing(
14098 "LinkinfoIptunAttrs",
14099 "Flags",
14100 self.orig_loc,
14101 self.buf.as_ptr() as usize,
14102 ))
14103 }
14104 pub fn get_proto(&self) -> Result<u8, ErrorContext> {
14105 let mut iter = self.clone();
14106 iter.pos = 0;
14107 for attr in iter {
14108 if let LinkinfoIptunAttrs::Proto(val) = attr? {
14109 return Ok(val);
14110 }
14111 }
14112 Err(ErrorContext::new_missing(
14113 "LinkinfoIptunAttrs",
14114 "Proto",
14115 self.orig_loc,
14116 self.buf.as_ptr() as usize,
14117 ))
14118 }
14119 pub fn get_pmtudisc(&self) -> Result<u8, ErrorContext> {
14120 let mut iter = self.clone();
14121 iter.pos = 0;
14122 for attr in iter {
14123 if let LinkinfoIptunAttrs::Pmtudisc(val) = attr? {
14124 return Ok(val);
14125 }
14126 }
14127 Err(ErrorContext::new_missing(
14128 "LinkinfoIptunAttrs",
14129 "Pmtudisc",
14130 self.orig_loc,
14131 self.buf.as_ptr() as usize,
14132 ))
14133 }
14134 pub fn get_6rd_prefix(&self) -> Result<&'a [u8], ErrorContext> {
14135 let mut iter = self.clone();
14136 iter.pos = 0;
14137 for attr in iter {
14138 if let LinkinfoIptunAttrs::_6rdPrefix(val) = attr? {
14139 return Ok(val);
14140 }
14141 }
14142 Err(ErrorContext::new_missing(
14143 "LinkinfoIptunAttrs",
14144 "6rdPrefix",
14145 self.orig_loc,
14146 self.buf.as_ptr() as usize,
14147 ))
14148 }
14149 pub fn get_6rd_relay_prefix(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
14150 let mut iter = self.clone();
14151 iter.pos = 0;
14152 for attr in iter {
14153 if let LinkinfoIptunAttrs::_6rdRelayPrefix(val) = attr? {
14154 return Ok(val);
14155 }
14156 }
14157 Err(ErrorContext::new_missing(
14158 "LinkinfoIptunAttrs",
14159 "6rdRelayPrefix",
14160 self.orig_loc,
14161 self.buf.as_ptr() as usize,
14162 ))
14163 }
14164 pub fn get_6rd_prefixlen(&self) -> Result<u16, ErrorContext> {
14165 let mut iter = self.clone();
14166 iter.pos = 0;
14167 for attr in iter {
14168 if let LinkinfoIptunAttrs::_6rdPrefixlen(val) = attr? {
14169 return Ok(val);
14170 }
14171 }
14172 Err(ErrorContext::new_missing(
14173 "LinkinfoIptunAttrs",
14174 "6rdPrefixlen",
14175 self.orig_loc,
14176 self.buf.as_ptr() as usize,
14177 ))
14178 }
14179 pub fn get_6rd_relay_prefixlen(&self) -> Result<u16, ErrorContext> {
14180 let mut iter = self.clone();
14181 iter.pos = 0;
14182 for attr in iter {
14183 if let LinkinfoIptunAttrs::_6rdRelayPrefixlen(val) = attr? {
14184 return Ok(val);
14185 }
14186 }
14187 Err(ErrorContext::new_missing(
14188 "LinkinfoIptunAttrs",
14189 "6rdRelayPrefixlen",
14190 self.orig_loc,
14191 self.buf.as_ptr() as usize,
14192 ))
14193 }
14194 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
14195 let mut iter = self.clone();
14196 iter.pos = 0;
14197 for attr in iter {
14198 if let LinkinfoIptunAttrs::EncapType(val) = attr? {
14199 return Ok(val);
14200 }
14201 }
14202 Err(ErrorContext::new_missing(
14203 "LinkinfoIptunAttrs",
14204 "EncapType",
14205 self.orig_loc,
14206 self.buf.as_ptr() as usize,
14207 ))
14208 }
14209 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
14210 let mut iter = self.clone();
14211 iter.pos = 0;
14212 for attr in iter {
14213 if let LinkinfoIptunAttrs::EncapFlags(val) = attr? {
14214 return Ok(val);
14215 }
14216 }
14217 Err(ErrorContext::new_missing(
14218 "LinkinfoIptunAttrs",
14219 "EncapFlags",
14220 self.orig_loc,
14221 self.buf.as_ptr() as usize,
14222 ))
14223 }
14224 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
14225 let mut iter = self.clone();
14226 iter.pos = 0;
14227 for attr in iter {
14228 if let LinkinfoIptunAttrs::EncapSport(val) = attr? {
14229 return Ok(val);
14230 }
14231 }
14232 Err(ErrorContext::new_missing(
14233 "LinkinfoIptunAttrs",
14234 "EncapSport",
14235 self.orig_loc,
14236 self.buf.as_ptr() as usize,
14237 ))
14238 }
14239 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
14240 let mut iter = self.clone();
14241 iter.pos = 0;
14242 for attr in iter {
14243 if let LinkinfoIptunAttrs::EncapDport(val) = attr? {
14244 return Ok(val);
14245 }
14246 }
14247 Err(ErrorContext::new_missing(
14248 "LinkinfoIptunAttrs",
14249 "EncapDport",
14250 self.orig_loc,
14251 self.buf.as_ptr() as usize,
14252 ))
14253 }
14254 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
14255 let mut iter = self.clone();
14256 iter.pos = 0;
14257 for attr in iter {
14258 if let LinkinfoIptunAttrs::CollectMetadata(val) = attr? {
14259 return Ok(val);
14260 }
14261 }
14262 Err(ErrorContext::new_missing(
14263 "LinkinfoIptunAttrs",
14264 "CollectMetadata",
14265 self.orig_loc,
14266 self.buf.as_ptr() as usize,
14267 ))
14268 }
14269 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
14270 let mut iter = self.clone();
14271 iter.pos = 0;
14272 for attr in iter {
14273 if let LinkinfoIptunAttrs::Fwmark(val) = attr? {
14274 return Ok(val);
14275 }
14276 }
14277 Err(ErrorContext::new_missing(
14278 "LinkinfoIptunAttrs",
14279 "Fwmark",
14280 self.orig_loc,
14281 self.buf.as_ptr() as usize,
14282 ))
14283 }
14284}
14285impl LinkinfoIptunAttrs<'_> {
14286 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoIptunAttrs<'a> {
14287 IterableLinkinfoIptunAttrs::with_loc(buf, buf.as_ptr() as usize)
14288 }
14289 fn attr_from_type(r#type: u16) -> Option<&'static str> {
14290 let res = match r#type {
14291 1u16 => "Link",
14292 2u16 => "Local",
14293 3u16 => "Remote",
14294 4u16 => "Ttl",
14295 5u16 => "Tos",
14296 6u16 => "EncapLimit",
14297 7u16 => "Flowinfo",
14298 8u16 => "Flags",
14299 9u16 => "Proto",
14300 10u16 => "Pmtudisc",
14301 11u16 => "6rdPrefix",
14302 12u16 => "6rdRelayPrefix",
14303 13u16 => "6rdPrefixlen",
14304 14u16 => "6rdRelayPrefixlen",
14305 15u16 => "EncapType",
14306 16u16 => "EncapFlags",
14307 17u16 => "EncapSport",
14308 18u16 => "EncapDport",
14309 19u16 => "CollectMetadata",
14310 20u16 => "Fwmark",
14311 _ => return None,
14312 };
14313 Some(res)
14314 }
14315}
14316#[derive(Clone, Copy, Default)]
14317pub struct IterableLinkinfoIptunAttrs<'a> {
14318 buf: &'a [u8],
14319 pos: usize,
14320 orig_loc: usize,
14321}
14322impl<'a> IterableLinkinfoIptunAttrs<'a> {
14323 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
14324 Self {
14325 buf,
14326 pos: 0,
14327 orig_loc,
14328 }
14329 }
14330 pub fn get_buf(&self) -> &'a [u8] {
14331 self.buf
14332 }
14333}
14334impl<'a> Iterator for IterableLinkinfoIptunAttrs<'a> {
14335 type Item = Result<LinkinfoIptunAttrs<'a>, ErrorContext>;
14336 fn next(&mut self) -> Option<Self::Item> {
14337 let pos = self.pos;
14338 let mut r#type;
14339 loop {
14340 r#type = None;
14341 if self.buf.len() == self.pos {
14342 return None;
14343 }
14344 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
14345 break;
14346 };
14347 r#type = Some(header.r#type);
14348 let res = match header.r#type {
14349 1u16 => LinkinfoIptunAttrs::Link({
14350 let res = parse_u32(next);
14351 let Some(val) = res else { break };
14352 val
14353 }),
14354 2u16 => LinkinfoIptunAttrs::Local({
14355 let res = parse_ip(next);
14356 let Some(val) = res else { break };
14357 val
14358 }),
14359 3u16 => LinkinfoIptunAttrs::Remote({
14360 let res = parse_ip(next);
14361 let Some(val) = res else { break };
14362 val
14363 }),
14364 4u16 => LinkinfoIptunAttrs::Ttl({
14365 let res = parse_u8(next);
14366 let Some(val) = res else { break };
14367 val
14368 }),
14369 5u16 => LinkinfoIptunAttrs::Tos({
14370 let res = parse_u8(next);
14371 let Some(val) = res else { break };
14372 val
14373 }),
14374 6u16 => LinkinfoIptunAttrs::EncapLimit({
14375 let res = parse_u8(next);
14376 let Some(val) = res else { break };
14377 val
14378 }),
14379 7u16 => LinkinfoIptunAttrs::Flowinfo({
14380 let res = parse_be_u32(next);
14381 let Some(val) = res else { break };
14382 val
14383 }),
14384 8u16 => LinkinfoIptunAttrs::Flags({
14385 let res = parse_be_u16(next);
14386 let Some(val) = res else { break };
14387 val
14388 }),
14389 9u16 => LinkinfoIptunAttrs::Proto({
14390 let res = parse_u8(next);
14391 let Some(val) = res else { break };
14392 val
14393 }),
14394 10u16 => LinkinfoIptunAttrs::Pmtudisc({
14395 let res = parse_u8(next);
14396 let Some(val) = res else { break };
14397 val
14398 }),
14399 11u16 => LinkinfoIptunAttrs::_6rdPrefix({
14400 let res = Some(next);
14401 let Some(val) = res else { break };
14402 val
14403 }),
14404 12u16 => LinkinfoIptunAttrs::_6rdRelayPrefix({
14405 let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
14406 let Some(val) = res else { break };
14407 val
14408 }),
14409 13u16 => LinkinfoIptunAttrs::_6rdPrefixlen({
14410 let res = parse_u16(next);
14411 let Some(val) = res else { break };
14412 val
14413 }),
14414 14u16 => LinkinfoIptunAttrs::_6rdRelayPrefixlen({
14415 let res = parse_u16(next);
14416 let Some(val) = res else { break };
14417 val
14418 }),
14419 15u16 => LinkinfoIptunAttrs::EncapType({
14420 let res = parse_u16(next);
14421 let Some(val) = res else { break };
14422 val
14423 }),
14424 16u16 => LinkinfoIptunAttrs::EncapFlags({
14425 let res = parse_u16(next);
14426 let Some(val) = res else { break };
14427 val
14428 }),
14429 17u16 => LinkinfoIptunAttrs::EncapSport({
14430 let res = parse_be_u16(next);
14431 let Some(val) = res else { break };
14432 val
14433 }),
14434 18u16 => LinkinfoIptunAttrs::EncapDport({
14435 let res = parse_be_u16(next);
14436 let Some(val) = res else { break };
14437 val
14438 }),
14439 19u16 => LinkinfoIptunAttrs::CollectMetadata(()),
14440 20u16 => LinkinfoIptunAttrs::Fwmark({
14441 let res = parse_u32(next);
14442 let Some(val) = res else { break };
14443 val
14444 }),
14445 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
14446 n => continue,
14447 };
14448 return Some(Ok(res));
14449 }
14450 Some(Err(ErrorContext::new(
14451 "LinkinfoIptunAttrs",
14452 r#type.and_then(|t| LinkinfoIptunAttrs::attr_from_type(t)),
14453 self.orig_loc,
14454 self.buf.as_ptr().wrapping_add(pos) as usize,
14455 )))
14456 }
14457}
14458impl<'a> std::fmt::Debug for IterableLinkinfoIptunAttrs<'_> {
14459 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14460 let mut fmt = f.debug_struct("LinkinfoIptunAttrs");
14461 for attr in self.clone() {
14462 let attr = match attr {
14463 Ok(a) => a,
14464 Err(err) => {
14465 fmt.finish()?;
14466 f.write_str("Err(")?;
14467 err.fmt(f)?;
14468 return f.write_str(")");
14469 }
14470 };
14471 match attr {
14472 LinkinfoIptunAttrs::Link(val) => fmt.field("Link", &val),
14473 LinkinfoIptunAttrs::Local(val) => fmt.field("Local", &val),
14474 LinkinfoIptunAttrs::Remote(val) => fmt.field("Remote", &val),
14475 LinkinfoIptunAttrs::Ttl(val) => fmt.field("Ttl", &val),
14476 LinkinfoIptunAttrs::Tos(val) => fmt.field("Tos", &val),
14477 LinkinfoIptunAttrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
14478 LinkinfoIptunAttrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
14479 LinkinfoIptunAttrs::Flags(val) => fmt.field("Flags", &val),
14480 LinkinfoIptunAttrs::Proto(val) => fmt.field("Proto", &val),
14481 LinkinfoIptunAttrs::Pmtudisc(val) => fmt.field("Pmtudisc", &val),
14482 LinkinfoIptunAttrs::_6rdPrefix(val) => fmt.field("_6rdPrefix", &val),
14483 LinkinfoIptunAttrs::_6rdRelayPrefix(val) => fmt.field("_6rdRelayPrefix", &val),
14484 LinkinfoIptunAttrs::_6rdPrefixlen(val) => fmt.field("_6rdPrefixlen", &val),
14485 LinkinfoIptunAttrs::_6rdRelayPrefixlen(val) => {
14486 fmt.field("_6rdRelayPrefixlen", &val)
14487 }
14488 LinkinfoIptunAttrs::EncapType(val) => fmt.field("EncapType", &val),
14489 LinkinfoIptunAttrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
14490 LinkinfoIptunAttrs::EncapSport(val) => fmt.field("EncapSport", &val),
14491 LinkinfoIptunAttrs::EncapDport(val) => fmt.field("EncapDport", &val),
14492 LinkinfoIptunAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
14493 LinkinfoIptunAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
14494 };
14495 }
14496 fmt.finish()
14497 }
14498}
14499impl IterableLinkinfoIptunAttrs<'_> {
14500 pub fn lookup_attr(
14501 &self,
14502 offset: usize,
14503 missing_type: Option<u16>,
14504 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
14505 let mut stack = Vec::new();
14506 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
14507 if missing_type.is_some() && cur == offset {
14508 stack.push(("LinkinfoIptunAttrs", offset));
14509 return (
14510 stack,
14511 missing_type.and_then(|t| LinkinfoIptunAttrs::attr_from_type(t)),
14512 );
14513 }
14514 if cur > offset || cur + self.buf.len() < offset {
14515 return (stack, None);
14516 }
14517 let mut attrs = self.clone();
14518 let mut last_off = cur + attrs.pos;
14519 while let Some(attr) = attrs.next() {
14520 let Ok(attr) = attr else { break };
14521 match attr {
14522 LinkinfoIptunAttrs::Link(val) => {
14523 if last_off == offset {
14524 stack.push(("Link", last_off));
14525 break;
14526 }
14527 }
14528 LinkinfoIptunAttrs::Local(val) => {
14529 if last_off == offset {
14530 stack.push(("Local", last_off));
14531 break;
14532 }
14533 }
14534 LinkinfoIptunAttrs::Remote(val) => {
14535 if last_off == offset {
14536 stack.push(("Remote", last_off));
14537 break;
14538 }
14539 }
14540 LinkinfoIptunAttrs::Ttl(val) => {
14541 if last_off == offset {
14542 stack.push(("Ttl", last_off));
14543 break;
14544 }
14545 }
14546 LinkinfoIptunAttrs::Tos(val) => {
14547 if last_off == offset {
14548 stack.push(("Tos", last_off));
14549 break;
14550 }
14551 }
14552 LinkinfoIptunAttrs::EncapLimit(val) => {
14553 if last_off == offset {
14554 stack.push(("EncapLimit", last_off));
14555 break;
14556 }
14557 }
14558 LinkinfoIptunAttrs::Flowinfo(val) => {
14559 if last_off == offset {
14560 stack.push(("Flowinfo", last_off));
14561 break;
14562 }
14563 }
14564 LinkinfoIptunAttrs::Flags(val) => {
14565 if last_off == offset {
14566 stack.push(("Flags", last_off));
14567 break;
14568 }
14569 }
14570 LinkinfoIptunAttrs::Proto(val) => {
14571 if last_off == offset {
14572 stack.push(("Proto", last_off));
14573 break;
14574 }
14575 }
14576 LinkinfoIptunAttrs::Pmtudisc(val) => {
14577 if last_off == offset {
14578 stack.push(("Pmtudisc", last_off));
14579 break;
14580 }
14581 }
14582 LinkinfoIptunAttrs::_6rdPrefix(val) => {
14583 if last_off == offset {
14584 stack.push(("6rdPrefix", last_off));
14585 break;
14586 }
14587 }
14588 LinkinfoIptunAttrs::_6rdRelayPrefix(val) => {
14589 if last_off == offset {
14590 stack.push(("6rdRelayPrefix", last_off));
14591 break;
14592 }
14593 }
14594 LinkinfoIptunAttrs::_6rdPrefixlen(val) => {
14595 if last_off == offset {
14596 stack.push(("6rdPrefixlen", last_off));
14597 break;
14598 }
14599 }
14600 LinkinfoIptunAttrs::_6rdRelayPrefixlen(val) => {
14601 if last_off == offset {
14602 stack.push(("6rdRelayPrefixlen", last_off));
14603 break;
14604 }
14605 }
14606 LinkinfoIptunAttrs::EncapType(val) => {
14607 if last_off == offset {
14608 stack.push(("EncapType", last_off));
14609 break;
14610 }
14611 }
14612 LinkinfoIptunAttrs::EncapFlags(val) => {
14613 if last_off == offset {
14614 stack.push(("EncapFlags", last_off));
14615 break;
14616 }
14617 }
14618 LinkinfoIptunAttrs::EncapSport(val) => {
14619 if last_off == offset {
14620 stack.push(("EncapSport", last_off));
14621 break;
14622 }
14623 }
14624 LinkinfoIptunAttrs::EncapDport(val) => {
14625 if last_off == offset {
14626 stack.push(("EncapDport", last_off));
14627 break;
14628 }
14629 }
14630 LinkinfoIptunAttrs::CollectMetadata(val) => {
14631 if last_off == offset {
14632 stack.push(("CollectMetadata", last_off));
14633 break;
14634 }
14635 }
14636 LinkinfoIptunAttrs::Fwmark(val) => {
14637 if last_off == offset {
14638 stack.push(("Fwmark", last_off));
14639 break;
14640 }
14641 }
14642 _ => {}
14643 };
14644 last_off = cur + attrs.pos;
14645 }
14646 if !stack.is_empty() {
14647 stack.push(("LinkinfoIptunAttrs", cur));
14648 }
14649 (stack, None)
14650 }
14651}
14652#[derive(Clone)]
14653pub enum LinkinfoIp6tnlAttrs<'a> {
14654 Link(u32),
14655 Local(&'a [u8]),
14656 Remote(&'a [u8]),
14657 Ttl(u8),
14658 EncapLimit(u8),
14659 Flowinfo(u32),
14660 Flags(u32),
14661 Proto(u8),
14662 EncapType(u16),
14663 EncapFlags(u16),
14664 EncapSport(u16),
14665 EncapDport(u16),
14666 CollectMetadata(()),
14667 Fwmark(u32),
14668}
14669impl<'a> IterableLinkinfoIp6tnlAttrs<'a> {
14670 pub fn get_link(&self) -> Result<u32, ErrorContext> {
14671 let mut iter = self.clone();
14672 iter.pos = 0;
14673 for attr in iter {
14674 if let LinkinfoIp6tnlAttrs::Link(val) = attr? {
14675 return Ok(val);
14676 }
14677 }
14678 Err(ErrorContext::new_missing(
14679 "LinkinfoIp6tnlAttrs",
14680 "Link",
14681 self.orig_loc,
14682 self.buf.as_ptr() as usize,
14683 ))
14684 }
14685 pub fn get_local(&self) -> Result<&'a [u8], ErrorContext> {
14686 let mut iter = self.clone();
14687 iter.pos = 0;
14688 for attr in iter {
14689 if let LinkinfoIp6tnlAttrs::Local(val) = attr? {
14690 return Ok(val);
14691 }
14692 }
14693 Err(ErrorContext::new_missing(
14694 "LinkinfoIp6tnlAttrs",
14695 "Local",
14696 self.orig_loc,
14697 self.buf.as_ptr() as usize,
14698 ))
14699 }
14700 pub fn get_remote(&self) -> Result<&'a [u8], ErrorContext> {
14701 let mut iter = self.clone();
14702 iter.pos = 0;
14703 for attr in iter {
14704 if let LinkinfoIp6tnlAttrs::Remote(val) = attr? {
14705 return Ok(val);
14706 }
14707 }
14708 Err(ErrorContext::new_missing(
14709 "LinkinfoIp6tnlAttrs",
14710 "Remote",
14711 self.orig_loc,
14712 self.buf.as_ptr() as usize,
14713 ))
14714 }
14715 pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
14716 let mut iter = self.clone();
14717 iter.pos = 0;
14718 for attr in iter {
14719 if let LinkinfoIp6tnlAttrs::Ttl(val) = attr? {
14720 return Ok(val);
14721 }
14722 }
14723 Err(ErrorContext::new_missing(
14724 "LinkinfoIp6tnlAttrs",
14725 "Ttl",
14726 self.orig_loc,
14727 self.buf.as_ptr() as usize,
14728 ))
14729 }
14730 pub fn get_encap_limit(&self) -> Result<u8, ErrorContext> {
14731 let mut iter = self.clone();
14732 iter.pos = 0;
14733 for attr in iter {
14734 if let LinkinfoIp6tnlAttrs::EncapLimit(val) = attr? {
14735 return Ok(val);
14736 }
14737 }
14738 Err(ErrorContext::new_missing(
14739 "LinkinfoIp6tnlAttrs",
14740 "EncapLimit",
14741 self.orig_loc,
14742 self.buf.as_ptr() as usize,
14743 ))
14744 }
14745 pub fn get_flowinfo(&self) -> Result<u32, ErrorContext> {
14746 let mut iter = self.clone();
14747 iter.pos = 0;
14748 for attr in iter {
14749 if let LinkinfoIp6tnlAttrs::Flowinfo(val) = attr? {
14750 return Ok(val);
14751 }
14752 }
14753 Err(ErrorContext::new_missing(
14754 "LinkinfoIp6tnlAttrs",
14755 "Flowinfo",
14756 self.orig_loc,
14757 self.buf.as_ptr() as usize,
14758 ))
14759 }
14760 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
14761 let mut iter = self.clone();
14762 iter.pos = 0;
14763 for attr in iter {
14764 if let LinkinfoIp6tnlAttrs::Flags(val) = attr? {
14765 return Ok(val);
14766 }
14767 }
14768 Err(ErrorContext::new_missing(
14769 "LinkinfoIp6tnlAttrs",
14770 "Flags",
14771 self.orig_loc,
14772 self.buf.as_ptr() as usize,
14773 ))
14774 }
14775 pub fn get_proto(&self) -> Result<u8, ErrorContext> {
14776 let mut iter = self.clone();
14777 iter.pos = 0;
14778 for attr in iter {
14779 if let LinkinfoIp6tnlAttrs::Proto(val) = attr? {
14780 return Ok(val);
14781 }
14782 }
14783 Err(ErrorContext::new_missing(
14784 "LinkinfoIp6tnlAttrs",
14785 "Proto",
14786 self.orig_loc,
14787 self.buf.as_ptr() as usize,
14788 ))
14789 }
14790 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
14791 let mut iter = self.clone();
14792 iter.pos = 0;
14793 for attr in iter {
14794 if let LinkinfoIp6tnlAttrs::EncapType(val) = attr? {
14795 return Ok(val);
14796 }
14797 }
14798 Err(ErrorContext::new_missing(
14799 "LinkinfoIp6tnlAttrs",
14800 "EncapType",
14801 self.orig_loc,
14802 self.buf.as_ptr() as usize,
14803 ))
14804 }
14805 pub fn get_encap_flags(&self) -> Result<u16, ErrorContext> {
14806 let mut iter = self.clone();
14807 iter.pos = 0;
14808 for attr in iter {
14809 if let LinkinfoIp6tnlAttrs::EncapFlags(val) = attr? {
14810 return Ok(val);
14811 }
14812 }
14813 Err(ErrorContext::new_missing(
14814 "LinkinfoIp6tnlAttrs",
14815 "EncapFlags",
14816 self.orig_loc,
14817 self.buf.as_ptr() as usize,
14818 ))
14819 }
14820 pub fn get_encap_sport(&self) -> Result<u16, ErrorContext> {
14821 let mut iter = self.clone();
14822 iter.pos = 0;
14823 for attr in iter {
14824 if let LinkinfoIp6tnlAttrs::EncapSport(val) = attr? {
14825 return Ok(val);
14826 }
14827 }
14828 Err(ErrorContext::new_missing(
14829 "LinkinfoIp6tnlAttrs",
14830 "EncapSport",
14831 self.orig_loc,
14832 self.buf.as_ptr() as usize,
14833 ))
14834 }
14835 pub fn get_encap_dport(&self) -> Result<u16, ErrorContext> {
14836 let mut iter = self.clone();
14837 iter.pos = 0;
14838 for attr in iter {
14839 if let LinkinfoIp6tnlAttrs::EncapDport(val) = attr? {
14840 return Ok(val);
14841 }
14842 }
14843 Err(ErrorContext::new_missing(
14844 "LinkinfoIp6tnlAttrs",
14845 "EncapDport",
14846 self.orig_loc,
14847 self.buf.as_ptr() as usize,
14848 ))
14849 }
14850 pub fn get_collect_metadata(&self) -> Result<(), ErrorContext> {
14851 let mut iter = self.clone();
14852 iter.pos = 0;
14853 for attr in iter {
14854 if let LinkinfoIp6tnlAttrs::CollectMetadata(val) = attr? {
14855 return Ok(val);
14856 }
14857 }
14858 Err(ErrorContext::new_missing(
14859 "LinkinfoIp6tnlAttrs",
14860 "CollectMetadata",
14861 self.orig_loc,
14862 self.buf.as_ptr() as usize,
14863 ))
14864 }
14865 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
14866 let mut iter = self.clone();
14867 iter.pos = 0;
14868 for attr in iter {
14869 if let LinkinfoIp6tnlAttrs::Fwmark(val) = attr? {
14870 return Ok(val);
14871 }
14872 }
14873 Err(ErrorContext::new_missing(
14874 "LinkinfoIp6tnlAttrs",
14875 "Fwmark",
14876 self.orig_loc,
14877 self.buf.as_ptr() as usize,
14878 ))
14879 }
14880}
14881impl LinkinfoIp6tnlAttrs<'_> {
14882 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoIp6tnlAttrs<'a> {
14883 IterableLinkinfoIp6tnlAttrs::with_loc(buf, buf.as_ptr() as usize)
14884 }
14885 fn attr_from_type(r#type: u16) -> Option<&'static str> {
14886 LinkinfoIptunAttrs::attr_from_type(r#type)
14887 }
14888}
14889#[derive(Clone, Copy, Default)]
14890pub struct IterableLinkinfoIp6tnlAttrs<'a> {
14891 buf: &'a [u8],
14892 pos: usize,
14893 orig_loc: usize,
14894}
14895impl<'a> IterableLinkinfoIp6tnlAttrs<'a> {
14896 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
14897 Self {
14898 buf,
14899 pos: 0,
14900 orig_loc,
14901 }
14902 }
14903 pub fn get_buf(&self) -> &'a [u8] {
14904 self.buf
14905 }
14906}
14907impl<'a> Iterator for IterableLinkinfoIp6tnlAttrs<'a> {
14908 type Item = Result<LinkinfoIp6tnlAttrs<'a>, ErrorContext>;
14909 fn next(&mut self) -> Option<Self::Item> {
14910 let pos = self.pos;
14911 let mut r#type;
14912 loop {
14913 r#type = None;
14914 if self.buf.len() == self.pos {
14915 return None;
14916 }
14917 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
14918 break;
14919 };
14920 r#type = Some(header.r#type);
14921 let res = match header.r#type {
14922 1u16 => LinkinfoIp6tnlAttrs::Link({
14923 let res = parse_u32(next);
14924 let Some(val) = res else { break };
14925 val
14926 }),
14927 2u16 => LinkinfoIp6tnlAttrs::Local({
14928 let res = Some(next);
14929 let Some(val) = res else { break };
14930 val
14931 }),
14932 3u16 => LinkinfoIp6tnlAttrs::Remote({
14933 let res = Some(next);
14934 let Some(val) = res else { break };
14935 val
14936 }),
14937 4u16 => LinkinfoIp6tnlAttrs::Ttl({
14938 let res = parse_u8(next);
14939 let Some(val) = res else { break };
14940 val
14941 }),
14942 6u16 => LinkinfoIp6tnlAttrs::EncapLimit({
14943 let res = parse_u8(next);
14944 let Some(val) = res else { break };
14945 val
14946 }),
14947 7u16 => LinkinfoIp6tnlAttrs::Flowinfo({
14948 let res = parse_be_u32(next);
14949 let Some(val) = res else { break };
14950 val
14951 }),
14952 8u16 => LinkinfoIp6tnlAttrs::Flags({
14953 let res = parse_be_u32(next);
14954 let Some(val) = res else { break };
14955 val
14956 }),
14957 9u16 => LinkinfoIp6tnlAttrs::Proto({
14958 let res = parse_u8(next);
14959 let Some(val) = res else { break };
14960 val
14961 }),
14962 15u16 => LinkinfoIp6tnlAttrs::EncapType({
14963 let res = parse_u16(next);
14964 let Some(val) = res else { break };
14965 val
14966 }),
14967 16u16 => LinkinfoIp6tnlAttrs::EncapFlags({
14968 let res = parse_u16(next);
14969 let Some(val) = res else { break };
14970 val
14971 }),
14972 17u16 => LinkinfoIp6tnlAttrs::EncapSport({
14973 let res = parse_be_u16(next);
14974 let Some(val) = res else { break };
14975 val
14976 }),
14977 18u16 => LinkinfoIp6tnlAttrs::EncapDport({
14978 let res = parse_be_u16(next);
14979 let Some(val) = res else { break };
14980 val
14981 }),
14982 19u16 => LinkinfoIp6tnlAttrs::CollectMetadata(()),
14983 20u16 => LinkinfoIp6tnlAttrs::Fwmark({
14984 let res = parse_u32(next);
14985 let Some(val) = res else { break };
14986 val
14987 }),
14988 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
14989 n => continue,
14990 };
14991 return Some(Ok(res));
14992 }
14993 Some(Err(ErrorContext::new(
14994 "LinkinfoIp6tnlAttrs",
14995 r#type.and_then(|t| LinkinfoIp6tnlAttrs::attr_from_type(t)),
14996 self.orig_loc,
14997 self.buf.as_ptr().wrapping_add(pos) as usize,
14998 )))
14999 }
15000}
15001impl<'a> std::fmt::Debug for IterableLinkinfoIp6tnlAttrs<'_> {
15002 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15003 let mut fmt = f.debug_struct("LinkinfoIp6tnlAttrs");
15004 for attr in self.clone() {
15005 let attr = match attr {
15006 Ok(a) => a,
15007 Err(err) => {
15008 fmt.finish()?;
15009 f.write_str("Err(")?;
15010 err.fmt(f)?;
15011 return f.write_str(")");
15012 }
15013 };
15014 match attr {
15015 LinkinfoIp6tnlAttrs::Link(val) => fmt.field("Link", &val),
15016 LinkinfoIp6tnlAttrs::Local(val) => fmt.field("Local", &val),
15017 LinkinfoIp6tnlAttrs::Remote(val) => fmt.field("Remote", &val),
15018 LinkinfoIp6tnlAttrs::Ttl(val) => fmt.field("Ttl", &val),
15019 LinkinfoIp6tnlAttrs::EncapLimit(val) => fmt.field("EncapLimit", &val),
15020 LinkinfoIp6tnlAttrs::Flowinfo(val) => fmt.field("Flowinfo", &val),
15021 LinkinfoIp6tnlAttrs::Flags(val) => fmt.field("Flags", &val),
15022 LinkinfoIp6tnlAttrs::Proto(val) => fmt.field("Proto", &val),
15023 LinkinfoIp6tnlAttrs::EncapType(val) => fmt.field("EncapType", &val),
15024 LinkinfoIp6tnlAttrs::EncapFlags(val) => fmt.field("EncapFlags", &val),
15025 LinkinfoIp6tnlAttrs::EncapSport(val) => fmt.field("EncapSport", &val),
15026 LinkinfoIp6tnlAttrs::EncapDport(val) => fmt.field("EncapDport", &val),
15027 LinkinfoIp6tnlAttrs::CollectMetadata(val) => fmt.field("CollectMetadata", &val),
15028 LinkinfoIp6tnlAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
15029 };
15030 }
15031 fmt.finish()
15032 }
15033}
15034impl IterableLinkinfoIp6tnlAttrs<'_> {
15035 pub fn lookup_attr(
15036 &self,
15037 offset: usize,
15038 missing_type: Option<u16>,
15039 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15040 let mut stack = Vec::new();
15041 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15042 if missing_type.is_some() && cur == offset {
15043 stack.push(("LinkinfoIp6tnlAttrs", offset));
15044 return (
15045 stack,
15046 missing_type.and_then(|t| LinkinfoIp6tnlAttrs::attr_from_type(t)),
15047 );
15048 }
15049 if cur > offset || cur + self.buf.len() < offset {
15050 return (stack, None);
15051 }
15052 let mut attrs = self.clone();
15053 let mut last_off = cur + attrs.pos;
15054 while let Some(attr) = attrs.next() {
15055 let Ok(attr) = attr else { break };
15056 match attr {
15057 LinkinfoIp6tnlAttrs::Link(val) => {
15058 if last_off == offset {
15059 stack.push(("Link", last_off));
15060 break;
15061 }
15062 }
15063 LinkinfoIp6tnlAttrs::Local(val) => {
15064 if last_off == offset {
15065 stack.push(("Local", last_off));
15066 break;
15067 }
15068 }
15069 LinkinfoIp6tnlAttrs::Remote(val) => {
15070 if last_off == offset {
15071 stack.push(("Remote", last_off));
15072 break;
15073 }
15074 }
15075 LinkinfoIp6tnlAttrs::Ttl(val) => {
15076 if last_off == offset {
15077 stack.push(("Ttl", last_off));
15078 break;
15079 }
15080 }
15081 LinkinfoIp6tnlAttrs::EncapLimit(val) => {
15082 if last_off == offset {
15083 stack.push(("EncapLimit", last_off));
15084 break;
15085 }
15086 }
15087 LinkinfoIp6tnlAttrs::Flowinfo(val) => {
15088 if last_off == offset {
15089 stack.push(("Flowinfo", last_off));
15090 break;
15091 }
15092 }
15093 LinkinfoIp6tnlAttrs::Flags(val) => {
15094 if last_off == offset {
15095 stack.push(("Flags", last_off));
15096 break;
15097 }
15098 }
15099 LinkinfoIp6tnlAttrs::Proto(val) => {
15100 if last_off == offset {
15101 stack.push(("Proto", last_off));
15102 break;
15103 }
15104 }
15105 LinkinfoIp6tnlAttrs::EncapType(val) => {
15106 if last_off == offset {
15107 stack.push(("EncapType", last_off));
15108 break;
15109 }
15110 }
15111 LinkinfoIp6tnlAttrs::EncapFlags(val) => {
15112 if last_off == offset {
15113 stack.push(("EncapFlags", last_off));
15114 break;
15115 }
15116 }
15117 LinkinfoIp6tnlAttrs::EncapSport(val) => {
15118 if last_off == offset {
15119 stack.push(("EncapSport", last_off));
15120 break;
15121 }
15122 }
15123 LinkinfoIp6tnlAttrs::EncapDport(val) => {
15124 if last_off == offset {
15125 stack.push(("EncapDport", last_off));
15126 break;
15127 }
15128 }
15129 LinkinfoIp6tnlAttrs::CollectMetadata(val) => {
15130 if last_off == offset {
15131 stack.push(("CollectMetadata", last_off));
15132 break;
15133 }
15134 }
15135 LinkinfoIp6tnlAttrs::Fwmark(val) => {
15136 if last_off == offset {
15137 stack.push(("Fwmark", last_off));
15138 break;
15139 }
15140 }
15141 _ => {}
15142 };
15143 last_off = cur + attrs.pos;
15144 }
15145 if !stack.is_empty() {
15146 stack.push(("LinkinfoIp6tnlAttrs", cur));
15147 }
15148 (stack, None)
15149 }
15150}
15151#[derive(Clone)]
15152pub enum LinkinfoTunAttrs {
15153 Owner(u32),
15154 Group(u32),
15155 Type(u8),
15156 Pi(u8),
15157 VnetHdr(u8),
15158 Persist(u8),
15159 MultiQueue(u8),
15160 NumQueues(u32),
15161 NumDisabledQueues(u32),
15162}
15163impl<'a> IterableLinkinfoTunAttrs<'a> {
15164 pub fn get_owner(&self) -> Result<u32, ErrorContext> {
15165 let mut iter = self.clone();
15166 iter.pos = 0;
15167 for attr in iter {
15168 if let LinkinfoTunAttrs::Owner(val) = attr? {
15169 return Ok(val);
15170 }
15171 }
15172 Err(ErrorContext::new_missing(
15173 "LinkinfoTunAttrs",
15174 "Owner",
15175 self.orig_loc,
15176 self.buf.as_ptr() as usize,
15177 ))
15178 }
15179 pub fn get_group(&self) -> Result<u32, ErrorContext> {
15180 let mut iter = self.clone();
15181 iter.pos = 0;
15182 for attr in iter {
15183 if let LinkinfoTunAttrs::Group(val) = attr? {
15184 return Ok(val);
15185 }
15186 }
15187 Err(ErrorContext::new_missing(
15188 "LinkinfoTunAttrs",
15189 "Group",
15190 self.orig_loc,
15191 self.buf.as_ptr() as usize,
15192 ))
15193 }
15194 pub fn get_type(&self) -> Result<u8, ErrorContext> {
15195 let mut iter = self.clone();
15196 iter.pos = 0;
15197 for attr in iter {
15198 if let LinkinfoTunAttrs::Type(val) = attr? {
15199 return Ok(val);
15200 }
15201 }
15202 Err(ErrorContext::new_missing(
15203 "LinkinfoTunAttrs",
15204 "Type",
15205 self.orig_loc,
15206 self.buf.as_ptr() as usize,
15207 ))
15208 }
15209 pub fn get_pi(&self) -> Result<u8, ErrorContext> {
15210 let mut iter = self.clone();
15211 iter.pos = 0;
15212 for attr in iter {
15213 if let LinkinfoTunAttrs::Pi(val) = attr? {
15214 return Ok(val);
15215 }
15216 }
15217 Err(ErrorContext::new_missing(
15218 "LinkinfoTunAttrs",
15219 "Pi",
15220 self.orig_loc,
15221 self.buf.as_ptr() as usize,
15222 ))
15223 }
15224 pub fn get_vnet_hdr(&self) -> Result<u8, ErrorContext> {
15225 let mut iter = self.clone();
15226 iter.pos = 0;
15227 for attr in iter {
15228 if let LinkinfoTunAttrs::VnetHdr(val) = attr? {
15229 return Ok(val);
15230 }
15231 }
15232 Err(ErrorContext::new_missing(
15233 "LinkinfoTunAttrs",
15234 "VnetHdr",
15235 self.orig_loc,
15236 self.buf.as_ptr() as usize,
15237 ))
15238 }
15239 pub fn get_persist(&self) -> Result<u8, ErrorContext> {
15240 let mut iter = self.clone();
15241 iter.pos = 0;
15242 for attr in iter {
15243 if let LinkinfoTunAttrs::Persist(val) = attr? {
15244 return Ok(val);
15245 }
15246 }
15247 Err(ErrorContext::new_missing(
15248 "LinkinfoTunAttrs",
15249 "Persist",
15250 self.orig_loc,
15251 self.buf.as_ptr() as usize,
15252 ))
15253 }
15254 pub fn get_multi_queue(&self) -> Result<u8, ErrorContext> {
15255 let mut iter = self.clone();
15256 iter.pos = 0;
15257 for attr in iter {
15258 if let LinkinfoTunAttrs::MultiQueue(val) = attr? {
15259 return Ok(val);
15260 }
15261 }
15262 Err(ErrorContext::new_missing(
15263 "LinkinfoTunAttrs",
15264 "MultiQueue",
15265 self.orig_loc,
15266 self.buf.as_ptr() as usize,
15267 ))
15268 }
15269 pub fn get_num_queues(&self) -> Result<u32, ErrorContext> {
15270 let mut iter = self.clone();
15271 iter.pos = 0;
15272 for attr in iter {
15273 if let LinkinfoTunAttrs::NumQueues(val) = attr? {
15274 return Ok(val);
15275 }
15276 }
15277 Err(ErrorContext::new_missing(
15278 "LinkinfoTunAttrs",
15279 "NumQueues",
15280 self.orig_loc,
15281 self.buf.as_ptr() as usize,
15282 ))
15283 }
15284 pub fn get_num_disabled_queues(&self) -> Result<u32, ErrorContext> {
15285 let mut iter = self.clone();
15286 iter.pos = 0;
15287 for attr in iter {
15288 if let LinkinfoTunAttrs::NumDisabledQueues(val) = attr? {
15289 return Ok(val);
15290 }
15291 }
15292 Err(ErrorContext::new_missing(
15293 "LinkinfoTunAttrs",
15294 "NumDisabledQueues",
15295 self.orig_loc,
15296 self.buf.as_ptr() as usize,
15297 ))
15298 }
15299}
15300impl LinkinfoTunAttrs {
15301 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoTunAttrs<'a> {
15302 IterableLinkinfoTunAttrs::with_loc(buf, buf.as_ptr() as usize)
15303 }
15304 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15305 let res = match r#type {
15306 1u16 => "Owner",
15307 2u16 => "Group",
15308 3u16 => "Type",
15309 4u16 => "Pi",
15310 5u16 => "VnetHdr",
15311 6u16 => "Persist",
15312 7u16 => "MultiQueue",
15313 8u16 => "NumQueues",
15314 9u16 => "NumDisabledQueues",
15315 _ => return None,
15316 };
15317 Some(res)
15318 }
15319}
15320#[derive(Clone, Copy, Default)]
15321pub struct IterableLinkinfoTunAttrs<'a> {
15322 buf: &'a [u8],
15323 pos: usize,
15324 orig_loc: usize,
15325}
15326impl<'a> IterableLinkinfoTunAttrs<'a> {
15327 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15328 Self {
15329 buf,
15330 pos: 0,
15331 orig_loc,
15332 }
15333 }
15334 pub fn get_buf(&self) -> &'a [u8] {
15335 self.buf
15336 }
15337}
15338impl<'a> Iterator for IterableLinkinfoTunAttrs<'a> {
15339 type Item = Result<LinkinfoTunAttrs, ErrorContext>;
15340 fn next(&mut self) -> Option<Self::Item> {
15341 let pos = self.pos;
15342 let mut r#type;
15343 loop {
15344 r#type = None;
15345 if self.buf.len() == self.pos {
15346 return None;
15347 }
15348 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15349 break;
15350 };
15351 r#type = Some(header.r#type);
15352 let res = match header.r#type {
15353 1u16 => LinkinfoTunAttrs::Owner({
15354 let res = parse_u32(next);
15355 let Some(val) = res else { break };
15356 val
15357 }),
15358 2u16 => LinkinfoTunAttrs::Group({
15359 let res = parse_u32(next);
15360 let Some(val) = res else { break };
15361 val
15362 }),
15363 3u16 => LinkinfoTunAttrs::Type({
15364 let res = parse_u8(next);
15365 let Some(val) = res else { break };
15366 val
15367 }),
15368 4u16 => LinkinfoTunAttrs::Pi({
15369 let res = parse_u8(next);
15370 let Some(val) = res else { break };
15371 val
15372 }),
15373 5u16 => LinkinfoTunAttrs::VnetHdr({
15374 let res = parse_u8(next);
15375 let Some(val) = res else { break };
15376 val
15377 }),
15378 6u16 => LinkinfoTunAttrs::Persist({
15379 let res = parse_u8(next);
15380 let Some(val) = res else { break };
15381 val
15382 }),
15383 7u16 => LinkinfoTunAttrs::MultiQueue({
15384 let res = parse_u8(next);
15385 let Some(val) = res else { break };
15386 val
15387 }),
15388 8u16 => LinkinfoTunAttrs::NumQueues({
15389 let res = parse_u32(next);
15390 let Some(val) = res else { break };
15391 val
15392 }),
15393 9u16 => LinkinfoTunAttrs::NumDisabledQueues({
15394 let res = parse_u32(next);
15395 let Some(val) = res else { break };
15396 val
15397 }),
15398 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15399 n => continue,
15400 };
15401 return Some(Ok(res));
15402 }
15403 Some(Err(ErrorContext::new(
15404 "LinkinfoTunAttrs",
15405 r#type.and_then(|t| LinkinfoTunAttrs::attr_from_type(t)),
15406 self.orig_loc,
15407 self.buf.as_ptr().wrapping_add(pos) as usize,
15408 )))
15409 }
15410}
15411impl std::fmt::Debug for IterableLinkinfoTunAttrs<'_> {
15412 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15413 let mut fmt = f.debug_struct("LinkinfoTunAttrs");
15414 for attr in self.clone() {
15415 let attr = match attr {
15416 Ok(a) => a,
15417 Err(err) => {
15418 fmt.finish()?;
15419 f.write_str("Err(")?;
15420 err.fmt(f)?;
15421 return f.write_str(")");
15422 }
15423 };
15424 match attr {
15425 LinkinfoTunAttrs::Owner(val) => fmt.field("Owner", &val),
15426 LinkinfoTunAttrs::Group(val) => fmt.field("Group", &val),
15427 LinkinfoTunAttrs::Type(val) => fmt.field("Type", &val),
15428 LinkinfoTunAttrs::Pi(val) => fmt.field("Pi", &val),
15429 LinkinfoTunAttrs::VnetHdr(val) => fmt.field("VnetHdr", &val),
15430 LinkinfoTunAttrs::Persist(val) => fmt.field("Persist", &val),
15431 LinkinfoTunAttrs::MultiQueue(val) => fmt.field("MultiQueue", &val),
15432 LinkinfoTunAttrs::NumQueues(val) => fmt.field("NumQueues", &val),
15433 LinkinfoTunAttrs::NumDisabledQueues(val) => fmt.field("NumDisabledQueues", &val),
15434 };
15435 }
15436 fmt.finish()
15437 }
15438}
15439impl IterableLinkinfoTunAttrs<'_> {
15440 pub fn lookup_attr(
15441 &self,
15442 offset: usize,
15443 missing_type: Option<u16>,
15444 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15445 let mut stack = Vec::new();
15446 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15447 if missing_type.is_some() && cur == offset {
15448 stack.push(("LinkinfoTunAttrs", offset));
15449 return (
15450 stack,
15451 missing_type.and_then(|t| LinkinfoTunAttrs::attr_from_type(t)),
15452 );
15453 }
15454 if cur > offset || cur + self.buf.len() < offset {
15455 return (stack, None);
15456 }
15457 let mut attrs = self.clone();
15458 let mut last_off = cur + attrs.pos;
15459 while let Some(attr) = attrs.next() {
15460 let Ok(attr) = attr else { break };
15461 match attr {
15462 LinkinfoTunAttrs::Owner(val) => {
15463 if last_off == offset {
15464 stack.push(("Owner", last_off));
15465 break;
15466 }
15467 }
15468 LinkinfoTunAttrs::Group(val) => {
15469 if last_off == offset {
15470 stack.push(("Group", last_off));
15471 break;
15472 }
15473 }
15474 LinkinfoTunAttrs::Type(val) => {
15475 if last_off == offset {
15476 stack.push(("Type", last_off));
15477 break;
15478 }
15479 }
15480 LinkinfoTunAttrs::Pi(val) => {
15481 if last_off == offset {
15482 stack.push(("Pi", last_off));
15483 break;
15484 }
15485 }
15486 LinkinfoTunAttrs::VnetHdr(val) => {
15487 if last_off == offset {
15488 stack.push(("VnetHdr", last_off));
15489 break;
15490 }
15491 }
15492 LinkinfoTunAttrs::Persist(val) => {
15493 if last_off == offset {
15494 stack.push(("Persist", last_off));
15495 break;
15496 }
15497 }
15498 LinkinfoTunAttrs::MultiQueue(val) => {
15499 if last_off == offset {
15500 stack.push(("MultiQueue", last_off));
15501 break;
15502 }
15503 }
15504 LinkinfoTunAttrs::NumQueues(val) => {
15505 if last_off == offset {
15506 stack.push(("NumQueues", last_off));
15507 break;
15508 }
15509 }
15510 LinkinfoTunAttrs::NumDisabledQueues(val) => {
15511 if last_off == offset {
15512 stack.push(("NumDisabledQueues", last_off));
15513 break;
15514 }
15515 }
15516 _ => {}
15517 };
15518 last_off = cur + attrs.pos;
15519 }
15520 if !stack.is_empty() {
15521 stack.push(("LinkinfoTunAttrs", cur));
15522 }
15523 (stack, None)
15524 }
15525}
15526#[derive(Clone)]
15527pub enum LinkinfoVlanAttrs<'a> {
15528 Id(u16),
15529 Flags(IflaVlanFlags),
15530 EgressQos(IterableIflaVlanQos<'a>),
15531 IngressQos(IterableIflaVlanQos<'a>),
15532 #[doc = "Associated type: [`VlanProtocols`] (enum)"]
15533 Protocol(u16),
15534}
15535impl<'a> IterableLinkinfoVlanAttrs<'a> {
15536 pub fn get_id(&self) -> Result<u16, ErrorContext> {
15537 let mut iter = self.clone();
15538 iter.pos = 0;
15539 for attr in iter {
15540 if let LinkinfoVlanAttrs::Id(val) = attr? {
15541 return Ok(val);
15542 }
15543 }
15544 Err(ErrorContext::new_missing(
15545 "LinkinfoVlanAttrs",
15546 "Id",
15547 self.orig_loc,
15548 self.buf.as_ptr() as usize,
15549 ))
15550 }
15551 pub fn get_flags(&self) -> Result<IflaVlanFlags, ErrorContext> {
15552 let mut iter = self.clone();
15553 iter.pos = 0;
15554 for attr in iter {
15555 if let LinkinfoVlanAttrs::Flags(val) = attr? {
15556 return Ok(val);
15557 }
15558 }
15559 Err(ErrorContext::new_missing(
15560 "LinkinfoVlanAttrs",
15561 "Flags",
15562 self.orig_loc,
15563 self.buf.as_ptr() as usize,
15564 ))
15565 }
15566 pub fn get_egress_qos(&self) -> Result<IterableIflaVlanQos<'a>, ErrorContext> {
15567 let mut iter = self.clone();
15568 iter.pos = 0;
15569 for attr in iter {
15570 if let LinkinfoVlanAttrs::EgressQos(val) = attr? {
15571 return Ok(val);
15572 }
15573 }
15574 Err(ErrorContext::new_missing(
15575 "LinkinfoVlanAttrs",
15576 "EgressQos",
15577 self.orig_loc,
15578 self.buf.as_ptr() as usize,
15579 ))
15580 }
15581 pub fn get_ingress_qos(&self) -> Result<IterableIflaVlanQos<'a>, ErrorContext> {
15582 let mut iter = self.clone();
15583 iter.pos = 0;
15584 for attr in iter {
15585 if let LinkinfoVlanAttrs::IngressQos(val) = attr? {
15586 return Ok(val);
15587 }
15588 }
15589 Err(ErrorContext::new_missing(
15590 "LinkinfoVlanAttrs",
15591 "IngressQos",
15592 self.orig_loc,
15593 self.buf.as_ptr() as usize,
15594 ))
15595 }
15596 #[doc = "Associated type: [`VlanProtocols`] (enum)"]
15597 pub fn get_protocol(&self) -> Result<u16, ErrorContext> {
15598 let mut iter = self.clone();
15599 iter.pos = 0;
15600 for attr in iter {
15601 if let LinkinfoVlanAttrs::Protocol(val) = attr? {
15602 return Ok(val);
15603 }
15604 }
15605 Err(ErrorContext::new_missing(
15606 "LinkinfoVlanAttrs",
15607 "Protocol",
15608 self.orig_loc,
15609 self.buf.as_ptr() as usize,
15610 ))
15611 }
15612}
15613impl LinkinfoVlanAttrs<'_> {
15614 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVlanAttrs<'a> {
15615 IterableLinkinfoVlanAttrs::with_loc(buf, buf.as_ptr() as usize)
15616 }
15617 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15618 let res = match r#type {
15619 1u16 => "Id",
15620 2u16 => "Flags",
15621 3u16 => "EgressQos",
15622 4u16 => "IngressQos",
15623 5u16 => "Protocol",
15624 _ => return None,
15625 };
15626 Some(res)
15627 }
15628}
15629#[derive(Clone, Copy, Default)]
15630pub struct IterableLinkinfoVlanAttrs<'a> {
15631 buf: &'a [u8],
15632 pos: usize,
15633 orig_loc: usize,
15634}
15635impl<'a> IterableLinkinfoVlanAttrs<'a> {
15636 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15637 Self {
15638 buf,
15639 pos: 0,
15640 orig_loc,
15641 }
15642 }
15643 pub fn get_buf(&self) -> &'a [u8] {
15644 self.buf
15645 }
15646}
15647impl<'a> Iterator for IterableLinkinfoVlanAttrs<'a> {
15648 type Item = Result<LinkinfoVlanAttrs<'a>, ErrorContext>;
15649 fn next(&mut self) -> Option<Self::Item> {
15650 let pos = self.pos;
15651 let mut r#type;
15652 loop {
15653 r#type = None;
15654 if self.buf.len() == self.pos {
15655 return None;
15656 }
15657 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15658 break;
15659 };
15660 r#type = Some(header.r#type);
15661 let res = match header.r#type {
15662 1u16 => LinkinfoVlanAttrs::Id({
15663 let res = parse_u16(next);
15664 let Some(val) = res else { break };
15665 val
15666 }),
15667 2u16 => LinkinfoVlanAttrs::Flags({
15668 let res = Some(IflaVlanFlags::new_from_zeroed(next));
15669 let Some(val) = res else { break };
15670 val
15671 }),
15672 3u16 => LinkinfoVlanAttrs::EgressQos({
15673 let res = Some(IterableIflaVlanQos::with_loc(next, self.orig_loc));
15674 let Some(val) = res else { break };
15675 val
15676 }),
15677 4u16 => LinkinfoVlanAttrs::IngressQos({
15678 let res = Some(IterableIflaVlanQos::with_loc(next, self.orig_loc));
15679 let Some(val) = res else { break };
15680 val
15681 }),
15682 5u16 => LinkinfoVlanAttrs::Protocol({
15683 let res = parse_be_u16(next);
15684 let Some(val) = res else { break };
15685 val
15686 }),
15687 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15688 n => continue,
15689 };
15690 return Some(Ok(res));
15691 }
15692 Some(Err(ErrorContext::new(
15693 "LinkinfoVlanAttrs",
15694 r#type.and_then(|t| LinkinfoVlanAttrs::attr_from_type(t)),
15695 self.orig_loc,
15696 self.buf.as_ptr().wrapping_add(pos) as usize,
15697 )))
15698 }
15699}
15700impl<'a> std::fmt::Debug for IterableLinkinfoVlanAttrs<'_> {
15701 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15702 let mut fmt = f.debug_struct("LinkinfoVlanAttrs");
15703 for attr in self.clone() {
15704 let attr = match attr {
15705 Ok(a) => a,
15706 Err(err) => {
15707 fmt.finish()?;
15708 f.write_str("Err(")?;
15709 err.fmt(f)?;
15710 return f.write_str(")");
15711 }
15712 };
15713 match attr {
15714 LinkinfoVlanAttrs::Id(val) => fmt.field("Id", &val),
15715 LinkinfoVlanAttrs::Flags(val) => fmt.field("Flags", &val),
15716 LinkinfoVlanAttrs::EgressQos(val) => fmt.field("EgressQos", &val),
15717 LinkinfoVlanAttrs::IngressQos(val) => fmt.field("IngressQos", &val),
15718 LinkinfoVlanAttrs::Protocol(val) => fmt.field(
15719 "Protocol",
15720 &FormatEnum(val.into(), VlanProtocols::from_value),
15721 ),
15722 };
15723 }
15724 fmt.finish()
15725 }
15726}
15727impl IterableLinkinfoVlanAttrs<'_> {
15728 pub fn lookup_attr(
15729 &self,
15730 offset: usize,
15731 missing_type: Option<u16>,
15732 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15733 let mut stack = Vec::new();
15734 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15735 if missing_type.is_some() && cur == offset {
15736 stack.push(("LinkinfoVlanAttrs", offset));
15737 return (
15738 stack,
15739 missing_type.and_then(|t| LinkinfoVlanAttrs::attr_from_type(t)),
15740 );
15741 }
15742 if cur > offset || cur + self.buf.len() < offset {
15743 return (stack, None);
15744 }
15745 let mut attrs = self.clone();
15746 let mut last_off = cur + attrs.pos;
15747 let mut missing = None;
15748 while let Some(attr) = attrs.next() {
15749 let Ok(attr) = attr else { break };
15750 match attr {
15751 LinkinfoVlanAttrs::Id(val) => {
15752 if last_off == offset {
15753 stack.push(("Id", last_off));
15754 break;
15755 }
15756 }
15757 LinkinfoVlanAttrs::Flags(val) => {
15758 if last_off == offset {
15759 stack.push(("Flags", last_off));
15760 break;
15761 }
15762 }
15763 LinkinfoVlanAttrs::EgressQos(val) => {
15764 (stack, missing) = val.lookup_attr(offset, missing_type);
15765 if !stack.is_empty() {
15766 break;
15767 }
15768 }
15769 LinkinfoVlanAttrs::IngressQos(val) => {
15770 (stack, missing) = val.lookup_attr(offset, missing_type);
15771 if !stack.is_empty() {
15772 break;
15773 }
15774 }
15775 LinkinfoVlanAttrs::Protocol(val) => {
15776 if last_off == offset {
15777 stack.push(("Protocol", last_off));
15778 break;
15779 }
15780 }
15781 _ => {}
15782 };
15783 last_off = cur + attrs.pos;
15784 }
15785 if !stack.is_empty() {
15786 stack.push(("LinkinfoVlanAttrs", cur));
15787 }
15788 (stack, missing)
15789 }
15790}
15791#[derive(Clone)]
15792pub enum IflaVlanQos {
15793 #[doc = "Attribute may repeat multiple times (treat it as array)"]
15794 Mapping(IflaVlanQosMapping),
15795}
15796impl<'a> IterableIflaVlanQos<'a> {
15797 #[doc = "Attribute may repeat multiple times (treat it as array)"]
15798 pub fn get_mapping(&self) -> MultiAttrIterable<Self, IflaVlanQos, IflaVlanQosMapping> {
15799 MultiAttrIterable::new(self.clone(), |variant| {
15800 if let IflaVlanQos::Mapping(val) = variant {
15801 Some(val)
15802 } else {
15803 None
15804 }
15805 })
15806 }
15807}
15808impl IflaVlanQos {
15809 pub fn new<'a>(buf: &'a [u8]) -> IterableIflaVlanQos<'a> {
15810 IterableIflaVlanQos::with_loc(buf, buf.as_ptr() as usize)
15811 }
15812 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15813 let res = match r#type {
15814 1u16 => "Mapping",
15815 _ => return None,
15816 };
15817 Some(res)
15818 }
15819}
15820#[derive(Clone, Copy, Default)]
15821pub struct IterableIflaVlanQos<'a> {
15822 buf: &'a [u8],
15823 pos: usize,
15824 orig_loc: usize,
15825}
15826impl<'a> IterableIflaVlanQos<'a> {
15827 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15828 Self {
15829 buf,
15830 pos: 0,
15831 orig_loc,
15832 }
15833 }
15834 pub fn get_buf(&self) -> &'a [u8] {
15835 self.buf
15836 }
15837}
15838impl<'a> Iterator for IterableIflaVlanQos<'a> {
15839 type Item = Result<IflaVlanQos, ErrorContext>;
15840 fn next(&mut self) -> Option<Self::Item> {
15841 let pos = self.pos;
15842 let mut r#type;
15843 loop {
15844 r#type = None;
15845 if self.buf.len() == self.pos {
15846 return None;
15847 }
15848 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15849 break;
15850 };
15851 r#type = Some(header.r#type);
15852 let res = match header.r#type {
15853 1u16 => IflaVlanQos::Mapping({
15854 let res = Some(IflaVlanQosMapping::new_from_zeroed(next));
15855 let Some(val) = res else { break };
15856 val
15857 }),
15858 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
15859 n => continue,
15860 };
15861 return Some(Ok(res));
15862 }
15863 Some(Err(ErrorContext::new(
15864 "IflaVlanQos",
15865 r#type.and_then(|t| IflaVlanQos::attr_from_type(t)),
15866 self.orig_loc,
15867 self.buf.as_ptr().wrapping_add(pos) as usize,
15868 )))
15869 }
15870}
15871impl std::fmt::Debug for IterableIflaVlanQos<'_> {
15872 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15873 let mut fmt = f.debug_struct("IflaVlanQos");
15874 for attr in self.clone() {
15875 let attr = match attr {
15876 Ok(a) => a,
15877 Err(err) => {
15878 fmt.finish()?;
15879 f.write_str("Err(")?;
15880 err.fmt(f)?;
15881 return f.write_str(")");
15882 }
15883 };
15884 match attr {
15885 IflaVlanQos::Mapping(val) => fmt.field("Mapping", &val),
15886 };
15887 }
15888 fmt.finish()
15889 }
15890}
15891impl IterableIflaVlanQos<'_> {
15892 pub fn lookup_attr(
15893 &self,
15894 offset: usize,
15895 missing_type: Option<u16>,
15896 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
15897 let mut stack = Vec::new();
15898 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
15899 if missing_type.is_some() && cur == offset {
15900 stack.push(("IflaVlanQos", offset));
15901 return (
15902 stack,
15903 missing_type.and_then(|t| IflaVlanQos::attr_from_type(t)),
15904 );
15905 }
15906 if cur > offset || cur + self.buf.len() < offset {
15907 return (stack, None);
15908 }
15909 let mut attrs = self.clone();
15910 let mut last_off = cur + attrs.pos;
15911 while let Some(attr) = attrs.next() {
15912 let Ok(attr) = attr else { break };
15913 match attr {
15914 IflaVlanQos::Mapping(val) => {
15915 if last_off == offset {
15916 stack.push(("Mapping", last_off));
15917 break;
15918 }
15919 }
15920 _ => {}
15921 };
15922 last_off = cur + attrs.pos;
15923 }
15924 if !stack.is_empty() {
15925 stack.push(("IflaVlanQos", cur));
15926 }
15927 (stack, None)
15928 }
15929}
15930#[derive(Clone)]
15931pub enum LinkinfoVrfAttrs {
15932 Table(u32),
15933}
15934impl<'a> IterableLinkinfoVrfAttrs<'a> {
15935 pub fn get_table(&self) -> Result<u32, ErrorContext> {
15936 let mut iter = self.clone();
15937 iter.pos = 0;
15938 for attr in iter {
15939 if let LinkinfoVrfAttrs::Table(val) = attr? {
15940 return Ok(val);
15941 }
15942 }
15943 Err(ErrorContext::new_missing(
15944 "LinkinfoVrfAttrs",
15945 "Table",
15946 self.orig_loc,
15947 self.buf.as_ptr() as usize,
15948 ))
15949 }
15950}
15951impl LinkinfoVrfAttrs {
15952 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoVrfAttrs<'a> {
15953 IterableLinkinfoVrfAttrs::with_loc(buf, buf.as_ptr() as usize)
15954 }
15955 fn attr_from_type(r#type: u16) -> Option<&'static str> {
15956 let res = match r#type {
15957 1u16 => "Table",
15958 _ => return None,
15959 };
15960 Some(res)
15961 }
15962}
15963#[derive(Clone, Copy, Default)]
15964pub struct IterableLinkinfoVrfAttrs<'a> {
15965 buf: &'a [u8],
15966 pos: usize,
15967 orig_loc: usize,
15968}
15969impl<'a> IterableLinkinfoVrfAttrs<'a> {
15970 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
15971 Self {
15972 buf,
15973 pos: 0,
15974 orig_loc,
15975 }
15976 }
15977 pub fn get_buf(&self) -> &'a [u8] {
15978 self.buf
15979 }
15980}
15981impl<'a> Iterator for IterableLinkinfoVrfAttrs<'a> {
15982 type Item = Result<LinkinfoVrfAttrs, ErrorContext>;
15983 fn next(&mut self) -> Option<Self::Item> {
15984 let pos = self.pos;
15985 let mut r#type;
15986 loop {
15987 r#type = None;
15988 if self.buf.len() == self.pos {
15989 return None;
15990 }
15991 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
15992 break;
15993 };
15994 r#type = Some(header.r#type);
15995 let res = match header.r#type {
15996 1u16 => LinkinfoVrfAttrs::Table({
15997 let res = parse_u32(next);
15998 let Some(val) = res else { break };
15999 val
16000 }),
16001 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16002 n => continue,
16003 };
16004 return Some(Ok(res));
16005 }
16006 Some(Err(ErrorContext::new(
16007 "LinkinfoVrfAttrs",
16008 r#type.and_then(|t| LinkinfoVrfAttrs::attr_from_type(t)),
16009 self.orig_loc,
16010 self.buf.as_ptr().wrapping_add(pos) as usize,
16011 )))
16012 }
16013}
16014impl std::fmt::Debug for IterableLinkinfoVrfAttrs<'_> {
16015 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16016 let mut fmt = f.debug_struct("LinkinfoVrfAttrs");
16017 for attr in self.clone() {
16018 let attr = match attr {
16019 Ok(a) => a,
16020 Err(err) => {
16021 fmt.finish()?;
16022 f.write_str("Err(")?;
16023 err.fmt(f)?;
16024 return f.write_str(")");
16025 }
16026 };
16027 match attr {
16028 LinkinfoVrfAttrs::Table(val) => fmt.field("Table", &val),
16029 };
16030 }
16031 fmt.finish()
16032 }
16033}
16034impl IterableLinkinfoVrfAttrs<'_> {
16035 pub fn lookup_attr(
16036 &self,
16037 offset: usize,
16038 missing_type: Option<u16>,
16039 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16040 let mut stack = Vec::new();
16041 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16042 if missing_type.is_some() && cur == offset {
16043 stack.push(("LinkinfoVrfAttrs", offset));
16044 return (
16045 stack,
16046 missing_type.and_then(|t| LinkinfoVrfAttrs::attr_from_type(t)),
16047 );
16048 }
16049 if cur > offset || cur + self.buf.len() < offset {
16050 return (stack, None);
16051 }
16052 let mut attrs = self.clone();
16053 let mut last_off = cur + attrs.pos;
16054 while let Some(attr) = attrs.next() {
16055 let Ok(attr) = attr else { break };
16056 match attr {
16057 LinkinfoVrfAttrs::Table(val) => {
16058 if last_off == offset {
16059 stack.push(("Table", last_off));
16060 break;
16061 }
16062 }
16063 _ => {}
16064 };
16065 last_off = cur + attrs.pos;
16066 }
16067 if !stack.is_empty() {
16068 stack.push(("LinkinfoVrfAttrs", cur));
16069 }
16070 (stack, None)
16071 }
16072}
16073#[derive(Clone)]
16074pub enum XdpAttrs {
16075 Fd(i32),
16076 Attached(u8),
16077 Flags(u32),
16078 ProgId(u32),
16079 DrvProgId(u32),
16080 SkbProgId(u32),
16081 HwProgId(u32),
16082 ExpectedFd(i32),
16083}
16084impl<'a> IterableXdpAttrs<'a> {
16085 pub fn get_fd(&self) -> Result<i32, ErrorContext> {
16086 let mut iter = self.clone();
16087 iter.pos = 0;
16088 for attr in iter {
16089 if let XdpAttrs::Fd(val) = attr? {
16090 return Ok(val);
16091 }
16092 }
16093 Err(ErrorContext::new_missing(
16094 "XdpAttrs",
16095 "Fd",
16096 self.orig_loc,
16097 self.buf.as_ptr() as usize,
16098 ))
16099 }
16100 pub fn get_attached(&self) -> Result<u8, ErrorContext> {
16101 let mut iter = self.clone();
16102 iter.pos = 0;
16103 for attr in iter {
16104 if let XdpAttrs::Attached(val) = attr? {
16105 return Ok(val);
16106 }
16107 }
16108 Err(ErrorContext::new_missing(
16109 "XdpAttrs",
16110 "Attached",
16111 self.orig_loc,
16112 self.buf.as_ptr() as usize,
16113 ))
16114 }
16115 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
16116 let mut iter = self.clone();
16117 iter.pos = 0;
16118 for attr in iter {
16119 if let XdpAttrs::Flags(val) = attr? {
16120 return Ok(val);
16121 }
16122 }
16123 Err(ErrorContext::new_missing(
16124 "XdpAttrs",
16125 "Flags",
16126 self.orig_loc,
16127 self.buf.as_ptr() as usize,
16128 ))
16129 }
16130 pub fn get_prog_id(&self) -> Result<u32, ErrorContext> {
16131 let mut iter = self.clone();
16132 iter.pos = 0;
16133 for attr in iter {
16134 if let XdpAttrs::ProgId(val) = attr? {
16135 return Ok(val);
16136 }
16137 }
16138 Err(ErrorContext::new_missing(
16139 "XdpAttrs",
16140 "ProgId",
16141 self.orig_loc,
16142 self.buf.as_ptr() as usize,
16143 ))
16144 }
16145 pub fn get_drv_prog_id(&self) -> Result<u32, ErrorContext> {
16146 let mut iter = self.clone();
16147 iter.pos = 0;
16148 for attr in iter {
16149 if let XdpAttrs::DrvProgId(val) = attr? {
16150 return Ok(val);
16151 }
16152 }
16153 Err(ErrorContext::new_missing(
16154 "XdpAttrs",
16155 "DrvProgId",
16156 self.orig_loc,
16157 self.buf.as_ptr() as usize,
16158 ))
16159 }
16160 pub fn get_skb_prog_id(&self) -> Result<u32, ErrorContext> {
16161 let mut iter = self.clone();
16162 iter.pos = 0;
16163 for attr in iter {
16164 if let XdpAttrs::SkbProgId(val) = attr? {
16165 return Ok(val);
16166 }
16167 }
16168 Err(ErrorContext::new_missing(
16169 "XdpAttrs",
16170 "SkbProgId",
16171 self.orig_loc,
16172 self.buf.as_ptr() as usize,
16173 ))
16174 }
16175 pub fn get_hw_prog_id(&self) -> Result<u32, ErrorContext> {
16176 let mut iter = self.clone();
16177 iter.pos = 0;
16178 for attr in iter {
16179 if let XdpAttrs::HwProgId(val) = attr? {
16180 return Ok(val);
16181 }
16182 }
16183 Err(ErrorContext::new_missing(
16184 "XdpAttrs",
16185 "HwProgId",
16186 self.orig_loc,
16187 self.buf.as_ptr() as usize,
16188 ))
16189 }
16190 pub fn get_expected_fd(&self) -> Result<i32, ErrorContext> {
16191 let mut iter = self.clone();
16192 iter.pos = 0;
16193 for attr in iter {
16194 if let XdpAttrs::ExpectedFd(val) = attr? {
16195 return Ok(val);
16196 }
16197 }
16198 Err(ErrorContext::new_missing(
16199 "XdpAttrs",
16200 "ExpectedFd",
16201 self.orig_loc,
16202 self.buf.as_ptr() as usize,
16203 ))
16204 }
16205}
16206impl XdpAttrs {
16207 pub fn new<'a>(buf: &'a [u8]) -> IterableXdpAttrs<'a> {
16208 IterableXdpAttrs::with_loc(buf, buf.as_ptr() as usize)
16209 }
16210 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16211 let res = match r#type {
16212 1u16 => "Fd",
16213 2u16 => "Attached",
16214 3u16 => "Flags",
16215 4u16 => "ProgId",
16216 5u16 => "DrvProgId",
16217 6u16 => "SkbProgId",
16218 7u16 => "HwProgId",
16219 8u16 => "ExpectedFd",
16220 _ => return None,
16221 };
16222 Some(res)
16223 }
16224}
16225#[derive(Clone, Copy, Default)]
16226pub struct IterableXdpAttrs<'a> {
16227 buf: &'a [u8],
16228 pos: usize,
16229 orig_loc: usize,
16230}
16231impl<'a> IterableXdpAttrs<'a> {
16232 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16233 Self {
16234 buf,
16235 pos: 0,
16236 orig_loc,
16237 }
16238 }
16239 pub fn get_buf(&self) -> &'a [u8] {
16240 self.buf
16241 }
16242}
16243impl<'a> Iterator for IterableXdpAttrs<'a> {
16244 type Item = Result<XdpAttrs, ErrorContext>;
16245 fn next(&mut self) -> Option<Self::Item> {
16246 let pos = self.pos;
16247 let mut r#type;
16248 loop {
16249 r#type = None;
16250 if self.buf.len() == self.pos {
16251 return None;
16252 }
16253 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16254 break;
16255 };
16256 r#type = Some(header.r#type);
16257 let res = match header.r#type {
16258 1u16 => XdpAttrs::Fd({
16259 let res = parse_i32(next);
16260 let Some(val) = res else { break };
16261 val
16262 }),
16263 2u16 => XdpAttrs::Attached({
16264 let res = parse_u8(next);
16265 let Some(val) = res else { break };
16266 val
16267 }),
16268 3u16 => XdpAttrs::Flags({
16269 let res = parse_u32(next);
16270 let Some(val) = res else { break };
16271 val
16272 }),
16273 4u16 => XdpAttrs::ProgId({
16274 let res = parse_u32(next);
16275 let Some(val) = res else { break };
16276 val
16277 }),
16278 5u16 => XdpAttrs::DrvProgId({
16279 let res = parse_u32(next);
16280 let Some(val) = res else { break };
16281 val
16282 }),
16283 6u16 => XdpAttrs::SkbProgId({
16284 let res = parse_u32(next);
16285 let Some(val) = res else { break };
16286 val
16287 }),
16288 7u16 => XdpAttrs::HwProgId({
16289 let res = parse_u32(next);
16290 let Some(val) = res else { break };
16291 val
16292 }),
16293 8u16 => XdpAttrs::ExpectedFd({
16294 let res = parse_i32(next);
16295 let Some(val) = res else { break };
16296 val
16297 }),
16298 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16299 n => continue,
16300 };
16301 return Some(Ok(res));
16302 }
16303 Some(Err(ErrorContext::new(
16304 "XdpAttrs",
16305 r#type.and_then(|t| XdpAttrs::attr_from_type(t)),
16306 self.orig_loc,
16307 self.buf.as_ptr().wrapping_add(pos) as usize,
16308 )))
16309 }
16310}
16311impl std::fmt::Debug for IterableXdpAttrs<'_> {
16312 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16313 let mut fmt = f.debug_struct("XdpAttrs");
16314 for attr in self.clone() {
16315 let attr = match attr {
16316 Ok(a) => a,
16317 Err(err) => {
16318 fmt.finish()?;
16319 f.write_str("Err(")?;
16320 err.fmt(f)?;
16321 return f.write_str(")");
16322 }
16323 };
16324 match attr {
16325 XdpAttrs::Fd(val) => fmt.field("Fd", &val),
16326 XdpAttrs::Attached(val) => fmt.field("Attached", &val),
16327 XdpAttrs::Flags(val) => fmt.field("Flags", &val),
16328 XdpAttrs::ProgId(val) => fmt.field("ProgId", &val),
16329 XdpAttrs::DrvProgId(val) => fmt.field("DrvProgId", &val),
16330 XdpAttrs::SkbProgId(val) => fmt.field("SkbProgId", &val),
16331 XdpAttrs::HwProgId(val) => fmt.field("HwProgId", &val),
16332 XdpAttrs::ExpectedFd(val) => fmt.field("ExpectedFd", &val),
16333 };
16334 }
16335 fmt.finish()
16336 }
16337}
16338impl IterableXdpAttrs<'_> {
16339 pub fn lookup_attr(
16340 &self,
16341 offset: usize,
16342 missing_type: Option<u16>,
16343 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16344 let mut stack = Vec::new();
16345 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16346 if missing_type.is_some() && cur == offset {
16347 stack.push(("XdpAttrs", offset));
16348 return (
16349 stack,
16350 missing_type.and_then(|t| XdpAttrs::attr_from_type(t)),
16351 );
16352 }
16353 if cur > offset || cur + self.buf.len() < offset {
16354 return (stack, None);
16355 }
16356 let mut attrs = self.clone();
16357 let mut last_off = cur + attrs.pos;
16358 while let Some(attr) = attrs.next() {
16359 let Ok(attr) = attr else { break };
16360 match attr {
16361 XdpAttrs::Fd(val) => {
16362 if last_off == offset {
16363 stack.push(("Fd", last_off));
16364 break;
16365 }
16366 }
16367 XdpAttrs::Attached(val) => {
16368 if last_off == offset {
16369 stack.push(("Attached", last_off));
16370 break;
16371 }
16372 }
16373 XdpAttrs::Flags(val) => {
16374 if last_off == offset {
16375 stack.push(("Flags", last_off));
16376 break;
16377 }
16378 }
16379 XdpAttrs::ProgId(val) => {
16380 if last_off == offset {
16381 stack.push(("ProgId", last_off));
16382 break;
16383 }
16384 }
16385 XdpAttrs::DrvProgId(val) => {
16386 if last_off == offset {
16387 stack.push(("DrvProgId", last_off));
16388 break;
16389 }
16390 }
16391 XdpAttrs::SkbProgId(val) => {
16392 if last_off == offset {
16393 stack.push(("SkbProgId", last_off));
16394 break;
16395 }
16396 }
16397 XdpAttrs::HwProgId(val) => {
16398 if last_off == offset {
16399 stack.push(("HwProgId", last_off));
16400 break;
16401 }
16402 }
16403 XdpAttrs::ExpectedFd(val) => {
16404 if last_off == offset {
16405 stack.push(("ExpectedFd", last_off));
16406 break;
16407 }
16408 }
16409 _ => {}
16410 };
16411 last_off = cur + attrs.pos;
16412 }
16413 if !stack.is_empty() {
16414 stack.push(("XdpAttrs", cur));
16415 }
16416 (stack, None)
16417 }
16418}
16419#[derive(Clone)]
16420pub enum IflaAttrs<'a> {
16421 #[doc = "u32 indexed by ipv4\\-devconf \\- 1 on output, on input it's a nest"]
16422 Conf(&'a [u8]),
16423}
16424impl<'a> IterableIflaAttrs<'a> {
16425 #[doc = "u32 indexed by ipv4\\-devconf \\- 1 on output, on input it's a nest"]
16426 pub fn get_conf(&self) -> Result<&'a [u8], ErrorContext> {
16427 let mut iter = self.clone();
16428 iter.pos = 0;
16429 for attr in iter {
16430 if let IflaAttrs::Conf(val) = attr? {
16431 return Ok(val);
16432 }
16433 }
16434 Err(ErrorContext::new_missing(
16435 "IflaAttrs",
16436 "Conf",
16437 self.orig_loc,
16438 self.buf.as_ptr() as usize,
16439 ))
16440 }
16441}
16442impl IflaAttrs<'_> {
16443 pub fn new<'a>(buf: &'a [u8]) -> IterableIflaAttrs<'a> {
16444 IterableIflaAttrs::with_loc(buf, buf.as_ptr() as usize)
16445 }
16446 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16447 let res = match r#type {
16448 1u16 => "Conf",
16449 _ => return None,
16450 };
16451 Some(res)
16452 }
16453}
16454#[derive(Clone, Copy, Default)]
16455pub struct IterableIflaAttrs<'a> {
16456 buf: &'a [u8],
16457 pos: usize,
16458 orig_loc: usize,
16459}
16460impl<'a> IterableIflaAttrs<'a> {
16461 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16462 Self {
16463 buf,
16464 pos: 0,
16465 orig_loc,
16466 }
16467 }
16468 pub fn get_buf(&self) -> &'a [u8] {
16469 self.buf
16470 }
16471}
16472impl<'a> Iterator for IterableIflaAttrs<'a> {
16473 type Item = Result<IflaAttrs<'a>, ErrorContext>;
16474 fn next(&mut self) -> Option<Self::Item> {
16475 let pos = self.pos;
16476 let mut r#type;
16477 loop {
16478 r#type = None;
16479 if self.buf.len() == self.pos {
16480 return None;
16481 }
16482 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16483 break;
16484 };
16485 r#type = Some(header.r#type);
16486 let res = match header.r#type {
16487 1u16 => IflaAttrs::Conf({
16488 let res = Some(next);
16489 let Some(val) = res else { break };
16490 val
16491 }),
16492 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16493 n => continue,
16494 };
16495 return Some(Ok(res));
16496 }
16497 Some(Err(ErrorContext::new(
16498 "IflaAttrs",
16499 r#type.and_then(|t| IflaAttrs::attr_from_type(t)),
16500 self.orig_loc,
16501 self.buf.as_ptr().wrapping_add(pos) as usize,
16502 )))
16503 }
16504}
16505impl<'a> std::fmt::Debug for IterableIflaAttrs<'_> {
16506 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16507 let mut fmt = f.debug_struct("IflaAttrs");
16508 for attr in self.clone() {
16509 let attr = match attr {
16510 Ok(a) => a,
16511 Err(err) => {
16512 fmt.finish()?;
16513 f.write_str("Err(")?;
16514 err.fmt(f)?;
16515 return f.write_str(")");
16516 }
16517 };
16518 match attr {
16519 IflaAttrs::Conf(val) => fmt.field("Conf", &val),
16520 };
16521 }
16522 fmt.finish()
16523 }
16524}
16525impl IterableIflaAttrs<'_> {
16526 pub fn lookup_attr(
16527 &self,
16528 offset: usize,
16529 missing_type: Option<u16>,
16530 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16531 let mut stack = Vec::new();
16532 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16533 if missing_type.is_some() && cur == offset {
16534 stack.push(("IflaAttrs", offset));
16535 return (
16536 stack,
16537 missing_type.and_then(|t| IflaAttrs::attr_from_type(t)),
16538 );
16539 }
16540 if cur > offset || cur + self.buf.len() < offset {
16541 return (stack, None);
16542 }
16543 let mut attrs = self.clone();
16544 let mut last_off = cur + attrs.pos;
16545 while let Some(attr) = attrs.next() {
16546 let Ok(attr) = attr else { break };
16547 match attr {
16548 IflaAttrs::Conf(val) => {
16549 if last_off == offset {
16550 stack.push(("Conf", last_off));
16551 break;
16552 }
16553 }
16554 _ => {}
16555 };
16556 last_off = cur + attrs.pos;
16557 }
16558 if !stack.is_empty() {
16559 stack.push(("IflaAttrs", cur));
16560 }
16561 (stack, None)
16562 }
16563}
16564#[derive(Clone)]
16565pub enum Ifla6Attrs<'a> {
16566 Flags(u32),
16567 #[doc = "u32 indexed by ipv6\\-devconf \\- 1 on output, on input it's a nest"]
16568 Conf(&'a [u8]),
16569 Stats(&'a [u8]),
16570 Mcast(&'a [u8]),
16571 Cacheinfo(IflaCacheinfo),
16572 Icmp6stats(&'a [u8]),
16573 Token(&'a [u8]),
16574 AddrGenMode(u8),
16575 RaMtu(u32),
16576}
16577impl<'a> IterableIfla6Attrs<'a> {
16578 pub fn get_flags(&self) -> Result<u32, ErrorContext> {
16579 let mut iter = self.clone();
16580 iter.pos = 0;
16581 for attr in iter {
16582 if let Ifla6Attrs::Flags(val) = attr? {
16583 return Ok(val);
16584 }
16585 }
16586 Err(ErrorContext::new_missing(
16587 "Ifla6Attrs",
16588 "Flags",
16589 self.orig_loc,
16590 self.buf.as_ptr() as usize,
16591 ))
16592 }
16593 #[doc = "u32 indexed by ipv6\\-devconf \\- 1 on output, on input it's a nest"]
16594 pub fn get_conf(&self) -> Result<&'a [u8], ErrorContext> {
16595 let mut iter = self.clone();
16596 iter.pos = 0;
16597 for attr in iter {
16598 if let Ifla6Attrs::Conf(val) = attr? {
16599 return Ok(val);
16600 }
16601 }
16602 Err(ErrorContext::new_missing(
16603 "Ifla6Attrs",
16604 "Conf",
16605 self.orig_loc,
16606 self.buf.as_ptr() as usize,
16607 ))
16608 }
16609 pub fn get_stats(&self) -> Result<&'a [u8], ErrorContext> {
16610 let mut iter = self.clone();
16611 iter.pos = 0;
16612 for attr in iter {
16613 if let Ifla6Attrs::Stats(val) = attr? {
16614 return Ok(val);
16615 }
16616 }
16617 Err(ErrorContext::new_missing(
16618 "Ifla6Attrs",
16619 "Stats",
16620 self.orig_loc,
16621 self.buf.as_ptr() as usize,
16622 ))
16623 }
16624 pub fn get_mcast(&self) -> Result<&'a [u8], ErrorContext> {
16625 let mut iter = self.clone();
16626 iter.pos = 0;
16627 for attr in iter {
16628 if let Ifla6Attrs::Mcast(val) = attr? {
16629 return Ok(val);
16630 }
16631 }
16632 Err(ErrorContext::new_missing(
16633 "Ifla6Attrs",
16634 "Mcast",
16635 self.orig_loc,
16636 self.buf.as_ptr() as usize,
16637 ))
16638 }
16639 pub fn get_cacheinfo(&self) -> Result<IflaCacheinfo, ErrorContext> {
16640 let mut iter = self.clone();
16641 iter.pos = 0;
16642 for attr in iter {
16643 if let Ifla6Attrs::Cacheinfo(val) = attr? {
16644 return Ok(val);
16645 }
16646 }
16647 Err(ErrorContext::new_missing(
16648 "Ifla6Attrs",
16649 "Cacheinfo",
16650 self.orig_loc,
16651 self.buf.as_ptr() as usize,
16652 ))
16653 }
16654 pub fn get_icmp6stats(&self) -> Result<&'a [u8], ErrorContext> {
16655 let mut iter = self.clone();
16656 iter.pos = 0;
16657 for attr in iter {
16658 if let Ifla6Attrs::Icmp6stats(val) = attr? {
16659 return Ok(val);
16660 }
16661 }
16662 Err(ErrorContext::new_missing(
16663 "Ifla6Attrs",
16664 "Icmp6stats",
16665 self.orig_loc,
16666 self.buf.as_ptr() as usize,
16667 ))
16668 }
16669 pub fn get_token(&self) -> Result<&'a [u8], ErrorContext> {
16670 let mut iter = self.clone();
16671 iter.pos = 0;
16672 for attr in iter {
16673 if let Ifla6Attrs::Token(val) = attr? {
16674 return Ok(val);
16675 }
16676 }
16677 Err(ErrorContext::new_missing(
16678 "Ifla6Attrs",
16679 "Token",
16680 self.orig_loc,
16681 self.buf.as_ptr() as usize,
16682 ))
16683 }
16684 pub fn get_addr_gen_mode(&self) -> Result<u8, ErrorContext> {
16685 let mut iter = self.clone();
16686 iter.pos = 0;
16687 for attr in iter {
16688 if let Ifla6Attrs::AddrGenMode(val) = attr? {
16689 return Ok(val);
16690 }
16691 }
16692 Err(ErrorContext::new_missing(
16693 "Ifla6Attrs",
16694 "AddrGenMode",
16695 self.orig_loc,
16696 self.buf.as_ptr() as usize,
16697 ))
16698 }
16699 pub fn get_ra_mtu(&self) -> Result<u32, ErrorContext> {
16700 let mut iter = self.clone();
16701 iter.pos = 0;
16702 for attr in iter {
16703 if let Ifla6Attrs::RaMtu(val) = attr? {
16704 return Ok(val);
16705 }
16706 }
16707 Err(ErrorContext::new_missing(
16708 "Ifla6Attrs",
16709 "RaMtu",
16710 self.orig_loc,
16711 self.buf.as_ptr() as usize,
16712 ))
16713 }
16714}
16715impl Ifla6Attrs<'_> {
16716 pub fn new<'a>(buf: &'a [u8]) -> IterableIfla6Attrs<'a> {
16717 IterableIfla6Attrs::with_loc(buf, buf.as_ptr() as usize)
16718 }
16719 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16720 let res = match r#type {
16721 1u16 => "Flags",
16722 2u16 => "Conf",
16723 3u16 => "Stats",
16724 4u16 => "Mcast",
16725 5u16 => "Cacheinfo",
16726 6u16 => "Icmp6stats",
16727 7u16 => "Token",
16728 8u16 => "AddrGenMode",
16729 9u16 => "RaMtu",
16730 _ => return None,
16731 };
16732 Some(res)
16733 }
16734}
16735#[derive(Clone, Copy, Default)]
16736pub struct IterableIfla6Attrs<'a> {
16737 buf: &'a [u8],
16738 pos: usize,
16739 orig_loc: usize,
16740}
16741impl<'a> IterableIfla6Attrs<'a> {
16742 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16743 Self {
16744 buf,
16745 pos: 0,
16746 orig_loc,
16747 }
16748 }
16749 pub fn get_buf(&self) -> &'a [u8] {
16750 self.buf
16751 }
16752}
16753impl<'a> Iterator for IterableIfla6Attrs<'a> {
16754 type Item = Result<Ifla6Attrs<'a>, ErrorContext>;
16755 fn next(&mut self) -> Option<Self::Item> {
16756 let pos = self.pos;
16757 let mut r#type;
16758 loop {
16759 r#type = None;
16760 if self.buf.len() == self.pos {
16761 return None;
16762 }
16763 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
16764 break;
16765 };
16766 r#type = Some(header.r#type);
16767 let res = match header.r#type {
16768 1u16 => Ifla6Attrs::Flags({
16769 let res = parse_u32(next);
16770 let Some(val) = res else { break };
16771 val
16772 }),
16773 2u16 => Ifla6Attrs::Conf({
16774 let res = Some(next);
16775 let Some(val) = res else { break };
16776 val
16777 }),
16778 3u16 => Ifla6Attrs::Stats({
16779 let res = Some(next);
16780 let Some(val) = res else { break };
16781 val
16782 }),
16783 4u16 => Ifla6Attrs::Mcast({
16784 let res = Some(next);
16785 let Some(val) = res else { break };
16786 val
16787 }),
16788 5u16 => Ifla6Attrs::Cacheinfo({
16789 let res = Some(IflaCacheinfo::new_from_zeroed(next));
16790 let Some(val) = res else { break };
16791 val
16792 }),
16793 6u16 => Ifla6Attrs::Icmp6stats({
16794 let res = Some(next);
16795 let Some(val) = res else { break };
16796 val
16797 }),
16798 7u16 => Ifla6Attrs::Token({
16799 let res = Some(next);
16800 let Some(val) = res else { break };
16801 val
16802 }),
16803 8u16 => Ifla6Attrs::AddrGenMode({
16804 let res = parse_u8(next);
16805 let Some(val) = res else { break };
16806 val
16807 }),
16808 9u16 => Ifla6Attrs::RaMtu({
16809 let res = parse_u32(next);
16810 let Some(val) = res else { break };
16811 val
16812 }),
16813 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
16814 n => continue,
16815 };
16816 return Some(Ok(res));
16817 }
16818 Some(Err(ErrorContext::new(
16819 "Ifla6Attrs",
16820 r#type.and_then(|t| Ifla6Attrs::attr_from_type(t)),
16821 self.orig_loc,
16822 self.buf.as_ptr().wrapping_add(pos) as usize,
16823 )))
16824 }
16825}
16826impl<'a> std::fmt::Debug for IterableIfla6Attrs<'_> {
16827 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16828 let mut fmt = f.debug_struct("Ifla6Attrs");
16829 for attr in self.clone() {
16830 let attr = match attr {
16831 Ok(a) => a,
16832 Err(err) => {
16833 fmt.finish()?;
16834 f.write_str("Err(")?;
16835 err.fmt(f)?;
16836 return f.write_str(")");
16837 }
16838 };
16839 match attr {
16840 Ifla6Attrs::Flags(val) => fmt.field("Flags", &val),
16841 Ifla6Attrs::Conf(val) => fmt.field("Conf", &val),
16842 Ifla6Attrs::Stats(val) => fmt.field("Stats", &val),
16843 Ifla6Attrs::Mcast(val) => fmt.field("Mcast", &val),
16844 Ifla6Attrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
16845 Ifla6Attrs::Icmp6stats(val) => fmt.field("Icmp6stats", &val),
16846 Ifla6Attrs::Token(val) => fmt.field("Token", &val),
16847 Ifla6Attrs::AddrGenMode(val) => fmt.field("AddrGenMode", &val),
16848 Ifla6Attrs::RaMtu(val) => fmt.field("RaMtu", &val),
16849 };
16850 }
16851 fmt.finish()
16852 }
16853}
16854impl IterableIfla6Attrs<'_> {
16855 pub fn lookup_attr(
16856 &self,
16857 offset: usize,
16858 missing_type: Option<u16>,
16859 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
16860 let mut stack = Vec::new();
16861 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
16862 if missing_type.is_some() && cur == offset {
16863 stack.push(("Ifla6Attrs", offset));
16864 return (
16865 stack,
16866 missing_type.and_then(|t| Ifla6Attrs::attr_from_type(t)),
16867 );
16868 }
16869 if cur > offset || cur + self.buf.len() < offset {
16870 return (stack, None);
16871 }
16872 let mut attrs = self.clone();
16873 let mut last_off = cur + attrs.pos;
16874 while let Some(attr) = attrs.next() {
16875 let Ok(attr) = attr else { break };
16876 match attr {
16877 Ifla6Attrs::Flags(val) => {
16878 if last_off == offset {
16879 stack.push(("Flags", last_off));
16880 break;
16881 }
16882 }
16883 Ifla6Attrs::Conf(val) => {
16884 if last_off == offset {
16885 stack.push(("Conf", last_off));
16886 break;
16887 }
16888 }
16889 Ifla6Attrs::Stats(val) => {
16890 if last_off == offset {
16891 stack.push(("Stats", last_off));
16892 break;
16893 }
16894 }
16895 Ifla6Attrs::Mcast(val) => {
16896 if last_off == offset {
16897 stack.push(("Mcast", last_off));
16898 break;
16899 }
16900 }
16901 Ifla6Attrs::Cacheinfo(val) => {
16902 if last_off == offset {
16903 stack.push(("Cacheinfo", last_off));
16904 break;
16905 }
16906 }
16907 Ifla6Attrs::Icmp6stats(val) => {
16908 if last_off == offset {
16909 stack.push(("Icmp6stats", last_off));
16910 break;
16911 }
16912 }
16913 Ifla6Attrs::Token(val) => {
16914 if last_off == offset {
16915 stack.push(("Token", last_off));
16916 break;
16917 }
16918 }
16919 Ifla6Attrs::AddrGenMode(val) => {
16920 if last_off == offset {
16921 stack.push(("AddrGenMode", last_off));
16922 break;
16923 }
16924 }
16925 Ifla6Attrs::RaMtu(val) => {
16926 if last_off == offset {
16927 stack.push(("RaMtu", last_off));
16928 break;
16929 }
16930 }
16931 _ => {}
16932 };
16933 last_off = cur + attrs.pos;
16934 }
16935 if !stack.is_empty() {
16936 stack.push(("Ifla6Attrs", cur));
16937 }
16938 (stack, None)
16939 }
16940}
16941#[derive(Clone)]
16942pub enum MctpAttrs {
16943 Net(u32),
16944 PhysBinding(u8),
16945}
16946impl<'a> IterableMctpAttrs<'a> {
16947 pub fn get_net(&self) -> Result<u32, ErrorContext> {
16948 let mut iter = self.clone();
16949 iter.pos = 0;
16950 for attr in iter {
16951 if let MctpAttrs::Net(val) = attr? {
16952 return Ok(val);
16953 }
16954 }
16955 Err(ErrorContext::new_missing(
16956 "MctpAttrs",
16957 "Net",
16958 self.orig_loc,
16959 self.buf.as_ptr() as usize,
16960 ))
16961 }
16962 pub fn get_phys_binding(&self) -> Result<u8, ErrorContext> {
16963 let mut iter = self.clone();
16964 iter.pos = 0;
16965 for attr in iter {
16966 if let MctpAttrs::PhysBinding(val) = attr? {
16967 return Ok(val);
16968 }
16969 }
16970 Err(ErrorContext::new_missing(
16971 "MctpAttrs",
16972 "PhysBinding",
16973 self.orig_loc,
16974 self.buf.as_ptr() as usize,
16975 ))
16976 }
16977}
16978impl MctpAttrs {
16979 pub fn new<'a>(buf: &'a [u8]) -> IterableMctpAttrs<'a> {
16980 IterableMctpAttrs::with_loc(buf, buf.as_ptr() as usize)
16981 }
16982 fn attr_from_type(r#type: u16) -> Option<&'static str> {
16983 let res = match r#type {
16984 1u16 => "Net",
16985 2u16 => "PhysBinding",
16986 _ => return None,
16987 };
16988 Some(res)
16989 }
16990}
16991#[derive(Clone, Copy, Default)]
16992pub struct IterableMctpAttrs<'a> {
16993 buf: &'a [u8],
16994 pos: usize,
16995 orig_loc: usize,
16996}
16997impl<'a> IterableMctpAttrs<'a> {
16998 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
16999 Self {
17000 buf,
17001 pos: 0,
17002 orig_loc,
17003 }
17004 }
17005 pub fn get_buf(&self) -> &'a [u8] {
17006 self.buf
17007 }
17008}
17009impl<'a> Iterator for IterableMctpAttrs<'a> {
17010 type Item = Result<MctpAttrs, ErrorContext>;
17011 fn next(&mut self) -> Option<Self::Item> {
17012 let pos = self.pos;
17013 let mut r#type;
17014 loop {
17015 r#type = None;
17016 if self.buf.len() == self.pos {
17017 return None;
17018 }
17019 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17020 break;
17021 };
17022 r#type = Some(header.r#type);
17023 let res = match header.r#type {
17024 1u16 => MctpAttrs::Net({
17025 let res = parse_u32(next);
17026 let Some(val) = res else { break };
17027 val
17028 }),
17029 2u16 => MctpAttrs::PhysBinding({
17030 let res = parse_u8(next);
17031 let Some(val) = res else { break };
17032 val
17033 }),
17034 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17035 n => continue,
17036 };
17037 return Some(Ok(res));
17038 }
17039 Some(Err(ErrorContext::new(
17040 "MctpAttrs",
17041 r#type.and_then(|t| MctpAttrs::attr_from_type(t)),
17042 self.orig_loc,
17043 self.buf.as_ptr().wrapping_add(pos) as usize,
17044 )))
17045 }
17046}
17047impl std::fmt::Debug for IterableMctpAttrs<'_> {
17048 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17049 let mut fmt = f.debug_struct("MctpAttrs");
17050 for attr in self.clone() {
17051 let attr = match attr {
17052 Ok(a) => a,
17053 Err(err) => {
17054 fmt.finish()?;
17055 f.write_str("Err(")?;
17056 err.fmt(f)?;
17057 return f.write_str(")");
17058 }
17059 };
17060 match attr {
17061 MctpAttrs::Net(val) => fmt.field("Net", &val),
17062 MctpAttrs::PhysBinding(val) => fmt.field("PhysBinding", &val),
17063 };
17064 }
17065 fmt.finish()
17066 }
17067}
17068impl IterableMctpAttrs<'_> {
17069 pub fn lookup_attr(
17070 &self,
17071 offset: usize,
17072 missing_type: Option<u16>,
17073 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17074 let mut stack = Vec::new();
17075 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17076 if missing_type.is_some() && cur == offset {
17077 stack.push(("MctpAttrs", offset));
17078 return (
17079 stack,
17080 missing_type.and_then(|t| MctpAttrs::attr_from_type(t)),
17081 );
17082 }
17083 if cur > offset || cur + self.buf.len() < offset {
17084 return (stack, None);
17085 }
17086 let mut attrs = self.clone();
17087 let mut last_off = cur + attrs.pos;
17088 while let Some(attr) = attrs.next() {
17089 let Ok(attr) = attr else { break };
17090 match attr {
17091 MctpAttrs::Net(val) => {
17092 if last_off == offset {
17093 stack.push(("Net", last_off));
17094 break;
17095 }
17096 }
17097 MctpAttrs::PhysBinding(val) => {
17098 if last_off == offset {
17099 stack.push(("PhysBinding", last_off));
17100 break;
17101 }
17102 }
17103 _ => {}
17104 };
17105 last_off = cur + attrs.pos;
17106 }
17107 if !stack.is_empty() {
17108 stack.push(("MctpAttrs", cur));
17109 }
17110 (stack, None)
17111 }
17112}
17113#[derive(Clone)]
17114pub enum StatsAttrs<'a> {
17115 Link64(RtnlLinkStats64),
17116 LinkXstats(&'a [u8]),
17117 LinkXstatsSlave(&'a [u8]),
17118 LinkOffloadXstats(IterableLinkOffloadXstats<'a>),
17119 AfSpec(&'a [u8]),
17120}
17121impl<'a> IterableStatsAttrs<'a> {
17122 pub fn get_link_64(&self) -> Result<RtnlLinkStats64, ErrorContext> {
17123 let mut iter = self.clone();
17124 iter.pos = 0;
17125 for attr in iter {
17126 if let StatsAttrs::Link64(val) = attr? {
17127 return Ok(val);
17128 }
17129 }
17130 Err(ErrorContext::new_missing(
17131 "StatsAttrs",
17132 "Link64",
17133 self.orig_loc,
17134 self.buf.as_ptr() as usize,
17135 ))
17136 }
17137 pub fn get_link_xstats(&self) -> Result<&'a [u8], ErrorContext> {
17138 let mut iter = self.clone();
17139 iter.pos = 0;
17140 for attr in iter {
17141 if let StatsAttrs::LinkXstats(val) = attr? {
17142 return Ok(val);
17143 }
17144 }
17145 Err(ErrorContext::new_missing(
17146 "StatsAttrs",
17147 "LinkXstats",
17148 self.orig_loc,
17149 self.buf.as_ptr() as usize,
17150 ))
17151 }
17152 pub fn get_link_xstats_slave(&self) -> Result<&'a [u8], ErrorContext> {
17153 let mut iter = self.clone();
17154 iter.pos = 0;
17155 for attr in iter {
17156 if let StatsAttrs::LinkXstatsSlave(val) = attr? {
17157 return Ok(val);
17158 }
17159 }
17160 Err(ErrorContext::new_missing(
17161 "StatsAttrs",
17162 "LinkXstatsSlave",
17163 self.orig_loc,
17164 self.buf.as_ptr() as usize,
17165 ))
17166 }
17167 pub fn get_link_offload_xstats(&self) -> Result<IterableLinkOffloadXstats<'a>, ErrorContext> {
17168 let mut iter = self.clone();
17169 iter.pos = 0;
17170 for attr in iter {
17171 if let StatsAttrs::LinkOffloadXstats(val) = attr? {
17172 return Ok(val);
17173 }
17174 }
17175 Err(ErrorContext::new_missing(
17176 "StatsAttrs",
17177 "LinkOffloadXstats",
17178 self.orig_loc,
17179 self.buf.as_ptr() as usize,
17180 ))
17181 }
17182 pub fn get_af_spec(&self) -> Result<&'a [u8], ErrorContext> {
17183 let mut iter = self.clone();
17184 iter.pos = 0;
17185 for attr in iter {
17186 if let StatsAttrs::AfSpec(val) = attr? {
17187 return Ok(val);
17188 }
17189 }
17190 Err(ErrorContext::new_missing(
17191 "StatsAttrs",
17192 "AfSpec",
17193 self.orig_loc,
17194 self.buf.as_ptr() as usize,
17195 ))
17196 }
17197}
17198impl StatsAttrs<'_> {
17199 pub fn new<'a>(buf: &'a [u8]) -> IterableStatsAttrs<'a> {
17200 IterableStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
17201 }
17202 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17203 let res = match r#type {
17204 1u16 => "Link64",
17205 2u16 => "LinkXstats",
17206 3u16 => "LinkXstatsSlave",
17207 4u16 => "LinkOffloadXstats",
17208 5u16 => "AfSpec",
17209 _ => return None,
17210 };
17211 Some(res)
17212 }
17213}
17214#[derive(Clone, Copy, Default)]
17215pub struct IterableStatsAttrs<'a> {
17216 buf: &'a [u8],
17217 pos: usize,
17218 orig_loc: usize,
17219}
17220impl<'a> IterableStatsAttrs<'a> {
17221 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17222 Self {
17223 buf,
17224 pos: 0,
17225 orig_loc,
17226 }
17227 }
17228 pub fn get_buf(&self) -> &'a [u8] {
17229 self.buf
17230 }
17231}
17232impl<'a> Iterator for IterableStatsAttrs<'a> {
17233 type Item = Result<StatsAttrs<'a>, ErrorContext>;
17234 fn next(&mut self) -> Option<Self::Item> {
17235 let pos = self.pos;
17236 let mut r#type;
17237 loop {
17238 r#type = None;
17239 if self.buf.len() == self.pos {
17240 return None;
17241 }
17242 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17243 break;
17244 };
17245 r#type = Some(header.r#type);
17246 let res = match header.r#type {
17247 1u16 => StatsAttrs::Link64({
17248 let res = Some(RtnlLinkStats64::new_from_zeroed(next));
17249 let Some(val) = res else { break };
17250 val
17251 }),
17252 2u16 => StatsAttrs::LinkXstats({
17253 let res = Some(next);
17254 let Some(val) = res else { break };
17255 val
17256 }),
17257 3u16 => StatsAttrs::LinkXstatsSlave({
17258 let res = Some(next);
17259 let Some(val) = res else { break };
17260 val
17261 }),
17262 4u16 => StatsAttrs::LinkOffloadXstats({
17263 let res = Some(IterableLinkOffloadXstats::with_loc(next, self.orig_loc));
17264 let Some(val) = res else { break };
17265 val
17266 }),
17267 5u16 => StatsAttrs::AfSpec({
17268 let res = Some(next);
17269 let Some(val) = res else { break };
17270 val
17271 }),
17272 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17273 n => continue,
17274 };
17275 return Some(Ok(res));
17276 }
17277 Some(Err(ErrorContext::new(
17278 "StatsAttrs",
17279 r#type.and_then(|t| StatsAttrs::attr_from_type(t)),
17280 self.orig_loc,
17281 self.buf.as_ptr().wrapping_add(pos) as usize,
17282 )))
17283 }
17284}
17285impl<'a> std::fmt::Debug for IterableStatsAttrs<'_> {
17286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17287 let mut fmt = f.debug_struct("StatsAttrs");
17288 for attr in self.clone() {
17289 let attr = match attr {
17290 Ok(a) => a,
17291 Err(err) => {
17292 fmt.finish()?;
17293 f.write_str("Err(")?;
17294 err.fmt(f)?;
17295 return f.write_str(")");
17296 }
17297 };
17298 match attr {
17299 StatsAttrs::Link64(val) => fmt.field("Link64", &val),
17300 StatsAttrs::LinkXstats(val) => fmt.field("LinkXstats", &val),
17301 StatsAttrs::LinkXstatsSlave(val) => fmt.field("LinkXstatsSlave", &val),
17302 StatsAttrs::LinkOffloadXstats(val) => fmt.field("LinkOffloadXstats", &val),
17303 StatsAttrs::AfSpec(val) => fmt.field("AfSpec", &val),
17304 };
17305 }
17306 fmt.finish()
17307 }
17308}
17309impl IterableStatsAttrs<'_> {
17310 pub fn lookup_attr(
17311 &self,
17312 offset: usize,
17313 missing_type: Option<u16>,
17314 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17315 let mut stack = Vec::new();
17316 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17317 if missing_type.is_some() && cur == offset {
17318 stack.push(("StatsAttrs", offset));
17319 return (
17320 stack,
17321 missing_type.and_then(|t| StatsAttrs::attr_from_type(t)),
17322 );
17323 }
17324 if cur > offset || cur + self.buf.len() < offset {
17325 return (stack, None);
17326 }
17327 let mut attrs = self.clone();
17328 let mut last_off = cur + attrs.pos;
17329 let mut missing = None;
17330 while let Some(attr) = attrs.next() {
17331 let Ok(attr) = attr else { break };
17332 match attr {
17333 StatsAttrs::Link64(val) => {
17334 if last_off == offset {
17335 stack.push(("Link64", last_off));
17336 break;
17337 }
17338 }
17339 StatsAttrs::LinkXstats(val) => {
17340 if last_off == offset {
17341 stack.push(("LinkXstats", last_off));
17342 break;
17343 }
17344 }
17345 StatsAttrs::LinkXstatsSlave(val) => {
17346 if last_off == offset {
17347 stack.push(("LinkXstatsSlave", last_off));
17348 break;
17349 }
17350 }
17351 StatsAttrs::LinkOffloadXstats(val) => {
17352 (stack, missing) = val.lookup_attr(offset, missing_type);
17353 if !stack.is_empty() {
17354 break;
17355 }
17356 }
17357 StatsAttrs::AfSpec(val) => {
17358 if last_off == offset {
17359 stack.push(("AfSpec", last_off));
17360 break;
17361 }
17362 }
17363 _ => {}
17364 };
17365 last_off = cur + attrs.pos;
17366 }
17367 if !stack.is_empty() {
17368 stack.push(("StatsAttrs", cur));
17369 }
17370 (stack, missing)
17371 }
17372}
17373#[derive(Clone)]
17374pub enum LinkOffloadXstats<'a> {
17375 CpuHit(&'a [u8]),
17376 HwSInfo(IterableArrayHwSInfoOne<'a>),
17377 L3Stats(&'a [u8]),
17378}
17379impl<'a> IterableLinkOffloadXstats<'a> {
17380 pub fn get_cpu_hit(&self) -> Result<&'a [u8], ErrorContext> {
17381 let mut iter = self.clone();
17382 iter.pos = 0;
17383 for attr in iter {
17384 if let LinkOffloadXstats::CpuHit(val) = attr? {
17385 return Ok(val);
17386 }
17387 }
17388 Err(ErrorContext::new_missing(
17389 "LinkOffloadXstats",
17390 "CpuHit",
17391 self.orig_loc,
17392 self.buf.as_ptr() as usize,
17393 ))
17394 }
17395 pub fn get_hw_s_info(
17396 &self,
17397 ) -> Result<ArrayIterable<IterableArrayHwSInfoOne<'a>, IterableHwSInfoOne<'a>>, ErrorContext>
17398 {
17399 for attr in self.clone() {
17400 if let LinkOffloadXstats::HwSInfo(val) = attr? {
17401 return Ok(ArrayIterable::new(val));
17402 }
17403 }
17404 Err(ErrorContext::new_missing(
17405 "LinkOffloadXstats",
17406 "HwSInfo",
17407 self.orig_loc,
17408 self.buf.as_ptr() as usize,
17409 ))
17410 }
17411 pub fn get_l3_stats(&self) -> Result<&'a [u8], ErrorContext> {
17412 let mut iter = self.clone();
17413 iter.pos = 0;
17414 for attr in iter {
17415 if let LinkOffloadXstats::L3Stats(val) = attr? {
17416 return Ok(val);
17417 }
17418 }
17419 Err(ErrorContext::new_missing(
17420 "LinkOffloadXstats",
17421 "L3Stats",
17422 self.orig_loc,
17423 self.buf.as_ptr() as usize,
17424 ))
17425 }
17426}
17427impl HwSInfoOne {
17428 pub fn new_array(buf: &[u8]) -> IterableArrayHwSInfoOne<'_> {
17429 IterableArrayHwSInfoOne::with_loc(buf, buf.as_ptr() as usize)
17430 }
17431}
17432#[derive(Clone, Copy, Default)]
17433pub struct IterableArrayHwSInfoOne<'a> {
17434 buf: &'a [u8],
17435 pos: usize,
17436 orig_loc: usize,
17437}
17438impl<'a> IterableArrayHwSInfoOne<'a> {
17439 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17440 Self {
17441 buf,
17442 pos: 0,
17443 orig_loc,
17444 }
17445 }
17446 pub fn get_buf(&self) -> &'a [u8] {
17447 self.buf
17448 }
17449}
17450impl<'a> Iterator for IterableArrayHwSInfoOne<'a> {
17451 type Item = Result<IterableHwSInfoOne<'a>, ErrorContext>;
17452 fn next(&mut self) -> Option<Self::Item> {
17453 if self.buf.len() == self.pos {
17454 return None;
17455 }
17456 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
17457 {
17458 return Some(Ok(IterableHwSInfoOne::with_loc(next, self.orig_loc)));
17459 }
17460 }
17461 Some(Err(ErrorContext::new(
17462 "HwSInfoOne",
17463 None,
17464 self.orig_loc,
17465 self.buf.as_ptr().wrapping_add(self.pos) as usize,
17466 )))
17467 }
17468}
17469impl LinkOffloadXstats<'_> {
17470 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkOffloadXstats<'a> {
17471 IterableLinkOffloadXstats::with_loc(buf, buf.as_ptr() as usize)
17472 }
17473 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17474 let res = match r#type {
17475 1u16 => "CpuHit",
17476 2u16 => "HwSInfo",
17477 3u16 => "L3Stats",
17478 _ => return None,
17479 };
17480 Some(res)
17481 }
17482}
17483#[derive(Clone, Copy, Default)]
17484pub struct IterableLinkOffloadXstats<'a> {
17485 buf: &'a [u8],
17486 pos: usize,
17487 orig_loc: usize,
17488}
17489impl<'a> IterableLinkOffloadXstats<'a> {
17490 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17491 Self {
17492 buf,
17493 pos: 0,
17494 orig_loc,
17495 }
17496 }
17497 pub fn get_buf(&self) -> &'a [u8] {
17498 self.buf
17499 }
17500}
17501impl<'a> Iterator for IterableLinkOffloadXstats<'a> {
17502 type Item = Result<LinkOffloadXstats<'a>, ErrorContext>;
17503 fn next(&mut self) -> Option<Self::Item> {
17504 let pos = self.pos;
17505 let mut r#type;
17506 loop {
17507 r#type = None;
17508 if self.buf.len() == self.pos {
17509 return None;
17510 }
17511 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17512 break;
17513 };
17514 r#type = Some(header.r#type);
17515 let res = match header.r#type {
17516 1u16 => LinkOffloadXstats::CpuHit({
17517 let res = Some(next);
17518 let Some(val) = res else { break };
17519 val
17520 }),
17521 2u16 => LinkOffloadXstats::HwSInfo({
17522 let res = Some(IterableArrayHwSInfoOne::with_loc(next, self.orig_loc));
17523 let Some(val) = res else { break };
17524 val
17525 }),
17526 3u16 => LinkOffloadXstats::L3Stats({
17527 let res = Some(next);
17528 let Some(val) = res else { break };
17529 val
17530 }),
17531 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17532 n => continue,
17533 };
17534 return Some(Ok(res));
17535 }
17536 Some(Err(ErrorContext::new(
17537 "LinkOffloadXstats",
17538 r#type.and_then(|t| LinkOffloadXstats::attr_from_type(t)),
17539 self.orig_loc,
17540 self.buf.as_ptr().wrapping_add(pos) as usize,
17541 )))
17542 }
17543}
17544impl std::fmt::Debug for IterableArrayHwSInfoOne<'_> {
17545 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17546 fmt.debug_list()
17547 .entries(self.clone().map(FlattenErrorContext))
17548 .finish()
17549 }
17550}
17551impl<'a> std::fmt::Debug for IterableLinkOffloadXstats<'_> {
17552 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17553 let mut fmt = f.debug_struct("LinkOffloadXstats");
17554 for attr in self.clone() {
17555 let attr = match attr {
17556 Ok(a) => a,
17557 Err(err) => {
17558 fmt.finish()?;
17559 f.write_str("Err(")?;
17560 err.fmt(f)?;
17561 return f.write_str(")");
17562 }
17563 };
17564 match attr {
17565 LinkOffloadXstats::CpuHit(val) => fmt.field("CpuHit", &val),
17566 LinkOffloadXstats::HwSInfo(val) => fmt.field("HwSInfo", &val),
17567 LinkOffloadXstats::L3Stats(val) => fmt.field("L3Stats", &val),
17568 };
17569 }
17570 fmt.finish()
17571 }
17572}
17573impl IterableLinkOffloadXstats<'_> {
17574 pub fn lookup_attr(
17575 &self,
17576 offset: usize,
17577 missing_type: Option<u16>,
17578 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17579 let mut stack = Vec::new();
17580 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17581 if missing_type.is_some() && cur == offset {
17582 stack.push(("LinkOffloadXstats", offset));
17583 return (
17584 stack,
17585 missing_type.and_then(|t| LinkOffloadXstats::attr_from_type(t)),
17586 );
17587 }
17588 if cur > offset || cur + self.buf.len() < offset {
17589 return (stack, None);
17590 }
17591 let mut attrs = self.clone();
17592 let mut last_off = cur + attrs.pos;
17593 let mut missing = None;
17594 while let Some(attr) = attrs.next() {
17595 let Ok(attr) = attr else { break };
17596 match attr {
17597 LinkOffloadXstats::CpuHit(val) => {
17598 if last_off == offset {
17599 stack.push(("CpuHit", last_off));
17600 break;
17601 }
17602 }
17603 LinkOffloadXstats::HwSInfo(val) => {
17604 for entry in val {
17605 let Ok(attr) = entry else { break };
17606 (stack, missing) = attr.lookup_attr(offset, missing_type);
17607 if !stack.is_empty() {
17608 break;
17609 }
17610 }
17611 if !stack.is_empty() {
17612 stack.push(("HwSInfo", last_off));
17613 break;
17614 }
17615 }
17616 LinkOffloadXstats::L3Stats(val) => {
17617 if last_off == offset {
17618 stack.push(("L3Stats", last_off));
17619 break;
17620 }
17621 }
17622 _ => {}
17623 };
17624 last_off = cur + attrs.pos;
17625 }
17626 if !stack.is_empty() {
17627 stack.push(("LinkOffloadXstats", cur));
17628 }
17629 (stack, missing)
17630 }
17631}
17632#[derive(Clone)]
17633pub enum HwSInfoOne {
17634 Request(u8),
17635 Used(u8),
17636}
17637impl<'a> IterableHwSInfoOne<'a> {
17638 pub fn get_request(&self) -> Result<u8, ErrorContext> {
17639 let mut iter = self.clone();
17640 iter.pos = 0;
17641 for attr in iter {
17642 if let HwSInfoOne::Request(val) = attr? {
17643 return Ok(val);
17644 }
17645 }
17646 Err(ErrorContext::new_missing(
17647 "HwSInfoOne",
17648 "Request",
17649 self.orig_loc,
17650 self.buf.as_ptr() as usize,
17651 ))
17652 }
17653 pub fn get_used(&self) -> Result<u8, ErrorContext> {
17654 let mut iter = self.clone();
17655 iter.pos = 0;
17656 for attr in iter {
17657 if let HwSInfoOne::Used(val) = attr? {
17658 return Ok(val);
17659 }
17660 }
17661 Err(ErrorContext::new_missing(
17662 "HwSInfoOne",
17663 "Used",
17664 self.orig_loc,
17665 self.buf.as_ptr() as usize,
17666 ))
17667 }
17668}
17669impl HwSInfoOne {
17670 pub fn new<'a>(buf: &'a [u8]) -> IterableHwSInfoOne<'a> {
17671 IterableHwSInfoOne::with_loc(buf, buf.as_ptr() as usize)
17672 }
17673 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17674 let res = match r#type {
17675 1u16 => "Request",
17676 2u16 => "Used",
17677 _ => return None,
17678 };
17679 Some(res)
17680 }
17681}
17682#[derive(Clone, Copy, Default)]
17683pub struct IterableHwSInfoOne<'a> {
17684 buf: &'a [u8],
17685 pos: usize,
17686 orig_loc: usize,
17687}
17688impl<'a> IterableHwSInfoOne<'a> {
17689 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17690 Self {
17691 buf,
17692 pos: 0,
17693 orig_loc,
17694 }
17695 }
17696 pub fn get_buf(&self) -> &'a [u8] {
17697 self.buf
17698 }
17699}
17700impl<'a> Iterator for IterableHwSInfoOne<'a> {
17701 type Item = Result<HwSInfoOne, ErrorContext>;
17702 fn next(&mut self) -> Option<Self::Item> {
17703 let pos = self.pos;
17704 let mut r#type;
17705 loop {
17706 r#type = None;
17707 if self.buf.len() == self.pos {
17708 return None;
17709 }
17710 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17711 break;
17712 };
17713 r#type = Some(header.r#type);
17714 let res = match header.r#type {
17715 1u16 => HwSInfoOne::Request({
17716 let res = parse_u8(next);
17717 let Some(val) = res else { break };
17718 val
17719 }),
17720 2u16 => HwSInfoOne::Used({
17721 let res = parse_u8(next);
17722 let Some(val) = res else { break };
17723 val
17724 }),
17725 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17726 n => continue,
17727 };
17728 return Some(Ok(res));
17729 }
17730 Some(Err(ErrorContext::new(
17731 "HwSInfoOne",
17732 r#type.and_then(|t| HwSInfoOne::attr_from_type(t)),
17733 self.orig_loc,
17734 self.buf.as_ptr().wrapping_add(pos) as usize,
17735 )))
17736 }
17737}
17738impl std::fmt::Debug for IterableHwSInfoOne<'_> {
17739 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17740 let mut fmt = f.debug_struct("HwSInfoOne");
17741 for attr in self.clone() {
17742 let attr = match attr {
17743 Ok(a) => a,
17744 Err(err) => {
17745 fmt.finish()?;
17746 f.write_str("Err(")?;
17747 err.fmt(f)?;
17748 return f.write_str(")");
17749 }
17750 };
17751 match attr {
17752 HwSInfoOne::Request(val) => fmt.field("Request", &val),
17753 HwSInfoOne::Used(val) => fmt.field("Used", &val),
17754 };
17755 }
17756 fmt.finish()
17757 }
17758}
17759impl IterableHwSInfoOne<'_> {
17760 pub fn lookup_attr(
17761 &self,
17762 offset: usize,
17763 missing_type: Option<u16>,
17764 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17765 let mut stack = Vec::new();
17766 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17767 if missing_type.is_some() && cur == offset {
17768 stack.push(("HwSInfoOne", offset));
17769 return (
17770 stack,
17771 missing_type.and_then(|t| HwSInfoOne::attr_from_type(t)),
17772 );
17773 }
17774 if cur > offset || cur + self.buf.len() < offset {
17775 return (stack, None);
17776 }
17777 let mut attrs = self.clone();
17778 let mut last_off = cur + attrs.pos;
17779 while let Some(attr) = attrs.next() {
17780 let Ok(attr) = attr else { break };
17781 match attr {
17782 HwSInfoOne::Request(val) => {
17783 if last_off == offset {
17784 stack.push(("Request", last_off));
17785 break;
17786 }
17787 }
17788 HwSInfoOne::Used(val) => {
17789 if last_off == offset {
17790 stack.push(("Used", last_off));
17791 break;
17792 }
17793 }
17794 _ => {}
17795 };
17796 last_off = cur + attrs.pos;
17797 }
17798 if !stack.is_empty() {
17799 stack.push(("HwSInfoOne", cur));
17800 }
17801 (stack, None)
17802 }
17803}
17804#[derive(Clone)]
17805pub enum LinkDpllPinAttrs {
17806 Id(u32),
17807}
17808impl<'a> IterableLinkDpllPinAttrs<'a> {
17809 pub fn get_id(&self) -> Result<u32, ErrorContext> {
17810 let mut iter = self.clone();
17811 iter.pos = 0;
17812 for attr in iter {
17813 if let LinkDpllPinAttrs::Id(val) = attr? {
17814 return Ok(val);
17815 }
17816 }
17817 Err(ErrorContext::new_missing(
17818 "LinkDpllPinAttrs",
17819 "Id",
17820 self.orig_loc,
17821 self.buf.as_ptr() as usize,
17822 ))
17823 }
17824}
17825impl LinkDpllPinAttrs {
17826 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkDpllPinAttrs<'a> {
17827 IterableLinkDpllPinAttrs::with_loc(buf, buf.as_ptr() as usize)
17828 }
17829 fn attr_from_type(r#type: u16) -> Option<&'static str> {
17830 let res = match r#type {
17831 1u16 => "Id",
17832 _ => return None,
17833 };
17834 Some(res)
17835 }
17836}
17837#[derive(Clone, Copy, Default)]
17838pub struct IterableLinkDpllPinAttrs<'a> {
17839 buf: &'a [u8],
17840 pos: usize,
17841 orig_loc: usize,
17842}
17843impl<'a> IterableLinkDpllPinAttrs<'a> {
17844 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
17845 Self {
17846 buf,
17847 pos: 0,
17848 orig_loc,
17849 }
17850 }
17851 pub fn get_buf(&self) -> &'a [u8] {
17852 self.buf
17853 }
17854}
17855impl<'a> Iterator for IterableLinkDpllPinAttrs<'a> {
17856 type Item = Result<LinkDpllPinAttrs, ErrorContext>;
17857 fn next(&mut self) -> Option<Self::Item> {
17858 let pos = self.pos;
17859 let mut r#type;
17860 loop {
17861 r#type = None;
17862 if self.buf.len() == self.pos {
17863 return None;
17864 }
17865 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
17866 break;
17867 };
17868 r#type = Some(header.r#type);
17869 let res = match header.r#type {
17870 1u16 => LinkDpllPinAttrs::Id({
17871 let res = parse_u32(next);
17872 let Some(val) = res else { break };
17873 val
17874 }),
17875 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
17876 n => continue,
17877 };
17878 return Some(Ok(res));
17879 }
17880 Some(Err(ErrorContext::new(
17881 "LinkDpllPinAttrs",
17882 r#type.and_then(|t| LinkDpllPinAttrs::attr_from_type(t)),
17883 self.orig_loc,
17884 self.buf.as_ptr().wrapping_add(pos) as usize,
17885 )))
17886 }
17887}
17888impl std::fmt::Debug for IterableLinkDpllPinAttrs<'_> {
17889 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17890 let mut fmt = f.debug_struct("LinkDpllPinAttrs");
17891 for attr in self.clone() {
17892 let attr = match attr {
17893 Ok(a) => a,
17894 Err(err) => {
17895 fmt.finish()?;
17896 f.write_str("Err(")?;
17897 err.fmt(f)?;
17898 return f.write_str(")");
17899 }
17900 };
17901 match attr {
17902 LinkDpllPinAttrs::Id(val) => fmt.field("Id", &val),
17903 };
17904 }
17905 fmt.finish()
17906 }
17907}
17908impl IterableLinkDpllPinAttrs<'_> {
17909 pub fn lookup_attr(
17910 &self,
17911 offset: usize,
17912 missing_type: Option<u16>,
17913 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
17914 let mut stack = Vec::new();
17915 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
17916 if missing_type.is_some() && cur == offset {
17917 stack.push(("LinkDpllPinAttrs", offset));
17918 return (
17919 stack,
17920 missing_type.and_then(|t| LinkDpllPinAttrs::attr_from_type(t)),
17921 );
17922 }
17923 if cur > offset || cur + self.buf.len() < offset {
17924 return (stack, None);
17925 }
17926 let mut attrs = self.clone();
17927 let mut last_off = cur + attrs.pos;
17928 while let Some(attr) = attrs.next() {
17929 let Ok(attr) = attr else { break };
17930 match attr {
17931 LinkDpllPinAttrs::Id(val) => {
17932 if last_off == offset {
17933 stack.push(("Id", last_off));
17934 break;
17935 }
17936 }
17937 _ => {}
17938 };
17939 last_off = cur + attrs.pos;
17940 }
17941 if !stack.is_empty() {
17942 stack.push(("LinkDpllPinAttrs", cur));
17943 }
17944 (stack, None)
17945 }
17946}
17947#[derive(Clone)]
17948pub enum LinkinfoNetkitAttrs<'a> {
17949 PeerInfo(&'a [u8]),
17950 Primary(u8),
17951 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
17952 Policy(u32),
17953 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
17954 PeerPolicy(u32),
17955 #[doc = "Associated type: [`NetkitMode`] (enum)"]
17956 Mode(u32),
17957 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
17958 Scrub(u32),
17959 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
17960 PeerScrub(u32),
17961 Headroom(u16),
17962 Tailroom(u16),
17963}
17964impl<'a> IterableLinkinfoNetkitAttrs<'a> {
17965 pub fn get_peer_info(&self) -> Result<&'a [u8], ErrorContext> {
17966 let mut iter = self.clone();
17967 iter.pos = 0;
17968 for attr in iter {
17969 if let LinkinfoNetkitAttrs::PeerInfo(val) = attr? {
17970 return Ok(val);
17971 }
17972 }
17973 Err(ErrorContext::new_missing(
17974 "LinkinfoNetkitAttrs",
17975 "PeerInfo",
17976 self.orig_loc,
17977 self.buf.as_ptr() as usize,
17978 ))
17979 }
17980 pub fn get_primary(&self) -> Result<u8, ErrorContext> {
17981 let mut iter = self.clone();
17982 iter.pos = 0;
17983 for attr in iter {
17984 if let LinkinfoNetkitAttrs::Primary(val) = attr? {
17985 return Ok(val);
17986 }
17987 }
17988 Err(ErrorContext::new_missing(
17989 "LinkinfoNetkitAttrs",
17990 "Primary",
17991 self.orig_loc,
17992 self.buf.as_ptr() as usize,
17993 ))
17994 }
17995 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
17996 pub fn get_policy(&self) -> Result<u32, ErrorContext> {
17997 let mut iter = self.clone();
17998 iter.pos = 0;
17999 for attr in iter {
18000 if let LinkinfoNetkitAttrs::Policy(val) = attr? {
18001 return Ok(val);
18002 }
18003 }
18004 Err(ErrorContext::new_missing(
18005 "LinkinfoNetkitAttrs",
18006 "Policy",
18007 self.orig_loc,
18008 self.buf.as_ptr() as usize,
18009 ))
18010 }
18011 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
18012 pub fn get_peer_policy(&self) -> Result<u32, ErrorContext> {
18013 let mut iter = self.clone();
18014 iter.pos = 0;
18015 for attr in iter {
18016 if let LinkinfoNetkitAttrs::PeerPolicy(val) = attr? {
18017 return Ok(val);
18018 }
18019 }
18020 Err(ErrorContext::new_missing(
18021 "LinkinfoNetkitAttrs",
18022 "PeerPolicy",
18023 self.orig_loc,
18024 self.buf.as_ptr() as usize,
18025 ))
18026 }
18027 #[doc = "Associated type: [`NetkitMode`] (enum)"]
18028 pub fn get_mode(&self) -> Result<u32, ErrorContext> {
18029 let mut iter = self.clone();
18030 iter.pos = 0;
18031 for attr in iter {
18032 if let LinkinfoNetkitAttrs::Mode(val) = attr? {
18033 return Ok(val);
18034 }
18035 }
18036 Err(ErrorContext::new_missing(
18037 "LinkinfoNetkitAttrs",
18038 "Mode",
18039 self.orig_loc,
18040 self.buf.as_ptr() as usize,
18041 ))
18042 }
18043 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
18044 pub fn get_scrub(&self) -> Result<u32, ErrorContext> {
18045 let mut iter = self.clone();
18046 iter.pos = 0;
18047 for attr in iter {
18048 if let LinkinfoNetkitAttrs::Scrub(val) = attr? {
18049 return Ok(val);
18050 }
18051 }
18052 Err(ErrorContext::new_missing(
18053 "LinkinfoNetkitAttrs",
18054 "Scrub",
18055 self.orig_loc,
18056 self.buf.as_ptr() as usize,
18057 ))
18058 }
18059 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
18060 pub fn get_peer_scrub(&self) -> Result<u32, ErrorContext> {
18061 let mut iter = self.clone();
18062 iter.pos = 0;
18063 for attr in iter {
18064 if let LinkinfoNetkitAttrs::PeerScrub(val) = attr? {
18065 return Ok(val);
18066 }
18067 }
18068 Err(ErrorContext::new_missing(
18069 "LinkinfoNetkitAttrs",
18070 "PeerScrub",
18071 self.orig_loc,
18072 self.buf.as_ptr() as usize,
18073 ))
18074 }
18075 pub fn get_headroom(&self) -> Result<u16, ErrorContext> {
18076 let mut iter = self.clone();
18077 iter.pos = 0;
18078 for attr in iter {
18079 if let LinkinfoNetkitAttrs::Headroom(val) = attr? {
18080 return Ok(val);
18081 }
18082 }
18083 Err(ErrorContext::new_missing(
18084 "LinkinfoNetkitAttrs",
18085 "Headroom",
18086 self.orig_loc,
18087 self.buf.as_ptr() as usize,
18088 ))
18089 }
18090 pub fn get_tailroom(&self) -> Result<u16, ErrorContext> {
18091 let mut iter = self.clone();
18092 iter.pos = 0;
18093 for attr in iter {
18094 if let LinkinfoNetkitAttrs::Tailroom(val) = attr? {
18095 return Ok(val);
18096 }
18097 }
18098 Err(ErrorContext::new_missing(
18099 "LinkinfoNetkitAttrs",
18100 "Tailroom",
18101 self.orig_loc,
18102 self.buf.as_ptr() as usize,
18103 ))
18104 }
18105}
18106impl LinkinfoNetkitAttrs<'_> {
18107 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoNetkitAttrs<'a> {
18108 IterableLinkinfoNetkitAttrs::with_loc(buf, buf.as_ptr() as usize)
18109 }
18110 fn attr_from_type(r#type: u16) -> Option<&'static str> {
18111 let res = match r#type {
18112 1u16 => "PeerInfo",
18113 2u16 => "Primary",
18114 3u16 => "Policy",
18115 4u16 => "PeerPolicy",
18116 5u16 => "Mode",
18117 6u16 => "Scrub",
18118 7u16 => "PeerScrub",
18119 8u16 => "Headroom",
18120 9u16 => "Tailroom",
18121 _ => return None,
18122 };
18123 Some(res)
18124 }
18125}
18126#[derive(Clone, Copy, Default)]
18127pub struct IterableLinkinfoNetkitAttrs<'a> {
18128 buf: &'a [u8],
18129 pos: usize,
18130 orig_loc: usize,
18131}
18132impl<'a> IterableLinkinfoNetkitAttrs<'a> {
18133 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
18134 Self {
18135 buf,
18136 pos: 0,
18137 orig_loc,
18138 }
18139 }
18140 pub fn get_buf(&self) -> &'a [u8] {
18141 self.buf
18142 }
18143}
18144impl<'a> Iterator for IterableLinkinfoNetkitAttrs<'a> {
18145 type Item = Result<LinkinfoNetkitAttrs<'a>, ErrorContext>;
18146 fn next(&mut self) -> Option<Self::Item> {
18147 let pos = self.pos;
18148 let mut r#type;
18149 loop {
18150 r#type = None;
18151 if self.buf.len() == self.pos {
18152 return None;
18153 }
18154 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
18155 break;
18156 };
18157 r#type = Some(header.r#type);
18158 let res = match header.r#type {
18159 1u16 => LinkinfoNetkitAttrs::PeerInfo({
18160 let res = Some(next);
18161 let Some(val) = res else { break };
18162 val
18163 }),
18164 2u16 => LinkinfoNetkitAttrs::Primary({
18165 let res = parse_u8(next);
18166 let Some(val) = res else { break };
18167 val
18168 }),
18169 3u16 => LinkinfoNetkitAttrs::Policy({
18170 let res = parse_u32(next);
18171 let Some(val) = res else { break };
18172 val
18173 }),
18174 4u16 => LinkinfoNetkitAttrs::PeerPolicy({
18175 let res = parse_u32(next);
18176 let Some(val) = res else { break };
18177 val
18178 }),
18179 5u16 => LinkinfoNetkitAttrs::Mode({
18180 let res = parse_u32(next);
18181 let Some(val) = res else { break };
18182 val
18183 }),
18184 6u16 => LinkinfoNetkitAttrs::Scrub({
18185 let res = parse_u32(next);
18186 let Some(val) = res else { break };
18187 val
18188 }),
18189 7u16 => LinkinfoNetkitAttrs::PeerScrub({
18190 let res = parse_u32(next);
18191 let Some(val) = res else { break };
18192 val
18193 }),
18194 8u16 => LinkinfoNetkitAttrs::Headroom({
18195 let res = parse_u16(next);
18196 let Some(val) = res else { break };
18197 val
18198 }),
18199 9u16 => LinkinfoNetkitAttrs::Tailroom({
18200 let res = parse_u16(next);
18201 let Some(val) = res else { break };
18202 val
18203 }),
18204 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
18205 n => continue,
18206 };
18207 return Some(Ok(res));
18208 }
18209 Some(Err(ErrorContext::new(
18210 "LinkinfoNetkitAttrs",
18211 r#type.and_then(|t| LinkinfoNetkitAttrs::attr_from_type(t)),
18212 self.orig_loc,
18213 self.buf.as_ptr().wrapping_add(pos) as usize,
18214 )))
18215 }
18216}
18217impl<'a> std::fmt::Debug for IterableLinkinfoNetkitAttrs<'_> {
18218 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18219 let mut fmt = f.debug_struct("LinkinfoNetkitAttrs");
18220 for attr in self.clone() {
18221 let attr = match attr {
18222 Ok(a) => a,
18223 Err(err) => {
18224 fmt.finish()?;
18225 f.write_str("Err(")?;
18226 err.fmt(f)?;
18227 return f.write_str(")");
18228 }
18229 };
18230 match attr {
18231 LinkinfoNetkitAttrs::PeerInfo(val) => fmt.field("PeerInfo", &val),
18232 LinkinfoNetkitAttrs::Primary(val) => fmt.field("Primary", &val),
18233 LinkinfoNetkitAttrs::Policy(val) => {
18234 fmt.field("Policy", &FormatEnum(val.into(), NetkitPolicy::from_value))
18235 }
18236 LinkinfoNetkitAttrs::PeerPolicy(val) => fmt.field(
18237 "PeerPolicy",
18238 &FormatEnum(val.into(), NetkitPolicy::from_value),
18239 ),
18240 LinkinfoNetkitAttrs::Mode(val) => {
18241 fmt.field("Mode", &FormatEnum(val.into(), NetkitMode::from_value))
18242 }
18243 LinkinfoNetkitAttrs::Scrub(val) => {
18244 fmt.field("Scrub", &FormatEnum(val.into(), NetkitScrub::from_value))
18245 }
18246 LinkinfoNetkitAttrs::PeerScrub(val) => fmt.field(
18247 "PeerScrub",
18248 &FormatEnum(val.into(), NetkitScrub::from_value),
18249 ),
18250 LinkinfoNetkitAttrs::Headroom(val) => fmt.field("Headroom", &val),
18251 LinkinfoNetkitAttrs::Tailroom(val) => fmt.field("Tailroom", &val),
18252 };
18253 }
18254 fmt.finish()
18255 }
18256}
18257impl IterableLinkinfoNetkitAttrs<'_> {
18258 pub fn lookup_attr(
18259 &self,
18260 offset: usize,
18261 missing_type: Option<u16>,
18262 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
18263 let mut stack = Vec::new();
18264 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
18265 if missing_type.is_some() && cur == offset {
18266 stack.push(("LinkinfoNetkitAttrs", offset));
18267 return (
18268 stack,
18269 missing_type.and_then(|t| LinkinfoNetkitAttrs::attr_from_type(t)),
18270 );
18271 }
18272 if cur > offset || cur + self.buf.len() < offset {
18273 return (stack, None);
18274 }
18275 let mut attrs = self.clone();
18276 let mut last_off = cur + attrs.pos;
18277 while let Some(attr) = attrs.next() {
18278 let Ok(attr) = attr else { break };
18279 match attr {
18280 LinkinfoNetkitAttrs::PeerInfo(val) => {
18281 if last_off == offset {
18282 stack.push(("PeerInfo", last_off));
18283 break;
18284 }
18285 }
18286 LinkinfoNetkitAttrs::Primary(val) => {
18287 if last_off == offset {
18288 stack.push(("Primary", last_off));
18289 break;
18290 }
18291 }
18292 LinkinfoNetkitAttrs::Policy(val) => {
18293 if last_off == offset {
18294 stack.push(("Policy", last_off));
18295 break;
18296 }
18297 }
18298 LinkinfoNetkitAttrs::PeerPolicy(val) => {
18299 if last_off == offset {
18300 stack.push(("PeerPolicy", last_off));
18301 break;
18302 }
18303 }
18304 LinkinfoNetkitAttrs::Mode(val) => {
18305 if last_off == offset {
18306 stack.push(("Mode", last_off));
18307 break;
18308 }
18309 }
18310 LinkinfoNetkitAttrs::Scrub(val) => {
18311 if last_off == offset {
18312 stack.push(("Scrub", last_off));
18313 break;
18314 }
18315 }
18316 LinkinfoNetkitAttrs::PeerScrub(val) => {
18317 if last_off == offset {
18318 stack.push(("PeerScrub", last_off));
18319 break;
18320 }
18321 }
18322 LinkinfoNetkitAttrs::Headroom(val) => {
18323 if last_off == offset {
18324 stack.push(("Headroom", last_off));
18325 break;
18326 }
18327 }
18328 LinkinfoNetkitAttrs::Tailroom(val) => {
18329 if last_off == offset {
18330 stack.push(("Tailroom", last_off));
18331 break;
18332 }
18333 }
18334 _ => {}
18335 };
18336 last_off = cur + attrs.pos;
18337 }
18338 if !stack.is_empty() {
18339 stack.push(("LinkinfoNetkitAttrs", cur));
18340 }
18341 (stack, None)
18342 }
18343}
18344#[derive(Clone)]
18345pub enum LinkinfoOvpnAttrs {
18346 #[doc = "Associated type: [`OvpnMode`] (enum)"]
18347 Mode(u8),
18348}
18349impl<'a> IterableLinkinfoOvpnAttrs<'a> {
18350 #[doc = "Associated type: [`OvpnMode`] (enum)"]
18351 pub fn get_mode(&self) -> Result<u8, ErrorContext> {
18352 let mut iter = self.clone();
18353 iter.pos = 0;
18354 for attr in iter {
18355 if let LinkinfoOvpnAttrs::Mode(val) = attr? {
18356 return Ok(val);
18357 }
18358 }
18359 Err(ErrorContext::new_missing(
18360 "LinkinfoOvpnAttrs",
18361 "Mode",
18362 self.orig_loc,
18363 self.buf.as_ptr() as usize,
18364 ))
18365 }
18366}
18367impl LinkinfoOvpnAttrs {
18368 pub fn new<'a>(buf: &'a [u8]) -> IterableLinkinfoOvpnAttrs<'a> {
18369 IterableLinkinfoOvpnAttrs::with_loc(buf, buf.as_ptr() as usize)
18370 }
18371 fn attr_from_type(r#type: u16) -> Option<&'static str> {
18372 let res = match r#type {
18373 1u16 => "Mode",
18374 _ => return None,
18375 };
18376 Some(res)
18377 }
18378}
18379#[derive(Clone, Copy, Default)]
18380pub struct IterableLinkinfoOvpnAttrs<'a> {
18381 buf: &'a [u8],
18382 pos: usize,
18383 orig_loc: usize,
18384}
18385impl<'a> IterableLinkinfoOvpnAttrs<'a> {
18386 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
18387 Self {
18388 buf,
18389 pos: 0,
18390 orig_loc,
18391 }
18392 }
18393 pub fn get_buf(&self) -> &'a [u8] {
18394 self.buf
18395 }
18396}
18397impl<'a> Iterator for IterableLinkinfoOvpnAttrs<'a> {
18398 type Item = Result<LinkinfoOvpnAttrs, ErrorContext>;
18399 fn next(&mut self) -> Option<Self::Item> {
18400 let pos = self.pos;
18401 let mut r#type;
18402 loop {
18403 r#type = None;
18404 if self.buf.len() == self.pos {
18405 return None;
18406 }
18407 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
18408 break;
18409 };
18410 r#type = Some(header.r#type);
18411 let res = match header.r#type {
18412 1u16 => LinkinfoOvpnAttrs::Mode({
18413 let res = parse_u8(next);
18414 let Some(val) = res else { break };
18415 val
18416 }),
18417 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
18418 n => continue,
18419 };
18420 return Some(Ok(res));
18421 }
18422 Some(Err(ErrorContext::new(
18423 "LinkinfoOvpnAttrs",
18424 r#type.and_then(|t| LinkinfoOvpnAttrs::attr_from_type(t)),
18425 self.orig_loc,
18426 self.buf.as_ptr().wrapping_add(pos) as usize,
18427 )))
18428 }
18429}
18430impl std::fmt::Debug for IterableLinkinfoOvpnAttrs<'_> {
18431 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18432 let mut fmt = f.debug_struct("LinkinfoOvpnAttrs");
18433 for attr in self.clone() {
18434 let attr = match attr {
18435 Ok(a) => a,
18436 Err(err) => {
18437 fmt.finish()?;
18438 f.write_str("Err(")?;
18439 err.fmt(f)?;
18440 return f.write_str(")");
18441 }
18442 };
18443 match attr {
18444 LinkinfoOvpnAttrs::Mode(val) => {
18445 fmt.field("Mode", &FormatEnum(val.into(), OvpnMode::from_value))
18446 }
18447 };
18448 }
18449 fmt.finish()
18450 }
18451}
18452impl IterableLinkinfoOvpnAttrs<'_> {
18453 pub fn lookup_attr(
18454 &self,
18455 offset: usize,
18456 missing_type: Option<u16>,
18457 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
18458 let mut stack = Vec::new();
18459 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
18460 if missing_type.is_some() && cur == offset {
18461 stack.push(("LinkinfoOvpnAttrs", offset));
18462 return (
18463 stack,
18464 missing_type.and_then(|t| LinkinfoOvpnAttrs::attr_from_type(t)),
18465 );
18466 }
18467 if cur > offset || cur + self.buf.len() < offset {
18468 return (stack, None);
18469 }
18470 let mut attrs = self.clone();
18471 let mut last_off = cur + attrs.pos;
18472 while let Some(attr) = attrs.next() {
18473 let Ok(attr) = attr else { break };
18474 match attr {
18475 LinkinfoOvpnAttrs::Mode(val) => {
18476 if last_off == offset {
18477 stack.push(("Mode", last_off));
18478 break;
18479 }
18480 }
18481 _ => {}
18482 };
18483 last_off = cur + attrs.pos;
18484 }
18485 if !stack.is_empty() {
18486 stack.push(("LinkinfoOvpnAttrs", cur));
18487 }
18488 (stack, None)
18489 }
18490}
18491pub struct PushLinkAttrs<Prev: Rec> {
18492 pub(crate) prev: Option<Prev>,
18493 pub(crate) header_offset: Option<usize>,
18494}
18495impl<Prev: Rec> Rec for PushLinkAttrs<Prev> {
18496 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
18497 self.prev.as_mut().unwrap().as_rec_mut()
18498 }
18499 fn as_rec(&self) -> &Vec<u8> {
18500 self.prev.as_ref().unwrap().as_rec()
18501 }
18502}
18503impl<Prev: Rec> PushLinkAttrs<Prev> {
18504 pub fn new(prev: Prev) -> Self {
18505 Self {
18506 prev: Some(prev),
18507 header_offset: None,
18508 }
18509 }
18510 pub fn end_nested(mut self) -> Prev {
18511 let mut prev = self.prev.take().unwrap();
18512 if let Some(header_offset) = &self.header_offset {
18513 finalize_nested_header(prev.as_rec_mut(), *header_offset);
18514 }
18515 prev
18516 }
18517 pub fn push_address(mut self, value: &[u8]) -> Self {
18518 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
18519 self.as_rec_mut().extend(value);
18520 self
18521 }
18522 pub fn push_broadcast(mut self, value: &[u8]) -> Self {
18523 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
18524 self.as_rec_mut().extend(value);
18525 self
18526 }
18527 pub fn push_ifname(mut self, value: &CStr) -> Self {
18528 push_header(
18529 self.as_rec_mut(),
18530 3u16,
18531 value.to_bytes_with_nul().len() as u16,
18532 );
18533 self.as_rec_mut().extend(value.to_bytes_with_nul());
18534 self
18535 }
18536 pub fn push_ifname_bytes(mut self, value: &[u8]) -> Self {
18537 push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
18538 self.as_rec_mut().extend(value);
18539 self.as_rec_mut().push(0);
18540 self
18541 }
18542 pub fn push_mtu(mut self, value: u32) -> Self {
18543 push_header(self.as_rec_mut(), 4u16, 4 as u16);
18544 self.as_rec_mut().extend(value.to_ne_bytes());
18545 self
18546 }
18547 pub fn push_link(mut self, value: u32) -> Self {
18548 push_header(self.as_rec_mut(), 5u16, 4 as u16);
18549 self.as_rec_mut().extend(value.to_ne_bytes());
18550 self
18551 }
18552 pub fn push_qdisc(mut self, value: &CStr) -> Self {
18553 push_header(
18554 self.as_rec_mut(),
18555 6u16,
18556 value.to_bytes_with_nul().len() as u16,
18557 );
18558 self.as_rec_mut().extend(value.to_bytes_with_nul());
18559 self
18560 }
18561 pub fn push_qdisc_bytes(mut self, value: &[u8]) -> Self {
18562 push_header(self.as_rec_mut(), 6u16, (value.len() + 1) as u16);
18563 self.as_rec_mut().extend(value);
18564 self.as_rec_mut().push(0);
18565 self
18566 }
18567 pub fn push_stats(mut self, value: RtnlLinkStats) -> Self {
18568 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
18569 self.as_rec_mut().extend(value.as_slice());
18570 self
18571 }
18572 pub fn push_cost(mut self, value: &CStr) -> Self {
18573 push_header(
18574 self.as_rec_mut(),
18575 8u16,
18576 value.to_bytes_with_nul().len() as u16,
18577 );
18578 self.as_rec_mut().extend(value.to_bytes_with_nul());
18579 self
18580 }
18581 pub fn push_cost_bytes(mut self, value: &[u8]) -> Self {
18582 push_header(self.as_rec_mut(), 8u16, (value.len() + 1) as u16);
18583 self.as_rec_mut().extend(value);
18584 self.as_rec_mut().push(0);
18585 self
18586 }
18587 pub fn push_priority(mut self, value: &CStr) -> Self {
18588 push_header(
18589 self.as_rec_mut(),
18590 9u16,
18591 value.to_bytes_with_nul().len() as u16,
18592 );
18593 self.as_rec_mut().extend(value.to_bytes_with_nul());
18594 self
18595 }
18596 pub fn push_priority_bytes(mut self, value: &[u8]) -> Self {
18597 push_header(self.as_rec_mut(), 9u16, (value.len() + 1) as u16);
18598 self.as_rec_mut().extend(value);
18599 self.as_rec_mut().push(0);
18600 self
18601 }
18602 pub fn push_master(mut self, value: u32) -> Self {
18603 push_header(self.as_rec_mut(), 10u16, 4 as u16);
18604 self.as_rec_mut().extend(value.to_ne_bytes());
18605 self
18606 }
18607 pub fn push_wireless(mut self, value: &CStr) -> Self {
18608 push_header(
18609 self.as_rec_mut(),
18610 11u16,
18611 value.to_bytes_with_nul().len() as u16,
18612 );
18613 self.as_rec_mut().extend(value.to_bytes_with_nul());
18614 self
18615 }
18616 pub fn push_wireless_bytes(mut self, value: &[u8]) -> Self {
18617 push_header(self.as_rec_mut(), 11u16, (value.len() + 1) as u16);
18618 self.as_rec_mut().extend(value);
18619 self.as_rec_mut().push(0);
18620 self
18621 }
18622 pub fn push_protinfo(mut self, value: &CStr) -> Self {
18623 push_header(
18624 self.as_rec_mut(),
18625 12u16,
18626 value.to_bytes_with_nul().len() as u16,
18627 );
18628 self.as_rec_mut().extend(value.to_bytes_with_nul());
18629 self
18630 }
18631 pub fn push_protinfo_bytes(mut self, value: &[u8]) -> Self {
18632 push_header(self.as_rec_mut(), 12u16, (value.len() + 1) as u16);
18633 self.as_rec_mut().extend(value);
18634 self.as_rec_mut().push(0);
18635 self
18636 }
18637 pub fn push_txqlen(mut self, value: u32) -> Self {
18638 push_header(self.as_rec_mut(), 13u16, 4 as u16);
18639 self.as_rec_mut().extend(value.to_ne_bytes());
18640 self
18641 }
18642 pub fn push_map(mut self, value: RtnlLinkIfmap) -> Self {
18643 push_header(self.as_rec_mut(), 14u16, value.as_slice().len() as u16);
18644 self.as_rec_mut().extend(value.as_slice());
18645 self
18646 }
18647 pub fn push_weight(mut self, value: u32) -> Self {
18648 push_header(self.as_rec_mut(), 15u16, 4 as u16);
18649 self.as_rec_mut().extend(value.to_ne_bytes());
18650 self
18651 }
18652 pub fn push_operstate(mut self, value: u8) -> Self {
18653 push_header(self.as_rec_mut(), 16u16, 1 as u16);
18654 self.as_rec_mut().extend(value.to_ne_bytes());
18655 self
18656 }
18657 pub fn push_linkmode(mut self, value: u8) -> Self {
18658 push_header(self.as_rec_mut(), 17u16, 1 as u16);
18659 self.as_rec_mut().extend(value.to_ne_bytes());
18660 self
18661 }
18662 pub fn nested_linkinfo(mut self) -> PushLinkinfoAttrs<Self> {
18663 let header_offset = push_nested_header(self.as_rec_mut(), 18u16);
18664 PushLinkinfoAttrs {
18665 prev: Some(self),
18666 header_offset: Some(header_offset),
18667 }
18668 }
18669 pub fn push_net_ns_pid(mut self, value: u32) -> Self {
18670 push_header(self.as_rec_mut(), 19u16, 4 as u16);
18671 self.as_rec_mut().extend(value.to_ne_bytes());
18672 self
18673 }
18674 pub fn push_ifalias(mut self, value: &CStr) -> Self {
18675 push_header(
18676 self.as_rec_mut(),
18677 20u16,
18678 value.to_bytes_with_nul().len() as u16,
18679 );
18680 self.as_rec_mut().extend(value.to_bytes_with_nul());
18681 self
18682 }
18683 pub fn push_ifalias_bytes(mut self, value: &[u8]) -> Self {
18684 push_header(self.as_rec_mut(), 20u16, (value.len() + 1) as u16);
18685 self.as_rec_mut().extend(value);
18686 self.as_rec_mut().push(0);
18687 self
18688 }
18689 pub fn push_num_vf(mut self, value: u32) -> Self {
18690 push_header(self.as_rec_mut(), 21u16, 4 as u16);
18691 self.as_rec_mut().extend(value.to_ne_bytes());
18692 self
18693 }
18694 pub fn nested_vfinfo_list(mut self) -> PushVfinfoListAttrs<Self> {
18695 let header_offset = push_nested_header(self.as_rec_mut(), 22u16);
18696 PushVfinfoListAttrs {
18697 prev: Some(self),
18698 header_offset: Some(header_offset),
18699 }
18700 }
18701 pub fn push_stats64(mut self, value: RtnlLinkStats64) -> Self {
18702 push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
18703 self.as_rec_mut().extend(value.as_slice());
18704 self
18705 }
18706 pub fn nested_vf_ports(mut self) -> PushVfPortsAttrs<Self> {
18707 let header_offset = push_nested_header(self.as_rec_mut(), 24u16);
18708 PushVfPortsAttrs {
18709 prev: Some(self),
18710 header_offset: Some(header_offset),
18711 }
18712 }
18713 pub fn nested_port_self(mut self) -> PushPortSelfAttrs<Self> {
18714 let header_offset = push_nested_header(self.as_rec_mut(), 25u16);
18715 PushPortSelfAttrs {
18716 prev: Some(self),
18717 header_offset: Some(header_offset),
18718 }
18719 }
18720 pub fn nested_af_spec(mut self) -> PushAfSpecAttrs<Self> {
18721 let header_offset = push_nested_header(self.as_rec_mut(), 26u16);
18722 PushAfSpecAttrs {
18723 prev: Some(self),
18724 header_offset: Some(header_offset),
18725 }
18726 }
18727 pub fn push_group(mut self, value: u32) -> Self {
18728 push_header(self.as_rec_mut(), 27u16, 4 as u16);
18729 self.as_rec_mut().extend(value.to_ne_bytes());
18730 self
18731 }
18732 pub fn push_net_ns_fd(mut self, value: u32) -> Self {
18733 push_header(self.as_rec_mut(), 28u16, 4 as u16);
18734 self.as_rec_mut().extend(value.to_ne_bytes());
18735 self
18736 }
18737 #[doc = "Associated type: [`RtextFilter`] (1 bit per enumeration)"]
18738 pub fn push_ext_mask(mut self, value: u32) -> Self {
18739 push_header(self.as_rec_mut(), 29u16, 4 as u16);
18740 self.as_rec_mut().extend(value.to_ne_bytes());
18741 self
18742 }
18743 pub fn push_promiscuity(mut self, value: u32) -> Self {
18744 push_header(self.as_rec_mut(), 30u16, 4 as u16);
18745 self.as_rec_mut().extend(value.to_ne_bytes());
18746 self
18747 }
18748 pub fn push_num_tx_queues(mut self, value: u32) -> Self {
18749 push_header(self.as_rec_mut(), 31u16, 4 as u16);
18750 self.as_rec_mut().extend(value.to_ne_bytes());
18751 self
18752 }
18753 pub fn push_num_rx_queues(mut self, value: u32) -> Self {
18754 push_header(self.as_rec_mut(), 32u16, 4 as u16);
18755 self.as_rec_mut().extend(value.to_ne_bytes());
18756 self
18757 }
18758 pub fn push_carrier(mut self, value: u8) -> Self {
18759 push_header(self.as_rec_mut(), 33u16, 1 as u16);
18760 self.as_rec_mut().extend(value.to_ne_bytes());
18761 self
18762 }
18763 pub fn push_phys_port_id(mut self, value: &[u8]) -> Self {
18764 push_header(self.as_rec_mut(), 34u16, value.len() as u16);
18765 self.as_rec_mut().extend(value);
18766 self
18767 }
18768 pub fn push_carrier_changes(mut self, value: u32) -> Self {
18769 push_header(self.as_rec_mut(), 35u16, 4 as u16);
18770 self.as_rec_mut().extend(value.to_ne_bytes());
18771 self
18772 }
18773 pub fn push_phys_switch_id(mut self, value: &[u8]) -> Self {
18774 push_header(self.as_rec_mut(), 36u16, value.len() as u16);
18775 self.as_rec_mut().extend(value);
18776 self
18777 }
18778 pub fn push_link_netnsid(mut self, value: i32) -> Self {
18779 push_header(self.as_rec_mut(), 37u16, 4 as u16);
18780 self.as_rec_mut().extend(value.to_ne_bytes());
18781 self
18782 }
18783 pub fn push_phys_port_name(mut self, value: &CStr) -> Self {
18784 push_header(
18785 self.as_rec_mut(),
18786 38u16,
18787 value.to_bytes_with_nul().len() as u16,
18788 );
18789 self.as_rec_mut().extend(value.to_bytes_with_nul());
18790 self
18791 }
18792 pub fn push_phys_port_name_bytes(mut self, value: &[u8]) -> Self {
18793 push_header(self.as_rec_mut(), 38u16, (value.len() + 1) as u16);
18794 self.as_rec_mut().extend(value);
18795 self.as_rec_mut().push(0);
18796 self
18797 }
18798 pub fn push_proto_down(mut self, value: u8) -> Self {
18799 push_header(self.as_rec_mut(), 39u16, 1 as u16);
18800 self.as_rec_mut().extend(value.to_ne_bytes());
18801 self
18802 }
18803 pub fn push_gso_max_segs(mut self, value: u32) -> Self {
18804 push_header(self.as_rec_mut(), 40u16, 4 as u16);
18805 self.as_rec_mut().extend(value.to_ne_bytes());
18806 self
18807 }
18808 pub fn push_gso_max_size(mut self, value: u32) -> Self {
18809 push_header(self.as_rec_mut(), 41u16, 4 as u16);
18810 self.as_rec_mut().extend(value.to_ne_bytes());
18811 self
18812 }
18813 pub fn push_pad(mut self, value: &[u8]) -> Self {
18814 push_header(self.as_rec_mut(), 42u16, value.len() as u16);
18815 self.as_rec_mut().extend(value);
18816 self
18817 }
18818 pub fn nested_xdp(mut self) -> PushXdpAttrs<Self> {
18819 let header_offset = push_nested_header(self.as_rec_mut(), 43u16);
18820 PushXdpAttrs {
18821 prev: Some(self),
18822 header_offset: Some(header_offset),
18823 }
18824 }
18825 pub fn push_event(mut self, value: u32) -> Self {
18826 push_header(self.as_rec_mut(), 44u16, 4 as u16);
18827 self.as_rec_mut().extend(value.to_ne_bytes());
18828 self
18829 }
18830 pub fn push_new_netnsid(mut self, value: i32) -> Self {
18831 push_header(self.as_rec_mut(), 45u16, 4 as u16);
18832 self.as_rec_mut().extend(value.to_ne_bytes());
18833 self
18834 }
18835 pub fn push_target_netnsid(mut self, value: i32) -> Self {
18836 push_header(self.as_rec_mut(), 46u16, 4 as u16);
18837 self.as_rec_mut().extend(value.to_ne_bytes());
18838 self
18839 }
18840 pub fn push_carrier_up_count(mut self, value: u32) -> Self {
18841 push_header(self.as_rec_mut(), 47u16, 4 as u16);
18842 self.as_rec_mut().extend(value.to_ne_bytes());
18843 self
18844 }
18845 pub fn push_carrier_down_count(mut self, value: u32) -> Self {
18846 push_header(self.as_rec_mut(), 48u16, 4 as u16);
18847 self.as_rec_mut().extend(value.to_ne_bytes());
18848 self
18849 }
18850 pub fn push_new_ifindex(mut self, value: i32) -> Self {
18851 push_header(self.as_rec_mut(), 49u16, 4 as u16);
18852 self.as_rec_mut().extend(value.to_ne_bytes());
18853 self
18854 }
18855 pub fn push_min_mtu(mut self, value: u32) -> Self {
18856 push_header(self.as_rec_mut(), 50u16, 4 as u16);
18857 self.as_rec_mut().extend(value.to_ne_bytes());
18858 self
18859 }
18860 pub fn push_max_mtu(mut self, value: u32) -> Self {
18861 push_header(self.as_rec_mut(), 51u16, 4 as u16);
18862 self.as_rec_mut().extend(value.to_ne_bytes());
18863 self
18864 }
18865 pub fn nested_prop_list(mut self) -> PushPropListLinkAttrs<Self> {
18866 let header_offset = push_nested_header(self.as_rec_mut(), 52u16);
18867 PushPropListLinkAttrs {
18868 prev: Some(self),
18869 header_offset: Some(header_offset),
18870 }
18871 }
18872 pub fn push_alt_ifname(mut self, value: &CStr) -> Self {
18873 push_header(
18874 self.as_rec_mut(),
18875 53u16,
18876 value.to_bytes_with_nul().len() as u16,
18877 );
18878 self.as_rec_mut().extend(value.to_bytes_with_nul());
18879 self
18880 }
18881 pub fn push_alt_ifname_bytes(mut self, value: &[u8]) -> Self {
18882 push_header(self.as_rec_mut(), 53u16, (value.len() + 1) as u16);
18883 self.as_rec_mut().extend(value);
18884 self.as_rec_mut().push(0);
18885 self
18886 }
18887 pub fn push_perm_address(mut self, value: &[u8]) -> Self {
18888 push_header(self.as_rec_mut(), 54u16, value.len() as u16);
18889 self.as_rec_mut().extend(value);
18890 self
18891 }
18892 pub fn push_proto_down_reason(mut self, value: &CStr) -> Self {
18893 push_header(
18894 self.as_rec_mut(),
18895 55u16,
18896 value.to_bytes_with_nul().len() as u16,
18897 );
18898 self.as_rec_mut().extend(value.to_bytes_with_nul());
18899 self
18900 }
18901 pub fn push_proto_down_reason_bytes(mut self, value: &[u8]) -> Self {
18902 push_header(self.as_rec_mut(), 55u16, (value.len() + 1) as u16);
18903 self.as_rec_mut().extend(value);
18904 self.as_rec_mut().push(0);
18905 self
18906 }
18907 pub fn push_parent_dev_name(mut self, value: &CStr) -> Self {
18908 push_header(
18909 self.as_rec_mut(),
18910 56u16,
18911 value.to_bytes_with_nul().len() as u16,
18912 );
18913 self.as_rec_mut().extend(value.to_bytes_with_nul());
18914 self
18915 }
18916 pub fn push_parent_dev_name_bytes(mut self, value: &[u8]) -> Self {
18917 push_header(self.as_rec_mut(), 56u16, (value.len() + 1) as u16);
18918 self.as_rec_mut().extend(value);
18919 self.as_rec_mut().push(0);
18920 self
18921 }
18922 pub fn push_parent_dev_bus_name(mut self, value: &CStr) -> Self {
18923 push_header(
18924 self.as_rec_mut(),
18925 57u16,
18926 value.to_bytes_with_nul().len() as u16,
18927 );
18928 self.as_rec_mut().extend(value.to_bytes_with_nul());
18929 self
18930 }
18931 pub fn push_parent_dev_bus_name_bytes(mut self, value: &[u8]) -> Self {
18932 push_header(self.as_rec_mut(), 57u16, (value.len() + 1) as u16);
18933 self.as_rec_mut().extend(value);
18934 self.as_rec_mut().push(0);
18935 self
18936 }
18937 pub fn push_gro_max_size(mut self, value: u32) -> Self {
18938 push_header(self.as_rec_mut(), 58u16, 4 as u16);
18939 self.as_rec_mut().extend(value.to_ne_bytes());
18940 self
18941 }
18942 pub fn push_tso_max_size(mut self, value: u32) -> Self {
18943 push_header(self.as_rec_mut(), 59u16, 4 as u16);
18944 self.as_rec_mut().extend(value.to_ne_bytes());
18945 self
18946 }
18947 pub fn push_tso_max_segs(mut self, value: u32) -> Self {
18948 push_header(self.as_rec_mut(), 60u16, 4 as u16);
18949 self.as_rec_mut().extend(value.to_ne_bytes());
18950 self
18951 }
18952 pub fn push_allmulti(mut self, value: u32) -> Self {
18953 push_header(self.as_rec_mut(), 61u16, 4 as u16);
18954 self.as_rec_mut().extend(value.to_ne_bytes());
18955 self
18956 }
18957 pub fn push_devlink_port(mut self, value: &[u8]) -> Self {
18958 push_header(self.as_rec_mut(), 62u16, value.len() as u16);
18959 self.as_rec_mut().extend(value);
18960 self
18961 }
18962 pub fn push_gso_ipv4_max_size(mut self, value: u32) -> Self {
18963 push_header(self.as_rec_mut(), 63u16, 4 as u16);
18964 self.as_rec_mut().extend(value.to_ne_bytes());
18965 self
18966 }
18967 pub fn push_gro_ipv4_max_size(mut self, value: u32) -> Self {
18968 push_header(self.as_rec_mut(), 64u16, 4 as u16);
18969 self.as_rec_mut().extend(value.to_ne_bytes());
18970 self
18971 }
18972 pub fn nested_dpll_pin(mut self) -> PushLinkDpllPinAttrs<Self> {
18973 let header_offset = push_nested_header(self.as_rec_mut(), 65u16);
18974 PushLinkDpllPinAttrs {
18975 prev: Some(self),
18976 header_offset: Some(header_offset),
18977 }
18978 }
18979 #[doc = "EDT offload horizon supported by the device (in nsec)\\."]
18980 pub fn push_max_pacing_offload_horizon(mut self, value: u32) -> Self {
18981 push_header(self.as_rec_mut(), 66u16, 4 as u16);
18982 self.as_rec_mut().extend(value.to_ne_bytes());
18983 self
18984 }
18985 pub fn push_netns_immutable(mut self, value: u8) -> Self {
18986 push_header(self.as_rec_mut(), 67u16, 1 as u16);
18987 self.as_rec_mut().extend(value.to_ne_bytes());
18988 self
18989 }
18990 pub fn push_headroom(mut self, value: u16) -> Self {
18991 push_header(self.as_rec_mut(), 68u16, 2 as u16);
18992 self.as_rec_mut().extend(value.to_ne_bytes());
18993 self
18994 }
18995 pub fn push_tailroom(mut self, value: u16) -> Self {
18996 push_header(self.as_rec_mut(), 69u16, 2 as u16);
18997 self.as_rec_mut().extend(value.to_ne_bytes());
18998 self
18999 }
19000}
19001impl<Prev: Rec> Drop for PushLinkAttrs<Prev> {
19002 fn drop(&mut self) {
19003 if let Some(prev) = &mut self.prev {
19004 if let Some(header_offset) = &self.header_offset {
19005 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19006 }
19007 }
19008 }
19009}
19010pub struct PushPropListLinkAttrs<Prev: Rec> {
19011 pub(crate) prev: Option<Prev>,
19012 pub(crate) header_offset: Option<usize>,
19013}
19014impl<Prev: Rec> Rec for PushPropListLinkAttrs<Prev> {
19015 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19016 self.prev.as_mut().unwrap().as_rec_mut()
19017 }
19018 fn as_rec(&self) -> &Vec<u8> {
19019 self.prev.as_ref().unwrap().as_rec()
19020 }
19021}
19022impl<Prev: Rec> PushPropListLinkAttrs<Prev> {
19023 pub fn new(prev: Prev) -> Self {
19024 Self {
19025 prev: Some(prev),
19026 header_offset: None,
19027 }
19028 }
19029 pub fn end_nested(mut self) -> Prev {
19030 let mut prev = self.prev.take().unwrap();
19031 if let Some(header_offset) = &self.header_offset {
19032 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19033 }
19034 prev
19035 }
19036 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19037 pub fn push_alt_ifname(mut self, value: &CStr) -> Self {
19038 push_header(
19039 self.as_rec_mut(),
19040 53u16,
19041 value.to_bytes_with_nul().len() as u16,
19042 );
19043 self.as_rec_mut().extend(value.to_bytes_with_nul());
19044 self
19045 }
19046 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19047 pub fn push_alt_ifname_bytes(mut self, value: &[u8]) -> Self {
19048 push_header(self.as_rec_mut(), 53u16, (value.len() + 1) as u16);
19049 self.as_rec_mut().extend(value);
19050 self.as_rec_mut().push(0);
19051 self
19052 }
19053}
19054impl<Prev: Rec> Drop for PushPropListLinkAttrs<Prev> {
19055 fn drop(&mut self) {
19056 if let Some(prev) = &mut self.prev {
19057 if let Some(header_offset) = &self.header_offset {
19058 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19059 }
19060 }
19061 }
19062}
19063pub struct PushAfSpecAttrs<Prev: Rec> {
19064 pub(crate) prev: Option<Prev>,
19065 pub(crate) header_offset: Option<usize>,
19066}
19067impl<Prev: Rec> Rec for PushAfSpecAttrs<Prev> {
19068 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19069 self.prev.as_mut().unwrap().as_rec_mut()
19070 }
19071 fn as_rec(&self) -> &Vec<u8> {
19072 self.prev.as_ref().unwrap().as_rec()
19073 }
19074}
19075impl<Prev: Rec> PushAfSpecAttrs<Prev> {
19076 pub fn new(prev: Prev) -> Self {
19077 Self {
19078 prev: Some(prev),
19079 header_offset: None,
19080 }
19081 }
19082 pub fn end_nested(mut self) -> Prev {
19083 let mut prev = self.prev.take().unwrap();
19084 if let Some(header_offset) = &self.header_offset {
19085 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19086 }
19087 prev
19088 }
19089 pub fn nested_inet(mut self) -> PushIflaAttrs<Self> {
19090 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19091 PushIflaAttrs {
19092 prev: Some(self),
19093 header_offset: Some(header_offset),
19094 }
19095 }
19096 pub fn nested_inet6(mut self) -> PushIfla6Attrs<Self> {
19097 let header_offset = push_nested_header(self.as_rec_mut(), 10u16);
19098 PushIfla6Attrs {
19099 prev: Some(self),
19100 header_offset: Some(header_offset),
19101 }
19102 }
19103 pub fn nested_mctp(mut self) -> PushMctpAttrs<Self> {
19104 let header_offset = push_nested_header(self.as_rec_mut(), 45u16);
19105 PushMctpAttrs {
19106 prev: Some(self),
19107 header_offset: Some(header_offset),
19108 }
19109 }
19110}
19111impl<Prev: Rec> Drop for PushAfSpecAttrs<Prev> {
19112 fn drop(&mut self) {
19113 if let Some(prev) = &mut self.prev {
19114 if let Some(header_offset) = &self.header_offset {
19115 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19116 }
19117 }
19118 }
19119}
19120pub struct PushVfinfoListAttrs<Prev: Rec> {
19121 pub(crate) prev: Option<Prev>,
19122 pub(crate) header_offset: Option<usize>,
19123}
19124impl<Prev: Rec> Rec for PushVfinfoListAttrs<Prev> {
19125 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19126 self.prev.as_mut().unwrap().as_rec_mut()
19127 }
19128 fn as_rec(&self) -> &Vec<u8> {
19129 self.prev.as_ref().unwrap().as_rec()
19130 }
19131}
19132impl<Prev: Rec> PushVfinfoListAttrs<Prev> {
19133 pub fn new(prev: Prev) -> Self {
19134 Self {
19135 prev: Some(prev),
19136 header_offset: None,
19137 }
19138 }
19139 pub fn end_nested(mut self) -> Prev {
19140 let mut prev = self.prev.take().unwrap();
19141 if let Some(header_offset) = &self.header_offset {
19142 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19143 }
19144 prev
19145 }
19146 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19147 pub fn nested_info(mut self) -> PushVfinfoAttrs<Self> {
19148 let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
19149 PushVfinfoAttrs {
19150 prev: Some(self),
19151 header_offset: Some(header_offset),
19152 }
19153 }
19154}
19155impl<Prev: Rec> Drop for PushVfinfoListAttrs<Prev> {
19156 fn drop(&mut self) {
19157 if let Some(prev) = &mut self.prev {
19158 if let Some(header_offset) = &self.header_offset {
19159 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19160 }
19161 }
19162 }
19163}
19164pub struct PushVfinfoAttrs<Prev: Rec> {
19165 pub(crate) prev: Option<Prev>,
19166 pub(crate) header_offset: Option<usize>,
19167}
19168impl<Prev: Rec> Rec for PushVfinfoAttrs<Prev> {
19169 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19170 self.prev.as_mut().unwrap().as_rec_mut()
19171 }
19172 fn as_rec(&self) -> &Vec<u8> {
19173 self.prev.as_ref().unwrap().as_rec()
19174 }
19175}
19176impl<Prev: Rec> PushVfinfoAttrs<Prev> {
19177 pub fn new(prev: Prev) -> Self {
19178 Self {
19179 prev: Some(prev),
19180 header_offset: None,
19181 }
19182 }
19183 pub fn end_nested(mut self) -> Prev {
19184 let mut prev = self.prev.take().unwrap();
19185 if let Some(header_offset) = &self.header_offset {
19186 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19187 }
19188 prev
19189 }
19190 pub fn push_mac(mut self, value: IflaVfMac) -> Self {
19191 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
19192 self.as_rec_mut().extend(value.as_slice());
19193 self
19194 }
19195 pub fn push_vlan(mut self, value: IflaVfVlan) -> Self {
19196 push_header(self.as_rec_mut(), 2u16, value.as_slice().len() as u16);
19197 self.as_rec_mut().extend(value.as_slice());
19198 self
19199 }
19200 pub fn push_tx_rate(mut self, value: IflaVfTxRate) -> Self {
19201 push_header(self.as_rec_mut(), 3u16, value.as_slice().len() as u16);
19202 self.as_rec_mut().extend(value.as_slice());
19203 self
19204 }
19205 pub fn push_spoofchk(mut self, value: IflaVfSpoofchk) -> Self {
19206 push_header(self.as_rec_mut(), 4u16, value.as_slice().len() as u16);
19207 self.as_rec_mut().extend(value.as_slice());
19208 self
19209 }
19210 pub fn push_link_state(mut self, value: IflaVfLinkState) -> Self {
19211 push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
19212 self.as_rec_mut().extend(value.as_slice());
19213 self
19214 }
19215 pub fn push_rate(mut self, value: IflaVfRate) -> Self {
19216 push_header(self.as_rec_mut(), 6u16, value.as_slice().len() as u16);
19217 self.as_rec_mut().extend(value.as_slice());
19218 self
19219 }
19220 pub fn push_rss_query_en(mut self, value: IflaVfRssQueryEn) -> Self {
19221 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
19222 self.as_rec_mut().extend(value.as_slice());
19223 self
19224 }
19225 pub fn nested_stats(mut self) -> PushVfStatsAttrs<Self> {
19226 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
19227 PushVfStatsAttrs {
19228 prev: Some(self),
19229 header_offset: Some(header_offset),
19230 }
19231 }
19232 pub fn push_trust(mut self, value: IflaVfTrust) -> Self {
19233 push_header(self.as_rec_mut(), 9u16, value.as_slice().len() as u16);
19234 self.as_rec_mut().extend(value.as_slice());
19235 self
19236 }
19237 pub fn push_ib_node_guid(mut self, value: IflaVfGuid) -> Self {
19238 push_header(self.as_rec_mut(), 10u16, value.as_slice().len() as u16);
19239 self.as_rec_mut().extend(value.as_slice());
19240 self
19241 }
19242 pub fn push_ib_port_guid(mut self, value: IflaVfGuid) -> Self {
19243 push_header(self.as_rec_mut(), 11u16, value.as_slice().len() as u16);
19244 self.as_rec_mut().extend(value.as_slice());
19245 self
19246 }
19247 pub fn nested_vlan_list(mut self) -> PushVfVlanAttrs<Self> {
19248 let header_offset = push_nested_header(self.as_rec_mut(), 12u16);
19249 PushVfVlanAttrs {
19250 prev: Some(self),
19251 header_offset: Some(header_offset),
19252 }
19253 }
19254 pub fn push_broadcast(mut self, value: &[u8]) -> Self {
19255 push_header(self.as_rec_mut(), 13u16, value.len() as u16);
19256 self.as_rec_mut().extend(value);
19257 self
19258 }
19259}
19260impl<Prev: Rec> Drop for PushVfinfoAttrs<Prev> {
19261 fn drop(&mut self) {
19262 if let Some(prev) = &mut self.prev {
19263 if let Some(header_offset) = &self.header_offset {
19264 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19265 }
19266 }
19267 }
19268}
19269pub struct PushVfStatsAttrs<Prev: Rec> {
19270 pub(crate) prev: Option<Prev>,
19271 pub(crate) header_offset: Option<usize>,
19272}
19273impl<Prev: Rec> Rec for PushVfStatsAttrs<Prev> {
19274 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19275 self.prev.as_mut().unwrap().as_rec_mut()
19276 }
19277 fn as_rec(&self) -> &Vec<u8> {
19278 self.prev.as_ref().unwrap().as_rec()
19279 }
19280}
19281impl<Prev: Rec> PushVfStatsAttrs<Prev> {
19282 pub fn new(prev: Prev) -> Self {
19283 Self {
19284 prev: Some(prev),
19285 header_offset: None,
19286 }
19287 }
19288 pub fn end_nested(mut self) -> Prev {
19289 let mut prev = self.prev.take().unwrap();
19290 if let Some(header_offset) = &self.header_offset {
19291 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19292 }
19293 prev
19294 }
19295 pub fn push_rx_packets(mut self, value: u64) -> Self {
19296 push_header(self.as_rec_mut(), 0u16, 8 as u16);
19297 self.as_rec_mut().extend(value.to_ne_bytes());
19298 self
19299 }
19300 pub fn push_tx_packets(mut self, value: u64) -> Self {
19301 push_header(self.as_rec_mut(), 1u16, 8 as u16);
19302 self.as_rec_mut().extend(value.to_ne_bytes());
19303 self
19304 }
19305 pub fn push_rx_bytes(mut self, value: u64) -> Self {
19306 push_header(self.as_rec_mut(), 2u16, 8 as u16);
19307 self.as_rec_mut().extend(value.to_ne_bytes());
19308 self
19309 }
19310 pub fn push_tx_bytes(mut self, value: u64) -> Self {
19311 push_header(self.as_rec_mut(), 3u16, 8 as u16);
19312 self.as_rec_mut().extend(value.to_ne_bytes());
19313 self
19314 }
19315 pub fn push_broadcast(mut self, value: u64) -> Self {
19316 push_header(self.as_rec_mut(), 4u16, 8 as u16);
19317 self.as_rec_mut().extend(value.to_ne_bytes());
19318 self
19319 }
19320 pub fn push_multicast(mut self, value: u64) -> Self {
19321 push_header(self.as_rec_mut(), 5u16, 8 as u16);
19322 self.as_rec_mut().extend(value.to_ne_bytes());
19323 self
19324 }
19325 pub fn push_pad(mut self, value: &[u8]) -> Self {
19326 push_header(self.as_rec_mut(), 6u16, value.len() as u16);
19327 self.as_rec_mut().extend(value);
19328 self
19329 }
19330 pub fn push_rx_dropped(mut self, value: u64) -> Self {
19331 push_header(self.as_rec_mut(), 7u16, 8 as u16);
19332 self.as_rec_mut().extend(value.to_ne_bytes());
19333 self
19334 }
19335 pub fn push_tx_dropped(mut self, value: u64) -> Self {
19336 push_header(self.as_rec_mut(), 8u16, 8 as u16);
19337 self.as_rec_mut().extend(value.to_ne_bytes());
19338 self
19339 }
19340}
19341impl<Prev: Rec> Drop for PushVfStatsAttrs<Prev> {
19342 fn drop(&mut self) {
19343 if let Some(prev) = &mut self.prev {
19344 if let Some(header_offset) = &self.header_offset {
19345 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19346 }
19347 }
19348 }
19349}
19350pub struct PushVfVlanAttrs<Prev: Rec> {
19351 pub(crate) prev: Option<Prev>,
19352 pub(crate) header_offset: Option<usize>,
19353}
19354impl<Prev: Rec> Rec for PushVfVlanAttrs<Prev> {
19355 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19356 self.prev.as_mut().unwrap().as_rec_mut()
19357 }
19358 fn as_rec(&self) -> &Vec<u8> {
19359 self.prev.as_ref().unwrap().as_rec()
19360 }
19361}
19362impl<Prev: Rec> PushVfVlanAttrs<Prev> {
19363 pub fn new(prev: Prev) -> Self {
19364 Self {
19365 prev: Some(prev),
19366 header_offset: None,
19367 }
19368 }
19369 pub fn end_nested(mut self) -> Prev {
19370 let mut prev = self.prev.take().unwrap();
19371 if let Some(header_offset) = &self.header_offset {
19372 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19373 }
19374 prev
19375 }
19376 #[doc = "Attribute may repeat multiple times (treat it as array)"]
19377 pub fn push_info(mut self, value: IflaVfVlanInfo) -> Self {
19378 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
19379 self.as_rec_mut().extend(value.as_slice());
19380 self
19381 }
19382}
19383impl<Prev: Rec> Drop for PushVfVlanAttrs<Prev> {
19384 fn drop(&mut self) {
19385 if let Some(prev) = &mut self.prev {
19386 if let Some(header_offset) = &self.header_offset {
19387 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19388 }
19389 }
19390 }
19391}
19392pub struct PushVfPortsAttrs<Prev: Rec> {
19393 pub(crate) prev: Option<Prev>,
19394 pub(crate) header_offset: Option<usize>,
19395}
19396impl<Prev: Rec> Rec for PushVfPortsAttrs<Prev> {
19397 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19398 self.prev.as_mut().unwrap().as_rec_mut()
19399 }
19400 fn as_rec(&self) -> &Vec<u8> {
19401 self.prev.as_ref().unwrap().as_rec()
19402 }
19403}
19404impl<Prev: Rec> PushVfPortsAttrs<Prev> {
19405 pub fn new(prev: Prev) -> Self {
19406 Self {
19407 prev: Some(prev),
19408 header_offset: None,
19409 }
19410 }
19411 pub fn end_nested(mut self) -> Prev {
19412 let mut prev = self.prev.take().unwrap();
19413 if let Some(header_offset) = &self.header_offset {
19414 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19415 }
19416 prev
19417 }
19418}
19419impl<Prev: Rec> Drop for PushVfPortsAttrs<Prev> {
19420 fn drop(&mut self) {
19421 if let Some(prev) = &mut self.prev {
19422 if let Some(header_offset) = &self.header_offset {
19423 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19424 }
19425 }
19426 }
19427}
19428pub struct PushPortSelfAttrs<Prev: Rec> {
19429 pub(crate) prev: Option<Prev>,
19430 pub(crate) header_offset: Option<usize>,
19431}
19432impl<Prev: Rec> Rec for PushPortSelfAttrs<Prev> {
19433 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19434 self.prev.as_mut().unwrap().as_rec_mut()
19435 }
19436 fn as_rec(&self) -> &Vec<u8> {
19437 self.prev.as_ref().unwrap().as_rec()
19438 }
19439}
19440impl<Prev: Rec> PushPortSelfAttrs<Prev> {
19441 pub fn new(prev: Prev) -> Self {
19442 Self {
19443 prev: Some(prev),
19444 header_offset: None,
19445 }
19446 }
19447 pub fn end_nested(mut self) -> Prev {
19448 let mut prev = self.prev.take().unwrap();
19449 if let Some(header_offset) = &self.header_offset {
19450 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19451 }
19452 prev
19453 }
19454}
19455impl<Prev: Rec> Drop for PushPortSelfAttrs<Prev> {
19456 fn drop(&mut self) {
19457 if let Some(prev) = &mut self.prev {
19458 if let Some(header_offset) = &self.header_offset {
19459 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19460 }
19461 }
19462 }
19463}
19464pub struct PushLinkinfoAttrs<Prev: Rec> {
19465 pub(crate) prev: Option<Prev>,
19466 pub(crate) header_offset: Option<usize>,
19467}
19468impl<Prev: Rec> Rec for PushLinkinfoAttrs<Prev> {
19469 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19470 self.prev.as_mut().unwrap().as_rec_mut()
19471 }
19472 fn as_rec(&self) -> &Vec<u8> {
19473 self.prev.as_ref().unwrap().as_rec()
19474 }
19475}
19476impl<Prev: Rec> PushLinkinfoAttrs<Prev> {
19477 pub fn new(prev: Prev) -> Self {
19478 Self {
19479 prev: Some(prev),
19480 header_offset: None,
19481 }
19482 }
19483 pub fn end_nested(mut self) -> Prev {
19484 let mut prev = self.prev.take().unwrap();
19485 if let Some(header_offset) = &self.header_offset {
19486 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19487 }
19488 prev
19489 }
19490 pub fn push_kind(mut self, value: &CStr) -> Self {
19491 push_header(
19492 self.as_rec_mut(),
19493 1u16,
19494 value.to_bytes_with_nul().len() as u16,
19495 );
19496 self.as_rec_mut().extend(value.to_bytes_with_nul());
19497 self
19498 }
19499 pub fn push_kind_bytes(mut self, value: &[u8]) -> Self {
19500 push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
19501 self.as_rec_mut().extend(value);
19502 self.as_rec_mut().push(0);
19503 self
19504 }
19505 #[doc = "Selector attribute is inserted automatically."]
19506 #[doc = "At most one sub-message attribute is expected per attribute set."]
19507 pub fn nested_data_bond(mut self) -> PushLinkinfoBondAttrs<PushDummy<Prev>> {
19508 self = self.push_kind(c"bond");
19509 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19510 let dummy = PushDummy {
19511 prev: self.prev.take(),
19512 header_offset: self.header_offset.take(),
19513 };
19514 PushLinkinfoBondAttrs {
19515 prev: Some(dummy),
19516 header_offset: Some(new_header_offset),
19517 }
19518 }
19519 #[doc = "Selector attribute is inserted automatically."]
19520 #[doc = "At most one sub-message attribute is expected per attribute set."]
19521 pub fn nested_data_bridge(mut self) -> PushLinkinfoBridgeAttrs<PushDummy<Prev>> {
19522 self = self.push_kind(c"bridge");
19523 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19524 let dummy = PushDummy {
19525 prev: self.prev.take(),
19526 header_offset: self.header_offset.take(),
19527 };
19528 PushLinkinfoBridgeAttrs {
19529 prev: Some(dummy),
19530 header_offset: Some(new_header_offset),
19531 }
19532 }
19533 #[doc = "Selector attribute is inserted automatically."]
19534 #[doc = "At most one sub-message attribute is expected per attribute set."]
19535 pub fn nested_data_erspan(mut self) -> PushLinkinfoGreAttrs<PushDummy<Prev>> {
19536 self = self.push_kind(c"erspan");
19537 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19538 let dummy = PushDummy {
19539 prev: self.prev.take(),
19540 header_offset: self.header_offset.take(),
19541 };
19542 PushLinkinfoGreAttrs {
19543 prev: Some(dummy),
19544 header_offset: Some(new_header_offset),
19545 }
19546 }
19547 #[doc = "Selector attribute is inserted automatically."]
19548 #[doc = "At most one sub-message attribute is expected per attribute set."]
19549 pub fn nested_data_gre(mut self) -> PushLinkinfoGreAttrs<PushDummy<Prev>> {
19550 self = self.push_kind(c"gre");
19551 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19552 let dummy = PushDummy {
19553 prev: self.prev.take(),
19554 header_offset: self.header_offset.take(),
19555 };
19556 PushLinkinfoGreAttrs {
19557 prev: Some(dummy),
19558 header_offset: Some(new_header_offset),
19559 }
19560 }
19561 #[doc = "Selector attribute is inserted automatically."]
19562 #[doc = "At most one sub-message attribute is expected per attribute set."]
19563 pub fn nested_data_gretap(mut self) -> PushLinkinfoGreAttrs<PushDummy<Prev>> {
19564 self = self.push_kind(c"gretap");
19565 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19566 let dummy = PushDummy {
19567 prev: self.prev.take(),
19568 header_offset: self.header_offset.take(),
19569 };
19570 PushLinkinfoGreAttrs {
19571 prev: Some(dummy),
19572 header_offset: Some(new_header_offset),
19573 }
19574 }
19575 #[doc = "Selector attribute is inserted automatically."]
19576 #[doc = "At most one sub-message attribute is expected per attribute set."]
19577 pub fn nested_data_ip6gre(mut self) -> PushLinkinfoGre6Attrs<PushDummy<Prev>> {
19578 self = self.push_kind(c"ip6gre");
19579 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19580 let dummy = PushDummy {
19581 prev: self.prev.take(),
19582 header_offset: self.header_offset.take(),
19583 };
19584 PushLinkinfoGre6Attrs {
19585 prev: Some(dummy),
19586 header_offset: Some(new_header_offset),
19587 }
19588 }
19589 #[doc = "Selector attribute is inserted automatically."]
19590 #[doc = "At most one sub-message attribute is expected per attribute set."]
19591 pub fn nested_data_geneve(mut self) -> PushLinkinfoGeneveAttrs<PushDummy<Prev>> {
19592 self = self.push_kind(c"geneve");
19593 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19594 let dummy = PushDummy {
19595 prev: self.prev.take(),
19596 header_offset: self.header_offset.take(),
19597 };
19598 PushLinkinfoGeneveAttrs {
19599 prev: Some(dummy),
19600 header_offset: Some(new_header_offset),
19601 }
19602 }
19603 #[doc = "Selector attribute is inserted automatically."]
19604 #[doc = "At most one sub-message attribute is expected per attribute set."]
19605 pub fn nested_data_hsr(mut self) -> PushLinkinfoHsrAttrs<PushDummy<Prev>> {
19606 self = self.push_kind(c"hsr");
19607 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19608 let dummy = PushDummy {
19609 prev: self.prev.take(),
19610 header_offset: self.header_offset.take(),
19611 };
19612 PushLinkinfoHsrAttrs {
19613 prev: Some(dummy),
19614 header_offset: Some(new_header_offset),
19615 }
19616 }
19617 #[doc = "Selector attribute is inserted automatically."]
19618 #[doc = "At most one sub-message attribute is expected per attribute set."]
19619 pub fn nested_data_ipip(mut self) -> PushLinkinfoIptunAttrs<PushDummy<Prev>> {
19620 self = self.push_kind(c"ipip");
19621 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19622 let dummy = PushDummy {
19623 prev: self.prev.take(),
19624 header_offset: self.header_offset.take(),
19625 };
19626 PushLinkinfoIptunAttrs {
19627 prev: Some(dummy),
19628 header_offset: Some(new_header_offset),
19629 }
19630 }
19631 #[doc = "Selector attribute is inserted automatically."]
19632 #[doc = "At most one sub-message attribute is expected per attribute set."]
19633 pub fn nested_data_ip6tnl(mut self) -> PushLinkinfoIp6tnlAttrs<PushDummy<Prev>> {
19634 self = self.push_kind(c"ip6tnl");
19635 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19636 let dummy = PushDummy {
19637 prev: self.prev.take(),
19638 header_offset: self.header_offset.take(),
19639 };
19640 PushLinkinfoIp6tnlAttrs {
19641 prev: Some(dummy),
19642 header_offset: Some(new_header_offset),
19643 }
19644 }
19645 #[doc = "Selector attribute is inserted automatically."]
19646 #[doc = "At most one sub-message attribute is expected per attribute set."]
19647 pub fn nested_data_sit(mut self) -> PushLinkinfoIptunAttrs<PushDummy<Prev>> {
19648 self = self.push_kind(c"sit");
19649 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19650 let dummy = PushDummy {
19651 prev: self.prev.take(),
19652 header_offset: self.header_offset.take(),
19653 };
19654 PushLinkinfoIptunAttrs {
19655 prev: Some(dummy),
19656 header_offset: Some(new_header_offset),
19657 }
19658 }
19659 #[doc = "Selector attribute is inserted automatically."]
19660 #[doc = "At most one sub-message attribute is expected per attribute set."]
19661 pub fn nested_data_tun(mut self) -> PushLinkinfoTunAttrs<PushDummy<Prev>> {
19662 self = self.push_kind(c"tun");
19663 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19664 let dummy = PushDummy {
19665 prev: self.prev.take(),
19666 header_offset: self.header_offset.take(),
19667 };
19668 PushLinkinfoTunAttrs {
19669 prev: Some(dummy),
19670 header_offset: Some(new_header_offset),
19671 }
19672 }
19673 #[doc = "Selector attribute is inserted automatically."]
19674 #[doc = "At most one sub-message attribute is expected per attribute set."]
19675 pub fn nested_data_vlan(mut self) -> PushLinkinfoVlanAttrs<PushDummy<Prev>> {
19676 self = self.push_kind(c"vlan");
19677 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19678 let dummy = PushDummy {
19679 prev: self.prev.take(),
19680 header_offset: self.header_offset.take(),
19681 };
19682 PushLinkinfoVlanAttrs {
19683 prev: Some(dummy),
19684 header_offset: Some(new_header_offset),
19685 }
19686 }
19687 #[doc = "Selector attribute is inserted automatically."]
19688 #[doc = "At most one sub-message attribute is expected per attribute set."]
19689 pub fn nested_data_vrf(mut self) -> PushLinkinfoVrfAttrs<PushDummy<Prev>> {
19690 self = self.push_kind(c"vrf");
19691 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19692 let dummy = PushDummy {
19693 prev: self.prev.take(),
19694 header_offset: self.header_offset.take(),
19695 };
19696 PushLinkinfoVrfAttrs {
19697 prev: Some(dummy),
19698 header_offset: Some(new_header_offset),
19699 }
19700 }
19701 #[doc = "Selector attribute is inserted automatically."]
19702 #[doc = "At most one sub-message attribute is expected per attribute set."]
19703 pub fn nested_data_vti(mut self) -> PushLinkinfoVtiAttrs<PushDummy<Prev>> {
19704 self = self.push_kind(c"vti");
19705 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19706 let dummy = PushDummy {
19707 prev: self.prev.take(),
19708 header_offset: self.header_offset.take(),
19709 };
19710 PushLinkinfoVtiAttrs {
19711 prev: Some(dummy),
19712 header_offset: Some(new_header_offset),
19713 }
19714 }
19715 #[doc = "Selector attribute is inserted automatically."]
19716 #[doc = "At most one sub-message attribute is expected per attribute set."]
19717 pub fn nested_data_vti6(mut self) -> PushLinkinfoVti6Attrs<PushDummy<Prev>> {
19718 self = self.push_kind(c"vti6");
19719 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19720 let dummy = PushDummy {
19721 prev: self.prev.take(),
19722 header_offset: self.header_offset.take(),
19723 };
19724 PushLinkinfoVti6Attrs {
19725 prev: Some(dummy),
19726 header_offset: Some(new_header_offset),
19727 }
19728 }
19729 #[doc = "Selector attribute is inserted automatically."]
19730 #[doc = "At most one sub-message attribute is expected per attribute set."]
19731 pub fn nested_data_netkit(mut self) -> PushLinkinfoNetkitAttrs<PushDummy<Prev>> {
19732 self = self.push_kind(c"netkit");
19733 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19734 let dummy = PushDummy {
19735 prev: self.prev.take(),
19736 header_offset: self.header_offset.take(),
19737 };
19738 PushLinkinfoNetkitAttrs {
19739 prev: Some(dummy),
19740 header_offset: Some(new_header_offset),
19741 }
19742 }
19743 #[doc = "Selector attribute is inserted automatically."]
19744 #[doc = "At most one sub-message attribute is expected per attribute set."]
19745 pub fn nested_data_ovpn(mut self) -> PushLinkinfoOvpnAttrs<PushDummy<Prev>> {
19746 self = self.push_kind(c"ovpn");
19747 let new_header_offset = push_nested_header(self.as_rec_mut(), 2u16);
19748 let dummy = PushDummy {
19749 prev: self.prev.take(),
19750 header_offset: self.header_offset.take(),
19751 };
19752 PushLinkinfoOvpnAttrs {
19753 prev: Some(dummy),
19754 header_offset: Some(new_header_offset),
19755 }
19756 }
19757 pub fn push_xstats(mut self, value: &[u8]) -> Self {
19758 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
19759 self.as_rec_mut().extend(value);
19760 self
19761 }
19762 pub fn push_slave_kind(mut self, value: &CStr) -> Self {
19763 push_header(
19764 self.as_rec_mut(),
19765 4u16,
19766 value.to_bytes_with_nul().len() as u16,
19767 );
19768 self.as_rec_mut().extend(value.to_bytes_with_nul());
19769 self
19770 }
19771 pub fn push_slave_kind_bytes(mut self, value: &[u8]) -> Self {
19772 push_header(self.as_rec_mut(), 4u16, (value.len() + 1) as u16);
19773 self.as_rec_mut().extend(value);
19774 self.as_rec_mut().push(0);
19775 self
19776 }
19777 #[doc = "Selector attribute is inserted automatically."]
19778 #[doc = "At most one sub-message attribute is expected per attribute set."]
19779 pub fn nested_slave_data_bridge(mut self) -> PushLinkinfoBrportAttrs<PushDummy<Prev>> {
19780 self = self.push_slave_kind(c"bridge");
19781 let new_header_offset = push_nested_header(self.as_rec_mut(), 5u16);
19782 let dummy = PushDummy {
19783 prev: self.prev.take(),
19784 header_offset: self.header_offset.take(),
19785 };
19786 PushLinkinfoBrportAttrs {
19787 prev: Some(dummy),
19788 header_offset: Some(new_header_offset),
19789 }
19790 }
19791 #[doc = "Selector attribute is inserted automatically."]
19792 #[doc = "At most one sub-message attribute is expected per attribute set."]
19793 pub fn nested_slave_data_bond(mut self) -> PushBondSlaveAttrs<PushDummy<Prev>> {
19794 self = self.push_slave_kind(c"bond");
19795 let new_header_offset = push_nested_header(self.as_rec_mut(), 5u16);
19796 let dummy = PushDummy {
19797 prev: self.prev.take(),
19798 header_offset: self.header_offset.take(),
19799 };
19800 PushBondSlaveAttrs {
19801 prev: Some(dummy),
19802 header_offset: Some(new_header_offset),
19803 }
19804 }
19805}
19806impl<Prev: Rec> Drop for PushLinkinfoAttrs<Prev> {
19807 fn drop(&mut self) {
19808 if let Some(prev) = &mut self.prev {
19809 if let Some(header_offset) = &self.header_offset {
19810 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19811 }
19812 }
19813 }
19814}
19815pub struct PushLinkinfoBondAttrs<Prev: Rec> {
19816 pub(crate) prev: Option<Prev>,
19817 pub(crate) header_offset: Option<usize>,
19818}
19819impl<Prev: Rec> Rec for PushLinkinfoBondAttrs<Prev> {
19820 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19821 self.prev.as_mut().unwrap().as_rec_mut()
19822 }
19823 fn as_rec(&self) -> &Vec<u8> {
19824 self.prev.as_ref().unwrap().as_rec()
19825 }
19826}
19827pub struct PushArrayU32<Prev: Rec> {
19828 pub(crate) prev: Option<Prev>,
19829 pub(crate) header_offset: Option<usize>,
19830 pub(crate) counter: u16,
19831}
19832impl<Prev: Rec> Rec for PushArrayU32<Prev> {
19833 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19834 self.prev.as_mut().unwrap().as_rec_mut()
19835 }
19836 fn as_rec(&self) -> &Vec<u8> {
19837 self.prev.as_ref().unwrap().as_rec()
19838 }
19839}
19840impl<Prev: Rec> PushArrayU32<Prev> {
19841 pub fn new(prev: Prev) -> Self {
19842 Self {
19843 prev: Some(prev),
19844 header_offset: None,
19845 counter: 0,
19846 }
19847 }
19848 pub fn end_array(mut self) -> Prev {
19849 let mut prev = self.prev.take().unwrap();
19850 if let Some(header_offset) = &self.header_offset {
19851 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19852 }
19853 prev
19854 }
19855 pub fn entry(mut self, value: std::net::Ipv4Addr) -> Self {
19856 let index = self.counter;
19857 self.counter += 1;
19858 push_header(self.as_rec_mut(), index, 4 as u16);
19859 self.as_rec_mut().extend(&value.to_bits().to_be_bytes());
19860 self
19861 }
19862}
19863impl<Prev: Rec> Drop for PushArrayU32<Prev> {
19864 fn drop(&mut self) {
19865 if let Some(prev) = &mut self.prev {
19866 if let Some(header_offset) = &self.header_offset {
19867 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19868 }
19869 }
19870 }
19871}
19872pub struct PushArrayBinary<Prev: Rec> {
19873 pub(crate) prev: Option<Prev>,
19874 pub(crate) header_offset: Option<usize>,
19875 pub(crate) counter: u16,
19876}
19877impl<Prev: Rec> Rec for PushArrayBinary<Prev> {
19878 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
19879 self.prev.as_mut().unwrap().as_rec_mut()
19880 }
19881 fn as_rec(&self) -> &Vec<u8> {
19882 self.prev.as_ref().unwrap().as_rec()
19883 }
19884}
19885impl<Prev: Rec> PushArrayBinary<Prev> {
19886 pub fn new(prev: Prev) -> Self {
19887 Self {
19888 prev: Some(prev),
19889 header_offset: None,
19890 counter: 0,
19891 }
19892 }
19893 pub fn end_array(mut self) -> Prev {
19894 let mut prev = self.prev.take().unwrap();
19895 if let Some(header_offset) = &self.header_offset {
19896 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19897 }
19898 prev
19899 }
19900 pub fn entry(mut self, value: &[u8]) -> Self {
19901 let index = self.counter;
19902 self.counter += 1;
19903 push_header(self.as_rec_mut(), index, value.len() as u16);
19904 self.as_rec_mut().extend(value);
19905 self
19906 }
19907}
19908impl<Prev: Rec> Drop for PushArrayBinary<Prev> {
19909 fn drop(&mut self) {
19910 if let Some(prev) = &mut self.prev {
19911 if let Some(header_offset) = &self.header_offset {
19912 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19913 }
19914 }
19915 }
19916}
19917impl<Prev: Rec> PushLinkinfoBondAttrs<Prev> {
19918 pub fn new(prev: Prev) -> Self {
19919 Self {
19920 prev: Some(prev),
19921 header_offset: None,
19922 }
19923 }
19924 pub fn end_nested(mut self) -> Prev {
19925 let mut prev = self.prev.take().unwrap();
19926 if let Some(header_offset) = &self.header_offset {
19927 finalize_nested_header(prev.as_rec_mut(), *header_offset);
19928 }
19929 prev
19930 }
19931 pub fn push_mode(mut self, value: u8) -> Self {
19932 push_header(self.as_rec_mut(), 1u16, 1 as u16);
19933 self.as_rec_mut().extend(value.to_ne_bytes());
19934 self
19935 }
19936 pub fn push_active_slave(mut self, value: u32) -> Self {
19937 push_header(self.as_rec_mut(), 2u16, 4 as u16);
19938 self.as_rec_mut().extend(value.to_ne_bytes());
19939 self
19940 }
19941 pub fn push_miimon(mut self, value: u32) -> Self {
19942 push_header(self.as_rec_mut(), 3u16, 4 as u16);
19943 self.as_rec_mut().extend(value.to_ne_bytes());
19944 self
19945 }
19946 pub fn push_updelay(mut self, value: u32) -> Self {
19947 push_header(self.as_rec_mut(), 4u16, 4 as u16);
19948 self.as_rec_mut().extend(value.to_ne_bytes());
19949 self
19950 }
19951 pub fn push_downdelay(mut self, value: u32) -> Self {
19952 push_header(self.as_rec_mut(), 5u16, 4 as u16);
19953 self.as_rec_mut().extend(value.to_ne_bytes());
19954 self
19955 }
19956 pub fn push_use_carrier(mut self, value: u8) -> Self {
19957 push_header(self.as_rec_mut(), 6u16, 1 as u16);
19958 self.as_rec_mut().extend(value.to_ne_bytes());
19959 self
19960 }
19961 pub fn push_arp_interval(mut self, value: u32) -> Self {
19962 push_header(self.as_rec_mut(), 7u16, 4 as u16);
19963 self.as_rec_mut().extend(value.to_ne_bytes());
19964 self
19965 }
19966 pub fn array_arp_ip_target(mut self) -> PushArrayU32<Self> {
19967 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
19968 PushArrayU32 {
19969 prev: Some(self),
19970 header_offset: Some(header_offset),
19971 counter: 0,
19972 }
19973 }
19974 pub fn push_arp_validate(mut self, value: u32) -> Self {
19975 push_header(self.as_rec_mut(), 9u16, 4 as u16);
19976 self.as_rec_mut().extend(value.to_ne_bytes());
19977 self
19978 }
19979 pub fn push_arp_all_targets(mut self, value: u32) -> Self {
19980 push_header(self.as_rec_mut(), 10u16, 4 as u16);
19981 self.as_rec_mut().extend(value.to_ne_bytes());
19982 self
19983 }
19984 pub fn push_primary(mut self, value: u32) -> Self {
19985 push_header(self.as_rec_mut(), 11u16, 4 as u16);
19986 self.as_rec_mut().extend(value.to_ne_bytes());
19987 self
19988 }
19989 pub fn push_primary_reselect(mut self, value: u8) -> Self {
19990 push_header(self.as_rec_mut(), 12u16, 1 as u16);
19991 self.as_rec_mut().extend(value.to_ne_bytes());
19992 self
19993 }
19994 pub fn push_fail_over_mac(mut self, value: u8) -> Self {
19995 push_header(self.as_rec_mut(), 13u16, 1 as u16);
19996 self.as_rec_mut().extend(value.to_ne_bytes());
19997 self
19998 }
19999 pub fn push_xmit_hash_policy(mut self, value: u8) -> Self {
20000 push_header(self.as_rec_mut(), 14u16, 1 as u16);
20001 self.as_rec_mut().extend(value.to_ne_bytes());
20002 self
20003 }
20004 pub fn push_resend_igmp(mut self, value: u32) -> Self {
20005 push_header(self.as_rec_mut(), 15u16, 4 as u16);
20006 self.as_rec_mut().extend(value.to_ne_bytes());
20007 self
20008 }
20009 pub fn push_num_peer_notif(mut self, value: u8) -> Self {
20010 push_header(self.as_rec_mut(), 16u16, 1 as u16);
20011 self.as_rec_mut().extend(value.to_ne_bytes());
20012 self
20013 }
20014 pub fn push_all_slaves_active(mut self, value: u8) -> Self {
20015 push_header(self.as_rec_mut(), 17u16, 1 as u16);
20016 self.as_rec_mut().extend(value.to_ne_bytes());
20017 self
20018 }
20019 pub fn push_min_links(mut self, value: u32) -> Self {
20020 push_header(self.as_rec_mut(), 18u16, 4 as u16);
20021 self.as_rec_mut().extend(value.to_ne_bytes());
20022 self
20023 }
20024 pub fn push_lp_interval(mut self, value: u32) -> Self {
20025 push_header(self.as_rec_mut(), 19u16, 4 as u16);
20026 self.as_rec_mut().extend(value.to_ne_bytes());
20027 self
20028 }
20029 pub fn push_packets_per_slave(mut self, value: u32) -> Self {
20030 push_header(self.as_rec_mut(), 20u16, 4 as u16);
20031 self.as_rec_mut().extend(value.to_ne_bytes());
20032 self
20033 }
20034 pub fn push_ad_lacp_rate(mut self, value: u8) -> Self {
20035 push_header(self.as_rec_mut(), 21u16, 1 as u16);
20036 self.as_rec_mut().extend(value.to_ne_bytes());
20037 self
20038 }
20039 pub fn push_ad_select(mut self, value: u8) -> Self {
20040 push_header(self.as_rec_mut(), 22u16, 1 as u16);
20041 self.as_rec_mut().extend(value.to_ne_bytes());
20042 self
20043 }
20044 pub fn nested_ad_info(mut self) -> PushBondAdInfoAttrs<Self> {
20045 let header_offset = push_nested_header(self.as_rec_mut(), 23u16);
20046 PushBondAdInfoAttrs {
20047 prev: Some(self),
20048 header_offset: Some(header_offset),
20049 }
20050 }
20051 pub fn push_ad_actor_sys_prio(mut self, value: u16) -> Self {
20052 push_header(self.as_rec_mut(), 24u16, 2 as u16);
20053 self.as_rec_mut().extend(value.to_ne_bytes());
20054 self
20055 }
20056 pub fn push_ad_user_port_key(mut self, value: u16) -> Self {
20057 push_header(self.as_rec_mut(), 25u16, 2 as u16);
20058 self.as_rec_mut().extend(value.to_ne_bytes());
20059 self
20060 }
20061 pub fn push_ad_actor_system(mut self, value: &[u8]) -> Self {
20062 push_header(self.as_rec_mut(), 26u16, value.len() as u16);
20063 self.as_rec_mut().extend(value);
20064 self
20065 }
20066 pub fn push_tlb_dynamic_lb(mut self, value: u8) -> Self {
20067 push_header(self.as_rec_mut(), 27u16, 1 as u16);
20068 self.as_rec_mut().extend(value.to_ne_bytes());
20069 self
20070 }
20071 pub fn push_peer_notif_delay(mut self, value: u32) -> Self {
20072 push_header(self.as_rec_mut(), 28u16, 4 as u16);
20073 self.as_rec_mut().extend(value.to_ne_bytes());
20074 self
20075 }
20076 pub fn push_ad_lacp_active(mut self, value: u8) -> Self {
20077 push_header(self.as_rec_mut(), 29u16, 1 as u16);
20078 self.as_rec_mut().extend(value.to_ne_bytes());
20079 self
20080 }
20081 pub fn push_missed_max(mut self, value: u8) -> Self {
20082 push_header(self.as_rec_mut(), 30u16, 1 as u16);
20083 self.as_rec_mut().extend(value.to_ne_bytes());
20084 self
20085 }
20086 pub fn array_ns_ip6_target(mut self) -> PushArrayBinary<Self> {
20087 let header_offset = push_nested_header(self.as_rec_mut(), 31u16);
20088 PushArrayBinary {
20089 prev: Some(self),
20090 header_offset: Some(header_offset),
20091 counter: 0,
20092 }
20093 }
20094 pub fn push_coupled_control(mut self, value: u8) -> Self {
20095 push_header(self.as_rec_mut(), 32u16, 1 as u16);
20096 self.as_rec_mut().extend(value.to_ne_bytes());
20097 self
20098 }
20099}
20100impl<Prev: Rec> Drop for PushLinkinfoBondAttrs<Prev> {
20101 fn drop(&mut self) {
20102 if let Some(prev) = &mut self.prev {
20103 if let Some(header_offset) = &self.header_offset {
20104 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20105 }
20106 }
20107 }
20108}
20109pub struct PushBondAdInfoAttrs<Prev: Rec> {
20110 pub(crate) prev: Option<Prev>,
20111 pub(crate) header_offset: Option<usize>,
20112}
20113impl<Prev: Rec> Rec for PushBondAdInfoAttrs<Prev> {
20114 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20115 self.prev.as_mut().unwrap().as_rec_mut()
20116 }
20117 fn as_rec(&self) -> &Vec<u8> {
20118 self.prev.as_ref().unwrap().as_rec()
20119 }
20120}
20121impl<Prev: Rec> PushBondAdInfoAttrs<Prev> {
20122 pub fn new(prev: Prev) -> Self {
20123 Self {
20124 prev: Some(prev),
20125 header_offset: None,
20126 }
20127 }
20128 pub fn end_nested(mut self) -> Prev {
20129 let mut prev = self.prev.take().unwrap();
20130 if let Some(header_offset) = &self.header_offset {
20131 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20132 }
20133 prev
20134 }
20135 pub fn push_aggregator(mut self, value: u16) -> Self {
20136 push_header(self.as_rec_mut(), 1u16, 2 as u16);
20137 self.as_rec_mut().extend(value.to_ne_bytes());
20138 self
20139 }
20140 pub fn push_num_ports(mut self, value: u16) -> Self {
20141 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20142 self.as_rec_mut().extend(value.to_ne_bytes());
20143 self
20144 }
20145 pub fn push_actor_key(mut self, value: u16) -> Self {
20146 push_header(self.as_rec_mut(), 3u16, 2 as u16);
20147 self.as_rec_mut().extend(value.to_ne_bytes());
20148 self
20149 }
20150 pub fn push_partner_key(mut self, value: u16) -> Self {
20151 push_header(self.as_rec_mut(), 4u16, 2 as u16);
20152 self.as_rec_mut().extend(value.to_ne_bytes());
20153 self
20154 }
20155 pub fn push_partner_mac(mut self, value: &[u8]) -> Self {
20156 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
20157 self.as_rec_mut().extend(value);
20158 self
20159 }
20160}
20161impl<Prev: Rec> Drop for PushBondAdInfoAttrs<Prev> {
20162 fn drop(&mut self) {
20163 if let Some(prev) = &mut self.prev {
20164 if let Some(header_offset) = &self.header_offset {
20165 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20166 }
20167 }
20168 }
20169}
20170pub struct PushBondSlaveAttrs<Prev: Rec> {
20171 pub(crate) prev: Option<Prev>,
20172 pub(crate) header_offset: Option<usize>,
20173}
20174impl<Prev: Rec> Rec for PushBondSlaveAttrs<Prev> {
20175 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20176 self.prev.as_mut().unwrap().as_rec_mut()
20177 }
20178 fn as_rec(&self) -> &Vec<u8> {
20179 self.prev.as_ref().unwrap().as_rec()
20180 }
20181}
20182impl<Prev: Rec> PushBondSlaveAttrs<Prev> {
20183 pub fn new(prev: Prev) -> Self {
20184 Self {
20185 prev: Some(prev),
20186 header_offset: None,
20187 }
20188 }
20189 pub fn end_nested(mut self) -> Prev {
20190 let mut prev = self.prev.take().unwrap();
20191 if let Some(header_offset) = &self.header_offset {
20192 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20193 }
20194 prev
20195 }
20196 pub fn push_state(mut self, value: u8) -> Self {
20197 push_header(self.as_rec_mut(), 1u16, 1 as u16);
20198 self.as_rec_mut().extend(value.to_ne_bytes());
20199 self
20200 }
20201 pub fn push_mii_status(mut self, value: u8) -> Self {
20202 push_header(self.as_rec_mut(), 2u16, 1 as u16);
20203 self.as_rec_mut().extend(value.to_ne_bytes());
20204 self
20205 }
20206 pub fn push_link_failure_count(mut self, value: u32) -> Self {
20207 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20208 self.as_rec_mut().extend(value.to_ne_bytes());
20209 self
20210 }
20211 pub fn push_perm_hwaddr(mut self, value: &[u8]) -> Self {
20212 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
20213 self.as_rec_mut().extend(value);
20214 self
20215 }
20216 pub fn push_queue_id(mut self, value: u16) -> Self {
20217 push_header(self.as_rec_mut(), 5u16, 2 as u16);
20218 self.as_rec_mut().extend(value.to_ne_bytes());
20219 self
20220 }
20221 pub fn push_ad_aggregator_id(mut self, value: u16) -> Self {
20222 push_header(self.as_rec_mut(), 6u16, 2 as u16);
20223 self.as_rec_mut().extend(value.to_ne_bytes());
20224 self
20225 }
20226 pub fn push_ad_actor_oper_port_state(mut self, value: u8) -> Self {
20227 push_header(self.as_rec_mut(), 7u16, 1 as u16);
20228 self.as_rec_mut().extend(value.to_ne_bytes());
20229 self
20230 }
20231 pub fn push_ad_partner_oper_port_state(mut self, value: u16) -> Self {
20232 push_header(self.as_rec_mut(), 8u16, 2 as u16);
20233 self.as_rec_mut().extend(value.to_ne_bytes());
20234 self
20235 }
20236 pub fn push_prio(mut self, value: u32) -> Self {
20237 push_header(self.as_rec_mut(), 9u16, 4 as u16);
20238 self.as_rec_mut().extend(value.to_ne_bytes());
20239 self
20240 }
20241}
20242impl<Prev: Rec> Drop for PushBondSlaveAttrs<Prev> {
20243 fn drop(&mut self) {
20244 if let Some(prev) = &mut self.prev {
20245 if let Some(header_offset) = &self.header_offset {
20246 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20247 }
20248 }
20249 }
20250}
20251pub struct PushLinkinfoBridgeAttrs<Prev: Rec> {
20252 pub(crate) prev: Option<Prev>,
20253 pub(crate) header_offset: Option<usize>,
20254}
20255impl<Prev: Rec> Rec for PushLinkinfoBridgeAttrs<Prev> {
20256 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20257 self.prev.as_mut().unwrap().as_rec_mut()
20258 }
20259 fn as_rec(&self) -> &Vec<u8> {
20260 self.prev.as_ref().unwrap().as_rec()
20261 }
20262}
20263impl<Prev: Rec> PushLinkinfoBridgeAttrs<Prev> {
20264 pub fn new(prev: Prev) -> Self {
20265 Self {
20266 prev: Some(prev),
20267 header_offset: None,
20268 }
20269 }
20270 pub fn end_nested(mut self) -> Prev {
20271 let mut prev = self.prev.take().unwrap();
20272 if let Some(header_offset) = &self.header_offset {
20273 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20274 }
20275 prev
20276 }
20277 pub fn push_forward_delay(mut self, value: u32) -> Self {
20278 push_header(self.as_rec_mut(), 1u16, 4 as u16);
20279 self.as_rec_mut().extend(value.to_ne_bytes());
20280 self
20281 }
20282 pub fn push_hello_time(mut self, value: u32) -> Self {
20283 push_header(self.as_rec_mut(), 2u16, 4 as u16);
20284 self.as_rec_mut().extend(value.to_ne_bytes());
20285 self
20286 }
20287 pub fn push_max_age(mut self, value: u32) -> Self {
20288 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20289 self.as_rec_mut().extend(value.to_ne_bytes());
20290 self
20291 }
20292 pub fn push_ageing_time(mut self, value: u32) -> Self {
20293 push_header(self.as_rec_mut(), 4u16, 4 as u16);
20294 self.as_rec_mut().extend(value.to_ne_bytes());
20295 self
20296 }
20297 pub fn push_stp_state(mut self, value: u32) -> Self {
20298 push_header(self.as_rec_mut(), 5u16, 4 as u16);
20299 self.as_rec_mut().extend(value.to_ne_bytes());
20300 self
20301 }
20302 pub fn push_priority(mut self, value: u16) -> Self {
20303 push_header(self.as_rec_mut(), 6u16, 2 as u16);
20304 self.as_rec_mut().extend(value.to_ne_bytes());
20305 self
20306 }
20307 pub fn push_vlan_filtering(mut self, value: u8) -> Self {
20308 push_header(self.as_rec_mut(), 7u16, 1 as u16);
20309 self.as_rec_mut().extend(value.to_ne_bytes());
20310 self
20311 }
20312 pub fn push_vlan_protocol(mut self, value: u16) -> Self {
20313 push_header(self.as_rec_mut(), 8u16, 2 as u16);
20314 self.as_rec_mut().extend(value.to_ne_bytes());
20315 self
20316 }
20317 pub fn push_group_fwd_mask(mut self, value: u16) -> Self {
20318 push_header(self.as_rec_mut(), 9u16, 2 as u16);
20319 self.as_rec_mut().extend(value.to_ne_bytes());
20320 self
20321 }
20322 pub fn push_root_id(mut self, value: IflaBridgeId) -> Self {
20323 push_header(self.as_rec_mut(), 10u16, value.as_slice().len() as u16);
20324 self.as_rec_mut().extend(value.as_slice());
20325 self
20326 }
20327 pub fn push_bridge_id(mut self, value: IflaBridgeId) -> Self {
20328 push_header(self.as_rec_mut(), 11u16, value.as_slice().len() as u16);
20329 self.as_rec_mut().extend(value.as_slice());
20330 self
20331 }
20332 pub fn push_root_port(mut self, value: u16) -> Self {
20333 push_header(self.as_rec_mut(), 12u16, 2 as u16);
20334 self.as_rec_mut().extend(value.to_ne_bytes());
20335 self
20336 }
20337 pub fn push_root_path_cost(mut self, value: u32) -> Self {
20338 push_header(self.as_rec_mut(), 13u16, 4 as u16);
20339 self.as_rec_mut().extend(value.to_ne_bytes());
20340 self
20341 }
20342 pub fn push_topology_change(mut self, value: u8) -> Self {
20343 push_header(self.as_rec_mut(), 14u16, 1 as u16);
20344 self.as_rec_mut().extend(value.to_ne_bytes());
20345 self
20346 }
20347 pub fn push_topology_change_detected(mut self, value: u8) -> Self {
20348 push_header(self.as_rec_mut(), 15u16, 1 as u16);
20349 self.as_rec_mut().extend(value.to_ne_bytes());
20350 self
20351 }
20352 pub fn push_hello_timer(mut self, value: u64) -> Self {
20353 push_header(self.as_rec_mut(), 16u16, 8 as u16);
20354 self.as_rec_mut().extend(value.to_ne_bytes());
20355 self
20356 }
20357 pub fn push_tcn_timer(mut self, value: u64) -> Self {
20358 push_header(self.as_rec_mut(), 17u16, 8 as u16);
20359 self.as_rec_mut().extend(value.to_ne_bytes());
20360 self
20361 }
20362 pub fn push_topology_change_timer(mut self, value: u64) -> Self {
20363 push_header(self.as_rec_mut(), 18u16, 8 as u16);
20364 self.as_rec_mut().extend(value.to_ne_bytes());
20365 self
20366 }
20367 pub fn push_gc_timer(mut self, value: u64) -> Self {
20368 push_header(self.as_rec_mut(), 19u16, 8 as u16);
20369 self.as_rec_mut().extend(value.to_ne_bytes());
20370 self
20371 }
20372 pub fn push_group_addr(mut self, value: &[u8]) -> Self {
20373 push_header(self.as_rec_mut(), 20u16, value.len() as u16);
20374 self.as_rec_mut().extend(value);
20375 self
20376 }
20377 pub fn push_fdb_flush(mut self, value: &[u8]) -> Self {
20378 push_header(self.as_rec_mut(), 21u16, value.len() as u16);
20379 self.as_rec_mut().extend(value);
20380 self
20381 }
20382 pub fn push_mcast_router(mut self, value: u8) -> Self {
20383 push_header(self.as_rec_mut(), 22u16, 1 as u16);
20384 self.as_rec_mut().extend(value.to_ne_bytes());
20385 self
20386 }
20387 pub fn push_mcast_snooping(mut self, value: u8) -> Self {
20388 push_header(self.as_rec_mut(), 23u16, 1 as u16);
20389 self.as_rec_mut().extend(value.to_ne_bytes());
20390 self
20391 }
20392 pub fn push_mcast_query_use_ifaddr(mut self, value: u8) -> Self {
20393 push_header(self.as_rec_mut(), 24u16, 1 as u16);
20394 self.as_rec_mut().extend(value.to_ne_bytes());
20395 self
20396 }
20397 pub fn push_mcast_querier(mut self, value: u8) -> Self {
20398 push_header(self.as_rec_mut(), 25u16, 1 as u16);
20399 self.as_rec_mut().extend(value.to_ne_bytes());
20400 self
20401 }
20402 pub fn push_mcast_hash_elasticity(mut self, value: u32) -> Self {
20403 push_header(self.as_rec_mut(), 26u16, 4 as u16);
20404 self.as_rec_mut().extend(value.to_ne_bytes());
20405 self
20406 }
20407 pub fn push_mcast_hash_max(mut self, value: u32) -> Self {
20408 push_header(self.as_rec_mut(), 27u16, 4 as u16);
20409 self.as_rec_mut().extend(value.to_ne_bytes());
20410 self
20411 }
20412 pub fn push_mcast_last_member_cnt(mut self, value: u32) -> Self {
20413 push_header(self.as_rec_mut(), 28u16, 4 as u16);
20414 self.as_rec_mut().extend(value.to_ne_bytes());
20415 self
20416 }
20417 pub fn push_mcast_startup_query_cnt(mut self, value: u32) -> Self {
20418 push_header(self.as_rec_mut(), 29u16, 4 as u16);
20419 self.as_rec_mut().extend(value.to_ne_bytes());
20420 self
20421 }
20422 pub fn push_mcast_last_member_intvl(mut self, value: u64) -> Self {
20423 push_header(self.as_rec_mut(), 30u16, 8 as u16);
20424 self.as_rec_mut().extend(value.to_ne_bytes());
20425 self
20426 }
20427 pub fn push_mcast_membership_intvl(mut self, value: u64) -> Self {
20428 push_header(self.as_rec_mut(), 31u16, 8 as u16);
20429 self.as_rec_mut().extend(value.to_ne_bytes());
20430 self
20431 }
20432 pub fn push_mcast_querier_intvl(mut self, value: u64) -> Self {
20433 push_header(self.as_rec_mut(), 32u16, 8 as u16);
20434 self.as_rec_mut().extend(value.to_ne_bytes());
20435 self
20436 }
20437 pub fn push_mcast_query_intvl(mut self, value: u64) -> Self {
20438 push_header(self.as_rec_mut(), 33u16, 8 as u16);
20439 self.as_rec_mut().extend(value.to_ne_bytes());
20440 self
20441 }
20442 pub fn push_mcast_query_response_intvl(mut self, value: u64) -> Self {
20443 push_header(self.as_rec_mut(), 34u16, 8 as u16);
20444 self.as_rec_mut().extend(value.to_ne_bytes());
20445 self
20446 }
20447 pub fn push_mcast_startup_query_intvl(mut self, value: u64) -> Self {
20448 push_header(self.as_rec_mut(), 35u16, 8 as u16);
20449 self.as_rec_mut().extend(value.to_ne_bytes());
20450 self
20451 }
20452 pub fn push_nf_call_iptables(mut self, value: u8) -> Self {
20453 push_header(self.as_rec_mut(), 36u16, 1 as u16);
20454 self.as_rec_mut().extend(value.to_ne_bytes());
20455 self
20456 }
20457 pub fn push_nf_call_ip6tables(mut self, value: u8) -> Self {
20458 push_header(self.as_rec_mut(), 37u16, 1 as u16);
20459 self.as_rec_mut().extend(value.to_ne_bytes());
20460 self
20461 }
20462 pub fn push_nf_call_arptables(mut self, value: u8) -> Self {
20463 push_header(self.as_rec_mut(), 38u16, 1 as u16);
20464 self.as_rec_mut().extend(value.to_ne_bytes());
20465 self
20466 }
20467 pub fn push_vlan_default_pvid(mut self, value: u16) -> Self {
20468 push_header(self.as_rec_mut(), 39u16, 2 as u16);
20469 self.as_rec_mut().extend(value.to_ne_bytes());
20470 self
20471 }
20472 pub fn push_pad(mut self, value: &[u8]) -> Self {
20473 push_header(self.as_rec_mut(), 40u16, value.len() as u16);
20474 self.as_rec_mut().extend(value);
20475 self
20476 }
20477 pub fn push_vlan_stats_enabled(mut self, value: u8) -> Self {
20478 push_header(self.as_rec_mut(), 41u16, 1 as u16);
20479 self.as_rec_mut().extend(value.to_ne_bytes());
20480 self
20481 }
20482 pub fn push_mcast_stats_enabled(mut self, value: u8) -> Self {
20483 push_header(self.as_rec_mut(), 42u16, 1 as u16);
20484 self.as_rec_mut().extend(value.to_ne_bytes());
20485 self
20486 }
20487 pub fn push_mcast_igmp_version(mut self, value: u8) -> Self {
20488 push_header(self.as_rec_mut(), 43u16, 1 as u16);
20489 self.as_rec_mut().extend(value.to_ne_bytes());
20490 self
20491 }
20492 pub fn push_mcast_mld_version(mut self, value: u8) -> Self {
20493 push_header(self.as_rec_mut(), 44u16, 1 as u16);
20494 self.as_rec_mut().extend(value.to_ne_bytes());
20495 self
20496 }
20497 pub fn push_vlan_stats_per_port(mut self, value: u8) -> Self {
20498 push_header(self.as_rec_mut(), 45u16, 1 as u16);
20499 self.as_rec_mut().extend(value.to_ne_bytes());
20500 self
20501 }
20502 pub fn push_multi_boolopt(mut self, value: BrBooloptMulti) -> Self {
20503 push_header(self.as_rec_mut(), 46u16, value.as_slice().len() as u16);
20504 self.as_rec_mut().extend(value.as_slice());
20505 self
20506 }
20507 pub fn push_mcast_querier_state(mut self, value: &[u8]) -> Self {
20508 push_header(self.as_rec_mut(), 47u16, value.len() as u16);
20509 self.as_rec_mut().extend(value);
20510 self
20511 }
20512 pub fn push_fdb_n_learned(mut self, value: u32) -> Self {
20513 push_header(self.as_rec_mut(), 48u16, 4 as u16);
20514 self.as_rec_mut().extend(value.to_ne_bytes());
20515 self
20516 }
20517 pub fn push_fdb_max_learned(mut self, value: u32) -> Self {
20518 push_header(self.as_rec_mut(), 49u16, 4 as u16);
20519 self.as_rec_mut().extend(value.to_ne_bytes());
20520 self
20521 }
20522}
20523impl<Prev: Rec> Drop for PushLinkinfoBridgeAttrs<Prev> {
20524 fn drop(&mut self) {
20525 if let Some(prev) = &mut self.prev {
20526 if let Some(header_offset) = &self.header_offset {
20527 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20528 }
20529 }
20530 }
20531}
20532pub struct PushLinkinfoBrportAttrs<Prev: Rec> {
20533 pub(crate) prev: Option<Prev>,
20534 pub(crate) header_offset: Option<usize>,
20535}
20536impl<Prev: Rec> Rec for PushLinkinfoBrportAttrs<Prev> {
20537 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20538 self.prev.as_mut().unwrap().as_rec_mut()
20539 }
20540 fn as_rec(&self) -> &Vec<u8> {
20541 self.prev.as_ref().unwrap().as_rec()
20542 }
20543}
20544impl<Prev: Rec> PushLinkinfoBrportAttrs<Prev> {
20545 pub fn new(prev: Prev) -> Self {
20546 Self {
20547 prev: Some(prev),
20548 header_offset: None,
20549 }
20550 }
20551 pub fn end_nested(mut self) -> Prev {
20552 let mut prev = self.prev.take().unwrap();
20553 if let Some(header_offset) = &self.header_offset {
20554 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20555 }
20556 prev
20557 }
20558 pub fn push_state(mut self, value: u8) -> Self {
20559 push_header(self.as_rec_mut(), 1u16, 1 as u16);
20560 self.as_rec_mut().extend(value.to_ne_bytes());
20561 self
20562 }
20563 pub fn push_priority(mut self, value: u16) -> Self {
20564 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20565 self.as_rec_mut().extend(value.to_ne_bytes());
20566 self
20567 }
20568 pub fn push_cost(mut self, value: u32) -> Self {
20569 push_header(self.as_rec_mut(), 3u16, 4 as u16);
20570 self.as_rec_mut().extend(value.to_ne_bytes());
20571 self
20572 }
20573 pub fn push_mode(mut self, value: ()) -> Self {
20574 push_header(self.as_rec_mut(), 4u16, 0 as u16);
20575 self
20576 }
20577 pub fn push_guard(mut self, value: ()) -> Self {
20578 push_header(self.as_rec_mut(), 5u16, 0 as u16);
20579 self
20580 }
20581 pub fn push_protect(mut self, value: ()) -> Self {
20582 push_header(self.as_rec_mut(), 6u16, 0 as u16);
20583 self
20584 }
20585 pub fn push_fast_leave(mut self, value: ()) -> Self {
20586 push_header(self.as_rec_mut(), 7u16, 0 as u16);
20587 self
20588 }
20589 pub fn push_learning(mut self, value: ()) -> Self {
20590 push_header(self.as_rec_mut(), 8u16, 0 as u16);
20591 self
20592 }
20593 pub fn push_unicast_flood(mut self, value: ()) -> Self {
20594 push_header(self.as_rec_mut(), 9u16, 0 as u16);
20595 self
20596 }
20597 pub fn push_proxyarp(mut self, value: ()) -> Self {
20598 push_header(self.as_rec_mut(), 10u16, 0 as u16);
20599 self
20600 }
20601 pub fn push_learning_sync(mut self, value: ()) -> Self {
20602 push_header(self.as_rec_mut(), 11u16, 0 as u16);
20603 self
20604 }
20605 pub fn push_proxyarp_wifi(mut self, value: ()) -> Self {
20606 push_header(self.as_rec_mut(), 12u16, 0 as u16);
20607 self
20608 }
20609 pub fn push_root_id(mut self, value: IflaBridgeId) -> Self {
20610 push_header(self.as_rec_mut(), 13u16, value.as_slice().len() as u16);
20611 self.as_rec_mut().extend(value.as_slice());
20612 self
20613 }
20614 pub fn push_bridge_id(mut self, value: IflaBridgeId) -> Self {
20615 push_header(self.as_rec_mut(), 14u16, value.as_slice().len() as u16);
20616 self.as_rec_mut().extend(value.as_slice());
20617 self
20618 }
20619 pub fn push_designated_port(mut self, value: u16) -> Self {
20620 push_header(self.as_rec_mut(), 15u16, 2 as u16);
20621 self.as_rec_mut().extend(value.to_ne_bytes());
20622 self
20623 }
20624 pub fn push_designated_cost(mut self, value: u16) -> Self {
20625 push_header(self.as_rec_mut(), 16u16, 2 as u16);
20626 self.as_rec_mut().extend(value.to_ne_bytes());
20627 self
20628 }
20629 pub fn push_id(mut self, value: u16) -> Self {
20630 push_header(self.as_rec_mut(), 17u16, 2 as u16);
20631 self.as_rec_mut().extend(value.to_ne_bytes());
20632 self
20633 }
20634 pub fn push_no(mut self, value: u16) -> Self {
20635 push_header(self.as_rec_mut(), 18u16, 2 as u16);
20636 self.as_rec_mut().extend(value.to_ne_bytes());
20637 self
20638 }
20639 pub fn push_topology_change_ack(mut self, value: u8) -> Self {
20640 push_header(self.as_rec_mut(), 19u16, 1 as u16);
20641 self.as_rec_mut().extend(value.to_ne_bytes());
20642 self
20643 }
20644 pub fn push_config_pending(mut self, value: u8) -> Self {
20645 push_header(self.as_rec_mut(), 20u16, 1 as u16);
20646 self.as_rec_mut().extend(value.to_ne_bytes());
20647 self
20648 }
20649 pub fn push_message_age_timer(mut self, value: u64) -> Self {
20650 push_header(self.as_rec_mut(), 21u16, 8 as u16);
20651 self.as_rec_mut().extend(value.to_ne_bytes());
20652 self
20653 }
20654 pub fn push_forward_delay_timer(mut self, value: u64) -> Self {
20655 push_header(self.as_rec_mut(), 22u16, 8 as u16);
20656 self.as_rec_mut().extend(value.to_ne_bytes());
20657 self
20658 }
20659 pub fn push_hold_timer(mut self, value: u64) -> Self {
20660 push_header(self.as_rec_mut(), 23u16, 8 as u16);
20661 self.as_rec_mut().extend(value.to_ne_bytes());
20662 self
20663 }
20664 pub fn push_flush(mut self, value: ()) -> Self {
20665 push_header(self.as_rec_mut(), 24u16, 0 as u16);
20666 self
20667 }
20668 pub fn push_multicast_router(mut self, value: u8) -> Self {
20669 push_header(self.as_rec_mut(), 25u16, 1 as u16);
20670 self.as_rec_mut().extend(value.to_ne_bytes());
20671 self
20672 }
20673 pub fn push_pad(mut self, value: &[u8]) -> Self {
20674 push_header(self.as_rec_mut(), 26u16, value.len() as u16);
20675 self.as_rec_mut().extend(value);
20676 self
20677 }
20678 pub fn push_mcast_flood(mut self, value: ()) -> Self {
20679 push_header(self.as_rec_mut(), 27u16, 0 as u16);
20680 self
20681 }
20682 pub fn push_mcast_to_ucast(mut self, value: ()) -> Self {
20683 push_header(self.as_rec_mut(), 28u16, 0 as u16);
20684 self
20685 }
20686 pub fn push_vlan_tunnel(mut self, value: ()) -> Self {
20687 push_header(self.as_rec_mut(), 29u16, 0 as u16);
20688 self
20689 }
20690 pub fn push_bcast_flood(mut self, value: ()) -> Self {
20691 push_header(self.as_rec_mut(), 30u16, 0 as u16);
20692 self
20693 }
20694 pub fn push_group_fwd_mask(mut self, value: u16) -> Self {
20695 push_header(self.as_rec_mut(), 31u16, 2 as u16);
20696 self.as_rec_mut().extend(value.to_ne_bytes());
20697 self
20698 }
20699 pub fn push_neigh_suppress(mut self, value: ()) -> Self {
20700 push_header(self.as_rec_mut(), 32u16, 0 as u16);
20701 self
20702 }
20703 pub fn push_isolated(mut self, value: ()) -> Self {
20704 push_header(self.as_rec_mut(), 33u16, 0 as u16);
20705 self
20706 }
20707 pub fn push_backup_port(mut self, value: u32) -> Self {
20708 push_header(self.as_rec_mut(), 34u16, 4 as u16);
20709 self.as_rec_mut().extend(value.to_ne_bytes());
20710 self
20711 }
20712 pub fn push_mrp_ring_open(mut self, value: ()) -> Self {
20713 push_header(self.as_rec_mut(), 35u16, 0 as u16);
20714 self
20715 }
20716 pub fn push_mrp_in_open(mut self, value: ()) -> Self {
20717 push_header(self.as_rec_mut(), 36u16, 0 as u16);
20718 self
20719 }
20720 pub fn push_mcast_eht_hosts_limit(mut self, value: u32) -> Self {
20721 push_header(self.as_rec_mut(), 37u16, 4 as u16);
20722 self.as_rec_mut().extend(value.to_ne_bytes());
20723 self
20724 }
20725 pub fn push_mcast_eht_hosts_cnt(mut self, value: u32) -> Self {
20726 push_header(self.as_rec_mut(), 38u16, 4 as u16);
20727 self.as_rec_mut().extend(value.to_ne_bytes());
20728 self
20729 }
20730 pub fn push_locked(mut self, value: ()) -> Self {
20731 push_header(self.as_rec_mut(), 39u16, 0 as u16);
20732 self
20733 }
20734 pub fn push_mab(mut self, value: ()) -> Self {
20735 push_header(self.as_rec_mut(), 40u16, 0 as u16);
20736 self
20737 }
20738 pub fn push_mcast_n_groups(mut self, value: u32) -> Self {
20739 push_header(self.as_rec_mut(), 41u16, 4 as u16);
20740 self.as_rec_mut().extend(value.to_ne_bytes());
20741 self
20742 }
20743 pub fn push_mcast_max_groups(mut self, value: u32) -> Self {
20744 push_header(self.as_rec_mut(), 42u16, 4 as u16);
20745 self.as_rec_mut().extend(value.to_ne_bytes());
20746 self
20747 }
20748 pub fn push_neigh_vlan_suppress(mut self, value: ()) -> Self {
20749 push_header(self.as_rec_mut(), 43u16, 0 as u16);
20750 self
20751 }
20752 pub fn push_backup_nhid(mut self, value: u32) -> Self {
20753 push_header(self.as_rec_mut(), 44u16, 4 as u16);
20754 self.as_rec_mut().extend(value.to_ne_bytes());
20755 self
20756 }
20757}
20758impl<Prev: Rec> Drop for PushLinkinfoBrportAttrs<Prev> {
20759 fn drop(&mut self) {
20760 if let Some(prev) = &mut self.prev {
20761 if let Some(header_offset) = &self.header_offset {
20762 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20763 }
20764 }
20765 }
20766}
20767pub struct PushLinkinfoGreAttrs<Prev: Rec> {
20768 pub(crate) prev: Option<Prev>,
20769 pub(crate) header_offset: Option<usize>,
20770}
20771impl<Prev: Rec> Rec for PushLinkinfoGreAttrs<Prev> {
20772 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20773 self.prev.as_mut().unwrap().as_rec_mut()
20774 }
20775 fn as_rec(&self) -> &Vec<u8> {
20776 self.prev.as_ref().unwrap().as_rec()
20777 }
20778}
20779impl<Prev: Rec> PushLinkinfoGreAttrs<Prev> {
20780 pub fn new(prev: Prev) -> Self {
20781 Self {
20782 prev: Some(prev),
20783 header_offset: None,
20784 }
20785 }
20786 pub fn end_nested(mut self) -> Prev {
20787 let mut prev = self.prev.take().unwrap();
20788 if let Some(header_offset) = &self.header_offset {
20789 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20790 }
20791 prev
20792 }
20793 pub fn push_link(mut self, value: u32) -> Self {
20794 push_header(self.as_rec_mut(), 1u16, 4 as u16);
20795 self.as_rec_mut().extend(value.to_ne_bytes());
20796 self
20797 }
20798 pub fn push_iflags(mut self, value: u16) -> Self {
20799 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20800 self.as_rec_mut().extend(value.to_be_bytes());
20801 self
20802 }
20803 pub fn push_oflags(mut self, value: u16) -> Self {
20804 push_header(self.as_rec_mut(), 3u16, 2 as u16);
20805 self.as_rec_mut().extend(value.to_be_bytes());
20806 self
20807 }
20808 pub fn push_ikey(mut self, value: u32) -> Self {
20809 push_header(self.as_rec_mut(), 4u16, 4 as u16);
20810 self.as_rec_mut().extend(value.to_be_bytes());
20811 self
20812 }
20813 pub fn push_okey(mut self, value: u32) -> Self {
20814 push_header(self.as_rec_mut(), 5u16, 4 as u16);
20815 self.as_rec_mut().extend(value.to_be_bytes());
20816 self
20817 }
20818 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
20819 push_header(self.as_rec_mut(), 6u16, {
20820 match &value {
20821 IpAddr::V4(_) => 4,
20822 IpAddr::V6(_) => 16,
20823 }
20824 } as u16);
20825 encode_ip(self.as_rec_mut(), value);
20826 self
20827 }
20828 pub fn push_remote(mut self, value: std::net::IpAddr) -> Self {
20829 push_header(self.as_rec_mut(), 7u16, {
20830 match &value {
20831 IpAddr::V4(_) => 4,
20832 IpAddr::V6(_) => 16,
20833 }
20834 } as u16);
20835 encode_ip(self.as_rec_mut(), value);
20836 self
20837 }
20838 pub fn push_ttl(mut self, value: u8) -> Self {
20839 push_header(self.as_rec_mut(), 8u16, 1 as u16);
20840 self.as_rec_mut().extend(value.to_ne_bytes());
20841 self
20842 }
20843 pub fn push_tos(mut self, value: u8) -> Self {
20844 push_header(self.as_rec_mut(), 9u16, 1 as u16);
20845 self.as_rec_mut().extend(value.to_ne_bytes());
20846 self
20847 }
20848 pub fn push_pmtudisc(mut self, value: u8) -> Self {
20849 push_header(self.as_rec_mut(), 10u16, 1 as u16);
20850 self.as_rec_mut().extend(value.to_ne_bytes());
20851 self
20852 }
20853 pub fn push_encap_limit(mut self, value: u8) -> Self {
20854 push_header(self.as_rec_mut(), 11u16, 1 as u16);
20855 self.as_rec_mut().extend(value.to_ne_bytes());
20856 self
20857 }
20858 pub fn push_flowinfo(mut self, value: u32) -> Self {
20859 push_header(self.as_rec_mut(), 12u16, 4 as u16);
20860 self.as_rec_mut().extend(value.to_be_bytes());
20861 self
20862 }
20863 pub fn push_flags(mut self, value: u32) -> Self {
20864 push_header(self.as_rec_mut(), 13u16, 4 as u16);
20865 self.as_rec_mut().extend(value.to_ne_bytes());
20866 self
20867 }
20868 pub fn push_encap_type(mut self, value: u16) -> Self {
20869 push_header(self.as_rec_mut(), 14u16, 2 as u16);
20870 self.as_rec_mut().extend(value.to_ne_bytes());
20871 self
20872 }
20873 pub fn push_encap_flags(mut self, value: u16) -> Self {
20874 push_header(self.as_rec_mut(), 15u16, 2 as u16);
20875 self.as_rec_mut().extend(value.to_ne_bytes());
20876 self
20877 }
20878 pub fn push_encap_sport(mut self, value: u16) -> Self {
20879 push_header(self.as_rec_mut(), 16u16, 2 as u16);
20880 self.as_rec_mut().extend(value.to_be_bytes());
20881 self
20882 }
20883 pub fn push_encap_dport(mut self, value: u16) -> Self {
20884 push_header(self.as_rec_mut(), 17u16, 2 as u16);
20885 self.as_rec_mut().extend(value.to_be_bytes());
20886 self
20887 }
20888 pub fn push_collect_metadata(mut self, value: ()) -> Self {
20889 push_header(self.as_rec_mut(), 18u16, 0 as u16);
20890 self
20891 }
20892 pub fn push_ignore_df(mut self, value: u8) -> Self {
20893 push_header(self.as_rec_mut(), 19u16, 1 as u16);
20894 self.as_rec_mut().extend(value.to_ne_bytes());
20895 self
20896 }
20897 pub fn push_fwmark(mut self, value: u32) -> Self {
20898 push_header(self.as_rec_mut(), 20u16, 4 as u16);
20899 self.as_rec_mut().extend(value.to_ne_bytes());
20900 self
20901 }
20902 pub fn push_erspan_index(mut self, value: u32) -> Self {
20903 push_header(self.as_rec_mut(), 21u16, 4 as u16);
20904 self.as_rec_mut().extend(value.to_ne_bytes());
20905 self
20906 }
20907 pub fn push_erspan_ver(mut self, value: u8) -> Self {
20908 push_header(self.as_rec_mut(), 22u16, 1 as u16);
20909 self.as_rec_mut().extend(value.to_ne_bytes());
20910 self
20911 }
20912 pub fn push_erspan_dir(mut self, value: u8) -> Self {
20913 push_header(self.as_rec_mut(), 23u16, 1 as u16);
20914 self.as_rec_mut().extend(value.to_ne_bytes());
20915 self
20916 }
20917 pub fn push_erspan_hwid(mut self, value: u16) -> Self {
20918 push_header(self.as_rec_mut(), 24u16, 2 as u16);
20919 self.as_rec_mut().extend(value.to_ne_bytes());
20920 self
20921 }
20922}
20923impl<Prev: Rec> Drop for PushLinkinfoGreAttrs<Prev> {
20924 fn drop(&mut self) {
20925 if let Some(prev) = &mut self.prev {
20926 if let Some(header_offset) = &self.header_offset {
20927 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20928 }
20929 }
20930 }
20931}
20932pub struct PushLinkinfoGre6Attrs<Prev: Rec> {
20933 pub(crate) prev: Option<Prev>,
20934 pub(crate) header_offset: Option<usize>,
20935}
20936impl<Prev: Rec> Rec for PushLinkinfoGre6Attrs<Prev> {
20937 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
20938 self.prev.as_mut().unwrap().as_rec_mut()
20939 }
20940 fn as_rec(&self) -> &Vec<u8> {
20941 self.prev.as_ref().unwrap().as_rec()
20942 }
20943}
20944impl<Prev: Rec> PushLinkinfoGre6Attrs<Prev> {
20945 pub fn new(prev: Prev) -> Self {
20946 Self {
20947 prev: Some(prev),
20948 header_offset: None,
20949 }
20950 }
20951 pub fn end_nested(mut self) -> Prev {
20952 let mut prev = self.prev.take().unwrap();
20953 if let Some(header_offset) = &self.header_offset {
20954 finalize_nested_header(prev.as_rec_mut(), *header_offset);
20955 }
20956 prev
20957 }
20958 pub fn push_link(mut self, value: u32) -> Self {
20959 push_header(self.as_rec_mut(), 1u16, 4 as u16);
20960 self.as_rec_mut().extend(value.to_ne_bytes());
20961 self
20962 }
20963 pub fn push_iflags(mut self, value: u16) -> Self {
20964 push_header(self.as_rec_mut(), 2u16, 2 as u16);
20965 self.as_rec_mut().extend(value.to_be_bytes());
20966 self
20967 }
20968 pub fn push_oflags(mut self, value: u16) -> Self {
20969 push_header(self.as_rec_mut(), 3u16, 2 as u16);
20970 self.as_rec_mut().extend(value.to_be_bytes());
20971 self
20972 }
20973 pub fn push_ikey(mut self, value: u32) -> Self {
20974 push_header(self.as_rec_mut(), 4u16, 4 as u16);
20975 self.as_rec_mut().extend(value.to_be_bytes());
20976 self
20977 }
20978 pub fn push_okey(mut self, value: u32) -> Self {
20979 push_header(self.as_rec_mut(), 5u16, 4 as u16);
20980 self.as_rec_mut().extend(value.to_be_bytes());
20981 self
20982 }
20983 pub fn push_local(mut self, value: &[u8]) -> Self {
20984 push_header(self.as_rec_mut(), 6u16, value.len() as u16);
20985 self.as_rec_mut().extend(value);
20986 self
20987 }
20988 pub fn push_remote(mut self, value: &[u8]) -> Self {
20989 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
20990 self.as_rec_mut().extend(value);
20991 self
20992 }
20993 pub fn push_ttl(mut self, value: u8) -> Self {
20994 push_header(self.as_rec_mut(), 8u16, 1 as u16);
20995 self.as_rec_mut().extend(value.to_ne_bytes());
20996 self
20997 }
20998 pub fn push_encap_limit(mut self, value: u8) -> Self {
20999 push_header(self.as_rec_mut(), 11u16, 1 as u16);
21000 self.as_rec_mut().extend(value.to_ne_bytes());
21001 self
21002 }
21003 pub fn push_flowinfo(mut self, value: u32) -> Self {
21004 push_header(self.as_rec_mut(), 12u16, 4 as u16);
21005 self.as_rec_mut().extend(value.to_be_bytes());
21006 self
21007 }
21008 pub fn push_flags(mut self, value: u32) -> Self {
21009 push_header(self.as_rec_mut(), 13u16, 4 as u16);
21010 self.as_rec_mut().extend(value.to_ne_bytes());
21011 self
21012 }
21013 pub fn push_encap_type(mut self, value: u16) -> Self {
21014 push_header(self.as_rec_mut(), 14u16, 2 as u16);
21015 self.as_rec_mut().extend(value.to_ne_bytes());
21016 self
21017 }
21018 pub fn push_encap_flags(mut self, value: u16) -> Self {
21019 push_header(self.as_rec_mut(), 15u16, 2 as u16);
21020 self.as_rec_mut().extend(value.to_ne_bytes());
21021 self
21022 }
21023 pub fn push_encap_sport(mut self, value: u16) -> Self {
21024 push_header(self.as_rec_mut(), 16u16, 2 as u16);
21025 self.as_rec_mut().extend(value.to_be_bytes());
21026 self
21027 }
21028 pub fn push_encap_dport(mut self, value: u16) -> Self {
21029 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21030 self.as_rec_mut().extend(value.to_be_bytes());
21031 self
21032 }
21033 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21034 push_header(self.as_rec_mut(), 18u16, 0 as u16);
21035 self
21036 }
21037 pub fn push_fwmark(mut self, value: u32) -> Self {
21038 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21039 self.as_rec_mut().extend(value.to_ne_bytes());
21040 self
21041 }
21042 pub fn push_erspan_index(mut self, value: u32) -> Self {
21043 push_header(self.as_rec_mut(), 21u16, 4 as u16);
21044 self.as_rec_mut().extend(value.to_ne_bytes());
21045 self
21046 }
21047 pub fn push_erspan_ver(mut self, value: u8) -> Self {
21048 push_header(self.as_rec_mut(), 22u16, 1 as u16);
21049 self.as_rec_mut().extend(value.to_ne_bytes());
21050 self
21051 }
21052 pub fn push_erspan_dir(mut self, value: u8) -> Self {
21053 push_header(self.as_rec_mut(), 23u16, 1 as u16);
21054 self.as_rec_mut().extend(value.to_ne_bytes());
21055 self
21056 }
21057 pub fn push_erspan_hwid(mut self, value: u16) -> Self {
21058 push_header(self.as_rec_mut(), 24u16, 2 as u16);
21059 self.as_rec_mut().extend(value.to_ne_bytes());
21060 self
21061 }
21062}
21063impl<Prev: Rec> Drop for PushLinkinfoGre6Attrs<Prev> {
21064 fn drop(&mut self) {
21065 if let Some(prev) = &mut self.prev {
21066 if let Some(header_offset) = &self.header_offset {
21067 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21068 }
21069 }
21070 }
21071}
21072pub struct PushLinkinfoVtiAttrs<Prev: Rec> {
21073 pub(crate) prev: Option<Prev>,
21074 pub(crate) header_offset: Option<usize>,
21075}
21076impl<Prev: Rec> Rec for PushLinkinfoVtiAttrs<Prev> {
21077 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21078 self.prev.as_mut().unwrap().as_rec_mut()
21079 }
21080 fn as_rec(&self) -> &Vec<u8> {
21081 self.prev.as_ref().unwrap().as_rec()
21082 }
21083}
21084impl<Prev: Rec> PushLinkinfoVtiAttrs<Prev> {
21085 pub fn new(prev: Prev) -> Self {
21086 Self {
21087 prev: Some(prev),
21088 header_offset: None,
21089 }
21090 }
21091 pub fn end_nested(mut self) -> Prev {
21092 let mut prev = self.prev.take().unwrap();
21093 if let Some(header_offset) = &self.header_offset {
21094 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21095 }
21096 prev
21097 }
21098 pub fn push_link(mut self, value: u32) -> Self {
21099 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21100 self.as_rec_mut().extend(value.to_ne_bytes());
21101 self
21102 }
21103 pub fn push_ikey(mut self, value: u32) -> Self {
21104 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21105 self.as_rec_mut().extend(value.to_be_bytes());
21106 self
21107 }
21108 pub fn push_okey(mut self, value: u32) -> Self {
21109 push_header(self.as_rec_mut(), 3u16, 4 as u16);
21110 self.as_rec_mut().extend(value.to_be_bytes());
21111 self
21112 }
21113 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
21114 push_header(self.as_rec_mut(), 4u16, {
21115 match &value {
21116 IpAddr::V4(_) => 4,
21117 IpAddr::V6(_) => 16,
21118 }
21119 } as u16);
21120 encode_ip(self.as_rec_mut(), value);
21121 self
21122 }
21123 pub fn push_remote(mut self, value: std::net::IpAddr) -> Self {
21124 push_header(self.as_rec_mut(), 5u16, {
21125 match &value {
21126 IpAddr::V4(_) => 4,
21127 IpAddr::V6(_) => 16,
21128 }
21129 } as u16);
21130 encode_ip(self.as_rec_mut(), value);
21131 self
21132 }
21133 pub fn push_fwmark(mut self, value: u32) -> Self {
21134 push_header(self.as_rec_mut(), 6u16, 4 as u16);
21135 self.as_rec_mut().extend(value.to_ne_bytes());
21136 self
21137 }
21138}
21139impl<Prev: Rec> Drop for PushLinkinfoVtiAttrs<Prev> {
21140 fn drop(&mut self) {
21141 if let Some(prev) = &mut self.prev {
21142 if let Some(header_offset) = &self.header_offset {
21143 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21144 }
21145 }
21146 }
21147}
21148pub struct PushLinkinfoVti6Attrs<Prev: Rec> {
21149 pub(crate) prev: Option<Prev>,
21150 pub(crate) header_offset: Option<usize>,
21151}
21152impl<Prev: Rec> Rec for PushLinkinfoVti6Attrs<Prev> {
21153 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21154 self.prev.as_mut().unwrap().as_rec_mut()
21155 }
21156 fn as_rec(&self) -> &Vec<u8> {
21157 self.prev.as_ref().unwrap().as_rec()
21158 }
21159}
21160impl<Prev: Rec> PushLinkinfoVti6Attrs<Prev> {
21161 pub fn new(prev: Prev) -> Self {
21162 Self {
21163 prev: Some(prev),
21164 header_offset: None,
21165 }
21166 }
21167 pub fn end_nested(mut self) -> Prev {
21168 let mut prev = self.prev.take().unwrap();
21169 if let Some(header_offset) = &self.header_offset {
21170 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21171 }
21172 prev
21173 }
21174 pub fn push_link(mut self, value: u32) -> Self {
21175 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21176 self.as_rec_mut().extend(value.to_ne_bytes());
21177 self
21178 }
21179 pub fn push_ikey(mut self, value: u32) -> Self {
21180 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21181 self.as_rec_mut().extend(value.to_be_bytes());
21182 self
21183 }
21184 pub fn push_okey(mut self, value: u32) -> Self {
21185 push_header(self.as_rec_mut(), 3u16, 4 as u16);
21186 self.as_rec_mut().extend(value.to_be_bytes());
21187 self
21188 }
21189 pub fn push_local(mut self, value: &[u8]) -> Self {
21190 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
21191 self.as_rec_mut().extend(value);
21192 self
21193 }
21194 pub fn push_remote(mut self, value: &[u8]) -> Self {
21195 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
21196 self.as_rec_mut().extend(value);
21197 self
21198 }
21199 pub fn push_fwmark(mut self, value: u32) -> Self {
21200 push_header(self.as_rec_mut(), 6u16, 4 as u16);
21201 self.as_rec_mut().extend(value.to_ne_bytes());
21202 self
21203 }
21204}
21205impl<Prev: Rec> Drop for PushLinkinfoVti6Attrs<Prev> {
21206 fn drop(&mut self) {
21207 if let Some(prev) = &mut self.prev {
21208 if let Some(header_offset) = &self.header_offset {
21209 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21210 }
21211 }
21212 }
21213}
21214pub struct PushLinkinfoGeneveAttrs<Prev: Rec> {
21215 pub(crate) prev: Option<Prev>,
21216 pub(crate) header_offset: Option<usize>,
21217}
21218impl<Prev: Rec> Rec for PushLinkinfoGeneveAttrs<Prev> {
21219 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21220 self.prev.as_mut().unwrap().as_rec_mut()
21221 }
21222 fn as_rec(&self) -> &Vec<u8> {
21223 self.prev.as_ref().unwrap().as_rec()
21224 }
21225}
21226impl<Prev: Rec> PushLinkinfoGeneveAttrs<Prev> {
21227 pub fn new(prev: Prev) -> Self {
21228 Self {
21229 prev: Some(prev),
21230 header_offset: None,
21231 }
21232 }
21233 pub fn end_nested(mut self) -> Prev {
21234 let mut prev = self.prev.take().unwrap();
21235 if let Some(header_offset) = &self.header_offset {
21236 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21237 }
21238 prev
21239 }
21240 pub fn push_id(mut self, value: u32) -> Self {
21241 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21242 self.as_rec_mut().extend(value.to_ne_bytes());
21243 self
21244 }
21245 pub fn push_remote(mut self, value: std::net::Ipv4Addr) -> Self {
21246 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21247 self.as_rec_mut().extend(&value.to_bits().to_be_bytes());
21248 self
21249 }
21250 pub fn push_ttl(mut self, value: u8) -> Self {
21251 push_header(self.as_rec_mut(), 3u16, 1 as u16);
21252 self.as_rec_mut().extend(value.to_ne_bytes());
21253 self
21254 }
21255 pub fn push_tos(mut self, value: u8) -> Self {
21256 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21257 self.as_rec_mut().extend(value.to_ne_bytes());
21258 self
21259 }
21260 pub fn push_port(mut self, value: u16) -> Self {
21261 push_header(self.as_rec_mut(), 5u16, 2 as u16);
21262 self.as_rec_mut().extend(value.to_be_bytes());
21263 self
21264 }
21265 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21266 push_header(self.as_rec_mut(), 6u16, 0 as u16);
21267 self
21268 }
21269 pub fn push_remote6(mut self, value: &[u8]) -> Self {
21270 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
21271 self.as_rec_mut().extend(value);
21272 self
21273 }
21274 pub fn push_udp_csum(mut self, value: u8) -> Self {
21275 push_header(self.as_rec_mut(), 8u16, 1 as u16);
21276 self.as_rec_mut().extend(value.to_ne_bytes());
21277 self
21278 }
21279 pub fn push_udp_zero_csum6_tx(mut self, value: u8) -> Self {
21280 push_header(self.as_rec_mut(), 9u16, 1 as u16);
21281 self.as_rec_mut().extend(value.to_ne_bytes());
21282 self
21283 }
21284 pub fn push_udp_zero_csum6_rx(mut self, value: u8) -> Self {
21285 push_header(self.as_rec_mut(), 10u16, 1 as u16);
21286 self.as_rec_mut().extend(value.to_ne_bytes());
21287 self
21288 }
21289 pub fn push_label(mut self, value: u32) -> Self {
21290 push_header(self.as_rec_mut(), 11u16, 4 as u16);
21291 self.as_rec_mut().extend(value.to_be_bytes());
21292 self
21293 }
21294 pub fn push_ttl_inherit(mut self, value: u8) -> Self {
21295 push_header(self.as_rec_mut(), 12u16, 1 as u16);
21296 self.as_rec_mut().extend(value.to_ne_bytes());
21297 self
21298 }
21299 pub fn push_df(mut self, value: u8) -> Self {
21300 push_header(self.as_rec_mut(), 13u16, 1 as u16);
21301 self.as_rec_mut().extend(value.to_ne_bytes());
21302 self
21303 }
21304 pub fn push_inner_proto_inherit(mut self, value: ()) -> Self {
21305 push_header(self.as_rec_mut(), 14u16, 0 as u16);
21306 self
21307 }
21308 pub fn push_port_range(mut self, value: IflaGenevePortRange) -> Self {
21309 push_header(self.as_rec_mut(), 15u16, value.as_slice().len() as u16);
21310 self.as_rec_mut().extend(value.as_slice());
21311 self
21312 }
21313 pub fn push_gro_hint(mut self, value: ()) -> Self {
21314 push_header(self.as_rec_mut(), 16u16, 0 as u16);
21315 self
21316 }
21317}
21318impl<Prev: Rec> Drop for PushLinkinfoGeneveAttrs<Prev> {
21319 fn drop(&mut self) {
21320 if let Some(prev) = &mut self.prev {
21321 if let Some(header_offset) = &self.header_offset {
21322 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21323 }
21324 }
21325 }
21326}
21327pub struct PushLinkinfoHsrAttrs<Prev: Rec> {
21328 pub(crate) prev: Option<Prev>,
21329 pub(crate) header_offset: Option<usize>,
21330}
21331impl<Prev: Rec> Rec for PushLinkinfoHsrAttrs<Prev> {
21332 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21333 self.prev.as_mut().unwrap().as_rec_mut()
21334 }
21335 fn as_rec(&self) -> &Vec<u8> {
21336 self.prev.as_ref().unwrap().as_rec()
21337 }
21338}
21339impl<Prev: Rec> PushLinkinfoHsrAttrs<Prev> {
21340 pub fn new(prev: Prev) -> Self {
21341 Self {
21342 prev: Some(prev),
21343 header_offset: None,
21344 }
21345 }
21346 pub fn end_nested(mut self) -> Prev {
21347 let mut prev = self.prev.take().unwrap();
21348 if let Some(header_offset) = &self.header_offset {
21349 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21350 }
21351 prev
21352 }
21353 pub fn push_slave1(mut self, value: u32) -> Self {
21354 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21355 self.as_rec_mut().extend(value.to_ne_bytes());
21356 self
21357 }
21358 pub fn push_slave2(mut self, value: u32) -> Self {
21359 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21360 self.as_rec_mut().extend(value.to_ne_bytes());
21361 self
21362 }
21363 pub fn push_multicast_spec(mut self, value: u8) -> Self {
21364 push_header(self.as_rec_mut(), 3u16, 1 as u16);
21365 self.as_rec_mut().extend(value.to_ne_bytes());
21366 self
21367 }
21368 pub fn push_supervision_addr(mut self, value: &[u8]) -> Self {
21369 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
21370 self.as_rec_mut().extend(value);
21371 self
21372 }
21373 pub fn push_seq_nr(mut self, value: u16) -> Self {
21374 push_header(self.as_rec_mut(), 5u16, 2 as u16);
21375 self.as_rec_mut().extend(value.to_ne_bytes());
21376 self
21377 }
21378 pub fn push_version(mut self, value: u8) -> Self {
21379 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21380 self.as_rec_mut().extend(value.to_ne_bytes());
21381 self
21382 }
21383 pub fn push_protocol(mut self, value: u8) -> Self {
21384 push_header(self.as_rec_mut(), 7u16, 1 as u16);
21385 self.as_rec_mut().extend(value.to_ne_bytes());
21386 self
21387 }
21388 pub fn push_interlink(mut self, value: u32) -> Self {
21389 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21390 self.as_rec_mut().extend(value.to_ne_bytes());
21391 self
21392 }
21393}
21394impl<Prev: Rec> Drop for PushLinkinfoHsrAttrs<Prev> {
21395 fn drop(&mut self) {
21396 if let Some(prev) = &mut self.prev {
21397 if let Some(header_offset) = &self.header_offset {
21398 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21399 }
21400 }
21401 }
21402}
21403pub struct PushLinkinfoIptunAttrs<Prev: Rec> {
21404 pub(crate) prev: Option<Prev>,
21405 pub(crate) header_offset: Option<usize>,
21406}
21407impl<Prev: Rec> Rec for PushLinkinfoIptunAttrs<Prev> {
21408 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21409 self.prev.as_mut().unwrap().as_rec_mut()
21410 }
21411 fn as_rec(&self) -> &Vec<u8> {
21412 self.prev.as_ref().unwrap().as_rec()
21413 }
21414}
21415impl<Prev: Rec> PushLinkinfoIptunAttrs<Prev> {
21416 pub fn new(prev: Prev) -> Self {
21417 Self {
21418 prev: Some(prev),
21419 header_offset: None,
21420 }
21421 }
21422 pub fn end_nested(mut self) -> Prev {
21423 let mut prev = self.prev.take().unwrap();
21424 if let Some(header_offset) = &self.header_offset {
21425 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21426 }
21427 prev
21428 }
21429 pub fn push_link(mut self, value: u32) -> Self {
21430 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21431 self.as_rec_mut().extend(value.to_ne_bytes());
21432 self
21433 }
21434 pub fn push_local(mut self, value: std::net::IpAddr) -> Self {
21435 push_header(self.as_rec_mut(), 2u16, {
21436 match &value {
21437 IpAddr::V4(_) => 4,
21438 IpAddr::V6(_) => 16,
21439 }
21440 } as u16);
21441 encode_ip(self.as_rec_mut(), value);
21442 self
21443 }
21444 pub fn push_remote(mut self, value: std::net::IpAddr) -> Self {
21445 push_header(self.as_rec_mut(), 3u16, {
21446 match &value {
21447 IpAddr::V4(_) => 4,
21448 IpAddr::V6(_) => 16,
21449 }
21450 } as u16);
21451 encode_ip(self.as_rec_mut(), value);
21452 self
21453 }
21454 pub fn push_ttl(mut self, value: u8) -> Self {
21455 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21456 self.as_rec_mut().extend(value.to_ne_bytes());
21457 self
21458 }
21459 pub fn push_tos(mut self, value: u8) -> Self {
21460 push_header(self.as_rec_mut(), 5u16, 1 as u16);
21461 self.as_rec_mut().extend(value.to_ne_bytes());
21462 self
21463 }
21464 pub fn push_encap_limit(mut self, value: u8) -> Self {
21465 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21466 self.as_rec_mut().extend(value.to_ne_bytes());
21467 self
21468 }
21469 pub fn push_flowinfo(mut self, value: u32) -> Self {
21470 push_header(self.as_rec_mut(), 7u16, 4 as u16);
21471 self.as_rec_mut().extend(value.to_be_bytes());
21472 self
21473 }
21474 pub fn push_flags(mut self, value: u16) -> Self {
21475 push_header(self.as_rec_mut(), 8u16, 2 as u16);
21476 self.as_rec_mut().extend(value.to_be_bytes());
21477 self
21478 }
21479 pub fn push_proto(mut self, value: u8) -> Self {
21480 push_header(self.as_rec_mut(), 9u16, 1 as u16);
21481 self.as_rec_mut().extend(value.to_ne_bytes());
21482 self
21483 }
21484 pub fn push_pmtudisc(mut self, value: u8) -> Self {
21485 push_header(self.as_rec_mut(), 10u16, 1 as u16);
21486 self.as_rec_mut().extend(value.to_ne_bytes());
21487 self
21488 }
21489 pub fn push_6rd_prefix(mut self, value: &[u8]) -> Self {
21490 push_header(self.as_rec_mut(), 11u16, value.len() as u16);
21491 self.as_rec_mut().extend(value);
21492 self
21493 }
21494 pub fn push_6rd_relay_prefix(mut self, value: std::net::Ipv4Addr) -> Self {
21495 push_header(self.as_rec_mut(), 12u16, 4 as u16);
21496 self.as_rec_mut().extend(&value.to_bits().to_be_bytes());
21497 self
21498 }
21499 pub fn push_6rd_prefixlen(mut self, value: u16) -> Self {
21500 push_header(self.as_rec_mut(), 13u16, 2 as u16);
21501 self.as_rec_mut().extend(value.to_ne_bytes());
21502 self
21503 }
21504 pub fn push_6rd_relay_prefixlen(mut self, value: u16) -> Self {
21505 push_header(self.as_rec_mut(), 14u16, 2 as u16);
21506 self.as_rec_mut().extend(value.to_ne_bytes());
21507 self
21508 }
21509 pub fn push_encap_type(mut self, value: u16) -> Self {
21510 push_header(self.as_rec_mut(), 15u16, 2 as u16);
21511 self.as_rec_mut().extend(value.to_ne_bytes());
21512 self
21513 }
21514 pub fn push_encap_flags(mut self, value: u16) -> Self {
21515 push_header(self.as_rec_mut(), 16u16, 2 as u16);
21516 self.as_rec_mut().extend(value.to_ne_bytes());
21517 self
21518 }
21519 pub fn push_encap_sport(mut self, value: u16) -> Self {
21520 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21521 self.as_rec_mut().extend(value.to_be_bytes());
21522 self
21523 }
21524 pub fn push_encap_dport(mut self, value: u16) -> Self {
21525 push_header(self.as_rec_mut(), 18u16, 2 as u16);
21526 self.as_rec_mut().extend(value.to_be_bytes());
21527 self
21528 }
21529 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21530 push_header(self.as_rec_mut(), 19u16, 0 as u16);
21531 self
21532 }
21533 pub fn push_fwmark(mut self, value: u32) -> Self {
21534 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21535 self.as_rec_mut().extend(value.to_ne_bytes());
21536 self
21537 }
21538}
21539impl<Prev: Rec> Drop for PushLinkinfoIptunAttrs<Prev> {
21540 fn drop(&mut self) {
21541 if let Some(prev) = &mut self.prev {
21542 if let Some(header_offset) = &self.header_offset {
21543 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21544 }
21545 }
21546 }
21547}
21548pub struct PushLinkinfoIp6tnlAttrs<Prev: Rec> {
21549 pub(crate) prev: Option<Prev>,
21550 pub(crate) header_offset: Option<usize>,
21551}
21552impl<Prev: Rec> Rec for PushLinkinfoIp6tnlAttrs<Prev> {
21553 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21554 self.prev.as_mut().unwrap().as_rec_mut()
21555 }
21556 fn as_rec(&self) -> &Vec<u8> {
21557 self.prev.as_ref().unwrap().as_rec()
21558 }
21559}
21560impl<Prev: Rec> PushLinkinfoIp6tnlAttrs<Prev> {
21561 pub fn new(prev: Prev) -> Self {
21562 Self {
21563 prev: Some(prev),
21564 header_offset: None,
21565 }
21566 }
21567 pub fn end_nested(mut self) -> Prev {
21568 let mut prev = self.prev.take().unwrap();
21569 if let Some(header_offset) = &self.header_offset {
21570 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21571 }
21572 prev
21573 }
21574 pub fn push_link(mut self, value: u32) -> Self {
21575 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21576 self.as_rec_mut().extend(value.to_ne_bytes());
21577 self
21578 }
21579 pub fn push_local(mut self, value: &[u8]) -> Self {
21580 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
21581 self.as_rec_mut().extend(value);
21582 self
21583 }
21584 pub fn push_remote(mut self, value: &[u8]) -> Self {
21585 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
21586 self.as_rec_mut().extend(value);
21587 self
21588 }
21589 pub fn push_ttl(mut self, value: u8) -> Self {
21590 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21591 self.as_rec_mut().extend(value.to_ne_bytes());
21592 self
21593 }
21594 pub fn push_encap_limit(mut self, value: u8) -> Self {
21595 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21596 self.as_rec_mut().extend(value.to_ne_bytes());
21597 self
21598 }
21599 pub fn push_flowinfo(mut self, value: u32) -> Self {
21600 push_header(self.as_rec_mut(), 7u16, 4 as u16);
21601 self.as_rec_mut().extend(value.to_be_bytes());
21602 self
21603 }
21604 pub fn push_flags(mut self, value: u32) -> Self {
21605 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21606 self.as_rec_mut().extend(value.to_be_bytes());
21607 self
21608 }
21609 pub fn push_proto(mut self, value: u8) -> Self {
21610 push_header(self.as_rec_mut(), 9u16, 1 as u16);
21611 self.as_rec_mut().extend(value.to_ne_bytes());
21612 self
21613 }
21614 pub fn push_encap_type(mut self, value: u16) -> Self {
21615 push_header(self.as_rec_mut(), 15u16, 2 as u16);
21616 self.as_rec_mut().extend(value.to_ne_bytes());
21617 self
21618 }
21619 pub fn push_encap_flags(mut self, value: u16) -> Self {
21620 push_header(self.as_rec_mut(), 16u16, 2 as u16);
21621 self.as_rec_mut().extend(value.to_ne_bytes());
21622 self
21623 }
21624 pub fn push_encap_sport(mut self, value: u16) -> Self {
21625 push_header(self.as_rec_mut(), 17u16, 2 as u16);
21626 self.as_rec_mut().extend(value.to_be_bytes());
21627 self
21628 }
21629 pub fn push_encap_dport(mut self, value: u16) -> Self {
21630 push_header(self.as_rec_mut(), 18u16, 2 as u16);
21631 self.as_rec_mut().extend(value.to_be_bytes());
21632 self
21633 }
21634 pub fn push_collect_metadata(mut self, value: ()) -> Self {
21635 push_header(self.as_rec_mut(), 19u16, 0 as u16);
21636 self
21637 }
21638 pub fn push_fwmark(mut self, value: u32) -> Self {
21639 push_header(self.as_rec_mut(), 20u16, 4 as u16);
21640 self.as_rec_mut().extend(value.to_ne_bytes());
21641 self
21642 }
21643}
21644impl<Prev: Rec> Drop for PushLinkinfoIp6tnlAttrs<Prev> {
21645 fn drop(&mut self) {
21646 if let Some(prev) = &mut self.prev {
21647 if let Some(header_offset) = &self.header_offset {
21648 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21649 }
21650 }
21651 }
21652}
21653pub struct PushLinkinfoTunAttrs<Prev: Rec> {
21654 pub(crate) prev: Option<Prev>,
21655 pub(crate) header_offset: Option<usize>,
21656}
21657impl<Prev: Rec> Rec for PushLinkinfoTunAttrs<Prev> {
21658 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21659 self.prev.as_mut().unwrap().as_rec_mut()
21660 }
21661 fn as_rec(&self) -> &Vec<u8> {
21662 self.prev.as_ref().unwrap().as_rec()
21663 }
21664}
21665impl<Prev: Rec> PushLinkinfoTunAttrs<Prev> {
21666 pub fn new(prev: Prev) -> Self {
21667 Self {
21668 prev: Some(prev),
21669 header_offset: None,
21670 }
21671 }
21672 pub fn end_nested(mut self) -> Prev {
21673 let mut prev = self.prev.take().unwrap();
21674 if let Some(header_offset) = &self.header_offset {
21675 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21676 }
21677 prev
21678 }
21679 pub fn push_owner(mut self, value: u32) -> Self {
21680 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21681 self.as_rec_mut().extend(value.to_ne_bytes());
21682 self
21683 }
21684 pub fn push_group(mut self, value: u32) -> Self {
21685 push_header(self.as_rec_mut(), 2u16, 4 as u16);
21686 self.as_rec_mut().extend(value.to_ne_bytes());
21687 self
21688 }
21689 pub fn push_type(mut self, value: u8) -> Self {
21690 push_header(self.as_rec_mut(), 3u16, 1 as u16);
21691 self.as_rec_mut().extend(value.to_ne_bytes());
21692 self
21693 }
21694 pub fn push_pi(mut self, value: u8) -> Self {
21695 push_header(self.as_rec_mut(), 4u16, 1 as u16);
21696 self.as_rec_mut().extend(value.to_ne_bytes());
21697 self
21698 }
21699 pub fn push_vnet_hdr(mut self, value: u8) -> Self {
21700 push_header(self.as_rec_mut(), 5u16, 1 as u16);
21701 self.as_rec_mut().extend(value.to_ne_bytes());
21702 self
21703 }
21704 pub fn push_persist(mut self, value: u8) -> Self {
21705 push_header(self.as_rec_mut(), 6u16, 1 as u16);
21706 self.as_rec_mut().extend(value.to_ne_bytes());
21707 self
21708 }
21709 pub fn push_multi_queue(mut self, value: u8) -> Self {
21710 push_header(self.as_rec_mut(), 7u16, 1 as u16);
21711 self.as_rec_mut().extend(value.to_ne_bytes());
21712 self
21713 }
21714 pub fn push_num_queues(mut self, value: u32) -> Self {
21715 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21716 self.as_rec_mut().extend(value.to_ne_bytes());
21717 self
21718 }
21719 pub fn push_num_disabled_queues(mut self, value: u32) -> Self {
21720 push_header(self.as_rec_mut(), 9u16, 4 as u16);
21721 self.as_rec_mut().extend(value.to_ne_bytes());
21722 self
21723 }
21724}
21725impl<Prev: Rec> Drop for PushLinkinfoTunAttrs<Prev> {
21726 fn drop(&mut self) {
21727 if let Some(prev) = &mut self.prev {
21728 if let Some(header_offset) = &self.header_offset {
21729 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21730 }
21731 }
21732 }
21733}
21734pub struct PushLinkinfoVlanAttrs<Prev: Rec> {
21735 pub(crate) prev: Option<Prev>,
21736 pub(crate) header_offset: Option<usize>,
21737}
21738impl<Prev: Rec> Rec for PushLinkinfoVlanAttrs<Prev> {
21739 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21740 self.prev.as_mut().unwrap().as_rec_mut()
21741 }
21742 fn as_rec(&self) -> &Vec<u8> {
21743 self.prev.as_ref().unwrap().as_rec()
21744 }
21745}
21746impl<Prev: Rec> PushLinkinfoVlanAttrs<Prev> {
21747 pub fn new(prev: Prev) -> Self {
21748 Self {
21749 prev: Some(prev),
21750 header_offset: None,
21751 }
21752 }
21753 pub fn end_nested(mut self) -> Prev {
21754 let mut prev = self.prev.take().unwrap();
21755 if let Some(header_offset) = &self.header_offset {
21756 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21757 }
21758 prev
21759 }
21760 pub fn push_id(mut self, value: u16) -> Self {
21761 push_header(self.as_rec_mut(), 1u16, 2 as u16);
21762 self.as_rec_mut().extend(value.to_ne_bytes());
21763 self
21764 }
21765 pub fn push_flags(mut self, value: IflaVlanFlags) -> Self {
21766 push_header(self.as_rec_mut(), 2u16, value.as_slice().len() as u16);
21767 self.as_rec_mut().extend(value.as_slice());
21768 self
21769 }
21770 pub fn nested_egress_qos(mut self) -> PushIflaVlanQos<Self> {
21771 let header_offset = push_nested_header(self.as_rec_mut(), 3u16);
21772 PushIflaVlanQos {
21773 prev: Some(self),
21774 header_offset: Some(header_offset),
21775 }
21776 }
21777 pub fn nested_ingress_qos(mut self) -> PushIflaVlanQos<Self> {
21778 let header_offset = push_nested_header(self.as_rec_mut(), 4u16);
21779 PushIflaVlanQos {
21780 prev: Some(self),
21781 header_offset: Some(header_offset),
21782 }
21783 }
21784 #[doc = "Associated type: [`VlanProtocols`] (enum)"]
21785 pub fn push_protocol(mut self, value: u16) -> Self {
21786 push_header(self.as_rec_mut(), 5u16, 2 as u16);
21787 self.as_rec_mut().extend(value.to_be_bytes());
21788 self
21789 }
21790}
21791impl<Prev: Rec> Drop for PushLinkinfoVlanAttrs<Prev> {
21792 fn drop(&mut self) {
21793 if let Some(prev) = &mut self.prev {
21794 if let Some(header_offset) = &self.header_offset {
21795 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21796 }
21797 }
21798 }
21799}
21800pub struct PushIflaVlanQos<Prev: Rec> {
21801 pub(crate) prev: Option<Prev>,
21802 pub(crate) header_offset: Option<usize>,
21803}
21804impl<Prev: Rec> Rec for PushIflaVlanQos<Prev> {
21805 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21806 self.prev.as_mut().unwrap().as_rec_mut()
21807 }
21808 fn as_rec(&self) -> &Vec<u8> {
21809 self.prev.as_ref().unwrap().as_rec()
21810 }
21811}
21812impl<Prev: Rec> PushIflaVlanQos<Prev> {
21813 pub fn new(prev: Prev) -> Self {
21814 Self {
21815 prev: Some(prev),
21816 header_offset: None,
21817 }
21818 }
21819 pub fn end_nested(mut self) -> Prev {
21820 let mut prev = self.prev.take().unwrap();
21821 if let Some(header_offset) = &self.header_offset {
21822 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21823 }
21824 prev
21825 }
21826 #[doc = "Attribute may repeat multiple times (treat it as array)"]
21827 pub fn push_mapping(mut self, value: IflaVlanQosMapping) -> Self {
21828 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
21829 self.as_rec_mut().extend(value.as_slice());
21830 self
21831 }
21832}
21833impl<Prev: Rec> Drop for PushIflaVlanQos<Prev> {
21834 fn drop(&mut self) {
21835 if let Some(prev) = &mut self.prev {
21836 if let Some(header_offset) = &self.header_offset {
21837 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21838 }
21839 }
21840 }
21841}
21842pub struct PushLinkinfoVrfAttrs<Prev: Rec> {
21843 pub(crate) prev: Option<Prev>,
21844 pub(crate) header_offset: Option<usize>,
21845}
21846impl<Prev: Rec> Rec for PushLinkinfoVrfAttrs<Prev> {
21847 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21848 self.prev.as_mut().unwrap().as_rec_mut()
21849 }
21850 fn as_rec(&self) -> &Vec<u8> {
21851 self.prev.as_ref().unwrap().as_rec()
21852 }
21853}
21854impl<Prev: Rec> PushLinkinfoVrfAttrs<Prev> {
21855 pub fn new(prev: Prev) -> Self {
21856 Self {
21857 prev: Some(prev),
21858 header_offset: None,
21859 }
21860 }
21861 pub fn end_nested(mut self) -> Prev {
21862 let mut prev = self.prev.take().unwrap();
21863 if let Some(header_offset) = &self.header_offset {
21864 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21865 }
21866 prev
21867 }
21868 pub fn push_table(mut self, value: u32) -> Self {
21869 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21870 self.as_rec_mut().extend(value.to_ne_bytes());
21871 self
21872 }
21873}
21874impl<Prev: Rec> Drop for PushLinkinfoVrfAttrs<Prev> {
21875 fn drop(&mut self) {
21876 if let Some(prev) = &mut self.prev {
21877 if let Some(header_offset) = &self.header_offset {
21878 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21879 }
21880 }
21881 }
21882}
21883pub struct PushXdpAttrs<Prev: Rec> {
21884 pub(crate) prev: Option<Prev>,
21885 pub(crate) header_offset: Option<usize>,
21886}
21887impl<Prev: Rec> Rec for PushXdpAttrs<Prev> {
21888 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21889 self.prev.as_mut().unwrap().as_rec_mut()
21890 }
21891 fn as_rec(&self) -> &Vec<u8> {
21892 self.prev.as_ref().unwrap().as_rec()
21893 }
21894}
21895impl<Prev: Rec> PushXdpAttrs<Prev> {
21896 pub fn new(prev: Prev) -> Self {
21897 Self {
21898 prev: Some(prev),
21899 header_offset: None,
21900 }
21901 }
21902 pub fn end_nested(mut self) -> Prev {
21903 let mut prev = self.prev.take().unwrap();
21904 if let Some(header_offset) = &self.header_offset {
21905 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21906 }
21907 prev
21908 }
21909 pub fn push_fd(mut self, value: i32) -> Self {
21910 push_header(self.as_rec_mut(), 1u16, 4 as u16);
21911 self.as_rec_mut().extend(value.to_ne_bytes());
21912 self
21913 }
21914 pub fn push_attached(mut self, value: u8) -> Self {
21915 push_header(self.as_rec_mut(), 2u16, 1 as u16);
21916 self.as_rec_mut().extend(value.to_ne_bytes());
21917 self
21918 }
21919 pub fn push_flags(mut self, value: u32) -> Self {
21920 push_header(self.as_rec_mut(), 3u16, 4 as u16);
21921 self.as_rec_mut().extend(value.to_ne_bytes());
21922 self
21923 }
21924 pub fn push_prog_id(mut self, value: u32) -> Self {
21925 push_header(self.as_rec_mut(), 4u16, 4 as u16);
21926 self.as_rec_mut().extend(value.to_ne_bytes());
21927 self
21928 }
21929 pub fn push_drv_prog_id(mut self, value: u32) -> Self {
21930 push_header(self.as_rec_mut(), 5u16, 4 as u16);
21931 self.as_rec_mut().extend(value.to_ne_bytes());
21932 self
21933 }
21934 pub fn push_skb_prog_id(mut self, value: u32) -> Self {
21935 push_header(self.as_rec_mut(), 6u16, 4 as u16);
21936 self.as_rec_mut().extend(value.to_ne_bytes());
21937 self
21938 }
21939 pub fn push_hw_prog_id(mut self, value: u32) -> Self {
21940 push_header(self.as_rec_mut(), 7u16, 4 as u16);
21941 self.as_rec_mut().extend(value.to_ne_bytes());
21942 self
21943 }
21944 pub fn push_expected_fd(mut self, value: i32) -> Self {
21945 push_header(self.as_rec_mut(), 8u16, 4 as u16);
21946 self.as_rec_mut().extend(value.to_ne_bytes());
21947 self
21948 }
21949}
21950impl<Prev: Rec> Drop for PushXdpAttrs<Prev> {
21951 fn drop(&mut self) {
21952 if let Some(prev) = &mut self.prev {
21953 if let Some(header_offset) = &self.header_offset {
21954 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21955 }
21956 }
21957 }
21958}
21959pub struct PushIflaAttrs<Prev: Rec> {
21960 pub(crate) prev: Option<Prev>,
21961 pub(crate) header_offset: Option<usize>,
21962}
21963impl<Prev: Rec> Rec for PushIflaAttrs<Prev> {
21964 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
21965 self.prev.as_mut().unwrap().as_rec_mut()
21966 }
21967 fn as_rec(&self) -> &Vec<u8> {
21968 self.prev.as_ref().unwrap().as_rec()
21969 }
21970}
21971impl<Prev: Rec> PushIflaAttrs<Prev> {
21972 pub fn new(prev: Prev) -> Self {
21973 Self {
21974 prev: Some(prev),
21975 header_offset: None,
21976 }
21977 }
21978 pub fn end_nested(mut self) -> Prev {
21979 let mut prev = self.prev.take().unwrap();
21980 if let Some(header_offset) = &self.header_offset {
21981 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21982 }
21983 prev
21984 }
21985 #[doc = "u32 indexed by ipv4\\-devconf \\- 1 on output, on input it's a nest"]
21986 pub fn push_conf(mut self, value: &[u8]) -> Self {
21987 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
21988 self.as_rec_mut().extend(value);
21989 self
21990 }
21991}
21992impl<Prev: Rec> Drop for PushIflaAttrs<Prev> {
21993 fn drop(&mut self) {
21994 if let Some(prev) = &mut self.prev {
21995 if let Some(header_offset) = &self.header_offset {
21996 finalize_nested_header(prev.as_rec_mut(), *header_offset);
21997 }
21998 }
21999 }
22000}
22001pub struct PushIfla6Attrs<Prev: Rec> {
22002 pub(crate) prev: Option<Prev>,
22003 pub(crate) header_offset: Option<usize>,
22004}
22005impl<Prev: Rec> Rec for PushIfla6Attrs<Prev> {
22006 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22007 self.prev.as_mut().unwrap().as_rec_mut()
22008 }
22009 fn as_rec(&self) -> &Vec<u8> {
22010 self.prev.as_ref().unwrap().as_rec()
22011 }
22012}
22013impl<Prev: Rec> PushIfla6Attrs<Prev> {
22014 pub fn new(prev: Prev) -> Self {
22015 Self {
22016 prev: Some(prev),
22017 header_offset: None,
22018 }
22019 }
22020 pub fn end_nested(mut self) -> Prev {
22021 let mut prev = self.prev.take().unwrap();
22022 if let Some(header_offset) = &self.header_offset {
22023 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22024 }
22025 prev
22026 }
22027 pub fn push_flags(mut self, value: u32) -> Self {
22028 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22029 self.as_rec_mut().extend(value.to_ne_bytes());
22030 self
22031 }
22032 #[doc = "u32 indexed by ipv6\\-devconf \\- 1 on output, on input it's a nest"]
22033 pub fn push_conf(mut self, value: &[u8]) -> Self {
22034 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
22035 self.as_rec_mut().extend(value);
22036 self
22037 }
22038 pub fn push_stats(mut self, value: &[u8]) -> Self {
22039 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
22040 self.as_rec_mut().extend(value);
22041 self
22042 }
22043 pub fn push_mcast(mut self, value: &[u8]) -> Self {
22044 push_header(self.as_rec_mut(), 4u16, value.len() as u16);
22045 self.as_rec_mut().extend(value);
22046 self
22047 }
22048 pub fn push_cacheinfo(mut self, value: IflaCacheinfo) -> Self {
22049 push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
22050 self.as_rec_mut().extend(value.as_slice());
22051 self
22052 }
22053 pub fn push_icmp6stats(mut self, value: &[u8]) -> Self {
22054 push_header(self.as_rec_mut(), 6u16, value.len() as u16);
22055 self.as_rec_mut().extend(value);
22056 self
22057 }
22058 pub fn push_token(mut self, value: &[u8]) -> Self {
22059 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
22060 self.as_rec_mut().extend(value);
22061 self
22062 }
22063 pub fn push_addr_gen_mode(mut self, value: u8) -> Self {
22064 push_header(self.as_rec_mut(), 8u16, 1 as u16);
22065 self.as_rec_mut().extend(value.to_ne_bytes());
22066 self
22067 }
22068 pub fn push_ra_mtu(mut self, value: u32) -> Self {
22069 push_header(self.as_rec_mut(), 9u16, 4 as u16);
22070 self.as_rec_mut().extend(value.to_ne_bytes());
22071 self
22072 }
22073}
22074impl<Prev: Rec> Drop for PushIfla6Attrs<Prev> {
22075 fn drop(&mut self) {
22076 if let Some(prev) = &mut self.prev {
22077 if let Some(header_offset) = &self.header_offset {
22078 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22079 }
22080 }
22081 }
22082}
22083pub struct PushMctpAttrs<Prev: Rec> {
22084 pub(crate) prev: Option<Prev>,
22085 pub(crate) header_offset: Option<usize>,
22086}
22087impl<Prev: Rec> Rec for PushMctpAttrs<Prev> {
22088 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22089 self.prev.as_mut().unwrap().as_rec_mut()
22090 }
22091 fn as_rec(&self) -> &Vec<u8> {
22092 self.prev.as_ref().unwrap().as_rec()
22093 }
22094}
22095impl<Prev: Rec> PushMctpAttrs<Prev> {
22096 pub fn new(prev: Prev) -> Self {
22097 Self {
22098 prev: Some(prev),
22099 header_offset: None,
22100 }
22101 }
22102 pub fn end_nested(mut self) -> Prev {
22103 let mut prev = self.prev.take().unwrap();
22104 if let Some(header_offset) = &self.header_offset {
22105 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22106 }
22107 prev
22108 }
22109 pub fn push_net(mut self, value: u32) -> Self {
22110 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22111 self.as_rec_mut().extend(value.to_ne_bytes());
22112 self
22113 }
22114 pub fn push_phys_binding(mut self, value: u8) -> Self {
22115 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22116 self.as_rec_mut().extend(value.to_ne_bytes());
22117 self
22118 }
22119}
22120impl<Prev: Rec> Drop for PushMctpAttrs<Prev> {
22121 fn drop(&mut self) {
22122 if let Some(prev) = &mut self.prev {
22123 if let Some(header_offset) = &self.header_offset {
22124 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22125 }
22126 }
22127 }
22128}
22129pub struct PushStatsAttrs<Prev: Rec> {
22130 pub(crate) prev: Option<Prev>,
22131 pub(crate) header_offset: Option<usize>,
22132}
22133impl<Prev: Rec> Rec for PushStatsAttrs<Prev> {
22134 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22135 self.prev.as_mut().unwrap().as_rec_mut()
22136 }
22137 fn as_rec(&self) -> &Vec<u8> {
22138 self.prev.as_ref().unwrap().as_rec()
22139 }
22140}
22141impl<Prev: Rec> PushStatsAttrs<Prev> {
22142 pub fn new(prev: Prev) -> Self {
22143 Self {
22144 prev: Some(prev),
22145 header_offset: None,
22146 }
22147 }
22148 pub fn end_nested(mut self) -> Prev {
22149 let mut prev = self.prev.take().unwrap();
22150 if let Some(header_offset) = &self.header_offset {
22151 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22152 }
22153 prev
22154 }
22155 pub fn push_link_64(mut self, value: RtnlLinkStats64) -> Self {
22156 push_header(self.as_rec_mut(), 1u16, value.as_slice().len() as u16);
22157 self.as_rec_mut().extend(value.as_slice());
22158 self
22159 }
22160 pub fn push_link_xstats(mut self, value: &[u8]) -> Self {
22161 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
22162 self.as_rec_mut().extend(value);
22163 self
22164 }
22165 pub fn push_link_xstats_slave(mut self, value: &[u8]) -> Self {
22166 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
22167 self.as_rec_mut().extend(value);
22168 self
22169 }
22170 pub fn nested_link_offload_xstats(mut self) -> PushLinkOffloadXstats<Self> {
22171 let header_offset = push_nested_header(self.as_rec_mut(), 4u16);
22172 PushLinkOffloadXstats {
22173 prev: Some(self),
22174 header_offset: Some(header_offset),
22175 }
22176 }
22177 pub fn push_af_spec(mut self, value: &[u8]) -> Self {
22178 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
22179 self.as_rec_mut().extend(value);
22180 self
22181 }
22182}
22183impl<Prev: Rec> Drop for PushStatsAttrs<Prev> {
22184 fn drop(&mut self) {
22185 if let Some(prev) = &mut self.prev {
22186 if let Some(header_offset) = &self.header_offset {
22187 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22188 }
22189 }
22190 }
22191}
22192pub struct PushLinkOffloadXstats<Prev: Rec> {
22193 pub(crate) prev: Option<Prev>,
22194 pub(crate) header_offset: Option<usize>,
22195}
22196impl<Prev: Rec> Rec for PushLinkOffloadXstats<Prev> {
22197 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22198 self.prev.as_mut().unwrap().as_rec_mut()
22199 }
22200 fn as_rec(&self) -> &Vec<u8> {
22201 self.prev.as_ref().unwrap().as_rec()
22202 }
22203}
22204pub struct PushArrayHwSInfoOne<Prev: Rec> {
22205 pub(crate) prev: Option<Prev>,
22206 pub(crate) header_offset: Option<usize>,
22207 pub(crate) counter: u16,
22208}
22209impl<Prev: Rec> Rec for PushArrayHwSInfoOne<Prev> {
22210 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22211 self.prev.as_mut().unwrap().as_rec_mut()
22212 }
22213 fn as_rec(&self) -> &Vec<u8> {
22214 self.prev.as_ref().unwrap().as_rec()
22215 }
22216}
22217impl<Prev: Rec> PushArrayHwSInfoOne<Prev> {
22218 pub fn new(prev: Prev) -> Self {
22219 Self {
22220 prev: Some(prev),
22221 header_offset: None,
22222 counter: 0,
22223 }
22224 }
22225 pub fn end_array(mut self) -> Prev {
22226 let mut prev = self.prev.take().unwrap();
22227 if let Some(header_offset) = &self.header_offset {
22228 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22229 }
22230 prev
22231 }
22232 pub fn entry_nested(mut self) -> PushHwSInfoOne<Self> {
22233 let index = self.counter;
22234 self.counter += 1;
22235 let header_offset = push_nested_header(self.as_rec_mut(), index);
22236 PushHwSInfoOne {
22237 prev: Some(self),
22238 header_offset: Some(header_offset),
22239 }
22240 }
22241}
22242impl<Prev: Rec> Drop for PushArrayHwSInfoOne<Prev> {
22243 fn drop(&mut self) {
22244 if let Some(prev) = &mut self.prev {
22245 if let Some(header_offset) = &self.header_offset {
22246 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22247 }
22248 }
22249 }
22250}
22251impl<Prev: Rec> PushLinkOffloadXstats<Prev> {
22252 pub fn new(prev: Prev) -> Self {
22253 Self {
22254 prev: Some(prev),
22255 header_offset: None,
22256 }
22257 }
22258 pub fn end_nested(mut self) -> Prev {
22259 let mut prev = self.prev.take().unwrap();
22260 if let Some(header_offset) = &self.header_offset {
22261 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22262 }
22263 prev
22264 }
22265 pub fn push_cpu_hit(mut self, value: &[u8]) -> Self {
22266 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
22267 self.as_rec_mut().extend(value);
22268 self
22269 }
22270 pub fn array_hw_s_info(mut self) -> PushArrayHwSInfoOne<Self> {
22271 let header_offset = push_nested_header(self.as_rec_mut(), 2u16);
22272 PushArrayHwSInfoOne {
22273 prev: Some(self),
22274 header_offset: Some(header_offset),
22275 counter: 0,
22276 }
22277 }
22278 pub fn push_l3_stats(mut self, value: &[u8]) -> Self {
22279 push_header(self.as_rec_mut(), 3u16, value.len() as u16);
22280 self.as_rec_mut().extend(value);
22281 self
22282 }
22283}
22284impl<Prev: Rec> Drop for PushLinkOffloadXstats<Prev> {
22285 fn drop(&mut self) {
22286 if let Some(prev) = &mut self.prev {
22287 if let Some(header_offset) = &self.header_offset {
22288 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22289 }
22290 }
22291 }
22292}
22293pub struct PushHwSInfoOne<Prev: Rec> {
22294 pub(crate) prev: Option<Prev>,
22295 pub(crate) header_offset: Option<usize>,
22296}
22297impl<Prev: Rec> Rec for PushHwSInfoOne<Prev> {
22298 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22299 self.prev.as_mut().unwrap().as_rec_mut()
22300 }
22301 fn as_rec(&self) -> &Vec<u8> {
22302 self.prev.as_ref().unwrap().as_rec()
22303 }
22304}
22305impl<Prev: Rec> PushHwSInfoOne<Prev> {
22306 pub fn new(prev: Prev) -> Self {
22307 Self {
22308 prev: Some(prev),
22309 header_offset: None,
22310 }
22311 }
22312 pub fn end_nested(mut self) -> Prev {
22313 let mut prev = self.prev.take().unwrap();
22314 if let Some(header_offset) = &self.header_offset {
22315 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22316 }
22317 prev
22318 }
22319 pub fn push_request(mut self, value: u8) -> Self {
22320 push_header(self.as_rec_mut(), 1u16, 1 as u16);
22321 self.as_rec_mut().extend(value.to_ne_bytes());
22322 self
22323 }
22324 pub fn push_used(mut self, value: u8) -> Self {
22325 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22326 self.as_rec_mut().extend(value.to_ne_bytes());
22327 self
22328 }
22329}
22330impl<Prev: Rec> Drop for PushHwSInfoOne<Prev> {
22331 fn drop(&mut self) {
22332 if let Some(prev) = &mut self.prev {
22333 if let Some(header_offset) = &self.header_offset {
22334 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22335 }
22336 }
22337 }
22338}
22339pub struct PushLinkDpllPinAttrs<Prev: Rec> {
22340 pub(crate) prev: Option<Prev>,
22341 pub(crate) header_offset: Option<usize>,
22342}
22343impl<Prev: Rec> Rec for PushLinkDpllPinAttrs<Prev> {
22344 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22345 self.prev.as_mut().unwrap().as_rec_mut()
22346 }
22347 fn as_rec(&self) -> &Vec<u8> {
22348 self.prev.as_ref().unwrap().as_rec()
22349 }
22350}
22351impl<Prev: Rec> PushLinkDpllPinAttrs<Prev> {
22352 pub fn new(prev: Prev) -> Self {
22353 Self {
22354 prev: Some(prev),
22355 header_offset: None,
22356 }
22357 }
22358 pub fn end_nested(mut self) -> Prev {
22359 let mut prev = self.prev.take().unwrap();
22360 if let Some(header_offset) = &self.header_offset {
22361 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22362 }
22363 prev
22364 }
22365 pub fn push_id(mut self, value: u32) -> Self {
22366 push_header(self.as_rec_mut(), 1u16, 4 as u16);
22367 self.as_rec_mut().extend(value.to_ne_bytes());
22368 self
22369 }
22370}
22371impl<Prev: Rec> Drop for PushLinkDpllPinAttrs<Prev> {
22372 fn drop(&mut self) {
22373 if let Some(prev) = &mut self.prev {
22374 if let Some(header_offset) = &self.header_offset {
22375 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22376 }
22377 }
22378 }
22379}
22380pub struct PushLinkinfoNetkitAttrs<Prev: Rec> {
22381 pub(crate) prev: Option<Prev>,
22382 pub(crate) header_offset: Option<usize>,
22383}
22384impl<Prev: Rec> Rec for PushLinkinfoNetkitAttrs<Prev> {
22385 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22386 self.prev.as_mut().unwrap().as_rec_mut()
22387 }
22388 fn as_rec(&self) -> &Vec<u8> {
22389 self.prev.as_ref().unwrap().as_rec()
22390 }
22391}
22392impl<Prev: Rec> PushLinkinfoNetkitAttrs<Prev> {
22393 pub fn new(prev: Prev) -> Self {
22394 Self {
22395 prev: Some(prev),
22396 header_offset: None,
22397 }
22398 }
22399 pub fn end_nested(mut self) -> Prev {
22400 let mut prev = self.prev.take().unwrap();
22401 if let Some(header_offset) = &self.header_offset {
22402 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22403 }
22404 prev
22405 }
22406 pub fn push_peer_info(mut self, value: &[u8]) -> Self {
22407 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
22408 self.as_rec_mut().extend(value);
22409 self
22410 }
22411 pub fn push_primary(mut self, value: u8) -> Self {
22412 push_header(self.as_rec_mut(), 2u16, 1 as u16);
22413 self.as_rec_mut().extend(value.to_ne_bytes());
22414 self
22415 }
22416 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
22417 pub fn push_policy(mut self, value: u32) -> Self {
22418 push_header(self.as_rec_mut(), 3u16, 4 as u16);
22419 self.as_rec_mut().extend(value.to_ne_bytes());
22420 self
22421 }
22422 #[doc = "Associated type: [`NetkitPolicy`] (enum)"]
22423 pub fn push_peer_policy(mut self, value: u32) -> Self {
22424 push_header(self.as_rec_mut(), 4u16, 4 as u16);
22425 self.as_rec_mut().extend(value.to_ne_bytes());
22426 self
22427 }
22428 #[doc = "Associated type: [`NetkitMode`] (enum)"]
22429 pub fn push_mode(mut self, value: u32) -> Self {
22430 push_header(self.as_rec_mut(), 5u16, 4 as u16);
22431 self.as_rec_mut().extend(value.to_ne_bytes());
22432 self
22433 }
22434 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
22435 pub fn push_scrub(mut self, value: u32) -> Self {
22436 push_header(self.as_rec_mut(), 6u16, 4 as u16);
22437 self.as_rec_mut().extend(value.to_ne_bytes());
22438 self
22439 }
22440 #[doc = "Associated type: [`NetkitScrub`] (enum)"]
22441 pub fn push_peer_scrub(mut self, value: u32) -> Self {
22442 push_header(self.as_rec_mut(), 7u16, 4 as u16);
22443 self.as_rec_mut().extend(value.to_ne_bytes());
22444 self
22445 }
22446 pub fn push_headroom(mut self, value: u16) -> Self {
22447 push_header(self.as_rec_mut(), 8u16, 2 as u16);
22448 self.as_rec_mut().extend(value.to_ne_bytes());
22449 self
22450 }
22451 pub fn push_tailroom(mut self, value: u16) -> Self {
22452 push_header(self.as_rec_mut(), 9u16, 2 as u16);
22453 self.as_rec_mut().extend(value.to_ne_bytes());
22454 self
22455 }
22456}
22457impl<Prev: Rec> Drop for PushLinkinfoNetkitAttrs<Prev> {
22458 fn drop(&mut self) {
22459 if let Some(prev) = &mut self.prev {
22460 if let Some(header_offset) = &self.header_offset {
22461 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22462 }
22463 }
22464 }
22465}
22466pub struct PushLinkinfoOvpnAttrs<Prev: Rec> {
22467 pub(crate) prev: Option<Prev>,
22468 pub(crate) header_offset: Option<usize>,
22469}
22470impl<Prev: Rec> Rec for PushLinkinfoOvpnAttrs<Prev> {
22471 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
22472 self.prev.as_mut().unwrap().as_rec_mut()
22473 }
22474 fn as_rec(&self) -> &Vec<u8> {
22475 self.prev.as_ref().unwrap().as_rec()
22476 }
22477}
22478impl<Prev: Rec> PushLinkinfoOvpnAttrs<Prev> {
22479 pub fn new(prev: Prev) -> Self {
22480 Self {
22481 prev: Some(prev),
22482 header_offset: None,
22483 }
22484 }
22485 pub fn end_nested(mut self) -> Prev {
22486 let mut prev = self.prev.take().unwrap();
22487 if let Some(header_offset) = &self.header_offset {
22488 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22489 }
22490 prev
22491 }
22492 #[doc = "Associated type: [`OvpnMode`] (enum)"]
22493 pub fn push_mode(mut self, value: u8) -> Self {
22494 push_header(self.as_rec_mut(), 1u16, 1 as u16);
22495 self.as_rec_mut().extend(value.to_ne_bytes());
22496 self
22497 }
22498}
22499impl<Prev: Rec> Drop for PushLinkinfoOvpnAttrs<Prev> {
22500 fn drop(&mut self) {
22501 if let Some(prev) = &mut self.prev {
22502 if let Some(header_offset) = &self.header_offset {
22503 finalize_nested_header(prev.as_rec_mut(), *header_offset);
22504 }
22505 }
22506 }
22507}
22508#[doc = "Create a new link\\.\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"]
22509#[derive(Debug)]
22510pub struct OpNewlinkDo<'r> {
22511 request: Request<'r>,
22512}
22513impl<'r> OpNewlinkDo<'r> {
22514 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22515 Self::write_header(request.buf_mut(), header);
22516 Self { request: request }
22517 }
22518 pub fn encode_request<'buf>(
22519 buf: &'buf mut Vec<u8>,
22520 header: &Ifinfomsg,
22521 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22522 Self::write_header(buf, header);
22523 PushLinkAttrs::new(buf)
22524 }
22525 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22526 PushLinkAttrs::new(self.request.buf_mut())
22527 }
22528 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22529 PushLinkAttrs::new(self.request.buf)
22530 }
22531 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22532 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22533 (
22534 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22535 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22536 )
22537 }
22538 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22539 prev.as_rec_mut().extend(header.as_slice());
22540 }
22541}
22542impl NetlinkRequest for OpNewlinkDo<'_> {
22543 fn protocol(&self) -> Protocol {
22544 Protocol::Raw {
22545 protonum: 0u16,
22546 request_type: 16u16,
22547 }
22548 }
22549 fn flags(&self) -> u16 {
22550 self.request.flags
22551 }
22552 fn payload(&self) -> &[u8] {
22553 self.request.buf()
22554 }
22555 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22556 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22557 Self::decode_request(buf)
22558 }
22559 fn lookup(
22560 buf: &[u8],
22561 offset: usize,
22562 missing_type: Option<u16>,
22563 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22564 Self::decode_request(buf)
22565 .1
22566 .lookup_attr(offset, missing_type)
22567 }
22568}
22569#[doc = "Delete an existing link\\.\nRequest attributes:\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n"]
22570#[derive(Debug)]
22571pub struct OpDellinkDo<'r> {
22572 request: Request<'r>,
22573}
22574impl<'r> OpDellinkDo<'r> {
22575 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22576 Self::write_header(request.buf_mut(), header);
22577 Self { request: request }
22578 }
22579 pub fn encode_request<'buf>(
22580 buf: &'buf mut Vec<u8>,
22581 header: &Ifinfomsg,
22582 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22583 Self::write_header(buf, header);
22584 PushLinkAttrs::new(buf)
22585 }
22586 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22587 PushLinkAttrs::new(self.request.buf_mut())
22588 }
22589 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22590 PushLinkAttrs::new(self.request.buf)
22591 }
22592 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22593 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22594 (
22595 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22596 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22597 )
22598 }
22599 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22600 prev.as_rec_mut().extend(header.as_slice());
22601 }
22602}
22603impl NetlinkRequest for OpDellinkDo<'_> {
22604 fn protocol(&self) -> Protocol {
22605 Protocol::Raw {
22606 protonum: 0u16,
22607 request_type: 17u16,
22608 }
22609 }
22610 fn flags(&self) -> u16 {
22611 self.request.flags
22612 }
22613 fn payload(&self) -> &[u8] {
22614 self.request.buf()
22615 }
22616 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22617 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22618 Self::decode_request(buf)
22619 }
22620 fn lookup(
22621 buf: &[u8],
22622 offset: usize,
22623 missing_type: Option<u16>,
22624 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22625 Self::decode_request(buf)
22626 .1
22627 .lookup_attr(offset, missing_type)
22628 }
22629}
22630#[doc = "Get / dump information about a link\\.\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_cost()](IterableLinkAttrs::get_cost)\n- [.get_priority()](IterableLinkAttrs::get_priority)\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"]
22631#[derive(Debug)]
22632pub struct OpGetlinkDump<'r> {
22633 request: Request<'r>,
22634}
22635impl<'r> OpGetlinkDump<'r> {
22636 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22637 Self::write_header(request.buf_mut(), header);
22638 Self {
22639 request: request.set_dump(),
22640 }
22641 }
22642 pub fn encode_request<'buf>(
22643 buf: &'buf mut Vec<u8>,
22644 header: &Ifinfomsg,
22645 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22646 Self::write_header(buf, header);
22647 PushLinkAttrs::new(buf)
22648 }
22649 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22650 PushLinkAttrs::new(self.request.buf_mut())
22651 }
22652 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22653 PushLinkAttrs::new(self.request.buf)
22654 }
22655 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22656 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22657 (
22658 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22659 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22660 )
22661 }
22662 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22663 prev.as_rec_mut().extend(header.as_slice());
22664 }
22665}
22666impl NetlinkRequest for OpGetlinkDump<'_> {
22667 fn protocol(&self) -> Protocol {
22668 Protocol::Raw {
22669 protonum: 0u16,
22670 request_type: 18u16,
22671 }
22672 }
22673 fn flags(&self) -> u16 {
22674 self.request.flags
22675 }
22676 fn payload(&self) -> &[u8] {
22677 self.request.buf()
22678 }
22679 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22680 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22681 Self::decode_request(buf)
22682 }
22683 fn lookup(
22684 buf: &[u8],
22685 offset: usize,
22686 missing_type: Option<u16>,
22687 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22688 Self::decode_request(buf)
22689 .1
22690 .lookup_attr(offset, missing_type)
22691 }
22692}
22693#[doc = "Get / dump information about a link\\.\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_cost()](IterableLinkAttrs::get_cost)\n- [.get_priority()](IterableLinkAttrs::get_priority)\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"]
22694#[derive(Debug)]
22695pub struct OpGetlinkDo<'r> {
22696 request: Request<'r>,
22697}
22698impl<'r> OpGetlinkDo<'r> {
22699 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22700 Self::write_header(request.buf_mut(), header);
22701 Self { request: request }
22702 }
22703 pub fn encode_request<'buf>(
22704 buf: &'buf mut Vec<u8>,
22705 header: &Ifinfomsg,
22706 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22707 Self::write_header(buf, header);
22708 PushLinkAttrs::new(buf)
22709 }
22710 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22711 PushLinkAttrs::new(self.request.buf_mut())
22712 }
22713 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22714 PushLinkAttrs::new(self.request.buf)
22715 }
22716 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22717 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22718 (
22719 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22720 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22721 )
22722 }
22723 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22724 prev.as_rec_mut().extend(header.as_slice());
22725 }
22726}
22727impl NetlinkRequest for OpGetlinkDo<'_> {
22728 fn protocol(&self) -> Protocol {
22729 Protocol::Raw {
22730 protonum: 0u16,
22731 request_type: 18u16,
22732 }
22733 }
22734 fn flags(&self) -> u16 {
22735 self.request.flags
22736 }
22737 fn payload(&self) -> &[u8] {
22738 self.request.buf()
22739 }
22740 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22741 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22742 Self::decode_request(buf)
22743 }
22744 fn lookup(
22745 buf: &[u8],
22746 offset: usize,
22747 missing_type: Option<u16>,
22748 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22749 Self::decode_request(buf)
22750 .1
22751 .lookup_attr(offset, missing_type)
22752 }
22753}
22754#[doc = "Set information about a link\\.\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_cost()](PushLinkAttrs::push_cost)\n- [.push_priority()](PushLinkAttrs::push_priority)\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"]
22755#[derive(Debug)]
22756pub struct OpSetlinkDo<'r> {
22757 request: Request<'r>,
22758}
22759impl<'r> OpSetlinkDo<'r> {
22760 pub fn new(mut request: Request<'r>, header: &Ifinfomsg) -> Self {
22761 Self::write_header(request.buf_mut(), header);
22762 Self { request: request }
22763 }
22764 pub fn encode_request<'buf>(
22765 buf: &'buf mut Vec<u8>,
22766 header: &Ifinfomsg,
22767 ) -> PushLinkAttrs<&'buf mut Vec<u8>> {
22768 Self::write_header(buf, header);
22769 PushLinkAttrs::new(buf)
22770 }
22771 pub fn encode(&mut self) -> PushLinkAttrs<&mut Vec<u8>> {
22772 PushLinkAttrs::new(self.request.buf_mut())
22773 }
22774 pub fn into_encoder(self) -> PushLinkAttrs<RequestBuf<'r>> {
22775 PushLinkAttrs::new(self.request.buf)
22776 }
22777 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ifinfomsg, IterableLinkAttrs<'a>) {
22778 let (header, attrs) = buf.split_at(buf.len().min(Ifinfomsg::len()));
22779 (
22780 Ifinfomsg::new_from_slice(header).unwrap_or_default(),
22781 IterableLinkAttrs::with_loc(attrs, buf.as_ptr() as usize),
22782 )
22783 }
22784 fn write_header<Prev: Rec>(prev: &mut Prev, header: &Ifinfomsg) {
22785 prev.as_rec_mut().extend(header.as_slice());
22786 }
22787}
22788impl NetlinkRequest for OpSetlinkDo<'_> {
22789 fn protocol(&self) -> Protocol {
22790 Protocol::Raw {
22791 protonum: 0u16,
22792 request_type: 19u16,
22793 }
22794 }
22795 fn flags(&self) -> u16 {
22796 self.request.flags
22797 }
22798 fn payload(&self) -> &[u8] {
22799 self.request.buf()
22800 }
22801 type ReplyType<'buf> = (Ifinfomsg, IterableLinkAttrs<'buf>);
22802 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22803 Self::decode_request(buf)
22804 }
22805 fn lookup(
22806 buf: &[u8],
22807 offset: usize,
22808 missing_type: Option<u16>,
22809 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22810 Self::decode_request(buf)
22811 .1
22812 .lookup_attr(offset, missing_type)
22813 }
22814}
22815#[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"]
22816#[derive(Debug)]
22817pub struct OpGetstatsDump<'r> {
22818 request: Request<'r>,
22819}
22820impl<'r> OpGetstatsDump<'r> {
22821 pub fn new(mut request: Request<'r>, header: &IfStatsMsg) -> Self {
22822 Self::write_header(request.buf_mut(), header);
22823 Self {
22824 request: request.set_dump(),
22825 }
22826 }
22827 pub fn encode_request<'buf>(
22828 buf: &'buf mut Vec<u8>,
22829 header: &IfStatsMsg,
22830 ) -> PushStatsAttrs<&'buf mut Vec<u8>> {
22831 Self::write_header(buf, header);
22832 PushStatsAttrs::new(buf)
22833 }
22834 pub fn encode(&mut self) -> PushStatsAttrs<&mut Vec<u8>> {
22835 PushStatsAttrs::new(self.request.buf_mut())
22836 }
22837 pub fn into_encoder(self) -> PushStatsAttrs<RequestBuf<'r>> {
22838 PushStatsAttrs::new(self.request.buf)
22839 }
22840 pub fn decode_request<'a>(buf: &'a [u8]) -> (IfStatsMsg, IterableStatsAttrs<'a>) {
22841 let (header, attrs) = buf.split_at(buf.len().min(IfStatsMsg::len()));
22842 (
22843 IfStatsMsg::new_from_slice(header).unwrap_or_default(),
22844 IterableStatsAttrs::with_loc(attrs, buf.as_ptr() as usize),
22845 )
22846 }
22847 fn write_header<Prev: Rec>(prev: &mut Prev, header: &IfStatsMsg) {
22848 prev.as_rec_mut().extend(header.as_slice());
22849 }
22850}
22851impl NetlinkRequest for OpGetstatsDump<'_> {
22852 fn protocol(&self) -> Protocol {
22853 Protocol::Raw {
22854 protonum: 0u16,
22855 request_type: 94u16,
22856 }
22857 }
22858 fn flags(&self) -> u16 {
22859 self.request.flags
22860 }
22861 fn payload(&self) -> &[u8] {
22862 self.request.buf()
22863 }
22864 type ReplyType<'buf> = (IfStatsMsg, IterableStatsAttrs<'buf>);
22865 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22866 Self::decode_request(buf)
22867 }
22868 fn lookup(
22869 buf: &[u8],
22870 offset: usize,
22871 missing_type: Option<u16>,
22872 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22873 Self::decode_request(buf)
22874 .1
22875 .lookup_attr(offset, missing_type)
22876 }
22877}
22878#[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"]
22879#[derive(Debug)]
22880pub struct OpGetstatsDo<'r> {
22881 request: Request<'r>,
22882}
22883impl<'r> OpGetstatsDo<'r> {
22884 pub fn new(mut request: Request<'r>, header: &IfStatsMsg) -> Self {
22885 Self::write_header(request.buf_mut(), header);
22886 Self { request: request }
22887 }
22888 pub fn encode_request<'buf>(
22889 buf: &'buf mut Vec<u8>,
22890 header: &IfStatsMsg,
22891 ) -> PushStatsAttrs<&'buf mut Vec<u8>> {
22892 Self::write_header(buf, header);
22893 PushStatsAttrs::new(buf)
22894 }
22895 pub fn encode(&mut self) -> PushStatsAttrs<&mut Vec<u8>> {
22896 PushStatsAttrs::new(self.request.buf_mut())
22897 }
22898 pub fn into_encoder(self) -> PushStatsAttrs<RequestBuf<'r>> {
22899 PushStatsAttrs::new(self.request.buf)
22900 }
22901 pub fn decode_request<'a>(buf: &'a [u8]) -> (IfStatsMsg, IterableStatsAttrs<'a>) {
22902 let (header, attrs) = buf.split_at(buf.len().min(IfStatsMsg::len()));
22903 (
22904 IfStatsMsg::new_from_slice(header).unwrap_or_default(),
22905 IterableStatsAttrs::with_loc(attrs, buf.as_ptr() as usize),
22906 )
22907 }
22908 fn write_header<Prev: Rec>(prev: &mut Prev, header: &IfStatsMsg) {
22909 prev.as_rec_mut().extend(header.as_slice());
22910 }
22911}
22912impl NetlinkRequest for OpGetstatsDo<'_> {
22913 fn protocol(&self) -> Protocol {
22914 Protocol::Raw {
22915 protonum: 0u16,
22916 request_type: 94u16,
22917 }
22918 }
22919 fn flags(&self) -> u16 {
22920 self.request.flags
22921 }
22922 fn payload(&self) -> &[u8] {
22923 self.request.buf()
22924 }
22925 type ReplyType<'buf> = (IfStatsMsg, IterableStatsAttrs<'buf>);
22926 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
22927 Self::decode_request(buf)
22928 }
22929 fn lookup(
22930 buf: &[u8],
22931 offset: usize,
22932 missing_type: Option<u16>,
22933 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
22934 Self::decode_request(buf)
22935 .1
22936 .lookup_attr(offset, missing_type)
22937 }
22938}
22939#[derive(Debug)]
22940pub struct ChainedFinal<'a> {
22941 inner: Chained<'a>,
22942}
22943#[derive(Debug)]
22944pub struct Chained<'a> {
22945 buf: RequestBuf<'a>,
22946 first_seq: u32,
22947 lookups: Vec<(&'static str, LookupFn)>,
22948 last_header_offset: usize,
22949 last_kind: Option<RequestInfo>,
22950}
22951impl<'a> ChainedFinal<'a> {
22952 pub fn into_chained(self) -> Chained<'a> {
22953 self.inner
22954 }
22955 pub fn buf(&self) -> &Vec<u8> {
22956 self.inner.buf()
22957 }
22958 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
22959 self.inner.buf_mut()
22960 }
22961 fn get_index(&self, seq: u32) -> Option<u32> {
22962 let min = self.inner.first_seq;
22963 let max = min.wrapping_add(self.inner.lookups.len() as u32);
22964 return if min <= max {
22965 (min..max).contains(&seq).then(|| seq - min)
22966 } else if min <= seq {
22967 Some(seq - min)
22968 } else if seq < max {
22969 Some(u32::MAX - min + seq)
22970 } else {
22971 None
22972 };
22973 }
22974}
22975impl crate::traits::NetlinkChained for ChainedFinal<'_> {
22976 fn protonum(&self) -> u16 {
22977 PROTONUM
22978 }
22979 fn payload(&self) -> &[u8] {
22980 self.buf()
22981 }
22982 fn chain_len(&self) -> usize {
22983 self.inner.lookups.len()
22984 }
22985 fn get_index(&self, seq: u32) -> Option<usize> {
22986 self.get_index(seq).map(|n| n as usize)
22987 }
22988 fn name(&self, index: usize) -> &'static str {
22989 self.inner.lookups[index].0
22990 }
22991 fn lookup(&self, index: usize) -> LookupFn {
22992 self.inner.lookups[index].1
22993 }
22994}
22995impl Chained<'static> {
22996 pub fn new(first_seq: u32) -> Self {
22997 Self::new_from_buf(Vec::new(), first_seq)
22998 }
22999 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
23000 Self {
23001 buf: RequestBuf::Own(buf),
23002 first_seq,
23003 lookups: Vec::new(),
23004 last_header_offset: 0,
23005 last_kind: None,
23006 }
23007 }
23008 pub fn into_buf(self) -> Vec<u8> {
23009 match self.buf {
23010 RequestBuf::Own(buf) => buf,
23011 _ => unreachable!(),
23012 }
23013 }
23014}
23015impl<'a> Chained<'a> {
23016 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
23017 Self {
23018 buf: RequestBuf::Ref(buf),
23019 first_seq,
23020 lookups: Vec::new(),
23021 last_header_offset: 0,
23022 last_kind: None,
23023 }
23024 }
23025 pub fn finalize(mut self) -> ChainedFinal<'a> {
23026 self.update_header();
23027 ChainedFinal { inner: self }
23028 }
23029 pub fn request(&mut self) -> Request<'_> {
23030 self.update_header();
23031 self.last_header_offset = self.buf().len();
23032 self.buf_mut().extend_from_slice(Nlmsghdr::new().as_slice());
23033 let mut request = Request::new_extend(self.buf.buf_mut());
23034 self.last_kind = None;
23035 request.writeback = Some(&mut self.last_kind);
23036 request
23037 }
23038 pub fn buf(&self) -> &Vec<u8> {
23039 self.buf.buf()
23040 }
23041 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
23042 self.buf.buf_mut()
23043 }
23044 fn update_header(&mut self) {
23045 let Some(RequestInfo {
23046 protocol,
23047 flags,
23048 name,
23049 lookup,
23050 }) = self.last_kind
23051 else {
23052 if !self.buf().is_empty() {
23053 assert_eq!(self.last_header_offset + Nlmsghdr::len(), self.buf().len());
23054 self.buf.buf_mut().truncate(self.last_header_offset);
23055 }
23056 return;
23057 };
23058 let header_offset = self.last_header_offset;
23059 let request_type = match protocol {
23060 Protocol::Raw { request_type, .. } => request_type,
23061 Protocol::Generic(_) => unreachable!(),
23062 };
23063 let index = self.lookups.len();
23064 let seq = self.first_seq.wrapping_add(index as u32);
23065 self.lookups.push((name, lookup));
23066 let buf = self.buf_mut();
23067 align(buf);
23068 let header = Nlmsghdr {
23069 len: (buf.len() - header_offset) as u32,
23070 r#type: request_type,
23071 flags: flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16,
23072 seq,
23073 pid: 0,
23074 };
23075 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
23076 }
23077}
23078use crate::traits::LookupFn;
23079use crate::utils::RequestBuf;
23080#[derive(Debug)]
23081pub struct Request<'buf> {
23082 buf: RequestBuf<'buf>,
23083 flags: u16,
23084 writeback: Option<&'buf mut Option<RequestInfo>>,
23085}
23086#[allow(unused)]
23087#[derive(Debug, Clone)]
23088pub struct RequestInfo {
23089 protocol: Protocol,
23090 flags: u16,
23091 name: &'static str,
23092 lookup: LookupFn,
23093}
23094impl Request<'static> {
23095 pub fn new() -> Self {
23096 Self::new_from_buf(Vec::new())
23097 }
23098 pub fn new_from_buf(buf: Vec<u8>) -> Self {
23099 Self {
23100 flags: 0,
23101 buf: RequestBuf::Own(buf),
23102 writeback: None,
23103 }
23104 }
23105 pub fn into_buf(self) -> Vec<u8> {
23106 match self.buf {
23107 RequestBuf::Own(buf) => buf,
23108 _ => unreachable!(),
23109 }
23110 }
23111}
23112impl<'buf> Request<'buf> {
23113 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
23114 buf.clear();
23115 Self::new_extend(buf)
23116 }
23117 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
23118 Self {
23119 flags: 0,
23120 buf: RequestBuf::Ref(buf),
23121 writeback: None,
23122 }
23123 }
23124 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
23125 let Some(writeback) = &mut self.writeback else {
23126 return;
23127 };
23128 **writeback = Some(RequestInfo {
23129 protocol,
23130 flags: self.flags,
23131 name,
23132 lookup,
23133 })
23134 }
23135 pub fn buf(&self) -> &Vec<u8> {
23136 self.buf.buf()
23137 }
23138 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
23139 self.buf.buf_mut()
23140 }
23141 #[doc = "Set `NLM_F_CREATE` flag"]
23142 pub fn set_create(mut self) -> Self {
23143 self.flags |= consts::NLM_F_CREATE as u16;
23144 self
23145 }
23146 #[doc = "Set `NLM_F_EXCL` flag"]
23147 pub fn set_excl(mut self) -> Self {
23148 self.flags |= consts::NLM_F_EXCL as u16;
23149 self
23150 }
23151 #[doc = "Set `NLM_F_REPLACE` flag"]
23152 pub fn set_replace(mut self) -> Self {
23153 self.flags |= consts::NLM_F_REPLACE as u16;
23154 self
23155 }
23156 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
23157 pub fn set_change(self) -> Self {
23158 self.set_create().set_replace()
23159 }
23160 #[doc = "Set `NLM_F_APPEND` flag"]
23161 pub fn set_append(mut self) -> Self {
23162 self.flags |= consts::NLM_F_APPEND as u16;
23163 self
23164 }
23165 #[doc = "Set `self.flags |= flags`"]
23166 pub fn set_flags(mut self, flags: u16) -> Self {
23167 self.flags |= flags;
23168 self
23169 }
23170 #[doc = "Set `self.flags ^= self.flags & flags`"]
23171 pub fn unset_flags(mut self, flags: u16) -> Self {
23172 self.flags ^= self.flags & flags;
23173 self
23174 }
23175 #[doc = "Set `NLM_F_DUMP` flag"]
23176 fn set_dump(mut self) -> Self {
23177 self.flags |= consts::NLM_F_DUMP as u16;
23178 self
23179 }
23180 #[doc = "Create a new link\\.\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"]
23181 pub fn op_newlink_do(self, header: &Ifinfomsg) -> OpNewlinkDo<'buf> {
23182 let mut res = OpNewlinkDo::new(self, header);
23183 res.request
23184 .do_writeback(res.protocol(), "op-newlink-do", OpNewlinkDo::lookup);
23185 res
23186 }
23187 #[doc = "Delete an existing link\\.\nRequest attributes:\n- [.push_ifname()](PushLinkAttrs::push_ifname)\n"]
23188 pub fn op_dellink_do(self, header: &Ifinfomsg) -> OpDellinkDo<'buf> {
23189 let mut res = OpDellinkDo::new(self, header);
23190 res.request
23191 .do_writeback(res.protocol(), "op-dellink-do", OpDellinkDo::lookup);
23192 res
23193 }
23194 #[doc = "Get / dump information about a link\\.\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_cost()](IterableLinkAttrs::get_cost)\n- [.get_priority()](IterableLinkAttrs::get_priority)\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"]
23195 pub fn op_getlink_dump(self, header: &Ifinfomsg) -> OpGetlinkDump<'buf> {
23196 let mut res = OpGetlinkDump::new(self, header);
23197 res.request
23198 .do_writeback(res.protocol(), "op-getlink-dump", OpGetlinkDump::lookup);
23199 res
23200 }
23201 #[doc = "Get / dump information about a link\\.\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_cost()](IterableLinkAttrs::get_cost)\n- [.get_priority()](IterableLinkAttrs::get_priority)\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"]
23202 pub fn op_getlink_do(self, header: &Ifinfomsg) -> OpGetlinkDo<'buf> {
23203 let mut res = OpGetlinkDo::new(self, header);
23204 res.request
23205 .do_writeback(res.protocol(), "op-getlink-do", OpGetlinkDo::lookup);
23206 res
23207 }
23208 #[doc = "Set information about a link\\.\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_cost()](PushLinkAttrs::push_cost)\n- [.push_priority()](PushLinkAttrs::push_priority)\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"]
23209 pub fn op_setlink_do(self, header: &Ifinfomsg) -> OpSetlinkDo<'buf> {
23210 let mut res = OpSetlinkDo::new(self, header);
23211 res.request
23212 .do_writeback(res.protocol(), "op-setlink-do", OpSetlinkDo::lookup);
23213 res
23214 }
23215 #[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"]
23216 pub fn op_getstats_dump(self, header: &IfStatsMsg) -> OpGetstatsDump<'buf> {
23217 let mut res = OpGetstatsDump::new(self, header);
23218 res.request
23219 .do_writeback(res.protocol(), "op-getstats-dump", OpGetstatsDump::lookup);
23220 res
23221 }
23222 #[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"]
23223 pub fn op_getstats_do(self, header: &IfStatsMsg) -> OpGetstatsDo<'buf> {
23224 let mut res = OpGetstatsDo::new(self, header);
23225 res.request
23226 .do_writeback(res.protocol(), "op-getstats-do", OpGetstatsDo::lookup);
23227 res
23228 }
23229}
23230#[cfg(test)]
23231mod generated_tests {
23232 use super::*;
23233 #[test]
23234 fn tests() {
23235 let _ = IterableLinkAttrs::get_address;
23236 let _ = IterableLinkAttrs::get_af_spec;
23237 let _ = IterableLinkAttrs::get_allmulti;
23238 let _ = IterableLinkAttrs::get_broadcast;
23239 let _ = IterableLinkAttrs::get_carrier;
23240 let _ = IterableLinkAttrs::get_carrier_changes;
23241 let _ = IterableLinkAttrs::get_carrier_down_count;
23242 let _ = IterableLinkAttrs::get_carrier_up_count;
23243 let _ = IterableLinkAttrs::get_cost;
23244 let _ = IterableLinkAttrs::get_devlink_port;
23245 let _ = IterableLinkAttrs::get_event;
23246 let _ = IterableLinkAttrs::get_ext_mask;
23247 let _ = IterableLinkAttrs::get_gro_ipv4_max_size;
23248 let _ = IterableLinkAttrs::get_gro_max_size;
23249 let _ = IterableLinkAttrs::get_group;
23250 let _ = IterableLinkAttrs::get_gso_ipv4_max_size;
23251 let _ = IterableLinkAttrs::get_gso_max_segs;
23252 let _ = IterableLinkAttrs::get_gso_max_size;
23253 let _ = IterableLinkAttrs::get_ifalias;
23254 let _ = IterableLinkAttrs::get_ifname;
23255 let _ = IterableLinkAttrs::get_link;
23256 let _ = IterableLinkAttrs::get_link_netnsid;
23257 let _ = IterableLinkAttrs::get_linkinfo;
23258 let _ = IterableLinkAttrs::get_linkmode;
23259 let _ = IterableLinkAttrs::get_map;
23260 let _ = IterableLinkAttrs::get_master;
23261 let _ = IterableLinkAttrs::get_max_mtu;
23262 let _ = IterableLinkAttrs::get_min_mtu;
23263 let _ = IterableLinkAttrs::get_mtu;
23264 let _ = IterableLinkAttrs::get_net_ns_fd;
23265 let _ = IterableLinkAttrs::get_net_ns_pid;
23266 let _ = IterableLinkAttrs::get_new_ifindex;
23267 let _ = IterableLinkAttrs::get_new_netnsid;
23268 let _ = IterableLinkAttrs::get_num_rx_queues;
23269 let _ = IterableLinkAttrs::get_num_tx_queues;
23270 let _ = IterableLinkAttrs::get_num_vf;
23271 let _ = IterableLinkAttrs::get_operstate;
23272 let _ = IterableLinkAttrs::get_parent_dev_bus_name;
23273 let _ = IterableLinkAttrs::get_parent_dev_name;
23274 let _ = IterableLinkAttrs::get_perm_address;
23275 let _ = IterableLinkAttrs::get_phys_port_id;
23276 let _ = IterableLinkAttrs::get_phys_port_name;
23277 let _ = IterableLinkAttrs::get_phys_switch_id;
23278 let _ = IterableLinkAttrs::get_port_self;
23279 let _ = IterableLinkAttrs::get_priority;
23280 let _ = IterableLinkAttrs::get_promiscuity;
23281 let _ = IterableLinkAttrs::get_prop_list;
23282 let _ = IterableLinkAttrs::get_protinfo;
23283 let _ = IterableLinkAttrs::get_proto_down;
23284 let _ = IterableLinkAttrs::get_proto_down_reason;
23285 let _ = IterableLinkAttrs::get_qdisc;
23286 let _ = IterableLinkAttrs::get_stats64;
23287 let _ = IterableLinkAttrs::get_stats;
23288 let _ = IterableLinkAttrs::get_target_netnsid;
23289 let _ = IterableLinkAttrs::get_tso_max_segs;
23290 let _ = IterableLinkAttrs::get_tso_max_size;
23291 let _ = IterableLinkAttrs::get_txqlen;
23292 let _ = IterableLinkAttrs::get_vf_ports;
23293 let _ = IterableLinkAttrs::get_vfinfo_list;
23294 let _ = IterableLinkAttrs::get_weight;
23295 let _ = IterableLinkAttrs::get_wireless;
23296 let _ = IterableLinkAttrs::get_xdp;
23297 let _ = IterableStatsAttrs::get_af_spec;
23298 let _ = IterableStatsAttrs::get_link_64;
23299 let _ = IterableStatsAttrs::get_link_offload_xstats;
23300 let _ = IterableStatsAttrs::get_link_xstats;
23301 let _ = IterableStatsAttrs::get_link_xstats_slave;
23302 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_af_spec;
23303 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_linkinfo;
23304 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_port_self;
23305 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_prop_list;
23306 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_vf_ports;
23307 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_vfinfo_list;
23308 let _ = PushLinkAttrs::<&mut Vec<u8>>::nested_xdp;
23309 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_address;
23310 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_allmulti;
23311 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_alt_ifname;
23312 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_broadcast;
23313 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier;
23314 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier_changes;
23315 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier_down_count;
23316 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_carrier_up_count;
23317 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_cost;
23318 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_devlink_port;
23319 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_event;
23320 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_ext_mask;
23321 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gro_ipv4_max_size;
23322 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gro_max_size;
23323 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_group;
23324 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gso_ipv4_max_size;
23325 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gso_max_segs;
23326 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_gso_max_size;
23327 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_ifalias;
23328 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_ifname;
23329 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_link;
23330 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_link_netnsid;
23331 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_linkmode;
23332 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_map;
23333 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_master;
23334 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_max_mtu;
23335 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_min_mtu;
23336 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_mtu;
23337 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_net_ns_fd;
23338 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_net_ns_pid;
23339 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_new_ifindex;
23340 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_new_netnsid;
23341 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_num_rx_queues;
23342 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_num_tx_queues;
23343 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_num_vf;
23344 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_operstate;
23345 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_parent_dev_bus_name;
23346 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_parent_dev_name;
23347 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_perm_address;
23348 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_phys_port_id;
23349 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_phys_port_name;
23350 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_phys_switch_id;
23351 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_priority;
23352 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_promiscuity;
23353 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_protinfo;
23354 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_proto_down;
23355 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_proto_down_reason;
23356 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_qdisc;
23357 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_stats64;
23358 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_stats;
23359 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_target_netnsid;
23360 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_tso_max_segs;
23361 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_tso_max_size;
23362 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_txqlen;
23363 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_weight;
23364 let _ = PushLinkAttrs::<&mut Vec<u8>>::push_wireless;
23365 }
23366}