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