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