Skip to main content

netlink_bindings/nlctrl/
mod.rs

1#![doc = "genetlink meta-family that exposes information about all genetlink\nfamilies registered in the kernel (including itself).\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12    consts,
13    traits::{NetlinkRequest, Protocol},
14    utils::*,
15};
16pub const PROTONAME: &str = "nlctrl";
17pub const PROTONAME_CSTR: &CStr = c"nlctrl";
18pub const PROTONUM: u16 = 0x10;
19#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
20#[derive(Debug, Clone, Copy)]
21pub enum OpFlags {
22    AdminPerm = 1 << 0,
23    CmdCapDo = 1 << 1,
24    CmdCapDump = 1 << 2,
25    CmdCapHaspol = 1 << 3,
26    UnsAdminPerm = 1 << 4,
27}
28impl OpFlags {
29    pub fn from_value(value: u64) -> Option<Self> {
30        Some(match value {
31            n if n == 1 << 0 => Self::AdminPerm,
32            n if n == 1 << 1 => Self::CmdCapDo,
33            n if n == 1 << 2 => Self::CmdCapDump,
34            n if n == 1 << 3 => Self::CmdCapHaspol,
35            n if n == 1 << 4 => Self::UnsAdminPerm,
36            _ => return None,
37        })
38    }
39}
40#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
41#[derive(Debug, Clone, Copy)]
42pub enum AttrType {
43    Invalid = 0,
44    Flag = 1,
45    U8 = 2,
46    U16 = 3,
47    U32 = 4,
48    U64 = 5,
49    S8 = 6,
50    S16 = 7,
51    S32 = 8,
52    S64 = 9,
53    Binary = 10,
54    String = 11,
55    NulString = 12,
56    Nested = 13,
57    NestedArray = 14,
58    Bitfield32 = 15,
59    Sint = 16,
60    Uint = 17,
61}
62impl AttrType {
63    pub fn from_value(value: u64) -> Option<Self> {
64        Some(match value {
65            0 => Self::Invalid,
66            1 => Self::Flag,
67            2 => Self::U8,
68            3 => Self::U16,
69            4 => Self::U32,
70            5 => Self::U64,
71            6 => Self::S8,
72            7 => Self::S16,
73            8 => Self::S32,
74            9 => Self::S64,
75            10 => Self::Binary,
76            11 => Self::String,
77            12 => Self::NulString,
78            13 => Self::Nested,
79            14 => Self::NestedArray,
80            15 => Self::Bitfield32,
81            16 => Self::Sint,
82            17 => Self::Uint,
83            _ => return None,
84        })
85    }
86}
87#[derive(Clone)]
88pub enum CtrlAttrs<'a> {
89    FamilyId(u16),
90    FamilyName(&'a CStr),
91    Version(u32),
92    Hdrsize(u32),
93    Maxattr(u32),
94    Ops(IterableArrayOpAttrs<'a>),
95    McastGroups(IterableArrayMcastGroupAttrs<'a>),
96    Policy(IterablePolicyAttrs<'a>),
97    OpPolicy(IterableOpPolicyAttrs<'a>),
98    Op(u32),
99}
100impl<'a> IterableCtrlAttrs<'a> {
101    pub fn get_family_id(&self) -> Result<u16, ErrorContext> {
102        let mut iter = self.clone();
103        iter.pos = 0;
104        for attr in iter {
105            if let Ok(CtrlAttrs::FamilyId(val)) = attr {
106                return Ok(val);
107            }
108        }
109        Err(ErrorContext::new_missing(
110            "CtrlAttrs",
111            "FamilyId",
112            self.orig_loc,
113            self.buf.as_ptr() as usize,
114        ))
115    }
116    pub fn get_family_name(&self) -> Result<&'a CStr, ErrorContext> {
117        let mut iter = self.clone();
118        iter.pos = 0;
119        for attr in iter {
120            if let Ok(CtrlAttrs::FamilyName(val)) = attr {
121                return Ok(val);
122            }
123        }
124        Err(ErrorContext::new_missing(
125            "CtrlAttrs",
126            "FamilyName",
127            self.orig_loc,
128            self.buf.as_ptr() as usize,
129        ))
130    }
131    pub fn get_version(&self) -> Result<u32, ErrorContext> {
132        let mut iter = self.clone();
133        iter.pos = 0;
134        for attr in iter {
135            if let Ok(CtrlAttrs::Version(val)) = attr {
136                return Ok(val);
137            }
138        }
139        Err(ErrorContext::new_missing(
140            "CtrlAttrs",
141            "Version",
142            self.orig_loc,
143            self.buf.as_ptr() as usize,
144        ))
145    }
146    pub fn get_hdrsize(&self) -> Result<u32, ErrorContext> {
147        let mut iter = self.clone();
148        iter.pos = 0;
149        for attr in iter {
150            if let Ok(CtrlAttrs::Hdrsize(val)) = attr {
151                return Ok(val);
152            }
153        }
154        Err(ErrorContext::new_missing(
155            "CtrlAttrs",
156            "Hdrsize",
157            self.orig_loc,
158            self.buf.as_ptr() as usize,
159        ))
160    }
161    pub fn get_maxattr(&self) -> Result<u32, ErrorContext> {
162        let mut iter = self.clone();
163        iter.pos = 0;
164        for attr in iter {
165            if let Ok(CtrlAttrs::Maxattr(val)) = attr {
166                return Ok(val);
167            }
168        }
169        Err(ErrorContext::new_missing(
170            "CtrlAttrs",
171            "Maxattr",
172            self.orig_loc,
173            self.buf.as_ptr() as usize,
174        ))
175    }
176    pub fn get_ops(
177        &self,
178    ) -> Result<ArrayIterable<IterableArrayOpAttrs<'a>, IterableOpAttrs<'a>>, ErrorContext> {
179        for attr in self.clone() {
180            if let Ok(CtrlAttrs::Ops(val)) = attr {
181                return Ok(ArrayIterable::new(val));
182            }
183        }
184        Err(ErrorContext::new_missing(
185            "CtrlAttrs",
186            "Ops",
187            self.orig_loc,
188            self.buf.as_ptr() as usize,
189        ))
190    }
191    pub fn get_mcast_groups(
192        &self,
193    ) -> Result<
194        ArrayIterable<IterableArrayMcastGroupAttrs<'a>, IterableMcastGroupAttrs<'a>>,
195        ErrorContext,
196    > {
197        for attr in self.clone() {
198            if let Ok(CtrlAttrs::McastGroups(val)) = attr {
199                return Ok(ArrayIterable::new(val));
200            }
201        }
202        Err(ErrorContext::new_missing(
203            "CtrlAttrs",
204            "McastGroups",
205            self.orig_loc,
206            self.buf.as_ptr() as usize,
207        ))
208    }
209    pub fn get_policy(&self) -> Result<IterablePolicyAttrs<'a>, ErrorContext> {
210        let mut iter = self.clone();
211        iter.pos = 0;
212        for attr in iter {
213            if let Ok(CtrlAttrs::Policy(val)) = attr {
214                return Ok(val);
215            }
216        }
217        Err(ErrorContext::new_missing(
218            "CtrlAttrs",
219            "Policy",
220            self.orig_loc,
221            self.buf.as_ptr() as usize,
222        ))
223    }
224    pub fn get_op_policy(&self) -> Result<IterableOpPolicyAttrs<'a>, ErrorContext> {
225        let mut iter = self.clone();
226        iter.pos = 0;
227        for attr in iter {
228            if let Ok(CtrlAttrs::OpPolicy(val)) = attr {
229                return Ok(val);
230            }
231        }
232        Err(ErrorContext::new_missing(
233            "CtrlAttrs",
234            "OpPolicy",
235            self.orig_loc,
236            self.buf.as_ptr() as usize,
237        ))
238    }
239    pub fn get_op(&self) -> Result<u32, ErrorContext> {
240        let mut iter = self.clone();
241        iter.pos = 0;
242        for attr in iter {
243            if let Ok(CtrlAttrs::Op(val)) = attr {
244                return Ok(val);
245            }
246        }
247        Err(ErrorContext::new_missing(
248            "CtrlAttrs",
249            "Op",
250            self.orig_loc,
251            self.buf.as_ptr() as usize,
252        ))
253    }
254}
255impl OpAttrs {
256    pub fn new_array(buf: &[u8]) -> IterableArrayOpAttrs<'_> {
257        IterableArrayOpAttrs::with_loc(buf, buf.as_ptr() as usize)
258    }
259}
260#[derive(Clone, Copy, Default)]
261pub struct IterableArrayOpAttrs<'a> {
262    buf: &'a [u8],
263    pos: usize,
264    orig_loc: usize,
265}
266impl<'a> IterableArrayOpAttrs<'a> {
267    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
268        Self {
269            buf,
270            pos: 0,
271            orig_loc,
272        }
273    }
274    pub fn get_buf(&self) -> &'a [u8] {
275        self.buf
276    }
277}
278impl<'a> Iterator for IterableArrayOpAttrs<'a> {
279    type Item = Result<IterableOpAttrs<'a>, ErrorContext>;
280    fn next(&mut self) -> Option<Self::Item> {
281        if self.buf.len() == self.pos {
282            return None;
283        }
284        while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
285            {
286                return Some(Ok(IterableOpAttrs::with_loc(next, self.orig_loc)));
287            }
288        }
289        let pos = self.pos;
290        self.pos = self.buf.len();
291        Some(Err(ErrorContext::new(
292            "OpAttrs",
293            None,
294            self.orig_loc,
295            self.buf.as_ptr().wrapping_add(pos) as usize,
296        )))
297    }
298}
299impl<'a> McastGroupAttrs<'a> {
300    pub fn new_array(buf: &[u8]) -> IterableArrayMcastGroupAttrs<'_> {
301        IterableArrayMcastGroupAttrs::with_loc(buf, buf.as_ptr() as usize)
302    }
303}
304#[derive(Clone, Copy, Default)]
305pub struct IterableArrayMcastGroupAttrs<'a> {
306    buf: &'a [u8],
307    pos: usize,
308    orig_loc: usize,
309}
310impl<'a> IterableArrayMcastGroupAttrs<'a> {
311    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
312        Self {
313            buf,
314            pos: 0,
315            orig_loc,
316        }
317    }
318    pub fn get_buf(&self) -> &'a [u8] {
319        self.buf
320    }
321}
322impl<'a> Iterator for IterableArrayMcastGroupAttrs<'a> {
323    type Item = Result<IterableMcastGroupAttrs<'a>, ErrorContext>;
324    fn next(&mut self) -> Option<Self::Item> {
325        if self.buf.len() == self.pos {
326            return None;
327        }
328        while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
329            {
330                return Some(Ok(IterableMcastGroupAttrs::with_loc(next, self.orig_loc)));
331            }
332        }
333        let pos = self.pos;
334        self.pos = self.buf.len();
335        Some(Err(ErrorContext::new(
336            "McastGroupAttrs",
337            None,
338            self.orig_loc,
339            self.buf.as_ptr().wrapping_add(pos) as usize,
340        )))
341    }
342}
343impl CtrlAttrs<'_> {
344    pub fn new<'a>(buf: &'a [u8]) -> IterableCtrlAttrs<'a> {
345        IterableCtrlAttrs::with_loc(buf, buf.as_ptr() as usize)
346    }
347    fn attr_from_type(r#type: u16) -> Option<&'static str> {
348        let res = match r#type {
349            1u16 => "FamilyId",
350            2u16 => "FamilyName",
351            3u16 => "Version",
352            4u16 => "Hdrsize",
353            5u16 => "Maxattr",
354            6u16 => "Ops",
355            7u16 => "McastGroups",
356            8u16 => "Policy",
357            9u16 => "OpPolicy",
358            10u16 => "Op",
359            _ => return None,
360        };
361        Some(res)
362    }
363}
364#[derive(Clone, Copy, Default)]
365pub struct IterableCtrlAttrs<'a> {
366    buf: &'a [u8],
367    pos: usize,
368    orig_loc: usize,
369}
370impl<'a> IterableCtrlAttrs<'a> {
371    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
372        Self {
373            buf,
374            pos: 0,
375            orig_loc,
376        }
377    }
378    pub fn get_buf(&self) -> &'a [u8] {
379        self.buf
380    }
381}
382impl<'a> Iterator for IterableCtrlAttrs<'a> {
383    type Item = Result<CtrlAttrs<'a>, ErrorContext>;
384    fn next(&mut self) -> Option<Self::Item> {
385        let mut pos;
386        let mut r#type;
387        loop {
388            pos = self.pos;
389            r#type = None;
390            if self.buf.len() == self.pos {
391                return None;
392            }
393            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
394                self.pos = self.buf.len();
395                break;
396            };
397            r#type = Some(header.r#type);
398            let res = match header.r#type {
399                1u16 => CtrlAttrs::FamilyId({
400                    let res = parse_u16(next);
401                    let Some(val) = res else { break };
402                    val
403                }),
404                2u16 => CtrlAttrs::FamilyName({
405                    let res = CStr::from_bytes_with_nul(next).ok();
406                    let Some(val) = res else { break };
407                    val
408                }),
409                3u16 => CtrlAttrs::Version({
410                    let res = parse_u32(next);
411                    let Some(val) = res else { break };
412                    val
413                }),
414                4u16 => CtrlAttrs::Hdrsize({
415                    let res = parse_u32(next);
416                    let Some(val) = res else { break };
417                    val
418                }),
419                5u16 => CtrlAttrs::Maxattr({
420                    let res = parse_u32(next);
421                    let Some(val) = res else { break };
422                    val
423                }),
424                6u16 => CtrlAttrs::Ops({
425                    let res = Some(IterableArrayOpAttrs::with_loc(next, self.orig_loc));
426                    let Some(val) = res else { break };
427                    val
428                }),
429                7u16 => CtrlAttrs::McastGroups({
430                    let res = Some(IterableArrayMcastGroupAttrs::with_loc(next, self.orig_loc));
431                    let Some(val) = res else { break };
432                    val
433                }),
434                8u16 => CtrlAttrs::Policy({
435                    let res = Some(IterablePolicyAttrs::with_loc(next, self.orig_loc));
436                    let Some(val) = res else { break };
437                    val
438                }),
439                9u16 => CtrlAttrs::OpPolicy({
440                    let res = Some(IterableOpPolicyAttrs::with_loc(next, self.orig_loc));
441                    let Some(val) = res else { break };
442                    val
443                }),
444                10u16 => CtrlAttrs::Op({
445                    let res = parse_u32(next);
446                    let Some(val) = res else { break };
447                    val
448                }),
449                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
450                n => continue,
451            };
452            return Some(Ok(res));
453        }
454        Some(Err(ErrorContext::new(
455            "CtrlAttrs",
456            r#type.and_then(|t| CtrlAttrs::attr_from_type(t)),
457            self.orig_loc,
458            self.buf.as_ptr().wrapping_add(pos) as usize,
459        )))
460    }
461}
462impl std::fmt::Debug for IterableArrayOpAttrs<'_> {
463    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
464        fmt.debug_list()
465            .entries(self.clone().map(FlattenErrorContext))
466            .finish()
467    }
468}
469impl std::fmt::Debug for IterableArrayMcastGroupAttrs<'_> {
470    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
471        fmt.debug_list()
472            .entries(self.clone().map(FlattenErrorContext))
473            .finish()
474    }
475}
476impl<'a> std::fmt::Debug for IterableCtrlAttrs<'_> {
477    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
478        let mut fmt = f.debug_struct("CtrlAttrs");
479        for attr in self.clone() {
480            let attr = match attr {
481                Ok(a) => a,
482                Err(err) => {
483                    fmt.finish()?;
484                    f.write_str("Err(")?;
485                    err.fmt(f)?;
486                    return f.write_str(")");
487                }
488            };
489            match attr {
490                CtrlAttrs::FamilyId(val) => fmt.field("FamilyId", &val),
491                CtrlAttrs::FamilyName(val) => fmt.field("FamilyName", &val),
492                CtrlAttrs::Version(val) => fmt.field("Version", &val),
493                CtrlAttrs::Hdrsize(val) => fmt.field("Hdrsize", &val),
494                CtrlAttrs::Maxattr(val) => fmt.field("Maxattr", &val),
495                CtrlAttrs::Ops(val) => fmt.field("Ops", &val),
496                CtrlAttrs::McastGroups(val) => fmt.field("McastGroups", &val),
497                CtrlAttrs::Policy(val) => fmt.field("Policy", &val),
498                CtrlAttrs::OpPolicy(val) => fmt.field("OpPolicy", &val),
499                CtrlAttrs::Op(val) => fmt.field("Op", &val),
500            };
501        }
502        fmt.finish()
503    }
504}
505impl IterableCtrlAttrs<'_> {
506    pub fn lookup_attr(
507        &self,
508        offset: usize,
509        missing_type: Option<u16>,
510    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
511        let mut stack = Vec::new();
512        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
513        if missing_type.is_some() && cur == offset {
514            stack.push(("CtrlAttrs", offset));
515            return (
516                stack,
517                missing_type.and_then(|t| CtrlAttrs::attr_from_type(t)),
518            );
519        }
520        if cur > offset || cur + self.buf.len() < offset {
521            return (stack, None);
522        }
523        let mut attrs = self.clone();
524        let mut last_off = cur + attrs.pos;
525        let mut missing = None;
526        while let Some(attr) = attrs.next() {
527            let Ok(attr) = attr else { break };
528            match attr {
529                CtrlAttrs::FamilyId(val) => {
530                    if last_off == offset {
531                        stack.push(("FamilyId", last_off));
532                        break;
533                    }
534                }
535                CtrlAttrs::FamilyName(val) => {
536                    if last_off == offset {
537                        stack.push(("FamilyName", last_off));
538                        break;
539                    }
540                }
541                CtrlAttrs::Version(val) => {
542                    if last_off == offset {
543                        stack.push(("Version", last_off));
544                        break;
545                    }
546                }
547                CtrlAttrs::Hdrsize(val) => {
548                    if last_off == offset {
549                        stack.push(("Hdrsize", last_off));
550                        break;
551                    }
552                }
553                CtrlAttrs::Maxattr(val) => {
554                    if last_off == offset {
555                        stack.push(("Maxattr", last_off));
556                        break;
557                    }
558                }
559                CtrlAttrs::Ops(val) => {
560                    for entry in val {
561                        let Ok(attr) = entry else { break };
562                        (stack, missing) = attr.lookup_attr(offset, missing_type);
563                        if !stack.is_empty() {
564                            break;
565                        }
566                    }
567                    if !stack.is_empty() {
568                        stack.push(("Ops", last_off));
569                        break;
570                    }
571                }
572                CtrlAttrs::McastGroups(val) => {
573                    for entry in val {
574                        let Ok(attr) = entry else { break };
575                        (stack, missing) = attr.lookup_attr(offset, missing_type);
576                        if !stack.is_empty() {
577                            break;
578                        }
579                    }
580                    if !stack.is_empty() {
581                        stack.push(("McastGroups", last_off));
582                        break;
583                    }
584                }
585                CtrlAttrs::Policy(val) => {
586                    (stack, missing) = val.lookup_attr(offset, missing_type);
587                    if !stack.is_empty() {
588                        break;
589                    }
590                }
591                CtrlAttrs::OpPolicy(val) => {
592                    (stack, missing) = val.lookup_attr(offset, missing_type);
593                    if !stack.is_empty() {
594                        break;
595                    }
596                }
597                CtrlAttrs::Op(val) => {
598                    if last_off == offset {
599                        stack.push(("Op", last_off));
600                        break;
601                    }
602                }
603                _ => {}
604            };
605            last_off = cur + attrs.pos;
606        }
607        if !stack.is_empty() {
608            stack.push(("CtrlAttrs", cur));
609        }
610        (stack, missing)
611    }
612}
613#[derive(Clone)]
614pub enum McastGroupAttrs<'a> {
615    Name(&'a CStr),
616    Id(u32),
617}
618impl<'a> IterableMcastGroupAttrs<'a> {
619    pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
620        let mut iter = self.clone();
621        iter.pos = 0;
622        for attr in iter {
623            if let Ok(McastGroupAttrs::Name(val)) = attr {
624                return Ok(val);
625            }
626        }
627        Err(ErrorContext::new_missing(
628            "McastGroupAttrs",
629            "Name",
630            self.orig_loc,
631            self.buf.as_ptr() as usize,
632        ))
633    }
634    pub fn get_id(&self) -> Result<u32, ErrorContext> {
635        let mut iter = self.clone();
636        iter.pos = 0;
637        for attr in iter {
638            if let Ok(McastGroupAttrs::Id(val)) = attr {
639                return Ok(val);
640            }
641        }
642        Err(ErrorContext::new_missing(
643            "McastGroupAttrs",
644            "Id",
645            self.orig_loc,
646            self.buf.as_ptr() as usize,
647        ))
648    }
649}
650impl McastGroupAttrs<'_> {
651    pub fn new<'a>(buf: &'a [u8]) -> IterableMcastGroupAttrs<'a> {
652        IterableMcastGroupAttrs::with_loc(buf, buf.as_ptr() as usize)
653    }
654    fn attr_from_type(r#type: u16) -> Option<&'static str> {
655        let res = match r#type {
656            1u16 => "Name",
657            2u16 => "Id",
658            _ => return None,
659        };
660        Some(res)
661    }
662}
663#[derive(Clone, Copy, Default)]
664pub struct IterableMcastGroupAttrs<'a> {
665    buf: &'a [u8],
666    pos: usize,
667    orig_loc: usize,
668}
669impl<'a> IterableMcastGroupAttrs<'a> {
670    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
671        Self {
672            buf,
673            pos: 0,
674            orig_loc,
675        }
676    }
677    pub fn get_buf(&self) -> &'a [u8] {
678        self.buf
679    }
680}
681impl<'a> Iterator for IterableMcastGroupAttrs<'a> {
682    type Item = Result<McastGroupAttrs<'a>, ErrorContext>;
683    fn next(&mut self) -> Option<Self::Item> {
684        let mut pos;
685        let mut r#type;
686        loop {
687            pos = self.pos;
688            r#type = None;
689            if self.buf.len() == self.pos {
690                return None;
691            }
692            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
693                self.pos = self.buf.len();
694                break;
695            };
696            r#type = Some(header.r#type);
697            let res = match header.r#type {
698                1u16 => McastGroupAttrs::Name({
699                    let res = CStr::from_bytes_with_nul(next).ok();
700                    let Some(val) = res else { break };
701                    val
702                }),
703                2u16 => McastGroupAttrs::Id({
704                    let res = parse_u32(next);
705                    let Some(val) = res else { break };
706                    val
707                }),
708                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
709                n => continue,
710            };
711            return Some(Ok(res));
712        }
713        Some(Err(ErrorContext::new(
714            "McastGroupAttrs",
715            r#type.and_then(|t| McastGroupAttrs::attr_from_type(t)),
716            self.orig_loc,
717            self.buf.as_ptr().wrapping_add(pos) as usize,
718        )))
719    }
720}
721impl<'a> std::fmt::Debug for IterableMcastGroupAttrs<'_> {
722    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
723        let mut fmt = f.debug_struct("McastGroupAttrs");
724        for attr in self.clone() {
725            let attr = match attr {
726                Ok(a) => a,
727                Err(err) => {
728                    fmt.finish()?;
729                    f.write_str("Err(")?;
730                    err.fmt(f)?;
731                    return f.write_str(")");
732                }
733            };
734            match attr {
735                McastGroupAttrs::Name(val) => fmt.field("Name", &val),
736                McastGroupAttrs::Id(val) => fmt.field("Id", &val),
737            };
738        }
739        fmt.finish()
740    }
741}
742impl IterableMcastGroupAttrs<'_> {
743    pub fn lookup_attr(
744        &self,
745        offset: usize,
746        missing_type: Option<u16>,
747    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
748        let mut stack = Vec::new();
749        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
750        if missing_type.is_some() && cur == offset {
751            stack.push(("McastGroupAttrs", offset));
752            return (
753                stack,
754                missing_type.and_then(|t| McastGroupAttrs::attr_from_type(t)),
755            );
756        }
757        if cur > offset || cur + self.buf.len() < offset {
758            return (stack, None);
759        }
760        let mut attrs = self.clone();
761        let mut last_off = cur + attrs.pos;
762        while let Some(attr) = attrs.next() {
763            let Ok(attr) = attr else { break };
764            match attr {
765                McastGroupAttrs::Name(val) => {
766                    if last_off == offset {
767                        stack.push(("Name", last_off));
768                        break;
769                    }
770                }
771                McastGroupAttrs::Id(val) => {
772                    if last_off == offset {
773                        stack.push(("Id", last_off));
774                        break;
775                    }
776                }
777                _ => {}
778            };
779            last_off = cur + attrs.pos;
780        }
781        if !stack.is_empty() {
782            stack.push(("McastGroupAttrs", cur));
783        }
784        (stack, None)
785    }
786}
787#[derive(Clone)]
788pub enum OpAttrs {
789    Id(u32),
790    #[doc = "Associated type: [`OpFlags`] (1 bit per enumeration)"]
791    Flags(u32),
792}
793impl<'a> IterableOpAttrs<'a> {
794    pub fn get_id(&self) -> Result<u32, ErrorContext> {
795        let mut iter = self.clone();
796        iter.pos = 0;
797        for attr in iter {
798            if let Ok(OpAttrs::Id(val)) = attr {
799                return Ok(val);
800            }
801        }
802        Err(ErrorContext::new_missing(
803            "OpAttrs",
804            "Id",
805            self.orig_loc,
806            self.buf.as_ptr() as usize,
807        ))
808    }
809    #[doc = "Associated type: [`OpFlags`] (1 bit per enumeration)"]
810    pub fn get_flags(&self) -> Result<u32, ErrorContext> {
811        let mut iter = self.clone();
812        iter.pos = 0;
813        for attr in iter {
814            if let Ok(OpAttrs::Flags(val)) = attr {
815                return Ok(val);
816            }
817        }
818        Err(ErrorContext::new_missing(
819            "OpAttrs",
820            "Flags",
821            self.orig_loc,
822            self.buf.as_ptr() as usize,
823        ))
824    }
825}
826impl OpAttrs {
827    pub fn new<'a>(buf: &'a [u8]) -> IterableOpAttrs<'a> {
828        IterableOpAttrs::with_loc(buf, buf.as_ptr() as usize)
829    }
830    fn attr_from_type(r#type: u16) -> Option<&'static str> {
831        let res = match r#type {
832            1u16 => "Id",
833            2u16 => "Flags",
834            _ => return None,
835        };
836        Some(res)
837    }
838}
839#[derive(Clone, Copy, Default)]
840pub struct IterableOpAttrs<'a> {
841    buf: &'a [u8],
842    pos: usize,
843    orig_loc: usize,
844}
845impl<'a> IterableOpAttrs<'a> {
846    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
847        Self {
848            buf,
849            pos: 0,
850            orig_loc,
851        }
852    }
853    pub fn get_buf(&self) -> &'a [u8] {
854        self.buf
855    }
856}
857impl<'a> Iterator for IterableOpAttrs<'a> {
858    type Item = Result<OpAttrs, ErrorContext>;
859    fn next(&mut self) -> Option<Self::Item> {
860        let mut pos;
861        let mut r#type;
862        loop {
863            pos = self.pos;
864            r#type = None;
865            if self.buf.len() == self.pos {
866                return None;
867            }
868            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
869                self.pos = self.buf.len();
870                break;
871            };
872            r#type = Some(header.r#type);
873            let res = match header.r#type {
874                1u16 => OpAttrs::Id({
875                    let res = parse_u32(next);
876                    let Some(val) = res else { break };
877                    val
878                }),
879                2u16 => OpAttrs::Flags({
880                    let res = parse_u32(next);
881                    let Some(val) = res else { break };
882                    val
883                }),
884                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
885                n => continue,
886            };
887            return Some(Ok(res));
888        }
889        Some(Err(ErrorContext::new(
890            "OpAttrs",
891            r#type.and_then(|t| OpAttrs::attr_from_type(t)),
892            self.orig_loc,
893            self.buf.as_ptr().wrapping_add(pos) as usize,
894        )))
895    }
896}
897impl std::fmt::Debug for IterableOpAttrs<'_> {
898    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
899        let mut fmt = f.debug_struct("OpAttrs");
900        for attr in self.clone() {
901            let attr = match attr {
902                Ok(a) => a,
903                Err(err) => {
904                    fmt.finish()?;
905                    f.write_str("Err(")?;
906                    err.fmt(f)?;
907                    return f.write_str(")");
908                }
909            };
910            match attr {
911                OpAttrs::Id(val) => fmt.field("Id", &val),
912                OpAttrs::Flags(val) => {
913                    fmt.field("Flags", &FormatFlags(val.into(), OpFlags::from_value))
914                }
915            };
916        }
917        fmt.finish()
918    }
919}
920impl IterableOpAttrs<'_> {
921    pub fn lookup_attr(
922        &self,
923        offset: usize,
924        missing_type: Option<u16>,
925    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
926        let mut stack = Vec::new();
927        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
928        if missing_type.is_some() && cur == offset {
929            stack.push(("OpAttrs", offset));
930            return (stack, missing_type.and_then(|t| OpAttrs::attr_from_type(t)));
931        }
932        if cur > offset || cur + self.buf.len() < offset {
933            return (stack, None);
934        }
935        let mut attrs = self.clone();
936        let mut last_off = cur + attrs.pos;
937        while let Some(attr) = attrs.next() {
938            let Ok(attr) = attr else { break };
939            match attr {
940                OpAttrs::Id(val) => {
941                    if last_off == offset {
942                        stack.push(("Id", last_off));
943                        break;
944                    }
945                }
946                OpAttrs::Flags(val) => {
947                    if last_off == offset {
948                        stack.push(("Flags", last_off));
949                        break;
950                    }
951                }
952                _ => {}
953            };
954            last_off = cur + attrs.pos;
955        }
956        if !stack.is_empty() {
957            stack.push(("OpAttrs", cur));
958        }
959        (stack, None)
960    }
961}
962#[derive(Clone)]
963pub enum PolicyAttrs<'a> {
964    #[doc = "Associated type: [`AttrType`] (enum)"]
965    Type(u32),
966    MinValueS(i64),
967    MaxValueS(i64),
968    MinValueU(u64),
969    MaxValueU(u64),
970    MinLength(u32),
971    MaxLength(u32),
972    PolicyIdx(u32),
973    PolicyMaxtype(u32),
974    Bitfield32Mask(u32),
975    Mask(u64),
976    Pad(&'a [u8]),
977}
978impl<'a> IterablePolicyAttrs<'a> {
979    #[doc = "Associated type: [`AttrType`] (enum)"]
980    pub fn get_type(&self) -> Result<u32, ErrorContext> {
981        let mut iter = self.clone();
982        iter.pos = 0;
983        for attr in iter {
984            if let Ok(PolicyAttrs::Type(val)) = attr {
985                return Ok(val);
986            }
987        }
988        Err(ErrorContext::new_missing(
989            "PolicyAttrs",
990            "Type",
991            self.orig_loc,
992            self.buf.as_ptr() as usize,
993        ))
994    }
995    pub fn get_min_value_s(&self) -> Result<i64, ErrorContext> {
996        let mut iter = self.clone();
997        iter.pos = 0;
998        for attr in iter {
999            if let Ok(PolicyAttrs::MinValueS(val)) = attr {
1000                return Ok(val);
1001            }
1002        }
1003        Err(ErrorContext::new_missing(
1004            "PolicyAttrs",
1005            "MinValueS",
1006            self.orig_loc,
1007            self.buf.as_ptr() as usize,
1008        ))
1009    }
1010    pub fn get_max_value_s(&self) -> Result<i64, ErrorContext> {
1011        let mut iter = self.clone();
1012        iter.pos = 0;
1013        for attr in iter {
1014            if let Ok(PolicyAttrs::MaxValueS(val)) = attr {
1015                return Ok(val);
1016            }
1017        }
1018        Err(ErrorContext::new_missing(
1019            "PolicyAttrs",
1020            "MaxValueS",
1021            self.orig_loc,
1022            self.buf.as_ptr() as usize,
1023        ))
1024    }
1025    pub fn get_min_value_u(&self) -> Result<u64, ErrorContext> {
1026        let mut iter = self.clone();
1027        iter.pos = 0;
1028        for attr in iter {
1029            if let Ok(PolicyAttrs::MinValueU(val)) = attr {
1030                return Ok(val);
1031            }
1032        }
1033        Err(ErrorContext::new_missing(
1034            "PolicyAttrs",
1035            "MinValueU",
1036            self.orig_loc,
1037            self.buf.as_ptr() as usize,
1038        ))
1039    }
1040    pub fn get_max_value_u(&self) -> Result<u64, ErrorContext> {
1041        let mut iter = self.clone();
1042        iter.pos = 0;
1043        for attr in iter {
1044            if let Ok(PolicyAttrs::MaxValueU(val)) = attr {
1045                return Ok(val);
1046            }
1047        }
1048        Err(ErrorContext::new_missing(
1049            "PolicyAttrs",
1050            "MaxValueU",
1051            self.orig_loc,
1052            self.buf.as_ptr() as usize,
1053        ))
1054    }
1055    pub fn get_min_length(&self) -> Result<u32, ErrorContext> {
1056        let mut iter = self.clone();
1057        iter.pos = 0;
1058        for attr in iter {
1059            if let Ok(PolicyAttrs::MinLength(val)) = attr {
1060                return Ok(val);
1061            }
1062        }
1063        Err(ErrorContext::new_missing(
1064            "PolicyAttrs",
1065            "MinLength",
1066            self.orig_loc,
1067            self.buf.as_ptr() as usize,
1068        ))
1069    }
1070    pub fn get_max_length(&self) -> Result<u32, ErrorContext> {
1071        let mut iter = self.clone();
1072        iter.pos = 0;
1073        for attr in iter {
1074            if let Ok(PolicyAttrs::MaxLength(val)) = attr {
1075                return Ok(val);
1076            }
1077        }
1078        Err(ErrorContext::new_missing(
1079            "PolicyAttrs",
1080            "MaxLength",
1081            self.orig_loc,
1082            self.buf.as_ptr() as usize,
1083        ))
1084    }
1085    pub fn get_policy_idx(&self) -> Result<u32, ErrorContext> {
1086        let mut iter = self.clone();
1087        iter.pos = 0;
1088        for attr in iter {
1089            if let Ok(PolicyAttrs::PolicyIdx(val)) = attr {
1090                return Ok(val);
1091            }
1092        }
1093        Err(ErrorContext::new_missing(
1094            "PolicyAttrs",
1095            "PolicyIdx",
1096            self.orig_loc,
1097            self.buf.as_ptr() as usize,
1098        ))
1099    }
1100    pub fn get_policy_maxtype(&self) -> Result<u32, ErrorContext> {
1101        let mut iter = self.clone();
1102        iter.pos = 0;
1103        for attr in iter {
1104            if let Ok(PolicyAttrs::PolicyMaxtype(val)) = attr {
1105                return Ok(val);
1106            }
1107        }
1108        Err(ErrorContext::new_missing(
1109            "PolicyAttrs",
1110            "PolicyMaxtype",
1111            self.orig_loc,
1112            self.buf.as_ptr() as usize,
1113        ))
1114    }
1115    pub fn get_bitfield32_mask(&self) -> Result<u32, ErrorContext> {
1116        let mut iter = self.clone();
1117        iter.pos = 0;
1118        for attr in iter {
1119            if let Ok(PolicyAttrs::Bitfield32Mask(val)) = attr {
1120                return Ok(val);
1121            }
1122        }
1123        Err(ErrorContext::new_missing(
1124            "PolicyAttrs",
1125            "Bitfield32Mask",
1126            self.orig_loc,
1127            self.buf.as_ptr() as usize,
1128        ))
1129    }
1130    pub fn get_mask(&self) -> Result<u64, ErrorContext> {
1131        let mut iter = self.clone();
1132        iter.pos = 0;
1133        for attr in iter {
1134            if let Ok(PolicyAttrs::Mask(val)) = attr {
1135                return Ok(val);
1136            }
1137        }
1138        Err(ErrorContext::new_missing(
1139            "PolicyAttrs",
1140            "Mask",
1141            self.orig_loc,
1142            self.buf.as_ptr() as usize,
1143        ))
1144    }
1145    pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
1146        let mut iter = self.clone();
1147        iter.pos = 0;
1148        for attr in iter {
1149            if let Ok(PolicyAttrs::Pad(val)) = attr {
1150                return Ok(val);
1151            }
1152        }
1153        Err(ErrorContext::new_missing(
1154            "PolicyAttrs",
1155            "Pad",
1156            self.orig_loc,
1157            self.buf.as_ptr() as usize,
1158        ))
1159    }
1160}
1161impl PolicyAttrs<'_> {
1162    pub fn new<'a>(buf: &'a [u8]) -> IterablePolicyAttrs<'a> {
1163        IterablePolicyAttrs::with_loc(buf, buf.as_ptr() as usize)
1164    }
1165    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1166        let res = match r#type {
1167            1u16 => "Type",
1168            2u16 => "MinValueS",
1169            3u16 => "MaxValueS",
1170            4u16 => "MinValueU",
1171            5u16 => "MaxValueU",
1172            6u16 => "MinLength",
1173            7u16 => "MaxLength",
1174            8u16 => "PolicyIdx",
1175            9u16 => "PolicyMaxtype",
1176            10u16 => "Bitfield32Mask",
1177            11u16 => "Mask",
1178            12u16 => "Pad",
1179            _ => return None,
1180        };
1181        Some(res)
1182    }
1183}
1184#[derive(Clone, Copy, Default)]
1185pub struct IterablePolicyAttrs<'a> {
1186    buf: &'a [u8],
1187    pos: usize,
1188    orig_loc: usize,
1189}
1190impl<'a> IterablePolicyAttrs<'a> {
1191    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1192        Self {
1193            buf,
1194            pos: 0,
1195            orig_loc,
1196        }
1197    }
1198    pub fn get_buf(&self) -> &'a [u8] {
1199        self.buf
1200    }
1201}
1202impl<'a> Iterator for IterablePolicyAttrs<'a> {
1203    type Item = Result<PolicyAttrs<'a>, ErrorContext>;
1204    fn next(&mut self) -> Option<Self::Item> {
1205        let mut pos;
1206        let mut r#type;
1207        loop {
1208            pos = self.pos;
1209            r#type = None;
1210            if self.buf.len() == self.pos {
1211                return None;
1212            }
1213            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1214                self.pos = self.buf.len();
1215                break;
1216            };
1217            r#type = Some(header.r#type);
1218            let res = match header.r#type {
1219                1u16 => PolicyAttrs::Type({
1220                    let res = parse_u32(next);
1221                    let Some(val) = res else { break };
1222                    val
1223                }),
1224                2u16 => PolicyAttrs::MinValueS({
1225                    let res = parse_i64(next);
1226                    let Some(val) = res else { break };
1227                    val
1228                }),
1229                3u16 => PolicyAttrs::MaxValueS({
1230                    let res = parse_i64(next);
1231                    let Some(val) = res else { break };
1232                    val
1233                }),
1234                4u16 => PolicyAttrs::MinValueU({
1235                    let res = parse_u64(next);
1236                    let Some(val) = res else { break };
1237                    val
1238                }),
1239                5u16 => PolicyAttrs::MaxValueU({
1240                    let res = parse_u64(next);
1241                    let Some(val) = res else { break };
1242                    val
1243                }),
1244                6u16 => PolicyAttrs::MinLength({
1245                    let res = parse_u32(next);
1246                    let Some(val) = res else { break };
1247                    val
1248                }),
1249                7u16 => PolicyAttrs::MaxLength({
1250                    let res = parse_u32(next);
1251                    let Some(val) = res else { break };
1252                    val
1253                }),
1254                8u16 => PolicyAttrs::PolicyIdx({
1255                    let res = parse_u32(next);
1256                    let Some(val) = res else { break };
1257                    val
1258                }),
1259                9u16 => PolicyAttrs::PolicyMaxtype({
1260                    let res = parse_u32(next);
1261                    let Some(val) = res else { break };
1262                    val
1263                }),
1264                10u16 => PolicyAttrs::Bitfield32Mask({
1265                    let res = parse_u32(next);
1266                    let Some(val) = res else { break };
1267                    val
1268                }),
1269                11u16 => PolicyAttrs::Mask({
1270                    let res = parse_u64(next);
1271                    let Some(val) = res else { break };
1272                    val
1273                }),
1274                12u16 => PolicyAttrs::Pad({
1275                    let res = Some(next);
1276                    let Some(val) = res else { break };
1277                    val
1278                }),
1279                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1280                n => continue,
1281            };
1282            return Some(Ok(res));
1283        }
1284        Some(Err(ErrorContext::new(
1285            "PolicyAttrs",
1286            r#type.and_then(|t| PolicyAttrs::attr_from_type(t)),
1287            self.orig_loc,
1288            self.buf.as_ptr().wrapping_add(pos) as usize,
1289        )))
1290    }
1291}
1292impl<'a> std::fmt::Debug for IterablePolicyAttrs<'_> {
1293    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1294        let mut fmt = f.debug_struct("PolicyAttrs");
1295        for attr in self.clone() {
1296            let attr = match attr {
1297                Ok(a) => a,
1298                Err(err) => {
1299                    fmt.finish()?;
1300                    f.write_str("Err(")?;
1301                    err.fmt(f)?;
1302                    return f.write_str(")");
1303                }
1304            };
1305            match attr {
1306                PolicyAttrs::Type(val) => {
1307                    fmt.field("Type", &FormatEnum(val.into(), AttrType::from_value))
1308                }
1309                PolicyAttrs::MinValueS(val) => fmt.field("MinValueS", &val),
1310                PolicyAttrs::MaxValueS(val) => fmt.field("MaxValueS", &val),
1311                PolicyAttrs::MinValueU(val) => fmt.field("MinValueU", &val),
1312                PolicyAttrs::MaxValueU(val) => fmt.field("MaxValueU", &val),
1313                PolicyAttrs::MinLength(val) => fmt.field("MinLength", &val),
1314                PolicyAttrs::MaxLength(val) => fmt.field("MaxLength", &val),
1315                PolicyAttrs::PolicyIdx(val) => fmt.field("PolicyIdx", &val),
1316                PolicyAttrs::PolicyMaxtype(val) => fmt.field("PolicyMaxtype", &val),
1317                PolicyAttrs::Bitfield32Mask(val) => fmt.field("Bitfield32Mask", &val),
1318                PolicyAttrs::Mask(val) => fmt.field("Mask", &val),
1319                PolicyAttrs::Pad(val) => fmt.field("Pad", &val),
1320            };
1321        }
1322        fmt.finish()
1323    }
1324}
1325impl IterablePolicyAttrs<'_> {
1326    pub fn lookup_attr(
1327        &self,
1328        offset: usize,
1329        missing_type: Option<u16>,
1330    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1331        let mut stack = Vec::new();
1332        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1333        if missing_type.is_some() && cur == offset {
1334            stack.push(("PolicyAttrs", offset));
1335            return (
1336                stack,
1337                missing_type.and_then(|t| PolicyAttrs::attr_from_type(t)),
1338            );
1339        }
1340        if cur > offset || cur + self.buf.len() < offset {
1341            return (stack, None);
1342        }
1343        let mut attrs = self.clone();
1344        let mut last_off = cur + attrs.pos;
1345        while let Some(attr) = attrs.next() {
1346            let Ok(attr) = attr else { break };
1347            match attr {
1348                PolicyAttrs::Type(val) => {
1349                    if last_off == offset {
1350                        stack.push(("Type", last_off));
1351                        break;
1352                    }
1353                }
1354                PolicyAttrs::MinValueS(val) => {
1355                    if last_off == offset {
1356                        stack.push(("MinValueS", last_off));
1357                        break;
1358                    }
1359                }
1360                PolicyAttrs::MaxValueS(val) => {
1361                    if last_off == offset {
1362                        stack.push(("MaxValueS", last_off));
1363                        break;
1364                    }
1365                }
1366                PolicyAttrs::MinValueU(val) => {
1367                    if last_off == offset {
1368                        stack.push(("MinValueU", last_off));
1369                        break;
1370                    }
1371                }
1372                PolicyAttrs::MaxValueU(val) => {
1373                    if last_off == offset {
1374                        stack.push(("MaxValueU", last_off));
1375                        break;
1376                    }
1377                }
1378                PolicyAttrs::MinLength(val) => {
1379                    if last_off == offset {
1380                        stack.push(("MinLength", last_off));
1381                        break;
1382                    }
1383                }
1384                PolicyAttrs::MaxLength(val) => {
1385                    if last_off == offset {
1386                        stack.push(("MaxLength", last_off));
1387                        break;
1388                    }
1389                }
1390                PolicyAttrs::PolicyIdx(val) => {
1391                    if last_off == offset {
1392                        stack.push(("PolicyIdx", last_off));
1393                        break;
1394                    }
1395                }
1396                PolicyAttrs::PolicyMaxtype(val) => {
1397                    if last_off == offset {
1398                        stack.push(("PolicyMaxtype", last_off));
1399                        break;
1400                    }
1401                }
1402                PolicyAttrs::Bitfield32Mask(val) => {
1403                    if last_off == offset {
1404                        stack.push(("Bitfield32Mask", last_off));
1405                        break;
1406                    }
1407                }
1408                PolicyAttrs::Mask(val) => {
1409                    if last_off == offset {
1410                        stack.push(("Mask", last_off));
1411                        break;
1412                    }
1413                }
1414                PolicyAttrs::Pad(val) => {
1415                    if last_off == offset {
1416                        stack.push(("Pad", last_off));
1417                        break;
1418                    }
1419                }
1420                _ => {}
1421            };
1422            last_off = cur + attrs.pos;
1423        }
1424        if !stack.is_empty() {
1425            stack.push(("PolicyAttrs", cur));
1426        }
1427        (stack, None)
1428    }
1429}
1430#[derive(Clone)]
1431pub enum OpPolicyAttrs {
1432    Do(u32),
1433    Dump(u32),
1434}
1435impl<'a> IterableOpPolicyAttrs<'a> {
1436    pub fn get_do(&self) -> Result<u32, ErrorContext> {
1437        let mut iter = self.clone();
1438        iter.pos = 0;
1439        for attr in iter {
1440            if let Ok(OpPolicyAttrs::Do(val)) = attr {
1441                return Ok(val);
1442            }
1443        }
1444        Err(ErrorContext::new_missing(
1445            "OpPolicyAttrs",
1446            "Do",
1447            self.orig_loc,
1448            self.buf.as_ptr() as usize,
1449        ))
1450    }
1451    pub fn get_dump(&self) -> Result<u32, ErrorContext> {
1452        let mut iter = self.clone();
1453        iter.pos = 0;
1454        for attr in iter {
1455            if let Ok(OpPolicyAttrs::Dump(val)) = attr {
1456                return Ok(val);
1457            }
1458        }
1459        Err(ErrorContext::new_missing(
1460            "OpPolicyAttrs",
1461            "Dump",
1462            self.orig_loc,
1463            self.buf.as_ptr() as usize,
1464        ))
1465    }
1466}
1467impl OpPolicyAttrs {
1468    pub fn new<'a>(buf: &'a [u8]) -> IterableOpPolicyAttrs<'a> {
1469        IterableOpPolicyAttrs::with_loc(buf, buf.as_ptr() as usize)
1470    }
1471    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1472        let res = match r#type {
1473            1u16 => "Do",
1474            2u16 => "Dump",
1475            _ => return None,
1476        };
1477        Some(res)
1478    }
1479}
1480#[derive(Clone, Copy, Default)]
1481pub struct IterableOpPolicyAttrs<'a> {
1482    buf: &'a [u8],
1483    pos: usize,
1484    orig_loc: usize,
1485}
1486impl<'a> IterableOpPolicyAttrs<'a> {
1487    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1488        Self {
1489            buf,
1490            pos: 0,
1491            orig_loc,
1492        }
1493    }
1494    pub fn get_buf(&self) -> &'a [u8] {
1495        self.buf
1496    }
1497}
1498impl<'a> Iterator for IterableOpPolicyAttrs<'a> {
1499    type Item = Result<OpPolicyAttrs, ErrorContext>;
1500    fn next(&mut self) -> Option<Self::Item> {
1501        let mut pos;
1502        let mut r#type;
1503        loop {
1504            pos = self.pos;
1505            r#type = None;
1506            if self.buf.len() == self.pos {
1507                return None;
1508            }
1509            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1510                self.pos = self.buf.len();
1511                break;
1512            };
1513            r#type = Some(header.r#type);
1514            let res = match header.r#type {
1515                1u16 => OpPolicyAttrs::Do({
1516                    let res = parse_u32(next);
1517                    let Some(val) = res else { break };
1518                    val
1519                }),
1520                2u16 => OpPolicyAttrs::Dump({
1521                    let res = parse_u32(next);
1522                    let Some(val) = res else { break };
1523                    val
1524                }),
1525                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1526                n => continue,
1527            };
1528            return Some(Ok(res));
1529        }
1530        Some(Err(ErrorContext::new(
1531            "OpPolicyAttrs",
1532            r#type.and_then(|t| OpPolicyAttrs::attr_from_type(t)),
1533            self.orig_loc,
1534            self.buf.as_ptr().wrapping_add(pos) as usize,
1535        )))
1536    }
1537}
1538impl std::fmt::Debug for IterableOpPolicyAttrs<'_> {
1539    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1540        let mut fmt = f.debug_struct("OpPolicyAttrs");
1541        for attr in self.clone() {
1542            let attr = match attr {
1543                Ok(a) => a,
1544                Err(err) => {
1545                    fmt.finish()?;
1546                    f.write_str("Err(")?;
1547                    err.fmt(f)?;
1548                    return f.write_str(")");
1549                }
1550            };
1551            match attr {
1552                OpPolicyAttrs::Do(val) => fmt.field("Do", &val),
1553                OpPolicyAttrs::Dump(val) => fmt.field("Dump", &val),
1554            };
1555        }
1556        fmt.finish()
1557    }
1558}
1559impl IterableOpPolicyAttrs<'_> {
1560    pub fn lookup_attr(
1561        &self,
1562        offset: usize,
1563        missing_type: Option<u16>,
1564    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1565        let mut stack = Vec::new();
1566        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1567        if missing_type.is_some() && cur == offset {
1568            stack.push(("OpPolicyAttrs", offset));
1569            return (
1570                stack,
1571                missing_type.and_then(|t| OpPolicyAttrs::attr_from_type(t)),
1572            );
1573        }
1574        if cur > offset || cur + self.buf.len() < offset {
1575            return (stack, None);
1576        }
1577        let mut attrs = self.clone();
1578        let mut last_off = cur + attrs.pos;
1579        while let Some(attr) = attrs.next() {
1580            let Ok(attr) = attr else { break };
1581            match attr {
1582                OpPolicyAttrs::Do(val) => {
1583                    if last_off == offset {
1584                        stack.push(("Do", last_off));
1585                        break;
1586                    }
1587                }
1588                OpPolicyAttrs::Dump(val) => {
1589                    if last_off == offset {
1590                        stack.push(("Dump", last_off));
1591                        break;
1592                    }
1593                }
1594                _ => {}
1595            };
1596            last_off = cur + attrs.pos;
1597        }
1598        if !stack.is_empty() {
1599            stack.push(("OpPolicyAttrs", cur));
1600        }
1601        (stack, None)
1602    }
1603}
1604pub struct PushCtrlAttrs<Prev: Rec> {
1605    pub(crate) prev: Option<Prev>,
1606    pub(crate) header_offset: Option<usize>,
1607}
1608impl<Prev: Rec> Rec for PushCtrlAttrs<Prev> {
1609    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1610        self.prev.as_mut().unwrap().as_rec_mut()
1611    }
1612    fn as_rec(&self) -> &Vec<u8> {
1613        self.prev.as_ref().unwrap().as_rec()
1614    }
1615}
1616pub struct PushArrayOpAttrs<Prev: Rec> {
1617    pub(crate) prev: Option<Prev>,
1618    pub(crate) header_offset: Option<usize>,
1619    pub(crate) counter: u16,
1620}
1621impl<Prev: Rec> Rec for PushArrayOpAttrs<Prev> {
1622    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1623        self.prev.as_mut().unwrap().as_rec_mut()
1624    }
1625    fn as_rec(&self) -> &Vec<u8> {
1626        self.prev.as_ref().unwrap().as_rec()
1627    }
1628}
1629impl<Prev: Rec> PushArrayOpAttrs<Prev> {
1630    pub fn new(prev: Prev) -> Self {
1631        Self {
1632            prev: Some(prev),
1633            header_offset: None,
1634            counter: 0,
1635        }
1636    }
1637    pub fn end_array(mut self) -> Prev {
1638        let mut prev = self.prev.take().unwrap();
1639        if let Some(header_offset) = &self.header_offset {
1640            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1641        }
1642        prev
1643    }
1644    pub fn entry_nested(mut self) -> PushOpAttrs<Self> {
1645        let index = self.counter;
1646        self.counter += 1;
1647        let header_offset = push_nested_header(self.as_rec_mut(), index);
1648        PushOpAttrs {
1649            prev: Some(self),
1650            header_offset: Some(header_offset),
1651        }
1652    }
1653}
1654impl<Prev: Rec> Drop for PushArrayOpAttrs<Prev> {
1655    fn drop(&mut self) {
1656        if let Some(prev) = &mut self.prev {
1657            if let Some(header_offset) = &self.header_offset {
1658                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1659            }
1660        }
1661    }
1662}
1663pub struct PushArrayMcastGroupAttrs<Prev: Rec> {
1664    pub(crate) prev: Option<Prev>,
1665    pub(crate) header_offset: Option<usize>,
1666    pub(crate) counter: u16,
1667}
1668impl<Prev: Rec> Rec for PushArrayMcastGroupAttrs<Prev> {
1669    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1670        self.prev.as_mut().unwrap().as_rec_mut()
1671    }
1672    fn as_rec(&self) -> &Vec<u8> {
1673        self.prev.as_ref().unwrap().as_rec()
1674    }
1675}
1676impl<Prev: Rec> PushArrayMcastGroupAttrs<Prev> {
1677    pub fn new(prev: Prev) -> Self {
1678        Self {
1679            prev: Some(prev),
1680            header_offset: None,
1681            counter: 0,
1682        }
1683    }
1684    pub fn end_array(mut self) -> Prev {
1685        let mut prev = self.prev.take().unwrap();
1686        if let Some(header_offset) = &self.header_offset {
1687            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1688        }
1689        prev
1690    }
1691    pub fn entry_nested(mut self) -> PushMcastGroupAttrs<Self> {
1692        let index = self.counter;
1693        self.counter += 1;
1694        let header_offset = push_nested_header(self.as_rec_mut(), index);
1695        PushMcastGroupAttrs {
1696            prev: Some(self),
1697            header_offset: Some(header_offset),
1698        }
1699    }
1700}
1701impl<Prev: Rec> Drop for PushArrayMcastGroupAttrs<Prev> {
1702    fn drop(&mut self) {
1703        if let Some(prev) = &mut self.prev {
1704            if let Some(header_offset) = &self.header_offset {
1705                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1706            }
1707        }
1708    }
1709}
1710impl<Prev: Rec> PushCtrlAttrs<Prev> {
1711    pub fn new(prev: Prev) -> Self {
1712        Self {
1713            prev: Some(prev),
1714            header_offset: None,
1715        }
1716    }
1717    pub fn end_nested(mut self) -> Prev {
1718        let mut prev = self.prev.take().unwrap();
1719        if let Some(header_offset) = &self.header_offset {
1720            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1721        }
1722        prev
1723    }
1724    pub fn push_family_id(mut self, value: u16) -> Self {
1725        push_header(self.as_rec_mut(), 1u16, 2 as u16);
1726        self.as_rec_mut().extend(value.to_ne_bytes());
1727        self
1728    }
1729    pub fn push_family_name(mut self, value: &CStr) -> Self {
1730        push_header(
1731            self.as_rec_mut(),
1732            2u16,
1733            value.to_bytes_with_nul().len() as u16,
1734        );
1735        self.as_rec_mut().extend(value.to_bytes_with_nul());
1736        self
1737    }
1738    pub fn push_family_name_bytes(mut self, value: &[u8]) -> Self {
1739        push_header(self.as_rec_mut(), 2u16, (value.len() + 1) as u16);
1740        self.as_rec_mut().extend(value);
1741        self.as_rec_mut().push(0);
1742        self
1743    }
1744    pub fn push_version(mut self, value: u32) -> Self {
1745        push_header(self.as_rec_mut(), 3u16, 4 as u16);
1746        self.as_rec_mut().extend(value.to_ne_bytes());
1747        self
1748    }
1749    pub fn push_hdrsize(mut self, value: u32) -> Self {
1750        push_header(self.as_rec_mut(), 4u16, 4 as u16);
1751        self.as_rec_mut().extend(value.to_ne_bytes());
1752        self
1753    }
1754    pub fn push_maxattr(mut self, value: u32) -> Self {
1755        push_header(self.as_rec_mut(), 5u16, 4 as u16);
1756        self.as_rec_mut().extend(value.to_ne_bytes());
1757        self
1758    }
1759    pub fn array_ops(mut self) -> PushArrayOpAttrs<Self> {
1760        let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
1761        PushArrayOpAttrs {
1762            prev: Some(self),
1763            header_offset: Some(header_offset),
1764            counter: 0,
1765        }
1766    }
1767    pub fn array_mcast_groups(mut self) -> PushArrayMcastGroupAttrs<Self> {
1768        let header_offset = push_nested_header(self.as_rec_mut(), 7u16);
1769        PushArrayMcastGroupAttrs {
1770            prev: Some(self),
1771            header_offset: Some(header_offset),
1772            counter: 0,
1773        }
1774    }
1775    pub fn nested_policy(mut self) -> PushPolicyAttrs<Self> {
1776        let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
1777        PushPolicyAttrs {
1778            prev: Some(self),
1779            header_offset: Some(header_offset),
1780        }
1781    }
1782    pub fn nested_op_policy(mut self) -> PushOpPolicyAttrs<Self> {
1783        let header_offset = push_nested_header(self.as_rec_mut(), 9u16);
1784        PushOpPolicyAttrs {
1785            prev: Some(self),
1786            header_offset: Some(header_offset),
1787        }
1788    }
1789    pub fn push_op(mut self, value: u32) -> Self {
1790        push_header(self.as_rec_mut(), 10u16, 4 as u16);
1791        self.as_rec_mut().extend(value.to_ne_bytes());
1792        self
1793    }
1794}
1795impl<Prev: Rec> Drop for PushCtrlAttrs<Prev> {
1796    fn drop(&mut self) {
1797        if let Some(prev) = &mut self.prev {
1798            if let Some(header_offset) = &self.header_offset {
1799                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1800            }
1801        }
1802    }
1803}
1804pub struct PushMcastGroupAttrs<Prev: Rec> {
1805    pub(crate) prev: Option<Prev>,
1806    pub(crate) header_offset: Option<usize>,
1807}
1808impl<Prev: Rec> Rec for PushMcastGroupAttrs<Prev> {
1809    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1810        self.prev.as_mut().unwrap().as_rec_mut()
1811    }
1812    fn as_rec(&self) -> &Vec<u8> {
1813        self.prev.as_ref().unwrap().as_rec()
1814    }
1815}
1816impl<Prev: Rec> PushMcastGroupAttrs<Prev> {
1817    pub fn new(prev: Prev) -> Self {
1818        Self {
1819            prev: Some(prev),
1820            header_offset: None,
1821        }
1822    }
1823    pub fn end_nested(mut self) -> Prev {
1824        let mut prev = self.prev.take().unwrap();
1825        if let Some(header_offset) = &self.header_offset {
1826            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1827        }
1828        prev
1829    }
1830    pub fn push_name(mut self, value: &CStr) -> Self {
1831        push_header(
1832            self.as_rec_mut(),
1833            1u16,
1834            value.to_bytes_with_nul().len() as u16,
1835        );
1836        self.as_rec_mut().extend(value.to_bytes_with_nul());
1837        self
1838    }
1839    pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
1840        push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
1841        self.as_rec_mut().extend(value);
1842        self.as_rec_mut().push(0);
1843        self
1844    }
1845    pub fn push_id(mut self, value: u32) -> Self {
1846        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1847        self.as_rec_mut().extend(value.to_ne_bytes());
1848        self
1849    }
1850}
1851impl<Prev: Rec> Drop for PushMcastGroupAttrs<Prev> {
1852    fn drop(&mut self) {
1853        if let Some(prev) = &mut self.prev {
1854            if let Some(header_offset) = &self.header_offset {
1855                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1856            }
1857        }
1858    }
1859}
1860pub struct PushOpAttrs<Prev: Rec> {
1861    pub(crate) prev: Option<Prev>,
1862    pub(crate) header_offset: Option<usize>,
1863}
1864impl<Prev: Rec> Rec for PushOpAttrs<Prev> {
1865    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1866        self.prev.as_mut().unwrap().as_rec_mut()
1867    }
1868    fn as_rec(&self) -> &Vec<u8> {
1869        self.prev.as_ref().unwrap().as_rec()
1870    }
1871}
1872impl<Prev: Rec> PushOpAttrs<Prev> {
1873    pub fn new(prev: Prev) -> Self {
1874        Self {
1875            prev: Some(prev),
1876            header_offset: None,
1877        }
1878    }
1879    pub fn end_nested(mut self) -> Prev {
1880        let mut prev = self.prev.take().unwrap();
1881        if let Some(header_offset) = &self.header_offset {
1882            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1883        }
1884        prev
1885    }
1886    pub fn push_id(mut self, value: u32) -> Self {
1887        push_header(self.as_rec_mut(), 1u16, 4 as u16);
1888        self.as_rec_mut().extend(value.to_ne_bytes());
1889        self
1890    }
1891    #[doc = "Associated type: [`OpFlags`] (1 bit per enumeration)"]
1892    pub fn push_flags(mut self, value: u32) -> Self {
1893        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1894        self.as_rec_mut().extend(value.to_ne_bytes());
1895        self
1896    }
1897}
1898impl<Prev: Rec> Drop for PushOpAttrs<Prev> {
1899    fn drop(&mut self) {
1900        if let Some(prev) = &mut self.prev {
1901            if let Some(header_offset) = &self.header_offset {
1902                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1903            }
1904        }
1905    }
1906}
1907pub struct PushPolicyAttrs<Prev: Rec> {
1908    pub(crate) prev: Option<Prev>,
1909    pub(crate) header_offset: Option<usize>,
1910}
1911impl<Prev: Rec> Rec for PushPolicyAttrs<Prev> {
1912    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1913        self.prev.as_mut().unwrap().as_rec_mut()
1914    }
1915    fn as_rec(&self) -> &Vec<u8> {
1916        self.prev.as_ref().unwrap().as_rec()
1917    }
1918}
1919impl<Prev: Rec> PushPolicyAttrs<Prev> {
1920    pub fn new(prev: Prev) -> Self {
1921        Self {
1922            prev: Some(prev),
1923            header_offset: None,
1924        }
1925    }
1926    pub fn end_nested(mut self) -> Prev {
1927        let mut prev = self.prev.take().unwrap();
1928        if let Some(header_offset) = &self.header_offset {
1929            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1930        }
1931        prev
1932    }
1933    #[doc = "Associated type: [`AttrType`] (enum)"]
1934    pub fn push_type(mut self, value: u32) -> Self {
1935        push_header(self.as_rec_mut(), 1u16, 4 as u16);
1936        self.as_rec_mut().extend(value.to_ne_bytes());
1937        self
1938    }
1939    pub fn push_min_value_s(mut self, value: i64) -> Self {
1940        push_header(self.as_rec_mut(), 2u16, 8 as u16);
1941        self.as_rec_mut().extend(value.to_ne_bytes());
1942        self
1943    }
1944    pub fn push_max_value_s(mut self, value: i64) -> Self {
1945        push_header(self.as_rec_mut(), 3u16, 8 as u16);
1946        self.as_rec_mut().extend(value.to_ne_bytes());
1947        self
1948    }
1949    pub fn push_min_value_u(mut self, value: u64) -> Self {
1950        push_header(self.as_rec_mut(), 4u16, 8 as u16);
1951        self.as_rec_mut().extend(value.to_ne_bytes());
1952        self
1953    }
1954    pub fn push_max_value_u(mut self, value: u64) -> Self {
1955        push_header(self.as_rec_mut(), 5u16, 8 as u16);
1956        self.as_rec_mut().extend(value.to_ne_bytes());
1957        self
1958    }
1959    pub fn push_min_length(mut self, value: u32) -> Self {
1960        push_header(self.as_rec_mut(), 6u16, 4 as u16);
1961        self.as_rec_mut().extend(value.to_ne_bytes());
1962        self
1963    }
1964    pub fn push_max_length(mut self, value: u32) -> Self {
1965        push_header(self.as_rec_mut(), 7u16, 4 as u16);
1966        self.as_rec_mut().extend(value.to_ne_bytes());
1967        self
1968    }
1969    pub fn push_policy_idx(mut self, value: u32) -> Self {
1970        push_header(self.as_rec_mut(), 8u16, 4 as u16);
1971        self.as_rec_mut().extend(value.to_ne_bytes());
1972        self
1973    }
1974    pub fn push_policy_maxtype(mut self, value: u32) -> Self {
1975        push_header(self.as_rec_mut(), 9u16, 4 as u16);
1976        self.as_rec_mut().extend(value.to_ne_bytes());
1977        self
1978    }
1979    pub fn push_bitfield32_mask(mut self, value: u32) -> Self {
1980        push_header(self.as_rec_mut(), 10u16, 4 as u16);
1981        self.as_rec_mut().extend(value.to_ne_bytes());
1982        self
1983    }
1984    pub fn push_mask(mut self, value: u64) -> Self {
1985        push_header(self.as_rec_mut(), 11u16, 8 as u16);
1986        self.as_rec_mut().extend(value.to_ne_bytes());
1987        self
1988    }
1989    pub fn push_pad(mut self, value: &[u8]) -> Self {
1990        push_header(self.as_rec_mut(), 12u16, value.len() as u16);
1991        self.as_rec_mut().extend(value);
1992        self
1993    }
1994}
1995impl<Prev: Rec> Drop for PushPolicyAttrs<Prev> {
1996    fn drop(&mut self) {
1997        if let Some(prev) = &mut self.prev {
1998            if let Some(header_offset) = &self.header_offset {
1999                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2000            }
2001        }
2002    }
2003}
2004pub struct PushOpPolicyAttrs<Prev: Rec> {
2005    pub(crate) prev: Option<Prev>,
2006    pub(crate) header_offset: Option<usize>,
2007}
2008impl<Prev: Rec> Rec for PushOpPolicyAttrs<Prev> {
2009    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2010        self.prev.as_mut().unwrap().as_rec_mut()
2011    }
2012    fn as_rec(&self) -> &Vec<u8> {
2013        self.prev.as_ref().unwrap().as_rec()
2014    }
2015}
2016impl<Prev: Rec> PushOpPolicyAttrs<Prev> {
2017    pub fn new(prev: Prev) -> Self {
2018        Self {
2019            prev: Some(prev),
2020            header_offset: None,
2021        }
2022    }
2023    pub fn end_nested(mut self) -> Prev {
2024        let mut prev = self.prev.take().unwrap();
2025        if let Some(header_offset) = &self.header_offset {
2026            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2027        }
2028        prev
2029    }
2030    pub fn push_do(mut self, value: u32) -> Self {
2031        push_header(self.as_rec_mut(), 1u16, 4 as u16);
2032        self.as_rec_mut().extend(value.to_ne_bytes());
2033        self
2034    }
2035    pub fn push_dump(mut self, value: u32) -> Self {
2036        push_header(self.as_rec_mut(), 2u16, 4 as u16);
2037        self.as_rec_mut().extend(value.to_ne_bytes());
2038        self
2039    }
2040}
2041impl<Prev: Rec> Drop for PushOpPolicyAttrs<Prev> {
2042    fn drop(&mut self) {
2043        if let Some(prev) = &mut self.prev {
2044            if let Some(header_offset) = &self.header_offset {
2045                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2046            }
2047        }
2048    }
2049}
2050#[doc = "Get / dump genetlink families\n\nReply attributes:\n- [.get_family_id()](IterableCtrlAttrs::get_family_id)\n- [.get_family_name()](IterableCtrlAttrs::get_family_name)\n- [.get_version()](IterableCtrlAttrs::get_version)\n- [.get_hdrsize()](IterableCtrlAttrs::get_hdrsize)\n- [.get_maxattr()](IterableCtrlAttrs::get_maxattr)\n- [.get_ops()](IterableCtrlAttrs::get_ops)\n- [.get_mcast_groups()](IterableCtrlAttrs::get_mcast_groups)\n\n"]
2051#[derive(Debug)]
2052pub struct OpGetfamilyDump<'r> {
2053    request: Request<'r>,
2054}
2055impl<'r> OpGetfamilyDump<'r> {
2056    pub fn new(mut request: Request<'r>) -> Self {
2057        Self::write_header(request.buf_mut());
2058        Self {
2059            request: request.set_dump(),
2060        }
2061    }
2062    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCtrlAttrs<&'buf mut Vec<u8>> {
2063        Self::write_header(buf);
2064        PushCtrlAttrs::new(buf)
2065    }
2066    pub fn encode(&mut self) -> PushCtrlAttrs<&mut Vec<u8>> {
2067        PushCtrlAttrs::new(self.request.buf_mut())
2068    }
2069    pub fn into_encoder(self) -> PushCtrlAttrs<RequestBuf<'r>> {
2070        PushCtrlAttrs::new(self.request.buf)
2071    }
2072    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCtrlAttrs<'a> {
2073        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2074        IterableCtrlAttrs::with_loc(attrs, buf.as_ptr() as usize)
2075    }
2076    fn write_header<Prev: Rec>(prev: &mut Prev) {
2077        let mut header = BuiltinNfgenmsg::new();
2078        header.cmd = 3u8;
2079        header.version = 1u8;
2080        prev.as_rec_mut().extend(header.as_slice());
2081    }
2082}
2083impl NetlinkRequest for OpGetfamilyDump<'_> {
2084    fn protocol(&self) -> Protocol {
2085        Protocol::Raw {
2086            protonum: 0x10,
2087            request_type: 0x10,
2088        }
2089    }
2090    fn flags(&self) -> u16 {
2091        self.request.flags
2092    }
2093    fn payload(&self) -> &[u8] {
2094        self.request.buf()
2095    }
2096    type ReplyType<'buf> = IterableCtrlAttrs<'buf>;
2097    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2098        Self::decode_request(buf)
2099    }
2100    fn lookup(
2101        buf: &[u8],
2102        offset: usize,
2103        missing_type: Option<u16>,
2104    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2105        Self::decode_request(buf).lookup_attr(offset, missing_type)
2106    }
2107}
2108#[doc = "Get / dump genetlink families\n\nRequest attributes:\n- [.push_family_name()](PushCtrlAttrs::push_family_name)\n\nReply attributes:\n- [.get_family_id()](IterableCtrlAttrs::get_family_id)\n- [.get_family_name()](IterableCtrlAttrs::get_family_name)\n- [.get_version()](IterableCtrlAttrs::get_version)\n- [.get_hdrsize()](IterableCtrlAttrs::get_hdrsize)\n- [.get_maxattr()](IterableCtrlAttrs::get_maxattr)\n- [.get_ops()](IterableCtrlAttrs::get_ops)\n- [.get_mcast_groups()](IterableCtrlAttrs::get_mcast_groups)\n\n"]
2109#[derive(Debug)]
2110pub struct OpGetfamilyDo<'r> {
2111    request: Request<'r>,
2112}
2113impl<'r> OpGetfamilyDo<'r> {
2114    pub fn new(mut request: Request<'r>) -> Self {
2115        Self::write_header(request.buf_mut());
2116        Self { request: request }
2117    }
2118    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCtrlAttrs<&'buf mut Vec<u8>> {
2119        Self::write_header(buf);
2120        PushCtrlAttrs::new(buf)
2121    }
2122    pub fn encode(&mut self) -> PushCtrlAttrs<&mut Vec<u8>> {
2123        PushCtrlAttrs::new(self.request.buf_mut())
2124    }
2125    pub fn into_encoder(self) -> PushCtrlAttrs<RequestBuf<'r>> {
2126        PushCtrlAttrs::new(self.request.buf)
2127    }
2128    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCtrlAttrs<'a> {
2129        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2130        IterableCtrlAttrs::with_loc(attrs, buf.as_ptr() as usize)
2131    }
2132    fn write_header<Prev: Rec>(prev: &mut Prev) {
2133        let mut header = BuiltinNfgenmsg::new();
2134        header.cmd = 3u8;
2135        header.version = 1u8;
2136        prev.as_rec_mut().extend(header.as_slice());
2137    }
2138}
2139impl NetlinkRequest for OpGetfamilyDo<'_> {
2140    fn protocol(&self) -> Protocol {
2141        Protocol::Raw {
2142            protonum: 0x10,
2143            request_type: 0x10,
2144        }
2145    }
2146    fn flags(&self) -> u16 {
2147        self.request.flags
2148    }
2149    fn payload(&self) -> &[u8] {
2150        self.request.buf()
2151    }
2152    type ReplyType<'buf> = IterableCtrlAttrs<'buf>;
2153    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2154        Self::decode_request(buf)
2155    }
2156    fn lookup(
2157        buf: &[u8],
2158        offset: usize,
2159        missing_type: Option<u16>,
2160    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2161        Self::decode_request(buf).lookup_attr(offset, missing_type)
2162    }
2163}
2164#[doc = "Get / dump genetlink policies\n\nRequest attributes:\n- [.push_family_id()](PushCtrlAttrs::push_family_id)\n- [.push_family_name()](PushCtrlAttrs::push_family_name)\n- [.push_op()](PushCtrlAttrs::push_op)\n\nReply attributes:\n- [.get_family_id()](IterableCtrlAttrs::get_family_id)\n- [.get_policy()](IterableCtrlAttrs::get_policy)\n- [.get_op_policy()](IterableCtrlAttrs::get_op_policy)\n\n"]
2165#[derive(Debug)]
2166pub struct OpGetpolicyDump<'r> {
2167    request: Request<'r>,
2168}
2169impl<'r> OpGetpolicyDump<'r> {
2170    pub fn new(mut request: Request<'r>) -> Self {
2171        Self::write_header(request.buf_mut());
2172        Self {
2173            request: request.set_dump(),
2174        }
2175    }
2176    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCtrlAttrs<&'buf mut Vec<u8>> {
2177        Self::write_header(buf);
2178        PushCtrlAttrs::new(buf)
2179    }
2180    pub fn encode(&mut self) -> PushCtrlAttrs<&mut Vec<u8>> {
2181        PushCtrlAttrs::new(self.request.buf_mut())
2182    }
2183    pub fn into_encoder(self) -> PushCtrlAttrs<RequestBuf<'r>> {
2184        PushCtrlAttrs::new(self.request.buf)
2185    }
2186    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCtrlAttrs<'a> {
2187        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2188        IterableCtrlAttrs::with_loc(attrs, buf.as_ptr() as usize)
2189    }
2190    fn write_header<Prev: Rec>(prev: &mut Prev) {
2191        let mut header = BuiltinNfgenmsg::new();
2192        header.cmd = 10u8;
2193        header.version = 1u8;
2194        prev.as_rec_mut().extend(header.as_slice());
2195    }
2196}
2197impl NetlinkRequest for OpGetpolicyDump<'_> {
2198    fn protocol(&self) -> Protocol {
2199        Protocol::Raw {
2200            protonum: 0x10,
2201            request_type: 0x10,
2202        }
2203    }
2204    fn flags(&self) -> u16 {
2205        self.request.flags
2206    }
2207    fn payload(&self) -> &[u8] {
2208        self.request.buf()
2209    }
2210    type ReplyType<'buf> = IterableCtrlAttrs<'buf>;
2211    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2212        Self::decode_request(buf)
2213    }
2214    fn lookup(
2215        buf: &[u8],
2216        offset: usize,
2217        missing_type: Option<u16>,
2218    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2219        Self::decode_request(buf).lookup_attr(offset, missing_type)
2220    }
2221}
2222use crate::traits::LookupFn;
2223use crate::utils::RequestBuf;
2224#[derive(Debug)]
2225pub struct Request<'buf> {
2226    buf: RequestBuf<'buf>,
2227    flags: u16,
2228    writeback: Option<&'buf mut Option<RequestInfo>>,
2229}
2230#[allow(unused)]
2231#[derive(Debug, Clone)]
2232pub struct RequestInfo {
2233    protocol: Protocol,
2234    flags: u16,
2235    name: &'static str,
2236    lookup: LookupFn,
2237}
2238impl Request<'static> {
2239    pub fn new() -> Self {
2240        Self::new_from_buf(Vec::new())
2241    }
2242    pub fn new_from_buf(buf: Vec<u8>) -> Self {
2243        Self {
2244            flags: 0,
2245            buf: RequestBuf::Own(buf),
2246            writeback: None,
2247        }
2248    }
2249    pub fn into_buf(self) -> Vec<u8> {
2250        match self.buf {
2251            RequestBuf::Own(buf) => buf,
2252            _ => unreachable!(),
2253        }
2254    }
2255}
2256impl<'buf> Request<'buf> {
2257    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
2258        buf.clear();
2259        Self::new_extend(buf)
2260    }
2261    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
2262        Self {
2263            flags: 0,
2264            buf: RequestBuf::Ref(buf),
2265            writeback: None,
2266        }
2267    }
2268    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
2269        let Some(writeback) = &mut self.writeback else {
2270            return;
2271        };
2272        **writeback = Some(RequestInfo {
2273            protocol,
2274            flags: self.flags,
2275            name,
2276            lookup,
2277        })
2278    }
2279    pub fn buf(&self) -> &Vec<u8> {
2280        self.buf.buf()
2281    }
2282    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
2283        self.buf.buf_mut()
2284    }
2285    #[doc = "Set `NLM_F_CREATE` flag"]
2286    pub fn set_create(mut self) -> Self {
2287        self.flags |= consts::NLM_F_CREATE as u16;
2288        self
2289    }
2290    #[doc = "Set `NLM_F_EXCL` flag"]
2291    pub fn set_excl(mut self) -> Self {
2292        self.flags |= consts::NLM_F_EXCL as u16;
2293        self
2294    }
2295    #[doc = "Set `NLM_F_REPLACE` flag"]
2296    pub fn set_replace(mut self) -> Self {
2297        self.flags |= consts::NLM_F_REPLACE as u16;
2298        self
2299    }
2300    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
2301    pub fn set_change(self) -> Self {
2302        self.set_create().set_replace()
2303    }
2304    #[doc = "Set `NLM_F_APPEND` flag"]
2305    pub fn set_append(mut self) -> Self {
2306        self.flags |= consts::NLM_F_APPEND as u16;
2307        self
2308    }
2309    #[doc = "Set `self.flags |= flags`"]
2310    pub fn set_flags(mut self, flags: u16) -> Self {
2311        self.flags |= flags;
2312        self
2313    }
2314    #[doc = "Set `self.flags ^= self.flags & flags`"]
2315    pub fn unset_flags(mut self, flags: u16) -> Self {
2316        self.flags ^= self.flags & flags;
2317        self
2318    }
2319    #[doc = "Set `NLM_F_DUMP` flag"]
2320    fn set_dump(mut self) -> Self {
2321        self.flags |= consts::NLM_F_DUMP as u16;
2322        self
2323    }
2324    #[doc = "Get / dump genetlink families\n\nReply attributes:\n- [.get_family_id()](IterableCtrlAttrs::get_family_id)\n- [.get_family_name()](IterableCtrlAttrs::get_family_name)\n- [.get_version()](IterableCtrlAttrs::get_version)\n- [.get_hdrsize()](IterableCtrlAttrs::get_hdrsize)\n- [.get_maxattr()](IterableCtrlAttrs::get_maxattr)\n- [.get_ops()](IterableCtrlAttrs::get_ops)\n- [.get_mcast_groups()](IterableCtrlAttrs::get_mcast_groups)\n\n"]
2325    pub fn op_getfamily_dump(self) -> OpGetfamilyDump<'buf> {
2326        let mut res = OpGetfamilyDump::new(self);
2327        res.request
2328            .do_writeback(res.protocol(), "op-getfamily-dump", OpGetfamilyDump::lookup);
2329        res
2330    }
2331    #[doc = "Get / dump genetlink families\n\nRequest attributes:\n- [.push_family_name()](PushCtrlAttrs::push_family_name)\n\nReply attributes:\n- [.get_family_id()](IterableCtrlAttrs::get_family_id)\n- [.get_family_name()](IterableCtrlAttrs::get_family_name)\n- [.get_version()](IterableCtrlAttrs::get_version)\n- [.get_hdrsize()](IterableCtrlAttrs::get_hdrsize)\n- [.get_maxattr()](IterableCtrlAttrs::get_maxattr)\n- [.get_ops()](IterableCtrlAttrs::get_ops)\n- [.get_mcast_groups()](IterableCtrlAttrs::get_mcast_groups)\n\n"]
2332    pub fn op_getfamily_do(self) -> OpGetfamilyDo<'buf> {
2333        let mut res = OpGetfamilyDo::new(self);
2334        res.request
2335            .do_writeback(res.protocol(), "op-getfamily-do", OpGetfamilyDo::lookup);
2336        res
2337    }
2338    #[doc = "Get / dump genetlink policies\n\nRequest attributes:\n- [.push_family_id()](PushCtrlAttrs::push_family_id)\n- [.push_family_name()](PushCtrlAttrs::push_family_name)\n- [.push_op()](PushCtrlAttrs::push_op)\n\nReply attributes:\n- [.get_family_id()](IterableCtrlAttrs::get_family_id)\n- [.get_policy()](IterableCtrlAttrs::get_policy)\n- [.get_op_policy()](IterableCtrlAttrs::get_op_policy)\n\n"]
2339    pub fn op_getpolicy_dump(self) -> OpGetpolicyDump<'buf> {
2340        let mut res = OpGetpolicyDump::new(self);
2341        res.request
2342            .do_writeback(res.protocol(), "op-getpolicy-dump", OpGetpolicyDump::lookup);
2343        res
2344    }
2345}
2346#[cfg(test)]
2347mod generated_tests {
2348    use super::*;
2349    #[test]
2350    fn tests() {
2351        let _ = IterableCtrlAttrs::get_family_id;
2352        let _ = IterableCtrlAttrs::get_family_name;
2353        let _ = IterableCtrlAttrs::get_hdrsize;
2354        let _ = IterableCtrlAttrs::get_maxattr;
2355        let _ = IterableCtrlAttrs::get_mcast_groups;
2356        let _ = IterableCtrlAttrs::get_op_policy;
2357        let _ = IterableCtrlAttrs::get_ops;
2358        let _ = IterableCtrlAttrs::get_policy;
2359        let _ = IterableCtrlAttrs::get_version;
2360        let _ = PushCtrlAttrs::<&mut Vec<u8>>::push_family_id;
2361        let _ = PushCtrlAttrs::<&mut Vec<u8>>::push_family_name;
2362        let _ = PushCtrlAttrs::<&mut Vec<u8>>::push_op;
2363    }
2364}