Skip to main content

netlink_bindings/net-shaper/
mod.rs

1#![doc = "Networking HW rate limiting configuration\\.\n\nThis API allows configuring HW shapers available on the network\ndevices at different levels (queues, network device) and allows\narbitrary manipulation of the scheduling tree of the involved\nshapers\\.\n\nEach @shaper is identified within the given device, by a @handle,\ncomprising both a @scope and an @id\\.\n\nDepending on the @scope value, the shapers are attached to specific\nHW objects (queues, devices) or, for @node scope, represent a\nscheduling group, that can be placed in an arbitrary location of\nthe scheduling tree\\.\n\nShapers can be created with two different operations: the @set\noperation, to create and update a single \"attached\" shaper, and\nthe @group operation, to create and update a scheduling\ngroup\\. Only the @group operation can create @node scope shapers\\.\n\nExisting shapers can be deleted/reset via the @delete operation\\.\n\nThe user can query the running configuration via the @get operation\\.\n\nDifferent devices can provide different feature sets, e\\.g\\. with no\nsupport for complex scheduling hierarchy, or for some shaping\nparameters\\. The user can introspect the HW capabilities via the\n@cap\\-get operation\\.\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 = "net-shaper";
17pub const PROTONAME_CSTR: &CStr = c"net-shaper";
18#[doc = "Defines the shaper @id interpretation\\."]
19#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
20#[derive(Debug, Clone, Copy)]
21pub enum Scope {
22    #[doc = "The scope is not specified\\."]
23    Unspec = 0,
24    #[doc = "The main shaper for the given network device\\."]
25    Netdev = 1,
26    #[doc = "The shaper is attached to the given device queue,\nthe @id represents the queue number\\.\n"]
27    Queue = 2,
28    #[doc = "The shaper allows grouping of queues or other\nnode shapers; can be nested in either @netdev\nshapers or other @node shapers, allowing placement\nin any location of the scheduling tree, except\nleaves and root\\.\n"]
29    Node = 3,
30}
31impl Scope {
32    pub fn from_value(value: u64) -> Option<Self> {
33        Some(match value {
34            0 => Self::Unspec,
35            1 => Self::Netdev,
36            2 => Self::Queue,
37            3 => Self::Node,
38            _ => return None,
39        })
40    }
41}
42#[doc = "Different metric supported by the shaper\\."]
43#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
44#[derive(Debug, Clone, Copy)]
45pub enum Metric {
46    #[doc = "Shaper operates on a bits per second basis\\."]
47    Bps = 0,
48    #[doc = "Shaper operates on a packets per second basis\\."]
49    Pps = 1,
50}
51impl Metric {
52    pub fn from_value(value: u64) -> Option<Self> {
53        Some(match value {
54            0 => Self::Bps,
55            1 => Self::Pps,
56            _ => return None,
57        })
58    }
59}
60#[derive(Clone)]
61pub enum NetShaper<'a> {
62    #[doc = "Unique identifier for the given shaper inside the owning device\\."]
63    Handle(IterableHandle<'a>),
64    #[doc = "Metric used by the given shaper for bw\\-min, bw\\-max and burst\\.\nAssociated type: [`Metric`] (enum)"]
65    Metric(u32),
66    #[doc = "Guaranteed bandwidth for the given shaper\\."]
67    BwMin(u32),
68    #[doc = "Maximum bandwidth for the given shaper or 0 when unlimited\\."]
69    BwMax(u32),
70    #[doc = "Maximum burst\\-size for shaping\\. Should not be interpreted\nas a quantum\\.\n"]
71    Burst(u32),
72    #[doc = "Scheduling priority for the given shaper\\. The priority\nscheduling is applied to sibling shapers\\.\n"]
73    Priority(u32),
74    #[doc = "Relative weight for round robin scheduling of the\ngiven shaper\\.\nThe scheduling is applied to all sibling shapers\nwith the same priority\\.\n"]
75    Weight(u32),
76    #[doc = "Interface index owning the specified shaper\\."]
77    Ifindex(u32),
78    #[doc = "Identifier for the parent of the affected shaper\\.\nOnly needed for @group operation\\.\n"]
79    Parent(IterableHandle<'a>),
80    #[doc = "Describes a set of leaves shapers for a @group operation\\.\n\nAttribute may repeat multiple times (treat it as array)"]
81    Leaves(IterableLeafInfo<'a>),
82}
83impl<'a> IterableNetShaper<'a> {
84    #[doc = "Unique identifier for the given shaper inside the owning device\\."]
85    pub fn get_handle(&self) -> Result<IterableHandle<'a>, ErrorContext> {
86        let mut iter = self.clone();
87        iter.pos = 0;
88        for attr in iter {
89            if let NetShaper::Handle(val) = attr? {
90                return Ok(val);
91            }
92        }
93        Err(ErrorContext::new_missing(
94            "NetShaper",
95            "Handle",
96            self.orig_loc,
97            self.buf.as_ptr() as usize,
98        ))
99    }
100    #[doc = "Metric used by the given shaper for bw\\-min, bw\\-max and burst\\.\nAssociated type: [`Metric`] (enum)"]
101    pub fn get_metric(&self) -> Result<u32, ErrorContext> {
102        let mut iter = self.clone();
103        iter.pos = 0;
104        for attr in iter {
105            if let NetShaper::Metric(val) = attr? {
106                return Ok(val);
107            }
108        }
109        Err(ErrorContext::new_missing(
110            "NetShaper",
111            "Metric",
112            self.orig_loc,
113            self.buf.as_ptr() as usize,
114        ))
115    }
116    #[doc = "Guaranteed bandwidth for the given shaper\\."]
117    pub fn get_bw_min(&self) -> Result<u32, ErrorContext> {
118        let mut iter = self.clone();
119        iter.pos = 0;
120        for attr in iter {
121            if let NetShaper::BwMin(val) = attr? {
122                return Ok(val);
123            }
124        }
125        Err(ErrorContext::new_missing(
126            "NetShaper",
127            "BwMin",
128            self.orig_loc,
129            self.buf.as_ptr() as usize,
130        ))
131    }
132    #[doc = "Maximum bandwidth for the given shaper or 0 when unlimited\\."]
133    pub fn get_bw_max(&self) -> Result<u32, ErrorContext> {
134        let mut iter = self.clone();
135        iter.pos = 0;
136        for attr in iter {
137            if let NetShaper::BwMax(val) = attr? {
138                return Ok(val);
139            }
140        }
141        Err(ErrorContext::new_missing(
142            "NetShaper",
143            "BwMax",
144            self.orig_loc,
145            self.buf.as_ptr() as usize,
146        ))
147    }
148    #[doc = "Maximum burst\\-size for shaping\\. Should not be interpreted\nas a quantum\\.\n"]
149    pub fn get_burst(&self) -> Result<u32, ErrorContext> {
150        let mut iter = self.clone();
151        iter.pos = 0;
152        for attr in iter {
153            if let NetShaper::Burst(val) = attr? {
154                return Ok(val);
155            }
156        }
157        Err(ErrorContext::new_missing(
158            "NetShaper",
159            "Burst",
160            self.orig_loc,
161            self.buf.as_ptr() as usize,
162        ))
163    }
164    #[doc = "Scheduling priority for the given shaper\\. The priority\nscheduling is applied to sibling shapers\\.\n"]
165    pub fn get_priority(&self) -> Result<u32, ErrorContext> {
166        let mut iter = self.clone();
167        iter.pos = 0;
168        for attr in iter {
169            if let NetShaper::Priority(val) = attr? {
170                return Ok(val);
171            }
172        }
173        Err(ErrorContext::new_missing(
174            "NetShaper",
175            "Priority",
176            self.orig_loc,
177            self.buf.as_ptr() as usize,
178        ))
179    }
180    #[doc = "Relative weight for round robin scheduling of the\ngiven shaper\\.\nThe scheduling is applied to all sibling shapers\nwith the same priority\\.\n"]
181    pub fn get_weight(&self) -> Result<u32, ErrorContext> {
182        let mut iter = self.clone();
183        iter.pos = 0;
184        for attr in iter {
185            if let NetShaper::Weight(val) = attr? {
186                return Ok(val);
187            }
188        }
189        Err(ErrorContext::new_missing(
190            "NetShaper",
191            "Weight",
192            self.orig_loc,
193            self.buf.as_ptr() as usize,
194        ))
195    }
196    #[doc = "Interface index owning the specified shaper\\."]
197    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
198        let mut iter = self.clone();
199        iter.pos = 0;
200        for attr in iter {
201            if let NetShaper::Ifindex(val) = attr? {
202                return Ok(val);
203            }
204        }
205        Err(ErrorContext::new_missing(
206            "NetShaper",
207            "Ifindex",
208            self.orig_loc,
209            self.buf.as_ptr() as usize,
210        ))
211    }
212    #[doc = "Identifier for the parent of the affected shaper\\.\nOnly needed for @group operation\\.\n"]
213    pub fn get_parent(&self) -> Result<IterableHandle<'a>, ErrorContext> {
214        let mut iter = self.clone();
215        iter.pos = 0;
216        for attr in iter {
217            if let NetShaper::Parent(val) = attr? {
218                return Ok(val);
219            }
220        }
221        Err(ErrorContext::new_missing(
222            "NetShaper",
223            "Parent",
224            self.orig_loc,
225            self.buf.as_ptr() as usize,
226        ))
227    }
228    #[doc = "Describes a set of leaves shapers for a @group operation\\.\n\nAttribute may repeat multiple times (treat it as array)"]
229    pub fn get_leaves(&self) -> MultiAttrIterable<Self, NetShaper<'a>, IterableLeafInfo<'a>> {
230        MultiAttrIterable::new(self.clone(), |variant| {
231            if let NetShaper::Leaves(val) = variant {
232                Some(val)
233            } else {
234                None
235            }
236        })
237    }
238}
239impl NetShaper<'_> {
240    pub fn new<'a>(buf: &'a [u8]) -> IterableNetShaper<'a> {
241        IterableNetShaper::with_loc(buf, buf.as_ptr() as usize)
242    }
243    fn attr_from_type(r#type: u16) -> Option<&'static str> {
244        let res = match r#type {
245            1u16 => "Handle",
246            2u16 => "Metric",
247            3u16 => "BwMin",
248            4u16 => "BwMax",
249            5u16 => "Burst",
250            6u16 => "Priority",
251            7u16 => "Weight",
252            8u16 => "Ifindex",
253            9u16 => "Parent",
254            10u16 => "Leaves",
255            _ => return None,
256        };
257        Some(res)
258    }
259}
260#[derive(Clone, Copy, Default)]
261pub struct IterableNetShaper<'a> {
262    buf: &'a [u8],
263    pos: usize,
264    orig_loc: usize,
265}
266impl<'a> IterableNetShaper<'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 IterableNetShaper<'a> {
279    type Item = Result<NetShaper<'a>, ErrorContext>;
280    fn next(&mut self) -> Option<Self::Item> {
281        let pos = self.pos;
282        let mut r#type;
283        loop {
284            r#type = None;
285            if self.buf.len() == self.pos {
286                return None;
287            }
288            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
289                break;
290            };
291            r#type = Some(header.r#type);
292            let res = match header.r#type {
293                1u16 => NetShaper::Handle({
294                    let res = Some(IterableHandle::with_loc(next, self.orig_loc));
295                    let Some(val) = res else { break };
296                    val
297                }),
298                2u16 => NetShaper::Metric({
299                    let res = parse_u32(next);
300                    let Some(val) = res else { break };
301                    val
302                }),
303                3u16 => NetShaper::BwMin({
304                    let res = parse_u32(next);
305                    let Some(val) = res else { break };
306                    val
307                }),
308                4u16 => NetShaper::BwMax({
309                    let res = parse_u32(next);
310                    let Some(val) = res else { break };
311                    val
312                }),
313                5u16 => NetShaper::Burst({
314                    let res = parse_u32(next);
315                    let Some(val) = res else { break };
316                    val
317                }),
318                6u16 => NetShaper::Priority({
319                    let res = parse_u32(next);
320                    let Some(val) = res else { break };
321                    val
322                }),
323                7u16 => NetShaper::Weight({
324                    let res = parse_u32(next);
325                    let Some(val) = res else { break };
326                    val
327                }),
328                8u16 => NetShaper::Ifindex({
329                    let res = parse_u32(next);
330                    let Some(val) = res else { break };
331                    val
332                }),
333                9u16 => NetShaper::Parent({
334                    let res = Some(IterableHandle::with_loc(next, self.orig_loc));
335                    let Some(val) = res else { break };
336                    val
337                }),
338                10u16 => NetShaper::Leaves({
339                    let res = Some(IterableLeafInfo::with_loc(next, self.orig_loc));
340                    let Some(val) = res else { break };
341                    val
342                }),
343                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
344                n => continue,
345            };
346            return Some(Ok(res));
347        }
348        Some(Err(ErrorContext::new(
349            "NetShaper",
350            r#type.and_then(|t| NetShaper::attr_from_type(t)),
351            self.orig_loc,
352            self.buf.as_ptr().wrapping_add(pos) as usize,
353        )))
354    }
355}
356impl<'a> std::fmt::Debug for IterableNetShaper<'_> {
357    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358        let mut fmt = f.debug_struct("NetShaper");
359        for attr in self.clone() {
360            let attr = match attr {
361                Ok(a) => a,
362                Err(err) => {
363                    fmt.finish()?;
364                    f.write_str("Err(")?;
365                    err.fmt(f)?;
366                    return f.write_str(")");
367                }
368            };
369            match attr {
370                NetShaper::Handle(val) => fmt.field("Handle", &val),
371                NetShaper::Metric(val) => {
372                    fmt.field("Metric", &FormatEnum(val.into(), Metric::from_value))
373                }
374                NetShaper::BwMin(val) => fmt.field("BwMin", &val),
375                NetShaper::BwMax(val) => fmt.field("BwMax", &val),
376                NetShaper::Burst(val) => fmt.field("Burst", &val),
377                NetShaper::Priority(val) => fmt.field("Priority", &val),
378                NetShaper::Weight(val) => fmt.field("Weight", &val),
379                NetShaper::Ifindex(val) => fmt.field("Ifindex", &val),
380                NetShaper::Parent(val) => fmt.field("Parent", &val),
381                NetShaper::Leaves(val) => fmt.field("Leaves", &val),
382            };
383        }
384        fmt.finish()
385    }
386}
387impl IterableNetShaper<'_> {
388    pub fn lookup_attr(
389        &self,
390        offset: usize,
391        missing_type: Option<u16>,
392    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
393        let mut stack = Vec::new();
394        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
395        if missing_type.is_some() && cur == offset {
396            stack.push(("NetShaper", offset));
397            return (
398                stack,
399                missing_type.and_then(|t| NetShaper::attr_from_type(t)),
400            );
401        }
402        if cur > offset || cur + self.buf.len() < offset {
403            return (stack, None);
404        }
405        let mut attrs = self.clone();
406        let mut last_off = cur + attrs.pos;
407        let mut missing = None;
408        while let Some(attr) = attrs.next() {
409            let Ok(attr) = attr else { break };
410            match attr {
411                NetShaper::Handle(val) => {
412                    (stack, missing) = val.lookup_attr(offset, missing_type);
413                    if !stack.is_empty() {
414                        break;
415                    }
416                }
417                NetShaper::Metric(val) => {
418                    if last_off == offset {
419                        stack.push(("Metric", last_off));
420                        break;
421                    }
422                }
423                NetShaper::BwMin(val) => {
424                    if last_off == offset {
425                        stack.push(("BwMin", last_off));
426                        break;
427                    }
428                }
429                NetShaper::BwMax(val) => {
430                    if last_off == offset {
431                        stack.push(("BwMax", last_off));
432                        break;
433                    }
434                }
435                NetShaper::Burst(val) => {
436                    if last_off == offset {
437                        stack.push(("Burst", last_off));
438                        break;
439                    }
440                }
441                NetShaper::Priority(val) => {
442                    if last_off == offset {
443                        stack.push(("Priority", last_off));
444                        break;
445                    }
446                }
447                NetShaper::Weight(val) => {
448                    if last_off == offset {
449                        stack.push(("Weight", last_off));
450                        break;
451                    }
452                }
453                NetShaper::Ifindex(val) => {
454                    if last_off == offset {
455                        stack.push(("Ifindex", last_off));
456                        break;
457                    }
458                }
459                NetShaper::Parent(val) => {
460                    (stack, missing) = val.lookup_attr(offset, missing_type);
461                    if !stack.is_empty() {
462                        break;
463                    }
464                }
465                NetShaper::Leaves(val) => {
466                    (stack, missing) = val.lookup_attr(offset, missing_type);
467                    if !stack.is_empty() {
468                        break;
469                    }
470                }
471                _ => {}
472            };
473            last_off = cur + attrs.pos;
474        }
475        if !stack.is_empty() {
476            stack.push(("NetShaper", cur));
477        }
478        (stack, missing)
479    }
480}
481#[derive(Clone)]
482pub enum Handle {
483    #[doc = "Defines the shaper @id interpretation\\.\nAssociated type: [`Scope`] (enum)"]
484    Scope(u32),
485    #[doc = "Numeric identifier of a shaper\\. The id semantic depends on\nthe scope\\. For @queue scope it's the queue id and for @node\nscope it's the node identifier\\.\n"]
486    Id(u32),
487}
488impl<'a> IterableHandle<'a> {
489    #[doc = "Defines the shaper @id interpretation\\.\nAssociated type: [`Scope`] (enum)"]
490    pub fn get_scope(&self) -> Result<u32, ErrorContext> {
491        let mut iter = self.clone();
492        iter.pos = 0;
493        for attr in iter {
494            if let Handle::Scope(val) = attr? {
495                return Ok(val);
496            }
497        }
498        Err(ErrorContext::new_missing(
499            "Handle",
500            "Scope",
501            self.orig_loc,
502            self.buf.as_ptr() as usize,
503        ))
504    }
505    #[doc = "Numeric identifier of a shaper\\. The id semantic depends on\nthe scope\\. For @queue scope it's the queue id and for @node\nscope it's the node identifier\\.\n"]
506    pub fn get_id(&self) -> Result<u32, ErrorContext> {
507        let mut iter = self.clone();
508        iter.pos = 0;
509        for attr in iter {
510            if let Handle::Id(val) = attr? {
511                return Ok(val);
512            }
513        }
514        Err(ErrorContext::new_missing(
515            "Handle",
516            "Id",
517            self.orig_loc,
518            self.buf.as_ptr() as usize,
519        ))
520    }
521}
522impl Handle {
523    pub fn new<'a>(buf: &'a [u8]) -> IterableHandle<'a> {
524        IterableHandle::with_loc(buf, buf.as_ptr() as usize)
525    }
526    fn attr_from_type(r#type: u16) -> Option<&'static str> {
527        let res = match r#type {
528            1u16 => "Scope",
529            2u16 => "Id",
530            _ => return None,
531        };
532        Some(res)
533    }
534}
535#[derive(Clone, Copy, Default)]
536pub struct IterableHandle<'a> {
537    buf: &'a [u8],
538    pos: usize,
539    orig_loc: usize,
540}
541impl<'a> IterableHandle<'a> {
542    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
543        Self {
544            buf,
545            pos: 0,
546            orig_loc,
547        }
548    }
549    pub fn get_buf(&self) -> &'a [u8] {
550        self.buf
551    }
552}
553impl<'a> Iterator for IterableHandle<'a> {
554    type Item = Result<Handle, ErrorContext>;
555    fn next(&mut self) -> Option<Self::Item> {
556        let pos = self.pos;
557        let mut r#type;
558        loop {
559            r#type = None;
560            if self.buf.len() == self.pos {
561                return None;
562            }
563            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
564                break;
565            };
566            r#type = Some(header.r#type);
567            let res = match header.r#type {
568                1u16 => Handle::Scope({
569                    let res = parse_u32(next);
570                    let Some(val) = res else { break };
571                    val
572                }),
573                2u16 => Handle::Id({
574                    let res = parse_u32(next);
575                    let Some(val) = res else { break };
576                    val
577                }),
578                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
579                n => continue,
580            };
581            return Some(Ok(res));
582        }
583        Some(Err(ErrorContext::new(
584            "Handle",
585            r#type.and_then(|t| Handle::attr_from_type(t)),
586            self.orig_loc,
587            self.buf.as_ptr().wrapping_add(pos) as usize,
588        )))
589    }
590}
591impl std::fmt::Debug for IterableHandle<'_> {
592    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
593        let mut fmt = f.debug_struct("Handle");
594        for attr in self.clone() {
595            let attr = match attr {
596                Ok(a) => a,
597                Err(err) => {
598                    fmt.finish()?;
599                    f.write_str("Err(")?;
600                    err.fmt(f)?;
601                    return f.write_str(")");
602                }
603            };
604            match attr {
605                Handle::Scope(val) => {
606                    fmt.field("Scope", &FormatEnum(val.into(), Scope::from_value))
607                }
608                Handle::Id(val) => fmt.field("Id", &val),
609            };
610        }
611        fmt.finish()
612    }
613}
614impl IterableHandle<'_> {
615    pub fn lookup_attr(
616        &self,
617        offset: usize,
618        missing_type: Option<u16>,
619    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
620        let mut stack = Vec::new();
621        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
622        if missing_type.is_some() && cur == offset {
623            stack.push(("Handle", offset));
624            return (stack, missing_type.and_then(|t| Handle::attr_from_type(t)));
625        }
626        if cur > offset || cur + self.buf.len() < offset {
627            return (stack, None);
628        }
629        let mut attrs = self.clone();
630        let mut last_off = cur + attrs.pos;
631        while let Some(attr) = attrs.next() {
632            let Ok(attr) = attr else { break };
633            match attr {
634                Handle::Scope(val) => {
635                    if last_off == offset {
636                        stack.push(("Scope", last_off));
637                        break;
638                    }
639                }
640                Handle::Id(val) => {
641                    if last_off == offset {
642                        stack.push(("Id", last_off));
643                        break;
644                    }
645                }
646                _ => {}
647            };
648            last_off = cur + attrs.pos;
649        }
650        if !stack.is_empty() {
651            stack.push(("Handle", cur));
652        }
653        (stack, None)
654    }
655}
656#[derive(Clone)]
657pub enum LeafInfo<'a> {
658    #[doc = "Unique identifier for the given shaper inside the owning device\\."]
659    Handle(IterableHandle<'a>),
660    #[doc = "Scheduling priority for the given shaper\\. The priority\nscheduling is applied to sibling shapers\\.\n"]
661    Priority(u32),
662    #[doc = "Relative weight for round robin scheduling of the\ngiven shaper\\.\nThe scheduling is applied to all sibling shapers\nwith the same priority\\.\n"]
663    Weight(u32),
664}
665impl<'a> IterableLeafInfo<'a> {
666    #[doc = "Unique identifier for the given shaper inside the owning device\\."]
667    pub fn get_handle(&self) -> Result<IterableHandle<'a>, ErrorContext> {
668        let mut iter = self.clone();
669        iter.pos = 0;
670        for attr in iter {
671            if let LeafInfo::Handle(val) = attr? {
672                return Ok(val);
673            }
674        }
675        Err(ErrorContext::new_missing(
676            "LeafInfo",
677            "Handle",
678            self.orig_loc,
679            self.buf.as_ptr() as usize,
680        ))
681    }
682    #[doc = "Scheduling priority for the given shaper\\. The priority\nscheduling is applied to sibling shapers\\.\n"]
683    pub fn get_priority(&self) -> Result<u32, ErrorContext> {
684        let mut iter = self.clone();
685        iter.pos = 0;
686        for attr in iter {
687            if let LeafInfo::Priority(val) = attr? {
688                return Ok(val);
689            }
690        }
691        Err(ErrorContext::new_missing(
692            "LeafInfo",
693            "Priority",
694            self.orig_loc,
695            self.buf.as_ptr() as usize,
696        ))
697    }
698    #[doc = "Relative weight for round robin scheduling of the\ngiven shaper\\.\nThe scheduling is applied to all sibling shapers\nwith the same priority\\.\n"]
699    pub fn get_weight(&self) -> Result<u32, ErrorContext> {
700        let mut iter = self.clone();
701        iter.pos = 0;
702        for attr in iter {
703            if let LeafInfo::Weight(val) = attr? {
704                return Ok(val);
705            }
706        }
707        Err(ErrorContext::new_missing(
708            "LeafInfo",
709            "Weight",
710            self.orig_loc,
711            self.buf.as_ptr() as usize,
712        ))
713    }
714}
715impl LeafInfo<'_> {
716    pub fn new<'a>(buf: &'a [u8]) -> IterableLeafInfo<'a> {
717        IterableLeafInfo::with_loc(buf, buf.as_ptr() as usize)
718    }
719    fn attr_from_type(r#type: u16) -> Option<&'static str> {
720        NetShaper::attr_from_type(r#type)
721    }
722}
723#[derive(Clone, Copy, Default)]
724pub struct IterableLeafInfo<'a> {
725    buf: &'a [u8],
726    pos: usize,
727    orig_loc: usize,
728}
729impl<'a> IterableLeafInfo<'a> {
730    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
731        Self {
732            buf,
733            pos: 0,
734            orig_loc,
735        }
736    }
737    pub fn get_buf(&self) -> &'a [u8] {
738        self.buf
739    }
740}
741impl<'a> Iterator for IterableLeafInfo<'a> {
742    type Item = Result<LeafInfo<'a>, ErrorContext>;
743    fn next(&mut self) -> Option<Self::Item> {
744        let pos = self.pos;
745        let mut r#type;
746        loop {
747            r#type = None;
748            if self.buf.len() == self.pos {
749                return None;
750            }
751            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
752                break;
753            };
754            r#type = Some(header.r#type);
755            let res = match header.r#type {
756                1u16 => LeafInfo::Handle({
757                    let res = Some(IterableHandle::with_loc(next, self.orig_loc));
758                    let Some(val) = res else { break };
759                    val
760                }),
761                6u16 => LeafInfo::Priority({
762                    let res = parse_u32(next);
763                    let Some(val) = res else { break };
764                    val
765                }),
766                7u16 => LeafInfo::Weight({
767                    let res = parse_u32(next);
768                    let Some(val) = res else { break };
769                    val
770                }),
771                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
772                n => continue,
773            };
774            return Some(Ok(res));
775        }
776        Some(Err(ErrorContext::new(
777            "LeafInfo",
778            r#type.and_then(|t| LeafInfo::attr_from_type(t)),
779            self.orig_loc,
780            self.buf.as_ptr().wrapping_add(pos) as usize,
781        )))
782    }
783}
784impl<'a> std::fmt::Debug for IterableLeafInfo<'_> {
785    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
786        let mut fmt = f.debug_struct("LeafInfo");
787        for attr in self.clone() {
788            let attr = match attr {
789                Ok(a) => a,
790                Err(err) => {
791                    fmt.finish()?;
792                    f.write_str("Err(")?;
793                    err.fmt(f)?;
794                    return f.write_str(")");
795                }
796            };
797            match attr {
798                LeafInfo::Handle(val) => fmt.field("Handle", &val),
799                LeafInfo::Priority(val) => fmt.field("Priority", &val),
800                LeafInfo::Weight(val) => fmt.field("Weight", &val),
801            };
802        }
803        fmt.finish()
804    }
805}
806impl IterableLeafInfo<'_> {
807    pub fn lookup_attr(
808        &self,
809        offset: usize,
810        missing_type: Option<u16>,
811    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
812        let mut stack = Vec::new();
813        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
814        if missing_type.is_some() && cur == offset {
815            stack.push(("LeafInfo", offset));
816            return (
817                stack,
818                missing_type.and_then(|t| LeafInfo::attr_from_type(t)),
819            );
820        }
821        if cur > offset || cur + self.buf.len() < offset {
822            return (stack, None);
823        }
824        let mut attrs = self.clone();
825        let mut last_off = cur + attrs.pos;
826        let mut missing = None;
827        while let Some(attr) = attrs.next() {
828            let Ok(attr) = attr else { break };
829            match attr {
830                LeafInfo::Handle(val) => {
831                    (stack, missing) = val.lookup_attr(offset, missing_type);
832                    if !stack.is_empty() {
833                        break;
834                    }
835                }
836                LeafInfo::Priority(val) => {
837                    if last_off == offset {
838                        stack.push(("Priority", last_off));
839                        break;
840                    }
841                }
842                LeafInfo::Weight(val) => {
843                    if last_off == offset {
844                        stack.push(("Weight", last_off));
845                        break;
846                    }
847                }
848                _ => {}
849            };
850            last_off = cur + attrs.pos;
851        }
852        if !stack.is_empty() {
853            stack.push(("LeafInfo", cur));
854        }
855        (stack, missing)
856    }
857}
858#[derive(Clone)]
859pub enum Caps {
860    #[doc = "Interface index queried for shapers capabilities\\."]
861    Ifindex(u32),
862    #[doc = "The scope to which the queried capabilities apply\\.\nAssociated type: [`Scope`] (enum)"]
863    Scope(u32),
864    #[doc = "The device accepts 'bps' metric for bw\\-min, bw\\-max and burst\\."]
865    SupportMetricBps(()),
866    #[doc = "The device accepts 'pps' metric for bw\\-min, bw\\-max and burst\\."]
867    SupportMetricPps(()),
868    #[doc = "The device supports nesting shaper belonging to this scope\nbelow 'node' scoped shapers\\. Only 'queue' and 'node'\nscope can have flag 'support\\-nesting'\\.\n"]
869    SupportNesting(()),
870    #[doc = "The device supports a minimum guaranteed B/W\\."]
871    SupportBwMin(()),
872    #[doc = "The device supports maximum B/W shaping\\."]
873    SupportBwMax(()),
874    #[doc = "The device supports a maximum burst size\\."]
875    SupportBurst(()),
876    #[doc = "The device supports priority scheduling\\."]
877    SupportPriority(()),
878    #[doc = "The device supports weighted round robin scheduling\\."]
879    SupportWeight(()),
880}
881impl<'a> IterableCaps<'a> {
882    #[doc = "Interface index queried for shapers capabilities\\."]
883    pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
884        let mut iter = self.clone();
885        iter.pos = 0;
886        for attr in iter {
887            if let Caps::Ifindex(val) = attr? {
888                return Ok(val);
889            }
890        }
891        Err(ErrorContext::new_missing(
892            "Caps",
893            "Ifindex",
894            self.orig_loc,
895            self.buf.as_ptr() as usize,
896        ))
897    }
898    #[doc = "The scope to which the queried capabilities apply\\.\nAssociated type: [`Scope`] (enum)"]
899    pub fn get_scope(&self) -> Result<u32, ErrorContext> {
900        let mut iter = self.clone();
901        iter.pos = 0;
902        for attr in iter {
903            if let Caps::Scope(val) = attr? {
904                return Ok(val);
905            }
906        }
907        Err(ErrorContext::new_missing(
908            "Caps",
909            "Scope",
910            self.orig_loc,
911            self.buf.as_ptr() as usize,
912        ))
913    }
914    #[doc = "The device accepts 'bps' metric for bw\\-min, bw\\-max and burst\\."]
915    pub fn get_support_metric_bps(&self) -> Result<(), ErrorContext> {
916        let mut iter = self.clone();
917        iter.pos = 0;
918        for attr in iter {
919            if let Caps::SupportMetricBps(val) = attr? {
920                return Ok(val);
921            }
922        }
923        Err(ErrorContext::new_missing(
924            "Caps",
925            "SupportMetricBps",
926            self.orig_loc,
927            self.buf.as_ptr() as usize,
928        ))
929    }
930    #[doc = "The device accepts 'pps' metric for bw\\-min, bw\\-max and burst\\."]
931    pub fn get_support_metric_pps(&self) -> Result<(), ErrorContext> {
932        let mut iter = self.clone();
933        iter.pos = 0;
934        for attr in iter {
935            if let Caps::SupportMetricPps(val) = attr? {
936                return Ok(val);
937            }
938        }
939        Err(ErrorContext::new_missing(
940            "Caps",
941            "SupportMetricPps",
942            self.orig_loc,
943            self.buf.as_ptr() as usize,
944        ))
945    }
946    #[doc = "The device supports nesting shaper belonging to this scope\nbelow 'node' scoped shapers\\. Only 'queue' and 'node'\nscope can have flag 'support\\-nesting'\\.\n"]
947    pub fn get_support_nesting(&self) -> Result<(), ErrorContext> {
948        let mut iter = self.clone();
949        iter.pos = 0;
950        for attr in iter {
951            if let Caps::SupportNesting(val) = attr? {
952                return Ok(val);
953            }
954        }
955        Err(ErrorContext::new_missing(
956            "Caps",
957            "SupportNesting",
958            self.orig_loc,
959            self.buf.as_ptr() as usize,
960        ))
961    }
962    #[doc = "The device supports a minimum guaranteed B/W\\."]
963    pub fn get_support_bw_min(&self) -> Result<(), ErrorContext> {
964        let mut iter = self.clone();
965        iter.pos = 0;
966        for attr in iter {
967            if let Caps::SupportBwMin(val) = attr? {
968                return Ok(val);
969            }
970        }
971        Err(ErrorContext::new_missing(
972            "Caps",
973            "SupportBwMin",
974            self.orig_loc,
975            self.buf.as_ptr() as usize,
976        ))
977    }
978    #[doc = "The device supports maximum B/W shaping\\."]
979    pub fn get_support_bw_max(&self) -> Result<(), ErrorContext> {
980        let mut iter = self.clone();
981        iter.pos = 0;
982        for attr in iter {
983            if let Caps::SupportBwMax(val) = attr? {
984                return Ok(val);
985            }
986        }
987        Err(ErrorContext::new_missing(
988            "Caps",
989            "SupportBwMax",
990            self.orig_loc,
991            self.buf.as_ptr() as usize,
992        ))
993    }
994    #[doc = "The device supports a maximum burst size\\."]
995    pub fn get_support_burst(&self) -> Result<(), ErrorContext> {
996        let mut iter = self.clone();
997        iter.pos = 0;
998        for attr in iter {
999            if let Caps::SupportBurst(val) = attr? {
1000                return Ok(val);
1001            }
1002        }
1003        Err(ErrorContext::new_missing(
1004            "Caps",
1005            "SupportBurst",
1006            self.orig_loc,
1007            self.buf.as_ptr() as usize,
1008        ))
1009    }
1010    #[doc = "The device supports priority scheduling\\."]
1011    pub fn get_support_priority(&self) -> Result<(), ErrorContext> {
1012        let mut iter = self.clone();
1013        iter.pos = 0;
1014        for attr in iter {
1015            if let Caps::SupportPriority(val) = attr? {
1016                return Ok(val);
1017            }
1018        }
1019        Err(ErrorContext::new_missing(
1020            "Caps",
1021            "SupportPriority",
1022            self.orig_loc,
1023            self.buf.as_ptr() as usize,
1024        ))
1025    }
1026    #[doc = "The device supports weighted round robin scheduling\\."]
1027    pub fn get_support_weight(&self) -> Result<(), ErrorContext> {
1028        let mut iter = self.clone();
1029        iter.pos = 0;
1030        for attr in iter {
1031            if let Caps::SupportWeight(val) = attr? {
1032                return Ok(val);
1033            }
1034        }
1035        Err(ErrorContext::new_missing(
1036            "Caps",
1037            "SupportWeight",
1038            self.orig_loc,
1039            self.buf.as_ptr() as usize,
1040        ))
1041    }
1042}
1043impl Caps {
1044    pub fn new<'a>(buf: &'a [u8]) -> IterableCaps<'a> {
1045        IterableCaps::with_loc(buf, buf.as_ptr() as usize)
1046    }
1047    fn attr_from_type(r#type: u16) -> Option<&'static str> {
1048        let res = match r#type {
1049            1u16 => "Ifindex",
1050            2u16 => "Scope",
1051            3u16 => "SupportMetricBps",
1052            4u16 => "SupportMetricPps",
1053            5u16 => "SupportNesting",
1054            6u16 => "SupportBwMin",
1055            7u16 => "SupportBwMax",
1056            8u16 => "SupportBurst",
1057            9u16 => "SupportPriority",
1058            10u16 => "SupportWeight",
1059            _ => return None,
1060        };
1061        Some(res)
1062    }
1063}
1064#[derive(Clone, Copy, Default)]
1065pub struct IterableCaps<'a> {
1066    buf: &'a [u8],
1067    pos: usize,
1068    orig_loc: usize,
1069}
1070impl<'a> IterableCaps<'a> {
1071    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1072        Self {
1073            buf,
1074            pos: 0,
1075            orig_loc,
1076        }
1077    }
1078    pub fn get_buf(&self) -> &'a [u8] {
1079        self.buf
1080    }
1081}
1082impl<'a> Iterator for IterableCaps<'a> {
1083    type Item = Result<Caps, ErrorContext>;
1084    fn next(&mut self) -> Option<Self::Item> {
1085        let pos = self.pos;
1086        let mut r#type;
1087        loop {
1088            r#type = None;
1089            if self.buf.len() == self.pos {
1090                return None;
1091            }
1092            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1093                break;
1094            };
1095            r#type = Some(header.r#type);
1096            let res = match header.r#type {
1097                1u16 => Caps::Ifindex({
1098                    let res = parse_u32(next);
1099                    let Some(val) = res else { break };
1100                    val
1101                }),
1102                2u16 => Caps::Scope({
1103                    let res = parse_u32(next);
1104                    let Some(val) = res else { break };
1105                    val
1106                }),
1107                3u16 => Caps::SupportMetricBps(()),
1108                4u16 => Caps::SupportMetricPps(()),
1109                5u16 => Caps::SupportNesting(()),
1110                6u16 => Caps::SupportBwMin(()),
1111                7u16 => Caps::SupportBwMax(()),
1112                8u16 => Caps::SupportBurst(()),
1113                9u16 => Caps::SupportPriority(()),
1114                10u16 => Caps::SupportWeight(()),
1115                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1116                n => continue,
1117            };
1118            return Some(Ok(res));
1119        }
1120        Some(Err(ErrorContext::new(
1121            "Caps",
1122            r#type.and_then(|t| Caps::attr_from_type(t)),
1123            self.orig_loc,
1124            self.buf.as_ptr().wrapping_add(pos) as usize,
1125        )))
1126    }
1127}
1128impl std::fmt::Debug for IterableCaps<'_> {
1129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1130        let mut fmt = f.debug_struct("Caps");
1131        for attr in self.clone() {
1132            let attr = match attr {
1133                Ok(a) => a,
1134                Err(err) => {
1135                    fmt.finish()?;
1136                    f.write_str("Err(")?;
1137                    err.fmt(f)?;
1138                    return f.write_str(")");
1139                }
1140            };
1141            match attr {
1142                Caps::Ifindex(val) => fmt.field("Ifindex", &val),
1143                Caps::Scope(val) => fmt.field("Scope", &FormatEnum(val.into(), Scope::from_value)),
1144                Caps::SupportMetricBps(val) => fmt.field("SupportMetricBps", &val),
1145                Caps::SupportMetricPps(val) => fmt.field("SupportMetricPps", &val),
1146                Caps::SupportNesting(val) => fmt.field("SupportNesting", &val),
1147                Caps::SupportBwMin(val) => fmt.field("SupportBwMin", &val),
1148                Caps::SupportBwMax(val) => fmt.field("SupportBwMax", &val),
1149                Caps::SupportBurst(val) => fmt.field("SupportBurst", &val),
1150                Caps::SupportPriority(val) => fmt.field("SupportPriority", &val),
1151                Caps::SupportWeight(val) => fmt.field("SupportWeight", &val),
1152            };
1153        }
1154        fmt.finish()
1155    }
1156}
1157impl IterableCaps<'_> {
1158    pub fn lookup_attr(
1159        &self,
1160        offset: usize,
1161        missing_type: Option<u16>,
1162    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1163        let mut stack = Vec::new();
1164        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1165        if missing_type.is_some() && cur == offset {
1166            stack.push(("Caps", offset));
1167            return (stack, missing_type.and_then(|t| Caps::attr_from_type(t)));
1168        }
1169        if cur > offset || cur + self.buf.len() < offset {
1170            return (stack, None);
1171        }
1172        let mut attrs = self.clone();
1173        let mut last_off = cur + attrs.pos;
1174        while let Some(attr) = attrs.next() {
1175            let Ok(attr) = attr else { break };
1176            match attr {
1177                Caps::Ifindex(val) => {
1178                    if last_off == offset {
1179                        stack.push(("Ifindex", last_off));
1180                        break;
1181                    }
1182                }
1183                Caps::Scope(val) => {
1184                    if last_off == offset {
1185                        stack.push(("Scope", last_off));
1186                        break;
1187                    }
1188                }
1189                Caps::SupportMetricBps(val) => {
1190                    if last_off == offset {
1191                        stack.push(("SupportMetricBps", last_off));
1192                        break;
1193                    }
1194                }
1195                Caps::SupportMetricPps(val) => {
1196                    if last_off == offset {
1197                        stack.push(("SupportMetricPps", last_off));
1198                        break;
1199                    }
1200                }
1201                Caps::SupportNesting(val) => {
1202                    if last_off == offset {
1203                        stack.push(("SupportNesting", last_off));
1204                        break;
1205                    }
1206                }
1207                Caps::SupportBwMin(val) => {
1208                    if last_off == offset {
1209                        stack.push(("SupportBwMin", last_off));
1210                        break;
1211                    }
1212                }
1213                Caps::SupportBwMax(val) => {
1214                    if last_off == offset {
1215                        stack.push(("SupportBwMax", last_off));
1216                        break;
1217                    }
1218                }
1219                Caps::SupportBurst(val) => {
1220                    if last_off == offset {
1221                        stack.push(("SupportBurst", last_off));
1222                        break;
1223                    }
1224                }
1225                Caps::SupportPriority(val) => {
1226                    if last_off == offset {
1227                        stack.push(("SupportPriority", last_off));
1228                        break;
1229                    }
1230                }
1231                Caps::SupportWeight(val) => {
1232                    if last_off == offset {
1233                        stack.push(("SupportWeight", last_off));
1234                        break;
1235                    }
1236                }
1237                _ => {}
1238            };
1239            last_off = cur + attrs.pos;
1240        }
1241        if !stack.is_empty() {
1242            stack.push(("Caps", cur));
1243        }
1244        (stack, None)
1245    }
1246}
1247pub struct PushNetShaper<Prev: Rec> {
1248    pub(crate) prev: Option<Prev>,
1249    pub(crate) header_offset: Option<usize>,
1250}
1251impl<Prev: Rec> Rec for PushNetShaper<Prev> {
1252    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1253        self.prev.as_mut().unwrap().as_rec_mut()
1254    }
1255    fn as_rec(&self) -> &Vec<u8> {
1256        self.prev.as_ref().unwrap().as_rec()
1257    }
1258}
1259impl<Prev: Rec> PushNetShaper<Prev> {
1260    pub fn new(prev: Prev) -> Self {
1261        Self {
1262            prev: Some(prev),
1263            header_offset: None,
1264        }
1265    }
1266    pub fn end_nested(mut self) -> Prev {
1267        let mut prev = self.prev.take().unwrap();
1268        if let Some(header_offset) = &self.header_offset {
1269            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1270        }
1271        prev
1272    }
1273    #[doc = "Unique identifier for the given shaper inside the owning device\\."]
1274    pub fn nested_handle(mut self) -> PushHandle<Self> {
1275        let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
1276        PushHandle {
1277            prev: Some(self),
1278            header_offset: Some(header_offset),
1279        }
1280    }
1281    #[doc = "Metric used by the given shaper for bw\\-min, bw\\-max and burst\\.\nAssociated type: [`Metric`] (enum)"]
1282    pub fn push_metric(mut self, value: u32) -> Self {
1283        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1284        self.as_rec_mut().extend(value.to_ne_bytes());
1285        self
1286    }
1287    #[doc = "Guaranteed bandwidth for the given shaper\\."]
1288    pub fn push_bw_min(mut self, value: u32) -> Self {
1289        push_header(self.as_rec_mut(), 3u16, 4 as u16);
1290        self.as_rec_mut().extend(value.to_ne_bytes());
1291        self
1292    }
1293    #[doc = "Maximum bandwidth for the given shaper or 0 when unlimited\\."]
1294    pub fn push_bw_max(mut self, value: u32) -> Self {
1295        push_header(self.as_rec_mut(), 4u16, 4 as u16);
1296        self.as_rec_mut().extend(value.to_ne_bytes());
1297        self
1298    }
1299    #[doc = "Maximum burst\\-size for shaping\\. Should not be interpreted\nas a quantum\\.\n"]
1300    pub fn push_burst(mut self, value: u32) -> Self {
1301        push_header(self.as_rec_mut(), 5u16, 4 as u16);
1302        self.as_rec_mut().extend(value.to_ne_bytes());
1303        self
1304    }
1305    #[doc = "Scheduling priority for the given shaper\\. The priority\nscheduling is applied to sibling shapers\\.\n"]
1306    pub fn push_priority(mut self, value: u32) -> Self {
1307        push_header(self.as_rec_mut(), 6u16, 4 as u16);
1308        self.as_rec_mut().extend(value.to_ne_bytes());
1309        self
1310    }
1311    #[doc = "Relative weight for round robin scheduling of the\ngiven shaper\\.\nThe scheduling is applied to all sibling shapers\nwith the same priority\\.\n"]
1312    pub fn push_weight(mut self, value: u32) -> Self {
1313        push_header(self.as_rec_mut(), 7u16, 4 as u16);
1314        self.as_rec_mut().extend(value.to_ne_bytes());
1315        self
1316    }
1317    #[doc = "Interface index owning the specified shaper\\."]
1318    pub fn push_ifindex(mut self, value: u32) -> Self {
1319        push_header(self.as_rec_mut(), 8u16, 4 as u16);
1320        self.as_rec_mut().extend(value.to_ne_bytes());
1321        self
1322    }
1323    #[doc = "Identifier for the parent of the affected shaper\\.\nOnly needed for @group operation\\.\n"]
1324    pub fn nested_parent(mut self) -> PushHandle<Self> {
1325        let header_offset = push_nested_header(self.as_rec_mut(), 9u16);
1326        PushHandle {
1327            prev: Some(self),
1328            header_offset: Some(header_offset),
1329        }
1330    }
1331    #[doc = "Describes a set of leaves shapers for a @group operation\\.\n\nAttribute may repeat multiple times (treat it as array)"]
1332    pub fn nested_leaves(mut self) -> PushLeafInfo<Self> {
1333        let header_offset = push_nested_header(self.as_rec_mut(), 10u16);
1334        PushLeafInfo {
1335            prev: Some(self),
1336            header_offset: Some(header_offset),
1337        }
1338    }
1339}
1340impl<Prev: Rec> Drop for PushNetShaper<Prev> {
1341    fn drop(&mut self) {
1342        if let Some(prev) = &mut self.prev {
1343            if let Some(header_offset) = &self.header_offset {
1344                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1345            }
1346        }
1347    }
1348}
1349pub struct PushHandle<Prev: Rec> {
1350    pub(crate) prev: Option<Prev>,
1351    pub(crate) header_offset: Option<usize>,
1352}
1353impl<Prev: Rec> Rec for PushHandle<Prev> {
1354    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1355        self.prev.as_mut().unwrap().as_rec_mut()
1356    }
1357    fn as_rec(&self) -> &Vec<u8> {
1358        self.prev.as_ref().unwrap().as_rec()
1359    }
1360}
1361impl<Prev: Rec> PushHandle<Prev> {
1362    pub fn new(prev: Prev) -> Self {
1363        Self {
1364            prev: Some(prev),
1365            header_offset: None,
1366        }
1367    }
1368    pub fn end_nested(mut self) -> Prev {
1369        let mut prev = self.prev.take().unwrap();
1370        if let Some(header_offset) = &self.header_offset {
1371            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1372        }
1373        prev
1374    }
1375    #[doc = "Defines the shaper @id interpretation\\.\nAssociated type: [`Scope`] (enum)"]
1376    pub fn push_scope(mut self, value: u32) -> Self {
1377        push_header(self.as_rec_mut(), 1u16, 4 as u16);
1378        self.as_rec_mut().extend(value.to_ne_bytes());
1379        self
1380    }
1381    #[doc = "Numeric identifier of a shaper\\. The id semantic depends on\nthe scope\\. For @queue scope it's the queue id and for @node\nscope it's the node identifier\\.\n"]
1382    pub fn push_id(mut self, value: u32) -> Self {
1383        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1384        self.as_rec_mut().extend(value.to_ne_bytes());
1385        self
1386    }
1387}
1388impl<Prev: Rec> Drop for PushHandle<Prev> {
1389    fn drop(&mut self) {
1390        if let Some(prev) = &mut self.prev {
1391            if let Some(header_offset) = &self.header_offset {
1392                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1393            }
1394        }
1395    }
1396}
1397pub struct PushLeafInfo<Prev: Rec> {
1398    pub(crate) prev: Option<Prev>,
1399    pub(crate) header_offset: Option<usize>,
1400}
1401impl<Prev: Rec> Rec for PushLeafInfo<Prev> {
1402    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1403        self.prev.as_mut().unwrap().as_rec_mut()
1404    }
1405    fn as_rec(&self) -> &Vec<u8> {
1406        self.prev.as_ref().unwrap().as_rec()
1407    }
1408}
1409impl<Prev: Rec> PushLeafInfo<Prev> {
1410    pub fn new(prev: Prev) -> Self {
1411        Self {
1412            prev: Some(prev),
1413            header_offset: None,
1414        }
1415    }
1416    pub fn end_nested(mut self) -> Prev {
1417        let mut prev = self.prev.take().unwrap();
1418        if let Some(header_offset) = &self.header_offset {
1419            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1420        }
1421        prev
1422    }
1423    #[doc = "Unique identifier for the given shaper inside the owning device\\."]
1424    pub fn nested_handle(mut self) -> PushHandle<Self> {
1425        let header_offset = push_nested_header(self.as_rec_mut(), 1u16);
1426        PushHandle {
1427            prev: Some(self),
1428            header_offset: Some(header_offset),
1429        }
1430    }
1431    #[doc = "Scheduling priority for the given shaper\\. The priority\nscheduling is applied to sibling shapers\\.\n"]
1432    pub fn push_priority(mut self, value: u32) -> Self {
1433        push_header(self.as_rec_mut(), 6u16, 4 as u16);
1434        self.as_rec_mut().extend(value.to_ne_bytes());
1435        self
1436    }
1437    #[doc = "Relative weight for round robin scheduling of the\ngiven shaper\\.\nThe scheduling is applied to all sibling shapers\nwith the same priority\\.\n"]
1438    pub fn push_weight(mut self, value: u32) -> Self {
1439        push_header(self.as_rec_mut(), 7u16, 4 as u16);
1440        self.as_rec_mut().extend(value.to_ne_bytes());
1441        self
1442    }
1443}
1444impl<Prev: Rec> Drop for PushLeafInfo<Prev> {
1445    fn drop(&mut self) {
1446        if let Some(prev) = &mut self.prev {
1447            if let Some(header_offset) = &self.header_offset {
1448                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1449            }
1450        }
1451    }
1452}
1453pub struct PushCaps<Prev: Rec> {
1454    pub(crate) prev: Option<Prev>,
1455    pub(crate) header_offset: Option<usize>,
1456}
1457impl<Prev: Rec> Rec for PushCaps<Prev> {
1458    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1459        self.prev.as_mut().unwrap().as_rec_mut()
1460    }
1461    fn as_rec(&self) -> &Vec<u8> {
1462        self.prev.as_ref().unwrap().as_rec()
1463    }
1464}
1465impl<Prev: Rec> PushCaps<Prev> {
1466    pub fn new(prev: Prev) -> Self {
1467        Self {
1468            prev: Some(prev),
1469            header_offset: None,
1470        }
1471    }
1472    pub fn end_nested(mut self) -> Prev {
1473        let mut prev = self.prev.take().unwrap();
1474        if let Some(header_offset) = &self.header_offset {
1475            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1476        }
1477        prev
1478    }
1479    #[doc = "Interface index queried for shapers capabilities\\."]
1480    pub fn push_ifindex(mut self, value: u32) -> Self {
1481        push_header(self.as_rec_mut(), 1u16, 4 as u16);
1482        self.as_rec_mut().extend(value.to_ne_bytes());
1483        self
1484    }
1485    #[doc = "The scope to which the queried capabilities apply\\.\nAssociated type: [`Scope`] (enum)"]
1486    pub fn push_scope(mut self, value: u32) -> Self {
1487        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1488        self.as_rec_mut().extend(value.to_ne_bytes());
1489        self
1490    }
1491    #[doc = "The device accepts 'bps' metric for bw\\-min, bw\\-max and burst\\."]
1492    pub fn push_support_metric_bps(mut self, value: ()) -> Self {
1493        push_header(self.as_rec_mut(), 3u16, 0 as u16);
1494        self
1495    }
1496    #[doc = "The device accepts 'pps' metric for bw\\-min, bw\\-max and burst\\."]
1497    pub fn push_support_metric_pps(mut self, value: ()) -> Self {
1498        push_header(self.as_rec_mut(), 4u16, 0 as u16);
1499        self
1500    }
1501    #[doc = "The device supports nesting shaper belonging to this scope\nbelow 'node' scoped shapers\\. Only 'queue' and 'node'\nscope can have flag 'support\\-nesting'\\.\n"]
1502    pub fn push_support_nesting(mut self, value: ()) -> Self {
1503        push_header(self.as_rec_mut(), 5u16, 0 as u16);
1504        self
1505    }
1506    #[doc = "The device supports a minimum guaranteed B/W\\."]
1507    pub fn push_support_bw_min(mut self, value: ()) -> Self {
1508        push_header(self.as_rec_mut(), 6u16, 0 as u16);
1509        self
1510    }
1511    #[doc = "The device supports maximum B/W shaping\\."]
1512    pub fn push_support_bw_max(mut self, value: ()) -> Self {
1513        push_header(self.as_rec_mut(), 7u16, 0 as u16);
1514        self
1515    }
1516    #[doc = "The device supports a maximum burst size\\."]
1517    pub fn push_support_burst(mut self, value: ()) -> Self {
1518        push_header(self.as_rec_mut(), 8u16, 0 as u16);
1519        self
1520    }
1521    #[doc = "The device supports priority scheduling\\."]
1522    pub fn push_support_priority(mut self, value: ()) -> Self {
1523        push_header(self.as_rec_mut(), 9u16, 0 as u16);
1524        self
1525    }
1526    #[doc = "The device supports weighted round robin scheduling\\."]
1527    pub fn push_support_weight(mut self, value: ()) -> Self {
1528        push_header(self.as_rec_mut(), 10u16, 0 as u16);
1529        self
1530    }
1531}
1532impl<Prev: Rec> Drop for PushCaps<Prev> {
1533    fn drop(&mut self) {
1534        if let Some(prev) = &mut self.prev {
1535            if let Some(header_offset) = &self.header_offset {
1536                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1537            }
1538        }
1539    }
1540}
1541#[doc = "Get information about a shaper for a given device\\.\n\nRequest attributes:\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n\nReply attributes:\n- [.get_handle()](IterableNetShaper::get_handle)\n- [.get_metric()](IterableNetShaper::get_metric)\n- [.get_bw_min()](IterableNetShaper::get_bw_min)\n- [.get_bw_max()](IterableNetShaper::get_bw_max)\n- [.get_burst()](IterableNetShaper::get_burst)\n- [.get_priority()](IterableNetShaper::get_priority)\n- [.get_weight()](IterableNetShaper::get_weight)\n- [.get_ifindex()](IterableNetShaper::get_ifindex)\n- [.get_parent()](IterableNetShaper::get_parent)\n"]
1542#[derive(Debug)]
1543pub struct OpGetDump<'r> {
1544    request: Request<'r>,
1545}
1546impl<'r> OpGetDump<'r> {
1547    pub fn new(mut request: Request<'r>) -> Self {
1548        Self::write_header(request.buf_mut());
1549        Self {
1550            request: request.set_dump(),
1551        }
1552    }
1553    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushNetShaper<&'buf mut Vec<u8>> {
1554        Self::write_header(buf);
1555        PushNetShaper::new(buf)
1556    }
1557    pub fn encode(&mut self) -> PushNetShaper<&mut Vec<u8>> {
1558        PushNetShaper::new(self.request.buf_mut())
1559    }
1560    pub fn into_encoder(self) -> PushNetShaper<RequestBuf<'r>> {
1561        PushNetShaper::new(self.request.buf)
1562    }
1563    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableNetShaper<'a> {
1564        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1565        IterableNetShaper::with_loc(attrs, buf.as_ptr() as usize)
1566    }
1567    fn write_header<Prev: Rec>(prev: &mut Prev) {
1568        let mut header = BuiltinNfgenmsg::new();
1569        header.cmd = 1u8;
1570        header.version = 1u8;
1571        prev.as_rec_mut().extend(header.as_slice());
1572    }
1573}
1574impl NetlinkRequest for OpGetDump<'_> {
1575    fn protocol(&self) -> Protocol {
1576        Protocol::Generic("net-shaper".as_bytes())
1577    }
1578    fn flags(&self) -> u16 {
1579        self.request.flags
1580    }
1581    fn payload(&self) -> &[u8] {
1582        self.request.buf()
1583    }
1584    type ReplyType<'buf> = IterableNetShaper<'buf>;
1585    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1586        Self::decode_request(buf)
1587    }
1588    fn lookup(
1589        buf: &[u8],
1590        offset: usize,
1591        missing_type: Option<u16>,
1592    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1593        Self::decode_request(buf).lookup_attr(offset, missing_type)
1594    }
1595}
1596#[doc = "Get information about a shaper for a given device\\.\n\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n\nReply attributes:\n- [.get_handle()](IterableNetShaper::get_handle)\n- [.get_metric()](IterableNetShaper::get_metric)\n- [.get_bw_min()](IterableNetShaper::get_bw_min)\n- [.get_bw_max()](IterableNetShaper::get_bw_max)\n- [.get_burst()](IterableNetShaper::get_burst)\n- [.get_priority()](IterableNetShaper::get_priority)\n- [.get_weight()](IterableNetShaper::get_weight)\n- [.get_ifindex()](IterableNetShaper::get_ifindex)\n- [.get_parent()](IterableNetShaper::get_parent)\n"]
1597#[derive(Debug)]
1598pub struct OpGetDo<'r> {
1599    request: Request<'r>,
1600}
1601impl<'r> OpGetDo<'r> {
1602    pub fn new(mut request: Request<'r>) -> Self {
1603        Self::write_header(request.buf_mut());
1604        Self { request: request }
1605    }
1606    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushNetShaper<&'buf mut Vec<u8>> {
1607        Self::write_header(buf);
1608        PushNetShaper::new(buf)
1609    }
1610    pub fn encode(&mut self) -> PushNetShaper<&mut Vec<u8>> {
1611        PushNetShaper::new(self.request.buf_mut())
1612    }
1613    pub fn into_encoder(self) -> PushNetShaper<RequestBuf<'r>> {
1614        PushNetShaper::new(self.request.buf)
1615    }
1616    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableNetShaper<'a> {
1617        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1618        IterableNetShaper::with_loc(attrs, buf.as_ptr() as usize)
1619    }
1620    fn write_header<Prev: Rec>(prev: &mut Prev) {
1621        let mut header = BuiltinNfgenmsg::new();
1622        header.cmd = 1u8;
1623        header.version = 1u8;
1624        prev.as_rec_mut().extend(header.as_slice());
1625    }
1626}
1627impl NetlinkRequest for OpGetDo<'_> {
1628    fn protocol(&self) -> Protocol {
1629        Protocol::Generic("net-shaper".as_bytes())
1630    }
1631    fn flags(&self) -> u16 {
1632        self.request.flags
1633    }
1634    fn payload(&self) -> &[u8] {
1635        self.request.buf()
1636    }
1637    type ReplyType<'buf> = IterableNetShaper<'buf>;
1638    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1639        Self::decode_request(buf)
1640    }
1641    fn lookup(
1642        buf: &[u8],
1643        offset: usize,
1644        missing_type: Option<u16>,
1645    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1646        Self::decode_request(buf).lookup_attr(offset, missing_type)
1647    }
1648}
1649#[doc = "Create or update the specified shaper\\.\nThe set operation can't be used to create a @node scope shaper,\nuse the @group operation instead\\.\n\nFlags: admin-perm\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_metric()](PushNetShaper::push_metric)\n- [.push_bw_min()](PushNetShaper::push_bw_min)\n- [.push_bw_max()](PushNetShaper::push_bw_max)\n- [.push_burst()](PushNetShaper::push_burst)\n- [.push_priority()](PushNetShaper::push_priority)\n- [.push_weight()](PushNetShaper::push_weight)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n"]
1650#[derive(Debug)]
1651pub struct OpSetDo<'r> {
1652    request: Request<'r>,
1653}
1654impl<'r> OpSetDo<'r> {
1655    pub fn new(mut request: Request<'r>) -> Self {
1656        Self::write_header(request.buf_mut());
1657        Self { request: request }
1658    }
1659    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushNetShaper<&'buf mut Vec<u8>> {
1660        Self::write_header(buf);
1661        PushNetShaper::new(buf)
1662    }
1663    pub fn encode(&mut self) -> PushNetShaper<&mut Vec<u8>> {
1664        PushNetShaper::new(self.request.buf_mut())
1665    }
1666    pub fn into_encoder(self) -> PushNetShaper<RequestBuf<'r>> {
1667        PushNetShaper::new(self.request.buf)
1668    }
1669    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableNetShaper<'a> {
1670        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1671        IterableNetShaper::with_loc(attrs, buf.as_ptr() as usize)
1672    }
1673    fn write_header<Prev: Rec>(prev: &mut Prev) {
1674        let mut header = BuiltinNfgenmsg::new();
1675        header.cmd = 2u8;
1676        header.version = 1u8;
1677        prev.as_rec_mut().extend(header.as_slice());
1678    }
1679}
1680impl NetlinkRequest for OpSetDo<'_> {
1681    fn protocol(&self) -> Protocol {
1682        Protocol::Generic("net-shaper".as_bytes())
1683    }
1684    fn flags(&self) -> u16 {
1685        self.request.flags
1686    }
1687    fn payload(&self) -> &[u8] {
1688        self.request.buf()
1689    }
1690    type ReplyType<'buf> = IterableNetShaper<'buf>;
1691    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1692        Self::decode_request(buf)
1693    }
1694    fn lookup(
1695        buf: &[u8],
1696        offset: usize,
1697        missing_type: Option<u16>,
1698    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1699        Self::decode_request(buf).lookup_attr(offset, missing_type)
1700    }
1701}
1702#[doc = "Clear (remove) the specified shaper\\. When deleting\na @node shaper, reattach all the node's leaves to the\ndeleted node's parent\\.\nIf, after the removal, the parent shaper has no more\nleaves and the parent shaper scope is @node, the parent\nnode is deleted, recursively\\.\nWhen deleting a @queue shaper or a @netdev shaper,\nthe shaper disappears from the hierarchy, but the\nqueue/device can still send traffic: it has an implicit\nnode with infinite bandwidth\\. The queue's implicit node\nfeeds an implicit RR node at the root of the hierarchy\\.\n\nFlags: admin-perm\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n"]
1703#[derive(Debug)]
1704pub struct OpDeleteDo<'r> {
1705    request: Request<'r>,
1706}
1707impl<'r> OpDeleteDo<'r> {
1708    pub fn new(mut request: Request<'r>) -> Self {
1709        Self::write_header(request.buf_mut());
1710        Self { request: request }
1711    }
1712    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushNetShaper<&'buf mut Vec<u8>> {
1713        Self::write_header(buf);
1714        PushNetShaper::new(buf)
1715    }
1716    pub fn encode(&mut self) -> PushNetShaper<&mut Vec<u8>> {
1717        PushNetShaper::new(self.request.buf_mut())
1718    }
1719    pub fn into_encoder(self) -> PushNetShaper<RequestBuf<'r>> {
1720        PushNetShaper::new(self.request.buf)
1721    }
1722    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableNetShaper<'a> {
1723        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1724        IterableNetShaper::with_loc(attrs, buf.as_ptr() as usize)
1725    }
1726    fn write_header<Prev: Rec>(prev: &mut Prev) {
1727        let mut header = BuiltinNfgenmsg::new();
1728        header.cmd = 3u8;
1729        header.version = 1u8;
1730        prev.as_rec_mut().extend(header.as_slice());
1731    }
1732}
1733impl NetlinkRequest for OpDeleteDo<'_> {
1734    fn protocol(&self) -> Protocol {
1735        Protocol::Generic("net-shaper".as_bytes())
1736    }
1737    fn flags(&self) -> u16 {
1738        self.request.flags
1739    }
1740    fn payload(&self) -> &[u8] {
1741        self.request.buf()
1742    }
1743    type ReplyType<'buf> = IterableNetShaper<'buf>;
1744    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1745        Self::decode_request(buf)
1746    }
1747    fn lookup(
1748        buf: &[u8],
1749        offset: usize,
1750        missing_type: Option<u16>,
1751    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1752        Self::decode_request(buf).lookup_attr(offset, missing_type)
1753    }
1754}
1755#[doc = "Create or update a scheduling group, attaching the specified\n@leaves shapers under the specified node identified by @handle\\.\nThe @leaves shapers scope must be @queue and the node shaper\nscope must be either @node or @netdev\\.\nWhen the node shaper has @node scope, if the @handle @id is not\nspecified, a new shaper of such scope is created, otherwise the\nspecified node must already exist\\.\nWhen updating an existing node shaper, the specified @leaves are\nadded to the existing node; such node will also retain any preexisting\nleave\\.\nThe @parent handle for a new node shaper defaults to the parent\nof all the leaves, provided all the leaves share the same parent\\.\nOtherwise @parent handle must be specified\\.\nThe user can optionally provide shaping attributes for the node\nshaper\\.\nThe operation is atomic, on failure no change is applied to\nthe device shaping configuration, otherwise the @node shaper\nfull identifier, comprising @binding and @handle, is provided\nas the reply\\.\n\nFlags: admin-perm\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_metric()](PushNetShaper::push_metric)\n- [.push_bw_min()](PushNetShaper::push_bw_min)\n- [.push_bw_max()](PushNetShaper::push_bw_max)\n- [.push_burst()](PushNetShaper::push_burst)\n- [.push_priority()](PushNetShaper::push_priority)\n- [.push_weight()](PushNetShaper::push_weight)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n- [.nested_parent()](PushNetShaper::nested_parent)\n- [.nested_leaves()](PushNetShaper::nested_leaves)\n\nReply attributes:\n- [.get_handle()](IterableNetShaper::get_handle)\n- [.get_ifindex()](IterableNetShaper::get_ifindex)\n"]
1756#[derive(Debug)]
1757pub struct OpGroupDo<'r> {
1758    request: Request<'r>,
1759}
1760impl<'r> OpGroupDo<'r> {
1761    pub fn new(mut request: Request<'r>) -> Self {
1762        Self::write_header(request.buf_mut());
1763        Self { request: request }
1764    }
1765    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushNetShaper<&'buf mut Vec<u8>> {
1766        Self::write_header(buf);
1767        PushNetShaper::new(buf)
1768    }
1769    pub fn encode(&mut self) -> PushNetShaper<&mut Vec<u8>> {
1770        PushNetShaper::new(self.request.buf_mut())
1771    }
1772    pub fn into_encoder(self) -> PushNetShaper<RequestBuf<'r>> {
1773        PushNetShaper::new(self.request.buf)
1774    }
1775    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableNetShaper<'a> {
1776        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1777        IterableNetShaper::with_loc(attrs, buf.as_ptr() as usize)
1778    }
1779    fn write_header<Prev: Rec>(prev: &mut Prev) {
1780        let mut header = BuiltinNfgenmsg::new();
1781        header.cmd = 4u8;
1782        header.version = 1u8;
1783        prev.as_rec_mut().extend(header.as_slice());
1784    }
1785}
1786impl NetlinkRequest for OpGroupDo<'_> {
1787    fn protocol(&self) -> Protocol {
1788        Protocol::Generic("net-shaper".as_bytes())
1789    }
1790    fn flags(&self) -> u16 {
1791        self.request.flags
1792    }
1793    fn payload(&self) -> &[u8] {
1794        self.request.buf()
1795    }
1796    type ReplyType<'buf> = IterableNetShaper<'buf>;
1797    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1798        Self::decode_request(buf)
1799    }
1800    fn lookup(
1801        buf: &[u8],
1802        offset: usize,
1803        missing_type: Option<u16>,
1804    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1805        Self::decode_request(buf).lookup_attr(offset, missing_type)
1806    }
1807}
1808#[doc = "Get the shaper capabilities supported by the given device\nfor the specified scope\\.\n\nRequest attributes:\n- [.push_ifindex()](PushCaps::push_ifindex)\n\nReply attributes:\n- [.get_ifindex()](IterableCaps::get_ifindex)\n- [.get_scope()](IterableCaps::get_scope)\n- [.get_support_metric_bps()](IterableCaps::get_support_metric_bps)\n- [.get_support_metric_pps()](IterableCaps::get_support_metric_pps)\n- [.get_support_nesting()](IterableCaps::get_support_nesting)\n- [.get_support_bw_min()](IterableCaps::get_support_bw_min)\n- [.get_support_bw_max()](IterableCaps::get_support_bw_max)\n- [.get_support_burst()](IterableCaps::get_support_burst)\n- [.get_support_priority()](IterableCaps::get_support_priority)\n- [.get_support_weight()](IterableCaps::get_support_weight)\n"]
1809#[derive(Debug)]
1810pub struct OpCapGetDump<'r> {
1811    request: Request<'r>,
1812}
1813impl<'r> OpCapGetDump<'r> {
1814    pub fn new(mut request: Request<'r>) -> Self {
1815        Self::write_header(request.buf_mut());
1816        Self {
1817            request: request.set_dump(),
1818        }
1819    }
1820    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCaps<&'buf mut Vec<u8>> {
1821        Self::write_header(buf);
1822        PushCaps::new(buf)
1823    }
1824    pub fn encode(&mut self) -> PushCaps<&mut Vec<u8>> {
1825        PushCaps::new(self.request.buf_mut())
1826    }
1827    pub fn into_encoder(self) -> PushCaps<RequestBuf<'r>> {
1828        PushCaps::new(self.request.buf)
1829    }
1830    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCaps<'a> {
1831        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1832        IterableCaps::with_loc(attrs, buf.as_ptr() as usize)
1833    }
1834    fn write_header<Prev: Rec>(prev: &mut Prev) {
1835        let mut header = BuiltinNfgenmsg::new();
1836        header.cmd = 5u8;
1837        header.version = 1u8;
1838        prev.as_rec_mut().extend(header.as_slice());
1839    }
1840}
1841impl NetlinkRequest for OpCapGetDump<'_> {
1842    fn protocol(&self) -> Protocol {
1843        Protocol::Generic("net-shaper".as_bytes())
1844    }
1845    fn flags(&self) -> u16 {
1846        self.request.flags
1847    }
1848    fn payload(&self) -> &[u8] {
1849        self.request.buf()
1850    }
1851    type ReplyType<'buf> = IterableCaps<'buf>;
1852    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1853        Self::decode_request(buf)
1854    }
1855    fn lookup(
1856        buf: &[u8],
1857        offset: usize,
1858        missing_type: Option<u16>,
1859    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1860        Self::decode_request(buf).lookup_attr(offset, missing_type)
1861    }
1862}
1863#[doc = "Get the shaper capabilities supported by the given device\nfor the specified scope\\.\n\nRequest attributes:\n- [.push_ifindex()](PushCaps::push_ifindex)\n- [.push_scope()](PushCaps::push_scope)\n\nReply attributes:\n- [.get_ifindex()](IterableCaps::get_ifindex)\n- [.get_scope()](IterableCaps::get_scope)\n- [.get_support_metric_bps()](IterableCaps::get_support_metric_bps)\n- [.get_support_metric_pps()](IterableCaps::get_support_metric_pps)\n- [.get_support_nesting()](IterableCaps::get_support_nesting)\n- [.get_support_bw_min()](IterableCaps::get_support_bw_min)\n- [.get_support_bw_max()](IterableCaps::get_support_bw_max)\n- [.get_support_burst()](IterableCaps::get_support_burst)\n- [.get_support_priority()](IterableCaps::get_support_priority)\n- [.get_support_weight()](IterableCaps::get_support_weight)\n"]
1864#[derive(Debug)]
1865pub struct OpCapGetDo<'r> {
1866    request: Request<'r>,
1867}
1868impl<'r> OpCapGetDo<'r> {
1869    pub fn new(mut request: Request<'r>) -> Self {
1870        Self::write_header(request.buf_mut());
1871        Self { request: request }
1872    }
1873    pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushCaps<&'buf mut Vec<u8>> {
1874        Self::write_header(buf);
1875        PushCaps::new(buf)
1876    }
1877    pub fn encode(&mut self) -> PushCaps<&mut Vec<u8>> {
1878        PushCaps::new(self.request.buf_mut())
1879    }
1880    pub fn into_encoder(self) -> PushCaps<RequestBuf<'r>> {
1881        PushCaps::new(self.request.buf)
1882    }
1883    pub fn decode_request<'a>(buf: &'a [u8]) -> IterableCaps<'a> {
1884        let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1885        IterableCaps::with_loc(attrs, buf.as_ptr() as usize)
1886    }
1887    fn write_header<Prev: Rec>(prev: &mut Prev) {
1888        let mut header = BuiltinNfgenmsg::new();
1889        header.cmd = 5u8;
1890        header.version = 1u8;
1891        prev.as_rec_mut().extend(header.as_slice());
1892    }
1893}
1894impl NetlinkRequest for OpCapGetDo<'_> {
1895    fn protocol(&self) -> Protocol {
1896        Protocol::Generic("net-shaper".as_bytes())
1897    }
1898    fn flags(&self) -> u16 {
1899        self.request.flags
1900    }
1901    fn payload(&self) -> &[u8] {
1902        self.request.buf()
1903    }
1904    type ReplyType<'buf> = IterableCaps<'buf>;
1905    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1906        Self::decode_request(buf)
1907    }
1908    fn lookup(
1909        buf: &[u8],
1910        offset: usize,
1911        missing_type: Option<u16>,
1912    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1913        Self::decode_request(buf).lookup_attr(offset, missing_type)
1914    }
1915}
1916use crate::traits::LookupFn;
1917use crate::utils::RequestBuf;
1918#[derive(Debug)]
1919pub struct Request<'buf> {
1920    buf: RequestBuf<'buf>,
1921    flags: u16,
1922    writeback: Option<&'buf mut Option<RequestInfo>>,
1923}
1924#[allow(unused)]
1925#[derive(Debug, Clone)]
1926pub struct RequestInfo {
1927    protocol: Protocol,
1928    flags: u16,
1929    name: &'static str,
1930    lookup: LookupFn,
1931}
1932impl Request<'static> {
1933    pub fn new() -> Self {
1934        Self::new_from_buf(Vec::new())
1935    }
1936    pub fn new_from_buf(buf: Vec<u8>) -> Self {
1937        Self {
1938            flags: 0,
1939            buf: RequestBuf::Own(buf),
1940            writeback: None,
1941        }
1942    }
1943    pub fn into_buf(self) -> Vec<u8> {
1944        match self.buf {
1945            RequestBuf::Own(buf) => buf,
1946            _ => unreachable!(),
1947        }
1948    }
1949}
1950impl<'buf> Request<'buf> {
1951    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1952        buf.clear();
1953        Self::new_extend(buf)
1954    }
1955    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1956        Self {
1957            flags: 0,
1958            buf: RequestBuf::Ref(buf),
1959            writeback: None,
1960        }
1961    }
1962    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1963        let Some(writeback) = &mut self.writeback else {
1964            return;
1965        };
1966        **writeback = Some(RequestInfo {
1967            protocol,
1968            flags: self.flags,
1969            name,
1970            lookup,
1971        })
1972    }
1973    pub fn buf(&self) -> &Vec<u8> {
1974        self.buf.buf()
1975    }
1976    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1977        self.buf.buf_mut()
1978    }
1979    #[doc = "Set `NLM_F_CREATE` flag"]
1980    pub fn set_create(mut self) -> Self {
1981        self.flags |= consts::NLM_F_CREATE as u16;
1982        self
1983    }
1984    #[doc = "Set `NLM_F_EXCL` flag"]
1985    pub fn set_excl(mut self) -> Self {
1986        self.flags |= consts::NLM_F_EXCL as u16;
1987        self
1988    }
1989    #[doc = "Set `NLM_F_REPLACE` flag"]
1990    pub fn set_replace(mut self) -> Self {
1991        self.flags |= consts::NLM_F_REPLACE as u16;
1992        self
1993    }
1994    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1995    pub fn set_change(self) -> Self {
1996        self.set_create().set_replace()
1997    }
1998    #[doc = "Set `NLM_F_APPEND` flag"]
1999    pub fn set_append(mut self) -> Self {
2000        self.flags |= consts::NLM_F_APPEND as u16;
2001        self
2002    }
2003    #[doc = "Set `self.flags |= flags`"]
2004    pub fn set_flags(mut self, flags: u16) -> Self {
2005        self.flags |= flags;
2006        self
2007    }
2008    #[doc = "Set `self.flags ^= self.flags & flags`"]
2009    pub fn unset_flags(mut self, flags: u16) -> Self {
2010        self.flags ^= self.flags & flags;
2011        self
2012    }
2013    #[doc = "Set `NLM_F_DUMP` flag"]
2014    fn set_dump(mut self) -> Self {
2015        self.flags |= consts::NLM_F_DUMP as u16;
2016        self
2017    }
2018    #[doc = "Get information about a shaper for a given device\\.\n\nRequest attributes:\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n\nReply attributes:\n- [.get_handle()](IterableNetShaper::get_handle)\n- [.get_metric()](IterableNetShaper::get_metric)\n- [.get_bw_min()](IterableNetShaper::get_bw_min)\n- [.get_bw_max()](IterableNetShaper::get_bw_max)\n- [.get_burst()](IterableNetShaper::get_burst)\n- [.get_priority()](IterableNetShaper::get_priority)\n- [.get_weight()](IterableNetShaper::get_weight)\n- [.get_ifindex()](IterableNetShaper::get_ifindex)\n- [.get_parent()](IterableNetShaper::get_parent)\n"]
2019    pub fn op_get_dump(self) -> OpGetDump<'buf> {
2020        let mut res = OpGetDump::new(self);
2021        res.request
2022            .do_writeback(res.protocol(), "op-get-dump", OpGetDump::lookup);
2023        res
2024    }
2025    #[doc = "Get information about a shaper for a given device\\.\n\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n\nReply attributes:\n- [.get_handle()](IterableNetShaper::get_handle)\n- [.get_metric()](IterableNetShaper::get_metric)\n- [.get_bw_min()](IterableNetShaper::get_bw_min)\n- [.get_bw_max()](IterableNetShaper::get_bw_max)\n- [.get_burst()](IterableNetShaper::get_burst)\n- [.get_priority()](IterableNetShaper::get_priority)\n- [.get_weight()](IterableNetShaper::get_weight)\n- [.get_ifindex()](IterableNetShaper::get_ifindex)\n- [.get_parent()](IterableNetShaper::get_parent)\n"]
2026    pub fn op_get_do(self) -> OpGetDo<'buf> {
2027        let mut res = OpGetDo::new(self);
2028        res.request
2029            .do_writeback(res.protocol(), "op-get-do", OpGetDo::lookup);
2030        res
2031    }
2032    #[doc = "Create or update the specified shaper\\.\nThe set operation can't be used to create a @node scope shaper,\nuse the @group operation instead\\.\n\nFlags: admin-perm\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_metric()](PushNetShaper::push_metric)\n- [.push_bw_min()](PushNetShaper::push_bw_min)\n- [.push_bw_max()](PushNetShaper::push_bw_max)\n- [.push_burst()](PushNetShaper::push_burst)\n- [.push_priority()](PushNetShaper::push_priority)\n- [.push_weight()](PushNetShaper::push_weight)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n"]
2033    pub fn op_set_do(self) -> OpSetDo<'buf> {
2034        let mut res = OpSetDo::new(self);
2035        res.request
2036            .do_writeback(res.protocol(), "op-set-do", OpSetDo::lookup);
2037        res
2038    }
2039    #[doc = "Clear (remove) the specified shaper\\. When deleting\na @node shaper, reattach all the node's leaves to the\ndeleted node's parent\\.\nIf, after the removal, the parent shaper has no more\nleaves and the parent shaper scope is @node, the parent\nnode is deleted, recursively\\.\nWhen deleting a @queue shaper or a @netdev shaper,\nthe shaper disappears from the hierarchy, but the\nqueue/device can still send traffic: it has an implicit\nnode with infinite bandwidth\\. The queue's implicit node\nfeeds an implicit RR node at the root of the hierarchy\\.\n\nFlags: admin-perm\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n"]
2040    pub fn op_delete_do(self) -> OpDeleteDo<'buf> {
2041        let mut res = OpDeleteDo::new(self);
2042        res.request
2043            .do_writeback(res.protocol(), "op-delete-do", OpDeleteDo::lookup);
2044        res
2045    }
2046    #[doc = "Create or update a scheduling group, attaching the specified\n@leaves shapers under the specified node identified by @handle\\.\nThe @leaves shapers scope must be @queue and the node shaper\nscope must be either @node or @netdev\\.\nWhen the node shaper has @node scope, if the @handle @id is not\nspecified, a new shaper of such scope is created, otherwise the\nspecified node must already exist\\.\nWhen updating an existing node shaper, the specified @leaves are\nadded to the existing node; such node will also retain any preexisting\nleave\\.\nThe @parent handle for a new node shaper defaults to the parent\nof all the leaves, provided all the leaves share the same parent\\.\nOtherwise @parent handle must be specified\\.\nThe user can optionally provide shaping attributes for the node\nshaper\\.\nThe operation is atomic, on failure no change is applied to\nthe device shaping configuration, otherwise the @node shaper\nfull identifier, comprising @binding and @handle, is provided\nas the reply\\.\n\nFlags: admin-perm\nRequest attributes:\n- [.nested_handle()](PushNetShaper::nested_handle)\n- [.push_metric()](PushNetShaper::push_metric)\n- [.push_bw_min()](PushNetShaper::push_bw_min)\n- [.push_bw_max()](PushNetShaper::push_bw_max)\n- [.push_burst()](PushNetShaper::push_burst)\n- [.push_priority()](PushNetShaper::push_priority)\n- [.push_weight()](PushNetShaper::push_weight)\n- [.push_ifindex()](PushNetShaper::push_ifindex)\n- [.nested_parent()](PushNetShaper::nested_parent)\n- [.nested_leaves()](PushNetShaper::nested_leaves)\n\nReply attributes:\n- [.get_handle()](IterableNetShaper::get_handle)\n- [.get_ifindex()](IterableNetShaper::get_ifindex)\n"]
2047    pub fn op_group_do(self) -> OpGroupDo<'buf> {
2048        let mut res = OpGroupDo::new(self);
2049        res.request
2050            .do_writeback(res.protocol(), "op-group-do", OpGroupDo::lookup);
2051        res
2052    }
2053    #[doc = "Get the shaper capabilities supported by the given device\nfor the specified scope\\.\n\nRequest attributes:\n- [.push_ifindex()](PushCaps::push_ifindex)\n\nReply attributes:\n- [.get_ifindex()](IterableCaps::get_ifindex)\n- [.get_scope()](IterableCaps::get_scope)\n- [.get_support_metric_bps()](IterableCaps::get_support_metric_bps)\n- [.get_support_metric_pps()](IterableCaps::get_support_metric_pps)\n- [.get_support_nesting()](IterableCaps::get_support_nesting)\n- [.get_support_bw_min()](IterableCaps::get_support_bw_min)\n- [.get_support_bw_max()](IterableCaps::get_support_bw_max)\n- [.get_support_burst()](IterableCaps::get_support_burst)\n- [.get_support_priority()](IterableCaps::get_support_priority)\n- [.get_support_weight()](IterableCaps::get_support_weight)\n"]
2054    pub fn op_cap_get_dump(self) -> OpCapGetDump<'buf> {
2055        let mut res = OpCapGetDump::new(self);
2056        res.request
2057            .do_writeback(res.protocol(), "op-cap-get-dump", OpCapGetDump::lookup);
2058        res
2059    }
2060    #[doc = "Get the shaper capabilities supported by the given device\nfor the specified scope\\.\n\nRequest attributes:\n- [.push_ifindex()](PushCaps::push_ifindex)\n- [.push_scope()](PushCaps::push_scope)\n\nReply attributes:\n- [.get_ifindex()](IterableCaps::get_ifindex)\n- [.get_scope()](IterableCaps::get_scope)\n- [.get_support_metric_bps()](IterableCaps::get_support_metric_bps)\n- [.get_support_metric_pps()](IterableCaps::get_support_metric_pps)\n- [.get_support_nesting()](IterableCaps::get_support_nesting)\n- [.get_support_bw_min()](IterableCaps::get_support_bw_min)\n- [.get_support_bw_max()](IterableCaps::get_support_bw_max)\n- [.get_support_burst()](IterableCaps::get_support_burst)\n- [.get_support_priority()](IterableCaps::get_support_priority)\n- [.get_support_weight()](IterableCaps::get_support_weight)\n"]
2061    pub fn op_cap_get_do(self) -> OpCapGetDo<'buf> {
2062        let mut res = OpCapGetDo::new(self);
2063        res.request
2064            .do_writeback(res.protocol(), "op-cap-get-do", OpCapGetDo::lookup);
2065        res
2066    }
2067}
2068#[cfg(test)]
2069mod generated_tests {
2070    use super::*;
2071    #[test]
2072    fn tests() {
2073        let _ = IterableCaps::get_ifindex;
2074        let _ = IterableCaps::get_scope;
2075        let _ = IterableCaps::get_support_burst;
2076        let _ = IterableCaps::get_support_bw_max;
2077        let _ = IterableCaps::get_support_bw_min;
2078        let _ = IterableCaps::get_support_metric_bps;
2079        let _ = IterableCaps::get_support_metric_pps;
2080        let _ = IterableCaps::get_support_nesting;
2081        let _ = IterableCaps::get_support_priority;
2082        let _ = IterableCaps::get_support_weight;
2083        let _ = IterableNetShaper::get_burst;
2084        let _ = IterableNetShaper::get_bw_max;
2085        let _ = IterableNetShaper::get_bw_min;
2086        let _ = IterableNetShaper::get_handle;
2087        let _ = IterableNetShaper::get_ifindex;
2088        let _ = IterableNetShaper::get_metric;
2089        let _ = IterableNetShaper::get_parent;
2090        let _ = IterableNetShaper::get_priority;
2091        let _ = IterableNetShaper::get_weight;
2092        let _ = PushCaps::<&mut Vec<u8>>::push_ifindex;
2093        let _ = PushCaps::<&mut Vec<u8>>::push_scope;
2094        let _ = PushNetShaper::<&mut Vec<u8>>::nested_handle;
2095        let _ = PushNetShaper::<&mut Vec<u8>>::nested_leaves;
2096        let _ = PushNetShaper::<&mut Vec<u8>>::nested_parent;
2097        let _ = PushNetShaper::<&mut Vec<u8>>::push_burst;
2098        let _ = PushNetShaper::<&mut Vec<u8>>::push_bw_max;
2099        let _ = PushNetShaper::<&mut Vec<u8>>::push_bw_min;
2100        let _ = PushNetShaper::<&mut Vec<u8>>::push_ifindex;
2101        let _ = PushNetShaper::<&mut Vec<u8>>::push_metric;
2102        let _ = PushNetShaper::<&mut Vec<u8>>::push_priority;
2103        let _ = PushNetShaper::<&mut Vec<u8>>::push_weight;
2104    }
2105}