Skip to main content

netlink_bindings/rt-neigh/
mod.rs

1#![doc = "IP neighbour management 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::{PushBuiltinBitfield32, PushBuiltinNfgenmsg, PushDummy, PushNlmsghdr};
11use crate::{
12    consts,
13    traits::{NetlinkRequest, Protocol},
14    utils::*,
15};
16pub const PROTONAME: &CStr = c"rt-neigh";
17pub const PROTONUM: u16 = 0u16;
18#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
19#[derive(Debug, Clone, Copy)]
20pub enum NudState {
21    Incomplete = 1 << 0,
22    Reachable = 1 << 1,
23    Stale = 1 << 2,
24    Delay = 1 << 3,
25    Probe = 1 << 4,
26    Failed = 1 << 5,
27    Noarp = 1 << 6,
28    Permanent = 1 << 7,
29}
30impl NudState {
31    pub fn from_value(value: u64) -> Option<Self> {
32        Some(match value {
33            n if n == 1 << 0 => Self::Incomplete,
34            n if n == 1 << 1 => Self::Reachable,
35            n if n == 1 << 2 => Self::Stale,
36            n if n == 1 << 3 => Self::Delay,
37            n if n == 1 << 4 => Self::Probe,
38            n if n == 1 << 5 => Self::Failed,
39            n if n == 1 << 6 => Self::Noarp,
40            n if n == 1 << 7 => Self::Permanent,
41            _ => return None,
42        })
43    }
44}
45#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
46#[derive(Debug, Clone, Copy)]
47pub enum NtfFlags {
48    Use = 1 << 0,
49    _Self = 1 << 1,
50    Master = 1 << 2,
51    Proxy = 1 << 3,
52    ExtLearned = 1 << 4,
53    Offloaded = 1 << 5,
54    Sticky = 1 << 6,
55    Router = 1 << 7,
56}
57impl NtfFlags {
58    pub fn from_value(value: u64) -> Option<Self> {
59        Some(match value {
60            n if n == 1 << 0 => Self::Use,
61            n if n == 1 << 1 => Self::_Self,
62            n if n == 1 << 2 => Self::Master,
63            n if n == 1 << 3 => Self::Proxy,
64            n if n == 1 << 4 => Self::ExtLearned,
65            n if n == 1 << 5 => Self::Offloaded,
66            n if n == 1 << 6 => Self::Sticky,
67            n if n == 1 << 7 => Self::Router,
68            _ => return None,
69        })
70    }
71}
72#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
73#[derive(Debug, Clone, Copy)]
74pub enum NtfExtFlags {
75    Managed = 1 << 0,
76    Locked = 1 << 1,
77    ExtValidated = 1 << 2,
78}
79impl NtfExtFlags {
80    pub fn from_value(value: u64) -> Option<Self> {
81        Some(match value {
82            n if n == 1 << 0 => Self::Managed,
83            n if n == 1 << 1 => Self::Locked,
84            n if n == 1 << 2 => Self::ExtValidated,
85            _ => return None,
86        })
87    }
88}
89#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
90#[derive(Debug, Clone, Copy)]
91pub enum RtmType {
92    Unspec = 0,
93    Unicast = 1,
94    Local = 2,
95    Broadcast = 3,
96    Anycast = 4,
97    Multicast = 5,
98    Blackhole = 6,
99    Unreachable = 7,
100    Prohibit = 8,
101    Throw = 9,
102    Nat = 10,
103    Xresolve = 11,
104}
105impl RtmType {
106    pub fn from_value(value: u64) -> Option<Self> {
107        Some(match value {
108            0 => Self::Unspec,
109            1 => Self::Unicast,
110            2 => Self::Local,
111            3 => Self::Broadcast,
112            4 => Self::Anycast,
113            5 => Self::Multicast,
114            6 => Self::Blackhole,
115            7 => Self::Unreachable,
116            8 => Self::Prohibit,
117            9 => Self::Throw,
118            10 => Self::Nat,
119            11 => Self::Xresolve,
120            _ => return None,
121        })
122    }
123}
124#[derive(Clone)]
125pub enum NeighbourAttrs<'a> {
126    Unspec(&'a [u8]),
127    Dst(&'a [u8]),
128    Lladdr(&'a [u8]),
129    Cacheinfo(PushNdaCacheinfo),
130    Probes(u32),
131    Vlan(u16),
132    Port(u16),
133    Vni(u32),
134    Ifindex(u32),
135    Master(u32),
136    LinkNetnsid(i32),
137    SrcVni(u32),
138    Protocol(u8),
139    NhId(u32),
140    FdbExtAttrs(&'a [u8]),
141    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
142    FlagsExt(u32),
143    NdmStateMask(u16),
144    NdmFlagsMask(u8),
145}
146impl<'a> IterableNeighbourAttrs<'a> {
147    pub fn get_unspec(&self) -> Result<&'a [u8], ErrorContext> {
148        let mut iter = self.clone();
149        iter.pos = 0;
150        for attr in iter {
151            if let NeighbourAttrs::Unspec(val) = attr? {
152                return Ok(val);
153            }
154        }
155        Err(ErrorContext::new_missing(
156            "NeighbourAttrs",
157            "Unspec",
158            self.orig_loc,
159            self.buf.as_ptr() as usize,
160        ))
161    }
162    pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
163        let mut iter = self.clone();
164        iter.pos = 0;
165        for attr in iter {
166            if let NeighbourAttrs::Dst(val) = attr? {
167                return Ok(val);
168            }
169        }
170        Err(ErrorContext::new_missing(
171            "NeighbourAttrs",
172            "Dst",
173            self.orig_loc,
174            self.buf.as_ptr() as usize,
175        ))
176    }
177    pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
178        let mut iter = self.clone();
179        iter.pos = 0;
180        for attr in iter {
181            if let NeighbourAttrs::Lladdr(val) = attr? {
182                return Ok(val);
183            }
184        }
185        Err(ErrorContext::new_missing(
186            "NeighbourAttrs",
187            "Lladdr",
188            self.orig_loc,
189            self.buf.as_ptr() as usize,
190        ))
191    }
192    pub fn get_cacheinfo(&self) -> Result<PushNdaCacheinfo, ErrorContext> {
193        let mut iter = self.clone();
194        iter.pos = 0;
195        for attr in iter {
196            if let NeighbourAttrs::Cacheinfo(val) = attr? {
197                return Ok(val);
198            }
199        }
200        Err(ErrorContext::new_missing(
201            "NeighbourAttrs",
202            "Cacheinfo",
203            self.orig_loc,
204            self.buf.as_ptr() as usize,
205        ))
206    }
207    pub fn get_probes(&self) -> Result<u32, ErrorContext> {
208        let mut iter = self.clone();
209        iter.pos = 0;
210        for attr in iter {
211            if let NeighbourAttrs::Probes(val) = attr? {
212                return Ok(val);
213            }
214        }
215        Err(ErrorContext::new_missing(
216            "NeighbourAttrs",
217            "Probes",
218            self.orig_loc,
219            self.buf.as_ptr() as usize,
220        ))
221    }
222    pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
223        let mut iter = self.clone();
224        iter.pos = 0;
225        for attr in iter {
226            if let NeighbourAttrs::Vlan(val) = attr? {
227                return Ok(val);
228            }
229        }
230        Err(ErrorContext::new_missing(
231            "NeighbourAttrs",
232            "Vlan",
233            self.orig_loc,
234            self.buf.as_ptr() as usize,
235        ))
236    }
237    pub fn get_port(&self) -> Result<u16, ErrorContext> {
238        let mut iter = self.clone();
239        iter.pos = 0;
240        for attr in iter {
241            if let NeighbourAttrs::Port(val) = attr? {
242                return Ok(val);
243            }
244        }
245        Err(ErrorContext::new_missing(
246            "NeighbourAttrs",
247            "Port",
248            self.orig_loc,
249            self.buf.as_ptr() as usize,
250        ))
251    }
252    pub fn get_vni(&self) -> Result<u32, ErrorContext> {
253        let mut iter = self.clone();
254        iter.pos = 0;
255        for attr in iter {
256            if let NeighbourAttrs::Vni(val) = attr? {
257                return Ok(val);
258            }
259        }
260        Err(ErrorContext::new_missing(
261            "NeighbourAttrs",
262            "Vni",
263            self.orig_loc,
264            self.buf.as_ptr() as usize,
265        ))
266    }
267    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
268        let mut iter = self.clone();
269        iter.pos = 0;
270        for attr in iter {
271            if let NeighbourAttrs::Ifindex(val) = attr? {
272                return Ok(val);
273            }
274        }
275        Err(ErrorContext::new_missing(
276            "NeighbourAttrs",
277            "Ifindex",
278            self.orig_loc,
279            self.buf.as_ptr() as usize,
280        ))
281    }
282    pub fn get_master(&self) -> Result<u32, ErrorContext> {
283        let mut iter = self.clone();
284        iter.pos = 0;
285        for attr in iter {
286            if let NeighbourAttrs::Master(val) = attr? {
287                return Ok(val);
288            }
289        }
290        Err(ErrorContext::new_missing(
291            "NeighbourAttrs",
292            "Master",
293            self.orig_loc,
294            self.buf.as_ptr() as usize,
295        ))
296    }
297    pub fn get_link_netnsid(&self) -> Result<i32, ErrorContext> {
298        let mut iter = self.clone();
299        iter.pos = 0;
300        for attr in iter {
301            if let NeighbourAttrs::LinkNetnsid(val) = attr? {
302                return Ok(val);
303            }
304        }
305        Err(ErrorContext::new_missing(
306            "NeighbourAttrs",
307            "LinkNetnsid",
308            self.orig_loc,
309            self.buf.as_ptr() as usize,
310        ))
311    }
312    pub fn get_src_vni(&self) -> Result<u32, ErrorContext> {
313        let mut iter = self.clone();
314        iter.pos = 0;
315        for attr in iter {
316            if let NeighbourAttrs::SrcVni(val) = attr? {
317                return Ok(val);
318            }
319        }
320        Err(ErrorContext::new_missing(
321            "NeighbourAttrs",
322            "SrcVni",
323            self.orig_loc,
324            self.buf.as_ptr() as usize,
325        ))
326    }
327    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
328        let mut iter = self.clone();
329        iter.pos = 0;
330        for attr in iter {
331            if let NeighbourAttrs::Protocol(val) = attr? {
332                return Ok(val);
333            }
334        }
335        Err(ErrorContext::new_missing(
336            "NeighbourAttrs",
337            "Protocol",
338            self.orig_loc,
339            self.buf.as_ptr() as usize,
340        ))
341    }
342    pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
343        let mut iter = self.clone();
344        iter.pos = 0;
345        for attr in iter {
346            if let NeighbourAttrs::NhId(val) = attr? {
347                return Ok(val);
348            }
349        }
350        Err(ErrorContext::new_missing(
351            "NeighbourAttrs",
352            "NhId",
353            self.orig_loc,
354            self.buf.as_ptr() as usize,
355        ))
356    }
357    pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
358        let mut iter = self.clone();
359        iter.pos = 0;
360        for attr in iter {
361            if let NeighbourAttrs::FdbExtAttrs(val) = attr? {
362                return Ok(val);
363            }
364        }
365        Err(ErrorContext::new_missing(
366            "NeighbourAttrs",
367            "FdbExtAttrs",
368            self.orig_loc,
369            self.buf.as_ptr() as usize,
370        ))
371    }
372    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
373    pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
374        let mut iter = self.clone();
375        iter.pos = 0;
376        for attr in iter {
377            if let NeighbourAttrs::FlagsExt(val) = attr? {
378                return Ok(val);
379            }
380        }
381        Err(ErrorContext::new_missing(
382            "NeighbourAttrs",
383            "FlagsExt",
384            self.orig_loc,
385            self.buf.as_ptr() as usize,
386        ))
387    }
388    pub fn get_ndm_state_mask(&self) -> Result<u16, ErrorContext> {
389        let mut iter = self.clone();
390        iter.pos = 0;
391        for attr in iter {
392            if let NeighbourAttrs::NdmStateMask(val) = attr? {
393                return Ok(val);
394            }
395        }
396        Err(ErrorContext::new_missing(
397            "NeighbourAttrs",
398            "NdmStateMask",
399            self.orig_loc,
400            self.buf.as_ptr() as usize,
401        ))
402    }
403    pub fn get_ndm_flags_mask(&self) -> Result<u8, ErrorContext> {
404        let mut iter = self.clone();
405        iter.pos = 0;
406        for attr in iter {
407            if let NeighbourAttrs::NdmFlagsMask(val) = attr? {
408                return Ok(val);
409            }
410        }
411        Err(ErrorContext::new_missing(
412            "NeighbourAttrs",
413            "NdmFlagsMask",
414            self.orig_loc,
415            self.buf.as_ptr() as usize,
416        ))
417    }
418}
419impl NeighbourAttrs<'_> {
420    pub fn new<'a>(buf: &'a [u8]) -> IterableNeighbourAttrs<'a> {
421        IterableNeighbourAttrs::with_loc(buf, buf.as_ptr() as usize)
422    }
423    fn attr_from_type(r#type: u16) -> Option<&'static str> {
424        let res = match r#type {
425            0u16 => "Unspec",
426            1u16 => "Dst",
427            2u16 => "Lladdr",
428            3u16 => "Cacheinfo",
429            4u16 => "Probes",
430            5u16 => "Vlan",
431            6u16 => "Port",
432            7u16 => "Vni",
433            8u16 => "Ifindex",
434            9u16 => "Master",
435            10u16 => "LinkNetnsid",
436            11u16 => "SrcVni",
437            12u16 => "Protocol",
438            13u16 => "NhId",
439            14u16 => "FdbExtAttrs",
440            15u16 => "FlagsExt",
441            16u16 => "NdmStateMask",
442            17u16 => "NdmFlagsMask",
443            _ => return None,
444        };
445        Some(res)
446    }
447}
448#[derive(Clone, Copy, Default)]
449pub struct IterableNeighbourAttrs<'a> {
450    buf: &'a [u8],
451    pos: usize,
452    orig_loc: usize,
453}
454impl<'a> IterableNeighbourAttrs<'a> {
455    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
456        Self {
457            buf,
458            pos: 0,
459            orig_loc,
460        }
461    }
462    pub fn get_buf(&self) -> &'a [u8] {
463        self.buf
464    }
465}
466impl<'a> Iterator for IterableNeighbourAttrs<'a> {
467    type Item = Result<NeighbourAttrs<'a>, ErrorContext>;
468    fn next(&mut self) -> Option<Self::Item> {
469        let pos = self.pos;
470        let mut r#type;
471        loop {
472            r#type = None;
473            if self.buf.len() == self.pos {
474                return None;
475            }
476            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
477                break;
478            };
479            r#type = Some(header.r#type);
480            let res = match header.r#type {
481                0u16 => NeighbourAttrs::Unspec({
482                    let res = Some(next);
483                    let Some(val) = res else { break };
484                    val
485                }),
486                1u16 => NeighbourAttrs::Dst({
487                    let res = Some(next);
488                    let Some(val) = res else { break };
489                    val
490                }),
491                2u16 => NeighbourAttrs::Lladdr({
492                    let res = Some(next);
493                    let Some(val) = res else { break };
494                    val
495                }),
496                3u16 => NeighbourAttrs::Cacheinfo({
497                    let res = PushNdaCacheinfo::new_from_slice(next);
498                    let Some(val) = res else { break };
499                    val
500                }),
501                4u16 => NeighbourAttrs::Probes({
502                    let res = parse_u32(next);
503                    let Some(val) = res else { break };
504                    val
505                }),
506                5u16 => NeighbourAttrs::Vlan({
507                    let res = parse_u16(next);
508                    let Some(val) = res else { break };
509                    val
510                }),
511                6u16 => NeighbourAttrs::Port({
512                    let res = parse_u16(next);
513                    let Some(val) = res else { break };
514                    val
515                }),
516                7u16 => NeighbourAttrs::Vni({
517                    let res = parse_u32(next);
518                    let Some(val) = res else { break };
519                    val
520                }),
521                8u16 => NeighbourAttrs::Ifindex({
522                    let res = parse_u32(next);
523                    let Some(val) = res else { break };
524                    val
525                }),
526                9u16 => NeighbourAttrs::Master({
527                    let res = parse_u32(next);
528                    let Some(val) = res else { break };
529                    val
530                }),
531                10u16 => NeighbourAttrs::LinkNetnsid({
532                    let res = parse_i32(next);
533                    let Some(val) = res else { break };
534                    val
535                }),
536                11u16 => NeighbourAttrs::SrcVni({
537                    let res = parse_u32(next);
538                    let Some(val) = res else { break };
539                    val
540                }),
541                12u16 => NeighbourAttrs::Protocol({
542                    let res = parse_u8(next);
543                    let Some(val) = res else { break };
544                    val
545                }),
546                13u16 => NeighbourAttrs::NhId({
547                    let res = parse_u32(next);
548                    let Some(val) = res else { break };
549                    val
550                }),
551                14u16 => NeighbourAttrs::FdbExtAttrs({
552                    let res = Some(next);
553                    let Some(val) = res else { break };
554                    val
555                }),
556                15u16 => NeighbourAttrs::FlagsExt({
557                    let res = parse_u32(next);
558                    let Some(val) = res else { break };
559                    val
560                }),
561                16u16 => NeighbourAttrs::NdmStateMask({
562                    let res = parse_u16(next);
563                    let Some(val) = res else { break };
564                    val
565                }),
566                17u16 => NeighbourAttrs::NdmFlagsMask({
567                    let res = parse_u8(next);
568                    let Some(val) = res else { break };
569                    val
570                }),
571                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
572                n => continue,
573            };
574            return Some(Ok(res));
575        }
576        Some(Err(ErrorContext::new(
577            "NeighbourAttrs",
578            r#type.and_then(|t| NeighbourAttrs::attr_from_type(t)),
579            self.orig_loc,
580            self.buf.as_ptr().wrapping_add(pos) as usize,
581        )))
582    }
583}
584impl<'a> std::fmt::Debug for IterableNeighbourAttrs<'_> {
585    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
586        let mut fmt = f.debug_struct("NeighbourAttrs");
587        for attr in self.clone() {
588            let attr = match attr {
589                Ok(a) => a,
590                Err(err) => {
591                    fmt.finish()?;
592                    f.write_str("Err(")?;
593                    err.fmt(f)?;
594                    return f.write_str(")");
595                }
596            };
597            match attr {
598                NeighbourAttrs::Unspec(val) => fmt.field("Unspec", &val),
599                NeighbourAttrs::Dst(val) => fmt.field("Dst", &val),
600                NeighbourAttrs::Lladdr(val) => fmt.field("Lladdr", &val),
601                NeighbourAttrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
602                NeighbourAttrs::Probes(val) => fmt.field("Probes", &val),
603                NeighbourAttrs::Vlan(val) => fmt.field("Vlan", &val),
604                NeighbourAttrs::Port(val) => fmt.field("Port", &val),
605                NeighbourAttrs::Vni(val) => fmt.field("Vni", &val),
606                NeighbourAttrs::Ifindex(val) => fmt.field("Ifindex", &val),
607                NeighbourAttrs::Master(val) => fmt.field("Master", &val),
608                NeighbourAttrs::LinkNetnsid(val) => fmt.field("LinkNetnsid", &val),
609                NeighbourAttrs::SrcVni(val) => fmt.field("SrcVni", &val),
610                NeighbourAttrs::Protocol(val) => fmt.field("Protocol", &val),
611                NeighbourAttrs::NhId(val) => fmt.field("NhId", &val),
612                NeighbourAttrs::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
613                NeighbourAttrs::FlagsExt(val) => fmt.field(
614                    "FlagsExt",
615                    &FormatFlags(val.into(), NtfExtFlags::from_value),
616                ),
617                NeighbourAttrs::NdmStateMask(val) => fmt.field("NdmStateMask", &val),
618                NeighbourAttrs::NdmFlagsMask(val) => fmt.field("NdmFlagsMask", &val),
619            };
620        }
621        fmt.finish()
622    }
623}
624impl IterableNeighbourAttrs<'_> {
625    pub fn lookup_attr(
626        &self,
627        offset: usize,
628        missing_type: Option<u16>,
629    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
630        let mut stack = Vec::new();
631        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
632        if cur == offset {
633            stack.push(("NeighbourAttrs", offset));
634            return (
635                stack,
636                missing_type.and_then(|t| NeighbourAttrs::attr_from_type(t)),
637            );
638        }
639        if cur > offset || cur + self.buf.len() < offset {
640            return (stack, None);
641        }
642        let mut attrs = self.clone();
643        let mut last_off = cur + attrs.pos;
644        while let Some(attr) = attrs.next() {
645            let Ok(attr) = attr else { break };
646            match attr {
647                NeighbourAttrs::Unspec(val) => {
648                    if last_off == offset {
649                        stack.push(("Unspec", last_off));
650                        break;
651                    }
652                }
653                NeighbourAttrs::Dst(val) => {
654                    if last_off == offset {
655                        stack.push(("Dst", last_off));
656                        break;
657                    }
658                }
659                NeighbourAttrs::Lladdr(val) => {
660                    if last_off == offset {
661                        stack.push(("Lladdr", last_off));
662                        break;
663                    }
664                }
665                NeighbourAttrs::Cacheinfo(val) => {
666                    if last_off == offset {
667                        stack.push(("Cacheinfo", last_off));
668                        break;
669                    }
670                }
671                NeighbourAttrs::Probes(val) => {
672                    if last_off == offset {
673                        stack.push(("Probes", last_off));
674                        break;
675                    }
676                }
677                NeighbourAttrs::Vlan(val) => {
678                    if last_off == offset {
679                        stack.push(("Vlan", last_off));
680                        break;
681                    }
682                }
683                NeighbourAttrs::Port(val) => {
684                    if last_off == offset {
685                        stack.push(("Port", last_off));
686                        break;
687                    }
688                }
689                NeighbourAttrs::Vni(val) => {
690                    if last_off == offset {
691                        stack.push(("Vni", last_off));
692                        break;
693                    }
694                }
695                NeighbourAttrs::Ifindex(val) => {
696                    if last_off == offset {
697                        stack.push(("Ifindex", last_off));
698                        break;
699                    }
700                }
701                NeighbourAttrs::Master(val) => {
702                    if last_off == offset {
703                        stack.push(("Master", last_off));
704                        break;
705                    }
706                }
707                NeighbourAttrs::LinkNetnsid(val) => {
708                    if last_off == offset {
709                        stack.push(("LinkNetnsid", last_off));
710                        break;
711                    }
712                }
713                NeighbourAttrs::SrcVni(val) => {
714                    if last_off == offset {
715                        stack.push(("SrcVni", last_off));
716                        break;
717                    }
718                }
719                NeighbourAttrs::Protocol(val) => {
720                    if last_off == offset {
721                        stack.push(("Protocol", last_off));
722                        break;
723                    }
724                }
725                NeighbourAttrs::NhId(val) => {
726                    if last_off == offset {
727                        stack.push(("NhId", last_off));
728                        break;
729                    }
730                }
731                NeighbourAttrs::FdbExtAttrs(val) => {
732                    if last_off == offset {
733                        stack.push(("FdbExtAttrs", last_off));
734                        break;
735                    }
736                }
737                NeighbourAttrs::FlagsExt(val) => {
738                    if last_off == offset {
739                        stack.push(("FlagsExt", last_off));
740                        break;
741                    }
742                }
743                NeighbourAttrs::NdmStateMask(val) => {
744                    if last_off == offset {
745                        stack.push(("NdmStateMask", last_off));
746                        break;
747                    }
748                }
749                NeighbourAttrs::NdmFlagsMask(val) => {
750                    if last_off == offset {
751                        stack.push(("NdmFlagsMask", last_off));
752                        break;
753                    }
754                }
755                _ => {}
756            };
757            last_off = cur + attrs.pos;
758        }
759        if !stack.is_empty() {
760            stack.push(("NeighbourAttrs", cur));
761        }
762        (stack, None)
763    }
764}
765#[derive(Clone)]
766pub enum NdtAttrs<'a> {
767    Name(&'a CStr),
768    Thresh1(u32),
769    Thresh2(u32),
770    Thresh3(u32),
771    Config(PushNdtConfig),
772    Parms(IterableNdtpaAttrs<'a>),
773    Stats(PushNdtStats),
774    GcInterval(u64),
775    Pad(&'a [u8]),
776}
777impl<'a> IterableNdtAttrs<'a> {
778    pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
779        let mut iter = self.clone();
780        iter.pos = 0;
781        for attr in iter {
782            if let NdtAttrs::Name(val) = attr? {
783                return Ok(val);
784            }
785        }
786        Err(ErrorContext::new_missing(
787            "NdtAttrs",
788            "Name",
789            self.orig_loc,
790            self.buf.as_ptr() as usize,
791        ))
792    }
793    pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
794        let mut iter = self.clone();
795        iter.pos = 0;
796        for attr in iter {
797            if let NdtAttrs::Thresh1(val) = attr? {
798                return Ok(val);
799            }
800        }
801        Err(ErrorContext::new_missing(
802            "NdtAttrs",
803            "Thresh1",
804            self.orig_loc,
805            self.buf.as_ptr() as usize,
806        ))
807    }
808    pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
809        let mut iter = self.clone();
810        iter.pos = 0;
811        for attr in iter {
812            if let NdtAttrs::Thresh2(val) = attr? {
813                return Ok(val);
814            }
815        }
816        Err(ErrorContext::new_missing(
817            "NdtAttrs",
818            "Thresh2",
819            self.orig_loc,
820            self.buf.as_ptr() as usize,
821        ))
822    }
823    pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
824        let mut iter = self.clone();
825        iter.pos = 0;
826        for attr in iter {
827            if let NdtAttrs::Thresh3(val) = attr? {
828                return Ok(val);
829            }
830        }
831        Err(ErrorContext::new_missing(
832            "NdtAttrs",
833            "Thresh3",
834            self.orig_loc,
835            self.buf.as_ptr() as usize,
836        ))
837    }
838    pub fn get_config(&self) -> Result<PushNdtConfig, ErrorContext> {
839        let mut iter = self.clone();
840        iter.pos = 0;
841        for attr in iter {
842            if let NdtAttrs::Config(val) = attr? {
843                return Ok(val);
844            }
845        }
846        Err(ErrorContext::new_missing(
847            "NdtAttrs",
848            "Config",
849            self.orig_loc,
850            self.buf.as_ptr() as usize,
851        ))
852    }
853    pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
854        let mut iter = self.clone();
855        iter.pos = 0;
856        for attr in iter {
857            if let NdtAttrs::Parms(val) = attr? {
858                return Ok(val);
859            }
860        }
861        Err(ErrorContext::new_missing(
862            "NdtAttrs",
863            "Parms",
864            self.orig_loc,
865            self.buf.as_ptr() as usize,
866        ))
867    }
868    pub fn get_stats(&self) -> Result<PushNdtStats, ErrorContext> {
869        let mut iter = self.clone();
870        iter.pos = 0;
871        for attr in iter {
872            if let NdtAttrs::Stats(val) = attr? {
873                return Ok(val);
874            }
875        }
876        Err(ErrorContext::new_missing(
877            "NdtAttrs",
878            "Stats",
879            self.orig_loc,
880            self.buf.as_ptr() as usize,
881        ))
882    }
883    pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
884        let mut iter = self.clone();
885        iter.pos = 0;
886        for attr in iter {
887            if let NdtAttrs::GcInterval(val) = attr? {
888                return Ok(val);
889            }
890        }
891        Err(ErrorContext::new_missing(
892            "NdtAttrs",
893            "GcInterval",
894            self.orig_loc,
895            self.buf.as_ptr() as usize,
896        ))
897    }
898    pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
899        let mut iter = self.clone();
900        iter.pos = 0;
901        for attr in iter {
902            if let NdtAttrs::Pad(val) = attr? {
903                return Ok(val);
904            }
905        }
906        Err(ErrorContext::new_missing(
907            "NdtAttrs",
908            "Pad",
909            self.orig_loc,
910            self.buf.as_ptr() as usize,
911        ))
912    }
913}
914impl NdtAttrs<'_> {
915    pub fn new<'a>(buf: &'a [u8]) -> IterableNdtAttrs<'a> {
916        IterableNdtAttrs::with_loc(buf, buf.as_ptr() as usize)
917    }
918    fn attr_from_type(r#type: u16) -> Option<&'static str> {
919        let res = match r#type {
920            1u16 => "Name",
921            2u16 => "Thresh1",
922            3u16 => "Thresh2",
923            4u16 => "Thresh3",
924            5u16 => "Config",
925            6u16 => "Parms",
926            7u16 => "Stats",
927            8u16 => "GcInterval",
928            9u16 => "Pad",
929            _ => return None,
930        };
931        Some(res)
932    }
933}
934#[derive(Clone, Copy, Default)]
935pub struct IterableNdtAttrs<'a> {
936    buf: &'a [u8],
937    pos: usize,
938    orig_loc: usize,
939}
940impl<'a> IterableNdtAttrs<'a> {
941    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
942        Self {
943            buf,
944            pos: 0,
945            orig_loc,
946        }
947    }
948    pub fn get_buf(&self) -> &'a [u8] {
949        self.buf
950    }
951}
952impl<'a> Iterator for IterableNdtAttrs<'a> {
953    type Item = Result<NdtAttrs<'a>, ErrorContext>;
954    fn next(&mut self) -> Option<Self::Item> {
955        let pos = self.pos;
956        let mut r#type;
957        loop {
958            r#type = None;
959            if self.buf.len() == self.pos {
960                return None;
961            }
962            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
963                break;
964            };
965            r#type = Some(header.r#type);
966            let res = match header.r#type {
967                1u16 => NdtAttrs::Name({
968                    let res = CStr::from_bytes_with_nul(next).ok();
969                    let Some(val) = res else { break };
970                    val
971                }),
972                2u16 => NdtAttrs::Thresh1({
973                    let res = parse_u32(next);
974                    let Some(val) = res else { break };
975                    val
976                }),
977                3u16 => NdtAttrs::Thresh2({
978                    let res = parse_u32(next);
979                    let Some(val) = res else { break };
980                    val
981                }),
982                4u16 => NdtAttrs::Thresh3({
983                    let res = parse_u32(next);
984                    let Some(val) = res else { break };
985                    val
986                }),
987                5u16 => NdtAttrs::Config({
988                    let res = PushNdtConfig::new_from_slice(next);
989                    let Some(val) = res else { break };
990                    val
991                }),
992                6u16 => NdtAttrs::Parms({
993                    let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
994                    let Some(val) = res else { break };
995                    val
996                }),
997                7u16 => NdtAttrs::Stats({
998                    let res = PushNdtStats::new_from_slice(next);
999                    let Some(val) = res else { break };
1000                    val
1001                }),
1002                8u16 => NdtAttrs::GcInterval({
1003                    let res = parse_u64(next);
1004                    let Some(val) = res else { break };
1005                    val
1006                }),
1007                9u16 => NdtAttrs::Pad({
1008                    let res = Some(next);
1009                    let Some(val) = res else { break };
1010                    val
1011                }),
1012                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1013                n => continue,
1014            };
1015            return Some(Ok(res));
1016        }
1017        Some(Err(ErrorContext::new(
1018            "NdtAttrs",
1019            r#type.and_then(|t| NdtAttrs::attr_from_type(t)),
1020            self.orig_loc,
1021            self.buf.as_ptr().wrapping_add(pos) as usize,
1022        )))
1023    }
1024}
1025impl<'a> std::fmt::Debug for IterableNdtAttrs<'_> {
1026    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1027        let mut fmt = f.debug_struct("NdtAttrs");
1028        for attr in self.clone() {
1029            let attr = match attr {
1030                Ok(a) => a,
1031                Err(err) => {
1032                    fmt.finish()?;
1033                    f.write_str("Err(")?;
1034                    err.fmt(f)?;
1035                    return f.write_str(")");
1036                }
1037            };
1038            match attr {
1039                NdtAttrs::Name(val) => fmt.field("Name", &val),
1040                NdtAttrs::Thresh1(val) => fmt.field("Thresh1", &val),
1041                NdtAttrs::Thresh2(val) => fmt.field("Thresh2", &val),
1042                NdtAttrs::Thresh3(val) => fmt.field("Thresh3", &val),
1043                NdtAttrs::Config(val) => fmt.field("Config", &val),
1044                NdtAttrs::Parms(val) => fmt.field("Parms", &val),
1045                NdtAttrs::Stats(val) => fmt.field("Stats", &val),
1046                NdtAttrs::GcInterval(val) => fmt.field("GcInterval", &val),
1047                NdtAttrs::Pad(val) => fmt.field("Pad", &val),
1048            };
1049        }
1050        fmt.finish()
1051    }
1052}
1053impl IterableNdtAttrs<'_> {
1054    pub fn lookup_attr(
1055        &self,
1056        offset: usize,
1057        missing_type: Option<u16>,
1058    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1059        let mut stack = Vec::new();
1060        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1061        if cur == offset {
1062            stack.push(("NdtAttrs", offset));
1063            return (
1064                stack,
1065                missing_type.and_then(|t| NdtAttrs::attr_from_type(t)),
1066            );
1067        }
1068        if cur > offset || cur + self.buf.len() < offset {
1069            return (stack, None);
1070        }
1071        let mut attrs = self.clone();
1072        let mut last_off = cur + attrs.pos;
1073        let mut missing = None;
1074        while let Some(attr) = attrs.next() {
1075            let Ok(attr) = attr else { break };
1076            match attr {
1077                NdtAttrs::Name(val) => {
1078                    if last_off == offset {
1079                        stack.push(("Name", last_off));
1080                        break;
1081                    }
1082                }
1083                NdtAttrs::Thresh1(val) => {
1084                    if last_off == offset {
1085                        stack.push(("Thresh1", last_off));
1086                        break;
1087                    }
1088                }
1089                NdtAttrs::Thresh2(val) => {
1090                    if last_off == offset {
1091                        stack.push(("Thresh2", last_off));
1092                        break;
1093                    }
1094                }
1095                NdtAttrs::Thresh3(val) => {
1096                    if last_off == offset {
1097                        stack.push(("Thresh3", last_off));
1098                        break;
1099                    }
1100                }
1101                NdtAttrs::Config(val) => {
1102                    if last_off == offset {
1103                        stack.push(("Config", last_off));
1104                        break;
1105                    }
1106                }
1107                NdtAttrs::Parms(val) => {
1108                    (stack, missing) = val.lookup_attr(offset, missing_type);
1109                    if !stack.is_empty() {
1110                        break;
1111                    }
1112                }
1113                NdtAttrs::Stats(val) => {
1114                    if last_off == offset {
1115                        stack.push(("Stats", last_off));
1116                        break;
1117                    }
1118                }
1119                NdtAttrs::GcInterval(val) => {
1120                    if last_off == offset {
1121                        stack.push(("GcInterval", last_off));
1122                        break;
1123                    }
1124                }
1125                NdtAttrs::Pad(val) => {
1126                    if last_off == offset {
1127                        stack.push(("Pad", last_off));
1128                        break;
1129                    }
1130                }
1131                _ => {}
1132            };
1133            last_off = cur + attrs.pos;
1134        }
1135        if !stack.is_empty() {
1136            stack.push(("NdtAttrs", cur));
1137        }
1138        (stack, missing)
1139    }
1140}
1141#[derive(Clone)]
1142pub enum NdtpaAttrs<'a> {
1143    Ifindex(u32),
1144    Refcnt(u32),
1145    ReachableTime(u64),
1146    BaseReachableTime(u64),
1147    RetransTime(u64),
1148    GcStaletime(u64),
1149    DelayProbeTime(u64),
1150    QueueLen(u32),
1151    AppProbes(u32),
1152    UcastProbes(u32),
1153    McastProbes(u32),
1154    AnycastDelay(u64),
1155    ProxyDelay(u64),
1156    ProxyQlen(u32),
1157    Locktime(u64),
1158    QueueLenbytes(u32),
1159    McastReprobes(u32),
1160    Pad(&'a [u8]),
1161    IntervalProbeTimeMs(u64),
1162}
1163impl<'a> IterableNdtpaAttrs<'a> {
1164    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
1165        let mut iter = self.clone();
1166        iter.pos = 0;
1167        for attr in iter {
1168            if let NdtpaAttrs::Ifindex(val) = attr? {
1169                return Ok(val);
1170            }
1171        }
1172        Err(ErrorContext::new_missing(
1173            "NdtpaAttrs",
1174            "Ifindex",
1175            self.orig_loc,
1176            self.buf.as_ptr() as usize,
1177        ))
1178    }
1179    pub fn get_refcnt(&self) -> Result<u32, ErrorContext> {
1180        let mut iter = self.clone();
1181        iter.pos = 0;
1182        for attr in iter {
1183            if let NdtpaAttrs::Refcnt(val) = attr? {
1184                return Ok(val);
1185            }
1186        }
1187        Err(ErrorContext::new_missing(
1188            "NdtpaAttrs",
1189            "Refcnt",
1190            self.orig_loc,
1191            self.buf.as_ptr() as usize,
1192        ))
1193    }
1194    pub fn get_reachable_time(&self) -> Result<u64, ErrorContext> {
1195        let mut iter = self.clone();
1196        iter.pos = 0;
1197        for attr in iter {
1198            if let NdtpaAttrs::ReachableTime(val) = attr? {
1199                return Ok(val);
1200            }
1201        }
1202        Err(ErrorContext::new_missing(
1203            "NdtpaAttrs",
1204            "ReachableTime",
1205            self.orig_loc,
1206            self.buf.as_ptr() as usize,
1207        ))
1208    }
1209    pub fn get_base_reachable_time(&self) -> Result<u64, ErrorContext> {
1210        let mut iter = self.clone();
1211        iter.pos = 0;
1212        for attr in iter {
1213            if let NdtpaAttrs::BaseReachableTime(val) = attr? {
1214                return Ok(val);
1215            }
1216        }
1217        Err(ErrorContext::new_missing(
1218            "NdtpaAttrs",
1219            "BaseReachableTime",
1220            self.orig_loc,
1221            self.buf.as_ptr() as usize,
1222        ))
1223    }
1224    pub fn get_retrans_time(&self) -> Result<u64, ErrorContext> {
1225        let mut iter = self.clone();
1226        iter.pos = 0;
1227        for attr in iter {
1228            if let NdtpaAttrs::RetransTime(val) = attr? {
1229                return Ok(val);
1230            }
1231        }
1232        Err(ErrorContext::new_missing(
1233            "NdtpaAttrs",
1234            "RetransTime",
1235            self.orig_loc,
1236            self.buf.as_ptr() as usize,
1237        ))
1238    }
1239    pub fn get_gc_staletime(&self) -> Result<u64, ErrorContext> {
1240        let mut iter = self.clone();
1241        iter.pos = 0;
1242        for attr in iter {
1243            if let NdtpaAttrs::GcStaletime(val) = attr? {
1244                return Ok(val);
1245            }
1246        }
1247        Err(ErrorContext::new_missing(
1248            "NdtpaAttrs",
1249            "GcStaletime",
1250            self.orig_loc,
1251            self.buf.as_ptr() as usize,
1252        ))
1253    }
1254    pub fn get_delay_probe_time(&self) -> Result<u64, ErrorContext> {
1255        let mut iter = self.clone();
1256        iter.pos = 0;
1257        for attr in iter {
1258            if let NdtpaAttrs::DelayProbeTime(val) = attr? {
1259                return Ok(val);
1260            }
1261        }
1262        Err(ErrorContext::new_missing(
1263            "NdtpaAttrs",
1264            "DelayProbeTime",
1265            self.orig_loc,
1266            self.buf.as_ptr() as usize,
1267        ))
1268    }
1269    pub fn get_queue_len(&self) -> Result<u32, ErrorContext> {
1270        let mut iter = self.clone();
1271        iter.pos = 0;
1272        for attr in iter {
1273            if let NdtpaAttrs::QueueLen(val) = attr? {
1274                return Ok(val);
1275            }
1276        }
1277        Err(ErrorContext::new_missing(
1278            "NdtpaAttrs",
1279            "QueueLen",
1280            self.orig_loc,
1281            self.buf.as_ptr() as usize,
1282        ))
1283    }
1284    pub fn get_app_probes(&self) -> Result<u32, ErrorContext> {
1285        let mut iter = self.clone();
1286        iter.pos = 0;
1287        for attr in iter {
1288            if let NdtpaAttrs::AppProbes(val) = attr? {
1289                return Ok(val);
1290            }
1291        }
1292        Err(ErrorContext::new_missing(
1293            "NdtpaAttrs",
1294            "AppProbes",
1295            self.orig_loc,
1296            self.buf.as_ptr() as usize,
1297        ))
1298    }
1299    pub fn get_ucast_probes(&self) -> Result<u32, ErrorContext> {
1300        let mut iter = self.clone();
1301        iter.pos = 0;
1302        for attr in iter {
1303            if let NdtpaAttrs::UcastProbes(val) = attr? {
1304                return Ok(val);
1305            }
1306        }
1307        Err(ErrorContext::new_missing(
1308            "NdtpaAttrs",
1309            "UcastProbes",
1310            self.orig_loc,
1311            self.buf.as_ptr() as usize,
1312        ))
1313    }
1314    pub fn get_mcast_probes(&self) -> Result<u32, ErrorContext> {
1315        let mut iter = self.clone();
1316        iter.pos = 0;
1317        for attr in iter {
1318            if let NdtpaAttrs::McastProbes(val) = attr? {
1319                return Ok(val);
1320            }
1321        }
1322        Err(ErrorContext::new_missing(
1323            "NdtpaAttrs",
1324            "McastProbes",
1325            self.orig_loc,
1326            self.buf.as_ptr() as usize,
1327        ))
1328    }
1329    pub fn get_anycast_delay(&self) -> Result<u64, ErrorContext> {
1330        let mut iter = self.clone();
1331        iter.pos = 0;
1332        for attr in iter {
1333            if let NdtpaAttrs::AnycastDelay(val) = attr? {
1334                return Ok(val);
1335            }
1336        }
1337        Err(ErrorContext::new_missing(
1338            "NdtpaAttrs",
1339            "AnycastDelay",
1340            self.orig_loc,
1341            self.buf.as_ptr() as usize,
1342        ))
1343    }
1344    pub fn get_proxy_delay(&self) -> Result<u64, ErrorContext> {
1345        let mut iter = self.clone();
1346        iter.pos = 0;
1347        for attr in iter {
1348            if let NdtpaAttrs::ProxyDelay(val) = attr? {
1349                return Ok(val);
1350            }
1351        }
1352        Err(ErrorContext::new_missing(
1353            "NdtpaAttrs",
1354            "ProxyDelay",
1355            self.orig_loc,
1356            self.buf.as_ptr() as usize,
1357        ))
1358    }
1359    pub fn get_proxy_qlen(&self) -> Result<u32, ErrorContext> {
1360        let mut iter = self.clone();
1361        iter.pos = 0;
1362        for attr in iter {
1363            if let NdtpaAttrs::ProxyQlen(val) = attr? {
1364                return Ok(val);
1365            }
1366        }
1367        Err(ErrorContext::new_missing(
1368            "NdtpaAttrs",
1369            "ProxyQlen",
1370            self.orig_loc,
1371            self.buf.as_ptr() as usize,
1372        ))
1373    }
1374    pub fn get_locktime(&self) -> Result<u64, ErrorContext> {
1375        let mut iter = self.clone();
1376        iter.pos = 0;
1377        for attr in iter {
1378            if let NdtpaAttrs::Locktime(val) = attr? {
1379                return Ok(val);
1380            }
1381        }
1382        Err(ErrorContext::new_missing(
1383            "NdtpaAttrs",
1384            "Locktime",
1385            self.orig_loc,
1386            self.buf.as_ptr() as usize,
1387        ))
1388    }
1389    pub fn get_queue_lenbytes(&self) -> Result<u32, ErrorContext> {
1390        let mut iter = self.clone();
1391        iter.pos = 0;
1392        for attr in iter {
1393            if let NdtpaAttrs::QueueLenbytes(val) = attr? {
1394                return Ok(val);
1395            }
1396        }
1397        Err(ErrorContext::new_missing(
1398            "NdtpaAttrs",
1399            "QueueLenbytes",
1400            self.orig_loc,
1401            self.buf.as_ptr() as usize,
1402        ))
1403    }
1404    pub fn get_mcast_reprobes(&self) -> Result<u32, ErrorContext> {
1405        let mut iter = self.clone();
1406        iter.pos = 0;
1407        for attr in iter {
1408            if let NdtpaAttrs::McastReprobes(val) = attr? {
1409                return Ok(val);
1410            }
1411        }
1412        Err(ErrorContext::new_missing(
1413            "NdtpaAttrs",
1414            "McastReprobes",
1415            self.orig_loc,
1416            self.buf.as_ptr() as usize,
1417        ))
1418    }
1419    pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
1420        let mut iter = self.clone();
1421        iter.pos = 0;
1422        for attr in iter {
1423            if let NdtpaAttrs::Pad(val) = attr? {
1424                return Ok(val);
1425            }
1426        }
1427        Err(ErrorContext::new_missing(
1428            "NdtpaAttrs",
1429            "Pad",
1430            self.orig_loc,
1431            self.buf.as_ptr() as usize,
1432        ))
1433    }
1434    pub fn get_interval_probe_time_ms(&self) -> Result<u64, ErrorContext> {
1435        let mut iter = self.clone();
1436        iter.pos = 0;
1437        for attr in iter {
1438            if let NdtpaAttrs::IntervalProbeTimeMs(val) = attr? {
1439                return Ok(val);
1440            }
1441        }
1442        Err(ErrorContext::new_missing(
1443            "NdtpaAttrs",
1444            "IntervalProbeTimeMs",
1445            self.orig_loc,
1446            self.buf.as_ptr() as usize,
1447        ))
1448    }
1449}
1450impl NdtpaAttrs<'_> {
1451    pub fn new<'a>(buf: &'a [u8]) -> IterableNdtpaAttrs<'a> {
1452        IterableNdtpaAttrs::with_loc(buf, buf.as_ptr() as usize)
1453    }
1454    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1455        let res = match r#type {
1456            1u16 => "Ifindex",
1457            2u16 => "Refcnt",
1458            3u16 => "ReachableTime",
1459            4u16 => "BaseReachableTime",
1460            5u16 => "RetransTime",
1461            6u16 => "GcStaletime",
1462            7u16 => "DelayProbeTime",
1463            8u16 => "QueueLen",
1464            9u16 => "AppProbes",
1465            10u16 => "UcastProbes",
1466            11u16 => "McastProbes",
1467            12u16 => "AnycastDelay",
1468            13u16 => "ProxyDelay",
1469            14u16 => "ProxyQlen",
1470            15u16 => "Locktime",
1471            16u16 => "QueueLenbytes",
1472            17u16 => "McastReprobes",
1473            18u16 => "Pad",
1474            19u16 => "IntervalProbeTimeMs",
1475            _ => return None,
1476        };
1477        Some(res)
1478    }
1479}
1480#[derive(Clone, Copy, Default)]
1481pub struct IterableNdtpaAttrs<'a> {
1482    buf: &'a [u8],
1483    pos: usize,
1484    orig_loc: usize,
1485}
1486impl<'a> IterableNdtpaAttrs<'a> {
1487    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1488        Self {
1489            buf,
1490            pos: 0,
1491            orig_loc,
1492        }
1493    }
1494    pub fn get_buf(&self) -> &'a [u8] {
1495        self.buf
1496    }
1497}
1498impl<'a> Iterator for IterableNdtpaAttrs<'a> {
1499    type Item = Result<NdtpaAttrs<'a>, ErrorContext>;
1500    fn next(&mut self) -> Option<Self::Item> {
1501        let pos = self.pos;
1502        let mut r#type;
1503        loop {
1504            r#type = None;
1505            if self.buf.len() == self.pos {
1506                return None;
1507            }
1508            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1509                break;
1510            };
1511            r#type = Some(header.r#type);
1512            let res = match header.r#type {
1513                1u16 => NdtpaAttrs::Ifindex({
1514                    let res = parse_u32(next);
1515                    let Some(val) = res else { break };
1516                    val
1517                }),
1518                2u16 => NdtpaAttrs::Refcnt({
1519                    let res = parse_u32(next);
1520                    let Some(val) = res else { break };
1521                    val
1522                }),
1523                3u16 => NdtpaAttrs::ReachableTime({
1524                    let res = parse_u64(next);
1525                    let Some(val) = res else { break };
1526                    val
1527                }),
1528                4u16 => NdtpaAttrs::BaseReachableTime({
1529                    let res = parse_u64(next);
1530                    let Some(val) = res else { break };
1531                    val
1532                }),
1533                5u16 => NdtpaAttrs::RetransTime({
1534                    let res = parse_u64(next);
1535                    let Some(val) = res else { break };
1536                    val
1537                }),
1538                6u16 => NdtpaAttrs::GcStaletime({
1539                    let res = parse_u64(next);
1540                    let Some(val) = res else { break };
1541                    val
1542                }),
1543                7u16 => NdtpaAttrs::DelayProbeTime({
1544                    let res = parse_u64(next);
1545                    let Some(val) = res else { break };
1546                    val
1547                }),
1548                8u16 => NdtpaAttrs::QueueLen({
1549                    let res = parse_u32(next);
1550                    let Some(val) = res else { break };
1551                    val
1552                }),
1553                9u16 => NdtpaAttrs::AppProbes({
1554                    let res = parse_u32(next);
1555                    let Some(val) = res else { break };
1556                    val
1557                }),
1558                10u16 => NdtpaAttrs::UcastProbes({
1559                    let res = parse_u32(next);
1560                    let Some(val) = res else { break };
1561                    val
1562                }),
1563                11u16 => NdtpaAttrs::McastProbes({
1564                    let res = parse_u32(next);
1565                    let Some(val) = res else { break };
1566                    val
1567                }),
1568                12u16 => NdtpaAttrs::AnycastDelay({
1569                    let res = parse_u64(next);
1570                    let Some(val) = res else { break };
1571                    val
1572                }),
1573                13u16 => NdtpaAttrs::ProxyDelay({
1574                    let res = parse_u64(next);
1575                    let Some(val) = res else { break };
1576                    val
1577                }),
1578                14u16 => NdtpaAttrs::ProxyQlen({
1579                    let res = parse_u32(next);
1580                    let Some(val) = res else { break };
1581                    val
1582                }),
1583                15u16 => NdtpaAttrs::Locktime({
1584                    let res = parse_u64(next);
1585                    let Some(val) = res else { break };
1586                    val
1587                }),
1588                16u16 => NdtpaAttrs::QueueLenbytes({
1589                    let res = parse_u32(next);
1590                    let Some(val) = res else { break };
1591                    val
1592                }),
1593                17u16 => NdtpaAttrs::McastReprobes({
1594                    let res = parse_u32(next);
1595                    let Some(val) = res else { break };
1596                    val
1597                }),
1598                18u16 => NdtpaAttrs::Pad({
1599                    let res = Some(next);
1600                    let Some(val) = res else { break };
1601                    val
1602                }),
1603                19u16 => NdtpaAttrs::IntervalProbeTimeMs({
1604                    let res = parse_u64(next);
1605                    let Some(val) = res else { break };
1606                    val
1607                }),
1608                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1609                n => continue,
1610            };
1611            return Some(Ok(res));
1612        }
1613        Some(Err(ErrorContext::new(
1614            "NdtpaAttrs",
1615            r#type.and_then(|t| NdtpaAttrs::attr_from_type(t)),
1616            self.orig_loc,
1617            self.buf.as_ptr().wrapping_add(pos) as usize,
1618        )))
1619    }
1620}
1621impl<'a> std::fmt::Debug for IterableNdtpaAttrs<'_> {
1622    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1623        let mut fmt = f.debug_struct("NdtpaAttrs");
1624        for attr in self.clone() {
1625            let attr = match attr {
1626                Ok(a) => a,
1627                Err(err) => {
1628                    fmt.finish()?;
1629                    f.write_str("Err(")?;
1630                    err.fmt(f)?;
1631                    return f.write_str(")");
1632                }
1633            };
1634            match attr {
1635                NdtpaAttrs::Ifindex(val) => fmt.field("Ifindex", &val),
1636                NdtpaAttrs::Refcnt(val) => fmt.field("Refcnt", &val),
1637                NdtpaAttrs::ReachableTime(val) => fmt.field("ReachableTime", &val),
1638                NdtpaAttrs::BaseReachableTime(val) => fmt.field("BaseReachableTime", &val),
1639                NdtpaAttrs::RetransTime(val) => fmt.field("RetransTime", &val),
1640                NdtpaAttrs::GcStaletime(val) => fmt.field("GcStaletime", &val),
1641                NdtpaAttrs::DelayProbeTime(val) => fmt.field("DelayProbeTime", &val),
1642                NdtpaAttrs::QueueLen(val) => fmt.field("QueueLen", &val),
1643                NdtpaAttrs::AppProbes(val) => fmt.field("AppProbes", &val),
1644                NdtpaAttrs::UcastProbes(val) => fmt.field("UcastProbes", &val),
1645                NdtpaAttrs::McastProbes(val) => fmt.field("McastProbes", &val),
1646                NdtpaAttrs::AnycastDelay(val) => fmt.field("AnycastDelay", &val),
1647                NdtpaAttrs::ProxyDelay(val) => fmt.field("ProxyDelay", &val),
1648                NdtpaAttrs::ProxyQlen(val) => fmt.field("ProxyQlen", &val),
1649                NdtpaAttrs::Locktime(val) => fmt.field("Locktime", &val),
1650                NdtpaAttrs::QueueLenbytes(val) => fmt.field("QueueLenbytes", &val),
1651                NdtpaAttrs::McastReprobes(val) => fmt.field("McastReprobes", &val),
1652                NdtpaAttrs::Pad(val) => fmt.field("Pad", &val),
1653                NdtpaAttrs::IntervalProbeTimeMs(val) => fmt.field("IntervalProbeTimeMs", &val),
1654            };
1655        }
1656        fmt.finish()
1657    }
1658}
1659impl IterableNdtpaAttrs<'_> {
1660    pub fn lookup_attr(
1661        &self,
1662        offset: usize,
1663        missing_type: Option<u16>,
1664    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1665        let mut stack = Vec::new();
1666        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1667        if cur == offset {
1668            stack.push(("NdtpaAttrs", offset));
1669            return (
1670                stack,
1671                missing_type.and_then(|t| NdtpaAttrs::attr_from_type(t)),
1672            );
1673        }
1674        if cur > offset || cur + self.buf.len() < offset {
1675            return (stack, None);
1676        }
1677        let mut attrs = self.clone();
1678        let mut last_off = cur + attrs.pos;
1679        while let Some(attr) = attrs.next() {
1680            let Ok(attr) = attr else { break };
1681            match attr {
1682                NdtpaAttrs::Ifindex(val) => {
1683                    if last_off == offset {
1684                        stack.push(("Ifindex", last_off));
1685                        break;
1686                    }
1687                }
1688                NdtpaAttrs::Refcnt(val) => {
1689                    if last_off == offset {
1690                        stack.push(("Refcnt", last_off));
1691                        break;
1692                    }
1693                }
1694                NdtpaAttrs::ReachableTime(val) => {
1695                    if last_off == offset {
1696                        stack.push(("ReachableTime", last_off));
1697                        break;
1698                    }
1699                }
1700                NdtpaAttrs::BaseReachableTime(val) => {
1701                    if last_off == offset {
1702                        stack.push(("BaseReachableTime", last_off));
1703                        break;
1704                    }
1705                }
1706                NdtpaAttrs::RetransTime(val) => {
1707                    if last_off == offset {
1708                        stack.push(("RetransTime", last_off));
1709                        break;
1710                    }
1711                }
1712                NdtpaAttrs::GcStaletime(val) => {
1713                    if last_off == offset {
1714                        stack.push(("GcStaletime", last_off));
1715                        break;
1716                    }
1717                }
1718                NdtpaAttrs::DelayProbeTime(val) => {
1719                    if last_off == offset {
1720                        stack.push(("DelayProbeTime", last_off));
1721                        break;
1722                    }
1723                }
1724                NdtpaAttrs::QueueLen(val) => {
1725                    if last_off == offset {
1726                        stack.push(("QueueLen", last_off));
1727                        break;
1728                    }
1729                }
1730                NdtpaAttrs::AppProbes(val) => {
1731                    if last_off == offset {
1732                        stack.push(("AppProbes", last_off));
1733                        break;
1734                    }
1735                }
1736                NdtpaAttrs::UcastProbes(val) => {
1737                    if last_off == offset {
1738                        stack.push(("UcastProbes", last_off));
1739                        break;
1740                    }
1741                }
1742                NdtpaAttrs::McastProbes(val) => {
1743                    if last_off == offset {
1744                        stack.push(("McastProbes", last_off));
1745                        break;
1746                    }
1747                }
1748                NdtpaAttrs::AnycastDelay(val) => {
1749                    if last_off == offset {
1750                        stack.push(("AnycastDelay", last_off));
1751                        break;
1752                    }
1753                }
1754                NdtpaAttrs::ProxyDelay(val) => {
1755                    if last_off == offset {
1756                        stack.push(("ProxyDelay", last_off));
1757                        break;
1758                    }
1759                }
1760                NdtpaAttrs::ProxyQlen(val) => {
1761                    if last_off == offset {
1762                        stack.push(("ProxyQlen", last_off));
1763                        break;
1764                    }
1765                }
1766                NdtpaAttrs::Locktime(val) => {
1767                    if last_off == offset {
1768                        stack.push(("Locktime", last_off));
1769                        break;
1770                    }
1771                }
1772                NdtpaAttrs::QueueLenbytes(val) => {
1773                    if last_off == offset {
1774                        stack.push(("QueueLenbytes", last_off));
1775                        break;
1776                    }
1777                }
1778                NdtpaAttrs::McastReprobes(val) => {
1779                    if last_off == offset {
1780                        stack.push(("McastReprobes", last_off));
1781                        break;
1782                    }
1783                }
1784                NdtpaAttrs::Pad(val) => {
1785                    if last_off == offset {
1786                        stack.push(("Pad", last_off));
1787                        break;
1788                    }
1789                }
1790                NdtpaAttrs::IntervalProbeTimeMs(val) => {
1791                    if last_off == offset {
1792                        stack.push(("IntervalProbeTimeMs", last_off));
1793                        break;
1794                    }
1795                }
1796                _ => {}
1797            };
1798            last_off = cur + attrs.pos;
1799        }
1800        if !stack.is_empty() {
1801            stack.push(("NdtpaAttrs", cur));
1802        }
1803        (stack, None)
1804    }
1805}
1806pub struct PushNeighbourAttrs<Prev: Rec> {
1807    pub(crate) prev: Option<Prev>,
1808    pub(crate) header_offset: Option<usize>,
1809}
1810impl<Prev: Rec> Rec for PushNeighbourAttrs<Prev> {
1811    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1812        self.prev.as_mut().unwrap().as_rec_mut()
1813    }
1814    fn as_rec(&self) -> &Vec<u8> {
1815        self.prev.as_ref().unwrap().as_rec()
1816    }
1817}
1818impl<Prev: Rec> PushNeighbourAttrs<Prev> {
1819    pub fn new(prev: Prev) -> Self {
1820        Self {
1821            prev: Some(prev),
1822            header_offset: None,
1823        }
1824    }
1825    pub fn end_nested(mut self) -> Prev {
1826        let mut prev = self.prev.take().unwrap();
1827        if let Some(header_offset) = &self.header_offset {
1828            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1829        }
1830        prev
1831    }
1832    pub fn push_unspec(mut self, value: &[u8]) -> Self {
1833        push_header(self.as_rec_mut(), 0u16, value.len() as u16);
1834        self.as_rec_mut().extend(value);
1835        self
1836    }
1837    pub fn push_dst(mut self, value: &[u8]) -> Self {
1838        push_header(self.as_rec_mut(), 1u16, value.len() as u16);
1839        self.as_rec_mut().extend(value);
1840        self
1841    }
1842    pub fn push_lladdr(mut self, value: &[u8]) -> Self {
1843        push_header(self.as_rec_mut(), 2u16, value.len() as u16);
1844        self.as_rec_mut().extend(value);
1845        self
1846    }
1847    pub fn push_cacheinfo(mut self, value: PushNdaCacheinfo) -> Self {
1848        push_header(self.as_rec_mut(), 3u16, value.as_slice().len() as u16);
1849        self.as_rec_mut().extend(value.as_slice());
1850        self
1851    }
1852    pub fn push_probes(mut self, value: u32) -> Self {
1853        push_header(self.as_rec_mut(), 4u16, 4 as u16);
1854        self.as_rec_mut().extend(value.to_ne_bytes());
1855        self
1856    }
1857    pub fn push_vlan(mut self, value: u16) -> Self {
1858        push_header(self.as_rec_mut(), 5u16, 2 as u16);
1859        self.as_rec_mut().extend(value.to_ne_bytes());
1860        self
1861    }
1862    pub fn push_port(mut self, value: u16) -> Self {
1863        push_header(self.as_rec_mut(), 6u16, 2 as u16);
1864        self.as_rec_mut().extend(value.to_ne_bytes());
1865        self
1866    }
1867    pub fn push_vni(mut self, value: u32) -> Self {
1868        push_header(self.as_rec_mut(), 7u16, 4 as u16);
1869        self.as_rec_mut().extend(value.to_ne_bytes());
1870        self
1871    }
1872    pub fn push_ifindex(mut self, value: u32) -> Self {
1873        push_header(self.as_rec_mut(), 8u16, 4 as u16);
1874        self.as_rec_mut().extend(value.to_ne_bytes());
1875        self
1876    }
1877    pub fn push_master(mut self, value: u32) -> Self {
1878        push_header(self.as_rec_mut(), 9u16, 4 as u16);
1879        self.as_rec_mut().extend(value.to_ne_bytes());
1880        self
1881    }
1882    pub fn push_link_netnsid(mut self, value: i32) -> Self {
1883        push_header(self.as_rec_mut(), 10u16, 4 as u16);
1884        self.as_rec_mut().extend(value.to_ne_bytes());
1885        self
1886    }
1887    pub fn push_src_vni(mut self, value: u32) -> Self {
1888        push_header(self.as_rec_mut(), 11u16, 4 as u16);
1889        self.as_rec_mut().extend(value.to_ne_bytes());
1890        self
1891    }
1892    pub fn push_protocol(mut self, value: u8) -> Self {
1893        push_header(self.as_rec_mut(), 12u16, 1 as u16);
1894        self.as_rec_mut().extend(value.to_ne_bytes());
1895        self
1896    }
1897    pub fn push_nh_id(mut self, value: u32) -> Self {
1898        push_header(self.as_rec_mut(), 13u16, 4 as u16);
1899        self.as_rec_mut().extend(value.to_ne_bytes());
1900        self
1901    }
1902    pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
1903        push_header(self.as_rec_mut(), 14u16, value.len() as u16);
1904        self.as_rec_mut().extend(value);
1905        self
1906    }
1907    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
1908    pub fn push_flags_ext(mut self, value: u32) -> Self {
1909        push_header(self.as_rec_mut(), 15u16, 4 as u16);
1910        self.as_rec_mut().extend(value.to_ne_bytes());
1911        self
1912    }
1913    pub fn push_ndm_state_mask(mut self, value: u16) -> Self {
1914        push_header(self.as_rec_mut(), 16u16, 2 as u16);
1915        self.as_rec_mut().extend(value.to_ne_bytes());
1916        self
1917    }
1918    pub fn push_ndm_flags_mask(mut self, value: u8) -> Self {
1919        push_header(self.as_rec_mut(), 17u16, 1 as u16);
1920        self.as_rec_mut().extend(value.to_ne_bytes());
1921        self
1922    }
1923}
1924impl<Prev: Rec> Drop for PushNeighbourAttrs<Prev> {
1925    fn drop(&mut self) {
1926        if let Some(prev) = &mut self.prev {
1927            if let Some(header_offset) = &self.header_offset {
1928                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1929            }
1930        }
1931    }
1932}
1933pub struct PushNdtAttrs<Prev: Rec> {
1934    pub(crate) prev: Option<Prev>,
1935    pub(crate) header_offset: Option<usize>,
1936}
1937impl<Prev: Rec> Rec for PushNdtAttrs<Prev> {
1938    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1939        self.prev.as_mut().unwrap().as_rec_mut()
1940    }
1941    fn as_rec(&self) -> &Vec<u8> {
1942        self.prev.as_ref().unwrap().as_rec()
1943    }
1944}
1945impl<Prev: Rec> PushNdtAttrs<Prev> {
1946    pub fn new(prev: Prev) -> Self {
1947        Self {
1948            prev: Some(prev),
1949            header_offset: None,
1950        }
1951    }
1952    pub fn end_nested(mut self) -> Prev {
1953        let mut prev = self.prev.take().unwrap();
1954        if let Some(header_offset) = &self.header_offset {
1955            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1956        }
1957        prev
1958    }
1959    pub fn push_name(mut self, value: &CStr) -> Self {
1960        push_header(
1961            self.as_rec_mut(),
1962            1u16,
1963            value.to_bytes_with_nul().len() as u16,
1964        );
1965        self.as_rec_mut().extend(value.to_bytes_with_nul());
1966        self
1967    }
1968    pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
1969        push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
1970        self.as_rec_mut().extend(value);
1971        self.as_rec_mut().push(0);
1972        self
1973    }
1974    pub fn push_thresh1(mut self, value: u32) -> Self {
1975        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1976        self.as_rec_mut().extend(value.to_ne_bytes());
1977        self
1978    }
1979    pub fn push_thresh2(mut self, value: u32) -> Self {
1980        push_header(self.as_rec_mut(), 3u16, 4 as u16);
1981        self.as_rec_mut().extend(value.to_ne_bytes());
1982        self
1983    }
1984    pub fn push_thresh3(mut self, value: u32) -> Self {
1985        push_header(self.as_rec_mut(), 4u16, 4 as u16);
1986        self.as_rec_mut().extend(value.to_ne_bytes());
1987        self
1988    }
1989    pub fn push_config(mut self, value: PushNdtConfig) -> Self {
1990        push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
1991        self.as_rec_mut().extend(value.as_slice());
1992        self
1993    }
1994    pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
1995        let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
1996        PushNdtpaAttrs {
1997            prev: Some(self),
1998            header_offset: Some(header_offset),
1999        }
2000    }
2001    pub fn push_stats(mut self, value: PushNdtStats) -> Self {
2002        push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
2003        self.as_rec_mut().extend(value.as_slice());
2004        self
2005    }
2006    pub fn push_gc_interval(mut self, value: u64) -> Self {
2007        push_header(self.as_rec_mut(), 8u16, 8 as u16);
2008        self.as_rec_mut().extend(value.to_ne_bytes());
2009        self
2010    }
2011    pub fn push_pad(mut self, value: &[u8]) -> Self {
2012        push_header(self.as_rec_mut(), 9u16, value.len() as u16);
2013        self.as_rec_mut().extend(value);
2014        self
2015    }
2016}
2017impl<Prev: Rec> Drop for PushNdtAttrs<Prev> {
2018    fn drop(&mut self) {
2019        if let Some(prev) = &mut self.prev {
2020            if let Some(header_offset) = &self.header_offset {
2021                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2022            }
2023        }
2024    }
2025}
2026pub struct PushNdtpaAttrs<Prev: Rec> {
2027    pub(crate) prev: Option<Prev>,
2028    pub(crate) header_offset: Option<usize>,
2029}
2030impl<Prev: Rec> Rec for PushNdtpaAttrs<Prev> {
2031    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2032        self.prev.as_mut().unwrap().as_rec_mut()
2033    }
2034    fn as_rec(&self) -> &Vec<u8> {
2035        self.prev.as_ref().unwrap().as_rec()
2036    }
2037}
2038impl<Prev: Rec> PushNdtpaAttrs<Prev> {
2039    pub fn new(prev: Prev) -> Self {
2040        Self {
2041            prev: Some(prev),
2042            header_offset: None,
2043        }
2044    }
2045    pub fn end_nested(mut self) -> Prev {
2046        let mut prev = self.prev.take().unwrap();
2047        if let Some(header_offset) = &self.header_offset {
2048            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2049        }
2050        prev
2051    }
2052    pub fn push_ifindex(mut self, value: u32) -> Self {
2053        push_header(self.as_rec_mut(), 1u16, 4 as u16);
2054        self.as_rec_mut().extend(value.to_ne_bytes());
2055        self
2056    }
2057    pub fn push_refcnt(mut self, value: u32) -> Self {
2058        push_header(self.as_rec_mut(), 2u16, 4 as u16);
2059        self.as_rec_mut().extend(value.to_ne_bytes());
2060        self
2061    }
2062    pub fn push_reachable_time(mut self, value: u64) -> Self {
2063        push_header(self.as_rec_mut(), 3u16, 8 as u16);
2064        self.as_rec_mut().extend(value.to_ne_bytes());
2065        self
2066    }
2067    pub fn push_base_reachable_time(mut self, value: u64) -> Self {
2068        push_header(self.as_rec_mut(), 4u16, 8 as u16);
2069        self.as_rec_mut().extend(value.to_ne_bytes());
2070        self
2071    }
2072    pub fn push_retrans_time(mut self, value: u64) -> Self {
2073        push_header(self.as_rec_mut(), 5u16, 8 as u16);
2074        self.as_rec_mut().extend(value.to_ne_bytes());
2075        self
2076    }
2077    pub fn push_gc_staletime(mut self, value: u64) -> Self {
2078        push_header(self.as_rec_mut(), 6u16, 8 as u16);
2079        self.as_rec_mut().extend(value.to_ne_bytes());
2080        self
2081    }
2082    pub fn push_delay_probe_time(mut self, value: u64) -> Self {
2083        push_header(self.as_rec_mut(), 7u16, 8 as u16);
2084        self.as_rec_mut().extend(value.to_ne_bytes());
2085        self
2086    }
2087    pub fn push_queue_len(mut self, value: u32) -> Self {
2088        push_header(self.as_rec_mut(), 8u16, 4 as u16);
2089        self.as_rec_mut().extend(value.to_ne_bytes());
2090        self
2091    }
2092    pub fn push_app_probes(mut self, value: u32) -> Self {
2093        push_header(self.as_rec_mut(), 9u16, 4 as u16);
2094        self.as_rec_mut().extend(value.to_ne_bytes());
2095        self
2096    }
2097    pub fn push_ucast_probes(mut self, value: u32) -> Self {
2098        push_header(self.as_rec_mut(), 10u16, 4 as u16);
2099        self.as_rec_mut().extend(value.to_ne_bytes());
2100        self
2101    }
2102    pub fn push_mcast_probes(mut self, value: u32) -> Self {
2103        push_header(self.as_rec_mut(), 11u16, 4 as u16);
2104        self.as_rec_mut().extend(value.to_ne_bytes());
2105        self
2106    }
2107    pub fn push_anycast_delay(mut self, value: u64) -> Self {
2108        push_header(self.as_rec_mut(), 12u16, 8 as u16);
2109        self.as_rec_mut().extend(value.to_ne_bytes());
2110        self
2111    }
2112    pub fn push_proxy_delay(mut self, value: u64) -> Self {
2113        push_header(self.as_rec_mut(), 13u16, 8 as u16);
2114        self.as_rec_mut().extend(value.to_ne_bytes());
2115        self
2116    }
2117    pub fn push_proxy_qlen(mut self, value: u32) -> Self {
2118        push_header(self.as_rec_mut(), 14u16, 4 as u16);
2119        self.as_rec_mut().extend(value.to_ne_bytes());
2120        self
2121    }
2122    pub fn push_locktime(mut self, value: u64) -> Self {
2123        push_header(self.as_rec_mut(), 15u16, 8 as u16);
2124        self.as_rec_mut().extend(value.to_ne_bytes());
2125        self
2126    }
2127    pub fn push_queue_lenbytes(mut self, value: u32) -> Self {
2128        push_header(self.as_rec_mut(), 16u16, 4 as u16);
2129        self.as_rec_mut().extend(value.to_ne_bytes());
2130        self
2131    }
2132    pub fn push_mcast_reprobes(mut self, value: u32) -> Self {
2133        push_header(self.as_rec_mut(), 17u16, 4 as u16);
2134        self.as_rec_mut().extend(value.to_ne_bytes());
2135        self
2136    }
2137    pub fn push_pad(mut self, value: &[u8]) -> Self {
2138        push_header(self.as_rec_mut(), 18u16, value.len() as u16);
2139        self.as_rec_mut().extend(value);
2140        self
2141    }
2142    pub fn push_interval_probe_time_ms(mut self, value: u64) -> Self {
2143        push_header(self.as_rec_mut(), 19u16, 8 as u16);
2144        self.as_rec_mut().extend(value.to_ne_bytes());
2145        self
2146    }
2147}
2148impl<Prev: Rec> Drop for PushNdtpaAttrs<Prev> {
2149    fn drop(&mut self) {
2150        if let Some(prev) = &mut self.prev {
2151            if let Some(header_offset) = &self.header_offset {
2152                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2153            }
2154        }
2155    }
2156}
2157#[derive(Clone)]
2158pub struct PushNdmsg {
2159    pub(crate) buf: [u8; 12usize],
2160}
2161#[doc = "Create zero-initialized struct"]
2162impl Default for PushNdmsg {
2163    fn default() -> Self {
2164        Self {
2165            buf: [0u8; 12usize],
2166        }
2167    }
2168}
2169impl PushNdmsg {
2170    #[doc = "Create zero-initialized struct"]
2171    pub fn new() -> Self {
2172        Default::default()
2173    }
2174    #[doc = "Copy from contents from other slice"]
2175    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2176        if other.len() != Self::len() {
2177            return None;
2178        }
2179        let mut buf = [0u8; Self::len()];
2180        buf.clone_from_slice(other);
2181        Some(Self { buf })
2182    }
2183    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2184    pub fn new_from_zeroed(other: &[u8]) -> Self {
2185        let mut buf = [0u8; Self::len()];
2186        let len = buf.len().min(other.len());
2187        buf[..len].clone_from_slice(&other[..len]);
2188        Self { buf }
2189    }
2190    pub fn as_slice(&self) -> &[u8] {
2191        &self.buf
2192    }
2193    pub fn as_mut_slice(&mut self) -> &mut [u8] {
2194        &mut self.buf
2195    }
2196    pub const fn len() -> usize {
2197        12usize
2198    }
2199    pub fn ndm_family(&self) -> u8 {
2200        parse_u8(&self.buf[0usize..1usize]).unwrap()
2201    }
2202    pub fn set_ndm_family(&mut self, value: u8) {
2203        self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
2204    }
2205    pub fn ndm_ifindex(&self) -> i32 {
2206        parse_i32(&self.buf[4usize..8usize]).unwrap()
2207    }
2208    pub fn set_ndm_ifindex(&mut self, value: i32) {
2209        self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2210    }
2211    #[doc = "Associated type: \"NudState\" (enum)"]
2212    pub fn ndm_state(&self) -> u16 {
2213        parse_u16(&self.buf[8usize..10usize]).unwrap()
2214    }
2215    #[doc = "Associated type: \"NudState\" (enum)"]
2216    pub fn set_ndm_state(&mut self, value: u16) {
2217        self.buf[8usize..10usize].copy_from_slice(&value.to_ne_bytes())
2218    }
2219    #[doc = "Associated type: \"NtfFlags\" (enum)"]
2220    pub fn ndm_flags(&self) -> u8 {
2221        parse_u8(&self.buf[10usize..11usize]).unwrap()
2222    }
2223    #[doc = "Associated type: \"NtfFlags\" (enum)"]
2224    pub fn set_ndm_flags(&mut self, value: u8) {
2225        self.buf[10usize..11usize].copy_from_slice(&value.to_ne_bytes())
2226    }
2227    #[doc = "Associated type: \"RtmType\" (enum)"]
2228    pub fn ndm_type(&self) -> u8 {
2229        parse_u8(&self.buf[11usize..12usize]).unwrap()
2230    }
2231    #[doc = "Associated type: \"RtmType\" (enum)"]
2232    pub fn set_ndm_type(&mut self, value: u8) {
2233        self.buf[11usize..12usize].copy_from_slice(&value.to_ne_bytes())
2234    }
2235}
2236impl std::fmt::Debug for PushNdmsg {
2237    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2238        fmt.debug_struct("Ndmsg")
2239            .field("ndm_family", &self.ndm_family())
2240            .field("ndm_ifindex", &self.ndm_ifindex())
2241            .field(
2242                "ndm_state",
2243                &FormatFlags(self.ndm_state().into(), NudState::from_value),
2244            )
2245            .field(
2246                "ndm_flags",
2247                &FormatFlags(self.ndm_flags().into(), NtfFlags::from_value),
2248            )
2249            .field(
2250                "ndm_type",
2251                &FormatEnum(self.ndm_type().into(), RtmType::from_value),
2252            )
2253            .finish()
2254    }
2255}
2256#[derive(Clone)]
2257pub struct PushNdtmsg {
2258    pub(crate) buf: [u8; 4usize],
2259}
2260#[doc = "Create zero-initialized struct"]
2261impl Default for PushNdtmsg {
2262    fn default() -> Self {
2263        Self { buf: [0u8; 4usize] }
2264    }
2265}
2266impl PushNdtmsg {
2267    #[doc = "Create zero-initialized struct"]
2268    pub fn new() -> Self {
2269        Default::default()
2270    }
2271    #[doc = "Copy from contents from other slice"]
2272    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2273        if other.len() != Self::len() {
2274            return None;
2275        }
2276        let mut buf = [0u8; Self::len()];
2277        buf.clone_from_slice(other);
2278        Some(Self { buf })
2279    }
2280    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2281    pub fn new_from_zeroed(other: &[u8]) -> Self {
2282        let mut buf = [0u8; Self::len()];
2283        let len = buf.len().min(other.len());
2284        buf[..len].clone_from_slice(&other[..len]);
2285        Self { buf }
2286    }
2287    pub fn as_slice(&self) -> &[u8] {
2288        &self.buf
2289    }
2290    pub fn as_mut_slice(&mut self) -> &mut [u8] {
2291        &mut self.buf
2292    }
2293    pub const fn len() -> usize {
2294        4usize
2295    }
2296    pub fn family(&self) -> u8 {
2297        parse_u8(&self.buf[0usize..1usize]).unwrap()
2298    }
2299    pub fn set_family(&mut self, value: u8) {
2300        self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
2301    }
2302}
2303impl std::fmt::Debug for PushNdtmsg {
2304    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2305        fmt.debug_struct("Ndtmsg")
2306            .field("family", &self.family())
2307            .finish()
2308    }
2309}
2310#[derive(Clone)]
2311pub struct PushNdaCacheinfo {
2312    pub(crate) buf: [u8; 16usize],
2313}
2314#[doc = "Create zero-initialized struct"]
2315impl Default for PushNdaCacheinfo {
2316    fn default() -> Self {
2317        Self {
2318            buf: [0u8; 16usize],
2319        }
2320    }
2321}
2322impl PushNdaCacheinfo {
2323    #[doc = "Create zero-initialized struct"]
2324    pub fn new() -> Self {
2325        Default::default()
2326    }
2327    #[doc = "Copy from contents from other slice"]
2328    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2329        if other.len() != Self::len() {
2330            return None;
2331        }
2332        let mut buf = [0u8; Self::len()];
2333        buf.clone_from_slice(other);
2334        Some(Self { buf })
2335    }
2336    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2337    pub fn new_from_zeroed(other: &[u8]) -> Self {
2338        let mut buf = [0u8; Self::len()];
2339        let len = buf.len().min(other.len());
2340        buf[..len].clone_from_slice(&other[..len]);
2341        Self { buf }
2342    }
2343    pub fn as_slice(&self) -> &[u8] {
2344        &self.buf
2345    }
2346    pub fn as_mut_slice(&mut self) -> &mut [u8] {
2347        &mut self.buf
2348    }
2349    pub const fn len() -> usize {
2350        16usize
2351    }
2352    pub fn confirmed(&self) -> u32 {
2353        parse_u32(&self.buf[0usize..4usize]).unwrap()
2354    }
2355    pub fn set_confirmed(&mut self, value: u32) {
2356        self.buf[0usize..4usize].copy_from_slice(&value.to_ne_bytes())
2357    }
2358    pub fn used(&self) -> u32 {
2359        parse_u32(&self.buf[4usize..8usize]).unwrap()
2360    }
2361    pub fn set_used(&mut self, value: u32) {
2362        self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2363    }
2364    pub fn updated(&self) -> u32 {
2365        parse_u32(&self.buf[8usize..12usize]).unwrap()
2366    }
2367    pub fn set_updated(&mut self, value: u32) {
2368        self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
2369    }
2370    pub fn refcnt(&self) -> u32 {
2371        parse_u32(&self.buf[12usize..16usize]).unwrap()
2372    }
2373    pub fn set_refcnt(&mut self, value: u32) {
2374        self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
2375    }
2376}
2377impl std::fmt::Debug for PushNdaCacheinfo {
2378    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2379        fmt.debug_struct("NdaCacheinfo")
2380            .field("confirmed", &self.confirmed())
2381            .field("used", &self.used())
2382            .field("updated", &self.updated())
2383            .field("refcnt", &self.refcnt())
2384            .finish()
2385    }
2386}
2387#[derive(Clone)]
2388pub struct PushNdtConfig {
2389    pub(crate) buf: [u8; 32usize],
2390}
2391#[doc = "Create zero-initialized struct"]
2392impl Default for PushNdtConfig {
2393    fn default() -> Self {
2394        Self {
2395            buf: [0u8; 32usize],
2396        }
2397    }
2398}
2399impl PushNdtConfig {
2400    #[doc = "Create zero-initialized struct"]
2401    pub fn new() -> Self {
2402        Default::default()
2403    }
2404    #[doc = "Copy from contents from other slice"]
2405    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2406        if other.len() != Self::len() {
2407            return None;
2408        }
2409        let mut buf = [0u8; Self::len()];
2410        buf.clone_from_slice(other);
2411        Some(Self { buf })
2412    }
2413    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2414    pub fn new_from_zeroed(other: &[u8]) -> Self {
2415        let mut buf = [0u8; Self::len()];
2416        let len = buf.len().min(other.len());
2417        buf[..len].clone_from_slice(&other[..len]);
2418        Self { buf }
2419    }
2420    pub fn as_slice(&self) -> &[u8] {
2421        &self.buf
2422    }
2423    pub fn as_mut_slice(&mut self) -> &mut [u8] {
2424        &mut self.buf
2425    }
2426    pub const fn len() -> usize {
2427        32usize
2428    }
2429    pub fn key_len(&self) -> u16 {
2430        parse_u16(&self.buf[0usize..2usize]).unwrap()
2431    }
2432    pub fn set_key_len(&mut self, value: u16) {
2433        self.buf[0usize..2usize].copy_from_slice(&value.to_ne_bytes())
2434    }
2435    pub fn entry_size(&self) -> u16 {
2436        parse_u16(&self.buf[2usize..4usize]).unwrap()
2437    }
2438    pub fn set_entry_size(&mut self, value: u16) {
2439        self.buf[2usize..4usize].copy_from_slice(&value.to_ne_bytes())
2440    }
2441    pub fn entries(&self) -> u32 {
2442        parse_u32(&self.buf[4usize..8usize]).unwrap()
2443    }
2444    pub fn set_entries(&mut self, value: u32) {
2445        self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2446    }
2447    pub fn last_flush(&self) -> u32 {
2448        parse_u32(&self.buf[8usize..12usize]).unwrap()
2449    }
2450    pub fn set_last_flush(&mut self, value: u32) {
2451        self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
2452    }
2453    pub fn last_rand(&self) -> u32 {
2454        parse_u32(&self.buf[12usize..16usize]).unwrap()
2455    }
2456    pub fn set_last_rand(&mut self, value: u32) {
2457        self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
2458    }
2459    pub fn hash_rnd(&self) -> u32 {
2460        parse_u32(&self.buf[16usize..20usize]).unwrap()
2461    }
2462    pub fn set_hash_rnd(&mut self, value: u32) {
2463        self.buf[16usize..20usize].copy_from_slice(&value.to_ne_bytes())
2464    }
2465    pub fn hash_mask(&self) -> u32 {
2466        parse_u32(&self.buf[20usize..24usize]).unwrap()
2467    }
2468    pub fn set_hash_mask(&mut self, value: u32) {
2469        self.buf[20usize..24usize].copy_from_slice(&value.to_ne_bytes())
2470    }
2471    pub fn hash_chain_gc(&self) -> u32 {
2472        parse_u32(&self.buf[24usize..28usize]).unwrap()
2473    }
2474    pub fn set_hash_chain_gc(&mut self, value: u32) {
2475        self.buf[24usize..28usize].copy_from_slice(&value.to_ne_bytes())
2476    }
2477    pub fn proxy_qlen(&self) -> u32 {
2478        parse_u32(&self.buf[28usize..32usize]).unwrap()
2479    }
2480    pub fn set_proxy_qlen(&mut self, value: u32) {
2481        self.buf[28usize..32usize].copy_from_slice(&value.to_ne_bytes())
2482    }
2483}
2484impl std::fmt::Debug for PushNdtConfig {
2485    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2486        fmt.debug_struct("NdtConfig")
2487            .field("key_len", &self.key_len())
2488            .field("entry_size", &self.entry_size())
2489            .field("entries", &self.entries())
2490            .field("last_flush", &self.last_flush())
2491            .field("last_rand", &self.last_rand())
2492            .field("hash_rnd", &self.hash_rnd())
2493            .field("hash_mask", &self.hash_mask())
2494            .field("hash_chain_gc", &self.hash_chain_gc())
2495            .field("proxy_qlen", &self.proxy_qlen())
2496            .finish()
2497    }
2498}
2499#[derive(Clone)]
2500pub struct PushNdtStats {
2501    pub(crate) buf: [u8; 88usize],
2502}
2503#[doc = "Create zero-initialized struct"]
2504impl Default for PushNdtStats {
2505    fn default() -> Self {
2506        Self {
2507            buf: [0u8; 88usize],
2508        }
2509    }
2510}
2511impl PushNdtStats {
2512    #[doc = "Create zero-initialized struct"]
2513    pub fn new() -> Self {
2514        Default::default()
2515    }
2516    #[doc = "Copy from contents from other slice"]
2517    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2518        if other.len() != Self::len() {
2519            return None;
2520        }
2521        let mut buf = [0u8; Self::len()];
2522        buf.clone_from_slice(other);
2523        Some(Self { buf })
2524    }
2525    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
2526    pub fn new_from_zeroed(other: &[u8]) -> Self {
2527        let mut buf = [0u8; Self::len()];
2528        let len = buf.len().min(other.len());
2529        buf[..len].clone_from_slice(&other[..len]);
2530        Self { buf }
2531    }
2532    pub fn as_slice(&self) -> &[u8] {
2533        &self.buf
2534    }
2535    pub fn as_mut_slice(&mut self) -> &mut [u8] {
2536        &mut self.buf
2537    }
2538    pub const fn len() -> usize {
2539        88usize
2540    }
2541    pub fn allocs(&self) -> u64 {
2542        parse_u64(&self.buf[0usize..8usize]).unwrap()
2543    }
2544    pub fn set_allocs(&mut self, value: u64) {
2545        self.buf[0usize..8usize].copy_from_slice(&value.to_ne_bytes())
2546    }
2547    pub fn destroys(&self) -> u64 {
2548        parse_u64(&self.buf[8usize..16usize]).unwrap()
2549    }
2550    pub fn set_destroys(&mut self, value: u64) {
2551        self.buf[8usize..16usize].copy_from_slice(&value.to_ne_bytes())
2552    }
2553    pub fn hash_grows(&self) -> u64 {
2554        parse_u64(&self.buf[16usize..24usize]).unwrap()
2555    }
2556    pub fn set_hash_grows(&mut self, value: u64) {
2557        self.buf[16usize..24usize].copy_from_slice(&value.to_ne_bytes())
2558    }
2559    pub fn res_failed(&self) -> u64 {
2560        parse_u64(&self.buf[24usize..32usize]).unwrap()
2561    }
2562    pub fn set_res_failed(&mut self, value: u64) {
2563        self.buf[24usize..32usize].copy_from_slice(&value.to_ne_bytes())
2564    }
2565    pub fn lookups(&self) -> u64 {
2566        parse_u64(&self.buf[32usize..40usize]).unwrap()
2567    }
2568    pub fn set_lookups(&mut self, value: u64) {
2569        self.buf[32usize..40usize].copy_from_slice(&value.to_ne_bytes())
2570    }
2571    pub fn hits(&self) -> u64 {
2572        parse_u64(&self.buf[40usize..48usize]).unwrap()
2573    }
2574    pub fn set_hits(&mut self, value: u64) {
2575        self.buf[40usize..48usize].copy_from_slice(&value.to_ne_bytes())
2576    }
2577    pub fn rcv_probes_mcast(&self) -> u64 {
2578        parse_u64(&self.buf[48usize..56usize]).unwrap()
2579    }
2580    pub fn set_rcv_probes_mcast(&mut self, value: u64) {
2581        self.buf[48usize..56usize].copy_from_slice(&value.to_ne_bytes())
2582    }
2583    pub fn rcv_probes_ucast(&self) -> u64 {
2584        parse_u64(&self.buf[56usize..64usize]).unwrap()
2585    }
2586    pub fn set_rcv_probes_ucast(&mut self, value: u64) {
2587        self.buf[56usize..64usize].copy_from_slice(&value.to_ne_bytes())
2588    }
2589    pub fn periodic_gc_runs(&self) -> u64 {
2590        parse_u64(&self.buf[64usize..72usize]).unwrap()
2591    }
2592    pub fn set_periodic_gc_runs(&mut self, value: u64) {
2593        self.buf[64usize..72usize].copy_from_slice(&value.to_ne_bytes())
2594    }
2595    pub fn forced_gc_runs(&self) -> u64 {
2596        parse_u64(&self.buf[72usize..80usize]).unwrap()
2597    }
2598    pub fn set_forced_gc_runs(&mut self, value: u64) {
2599        self.buf[72usize..80usize].copy_from_slice(&value.to_ne_bytes())
2600    }
2601    pub fn table_fulls(&self) -> u64 {
2602        parse_u64(&self.buf[80usize..88usize]).unwrap()
2603    }
2604    pub fn set_table_fulls(&mut self, value: u64) {
2605        self.buf[80usize..88usize].copy_from_slice(&value.to_ne_bytes())
2606    }
2607}
2608impl std::fmt::Debug for PushNdtStats {
2609    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2610        fmt.debug_struct("NdtStats")
2611            .field("allocs", &self.allocs())
2612            .field("destroys", &self.destroys())
2613            .field("hash_grows", &self.hash_grows())
2614            .field("res_failed", &self.res_failed())
2615            .field("lookups", &self.lookups())
2616            .field("hits", &self.hits())
2617            .field("rcv_probes_mcast", &self.rcv_probes_mcast())
2618            .field("rcv_probes_ucast", &self.rcv_probes_ucast())
2619            .field("periodic_gc_runs", &self.periodic_gc_runs())
2620            .field("forced_gc_runs", &self.forced_gc_runs())
2621            .field("table_fulls", &self.table_fulls())
2622            .finish()
2623    }
2624}
2625#[doc = "Add new neighbour entry"]
2626pub struct PushOpNewneighDoRequest<Prev: Rec> {
2627    pub(crate) prev: Option<Prev>,
2628    pub(crate) header_offset: Option<usize>,
2629}
2630impl<Prev: Rec> Rec for PushOpNewneighDoRequest<Prev> {
2631    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2632        self.prev.as_mut().unwrap().as_rec_mut()
2633    }
2634    fn as_rec(&self) -> &Vec<u8> {
2635        self.prev.as_ref().unwrap().as_rec()
2636    }
2637}
2638impl<Prev: Rec> PushOpNewneighDoRequest<Prev> {
2639    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
2640        Self::write_header(&mut prev, header);
2641        Self::new_without_header(prev)
2642    }
2643    fn new_without_header(prev: Prev) -> Self {
2644        Self {
2645            prev: Some(prev),
2646            header_offset: None,
2647        }
2648    }
2649    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
2650        prev.as_rec_mut().extend(header.as_slice());
2651    }
2652    pub fn end_nested(mut self) -> Prev {
2653        let mut prev = self.prev.take().unwrap();
2654        if let Some(header_offset) = &self.header_offset {
2655            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2656        }
2657        prev
2658    }
2659    pub fn push_dst(mut self, value: &[u8]) -> Self {
2660        push_header(self.as_rec_mut(), 1u16, value.len() as u16);
2661        self.as_rec_mut().extend(value);
2662        self
2663    }
2664    pub fn push_lladdr(mut self, value: &[u8]) -> Self {
2665        push_header(self.as_rec_mut(), 2u16, value.len() as u16);
2666        self.as_rec_mut().extend(value);
2667        self
2668    }
2669    pub fn push_probes(mut self, value: u32) -> Self {
2670        push_header(self.as_rec_mut(), 4u16, 4 as u16);
2671        self.as_rec_mut().extend(value.to_ne_bytes());
2672        self
2673    }
2674    pub fn push_vlan(mut self, value: u16) -> Self {
2675        push_header(self.as_rec_mut(), 5u16, 2 as u16);
2676        self.as_rec_mut().extend(value.to_ne_bytes());
2677        self
2678    }
2679    pub fn push_port(mut self, value: u16) -> Self {
2680        push_header(self.as_rec_mut(), 6u16, 2 as u16);
2681        self.as_rec_mut().extend(value.to_ne_bytes());
2682        self
2683    }
2684    pub fn push_vni(mut self, value: u32) -> Self {
2685        push_header(self.as_rec_mut(), 7u16, 4 as u16);
2686        self.as_rec_mut().extend(value.to_ne_bytes());
2687        self
2688    }
2689    pub fn push_ifindex(mut self, value: u32) -> Self {
2690        push_header(self.as_rec_mut(), 8u16, 4 as u16);
2691        self.as_rec_mut().extend(value.to_ne_bytes());
2692        self
2693    }
2694    pub fn push_master(mut self, value: u32) -> Self {
2695        push_header(self.as_rec_mut(), 9u16, 4 as u16);
2696        self.as_rec_mut().extend(value.to_ne_bytes());
2697        self
2698    }
2699    pub fn push_protocol(mut self, value: u8) -> Self {
2700        push_header(self.as_rec_mut(), 12u16, 1 as u16);
2701        self.as_rec_mut().extend(value.to_ne_bytes());
2702        self
2703    }
2704    pub fn push_nh_id(mut self, value: u32) -> Self {
2705        push_header(self.as_rec_mut(), 13u16, 4 as u16);
2706        self.as_rec_mut().extend(value.to_ne_bytes());
2707        self
2708    }
2709    pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
2710        push_header(self.as_rec_mut(), 14u16, value.len() as u16);
2711        self.as_rec_mut().extend(value);
2712        self
2713    }
2714    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
2715    pub fn push_flags_ext(mut self, value: u32) -> Self {
2716        push_header(self.as_rec_mut(), 15u16, 4 as u16);
2717        self.as_rec_mut().extend(value.to_ne_bytes());
2718        self
2719    }
2720}
2721impl<Prev: Rec> Drop for PushOpNewneighDoRequest<Prev> {
2722    fn drop(&mut self) {
2723        if let Some(prev) = &mut self.prev {
2724            if let Some(header_offset) = &self.header_offset {
2725                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2726            }
2727        }
2728    }
2729}
2730#[doc = "Add new neighbour entry"]
2731#[derive(Clone)]
2732pub enum OpNewneighDoRequest<'a> {
2733    Dst(&'a [u8]),
2734    Lladdr(&'a [u8]),
2735    Probes(u32),
2736    Vlan(u16),
2737    Port(u16),
2738    Vni(u32),
2739    Ifindex(u32),
2740    Master(u32),
2741    Protocol(u8),
2742    NhId(u32),
2743    FdbExtAttrs(&'a [u8]),
2744    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
2745    FlagsExt(u32),
2746}
2747impl<'a> IterableOpNewneighDoRequest<'a> {
2748    pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
2749        let mut iter = self.clone();
2750        iter.pos = 0;
2751        for attr in iter {
2752            if let OpNewneighDoRequest::Dst(val) = attr? {
2753                return Ok(val);
2754            }
2755        }
2756        Err(ErrorContext::new_missing(
2757            "OpNewneighDoRequest",
2758            "Dst",
2759            self.orig_loc,
2760            self.buf.as_ptr() as usize,
2761        ))
2762    }
2763    pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
2764        let mut iter = self.clone();
2765        iter.pos = 0;
2766        for attr in iter {
2767            if let OpNewneighDoRequest::Lladdr(val) = attr? {
2768                return Ok(val);
2769            }
2770        }
2771        Err(ErrorContext::new_missing(
2772            "OpNewneighDoRequest",
2773            "Lladdr",
2774            self.orig_loc,
2775            self.buf.as_ptr() as usize,
2776        ))
2777    }
2778    pub fn get_probes(&self) -> Result<u32, ErrorContext> {
2779        let mut iter = self.clone();
2780        iter.pos = 0;
2781        for attr in iter {
2782            if let OpNewneighDoRequest::Probes(val) = attr? {
2783                return Ok(val);
2784            }
2785        }
2786        Err(ErrorContext::new_missing(
2787            "OpNewneighDoRequest",
2788            "Probes",
2789            self.orig_loc,
2790            self.buf.as_ptr() as usize,
2791        ))
2792    }
2793    pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
2794        let mut iter = self.clone();
2795        iter.pos = 0;
2796        for attr in iter {
2797            if let OpNewneighDoRequest::Vlan(val) = attr? {
2798                return Ok(val);
2799            }
2800        }
2801        Err(ErrorContext::new_missing(
2802            "OpNewneighDoRequest",
2803            "Vlan",
2804            self.orig_loc,
2805            self.buf.as_ptr() as usize,
2806        ))
2807    }
2808    pub fn get_port(&self) -> Result<u16, ErrorContext> {
2809        let mut iter = self.clone();
2810        iter.pos = 0;
2811        for attr in iter {
2812            if let OpNewneighDoRequest::Port(val) = attr? {
2813                return Ok(val);
2814            }
2815        }
2816        Err(ErrorContext::new_missing(
2817            "OpNewneighDoRequest",
2818            "Port",
2819            self.orig_loc,
2820            self.buf.as_ptr() as usize,
2821        ))
2822    }
2823    pub fn get_vni(&self) -> Result<u32, ErrorContext> {
2824        let mut iter = self.clone();
2825        iter.pos = 0;
2826        for attr in iter {
2827            if let OpNewneighDoRequest::Vni(val) = attr? {
2828                return Ok(val);
2829            }
2830        }
2831        Err(ErrorContext::new_missing(
2832            "OpNewneighDoRequest",
2833            "Vni",
2834            self.orig_loc,
2835            self.buf.as_ptr() as usize,
2836        ))
2837    }
2838    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
2839        let mut iter = self.clone();
2840        iter.pos = 0;
2841        for attr in iter {
2842            if let OpNewneighDoRequest::Ifindex(val) = attr? {
2843                return Ok(val);
2844            }
2845        }
2846        Err(ErrorContext::new_missing(
2847            "OpNewneighDoRequest",
2848            "Ifindex",
2849            self.orig_loc,
2850            self.buf.as_ptr() as usize,
2851        ))
2852    }
2853    pub fn get_master(&self) -> Result<u32, ErrorContext> {
2854        let mut iter = self.clone();
2855        iter.pos = 0;
2856        for attr in iter {
2857            if let OpNewneighDoRequest::Master(val) = attr? {
2858                return Ok(val);
2859            }
2860        }
2861        Err(ErrorContext::new_missing(
2862            "OpNewneighDoRequest",
2863            "Master",
2864            self.orig_loc,
2865            self.buf.as_ptr() as usize,
2866        ))
2867    }
2868    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
2869        let mut iter = self.clone();
2870        iter.pos = 0;
2871        for attr in iter {
2872            if let OpNewneighDoRequest::Protocol(val) = attr? {
2873                return Ok(val);
2874            }
2875        }
2876        Err(ErrorContext::new_missing(
2877            "OpNewneighDoRequest",
2878            "Protocol",
2879            self.orig_loc,
2880            self.buf.as_ptr() as usize,
2881        ))
2882    }
2883    pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
2884        let mut iter = self.clone();
2885        iter.pos = 0;
2886        for attr in iter {
2887            if let OpNewneighDoRequest::NhId(val) = attr? {
2888                return Ok(val);
2889            }
2890        }
2891        Err(ErrorContext::new_missing(
2892            "OpNewneighDoRequest",
2893            "NhId",
2894            self.orig_loc,
2895            self.buf.as_ptr() as usize,
2896        ))
2897    }
2898    pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
2899        let mut iter = self.clone();
2900        iter.pos = 0;
2901        for attr in iter {
2902            if let OpNewneighDoRequest::FdbExtAttrs(val) = attr? {
2903                return Ok(val);
2904            }
2905        }
2906        Err(ErrorContext::new_missing(
2907            "OpNewneighDoRequest",
2908            "FdbExtAttrs",
2909            self.orig_loc,
2910            self.buf.as_ptr() as usize,
2911        ))
2912    }
2913    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
2914    pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
2915        let mut iter = self.clone();
2916        iter.pos = 0;
2917        for attr in iter {
2918            if let OpNewneighDoRequest::FlagsExt(val) = attr? {
2919                return Ok(val);
2920            }
2921        }
2922        Err(ErrorContext::new_missing(
2923            "OpNewneighDoRequest",
2924            "FlagsExt",
2925            self.orig_loc,
2926            self.buf.as_ptr() as usize,
2927        ))
2928    }
2929}
2930impl OpNewneighDoRequest<'_> {
2931    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpNewneighDoRequest<'a>) {
2932        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
2933        (
2934            PushNdmsg::new_from_slice(header).unwrap_or_default(),
2935            IterableOpNewneighDoRequest::with_loc(attrs, buf.as_ptr() as usize),
2936        )
2937    }
2938    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2939        NeighbourAttrs::attr_from_type(r#type)
2940    }
2941}
2942#[derive(Clone, Copy, Default)]
2943pub struct IterableOpNewneighDoRequest<'a> {
2944    buf: &'a [u8],
2945    pos: usize,
2946    orig_loc: usize,
2947}
2948impl<'a> IterableOpNewneighDoRequest<'a> {
2949    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2950        Self {
2951            buf,
2952            pos: 0,
2953            orig_loc,
2954        }
2955    }
2956    pub fn get_buf(&self) -> &'a [u8] {
2957        self.buf
2958    }
2959}
2960impl<'a> Iterator for IterableOpNewneighDoRequest<'a> {
2961    type Item = Result<OpNewneighDoRequest<'a>, ErrorContext>;
2962    fn next(&mut self) -> Option<Self::Item> {
2963        let pos = self.pos;
2964        let mut r#type;
2965        loop {
2966            r#type = None;
2967            if self.buf.len() == self.pos {
2968                return None;
2969            }
2970            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2971                break;
2972            };
2973            r#type = Some(header.r#type);
2974            let res = match header.r#type {
2975                1u16 => OpNewneighDoRequest::Dst({
2976                    let res = Some(next);
2977                    let Some(val) = res else { break };
2978                    val
2979                }),
2980                2u16 => OpNewneighDoRequest::Lladdr({
2981                    let res = Some(next);
2982                    let Some(val) = res else { break };
2983                    val
2984                }),
2985                4u16 => OpNewneighDoRequest::Probes({
2986                    let res = parse_u32(next);
2987                    let Some(val) = res else { break };
2988                    val
2989                }),
2990                5u16 => OpNewneighDoRequest::Vlan({
2991                    let res = parse_u16(next);
2992                    let Some(val) = res else { break };
2993                    val
2994                }),
2995                6u16 => OpNewneighDoRequest::Port({
2996                    let res = parse_u16(next);
2997                    let Some(val) = res else { break };
2998                    val
2999                }),
3000                7u16 => OpNewneighDoRequest::Vni({
3001                    let res = parse_u32(next);
3002                    let Some(val) = res else { break };
3003                    val
3004                }),
3005                8u16 => OpNewneighDoRequest::Ifindex({
3006                    let res = parse_u32(next);
3007                    let Some(val) = res else { break };
3008                    val
3009                }),
3010                9u16 => OpNewneighDoRequest::Master({
3011                    let res = parse_u32(next);
3012                    let Some(val) = res else { break };
3013                    val
3014                }),
3015                12u16 => OpNewneighDoRequest::Protocol({
3016                    let res = parse_u8(next);
3017                    let Some(val) = res else { break };
3018                    val
3019                }),
3020                13u16 => OpNewneighDoRequest::NhId({
3021                    let res = parse_u32(next);
3022                    let Some(val) = res else { break };
3023                    val
3024                }),
3025                14u16 => OpNewneighDoRequest::FdbExtAttrs({
3026                    let res = Some(next);
3027                    let Some(val) = res else { break };
3028                    val
3029                }),
3030                15u16 => OpNewneighDoRequest::FlagsExt({
3031                    let res = parse_u32(next);
3032                    let Some(val) = res else { break };
3033                    val
3034                }),
3035                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3036                n => continue,
3037            };
3038            return Some(Ok(res));
3039        }
3040        Some(Err(ErrorContext::new(
3041            "OpNewneighDoRequest",
3042            r#type.and_then(|t| OpNewneighDoRequest::attr_from_type(t)),
3043            self.orig_loc,
3044            self.buf.as_ptr().wrapping_add(pos) as usize,
3045        )))
3046    }
3047}
3048impl<'a> std::fmt::Debug for IterableOpNewneighDoRequest<'_> {
3049    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3050        let mut fmt = f.debug_struct("OpNewneighDoRequest");
3051        for attr in self.clone() {
3052            let attr = match attr {
3053                Ok(a) => a,
3054                Err(err) => {
3055                    fmt.finish()?;
3056                    f.write_str("Err(")?;
3057                    err.fmt(f)?;
3058                    return f.write_str(")");
3059                }
3060            };
3061            match attr {
3062                OpNewneighDoRequest::Dst(val) => fmt.field("Dst", &val),
3063                OpNewneighDoRequest::Lladdr(val) => fmt.field("Lladdr", &val),
3064                OpNewneighDoRequest::Probes(val) => fmt.field("Probes", &val),
3065                OpNewneighDoRequest::Vlan(val) => fmt.field("Vlan", &val),
3066                OpNewneighDoRequest::Port(val) => fmt.field("Port", &val),
3067                OpNewneighDoRequest::Vni(val) => fmt.field("Vni", &val),
3068                OpNewneighDoRequest::Ifindex(val) => fmt.field("Ifindex", &val),
3069                OpNewneighDoRequest::Master(val) => fmt.field("Master", &val),
3070                OpNewneighDoRequest::Protocol(val) => fmt.field("Protocol", &val),
3071                OpNewneighDoRequest::NhId(val) => fmt.field("NhId", &val),
3072                OpNewneighDoRequest::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
3073                OpNewneighDoRequest::FlagsExt(val) => fmt.field(
3074                    "FlagsExt",
3075                    &FormatFlags(val.into(), NtfExtFlags::from_value),
3076                ),
3077            };
3078        }
3079        fmt.finish()
3080    }
3081}
3082impl IterableOpNewneighDoRequest<'_> {
3083    pub fn lookup_attr(
3084        &self,
3085        offset: usize,
3086        missing_type: Option<u16>,
3087    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3088        let mut stack = Vec::new();
3089        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3090        if cur == offset + PushNdmsg::len() {
3091            stack.push(("OpNewneighDoRequest", offset));
3092            return (
3093                stack,
3094                missing_type.and_then(|t| OpNewneighDoRequest::attr_from_type(t)),
3095            );
3096        }
3097        if cur > offset || cur + self.buf.len() < offset {
3098            return (stack, None);
3099        }
3100        let mut attrs = self.clone();
3101        let mut last_off = cur + attrs.pos;
3102        while let Some(attr) = attrs.next() {
3103            let Ok(attr) = attr else { break };
3104            match attr {
3105                OpNewneighDoRequest::Dst(val) => {
3106                    if last_off == offset {
3107                        stack.push(("Dst", last_off));
3108                        break;
3109                    }
3110                }
3111                OpNewneighDoRequest::Lladdr(val) => {
3112                    if last_off == offset {
3113                        stack.push(("Lladdr", last_off));
3114                        break;
3115                    }
3116                }
3117                OpNewneighDoRequest::Probes(val) => {
3118                    if last_off == offset {
3119                        stack.push(("Probes", last_off));
3120                        break;
3121                    }
3122                }
3123                OpNewneighDoRequest::Vlan(val) => {
3124                    if last_off == offset {
3125                        stack.push(("Vlan", last_off));
3126                        break;
3127                    }
3128                }
3129                OpNewneighDoRequest::Port(val) => {
3130                    if last_off == offset {
3131                        stack.push(("Port", last_off));
3132                        break;
3133                    }
3134                }
3135                OpNewneighDoRequest::Vni(val) => {
3136                    if last_off == offset {
3137                        stack.push(("Vni", last_off));
3138                        break;
3139                    }
3140                }
3141                OpNewneighDoRequest::Ifindex(val) => {
3142                    if last_off == offset {
3143                        stack.push(("Ifindex", last_off));
3144                        break;
3145                    }
3146                }
3147                OpNewneighDoRequest::Master(val) => {
3148                    if last_off == offset {
3149                        stack.push(("Master", last_off));
3150                        break;
3151                    }
3152                }
3153                OpNewneighDoRequest::Protocol(val) => {
3154                    if last_off == offset {
3155                        stack.push(("Protocol", last_off));
3156                        break;
3157                    }
3158                }
3159                OpNewneighDoRequest::NhId(val) => {
3160                    if last_off == offset {
3161                        stack.push(("NhId", last_off));
3162                        break;
3163                    }
3164                }
3165                OpNewneighDoRequest::FdbExtAttrs(val) => {
3166                    if last_off == offset {
3167                        stack.push(("FdbExtAttrs", last_off));
3168                        break;
3169                    }
3170                }
3171                OpNewneighDoRequest::FlagsExt(val) => {
3172                    if last_off == offset {
3173                        stack.push(("FlagsExt", last_off));
3174                        break;
3175                    }
3176                }
3177                _ => {}
3178            };
3179            last_off = cur + attrs.pos;
3180        }
3181        if !stack.is_empty() {
3182            stack.push(("OpNewneighDoRequest", cur));
3183        }
3184        (stack, None)
3185    }
3186}
3187#[doc = "Add new neighbour entry"]
3188pub struct PushOpNewneighDoReply<Prev: Rec> {
3189    pub(crate) prev: Option<Prev>,
3190    pub(crate) header_offset: Option<usize>,
3191}
3192impl<Prev: Rec> Rec for PushOpNewneighDoReply<Prev> {
3193    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3194        self.prev.as_mut().unwrap().as_rec_mut()
3195    }
3196    fn as_rec(&self) -> &Vec<u8> {
3197        self.prev.as_ref().unwrap().as_rec()
3198    }
3199}
3200impl<Prev: Rec> PushOpNewneighDoReply<Prev> {
3201    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3202        Self::write_header(&mut prev, header);
3203        Self::new_without_header(prev)
3204    }
3205    fn new_without_header(prev: Prev) -> Self {
3206        Self {
3207            prev: Some(prev),
3208            header_offset: None,
3209        }
3210    }
3211    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3212        prev.as_rec_mut().extend(header.as_slice());
3213    }
3214    pub fn end_nested(mut self) -> Prev {
3215        let mut prev = self.prev.take().unwrap();
3216        if let Some(header_offset) = &self.header_offset {
3217            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3218        }
3219        prev
3220    }
3221}
3222impl<Prev: Rec> Drop for PushOpNewneighDoReply<Prev> {
3223    fn drop(&mut self) {
3224        if let Some(prev) = &mut self.prev {
3225            if let Some(header_offset) = &self.header_offset {
3226                finalize_nested_header(prev.as_rec_mut(), *header_offset);
3227            }
3228        }
3229    }
3230}
3231#[doc = "Add new neighbour entry"]
3232#[derive(Clone)]
3233pub enum OpNewneighDoReply {}
3234impl<'a> IterableOpNewneighDoReply<'a> {}
3235impl OpNewneighDoReply {
3236    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpNewneighDoReply<'a>) {
3237        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3238        (
3239            PushNdmsg::new_from_slice(header).unwrap_or_default(),
3240            IterableOpNewneighDoReply::with_loc(attrs, buf.as_ptr() as usize),
3241        )
3242    }
3243    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3244        NeighbourAttrs::attr_from_type(r#type)
3245    }
3246}
3247#[derive(Clone, Copy, Default)]
3248pub struct IterableOpNewneighDoReply<'a> {
3249    buf: &'a [u8],
3250    pos: usize,
3251    orig_loc: usize,
3252}
3253impl<'a> IterableOpNewneighDoReply<'a> {
3254    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3255        Self {
3256            buf,
3257            pos: 0,
3258            orig_loc,
3259        }
3260    }
3261    pub fn get_buf(&self) -> &'a [u8] {
3262        self.buf
3263    }
3264}
3265impl<'a> Iterator for IterableOpNewneighDoReply<'a> {
3266    type Item = Result<OpNewneighDoReply, ErrorContext>;
3267    fn next(&mut self) -> Option<Self::Item> {
3268        let pos = self.pos;
3269        let mut r#type;
3270        loop {
3271            r#type = None;
3272            if self.buf.len() == self.pos {
3273                return None;
3274            }
3275            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3276                break;
3277            };
3278            r#type = Some(header.r#type);
3279            let res = match header.r#type {
3280                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3281                n => continue,
3282            };
3283            return Some(Ok(res));
3284        }
3285        Some(Err(ErrorContext::new(
3286            "OpNewneighDoReply",
3287            r#type.and_then(|t| OpNewneighDoReply::attr_from_type(t)),
3288            self.orig_loc,
3289            self.buf.as_ptr().wrapping_add(pos) as usize,
3290        )))
3291    }
3292}
3293impl std::fmt::Debug for IterableOpNewneighDoReply<'_> {
3294    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3295        let mut fmt = f.debug_struct("OpNewneighDoReply");
3296        for attr in self.clone() {
3297            let attr = match attr {
3298                Ok(a) => a,
3299                Err(err) => {
3300                    fmt.finish()?;
3301                    f.write_str("Err(")?;
3302                    err.fmt(f)?;
3303                    return f.write_str(")");
3304                }
3305            };
3306            match attr {};
3307        }
3308        fmt.finish()
3309    }
3310}
3311impl IterableOpNewneighDoReply<'_> {
3312    pub fn lookup_attr(
3313        &self,
3314        offset: usize,
3315        missing_type: Option<u16>,
3316    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3317        let mut stack = Vec::new();
3318        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3319        if cur == offset + PushNdmsg::len() {
3320            stack.push(("OpNewneighDoReply", offset));
3321            return (
3322                stack,
3323                missing_type.and_then(|t| OpNewneighDoReply::attr_from_type(t)),
3324            );
3325        }
3326        (stack, None)
3327    }
3328}
3329#[derive(Debug)]
3330pub struct RequestOpNewneighDoRequest<'r> {
3331    request: Request<'r>,
3332}
3333impl<'r> RequestOpNewneighDoRequest<'r> {
3334    pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
3335        PushOpNewneighDoRequest::write_header(&mut request.buf_mut(), header);
3336        Self { request: request }
3337    }
3338    pub fn encode(&mut self) -> PushOpNewneighDoRequest<&mut Vec<u8>> {
3339        PushOpNewneighDoRequest::new_without_header(self.request.buf_mut())
3340    }
3341    pub fn into_encoder(self) -> PushOpNewneighDoRequest<RequestBuf<'r>> {
3342        PushOpNewneighDoRequest::new_without_header(self.request.buf)
3343    }
3344    pub fn decode_request<'buf>(buf: &'buf [u8]) -> (PushNdmsg, IterableOpNewneighDoRequest<'buf>) {
3345        OpNewneighDoRequest::new(buf)
3346    }
3347}
3348impl NetlinkRequest for RequestOpNewneighDoRequest<'_> {
3349    fn protocol(&self) -> Protocol {
3350        Protocol::Raw {
3351            protonum: 0u16,
3352            request_type: 28u16,
3353        }
3354    }
3355    fn flags(&self) -> u16 {
3356        self.request.flags
3357    }
3358    fn payload(&self) -> &[u8] {
3359        self.request.buf()
3360    }
3361    type ReplyType<'buf> = (PushNdmsg, IterableOpNewneighDoReply<'buf>);
3362    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3363        OpNewneighDoReply::new(buf)
3364    }
3365    fn lookup(
3366        buf: &[u8],
3367        offset: usize,
3368        missing_type: Option<u16>,
3369    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3370        OpNewneighDoRequest::new(buf)
3371            .1
3372            .lookup_attr(offset, missing_type)
3373    }
3374}
3375#[doc = "Remove an existing neighbour entry"]
3376pub struct PushOpDelneighDoRequest<Prev: Rec> {
3377    pub(crate) prev: Option<Prev>,
3378    pub(crate) header_offset: Option<usize>,
3379}
3380impl<Prev: Rec> Rec for PushOpDelneighDoRequest<Prev> {
3381    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3382        self.prev.as_mut().unwrap().as_rec_mut()
3383    }
3384    fn as_rec(&self) -> &Vec<u8> {
3385        self.prev.as_ref().unwrap().as_rec()
3386    }
3387}
3388impl<Prev: Rec> PushOpDelneighDoRequest<Prev> {
3389    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3390        Self::write_header(&mut prev, header);
3391        Self::new_without_header(prev)
3392    }
3393    fn new_without_header(prev: Prev) -> Self {
3394        Self {
3395            prev: Some(prev),
3396            header_offset: None,
3397        }
3398    }
3399    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3400        prev.as_rec_mut().extend(header.as_slice());
3401    }
3402    pub fn end_nested(mut self) -> Prev {
3403        let mut prev = self.prev.take().unwrap();
3404        if let Some(header_offset) = &self.header_offset {
3405            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3406        }
3407        prev
3408    }
3409    pub fn push_dst(mut self, value: &[u8]) -> Self {
3410        push_header(self.as_rec_mut(), 1u16, value.len() as u16);
3411        self.as_rec_mut().extend(value);
3412        self
3413    }
3414    pub fn push_ifindex(mut self, value: u32) -> Self {
3415        push_header(self.as_rec_mut(), 8u16, 4 as u16);
3416        self.as_rec_mut().extend(value.to_ne_bytes());
3417        self
3418    }
3419}
3420impl<Prev: Rec> Drop for PushOpDelneighDoRequest<Prev> {
3421    fn drop(&mut self) {
3422        if let Some(prev) = &mut self.prev {
3423            if let Some(header_offset) = &self.header_offset {
3424                finalize_nested_header(prev.as_rec_mut(), *header_offset);
3425            }
3426        }
3427    }
3428}
3429#[doc = "Remove an existing neighbour entry"]
3430#[derive(Clone)]
3431pub enum OpDelneighDoRequest<'a> {
3432    Dst(&'a [u8]),
3433    Ifindex(u32),
3434}
3435impl<'a> IterableOpDelneighDoRequest<'a> {
3436    pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
3437        let mut iter = self.clone();
3438        iter.pos = 0;
3439        for attr in iter {
3440            if let OpDelneighDoRequest::Dst(val) = attr? {
3441                return Ok(val);
3442            }
3443        }
3444        Err(ErrorContext::new_missing(
3445            "OpDelneighDoRequest",
3446            "Dst",
3447            self.orig_loc,
3448            self.buf.as_ptr() as usize,
3449        ))
3450    }
3451    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
3452        let mut iter = self.clone();
3453        iter.pos = 0;
3454        for attr in iter {
3455            if let OpDelneighDoRequest::Ifindex(val) = attr? {
3456                return Ok(val);
3457            }
3458        }
3459        Err(ErrorContext::new_missing(
3460            "OpDelneighDoRequest",
3461            "Ifindex",
3462            self.orig_loc,
3463            self.buf.as_ptr() as usize,
3464        ))
3465    }
3466}
3467impl OpDelneighDoRequest<'_> {
3468    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpDelneighDoRequest<'a>) {
3469        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3470        (
3471            PushNdmsg::new_from_slice(header).unwrap_or_default(),
3472            IterableOpDelneighDoRequest::with_loc(attrs, buf.as_ptr() as usize),
3473        )
3474    }
3475    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3476        NeighbourAttrs::attr_from_type(r#type)
3477    }
3478}
3479#[derive(Clone, Copy, Default)]
3480pub struct IterableOpDelneighDoRequest<'a> {
3481    buf: &'a [u8],
3482    pos: usize,
3483    orig_loc: usize,
3484}
3485impl<'a> IterableOpDelneighDoRequest<'a> {
3486    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3487        Self {
3488            buf,
3489            pos: 0,
3490            orig_loc,
3491        }
3492    }
3493    pub fn get_buf(&self) -> &'a [u8] {
3494        self.buf
3495    }
3496}
3497impl<'a> Iterator for IterableOpDelneighDoRequest<'a> {
3498    type Item = Result<OpDelneighDoRequest<'a>, ErrorContext>;
3499    fn next(&mut self) -> Option<Self::Item> {
3500        let pos = self.pos;
3501        let mut r#type;
3502        loop {
3503            r#type = None;
3504            if self.buf.len() == self.pos {
3505                return None;
3506            }
3507            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3508                break;
3509            };
3510            r#type = Some(header.r#type);
3511            let res = match header.r#type {
3512                1u16 => OpDelneighDoRequest::Dst({
3513                    let res = Some(next);
3514                    let Some(val) = res else { break };
3515                    val
3516                }),
3517                8u16 => OpDelneighDoRequest::Ifindex({
3518                    let res = parse_u32(next);
3519                    let Some(val) = res else { break };
3520                    val
3521                }),
3522                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3523                n => continue,
3524            };
3525            return Some(Ok(res));
3526        }
3527        Some(Err(ErrorContext::new(
3528            "OpDelneighDoRequest",
3529            r#type.and_then(|t| OpDelneighDoRequest::attr_from_type(t)),
3530            self.orig_loc,
3531            self.buf.as_ptr().wrapping_add(pos) as usize,
3532        )))
3533    }
3534}
3535impl<'a> std::fmt::Debug for IterableOpDelneighDoRequest<'_> {
3536    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3537        let mut fmt = f.debug_struct("OpDelneighDoRequest");
3538        for attr in self.clone() {
3539            let attr = match attr {
3540                Ok(a) => a,
3541                Err(err) => {
3542                    fmt.finish()?;
3543                    f.write_str("Err(")?;
3544                    err.fmt(f)?;
3545                    return f.write_str(")");
3546                }
3547            };
3548            match attr {
3549                OpDelneighDoRequest::Dst(val) => fmt.field("Dst", &val),
3550                OpDelneighDoRequest::Ifindex(val) => fmt.field("Ifindex", &val),
3551            };
3552        }
3553        fmt.finish()
3554    }
3555}
3556impl IterableOpDelneighDoRequest<'_> {
3557    pub fn lookup_attr(
3558        &self,
3559        offset: usize,
3560        missing_type: Option<u16>,
3561    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3562        let mut stack = Vec::new();
3563        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3564        if cur == offset + PushNdmsg::len() {
3565            stack.push(("OpDelneighDoRequest", offset));
3566            return (
3567                stack,
3568                missing_type.and_then(|t| OpDelneighDoRequest::attr_from_type(t)),
3569            );
3570        }
3571        if cur > offset || cur + self.buf.len() < offset {
3572            return (stack, None);
3573        }
3574        let mut attrs = self.clone();
3575        let mut last_off = cur + attrs.pos;
3576        while let Some(attr) = attrs.next() {
3577            let Ok(attr) = attr else { break };
3578            match attr {
3579                OpDelneighDoRequest::Dst(val) => {
3580                    if last_off == offset {
3581                        stack.push(("Dst", last_off));
3582                        break;
3583                    }
3584                }
3585                OpDelneighDoRequest::Ifindex(val) => {
3586                    if last_off == offset {
3587                        stack.push(("Ifindex", last_off));
3588                        break;
3589                    }
3590                }
3591                _ => {}
3592            };
3593            last_off = cur + attrs.pos;
3594        }
3595        if !stack.is_empty() {
3596            stack.push(("OpDelneighDoRequest", cur));
3597        }
3598        (stack, None)
3599    }
3600}
3601#[doc = "Remove an existing neighbour entry"]
3602pub struct PushOpDelneighDoReply<Prev: Rec> {
3603    pub(crate) prev: Option<Prev>,
3604    pub(crate) header_offset: Option<usize>,
3605}
3606impl<Prev: Rec> Rec for PushOpDelneighDoReply<Prev> {
3607    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3608        self.prev.as_mut().unwrap().as_rec_mut()
3609    }
3610    fn as_rec(&self) -> &Vec<u8> {
3611        self.prev.as_ref().unwrap().as_rec()
3612    }
3613}
3614impl<Prev: Rec> PushOpDelneighDoReply<Prev> {
3615    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3616        Self::write_header(&mut prev, header);
3617        Self::new_without_header(prev)
3618    }
3619    fn new_without_header(prev: Prev) -> Self {
3620        Self {
3621            prev: Some(prev),
3622            header_offset: None,
3623        }
3624    }
3625    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3626        prev.as_rec_mut().extend(header.as_slice());
3627    }
3628    pub fn end_nested(mut self) -> Prev {
3629        let mut prev = self.prev.take().unwrap();
3630        if let Some(header_offset) = &self.header_offset {
3631            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3632        }
3633        prev
3634    }
3635}
3636impl<Prev: Rec> Drop for PushOpDelneighDoReply<Prev> {
3637    fn drop(&mut self) {
3638        if let Some(prev) = &mut self.prev {
3639            if let Some(header_offset) = &self.header_offset {
3640                finalize_nested_header(prev.as_rec_mut(), *header_offset);
3641            }
3642        }
3643    }
3644}
3645#[doc = "Remove an existing neighbour entry"]
3646#[derive(Clone)]
3647pub enum OpDelneighDoReply {}
3648impl<'a> IterableOpDelneighDoReply<'a> {}
3649impl OpDelneighDoReply {
3650    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpDelneighDoReply<'a>) {
3651        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3652        (
3653            PushNdmsg::new_from_slice(header).unwrap_or_default(),
3654            IterableOpDelneighDoReply::with_loc(attrs, buf.as_ptr() as usize),
3655        )
3656    }
3657    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3658        NeighbourAttrs::attr_from_type(r#type)
3659    }
3660}
3661#[derive(Clone, Copy, Default)]
3662pub struct IterableOpDelneighDoReply<'a> {
3663    buf: &'a [u8],
3664    pos: usize,
3665    orig_loc: usize,
3666}
3667impl<'a> IterableOpDelneighDoReply<'a> {
3668    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3669        Self {
3670            buf,
3671            pos: 0,
3672            orig_loc,
3673        }
3674    }
3675    pub fn get_buf(&self) -> &'a [u8] {
3676        self.buf
3677    }
3678}
3679impl<'a> Iterator for IterableOpDelneighDoReply<'a> {
3680    type Item = Result<OpDelneighDoReply, ErrorContext>;
3681    fn next(&mut self) -> Option<Self::Item> {
3682        let pos = self.pos;
3683        let mut r#type;
3684        loop {
3685            r#type = None;
3686            if self.buf.len() == self.pos {
3687                return None;
3688            }
3689            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3690                break;
3691            };
3692            r#type = Some(header.r#type);
3693            let res = match header.r#type {
3694                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3695                n => continue,
3696            };
3697            return Some(Ok(res));
3698        }
3699        Some(Err(ErrorContext::new(
3700            "OpDelneighDoReply",
3701            r#type.and_then(|t| OpDelneighDoReply::attr_from_type(t)),
3702            self.orig_loc,
3703            self.buf.as_ptr().wrapping_add(pos) as usize,
3704        )))
3705    }
3706}
3707impl std::fmt::Debug for IterableOpDelneighDoReply<'_> {
3708    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3709        let mut fmt = f.debug_struct("OpDelneighDoReply");
3710        for attr in self.clone() {
3711            let attr = match attr {
3712                Ok(a) => a,
3713                Err(err) => {
3714                    fmt.finish()?;
3715                    f.write_str("Err(")?;
3716                    err.fmt(f)?;
3717                    return f.write_str(")");
3718                }
3719            };
3720            match attr {};
3721        }
3722        fmt.finish()
3723    }
3724}
3725impl IterableOpDelneighDoReply<'_> {
3726    pub fn lookup_attr(
3727        &self,
3728        offset: usize,
3729        missing_type: Option<u16>,
3730    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3731        let mut stack = Vec::new();
3732        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3733        if cur == offset + PushNdmsg::len() {
3734            stack.push(("OpDelneighDoReply", offset));
3735            return (
3736                stack,
3737                missing_type.and_then(|t| OpDelneighDoReply::attr_from_type(t)),
3738            );
3739        }
3740        (stack, None)
3741    }
3742}
3743#[derive(Debug)]
3744pub struct RequestOpDelneighDoRequest<'r> {
3745    request: Request<'r>,
3746}
3747impl<'r> RequestOpDelneighDoRequest<'r> {
3748    pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
3749        PushOpDelneighDoRequest::write_header(&mut request.buf_mut(), header);
3750        Self { request: request }
3751    }
3752    pub fn encode(&mut self) -> PushOpDelneighDoRequest<&mut Vec<u8>> {
3753        PushOpDelneighDoRequest::new_without_header(self.request.buf_mut())
3754    }
3755    pub fn into_encoder(self) -> PushOpDelneighDoRequest<RequestBuf<'r>> {
3756        PushOpDelneighDoRequest::new_without_header(self.request.buf)
3757    }
3758    pub fn decode_request<'buf>(buf: &'buf [u8]) -> (PushNdmsg, IterableOpDelneighDoRequest<'buf>) {
3759        OpDelneighDoRequest::new(buf)
3760    }
3761}
3762impl NetlinkRequest for RequestOpDelneighDoRequest<'_> {
3763    fn protocol(&self) -> Protocol {
3764        Protocol::Raw {
3765            protonum: 0u16,
3766            request_type: 29u16,
3767        }
3768    }
3769    fn flags(&self) -> u16 {
3770        self.request.flags
3771    }
3772    fn payload(&self) -> &[u8] {
3773        self.request.buf()
3774    }
3775    type ReplyType<'buf> = (PushNdmsg, IterableOpDelneighDoReply<'buf>);
3776    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3777        OpDelneighDoReply::new(buf)
3778    }
3779    fn lookup(
3780        buf: &[u8],
3781        offset: usize,
3782        missing_type: Option<u16>,
3783    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3784        OpDelneighDoRequest::new(buf)
3785            .1
3786            .lookup_attr(offset, missing_type)
3787    }
3788}
3789#[doc = "Get or dump neighbour entries"]
3790pub struct PushOpGetneighDumpRequest<Prev: Rec> {
3791    pub(crate) prev: Option<Prev>,
3792    pub(crate) header_offset: Option<usize>,
3793}
3794impl<Prev: Rec> Rec for PushOpGetneighDumpRequest<Prev> {
3795    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3796        self.prev.as_mut().unwrap().as_rec_mut()
3797    }
3798    fn as_rec(&self) -> &Vec<u8> {
3799        self.prev.as_ref().unwrap().as_rec()
3800    }
3801}
3802impl<Prev: Rec> PushOpGetneighDumpRequest<Prev> {
3803    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3804        Self::write_header(&mut prev, header);
3805        Self::new_without_header(prev)
3806    }
3807    fn new_without_header(prev: Prev) -> Self {
3808        Self {
3809            prev: Some(prev),
3810            header_offset: None,
3811        }
3812    }
3813    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3814        prev.as_rec_mut().extend(header.as_slice());
3815    }
3816    pub fn end_nested(mut self) -> Prev {
3817        let mut prev = self.prev.take().unwrap();
3818        if let Some(header_offset) = &self.header_offset {
3819            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3820        }
3821        prev
3822    }
3823    pub fn push_ifindex(mut self, value: u32) -> Self {
3824        push_header(self.as_rec_mut(), 8u16, 4 as u16);
3825        self.as_rec_mut().extend(value.to_ne_bytes());
3826        self
3827    }
3828    pub fn push_master(mut self, value: u32) -> Self {
3829        push_header(self.as_rec_mut(), 9u16, 4 as u16);
3830        self.as_rec_mut().extend(value.to_ne_bytes());
3831        self
3832    }
3833}
3834impl<Prev: Rec> Drop for PushOpGetneighDumpRequest<Prev> {
3835    fn drop(&mut self) {
3836        if let Some(prev) = &mut self.prev {
3837            if let Some(header_offset) = &self.header_offset {
3838                finalize_nested_header(prev.as_rec_mut(), *header_offset);
3839            }
3840        }
3841    }
3842}
3843#[doc = "Get or dump neighbour entries"]
3844#[derive(Clone)]
3845pub enum OpGetneighDumpRequest {
3846    Ifindex(u32),
3847    Master(u32),
3848}
3849impl<'a> IterableOpGetneighDumpRequest<'a> {
3850    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
3851        let mut iter = self.clone();
3852        iter.pos = 0;
3853        for attr in iter {
3854            if let OpGetneighDumpRequest::Ifindex(val) = attr? {
3855                return Ok(val);
3856            }
3857        }
3858        Err(ErrorContext::new_missing(
3859            "OpGetneighDumpRequest",
3860            "Ifindex",
3861            self.orig_loc,
3862            self.buf.as_ptr() as usize,
3863        ))
3864    }
3865    pub fn get_master(&self) -> Result<u32, ErrorContext> {
3866        let mut iter = self.clone();
3867        iter.pos = 0;
3868        for attr in iter {
3869            if let OpGetneighDumpRequest::Master(val) = attr? {
3870                return Ok(val);
3871            }
3872        }
3873        Err(ErrorContext::new_missing(
3874            "OpGetneighDumpRequest",
3875            "Master",
3876            self.orig_loc,
3877            self.buf.as_ptr() as usize,
3878        ))
3879    }
3880}
3881impl OpGetneighDumpRequest {
3882    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDumpRequest<'a>) {
3883        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3884        (
3885            PushNdmsg::new_from_slice(header).unwrap_or_default(),
3886            IterableOpGetneighDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
3887        )
3888    }
3889    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3890        NeighbourAttrs::attr_from_type(r#type)
3891    }
3892}
3893#[derive(Clone, Copy, Default)]
3894pub struct IterableOpGetneighDumpRequest<'a> {
3895    buf: &'a [u8],
3896    pos: usize,
3897    orig_loc: usize,
3898}
3899impl<'a> IterableOpGetneighDumpRequest<'a> {
3900    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3901        Self {
3902            buf,
3903            pos: 0,
3904            orig_loc,
3905        }
3906    }
3907    pub fn get_buf(&self) -> &'a [u8] {
3908        self.buf
3909    }
3910}
3911impl<'a> Iterator for IterableOpGetneighDumpRequest<'a> {
3912    type Item = Result<OpGetneighDumpRequest, ErrorContext>;
3913    fn next(&mut self) -> Option<Self::Item> {
3914        let pos = self.pos;
3915        let mut r#type;
3916        loop {
3917            r#type = None;
3918            if self.buf.len() == self.pos {
3919                return None;
3920            }
3921            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3922                break;
3923            };
3924            r#type = Some(header.r#type);
3925            let res = match header.r#type {
3926                8u16 => OpGetneighDumpRequest::Ifindex({
3927                    let res = parse_u32(next);
3928                    let Some(val) = res else { break };
3929                    val
3930                }),
3931                9u16 => OpGetneighDumpRequest::Master({
3932                    let res = parse_u32(next);
3933                    let Some(val) = res else { break };
3934                    val
3935                }),
3936                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3937                n => continue,
3938            };
3939            return Some(Ok(res));
3940        }
3941        Some(Err(ErrorContext::new(
3942            "OpGetneighDumpRequest",
3943            r#type.and_then(|t| OpGetneighDumpRequest::attr_from_type(t)),
3944            self.orig_loc,
3945            self.buf.as_ptr().wrapping_add(pos) as usize,
3946        )))
3947    }
3948}
3949impl std::fmt::Debug for IterableOpGetneighDumpRequest<'_> {
3950    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3951        let mut fmt = f.debug_struct("OpGetneighDumpRequest");
3952        for attr in self.clone() {
3953            let attr = match attr {
3954                Ok(a) => a,
3955                Err(err) => {
3956                    fmt.finish()?;
3957                    f.write_str("Err(")?;
3958                    err.fmt(f)?;
3959                    return f.write_str(")");
3960                }
3961            };
3962            match attr {
3963                OpGetneighDumpRequest::Ifindex(val) => fmt.field("Ifindex", &val),
3964                OpGetneighDumpRequest::Master(val) => fmt.field("Master", &val),
3965            };
3966        }
3967        fmt.finish()
3968    }
3969}
3970impl IterableOpGetneighDumpRequest<'_> {
3971    pub fn lookup_attr(
3972        &self,
3973        offset: usize,
3974        missing_type: Option<u16>,
3975    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3976        let mut stack = Vec::new();
3977        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3978        if cur == offset + PushNdmsg::len() {
3979            stack.push(("OpGetneighDumpRequest", offset));
3980            return (
3981                stack,
3982                missing_type.and_then(|t| OpGetneighDumpRequest::attr_from_type(t)),
3983            );
3984        }
3985        if cur > offset || cur + self.buf.len() < offset {
3986            return (stack, None);
3987        }
3988        let mut attrs = self.clone();
3989        let mut last_off = cur + attrs.pos;
3990        while let Some(attr) = attrs.next() {
3991            let Ok(attr) = attr else { break };
3992            match attr {
3993                OpGetneighDumpRequest::Ifindex(val) => {
3994                    if last_off == offset {
3995                        stack.push(("Ifindex", last_off));
3996                        break;
3997                    }
3998                }
3999                OpGetneighDumpRequest::Master(val) => {
4000                    if last_off == offset {
4001                        stack.push(("Master", last_off));
4002                        break;
4003                    }
4004                }
4005                _ => {}
4006            };
4007            last_off = cur + attrs.pos;
4008        }
4009        if !stack.is_empty() {
4010            stack.push(("OpGetneighDumpRequest", cur));
4011        }
4012        (stack, None)
4013    }
4014}
4015#[doc = "Get or dump neighbour entries"]
4016pub struct PushOpGetneighDumpReply<Prev: Rec> {
4017    pub(crate) prev: Option<Prev>,
4018    pub(crate) header_offset: Option<usize>,
4019}
4020impl<Prev: Rec> Rec for PushOpGetneighDumpReply<Prev> {
4021    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
4022        self.prev.as_mut().unwrap().as_rec_mut()
4023    }
4024    fn as_rec(&self) -> &Vec<u8> {
4025        self.prev.as_ref().unwrap().as_rec()
4026    }
4027}
4028impl<Prev: Rec> PushOpGetneighDumpReply<Prev> {
4029    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
4030        Self::write_header(&mut prev, header);
4031        Self::new_without_header(prev)
4032    }
4033    fn new_without_header(prev: Prev) -> Self {
4034        Self {
4035            prev: Some(prev),
4036            header_offset: None,
4037        }
4038    }
4039    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
4040        prev.as_rec_mut().extend(header.as_slice());
4041    }
4042    pub fn end_nested(mut self) -> Prev {
4043        let mut prev = self.prev.take().unwrap();
4044        if let Some(header_offset) = &self.header_offset {
4045            finalize_nested_header(prev.as_rec_mut(), *header_offset);
4046        }
4047        prev
4048    }
4049    pub fn push_dst(mut self, value: &[u8]) -> Self {
4050        push_header(self.as_rec_mut(), 1u16, value.len() as u16);
4051        self.as_rec_mut().extend(value);
4052        self
4053    }
4054    pub fn push_lladdr(mut self, value: &[u8]) -> Self {
4055        push_header(self.as_rec_mut(), 2u16, value.len() as u16);
4056        self.as_rec_mut().extend(value);
4057        self
4058    }
4059    pub fn push_probes(mut self, value: u32) -> Self {
4060        push_header(self.as_rec_mut(), 4u16, 4 as u16);
4061        self.as_rec_mut().extend(value.to_ne_bytes());
4062        self
4063    }
4064    pub fn push_vlan(mut self, value: u16) -> Self {
4065        push_header(self.as_rec_mut(), 5u16, 2 as u16);
4066        self.as_rec_mut().extend(value.to_ne_bytes());
4067        self
4068    }
4069    pub fn push_port(mut self, value: u16) -> Self {
4070        push_header(self.as_rec_mut(), 6u16, 2 as u16);
4071        self.as_rec_mut().extend(value.to_ne_bytes());
4072        self
4073    }
4074    pub fn push_vni(mut self, value: u32) -> Self {
4075        push_header(self.as_rec_mut(), 7u16, 4 as u16);
4076        self.as_rec_mut().extend(value.to_ne_bytes());
4077        self
4078    }
4079    pub fn push_ifindex(mut self, value: u32) -> Self {
4080        push_header(self.as_rec_mut(), 8u16, 4 as u16);
4081        self.as_rec_mut().extend(value.to_ne_bytes());
4082        self
4083    }
4084    pub fn push_master(mut self, value: u32) -> Self {
4085        push_header(self.as_rec_mut(), 9u16, 4 as u16);
4086        self.as_rec_mut().extend(value.to_ne_bytes());
4087        self
4088    }
4089    pub fn push_protocol(mut self, value: u8) -> Self {
4090        push_header(self.as_rec_mut(), 12u16, 1 as u16);
4091        self.as_rec_mut().extend(value.to_ne_bytes());
4092        self
4093    }
4094    pub fn push_nh_id(mut self, value: u32) -> Self {
4095        push_header(self.as_rec_mut(), 13u16, 4 as u16);
4096        self.as_rec_mut().extend(value.to_ne_bytes());
4097        self
4098    }
4099    pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
4100        push_header(self.as_rec_mut(), 14u16, value.len() as u16);
4101        self.as_rec_mut().extend(value);
4102        self
4103    }
4104    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4105    pub fn push_flags_ext(mut self, value: u32) -> Self {
4106        push_header(self.as_rec_mut(), 15u16, 4 as u16);
4107        self.as_rec_mut().extend(value.to_ne_bytes());
4108        self
4109    }
4110}
4111impl<Prev: Rec> Drop for PushOpGetneighDumpReply<Prev> {
4112    fn drop(&mut self) {
4113        if let Some(prev) = &mut self.prev {
4114            if let Some(header_offset) = &self.header_offset {
4115                finalize_nested_header(prev.as_rec_mut(), *header_offset);
4116            }
4117        }
4118    }
4119}
4120#[doc = "Get or dump neighbour entries"]
4121#[derive(Clone)]
4122pub enum OpGetneighDumpReply<'a> {
4123    Dst(&'a [u8]),
4124    Lladdr(&'a [u8]),
4125    Probes(u32),
4126    Vlan(u16),
4127    Port(u16),
4128    Vni(u32),
4129    Ifindex(u32),
4130    Master(u32),
4131    Protocol(u8),
4132    NhId(u32),
4133    FdbExtAttrs(&'a [u8]),
4134    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4135    FlagsExt(u32),
4136}
4137impl<'a> IterableOpGetneighDumpReply<'a> {
4138    pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4139        let mut iter = self.clone();
4140        iter.pos = 0;
4141        for attr in iter {
4142            if let OpGetneighDumpReply::Dst(val) = attr? {
4143                return Ok(val);
4144            }
4145        }
4146        Err(ErrorContext::new_missing(
4147            "OpGetneighDumpReply",
4148            "Dst",
4149            self.orig_loc,
4150            self.buf.as_ptr() as usize,
4151        ))
4152    }
4153    pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
4154        let mut iter = self.clone();
4155        iter.pos = 0;
4156        for attr in iter {
4157            if let OpGetneighDumpReply::Lladdr(val) = attr? {
4158                return Ok(val);
4159            }
4160        }
4161        Err(ErrorContext::new_missing(
4162            "OpGetneighDumpReply",
4163            "Lladdr",
4164            self.orig_loc,
4165            self.buf.as_ptr() as usize,
4166        ))
4167    }
4168    pub fn get_probes(&self) -> Result<u32, ErrorContext> {
4169        let mut iter = self.clone();
4170        iter.pos = 0;
4171        for attr in iter {
4172            if let OpGetneighDumpReply::Probes(val) = attr? {
4173                return Ok(val);
4174            }
4175        }
4176        Err(ErrorContext::new_missing(
4177            "OpGetneighDumpReply",
4178            "Probes",
4179            self.orig_loc,
4180            self.buf.as_ptr() as usize,
4181        ))
4182    }
4183    pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
4184        let mut iter = self.clone();
4185        iter.pos = 0;
4186        for attr in iter {
4187            if let OpGetneighDumpReply::Vlan(val) = attr? {
4188                return Ok(val);
4189            }
4190        }
4191        Err(ErrorContext::new_missing(
4192            "OpGetneighDumpReply",
4193            "Vlan",
4194            self.orig_loc,
4195            self.buf.as_ptr() as usize,
4196        ))
4197    }
4198    pub fn get_port(&self) -> Result<u16, ErrorContext> {
4199        let mut iter = self.clone();
4200        iter.pos = 0;
4201        for attr in iter {
4202            if let OpGetneighDumpReply::Port(val) = attr? {
4203                return Ok(val);
4204            }
4205        }
4206        Err(ErrorContext::new_missing(
4207            "OpGetneighDumpReply",
4208            "Port",
4209            self.orig_loc,
4210            self.buf.as_ptr() as usize,
4211        ))
4212    }
4213    pub fn get_vni(&self) -> Result<u32, ErrorContext> {
4214        let mut iter = self.clone();
4215        iter.pos = 0;
4216        for attr in iter {
4217            if let OpGetneighDumpReply::Vni(val) = attr? {
4218                return Ok(val);
4219            }
4220        }
4221        Err(ErrorContext::new_missing(
4222            "OpGetneighDumpReply",
4223            "Vni",
4224            self.orig_loc,
4225            self.buf.as_ptr() as usize,
4226        ))
4227    }
4228    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
4229        let mut iter = self.clone();
4230        iter.pos = 0;
4231        for attr in iter {
4232            if let OpGetneighDumpReply::Ifindex(val) = attr? {
4233                return Ok(val);
4234            }
4235        }
4236        Err(ErrorContext::new_missing(
4237            "OpGetneighDumpReply",
4238            "Ifindex",
4239            self.orig_loc,
4240            self.buf.as_ptr() as usize,
4241        ))
4242    }
4243    pub fn get_master(&self) -> Result<u32, ErrorContext> {
4244        let mut iter = self.clone();
4245        iter.pos = 0;
4246        for attr in iter {
4247            if let OpGetneighDumpReply::Master(val) = attr? {
4248                return Ok(val);
4249            }
4250        }
4251        Err(ErrorContext::new_missing(
4252            "OpGetneighDumpReply",
4253            "Master",
4254            self.orig_loc,
4255            self.buf.as_ptr() as usize,
4256        ))
4257    }
4258    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
4259        let mut iter = self.clone();
4260        iter.pos = 0;
4261        for attr in iter {
4262            if let OpGetneighDumpReply::Protocol(val) = attr? {
4263                return Ok(val);
4264            }
4265        }
4266        Err(ErrorContext::new_missing(
4267            "OpGetneighDumpReply",
4268            "Protocol",
4269            self.orig_loc,
4270            self.buf.as_ptr() as usize,
4271        ))
4272    }
4273    pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
4274        let mut iter = self.clone();
4275        iter.pos = 0;
4276        for attr in iter {
4277            if let OpGetneighDumpReply::NhId(val) = attr? {
4278                return Ok(val);
4279            }
4280        }
4281        Err(ErrorContext::new_missing(
4282            "OpGetneighDumpReply",
4283            "NhId",
4284            self.orig_loc,
4285            self.buf.as_ptr() as usize,
4286        ))
4287    }
4288    pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
4289        let mut iter = self.clone();
4290        iter.pos = 0;
4291        for attr in iter {
4292            if let OpGetneighDumpReply::FdbExtAttrs(val) = attr? {
4293                return Ok(val);
4294            }
4295        }
4296        Err(ErrorContext::new_missing(
4297            "OpGetneighDumpReply",
4298            "FdbExtAttrs",
4299            self.orig_loc,
4300            self.buf.as_ptr() as usize,
4301        ))
4302    }
4303    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4304    pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
4305        let mut iter = self.clone();
4306        iter.pos = 0;
4307        for attr in iter {
4308            if let OpGetneighDumpReply::FlagsExt(val) = attr? {
4309                return Ok(val);
4310            }
4311        }
4312        Err(ErrorContext::new_missing(
4313            "OpGetneighDumpReply",
4314            "FlagsExt",
4315            self.orig_loc,
4316            self.buf.as_ptr() as usize,
4317        ))
4318    }
4319}
4320impl OpGetneighDumpReply<'_> {
4321    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDumpReply<'a>) {
4322        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
4323        (
4324            PushNdmsg::new_from_slice(header).unwrap_or_default(),
4325            IterableOpGetneighDumpReply::with_loc(attrs, buf.as_ptr() as usize),
4326        )
4327    }
4328    fn attr_from_type(r#type: u16) -> Option<&'static str> {
4329        NeighbourAttrs::attr_from_type(r#type)
4330    }
4331}
4332#[derive(Clone, Copy, Default)]
4333pub struct IterableOpGetneighDumpReply<'a> {
4334    buf: &'a [u8],
4335    pos: usize,
4336    orig_loc: usize,
4337}
4338impl<'a> IterableOpGetneighDumpReply<'a> {
4339    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4340        Self {
4341            buf,
4342            pos: 0,
4343            orig_loc,
4344        }
4345    }
4346    pub fn get_buf(&self) -> &'a [u8] {
4347        self.buf
4348    }
4349}
4350impl<'a> Iterator for IterableOpGetneighDumpReply<'a> {
4351    type Item = Result<OpGetneighDumpReply<'a>, ErrorContext>;
4352    fn next(&mut self) -> Option<Self::Item> {
4353        let pos = self.pos;
4354        let mut r#type;
4355        loop {
4356            r#type = None;
4357            if self.buf.len() == self.pos {
4358                return None;
4359            }
4360            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4361                break;
4362            };
4363            r#type = Some(header.r#type);
4364            let res = match header.r#type {
4365                1u16 => OpGetneighDumpReply::Dst({
4366                    let res = Some(next);
4367                    let Some(val) = res else { break };
4368                    val
4369                }),
4370                2u16 => OpGetneighDumpReply::Lladdr({
4371                    let res = Some(next);
4372                    let Some(val) = res else { break };
4373                    val
4374                }),
4375                4u16 => OpGetneighDumpReply::Probes({
4376                    let res = parse_u32(next);
4377                    let Some(val) = res else { break };
4378                    val
4379                }),
4380                5u16 => OpGetneighDumpReply::Vlan({
4381                    let res = parse_u16(next);
4382                    let Some(val) = res else { break };
4383                    val
4384                }),
4385                6u16 => OpGetneighDumpReply::Port({
4386                    let res = parse_u16(next);
4387                    let Some(val) = res else { break };
4388                    val
4389                }),
4390                7u16 => OpGetneighDumpReply::Vni({
4391                    let res = parse_u32(next);
4392                    let Some(val) = res else { break };
4393                    val
4394                }),
4395                8u16 => OpGetneighDumpReply::Ifindex({
4396                    let res = parse_u32(next);
4397                    let Some(val) = res else { break };
4398                    val
4399                }),
4400                9u16 => OpGetneighDumpReply::Master({
4401                    let res = parse_u32(next);
4402                    let Some(val) = res else { break };
4403                    val
4404                }),
4405                12u16 => OpGetneighDumpReply::Protocol({
4406                    let res = parse_u8(next);
4407                    let Some(val) = res else { break };
4408                    val
4409                }),
4410                13u16 => OpGetneighDumpReply::NhId({
4411                    let res = parse_u32(next);
4412                    let Some(val) = res else { break };
4413                    val
4414                }),
4415                14u16 => OpGetneighDumpReply::FdbExtAttrs({
4416                    let res = Some(next);
4417                    let Some(val) = res else { break };
4418                    val
4419                }),
4420                15u16 => OpGetneighDumpReply::FlagsExt({
4421                    let res = parse_u32(next);
4422                    let Some(val) = res else { break };
4423                    val
4424                }),
4425                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4426                n => continue,
4427            };
4428            return Some(Ok(res));
4429        }
4430        Some(Err(ErrorContext::new(
4431            "OpGetneighDumpReply",
4432            r#type.and_then(|t| OpGetneighDumpReply::attr_from_type(t)),
4433            self.orig_loc,
4434            self.buf.as_ptr().wrapping_add(pos) as usize,
4435        )))
4436    }
4437}
4438impl<'a> std::fmt::Debug for IterableOpGetneighDumpReply<'_> {
4439    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4440        let mut fmt = f.debug_struct("OpGetneighDumpReply");
4441        for attr in self.clone() {
4442            let attr = match attr {
4443                Ok(a) => a,
4444                Err(err) => {
4445                    fmt.finish()?;
4446                    f.write_str("Err(")?;
4447                    err.fmt(f)?;
4448                    return f.write_str(")");
4449                }
4450            };
4451            match attr {
4452                OpGetneighDumpReply::Dst(val) => fmt.field("Dst", &val),
4453                OpGetneighDumpReply::Lladdr(val) => fmt.field("Lladdr", &val),
4454                OpGetneighDumpReply::Probes(val) => fmt.field("Probes", &val),
4455                OpGetneighDumpReply::Vlan(val) => fmt.field("Vlan", &val),
4456                OpGetneighDumpReply::Port(val) => fmt.field("Port", &val),
4457                OpGetneighDumpReply::Vni(val) => fmt.field("Vni", &val),
4458                OpGetneighDumpReply::Ifindex(val) => fmt.field("Ifindex", &val),
4459                OpGetneighDumpReply::Master(val) => fmt.field("Master", &val),
4460                OpGetneighDumpReply::Protocol(val) => fmt.field("Protocol", &val),
4461                OpGetneighDumpReply::NhId(val) => fmt.field("NhId", &val),
4462                OpGetneighDumpReply::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
4463                OpGetneighDumpReply::FlagsExt(val) => fmt.field(
4464                    "FlagsExt",
4465                    &FormatFlags(val.into(), NtfExtFlags::from_value),
4466                ),
4467            };
4468        }
4469        fmt.finish()
4470    }
4471}
4472impl IterableOpGetneighDumpReply<'_> {
4473    pub fn lookup_attr(
4474        &self,
4475        offset: usize,
4476        missing_type: Option<u16>,
4477    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4478        let mut stack = Vec::new();
4479        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4480        if cur == offset + PushNdmsg::len() {
4481            stack.push(("OpGetneighDumpReply", offset));
4482            return (
4483                stack,
4484                missing_type.and_then(|t| OpGetneighDumpReply::attr_from_type(t)),
4485            );
4486        }
4487        if cur > offset || cur + self.buf.len() < offset {
4488            return (stack, None);
4489        }
4490        let mut attrs = self.clone();
4491        let mut last_off = cur + attrs.pos;
4492        while let Some(attr) = attrs.next() {
4493            let Ok(attr) = attr else { break };
4494            match attr {
4495                OpGetneighDumpReply::Dst(val) => {
4496                    if last_off == offset {
4497                        stack.push(("Dst", last_off));
4498                        break;
4499                    }
4500                }
4501                OpGetneighDumpReply::Lladdr(val) => {
4502                    if last_off == offset {
4503                        stack.push(("Lladdr", last_off));
4504                        break;
4505                    }
4506                }
4507                OpGetneighDumpReply::Probes(val) => {
4508                    if last_off == offset {
4509                        stack.push(("Probes", last_off));
4510                        break;
4511                    }
4512                }
4513                OpGetneighDumpReply::Vlan(val) => {
4514                    if last_off == offset {
4515                        stack.push(("Vlan", last_off));
4516                        break;
4517                    }
4518                }
4519                OpGetneighDumpReply::Port(val) => {
4520                    if last_off == offset {
4521                        stack.push(("Port", last_off));
4522                        break;
4523                    }
4524                }
4525                OpGetneighDumpReply::Vni(val) => {
4526                    if last_off == offset {
4527                        stack.push(("Vni", last_off));
4528                        break;
4529                    }
4530                }
4531                OpGetneighDumpReply::Ifindex(val) => {
4532                    if last_off == offset {
4533                        stack.push(("Ifindex", last_off));
4534                        break;
4535                    }
4536                }
4537                OpGetneighDumpReply::Master(val) => {
4538                    if last_off == offset {
4539                        stack.push(("Master", last_off));
4540                        break;
4541                    }
4542                }
4543                OpGetneighDumpReply::Protocol(val) => {
4544                    if last_off == offset {
4545                        stack.push(("Protocol", last_off));
4546                        break;
4547                    }
4548                }
4549                OpGetneighDumpReply::NhId(val) => {
4550                    if last_off == offset {
4551                        stack.push(("NhId", last_off));
4552                        break;
4553                    }
4554                }
4555                OpGetneighDumpReply::FdbExtAttrs(val) => {
4556                    if last_off == offset {
4557                        stack.push(("FdbExtAttrs", last_off));
4558                        break;
4559                    }
4560                }
4561                OpGetneighDumpReply::FlagsExt(val) => {
4562                    if last_off == offset {
4563                        stack.push(("FlagsExt", last_off));
4564                        break;
4565                    }
4566                }
4567                _ => {}
4568            };
4569            last_off = cur + attrs.pos;
4570        }
4571        if !stack.is_empty() {
4572            stack.push(("OpGetneighDumpReply", cur));
4573        }
4574        (stack, None)
4575    }
4576}
4577#[derive(Debug)]
4578pub struct RequestOpGetneighDumpRequest<'r> {
4579    request: Request<'r>,
4580}
4581impl<'r> RequestOpGetneighDumpRequest<'r> {
4582    pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
4583        PushOpGetneighDumpRequest::write_header(&mut request.buf_mut(), header);
4584        Self {
4585            request: request.set_dump(),
4586        }
4587    }
4588    pub fn encode(&mut self) -> PushOpGetneighDumpRequest<&mut Vec<u8>> {
4589        PushOpGetneighDumpRequest::new_without_header(self.request.buf_mut())
4590    }
4591    pub fn into_encoder(self) -> PushOpGetneighDumpRequest<RequestBuf<'r>> {
4592        PushOpGetneighDumpRequest::new_without_header(self.request.buf)
4593    }
4594    pub fn decode_request<'buf>(
4595        buf: &'buf [u8],
4596    ) -> (PushNdmsg, IterableOpGetneighDumpRequest<'buf>) {
4597        OpGetneighDumpRequest::new(buf)
4598    }
4599}
4600impl NetlinkRequest for RequestOpGetneighDumpRequest<'_> {
4601    fn protocol(&self) -> Protocol {
4602        Protocol::Raw {
4603            protonum: 0u16,
4604            request_type: 30u16,
4605        }
4606    }
4607    fn flags(&self) -> u16 {
4608        self.request.flags
4609    }
4610    fn payload(&self) -> &[u8] {
4611        self.request.buf()
4612    }
4613    type ReplyType<'buf> = (PushNdmsg, IterableOpGetneighDumpReply<'buf>);
4614    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
4615        OpGetneighDumpReply::new(buf)
4616    }
4617    fn lookup(
4618        buf: &[u8],
4619        offset: usize,
4620        missing_type: Option<u16>,
4621    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4622        OpGetneighDumpRequest::new(buf)
4623            .1
4624            .lookup_attr(offset, missing_type)
4625    }
4626}
4627#[doc = "Get or dump neighbour entries"]
4628pub struct PushOpGetneighDoRequest<Prev: Rec> {
4629    pub(crate) prev: Option<Prev>,
4630    pub(crate) header_offset: Option<usize>,
4631}
4632impl<Prev: Rec> Rec for PushOpGetneighDoRequest<Prev> {
4633    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
4634        self.prev.as_mut().unwrap().as_rec_mut()
4635    }
4636    fn as_rec(&self) -> &Vec<u8> {
4637        self.prev.as_ref().unwrap().as_rec()
4638    }
4639}
4640impl<Prev: Rec> PushOpGetneighDoRequest<Prev> {
4641    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
4642        Self::write_header(&mut prev, header);
4643        Self::new_without_header(prev)
4644    }
4645    fn new_without_header(prev: Prev) -> Self {
4646        Self {
4647            prev: Some(prev),
4648            header_offset: None,
4649        }
4650    }
4651    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
4652        prev.as_rec_mut().extend(header.as_slice());
4653    }
4654    pub fn end_nested(mut self) -> Prev {
4655        let mut prev = self.prev.take().unwrap();
4656        if let Some(header_offset) = &self.header_offset {
4657            finalize_nested_header(prev.as_rec_mut(), *header_offset);
4658        }
4659        prev
4660    }
4661    pub fn push_dst(mut self, value: &[u8]) -> Self {
4662        push_header(self.as_rec_mut(), 1u16, value.len() as u16);
4663        self.as_rec_mut().extend(value);
4664        self
4665    }
4666}
4667impl<Prev: Rec> Drop for PushOpGetneighDoRequest<Prev> {
4668    fn drop(&mut self) {
4669        if let Some(prev) = &mut self.prev {
4670            if let Some(header_offset) = &self.header_offset {
4671                finalize_nested_header(prev.as_rec_mut(), *header_offset);
4672            }
4673        }
4674    }
4675}
4676#[doc = "Get or dump neighbour entries"]
4677#[derive(Clone)]
4678pub enum OpGetneighDoRequest<'a> {
4679    Dst(&'a [u8]),
4680}
4681impl<'a> IterableOpGetneighDoRequest<'a> {
4682    pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4683        let mut iter = self.clone();
4684        iter.pos = 0;
4685        for attr in iter {
4686            if let OpGetneighDoRequest::Dst(val) = attr? {
4687                return Ok(val);
4688            }
4689        }
4690        Err(ErrorContext::new_missing(
4691            "OpGetneighDoRequest",
4692            "Dst",
4693            self.orig_loc,
4694            self.buf.as_ptr() as usize,
4695        ))
4696    }
4697}
4698impl OpGetneighDoRequest<'_> {
4699    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDoRequest<'a>) {
4700        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
4701        (
4702            PushNdmsg::new_from_slice(header).unwrap_or_default(),
4703            IterableOpGetneighDoRequest::with_loc(attrs, buf.as_ptr() as usize),
4704        )
4705    }
4706    fn attr_from_type(r#type: u16) -> Option<&'static str> {
4707        NeighbourAttrs::attr_from_type(r#type)
4708    }
4709}
4710#[derive(Clone, Copy, Default)]
4711pub struct IterableOpGetneighDoRequest<'a> {
4712    buf: &'a [u8],
4713    pos: usize,
4714    orig_loc: usize,
4715}
4716impl<'a> IterableOpGetneighDoRequest<'a> {
4717    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4718        Self {
4719            buf,
4720            pos: 0,
4721            orig_loc,
4722        }
4723    }
4724    pub fn get_buf(&self) -> &'a [u8] {
4725        self.buf
4726    }
4727}
4728impl<'a> Iterator for IterableOpGetneighDoRequest<'a> {
4729    type Item = Result<OpGetneighDoRequest<'a>, ErrorContext>;
4730    fn next(&mut self) -> Option<Self::Item> {
4731        let pos = self.pos;
4732        let mut r#type;
4733        loop {
4734            r#type = None;
4735            if self.buf.len() == self.pos {
4736                return None;
4737            }
4738            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4739                break;
4740            };
4741            r#type = Some(header.r#type);
4742            let res = match header.r#type {
4743                1u16 => OpGetneighDoRequest::Dst({
4744                    let res = Some(next);
4745                    let Some(val) = res else { break };
4746                    val
4747                }),
4748                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4749                n => continue,
4750            };
4751            return Some(Ok(res));
4752        }
4753        Some(Err(ErrorContext::new(
4754            "OpGetneighDoRequest",
4755            r#type.and_then(|t| OpGetneighDoRequest::attr_from_type(t)),
4756            self.orig_loc,
4757            self.buf.as_ptr().wrapping_add(pos) as usize,
4758        )))
4759    }
4760}
4761impl<'a> std::fmt::Debug for IterableOpGetneighDoRequest<'_> {
4762    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4763        let mut fmt = f.debug_struct("OpGetneighDoRequest");
4764        for attr in self.clone() {
4765            let attr = match attr {
4766                Ok(a) => a,
4767                Err(err) => {
4768                    fmt.finish()?;
4769                    f.write_str("Err(")?;
4770                    err.fmt(f)?;
4771                    return f.write_str(")");
4772                }
4773            };
4774            match attr {
4775                OpGetneighDoRequest::Dst(val) => fmt.field("Dst", &val),
4776            };
4777        }
4778        fmt.finish()
4779    }
4780}
4781impl IterableOpGetneighDoRequest<'_> {
4782    pub fn lookup_attr(
4783        &self,
4784        offset: usize,
4785        missing_type: Option<u16>,
4786    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4787        let mut stack = Vec::new();
4788        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4789        if cur == offset + PushNdmsg::len() {
4790            stack.push(("OpGetneighDoRequest", offset));
4791            return (
4792                stack,
4793                missing_type.and_then(|t| OpGetneighDoRequest::attr_from_type(t)),
4794            );
4795        }
4796        if cur > offset || cur + self.buf.len() < offset {
4797            return (stack, None);
4798        }
4799        let mut attrs = self.clone();
4800        let mut last_off = cur + attrs.pos;
4801        while let Some(attr) = attrs.next() {
4802            let Ok(attr) = attr else { break };
4803            match attr {
4804                OpGetneighDoRequest::Dst(val) => {
4805                    if last_off == offset {
4806                        stack.push(("Dst", last_off));
4807                        break;
4808                    }
4809                }
4810                _ => {}
4811            };
4812            last_off = cur + attrs.pos;
4813        }
4814        if !stack.is_empty() {
4815            stack.push(("OpGetneighDoRequest", cur));
4816        }
4817        (stack, None)
4818    }
4819}
4820#[doc = "Get or dump neighbour entries"]
4821pub struct PushOpGetneighDoReply<Prev: Rec> {
4822    pub(crate) prev: Option<Prev>,
4823    pub(crate) header_offset: Option<usize>,
4824}
4825impl<Prev: Rec> Rec for PushOpGetneighDoReply<Prev> {
4826    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
4827        self.prev.as_mut().unwrap().as_rec_mut()
4828    }
4829    fn as_rec(&self) -> &Vec<u8> {
4830        self.prev.as_ref().unwrap().as_rec()
4831    }
4832}
4833impl<Prev: Rec> PushOpGetneighDoReply<Prev> {
4834    pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
4835        Self::write_header(&mut prev, header);
4836        Self::new_without_header(prev)
4837    }
4838    fn new_without_header(prev: Prev) -> Self {
4839        Self {
4840            prev: Some(prev),
4841            header_offset: None,
4842        }
4843    }
4844    fn write_header(prev: &mut Prev, header: &PushNdmsg) {
4845        prev.as_rec_mut().extend(header.as_slice());
4846    }
4847    pub fn end_nested(mut self) -> Prev {
4848        let mut prev = self.prev.take().unwrap();
4849        if let Some(header_offset) = &self.header_offset {
4850            finalize_nested_header(prev.as_rec_mut(), *header_offset);
4851        }
4852        prev
4853    }
4854    pub fn push_dst(mut self, value: &[u8]) -> Self {
4855        push_header(self.as_rec_mut(), 1u16, value.len() as u16);
4856        self.as_rec_mut().extend(value);
4857        self
4858    }
4859    pub fn push_lladdr(mut self, value: &[u8]) -> Self {
4860        push_header(self.as_rec_mut(), 2u16, value.len() as u16);
4861        self.as_rec_mut().extend(value);
4862        self
4863    }
4864    pub fn push_probes(mut self, value: u32) -> Self {
4865        push_header(self.as_rec_mut(), 4u16, 4 as u16);
4866        self.as_rec_mut().extend(value.to_ne_bytes());
4867        self
4868    }
4869    pub fn push_vlan(mut self, value: u16) -> Self {
4870        push_header(self.as_rec_mut(), 5u16, 2 as u16);
4871        self.as_rec_mut().extend(value.to_ne_bytes());
4872        self
4873    }
4874    pub fn push_port(mut self, value: u16) -> Self {
4875        push_header(self.as_rec_mut(), 6u16, 2 as u16);
4876        self.as_rec_mut().extend(value.to_ne_bytes());
4877        self
4878    }
4879    pub fn push_vni(mut self, value: u32) -> Self {
4880        push_header(self.as_rec_mut(), 7u16, 4 as u16);
4881        self.as_rec_mut().extend(value.to_ne_bytes());
4882        self
4883    }
4884    pub fn push_ifindex(mut self, value: u32) -> Self {
4885        push_header(self.as_rec_mut(), 8u16, 4 as u16);
4886        self.as_rec_mut().extend(value.to_ne_bytes());
4887        self
4888    }
4889    pub fn push_master(mut self, value: u32) -> Self {
4890        push_header(self.as_rec_mut(), 9u16, 4 as u16);
4891        self.as_rec_mut().extend(value.to_ne_bytes());
4892        self
4893    }
4894    pub fn push_protocol(mut self, value: u8) -> Self {
4895        push_header(self.as_rec_mut(), 12u16, 1 as u16);
4896        self.as_rec_mut().extend(value.to_ne_bytes());
4897        self
4898    }
4899    pub fn push_nh_id(mut self, value: u32) -> Self {
4900        push_header(self.as_rec_mut(), 13u16, 4 as u16);
4901        self.as_rec_mut().extend(value.to_ne_bytes());
4902        self
4903    }
4904    pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
4905        push_header(self.as_rec_mut(), 14u16, value.len() as u16);
4906        self.as_rec_mut().extend(value);
4907        self
4908    }
4909    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4910    pub fn push_flags_ext(mut self, value: u32) -> Self {
4911        push_header(self.as_rec_mut(), 15u16, 4 as u16);
4912        self.as_rec_mut().extend(value.to_ne_bytes());
4913        self
4914    }
4915}
4916impl<Prev: Rec> Drop for PushOpGetneighDoReply<Prev> {
4917    fn drop(&mut self) {
4918        if let Some(prev) = &mut self.prev {
4919            if let Some(header_offset) = &self.header_offset {
4920                finalize_nested_header(prev.as_rec_mut(), *header_offset);
4921            }
4922        }
4923    }
4924}
4925#[doc = "Get or dump neighbour entries"]
4926#[derive(Clone)]
4927pub enum OpGetneighDoReply<'a> {
4928    Dst(&'a [u8]),
4929    Lladdr(&'a [u8]),
4930    Probes(u32),
4931    Vlan(u16),
4932    Port(u16),
4933    Vni(u32),
4934    Ifindex(u32),
4935    Master(u32),
4936    Protocol(u8),
4937    NhId(u32),
4938    FdbExtAttrs(&'a [u8]),
4939    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4940    FlagsExt(u32),
4941}
4942impl<'a> IterableOpGetneighDoReply<'a> {
4943    pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4944        let mut iter = self.clone();
4945        iter.pos = 0;
4946        for attr in iter {
4947            if let OpGetneighDoReply::Dst(val) = attr? {
4948                return Ok(val);
4949            }
4950        }
4951        Err(ErrorContext::new_missing(
4952            "OpGetneighDoReply",
4953            "Dst",
4954            self.orig_loc,
4955            self.buf.as_ptr() as usize,
4956        ))
4957    }
4958    pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
4959        let mut iter = self.clone();
4960        iter.pos = 0;
4961        for attr in iter {
4962            if let OpGetneighDoReply::Lladdr(val) = attr? {
4963                return Ok(val);
4964            }
4965        }
4966        Err(ErrorContext::new_missing(
4967            "OpGetneighDoReply",
4968            "Lladdr",
4969            self.orig_loc,
4970            self.buf.as_ptr() as usize,
4971        ))
4972    }
4973    pub fn get_probes(&self) -> Result<u32, ErrorContext> {
4974        let mut iter = self.clone();
4975        iter.pos = 0;
4976        for attr in iter {
4977            if let OpGetneighDoReply::Probes(val) = attr? {
4978                return Ok(val);
4979            }
4980        }
4981        Err(ErrorContext::new_missing(
4982            "OpGetneighDoReply",
4983            "Probes",
4984            self.orig_loc,
4985            self.buf.as_ptr() as usize,
4986        ))
4987    }
4988    pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
4989        let mut iter = self.clone();
4990        iter.pos = 0;
4991        for attr in iter {
4992            if let OpGetneighDoReply::Vlan(val) = attr? {
4993                return Ok(val);
4994            }
4995        }
4996        Err(ErrorContext::new_missing(
4997            "OpGetneighDoReply",
4998            "Vlan",
4999            self.orig_loc,
5000            self.buf.as_ptr() as usize,
5001        ))
5002    }
5003    pub fn get_port(&self) -> Result<u16, ErrorContext> {
5004        let mut iter = self.clone();
5005        iter.pos = 0;
5006        for attr in iter {
5007            if let OpGetneighDoReply::Port(val) = attr? {
5008                return Ok(val);
5009            }
5010        }
5011        Err(ErrorContext::new_missing(
5012            "OpGetneighDoReply",
5013            "Port",
5014            self.orig_loc,
5015            self.buf.as_ptr() as usize,
5016        ))
5017    }
5018    pub fn get_vni(&self) -> Result<u32, ErrorContext> {
5019        let mut iter = self.clone();
5020        iter.pos = 0;
5021        for attr in iter {
5022            if let OpGetneighDoReply::Vni(val) = attr? {
5023                return Ok(val);
5024            }
5025        }
5026        Err(ErrorContext::new_missing(
5027            "OpGetneighDoReply",
5028            "Vni",
5029            self.orig_loc,
5030            self.buf.as_ptr() as usize,
5031        ))
5032    }
5033    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
5034        let mut iter = self.clone();
5035        iter.pos = 0;
5036        for attr in iter {
5037            if let OpGetneighDoReply::Ifindex(val) = attr? {
5038                return Ok(val);
5039            }
5040        }
5041        Err(ErrorContext::new_missing(
5042            "OpGetneighDoReply",
5043            "Ifindex",
5044            self.orig_loc,
5045            self.buf.as_ptr() as usize,
5046        ))
5047    }
5048    pub fn get_master(&self) -> Result<u32, ErrorContext> {
5049        let mut iter = self.clone();
5050        iter.pos = 0;
5051        for attr in iter {
5052            if let OpGetneighDoReply::Master(val) = attr? {
5053                return Ok(val);
5054            }
5055        }
5056        Err(ErrorContext::new_missing(
5057            "OpGetneighDoReply",
5058            "Master",
5059            self.orig_loc,
5060            self.buf.as_ptr() as usize,
5061        ))
5062    }
5063    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
5064        let mut iter = self.clone();
5065        iter.pos = 0;
5066        for attr in iter {
5067            if let OpGetneighDoReply::Protocol(val) = attr? {
5068                return Ok(val);
5069            }
5070        }
5071        Err(ErrorContext::new_missing(
5072            "OpGetneighDoReply",
5073            "Protocol",
5074            self.orig_loc,
5075            self.buf.as_ptr() as usize,
5076        ))
5077    }
5078    pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
5079        let mut iter = self.clone();
5080        iter.pos = 0;
5081        for attr in iter {
5082            if let OpGetneighDoReply::NhId(val) = attr? {
5083                return Ok(val);
5084            }
5085        }
5086        Err(ErrorContext::new_missing(
5087            "OpGetneighDoReply",
5088            "NhId",
5089            self.orig_loc,
5090            self.buf.as_ptr() as usize,
5091        ))
5092    }
5093    pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
5094        let mut iter = self.clone();
5095        iter.pos = 0;
5096        for attr in iter {
5097            if let OpGetneighDoReply::FdbExtAttrs(val) = attr? {
5098                return Ok(val);
5099            }
5100        }
5101        Err(ErrorContext::new_missing(
5102            "OpGetneighDoReply",
5103            "FdbExtAttrs",
5104            self.orig_loc,
5105            self.buf.as_ptr() as usize,
5106        ))
5107    }
5108    #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
5109    pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
5110        let mut iter = self.clone();
5111        iter.pos = 0;
5112        for attr in iter {
5113            if let OpGetneighDoReply::FlagsExt(val) = attr? {
5114                return Ok(val);
5115            }
5116        }
5117        Err(ErrorContext::new_missing(
5118            "OpGetneighDoReply",
5119            "FlagsExt",
5120            self.orig_loc,
5121            self.buf.as_ptr() as usize,
5122        ))
5123    }
5124}
5125impl OpGetneighDoReply<'_> {
5126    pub fn new<'a>(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDoReply<'a>) {
5127        let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
5128        (
5129            PushNdmsg::new_from_slice(header).unwrap_or_default(),
5130            IterableOpGetneighDoReply::with_loc(attrs, buf.as_ptr() as usize),
5131        )
5132    }
5133    fn attr_from_type(r#type: u16) -> Option<&'static str> {
5134        NeighbourAttrs::attr_from_type(r#type)
5135    }
5136}
5137#[derive(Clone, Copy, Default)]
5138pub struct IterableOpGetneighDoReply<'a> {
5139    buf: &'a [u8],
5140    pos: usize,
5141    orig_loc: usize,
5142}
5143impl<'a> IterableOpGetneighDoReply<'a> {
5144    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5145        Self {
5146            buf,
5147            pos: 0,
5148            orig_loc,
5149        }
5150    }
5151    pub fn get_buf(&self) -> &'a [u8] {
5152        self.buf
5153    }
5154}
5155impl<'a> Iterator for IterableOpGetneighDoReply<'a> {
5156    type Item = Result<OpGetneighDoReply<'a>, ErrorContext>;
5157    fn next(&mut self) -> Option<Self::Item> {
5158        let pos = self.pos;
5159        let mut r#type;
5160        loop {
5161            r#type = None;
5162            if self.buf.len() == self.pos {
5163                return None;
5164            }
5165            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5166                break;
5167            };
5168            r#type = Some(header.r#type);
5169            let res = match header.r#type {
5170                1u16 => OpGetneighDoReply::Dst({
5171                    let res = Some(next);
5172                    let Some(val) = res else { break };
5173                    val
5174                }),
5175                2u16 => OpGetneighDoReply::Lladdr({
5176                    let res = Some(next);
5177                    let Some(val) = res else { break };
5178                    val
5179                }),
5180                4u16 => OpGetneighDoReply::Probes({
5181                    let res = parse_u32(next);
5182                    let Some(val) = res else { break };
5183                    val
5184                }),
5185                5u16 => OpGetneighDoReply::Vlan({
5186                    let res = parse_u16(next);
5187                    let Some(val) = res else { break };
5188                    val
5189                }),
5190                6u16 => OpGetneighDoReply::Port({
5191                    let res = parse_u16(next);
5192                    let Some(val) = res else { break };
5193                    val
5194                }),
5195                7u16 => OpGetneighDoReply::Vni({
5196                    let res = parse_u32(next);
5197                    let Some(val) = res else { break };
5198                    val
5199                }),
5200                8u16 => OpGetneighDoReply::Ifindex({
5201                    let res = parse_u32(next);
5202                    let Some(val) = res else { break };
5203                    val
5204                }),
5205                9u16 => OpGetneighDoReply::Master({
5206                    let res = parse_u32(next);
5207                    let Some(val) = res else { break };
5208                    val
5209                }),
5210                12u16 => OpGetneighDoReply::Protocol({
5211                    let res = parse_u8(next);
5212                    let Some(val) = res else { break };
5213                    val
5214                }),
5215                13u16 => OpGetneighDoReply::NhId({
5216                    let res = parse_u32(next);
5217                    let Some(val) = res else { break };
5218                    val
5219                }),
5220                14u16 => OpGetneighDoReply::FdbExtAttrs({
5221                    let res = Some(next);
5222                    let Some(val) = res else { break };
5223                    val
5224                }),
5225                15u16 => OpGetneighDoReply::FlagsExt({
5226                    let res = parse_u32(next);
5227                    let Some(val) = res else { break };
5228                    val
5229                }),
5230                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5231                n => continue,
5232            };
5233            return Some(Ok(res));
5234        }
5235        Some(Err(ErrorContext::new(
5236            "OpGetneighDoReply",
5237            r#type.and_then(|t| OpGetneighDoReply::attr_from_type(t)),
5238            self.orig_loc,
5239            self.buf.as_ptr().wrapping_add(pos) as usize,
5240        )))
5241    }
5242}
5243impl<'a> std::fmt::Debug for IterableOpGetneighDoReply<'_> {
5244    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5245        let mut fmt = f.debug_struct("OpGetneighDoReply");
5246        for attr in self.clone() {
5247            let attr = match attr {
5248                Ok(a) => a,
5249                Err(err) => {
5250                    fmt.finish()?;
5251                    f.write_str("Err(")?;
5252                    err.fmt(f)?;
5253                    return f.write_str(")");
5254                }
5255            };
5256            match attr {
5257                OpGetneighDoReply::Dst(val) => fmt.field("Dst", &val),
5258                OpGetneighDoReply::Lladdr(val) => fmt.field("Lladdr", &val),
5259                OpGetneighDoReply::Probes(val) => fmt.field("Probes", &val),
5260                OpGetneighDoReply::Vlan(val) => fmt.field("Vlan", &val),
5261                OpGetneighDoReply::Port(val) => fmt.field("Port", &val),
5262                OpGetneighDoReply::Vni(val) => fmt.field("Vni", &val),
5263                OpGetneighDoReply::Ifindex(val) => fmt.field("Ifindex", &val),
5264                OpGetneighDoReply::Master(val) => fmt.field("Master", &val),
5265                OpGetneighDoReply::Protocol(val) => fmt.field("Protocol", &val),
5266                OpGetneighDoReply::NhId(val) => fmt.field("NhId", &val),
5267                OpGetneighDoReply::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
5268                OpGetneighDoReply::FlagsExt(val) => fmt.field(
5269                    "FlagsExt",
5270                    &FormatFlags(val.into(), NtfExtFlags::from_value),
5271                ),
5272            };
5273        }
5274        fmt.finish()
5275    }
5276}
5277impl IterableOpGetneighDoReply<'_> {
5278    pub fn lookup_attr(
5279        &self,
5280        offset: usize,
5281        missing_type: Option<u16>,
5282    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5283        let mut stack = Vec::new();
5284        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5285        if cur == offset + PushNdmsg::len() {
5286            stack.push(("OpGetneighDoReply", offset));
5287            return (
5288                stack,
5289                missing_type.and_then(|t| OpGetneighDoReply::attr_from_type(t)),
5290            );
5291        }
5292        if cur > offset || cur + self.buf.len() < offset {
5293            return (stack, None);
5294        }
5295        let mut attrs = self.clone();
5296        let mut last_off = cur + attrs.pos;
5297        while let Some(attr) = attrs.next() {
5298            let Ok(attr) = attr else { break };
5299            match attr {
5300                OpGetneighDoReply::Dst(val) => {
5301                    if last_off == offset {
5302                        stack.push(("Dst", last_off));
5303                        break;
5304                    }
5305                }
5306                OpGetneighDoReply::Lladdr(val) => {
5307                    if last_off == offset {
5308                        stack.push(("Lladdr", last_off));
5309                        break;
5310                    }
5311                }
5312                OpGetneighDoReply::Probes(val) => {
5313                    if last_off == offset {
5314                        stack.push(("Probes", last_off));
5315                        break;
5316                    }
5317                }
5318                OpGetneighDoReply::Vlan(val) => {
5319                    if last_off == offset {
5320                        stack.push(("Vlan", last_off));
5321                        break;
5322                    }
5323                }
5324                OpGetneighDoReply::Port(val) => {
5325                    if last_off == offset {
5326                        stack.push(("Port", last_off));
5327                        break;
5328                    }
5329                }
5330                OpGetneighDoReply::Vni(val) => {
5331                    if last_off == offset {
5332                        stack.push(("Vni", last_off));
5333                        break;
5334                    }
5335                }
5336                OpGetneighDoReply::Ifindex(val) => {
5337                    if last_off == offset {
5338                        stack.push(("Ifindex", last_off));
5339                        break;
5340                    }
5341                }
5342                OpGetneighDoReply::Master(val) => {
5343                    if last_off == offset {
5344                        stack.push(("Master", last_off));
5345                        break;
5346                    }
5347                }
5348                OpGetneighDoReply::Protocol(val) => {
5349                    if last_off == offset {
5350                        stack.push(("Protocol", last_off));
5351                        break;
5352                    }
5353                }
5354                OpGetneighDoReply::NhId(val) => {
5355                    if last_off == offset {
5356                        stack.push(("NhId", last_off));
5357                        break;
5358                    }
5359                }
5360                OpGetneighDoReply::FdbExtAttrs(val) => {
5361                    if last_off == offset {
5362                        stack.push(("FdbExtAttrs", last_off));
5363                        break;
5364                    }
5365                }
5366                OpGetneighDoReply::FlagsExt(val) => {
5367                    if last_off == offset {
5368                        stack.push(("FlagsExt", last_off));
5369                        break;
5370                    }
5371                }
5372                _ => {}
5373            };
5374            last_off = cur + attrs.pos;
5375        }
5376        if !stack.is_empty() {
5377            stack.push(("OpGetneighDoReply", cur));
5378        }
5379        (stack, None)
5380    }
5381}
5382#[derive(Debug)]
5383pub struct RequestOpGetneighDoRequest<'r> {
5384    request: Request<'r>,
5385}
5386impl<'r> RequestOpGetneighDoRequest<'r> {
5387    pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
5388        PushOpGetneighDoRequest::write_header(&mut request.buf_mut(), header);
5389        Self { request: request }
5390    }
5391    pub fn encode(&mut self) -> PushOpGetneighDoRequest<&mut Vec<u8>> {
5392        PushOpGetneighDoRequest::new_without_header(self.request.buf_mut())
5393    }
5394    pub fn into_encoder(self) -> PushOpGetneighDoRequest<RequestBuf<'r>> {
5395        PushOpGetneighDoRequest::new_without_header(self.request.buf)
5396    }
5397    pub fn decode_request<'buf>(buf: &'buf [u8]) -> (PushNdmsg, IterableOpGetneighDoRequest<'buf>) {
5398        OpGetneighDoRequest::new(buf)
5399    }
5400}
5401impl NetlinkRequest for RequestOpGetneighDoRequest<'_> {
5402    fn protocol(&self) -> Protocol {
5403        Protocol::Raw {
5404            protonum: 0u16,
5405            request_type: 30u16,
5406        }
5407    }
5408    fn flags(&self) -> u16 {
5409        self.request.flags
5410    }
5411    fn payload(&self) -> &[u8] {
5412        self.request.buf()
5413    }
5414    type ReplyType<'buf> = (PushNdmsg, IterableOpGetneighDoReply<'buf>);
5415    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5416        OpGetneighDoReply::new(buf)
5417    }
5418    fn lookup(
5419        buf: &[u8],
5420        offset: usize,
5421        missing_type: Option<u16>,
5422    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5423        OpGetneighDoRequest::new(buf)
5424            .1
5425            .lookup_attr(offset, missing_type)
5426    }
5427}
5428#[doc = "Get or dump neighbour tables"]
5429pub struct PushOpGetneightblDumpRequest<Prev: Rec> {
5430    pub(crate) prev: Option<Prev>,
5431    pub(crate) header_offset: Option<usize>,
5432}
5433impl<Prev: Rec> Rec for PushOpGetneightblDumpRequest<Prev> {
5434    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
5435        self.prev.as_mut().unwrap().as_rec_mut()
5436    }
5437    fn as_rec(&self) -> &Vec<u8> {
5438        self.prev.as_ref().unwrap().as_rec()
5439    }
5440}
5441impl<Prev: Rec> PushOpGetneightblDumpRequest<Prev> {
5442    pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
5443        Self::write_header(&mut prev, header);
5444        Self::new_without_header(prev)
5445    }
5446    fn new_without_header(prev: Prev) -> Self {
5447        Self {
5448            prev: Some(prev),
5449            header_offset: None,
5450        }
5451    }
5452    fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
5453        prev.as_rec_mut().extend(header.as_slice());
5454    }
5455    pub fn end_nested(mut self) -> Prev {
5456        let mut prev = self.prev.take().unwrap();
5457        if let Some(header_offset) = &self.header_offset {
5458            finalize_nested_header(prev.as_rec_mut(), *header_offset);
5459        }
5460        prev
5461    }
5462}
5463impl<Prev: Rec> Drop for PushOpGetneightblDumpRequest<Prev> {
5464    fn drop(&mut self) {
5465        if let Some(prev) = &mut self.prev {
5466            if let Some(header_offset) = &self.header_offset {
5467                finalize_nested_header(prev.as_rec_mut(), *header_offset);
5468            }
5469        }
5470    }
5471}
5472#[doc = "Get or dump neighbour tables"]
5473#[derive(Clone)]
5474pub enum OpGetneightblDumpRequest {}
5475impl<'a> IterableOpGetneightblDumpRequest<'a> {}
5476impl OpGetneightblDumpRequest {
5477    pub fn new<'a>(buf: &'a [u8]) -> (PushNdtmsg, IterableOpGetneightblDumpRequest<'a>) {
5478        let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
5479        (
5480            PushNdtmsg::new_from_slice(header).unwrap_or_default(),
5481            IterableOpGetneightblDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
5482        )
5483    }
5484    fn attr_from_type(r#type: u16) -> Option<&'static str> {
5485        NdtAttrs::attr_from_type(r#type)
5486    }
5487}
5488#[derive(Clone, Copy, Default)]
5489pub struct IterableOpGetneightblDumpRequest<'a> {
5490    buf: &'a [u8],
5491    pos: usize,
5492    orig_loc: usize,
5493}
5494impl<'a> IterableOpGetneightblDumpRequest<'a> {
5495    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5496        Self {
5497            buf,
5498            pos: 0,
5499            orig_loc,
5500        }
5501    }
5502    pub fn get_buf(&self) -> &'a [u8] {
5503        self.buf
5504    }
5505}
5506impl<'a> Iterator for IterableOpGetneightblDumpRequest<'a> {
5507    type Item = Result<OpGetneightblDumpRequest, ErrorContext>;
5508    fn next(&mut self) -> Option<Self::Item> {
5509        let pos = self.pos;
5510        let mut r#type;
5511        loop {
5512            r#type = None;
5513            if self.buf.len() == self.pos {
5514                return None;
5515            }
5516            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5517                break;
5518            };
5519            r#type = Some(header.r#type);
5520            let res = match header.r#type {
5521                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5522                n => continue,
5523            };
5524            return Some(Ok(res));
5525        }
5526        Some(Err(ErrorContext::new(
5527            "OpGetneightblDumpRequest",
5528            r#type.and_then(|t| OpGetneightblDumpRequest::attr_from_type(t)),
5529            self.orig_loc,
5530            self.buf.as_ptr().wrapping_add(pos) as usize,
5531        )))
5532    }
5533}
5534impl std::fmt::Debug for IterableOpGetneightblDumpRequest<'_> {
5535    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5536        let mut fmt = f.debug_struct("OpGetneightblDumpRequest");
5537        for attr in self.clone() {
5538            let attr = match attr {
5539                Ok(a) => a,
5540                Err(err) => {
5541                    fmt.finish()?;
5542                    f.write_str("Err(")?;
5543                    err.fmt(f)?;
5544                    return f.write_str(")");
5545                }
5546            };
5547            match attr {};
5548        }
5549        fmt.finish()
5550    }
5551}
5552impl IterableOpGetneightblDumpRequest<'_> {
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 cur == offset + PushNdtmsg::len() {
5561            stack.push(("OpGetneightblDumpRequest", offset));
5562            return (
5563                stack,
5564                missing_type.and_then(|t| OpGetneightblDumpRequest::attr_from_type(t)),
5565            );
5566        }
5567        (stack, None)
5568    }
5569}
5570#[doc = "Get or dump neighbour tables"]
5571pub struct PushOpGetneightblDumpReply<Prev: Rec> {
5572    pub(crate) prev: Option<Prev>,
5573    pub(crate) header_offset: Option<usize>,
5574}
5575impl<Prev: Rec> Rec for PushOpGetneightblDumpReply<Prev> {
5576    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
5577        self.prev.as_mut().unwrap().as_rec_mut()
5578    }
5579    fn as_rec(&self) -> &Vec<u8> {
5580        self.prev.as_ref().unwrap().as_rec()
5581    }
5582}
5583impl<Prev: Rec> PushOpGetneightblDumpReply<Prev> {
5584    pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
5585        Self::write_header(&mut prev, header);
5586        Self::new_without_header(prev)
5587    }
5588    fn new_without_header(prev: Prev) -> Self {
5589        Self {
5590            prev: Some(prev),
5591            header_offset: None,
5592        }
5593    }
5594    fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
5595        prev.as_rec_mut().extend(header.as_slice());
5596    }
5597    pub fn end_nested(mut self) -> Prev {
5598        let mut prev = self.prev.take().unwrap();
5599        if let Some(header_offset) = &self.header_offset {
5600            finalize_nested_header(prev.as_rec_mut(), *header_offset);
5601        }
5602        prev
5603    }
5604    pub fn push_name(mut self, value: &CStr) -> Self {
5605        push_header(
5606            self.as_rec_mut(),
5607            1u16,
5608            value.to_bytes_with_nul().len() as u16,
5609        );
5610        self.as_rec_mut().extend(value.to_bytes_with_nul());
5611        self
5612    }
5613    pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
5614        push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
5615        self.as_rec_mut().extend(value);
5616        self.as_rec_mut().push(0);
5617        self
5618    }
5619    pub fn push_thresh1(mut self, value: u32) -> Self {
5620        push_header(self.as_rec_mut(), 2u16, 4 as u16);
5621        self.as_rec_mut().extend(value.to_ne_bytes());
5622        self
5623    }
5624    pub fn push_thresh2(mut self, value: u32) -> Self {
5625        push_header(self.as_rec_mut(), 3u16, 4 as u16);
5626        self.as_rec_mut().extend(value.to_ne_bytes());
5627        self
5628    }
5629    pub fn push_thresh3(mut self, value: u32) -> Self {
5630        push_header(self.as_rec_mut(), 4u16, 4 as u16);
5631        self.as_rec_mut().extend(value.to_ne_bytes());
5632        self
5633    }
5634    pub fn push_config(mut self, value: PushNdtConfig) -> Self {
5635        push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
5636        self.as_rec_mut().extend(value.as_slice());
5637        self
5638    }
5639    pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
5640        let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
5641        PushNdtpaAttrs {
5642            prev: Some(self),
5643            header_offset: Some(header_offset),
5644        }
5645    }
5646    pub fn push_stats(mut self, value: PushNdtStats) -> Self {
5647        push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
5648        self.as_rec_mut().extend(value.as_slice());
5649        self
5650    }
5651    pub fn push_gc_interval(mut self, value: u64) -> Self {
5652        push_header(self.as_rec_mut(), 8u16, 8 as u16);
5653        self.as_rec_mut().extend(value.to_ne_bytes());
5654        self
5655    }
5656}
5657impl<Prev: Rec> Drop for PushOpGetneightblDumpReply<Prev> {
5658    fn drop(&mut self) {
5659        if let Some(prev) = &mut self.prev {
5660            if let Some(header_offset) = &self.header_offset {
5661                finalize_nested_header(prev.as_rec_mut(), *header_offset);
5662            }
5663        }
5664    }
5665}
5666#[doc = "Get or dump neighbour tables"]
5667#[derive(Clone)]
5668pub enum OpGetneightblDumpReply<'a> {
5669    Name(&'a CStr),
5670    Thresh1(u32),
5671    Thresh2(u32),
5672    Thresh3(u32),
5673    Config(PushNdtConfig),
5674    Parms(IterableNdtpaAttrs<'a>),
5675    Stats(PushNdtStats),
5676    GcInterval(u64),
5677}
5678impl<'a> IterableOpGetneightblDumpReply<'a> {
5679    pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
5680        let mut iter = self.clone();
5681        iter.pos = 0;
5682        for attr in iter {
5683            if let OpGetneightblDumpReply::Name(val) = attr? {
5684                return Ok(val);
5685            }
5686        }
5687        Err(ErrorContext::new_missing(
5688            "OpGetneightblDumpReply",
5689            "Name",
5690            self.orig_loc,
5691            self.buf.as_ptr() as usize,
5692        ))
5693    }
5694    pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
5695        let mut iter = self.clone();
5696        iter.pos = 0;
5697        for attr in iter {
5698            if let OpGetneightblDumpReply::Thresh1(val) = attr? {
5699                return Ok(val);
5700            }
5701        }
5702        Err(ErrorContext::new_missing(
5703            "OpGetneightblDumpReply",
5704            "Thresh1",
5705            self.orig_loc,
5706            self.buf.as_ptr() as usize,
5707        ))
5708    }
5709    pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
5710        let mut iter = self.clone();
5711        iter.pos = 0;
5712        for attr in iter {
5713            if let OpGetneightblDumpReply::Thresh2(val) = attr? {
5714                return Ok(val);
5715            }
5716        }
5717        Err(ErrorContext::new_missing(
5718            "OpGetneightblDumpReply",
5719            "Thresh2",
5720            self.orig_loc,
5721            self.buf.as_ptr() as usize,
5722        ))
5723    }
5724    pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
5725        let mut iter = self.clone();
5726        iter.pos = 0;
5727        for attr in iter {
5728            if let OpGetneightblDumpReply::Thresh3(val) = attr? {
5729                return Ok(val);
5730            }
5731        }
5732        Err(ErrorContext::new_missing(
5733            "OpGetneightblDumpReply",
5734            "Thresh3",
5735            self.orig_loc,
5736            self.buf.as_ptr() as usize,
5737        ))
5738    }
5739    pub fn get_config(&self) -> Result<PushNdtConfig, ErrorContext> {
5740        let mut iter = self.clone();
5741        iter.pos = 0;
5742        for attr in iter {
5743            if let OpGetneightblDumpReply::Config(val) = attr? {
5744                return Ok(val);
5745            }
5746        }
5747        Err(ErrorContext::new_missing(
5748            "OpGetneightblDumpReply",
5749            "Config",
5750            self.orig_loc,
5751            self.buf.as_ptr() as usize,
5752        ))
5753    }
5754    pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
5755        let mut iter = self.clone();
5756        iter.pos = 0;
5757        for attr in iter {
5758            if let OpGetneightblDumpReply::Parms(val) = attr? {
5759                return Ok(val);
5760            }
5761        }
5762        Err(ErrorContext::new_missing(
5763            "OpGetneightblDumpReply",
5764            "Parms",
5765            self.orig_loc,
5766            self.buf.as_ptr() as usize,
5767        ))
5768    }
5769    pub fn get_stats(&self) -> Result<PushNdtStats, ErrorContext> {
5770        let mut iter = self.clone();
5771        iter.pos = 0;
5772        for attr in iter {
5773            if let OpGetneightblDumpReply::Stats(val) = attr? {
5774                return Ok(val);
5775            }
5776        }
5777        Err(ErrorContext::new_missing(
5778            "OpGetneightblDumpReply",
5779            "Stats",
5780            self.orig_loc,
5781            self.buf.as_ptr() as usize,
5782        ))
5783    }
5784    pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
5785        let mut iter = self.clone();
5786        iter.pos = 0;
5787        for attr in iter {
5788            if let OpGetneightblDumpReply::GcInterval(val) = attr? {
5789                return Ok(val);
5790            }
5791        }
5792        Err(ErrorContext::new_missing(
5793            "OpGetneightblDumpReply",
5794            "GcInterval",
5795            self.orig_loc,
5796            self.buf.as_ptr() as usize,
5797        ))
5798    }
5799}
5800impl OpGetneightblDumpReply<'_> {
5801    pub fn new<'a>(buf: &'a [u8]) -> (PushNdtmsg, IterableOpGetneightblDumpReply<'a>) {
5802        let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
5803        (
5804            PushNdtmsg::new_from_slice(header).unwrap_or_default(),
5805            IterableOpGetneightblDumpReply::with_loc(attrs, buf.as_ptr() as usize),
5806        )
5807    }
5808    fn attr_from_type(r#type: u16) -> Option<&'static str> {
5809        NdtAttrs::attr_from_type(r#type)
5810    }
5811}
5812#[derive(Clone, Copy, Default)]
5813pub struct IterableOpGetneightblDumpReply<'a> {
5814    buf: &'a [u8],
5815    pos: usize,
5816    orig_loc: usize,
5817}
5818impl<'a> IterableOpGetneightblDumpReply<'a> {
5819    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5820        Self {
5821            buf,
5822            pos: 0,
5823            orig_loc,
5824        }
5825    }
5826    pub fn get_buf(&self) -> &'a [u8] {
5827        self.buf
5828    }
5829}
5830impl<'a> Iterator for IterableOpGetneightblDumpReply<'a> {
5831    type Item = Result<OpGetneightblDumpReply<'a>, ErrorContext>;
5832    fn next(&mut self) -> Option<Self::Item> {
5833        let pos = self.pos;
5834        let mut r#type;
5835        loop {
5836            r#type = None;
5837            if self.buf.len() == self.pos {
5838                return None;
5839            }
5840            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
5841                break;
5842            };
5843            r#type = Some(header.r#type);
5844            let res = match header.r#type {
5845                1u16 => OpGetneightblDumpReply::Name({
5846                    let res = CStr::from_bytes_with_nul(next).ok();
5847                    let Some(val) = res else { break };
5848                    val
5849                }),
5850                2u16 => OpGetneightblDumpReply::Thresh1({
5851                    let res = parse_u32(next);
5852                    let Some(val) = res else { break };
5853                    val
5854                }),
5855                3u16 => OpGetneightblDumpReply::Thresh2({
5856                    let res = parse_u32(next);
5857                    let Some(val) = res else { break };
5858                    val
5859                }),
5860                4u16 => OpGetneightblDumpReply::Thresh3({
5861                    let res = parse_u32(next);
5862                    let Some(val) = res else { break };
5863                    val
5864                }),
5865                5u16 => OpGetneightblDumpReply::Config({
5866                    let res = PushNdtConfig::new_from_slice(next);
5867                    let Some(val) = res else { break };
5868                    val
5869                }),
5870                6u16 => OpGetneightblDumpReply::Parms({
5871                    let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
5872                    let Some(val) = res else { break };
5873                    val
5874                }),
5875                7u16 => OpGetneightblDumpReply::Stats({
5876                    let res = PushNdtStats::new_from_slice(next);
5877                    let Some(val) = res else { break };
5878                    val
5879                }),
5880                8u16 => OpGetneightblDumpReply::GcInterval({
5881                    let res = parse_u64(next);
5882                    let Some(val) = res else { break };
5883                    val
5884                }),
5885                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
5886                n => continue,
5887            };
5888            return Some(Ok(res));
5889        }
5890        Some(Err(ErrorContext::new(
5891            "OpGetneightblDumpReply",
5892            r#type.and_then(|t| OpGetneightblDumpReply::attr_from_type(t)),
5893            self.orig_loc,
5894            self.buf.as_ptr().wrapping_add(pos) as usize,
5895        )))
5896    }
5897}
5898impl<'a> std::fmt::Debug for IterableOpGetneightblDumpReply<'_> {
5899    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5900        let mut fmt = f.debug_struct("OpGetneightblDumpReply");
5901        for attr in self.clone() {
5902            let attr = match attr {
5903                Ok(a) => a,
5904                Err(err) => {
5905                    fmt.finish()?;
5906                    f.write_str("Err(")?;
5907                    err.fmt(f)?;
5908                    return f.write_str(")");
5909                }
5910            };
5911            match attr {
5912                OpGetneightblDumpReply::Name(val) => fmt.field("Name", &val),
5913                OpGetneightblDumpReply::Thresh1(val) => fmt.field("Thresh1", &val),
5914                OpGetneightblDumpReply::Thresh2(val) => fmt.field("Thresh2", &val),
5915                OpGetneightblDumpReply::Thresh3(val) => fmt.field("Thresh3", &val),
5916                OpGetneightblDumpReply::Config(val) => fmt.field("Config", &val),
5917                OpGetneightblDumpReply::Parms(val) => fmt.field("Parms", &val),
5918                OpGetneightblDumpReply::Stats(val) => fmt.field("Stats", &val),
5919                OpGetneightblDumpReply::GcInterval(val) => fmt.field("GcInterval", &val),
5920            };
5921        }
5922        fmt.finish()
5923    }
5924}
5925impl IterableOpGetneightblDumpReply<'_> {
5926    pub fn lookup_attr(
5927        &self,
5928        offset: usize,
5929        missing_type: Option<u16>,
5930    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5931        let mut stack = Vec::new();
5932        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5933        if cur == offset + PushNdtmsg::len() {
5934            stack.push(("OpGetneightblDumpReply", offset));
5935            return (
5936                stack,
5937                missing_type.and_then(|t| OpGetneightblDumpReply::attr_from_type(t)),
5938            );
5939        }
5940        if cur > offset || cur + self.buf.len() < offset {
5941            return (stack, None);
5942        }
5943        let mut attrs = self.clone();
5944        let mut last_off = cur + attrs.pos;
5945        let mut missing = None;
5946        while let Some(attr) = attrs.next() {
5947            let Ok(attr) = attr else { break };
5948            match attr {
5949                OpGetneightblDumpReply::Name(val) => {
5950                    if last_off == offset {
5951                        stack.push(("Name", last_off));
5952                        break;
5953                    }
5954                }
5955                OpGetneightblDumpReply::Thresh1(val) => {
5956                    if last_off == offset {
5957                        stack.push(("Thresh1", last_off));
5958                        break;
5959                    }
5960                }
5961                OpGetneightblDumpReply::Thresh2(val) => {
5962                    if last_off == offset {
5963                        stack.push(("Thresh2", last_off));
5964                        break;
5965                    }
5966                }
5967                OpGetneightblDumpReply::Thresh3(val) => {
5968                    if last_off == offset {
5969                        stack.push(("Thresh3", last_off));
5970                        break;
5971                    }
5972                }
5973                OpGetneightblDumpReply::Config(val) => {
5974                    if last_off == offset {
5975                        stack.push(("Config", last_off));
5976                        break;
5977                    }
5978                }
5979                OpGetneightblDumpReply::Parms(val) => {
5980                    (stack, missing) = val.lookup_attr(offset, missing_type);
5981                    if !stack.is_empty() {
5982                        break;
5983                    }
5984                }
5985                OpGetneightblDumpReply::Stats(val) => {
5986                    if last_off == offset {
5987                        stack.push(("Stats", last_off));
5988                        break;
5989                    }
5990                }
5991                OpGetneightblDumpReply::GcInterval(val) => {
5992                    if last_off == offset {
5993                        stack.push(("GcInterval", last_off));
5994                        break;
5995                    }
5996                }
5997                _ => {}
5998            };
5999            last_off = cur + attrs.pos;
6000        }
6001        if !stack.is_empty() {
6002            stack.push(("OpGetneightblDumpReply", cur));
6003        }
6004        (stack, missing)
6005    }
6006}
6007#[derive(Debug)]
6008pub struct RequestOpGetneightblDumpRequest<'r> {
6009    request: Request<'r>,
6010}
6011impl<'r> RequestOpGetneightblDumpRequest<'r> {
6012    pub fn new(mut request: Request<'r>, header: &PushNdtmsg) -> Self {
6013        PushOpGetneightblDumpRequest::write_header(&mut request.buf_mut(), header);
6014        Self {
6015            request: request.set_dump(),
6016        }
6017    }
6018    pub fn encode(&mut self) -> PushOpGetneightblDumpRequest<&mut Vec<u8>> {
6019        PushOpGetneightblDumpRequest::new_without_header(self.request.buf_mut())
6020    }
6021    pub fn into_encoder(self) -> PushOpGetneightblDumpRequest<RequestBuf<'r>> {
6022        PushOpGetneightblDumpRequest::new_without_header(self.request.buf)
6023    }
6024    pub fn decode_request<'buf>(
6025        buf: &'buf [u8],
6026    ) -> (PushNdtmsg, IterableOpGetneightblDumpRequest<'buf>) {
6027        OpGetneightblDumpRequest::new(buf)
6028    }
6029}
6030impl NetlinkRequest for RequestOpGetneightblDumpRequest<'_> {
6031    fn protocol(&self) -> Protocol {
6032        Protocol::Raw {
6033            protonum: 0u16,
6034            request_type: 66u16,
6035        }
6036    }
6037    fn flags(&self) -> u16 {
6038        self.request.flags
6039    }
6040    fn payload(&self) -> &[u8] {
6041        self.request.buf()
6042    }
6043    type ReplyType<'buf> = (PushNdtmsg, IterableOpGetneightblDumpReply<'buf>);
6044    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6045        OpGetneightblDumpReply::new(buf)
6046    }
6047    fn lookup(
6048        buf: &[u8],
6049        offset: usize,
6050        missing_type: Option<u16>,
6051    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6052        OpGetneightblDumpRequest::new(buf)
6053            .1
6054            .lookup_attr(offset, missing_type)
6055    }
6056}
6057#[doc = "Set neighbour tables"]
6058pub struct PushOpSetneightblDoRequest<Prev: Rec> {
6059    pub(crate) prev: Option<Prev>,
6060    pub(crate) header_offset: Option<usize>,
6061}
6062impl<Prev: Rec> Rec for PushOpSetneightblDoRequest<Prev> {
6063    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6064        self.prev.as_mut().unwrap().as_rec_mut()
6065    }
6066    fn as_rec(&self) -> &Vec<u8> {
6067        self.prev.as_ref().unwrap().as_rec()
6068    }
6069}
6070impl<Prev: Rec> PushOpSetneightblDoRequest<Prev> {
6071    pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
6072        Self::write_header(&mut prev, header);
6073        Self::new_without_header(prev)
6074    }
6075    fn new_without_header(prev: Prev) -> Self {
6076        Self {
6077            prev: Some(prev),
6078            header_offset: None,
6079        }
6080    }
6081    fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
6082        prev.as_rec_mut().extend(header.as_slice());
6083    }
6084    pub fn end_nested(mut self) -> Prev {
6085        let mut prev = self.prev.take().unwrap();
6086        if let Some(header_offset) = &self.header_offset {
6087            finalize_nested_header(prev.as_rec_mut(), *header_offset);
6088        }
6089        prev
6090    }
6091    pub fn push_name(mut self, value: &CStr) -> Self {
6092        push_header(
6093            self.as_rec_mut(),
6094            1u16,
6095            value.to_bytes_with_nul().len() as u16,
6096        );
6097        self.as_rec_mut().extend(value.to_bytes_with_nul());
6098        self
6099    }
6100    pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
6101        push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
6102        self.as_rec_mut().extend(value);
6103        self.as_rec_mut().push(0);
6104        self
6105    }
6106    pub fn push_thresh1(mut self, value: u32) -> Self {
6107        push_header(self.as_rec_mut(), 2u16, 4 as u16);
6108        self.as_rec_mut().extend(value.to_ne_bytes());
6109        self
6110    }
6111    pub fn push_thresh2(mut self, value: u32) -> Self {
6112        push_header(self.as_rec_mut(), 3u16, 4 as u16);
6113        self.as_rec_mut().extend(value.to_ne_bytes());
6114        self
6115    }
6116    pub fn push_thresh3(mut self, value: u32) -> Self {
6117        push_header(self.as_rec_mut(), 4u16, 4 as u16);
6118        self.as_rec_mut().extend(value.to_ne_bytes());
6119        self
6120    }
6121    pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
6122        let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
6123        PushNdtpaAttrs {
6124            prev: Some(self),
6125            header_offset: Some(header_offset),
6126        }
6127    }
6128    pub fn push_gc_interval(mut self, value: u64) -> Self {
6129        push_header(self.as_rec_mut(), 8u16, 8 as u16);
6130        self.as_rec_mut().extend(value.to_ne_bytes());
6131        self
6132    }
6133}
6134impl<Prev: Rec> Drop for PushOpSetneightblDoRequest<Prev> {
6135    fn drop(&mut self) {
6136        if let Some(prev) = &mut self.prev {
6137            if let Some(header_offset) = &self.header_offset {
6138                finalize_nested_header(prev.as_rec_mut(), *header_offset);
6139            }
6140        }
6141    }
6142}
6143#[doc = "Set neighbour tables"]
6144#[derive(Clone)]
6145pub enum OpSetneightblDoRequest<'a> {
6146    Name(&'a CStr),
6147    Thresh1(u32),
6148    Thresh2(u32),
6149    Thresh3(u32),
6150    Parms(IterableNdtpaAttrs<'a>),
6151    GcInterval(u64),
6152}
6153impl<'a> IterableOpSetneightblDoRequest<'a> {
6154    pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
6155        let mut iter = self.clone();
6156        iter.pos = 0;
6157        for attr in iter {
6158            if let OpSetneightblDoRequest::Name(val) = attr? {
6159                return Ok(val);
6160            }
6161        }
6162        Err(ErrorContext::new_missing(
6163            "OpSetneightblDoRequest",
6164            "Name",
6165            self.orig_loc,
6166            self.buf.as_ptr() as usize,
6167        ))
6168    }
6169    pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
6170        let mut iter = self.clone();
6171        iter.pos = 0;
6172        for attr in iter {
6173            if let OpSetneightblDoRequest::Thresh1(val) = attr? {
6174                return Ok(val);
6175            }
6176        }
6177        Err(ErrorContext::new_missing(
6178            "OpSetneightblDoRequest",
6179            "Thresh1",
6180            self.orig_loc,
6181            self.buf.as_ptr() as usize,
6182        ))
6183    }
6184    pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
6185        let mut iter = self.clone();
6186        iter.pos = 0;
6187        for attr in iter {
6188            if let OpSetneightblDoRequest::Thresh2(val) = attr? {
6189                return Ok(val);
6190            }
6191        }
6192        Err(ErrorContext::new_missing(
6193            "OpSetneightblDoRequest",
6194            "Thresh2",
6195            self.orig_loc,
6196            self.buf.as_ptr() as usize,
6197        ))
6198    }
6199    pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
6200        let mut iter = self.clone();
6201        iter.pos = 0;
6202        for attr in iter {
6203            if let OpSetneightblDoRequest::Thresh3(val) = attr? {
6204                return Ok(val);
6205            }
6206        }
6207        Err(ErrorContext::new_missing(
6208            "OpSetneightblDoRequest",
6209            "Thresh3",
6210            self.orig_loc,
6211            self.buf.as_ptr() as usize,
6212        ))
6213    }
6214    pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
6215        let mut iter = self.clone();
6216        iter.pos = 0;
6217        for attr in iter {
6218            if let OpSetneightblDoRequest::Parms(val) = attr? {
6219                return Ok(val);
6220            }
6221        }
6222        Err(ErrorContext::new_missing(
6223            "OpSetneightblDoRequest",
6224            "Parms",
6225            self.orig_loc,
6226            self.buf.as_ptr() as usize,
6227        ))
6228    }
6229    pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
6230        let mut iter = self.clone();
6231        iter.pos = 0;
6232        for attr in iter {
6233            if let OpSetneightblDoRequest::GcInterval(val) = attr? {
6234                return Ok(val);
6235            }
6236        }
6237        Err(ErrorContext::new_missing(
6238            "OpSetneightblDoRequest",
6239            "GcInterval",
6240            self.orig_loc,
6241            self.buf.as_ptr() as usize,
6242        ))
6243    }
6244}
6245impl OpSetneightblDoRequest<'_> {
6246    pub fn new<'a>(buf: &'a [u8]) -> (PushNdtmsg, IterableOpSetneightblDoRequest<'a>) {
6247        let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
6248        (
6249            PushNdtmsg::new_from_slice(header).unwrap_or_default(),
6250            IterableOpSetneightblDoRequest::with_loc(attrs, buf.as_ptr() as usize),
6251        )
6252    }
6253    fn attr_from_type(r#type: u16) -> Option<&'static str> {
6254        NdtAttrs::attr_from_type(r#type)
6255    }
6256}
6257#[derive(Clone, Copy, Default)]
6258pub struct IterableOpSetneightblDoRequest<'a> {
6259    buf: &'a [u8],
6260    pos: usize,
6261    orig_loc: usize,
6262}
6263impl<'a> IterableOpSetneightblDoRequest<'a> {
6264    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6265        Self {
6266            buf,
6267            pos: 0,
6268            orig_loc,
6269        }
6270    }
6271    pub fn get_buf(&self) -> &'a [u8] {
6272        self.buf
6273    }
6274}
6275impl<'a> Iterator for IterableOpSetneightblDoRequest<'a> {
6276    type Item = Result<OpSetneightblDoRequest<'a>, ErrorContext>;
6277    fn next(&mut self) -> Option<Self::Item> {
6278        let pos = self.pos;
6279        let mut r#type;
6280        loop {
6281            r#type = None;
6282            if self.buf.len() == self.pos {
6283                return None;
6284            }
6285            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6286                break;
6287            };
6288            r#type = Some(header.r#type);
6289            let res = match header.r#type {
6290                1u16 => OpSetneightblDoRequest::Name({
6291                    let res = CStr::from_bytes_with_nul(next).ok();
6292                    let Some(val) = res else { break };
6293                    val
6294                }),
6295                2u16 => OpSetneightblDoRequest::Thresh1({
6296                    let res = parse_u32(next);
6297                    let Some(val) = res else { break };
6298                    val
6299                }),
6300                3u16 => OpSetneightblDoRequest::Thresh2({
6301                    let res = parse_u32(next);
6302                    let Some(val) = res else { break };
6303                    val
6304                }),
6305                4u16 => OpSetneightblDoRequest::Thresh3({
6306                    let res = parse_u32(next);
6307                    let Some(val) = res else { break };
6308                    val
6309                }),
6310                6u16 => OpSetneightblDoRequest::Parms({
6311                    let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
6312                    let Some(val) = res else { break };
6313                    val
6314                }),
6315                8u16 => OpSetneightblDoRequest::GcInterval({
6316                    let res = parse_u64(next);
6317                    let Some(val) = res else { break };
6318                    val
6319                }),
6320                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6321                n => continue,
6322            };
6323            return Some(Ok(res));
6324        }
6325        Some(Err(ErrorContext::new(
6326            "OpSetneightblDoRequest",
6327            r#type.and_then(|t| OpSetneightblDoRequest::attr_from_type(t)),
6328            self.orig_loc,
6329            self.buf.as_ptr().wrapping_add(pos) as usize,
6330        )))
6331    }
6332}
6333impl<'a> std::fmt::Debug for IterableOpSetneightblDoRequest<'_> {
6334    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6335        let mut fmt = f.debug_struct("OpSetneightblDoRequest");
6336        for attr in self.clone() {
6337            let attr = match attr {
6338                Ok(a) => a,
6339                Err(err) => {
6340                    fmt.finish()?;
6341                    f.write_str("Err(")?;
6342                    err.fmt(f)?;
6343                    return f.write_str(")");
6344                }
6345            };
6346            match attr {
6347                OpSetneightblDoRequest::Name(val) => fmt.field("Name", &val),
6348                OpSetneightblDoRequest::Thresh1(val) => fmt.field("Thresh1", &val),
6349                OpSetneightblDoRequest::Thresh2(val) => fmt.field("Thresh2", &val),
6350                OpSetneightblDoRequest::Thresh3(val) => fmt.field("Thresh3", &val),
6351                OpSetneightblDoRequest::Parms(val) => fmt.field("Parms", &val),
6352                OpSetneightblDoRequest::GcInterval(val) => fmt.field("GcInterval", &val),
6353            };
6354        }
6355        fmt.finish()
6356    }
6357}
6358impl IterableOpSetneightblDoRequest<'_> {
6359    pub fn lookup_attr(
6360        &self,
6361        offset: usize,
6362        missing_type: Option<u16>,
6363    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6364        let mut stack = Vec::new();
6365        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6366        if cur == offset + PushNdtmsg::len() {
6367            stack.push(("OpSetneightblDoRequest", offset));
6368            return (
6369                stack,
6370                missing_type.and_then(|t| OpSetneightblDoRequest::attr_from_type(t)),
6371            );
6372        }
6373        if cur > offset || cur + self.buf.len() < offset {
6374            return (stack, None);
6375        }
6376        let mut attrs = self.clone();
6377        let mut last_off = cur + attrs.pos;
6378        let mut missing = None;
6379        while let Some(attr) = attrs.next() {
6380            let Ok(attr) = attr else { break };
6381            match attr {
6382                OpSetneightblDoRequest::Name(val) => {
6383                    if last_off == offset {
6384                        stack.push(("Name", last_off));
6385                        break;
6386                    }
6387                }
6388                OpSetneightblDoRequest::Thresh1(val) => {
6389                    if last_off == offset {
6390                        stack.push(("Thresh1", last_off));
6391                        break;
6392                    }
6393                }
6394                OpSetneightblDoRequest::Thresh2(val) => {
6395                    if last_off == offset {
6396                        stack.push(("Thresh2", last_off));
6397                        break;
6398                    }
6399                }
6400                OpSetneightblDoRequest::Thresh3(val) => {
6401                    if last_off == offset {
6402                        stack.push(("Thresh3", last_off));
6403                        break;
6404                    }
6405                }
6406                OpSetneightblDoRequest::Parms(val) => {
6407                    (stack, missing) = val.lookup_attr(offset, missing_type);
6408                    if !stack.is_empty() {
6409                        break;
6410                    }
6411                }
6412                OpSetneightblDoRequest::GcInterval(val) => {
6413                    if last_off == offset {
6414                        stack.push(("GcInterval", last_off));
6415                        break;
6416                    }
6417                }
6418                _ => {}
6419            };
6420            last_off = cur + attrs.pos;
6421        }
6422        if !stack.is_empty() {
6423            stack.push(("OpSetneightblDoRequest", cur));
6424        }
6425        (stack, missing)
6426    }
6427}
6428#[doc = "Set neighbour tables"]
6429pub struct PushOpSetneightblDoReply<Prev: Rec> {
6430    pub(crate) prev: Option<Prev>,
6431    pub(crate) header_offset: Option<usize>,
6432}
6433impl<Prev: Rec> Rec for PushOpSetneightblDoReply<Prev> {
6434    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6435        self.prev.as_mut().unwrap().as_rec_mut()
6436    }
6437    fn as_rec(&self) -> &Vec<u8> {
6438        self.prev.as_ref().unwrap().as_rec()
6439    }
6440}
6441impl<Prev: Rec> PushOpSetneightblDoReply<Prev> {
6442    pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
6443        Self::write_header(&mut prev, header);
6444        Self::new_without_header(prev)
6445    }
6446    fn new_without_header(prev: Prev) -> Self {
6447        Self {
6448            prev: Some(prev),
6449            header_offset: None,
6450        }
6451    }
6452    fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
6453        prev.as_rec_mut().extend(header.as_slice());
6454    }
6455    pub fn end_nested(mut self) -> Prev {
6456        let mut prev = self.prev.take().unwrap();
6457        if let Some(header_offset) = &self.header_offset {
6458            finalize_nested_header(prev.as_rec_mut(), *header_offset);
6459        }
6460        prev
6461    }
6462}
6463impl<Prev: Rec> Drop for PushOpSetneightblDoReply<Prev> {
6464    fn drop(&mut self) {
6465        if let Some(prev) = &mut self.prev {
6466            if let Some(header_offset) = &self.header_offset {
6467                finalize_nested_header(prev.as_rec_mut(), *header_offset);
6468            }
6469        }
6470    }
6471}
6472#[doc = "Set neighbour tables"]
6473#[derive(Clone)]
6474pub enum OpSetneightblDoReply {}
6475impl<'a> IterableOpSetneightblDoReply<'a> {}
6476impl OpSetneightblDoReply {
6477    pub fn new<'a>(buf: &'a [u8]) -> (PushNdtmsg, IterableOpSetneightblDoReply<'a>) {
6478        let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
6479        (
6480            PushNdtmsg::new_from_slice(header).unwrap_or_default(),
6481            IterableOpSetneightblDoReply::with_loc(attrs, buf.as_ptr() as usize),
6482        )
6483    }
6484    fn attr_from_type(r#type: u16) -> Option<&'static str> {
6485        NdtAttrs::attr_from_type(r#type)
6486    }
6487}
6488#[derive(Clone, Copy, Default)]
6489pub struct IterableOpSetneightblDoReply<'a> {
6490    buf: &'a [u8],
6491    pos: usize,
6492    orig_loc: usize,
6493}
6494impl<'a> IterableOpSetneightblDoReply<'a> {
6495    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6496        Self {
6497            buf,
6498            pos: 0,
6499            orig_loc,
6500        }
6501    }
6502    pub fn get_buf(&self) -> &'a [u8] {
6503        self.buf
6504    }
6505}
6506impl<'a> Iterator for IterableOpSetneightblDoReply<'a> {
6507    type Item = Result<OpSetneightblDoReply, ErrorContext>;
6508    fn next(&mut self) -> Option<Self::Item> {
6509        let pos = self.pos;
6510        let mut r#type;
6511        loop {
6512            r#type = None;
6513            if self.buf.len() == self.pos {
6514                return None;
6515            }
6516            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
6517                break;
6518            };
6519            r#type = Some(header.r#type);
6520            let res = match header.r#type {
6521                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
6522                n => continue,
6523            };
6524            return Some(Ok(res));
6525        }
6526        Some(Err(ErrorContext::new(
6527            "OpSetneightblDoReply",
6528            r#type.and_then(|t| OpSetneightblDoReply::attr_from_type(t)),
6529            self.orig_loc,
6530            self.buf.as_ptr().wrapping_add(pos) as usize,
6531        )))
6532    }
6533}
6534impl std::fmt::Debug for IterableOpSetneightblDoReply<'_> {
6535    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6536        let mut fmt = f.debug_struct("OpSetneightblDoReply");
6537        for attr in self.clone() {
6538            let attr = match attr {
6539                Ok(a) => a,
6540                Err(err) => {
6541                    fmt.finish()?;
6542                    f.write_str("Err(")?;
6543                    err.fmt(f)?;
6544                    return f.write_str(")");
6545                }
6546            };
6547            match attr {};
6548        }
6549        fmt.finish()
6550    }
6551}
6552impl IterableOpSetneightblDoReply<'_> {
6553    pub fn lookup_attr(
6554        &self,
6555        offset: usize,
6556        missing_type: Option<u16>,
6557    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6558        let mut stack = Vec::new();
6559        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6560        if cur == offset + PushNdtmsg::len() {
6561            stack.push(("OpSetneightblDoReply", offset));
6562            return (
6563                stack,
6564                missing_type.and_then(|t| OpSetneightblDoReply::attr_from_type(t)),
6565            );
6566        }
6567        (stack, None)
6568    }
6569}
6570#[derive(Debug)]
6571pub struct RequestOpSetneightblDoRequest<'r> {
6572    request: Request<'r>,
6573}
6574impl<'r> RequestOpSetneightblDoRequest<'r> {
6575    pub fn new(mut request: Request<'r>, header: &PushNdtmsg) -> Self {
6576        PushOpSetneightblDoRequest::write_header(&mut request.buf_mut(), header);
6577        Self { request: request }
6578    }
6579    pub fn encode(&mut self) -> PushOpSetneightblDoRequest<&mut Vec<u8>> {
6580        PushOpSetneightblDoRequest::new_without_header(self.request.buf_mut())
6581    }
6582    pub fn into_encoder(self) -> PushOpSetneightblDoRequest<RequestBuf<'r>> {
6583        PushOpSetneightblDoRequest::new_without_header(self.request.buf)
6584    }
6585    pub fn decode_request<'buf>(
6586        buf: &'buf [u8],
6587    ) -> (PushNdtmsg, IterableOpSetneightblDoRequest<'buf>) {
6588        OpSetneightblDoRequest::new(buf)
6589    }
6590}
6591impl NetlinkRequest for RequestOpSetneightblDoRequest<'_> {
6592    fn protocol(&self) -> Protocol {
6593        Protocol::Raw {
6594            protonum: 0u16,
6595            request_type: 67u16,
6596        }
6597    }
6598    fn flags(&self) -> u16 {
6599        self.request.flags
6600    }
6601    fn payload(&self) -> &[u8] {
6602        self.request.buf()
6603    }
6604    type ReplyType<'buf> = (PushNdtmsg, IterableOpSetneightblDoReply<'buf>);
6605    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6606        OpSetneightblDoReply::new(buf)
6607    }
6608    fn lookup(
6609        buf: &[u8],
6610        offset: usize,
6611        missing_type: Option<u16>,
6612    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6613        OpSetneightblDoRequest::new(buf)
6614            .1
6615            .lookup_attr(offset, missing_type)
6616    }
6617}
6618#[derive(Debug)]
6619pub struct ChainedFinal<'a> {
6620    inner: Chained<'a>,
6621}
6622#[derive(Debug)]
6623pub struct Chained<'a> {
6624    buf: RequestBuf<'a>,
6625    first_seq: u32,
6626    lookups: Vec<(&'static str, LookupFn)>,
6627    last_header_offset: usize,
6628    last_kind: Option<RequestInfo>,
6629}
6630impl<'a> ChainedFinal<'a> {
6631    pub fn into_chained(self) -> Chained<'a> {
6632        self.inner
6633    }
6634    pub fn buf(&self) -> &Vec<u8> {
6635        self.inner.buf()
6636    }
6637    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6638        self.inner.buf_mut()
6639    }
6640    fn get_index(&self, seq: u32) -> Option<u32> {
6641        let min = self.inner.first_seq;
6642        let max = min.wrapping_add(self.inner.lookups.len() as u32);
6643        return if min <= max {
6644            (min..max).contains(&seq).then(|| seq - min)
6645        } else if min <= seq {
6646            Some(seq - min)
6647        } else if seq < max {
6648            Some(u32::MAX - min + seq)
6649        } else {
6650            None
6651        };
6652    }
6653}
6654impl crate::traits::NetlinkChained for ChainedFinal<'_> {
6655    fn protonum(&self) -> u16 {
6656        PROTONUM
6657    }
6658    fn payload(&self) -> &[u8] {
6659        self.buf()
6660    }
6661    fn chain_len(&self) -> usize {
6662        self.inner.lookups.len()
6663    }
6664    fn get_index(&self, seq: u32) -> Option<usize> {
6665        self.get_index(seq).map(|n| n as usize)
6666    }
6667    fn name(&self, index: usize) -> &'static str {
6668        self.inner.lookups[index].0
6669    }
6670    fn lookup(&self, index: usize) -> LookupFn {
6671        self.inner.lookups[index].1
6672    }
6673}
6674impl Chained<'static> {
6675    pub fn new(first_seq: u32) -> Self {
6676        Self::new_from_buf(Vec::new(), first_seq)
6677    }
6678    pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
6679        Self {
6680            buf: RequestBuf::Own(buf),
6681            first_seq,
6682            lookups: Vec::new(),
6683            last_header_offset: 0,
6684            last_kind: None,
6685        }
6686    }
6687    pub fn into_buf(self) -> Vec<u8> {
6688        match self.buf {
6689            RequestBuf::Own(buf) => buf,
6690            _ => unreachable!(),
6691        }
6692    }
6693}
6694impl<'a> Chained<'a> {
6695    pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
6696        Self {
6697            buf: RequestBuf::Ref(buf),
6698            first_seq,
6699            lookups: Vec::new(),
6700            last_header_offset: 0,
6701            last_kind: None,
6702        }
6703    }
6704    pub fn finalize(mut self) -> ChainedFinal<'a> {
6705        self.update_header();
6706        ChainedFinal { inner: self }
6707    }
6708    pub fn request(&mut self) -> Request<'_> {
6709        self.update_header();
6710        self.last_header_offset = self.buf().len();
6711        self.buf_mut()
6712            .extend_from_slice(PushNlmsghdr::new().as_slice());
6713        let mut request = Request::new_extend(self.buf.buf_mut());
6714        self.last_kind = None;
6715        request.writeback = Some(&mut self.last_kind);
6716        request
6717    }
6718    pub fn buf(&self) -> &Vec<u8> {
6719        self.buf.buf()
6720    }
6721    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6722        self.buf.buf_mut()
6723    }
6724    fn update_header(&mut self) {
6725        let Some(RequestInfo {
6726            protocol,
6727            flags,
6728            name,
6729            lookup,
6730        }) = self.last_kind
6731        else {
6732            if !self.buf().is_empty() {
6733                assert_eq!(
6734                    self.last_header_offset + PushNlmsghdr::len(),
6735                    self.buf().len()
6736                );
6737                self.buf.buf_mut().truncate(self.last_header_offset);
6738            }
6739            return;
6740        };
6741        let header_offset = self.last_header_offset;
6742        let request_type = match protocol {
6743            Protocol::Raw { request_type, .. } => request_type,
6744            Protocol::Generic(_) => unreachable!(),
6745        };
6746        let index = self.lookups.len();
6747        let seq = self.first_seq.wrapping_add(index as u32);
6748        self.lookups.push((name, lookup));
6749        let buf = self.buf_mut();
6750        align(buf);
6751        let mut header = PushNlmsghdr::new();
6752        header.set_len((buf.len() - header_offset) as u32);
6753        header.set_type(request_type);
6754        header.set_flags(flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16);
6755        header.set_seq(seq);
6756        buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
6757    }
6758}
6759use crate::traits::LookupFn;
6760use crate::utils::RequestBuf;
6761#[derive(Debug)]
6762pub struct Request<'buf> {
6763    buf: RequestBuf<'buf>,
6764    flags: u16,
6765    writeback: Option<&'buf mut Option<RequestInfo>>,
6766}
6767#[allow(unused)]
6768#[derive(Debug, Clone)]
6769pub struct RequestInfo {
6770    protocol: Protocol,
6771    flags: u16,
6772    name: &'static str,
6773    lookup: LookupFn,
6774}
6775impl Request<'static> {
6776    pub fn new() -> Self {
6777        Self::new_from_buf(Vec::new())
6778    }
6779    pub fn new_from_buf(buf: Vec<u8>) -> Self {
6780        Self {
6781            flags: 0,
6782            buf: RequestBuf::Own(buf),
6783            writeback: None,
6784        }
6785    }
6786    pub fn into_buf(self) -> Vec<u8> {
6787        match self.buf {
6788            RequestBuf::Own(buf) => buf,
6789            _ => unreachable!(),
6790        }
6791    }
6792}
6793impl<'buf> Request<'buf> {
6794    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
6795        buf.clear();
6796        Self::new_extend(buf)
6797    }
6798    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
6799        Self {
6800            flags: 0,
6801            buf: RequestBuf::Ref(buf),
6802            writeback: None,
6803        }
6804    }
6805    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
6806        let Some(writeback) = &mut self.writeback else {
6807            return;
6808        };
6809        **writeback = Some(RequestInfo {
6810            protocol,
6811            flags: self.flags,
6812            name,
6813            lookup,
6814        })
6815    }
6816    pub fn buf(&self) -> &Vec<u8> {
6817        self.buf.buf()
6818    }
6819    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6820        self.buf.buf_mut()
6821    }
6822    #[doc = "Set `NLM_F_CREATE` flag"]
6823    pub fn set_create(mut self) -> Self {
6824        self.flags |= consts::NLM_F_CREATE as u16;
6825        self
6826    }
6827    #[doc = "Set `NLM_F_EXCL` flag"]
6828    pub fn set_excl(mut self) -> Self {
6829        self.flags |= consts::NLM_F_EXCL as u16;
6830        self
6831    }
6832    #[doc = "Set `NLM_F_REPLACE` flag"]
6833    pub fn set_replace(mut self) -> Self {
6834        self.flags |= consts::NLM_F_REPLACE as u16;
6835        self
6836    }
6837    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
6838    pub fn set_change(self) -> Self {
6839        self.set_create().set_replace()
6840    }
6841    #[doc = "Set `NLM_F_APPEND` flag"]
6842    pub fn set_append(mut self) -> Self {
6843        self.flags |= consts::NLM_F_APPEND as u16;
6844        self
6845    }
6846    #[doc = "Set `NLM_F_DUMP` flag"]
6847    fn set_dump(mut self) -> Self {
6848        self.flags |= consts::NLM_F_DUMP as u16;
6849        self
6850    }
6851    pub fn op_newneigh_do_request(self, header: &PushNdmsg) -> RequestOpNewneighDoRequest<'buf> {
6852        let mut res = RequestOpNewneighDoRequest::new(self, header);
6853        res.request.do_writeback(
6854            res.protocol(),
6855            "op-newneigh-do-request",
6856            RequestOpNewneighDoRequest::lookup,
6857        );
6858        res
6859    }
6860    pub fn op_delneigh_do_request(self, header: &PushNdmsg) -> RequestOpDelneighDoRequest<'buf> {
6861        let mut res = RequestOpDelneighDoRequest::new(self, header);
6862        res.request.do_writeback(
6863            res.protocol(),
6864            "op-delneigh-do-request",
6865            RequestOpDelneighDoRequest::lookup,
6866        );
6867        res
6868    }
6869    pub fn op_getneigh_dump_request(
6870        self,
6871        header: &PushNdmsg,
6872    ) -> RequestOpGetneighDumpRequest<'buf> {
6873        let mut res = RequestOpGetneighDumpRequest::new(self, header);
6874        res.request.do_writeback(
6875            res.protocol(),
6876            "op-getneigh-dump-request",
6877            RequestOpGetneighDumpRequest::lookup,
6878        );
6879        res
6880    }
6881    pub fn op_getneigh_do_request(self, header: &PushNdmsg) -> RequestOpGetneighDoRequest<'buf> {
6882        let mut res = RequestOpGetneighDoRequest::new(self, header);
6883        res.request.do_writeback(
6884            res.protocol(),
6885            "op-getneigh-do-request",
6886            RequestOpGetneighDoRequest::lookup,
6887        );
6888        res
6889    }
6890    pub fn op_getneightbl_dump_request(
6891        self,
6892        header: &PushNdtmsg,
6893    ) -> RequestOpGetneightblDumpRequest<'buf> {
6894        let mut res = RequestOpGetneightblDumpRequest::new(self, header);
6895        res.request.do_writeback(
6896            res.protocol(),
6897            "op-getneightbl-dump-request",
6898            RequestOpGetneightblDumpRequest::lookup,
6899        );
6900        res
6901    }
6902    pub fn op_setneightbl_do_request(
6903        self,
6904        header: &PushNdtmsg,
6905    ) -> RequestOpSetneightblDoRequest<'buf> {
6906        let mut res = RequestOpSetneightblDoRequest::new(self, header);
6907        res.request.do_writeback(
6908            res.protocol(),
6909            "op-setneightbl-do-request",
6910            RequestOpSetneightblDoRequest::lookup,
6911        );
6912        res
6913    }
6914}