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