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