1#![doc = "Route configuration over rtnetlink."]
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::{PushBuiltinBitfield32, PushBuiltinNfgenmsg, PushDummy, PushNlmsghdr};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &CStr = c"rt-route";
17pub const PROTONUM: u16 = 0u16;
18#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
19#[derive(Debug, Clone, Copy)]
20pub enum RtmType {
21 Unspec = 0,
22 Unicast = 1,
23 Local = 2,
24 Broadcast = 3,
25 Anycast = 4,
26 Multicast = 5,
27 Blackhole = 6,
28 Unreachable = 7,
29 Prohibit = 8,
30 Throw = 9,
31 Nat = 10,
32 Xresolve = 11,
33}
34impl RtmType {
35 pub fn from_value(value: u64) -> Option<Self> {
36 Some(match value {
37 0 => Self::Unspec,
38 1 => Self::Unicast,
39 2 => Self::Local,
40 3 => Self::Broadcast,
41 4 => Self::Anycast,
42 5 => Self::Multicast,
43 6 => Self::Blackhole,
44 7 => Self::Unreachable,
45 8 => Self::Prohibit,
46 9 => Self::Throw,
47 10 => Self::Nat,
48 11 => Self::Xresolve,
49 _ => return None,
50 })
51 }
52}
53#[derive(Clone)]
54pub enum RouteAttrs<'a> {
55 Dst(&'a [u8]),
56 Src(&'a [u8]),
57 Iif(u32),
58 Oif(u32),
59 Gateway(&'a [u8]),
60 Priority(u32),
61 Prefsrc(&'a [u8]),
62 Metrics(IterableMetrics<'a>),
63 Multipath(&'a [u8]),
64 Protoinfo(&'a [u8]),
65 Flow(u32),
66 Cacheinfo(PushRtaCacheinfo),
67 Session(&'a [u8]),
68 MpAlgo(&'a [u8]),
69 Table(u32),
70 Mark(u32),
71 MfcStats(&'a [u8]),
72 Via(&'a [u8]),
73 Newdst(&'a [u8]),
74 Pref(u8),
75 EncapType(u16),
76 Encap(&'a [u8]),
77 Expires(u32),
78 Pad(&'a [u8]),
79 Uid(u32),
80 TtlPropagate(u8),
81 IpProto(u8),
82 Sport(u16),
83 Dport(u16),
84 NhId(u32),
85 Flowlabel(u32),
86}
87impl<'a> IterableRouteAttrs<'a> {
88 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
89 let mut iter = self.clone();
90 iter.pos = 0;
91 for attr in iter {
92 if let RouteAttrs::Dst(val) = attr? {
93 return Ok(val);
94 }
95 }
96 Err(ErrorContext::new_missing(
97 "RouteAttrs",
98 "Dst",
99 self.orig_loc,
100 self.buf.as_ptr() as usize,
101 ))
102 }
103 pub fn get_src(&self) -> Result<&'a [u8], ErrorContext> {
104 let mut iter = self.clone();
105 iter.pos = 0;
106 for attr in iter {
107 if let RouteAttrs::Src(val) = attr? {
108 return Ok(val);
109 }
110 }
111 Err(ErrorContext::new_missing(
112 "RouteAttrs",
113 "Src",
114 self.orig_loc,
115 self.buf.as_ptr() as usize,
116 ))
117 }
118 pub fn get_iif(&self) -> Result<u32, ErrorContext> {
119 let mut iter = self.clone();
120 iter.pos = 0;
121 for attr in iter {
122 if let RouteAttrs::Iif(val) = attr? {
123 return Ok(val);
124 }
125 }
126 Err(ErrorContext::new_missing(
127 "RouteAttrs",
128 "Iif",
129 self.orig_loc,
130 self.buf.as_ptr() as usize,
131 ))
132 }
133 pub fn get_oif(&self) -> Result<u32, ErrorContext> {
134 let mut iter = self.clone();
135 iter.pos = 0;
136 for attr in iter {
137 if let RouteAttrs::Oif(val) = attr? {
138 return Ok(val);
139 }
140 }
141 Err(ErrorContext::new_missing(
142 "RouteAttrs",
143 "Oif",
144 self.orig_loc,
145 self.buf.as_ptr() as usize,
146 ))
147 }
148 pub fn get_gateway(&self) -> Result<&'a [u8], ErrorContext> {
149 let mut iter = self.clone();
150 iter.pos = 0;
151 for attr in iter {
152 if let RouteAttrs::Gateway(val) = attr? {
153 return Ok(val);
154 }
155 }
156 Err(ErrorContext::new_missing(
157 "RouteAttrs",
158 "Gateway",
159 self.orig_loc,
160 self.buf.as_ptr() as usize,
161 ))
162 }
163 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
164 let mut iter = self.clone();
165 iter.pos = 0;
166 for attr in iter {
167 if let RouteAttrs::Priority(val) = attr? {
168 return Ok(val);
169 }
170 }
171 Err(ErrorContext::new_missing(
172 "RouteAttrs",
173 "Priority",
174 self.orig_loc,
175 self.buf.as_ptr() as usize,
176 ))
177 }
178 pub fn get_prefsrc(&self) -> Result<&'a [u8], ErrorContext> {
179 let mut iter = self.clone();
180 iter.pos = 0;
181 for attr in iter {
182 if let RouteAttrs::Prefsrc(val) = attr? {
183 return Ok(val);
184 }
185 }
186 Err(ErrorContext::new_missing(
187 "RouteAttrs",
188 "Prefsrc",
189 self.orig_loc,
190 self.buf.as_ptr() as usize,
191 ))
192 }
193 pub fn get_metrics(&self) -> Result<IterableMetrics<'a>, ErrorContext> {
194 let mut iter = self.clone();
195 iter.pos = 0;
196 for attr in iter {
197 if let RouteAttrs::Metrics(val) = attr? {
198 return Ok(val);
199 }
200 }
201 Err(ErrorContext::new_missing(
202 "RouteAttrs",
203 "Metrics",
204 self.orig_loc,
205 self.buf.as_ptr() as usize,
206 ))
207 }
208 pub fn get_multipath(&self) -> Result<&'a [u8], ErrorContext> {
209 let mut iter = self.clone();
210 iter.pos = 0;
211 for attr in iter {
212 if let RouteAttrs::Multipath(val) = attr? {
213 return Ok(val);
214 }
215 }
216 Err(ErrorContext::new_missing(
217 "RouteAttrs",
218 "Multipath",
219 self.orig_loc,
220 self.buf.as_ptr() as usize,
221 ))
222 }
223 pub fn get_protoinfo(&self) -> Result<&'a [u8], ErrorContext> {
224 let mut iter = self.clone();
225 iter.pos = 0;
226 for attr in iter {
227 if let RouteAttrs::Protoinfo(val) = attr? {
228 return Ok(val);
229 }
230 }
231 Err(ErrorContext::new_missing(
232 "RouteAttrs",
233 "Protoinfo",
234 self.orig_loc,
235 self.buf.as_ptr() as usize,
236 ))
237 }
238 pub fn get_flow(&self) -> Result<u32, ErrorContext> {
239 let mut iter = self.clone();
240 iter.pos = 0;
241 for attr in iter {
242 if let RouteAttrs::Flow(val) = attr? {
243 return Ok(val);
244 }
245 }
246 Err(ErrorContext::new_missing(
247 "RouteAttrs",
248 "Flow",
249 self.orig_loc,
250 self.buf.as_ptr() as usize,
251 ))
252 }
253 pub fn get_cacheinfo(&self) -> Result<PushRtaCacheinfo, ErrorContext> {
254 let mut iter = self.clone();
255 iter.pos = 0;
256 for attr in iter {
257 if let RouteAttrs::Cacheinfo(val) = attr? {
258 return Ok(val);
259 }
260 }
261 Err(ErrorContext::new_missing(
262 "RouteAttrs",
263 "Cacheinfo",
264 self.orig_loc,
265 self.buf.as_ptr() as usize,
266 ))
267 }
268 pub fn get_session(&self) -> Result<&'a [u8], ErrorContext> {
269 let mut iter = self.clone();
270 iter.pos = 0;
271 for attr in iter {
272 if let RouteAttrs::Session(val) = attr? {
273 return Ok(val);
274 }
275 }
276 Err(ErrorContext::new_missing(
277 "RouteAttrs",
278 "Session",
279 self.orig_loc,
280 self.buf.as_ptr() as usize,
281 ))
282 }
283 pub fn get_mp_algo(&self) -> Result<&'a [u8], ErrorContext> {
284 let mut iter = self.clone();
285 iter.pos = 0;
286 for attr in iter {
287 if let RouteAttrs::MpAlgo(val) = attr? {
288 return Ok(val);
289 }
290 }
291 Err(ErrorContext::new_missing(
292 "RouteAttrs",
293 "MpAlgo",
294 self.orig_loc,
295 self.buf.as_ptr() as usize,
296 ))
297 }
298 pub fn get_table(&self) -> Result<u32, ErrorContext> {
299 let mut iter = self.clone();
300 iter.pos = 0;
301 for attr in iter {
302 if let RouteAttrs::Table(val) = attr? {
303 return Ok(val);
304 }
305 }
306 Err(ErrorContext::new_missing(
307 "RouteAttrs",
308 "Table",
309 self.orig_loc,
310 self.buf.as_ptr() as usize,
311 ))
312 }
313 pub fn get_mark(&self) -> Result<u32, ErrorContext> {
314 let mut iter = self.clone();
315 iter.pos = 0;
316 for attr in iter {
317 if let RouteAttrs::Mark(val) = attr? {
318 return Ok(val);
319 }
320 }
321 Err(ErrorContext::new_missing(
322 "RouteAttrs",
323 "Mark",
324 self.orig_loc,
325 self.buf.as_ptr() as usize,
326 ))
327 }
328 pub fn get_mfc_stats(&self) -> Result<&'a [u8], ErrorContext> {
329 let mut iter = self.clone();
330 iter.pos = 0;
331 for attr in iter {
332 if let RouteAttrs::MfcStats(val) = attr? {
333 return Ok(val);
334 }
335 }
336 Err(ErrorContext::new_missing(
337 "RouteAttrs",
338 "MfcStats",
339 self.orig_loc,
340 self.buf.as_ptr() as usize,
341 ))
342 }
343 pub fn get_via(&self) -> Result<&'a [u8], ErrorContext> {
344 let mut iter = self.clone();
345 iter.pos = 0;
346 for attr in iter {
347 if let RouteAttrs::Via(val) = attr? {
348 return Ok(val);
349 }
350 }
351 Err(ErrorContext::new_missing(
352 "RouteAttrs",
353 "Via",
354 self.orig_loc,
355 self.buf.as_ptr() as usize,
356 ))
357 }
358 pub fn get_newdst(&self) -> Result<&'a [u8], ErrorContext> {
359 let mut iter = self.clone();
360 iter.pos = 0;
361 for attr in iter {
362 if let RouteAttrs::Newdst(val) = attr? {
363 return Ok(val);
364 }
365 }
366 Err(ErrorContext::new_missing(
367 "RouteAttrs",
368 "Newdst",
369 self.orig_loc,
370 self.buf.as_ptr() as usize,
371 ))
372 }
373 pub fn get_pref(&self) -> Result<u8, ErrorContext> {
374 let mut iter = self.clone();
375 iter.pos = 0;
376 for attr in iter {
377 if let RouteAttrs::Pref(val) = attr? {
378 return Ok(val);
379 }
380 }
381 Err(ErrorContext::new_missing(
382 "RouteAttrs",
383 "Pref",
384 self.orig_loc,
385 self.buf.as_ptr() as usize,
386 ))
387 }
388 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
389 let mut iter = self.clone();
390 iter.pos = 0;
391 for attr in iter {
392 if let RouteAttrs::EncapType(val) = attr? {
393 return Ok(val);
394 }
395 }
396 Err(ErrorContext::new_missing(
397 "RouteAttrs",
398 "EncapType",
399 self.orig_loc,
400 self.buf.as_ptr() as usize,
401 ))
402 }
403 pub fn get_encap(&self) -> Result<&'a [u8], ErrorContext> {
404 let mut iter = self.clone();
405 iter.pos = 0;
406 for attr in iter {
407 if let RouteAttrs::Encap(val) = attr? {
408 return Ok(val);
409 }
410 }
411 Err(ErrorContext::new_missing(
412 "RouteAttrs",
413 "Encap",
414 self.orig_loc,
415 self.buf.as_ptr() as usize,
416 ))
417 }
418 pub fn get_expires(&self) -> Result<u32, ErrorContext> {
419 let mut iter = self.clone();
420 iter.pos = 0;
421 for attr in iter {
422 if let RouteAttrs::Expires(val) = attr? {
423 return Ok(val);
424 }
425 }
426 Err(ErrorContext::new_missing(
427 "RouteAttrs",
428 "Expires",
429 self.orig_loc,
430 self.buf.as_ptr() as usize,
431 ))
432 }
433 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
434 let mut iter = self.clone();
435 iter.pos = 0;
436 for attr in iter {
437 if let RouteAttrs::Pad(val) = attr? {
438 return Ok(val);
439 }
440 }
441 Err(ErrorContext::new_missing(
442 "RouteAttrs",
443 "Pad",
444 self.orig_loc,
445 self.buf.as_ptr() as usize,
446 ))
447 }
448 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
449 let mut iter = self.clone();
450 iter.pos = 0;
451 for attr in iter {
452 if let RouteAttrs::Uid(val) = attr? {
453 return Ok(val);
454 }
455 }
456 Err(ErrorContext::new_missing(
457 "RouteAttrs",
458 "Uid",
459 self.orig_loc,
460 self.buf.as_ptr() as usize,
461 ))
462 }
463 pub fn get_ttl_propagate(&self) -> Result<u8, ErrorContext> {
464 let mut iter = self.clone();
465 iter.pos = 0;
466 for attr in iter {
467 if let RouteAttrs::TtlPropagate(val) = attr? {
468 return Ok(val);
469 }
470 }
471 Err(ErrorContext::new_missing(
472 "RouteAttrs",
473 "TtlPropagate",
474 self.orig_loc,
475 self.buf.as_ptr() as usize,
476 ))
477 }
478 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
479 let mut iter = self.clone();
480 iter.pos = 0;
481 for attr in iter {
482 if let RouteAttrs::IpProto(val) = attr? {
483 return Ok(val);
484 }
485 }
486 Err(ErrorContext::new_missing(
487 "RouteAttrs",
488 "IpProto",
489 self.orig_loc,
490 self.buf.as_ptr() as usize,
491 ))
492 }
493 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
494 let mut iter = self.clone();
495 iter.pos = 0;
496 for attr in iter {
497 if let RouteAttrs::Sport(val) = attr? {
498 return Ok(val);
499 }
500 }
501 Err(ErrorContext::new_missing(
502 "RouteAttrs",
503 "Sport",
504 self.orig_loc,
505 self.buf.as_ptr() as usize,
506 ))
507 }
508 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
509 let mut iter = self.clone();
510 iter.pos = 0;
511 for attr in iter {
512 if let RouteAttrs::Dport(val) = attr? {
513 return Ok(val);
514 }
515 }
516 Err(ErrorContext::new_missing(
517 "RouteAttrs",
518 "Dport",
519 self.orig_loc,
520 self.buf.as_ptr() as usize,
521 ))
522 }
523 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
524 let mut iter = self.clone();
525 iter.pos = 0;
526 for attr in iter {
527 if let RouteAttrs::NhId(val) = attr? {
528 return Ok(val);
529 }
530 }
531 Err(ErrorContext::new_missing(
532 "RouteAttrs",
533 "NhId",
534 self.orig_loc,
535 self.buf.as_ptr() as usize,
536 ))
537 }
538 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
539 let mut iter = self.clone();
540 iter.pos = 0;
541 for attr in iter {
542 if let RouteAttrs::Flowlabel(val) = attr? {
543 return Ok(val);
544 }
545 }
546 Err(ErrorContext::new_missing(
547 "RouteAttrs",
548 "Flowlabel",
549 self.orig_loc,
550 self.buf.as_ptr() as usize,
551 ))
552 }
553}
554impl<'a> RouteAttrs<'a> {
555 pub fn new(buf: &'a [u8]) -> IterableRouteAttrs<'a> {
556 IterableRouteAttrs::with_loc(buf, buf.as_ptr() as usize)
557 }
558 fn attr_from_type(r#type: u16) -> Option<&'static str> {
559 let res = match r#type {
560 1u16 => "Dst",
561 2u16 => "Src",
562 3u16 => "Iif",
563 4u16 => "Oif",
564 5u16 => "Gateway",
565 6u16 => "Priority",
566 7u16 => "Prefsrc",
567 8u16 => "Metrics",
568 9u16 => "Multipath",
569 10u16 => "Protoinfo",
570 11u16 => "Flow",
571 12u16 => "Cacheinfo",
572 13u16 => "Session",
573 14u16 => "MpAlgo",
574 15u16 => "Table",
575 16u16 => "Mark",
576 17u16 => "MfcStats",
577 18u16 => "Via",
578 19u16 => "Newdst",
579 20u16 => "Pref",
580 21u16 => "EncapType",
581 22u16 => "Encap",
582 23u16 => "Expires",
583 24u16 => "Pad",
584 25u16 => "Uid",
585 26u16 => "TtlPropagate",
586 27u16 => "IpProto",
587 28u16 => "Sport",
588 29u16 => "Dport",
589 30u16 => "NhId",
590 31u16 => "Flowlabel",
591 _ => return None,
592 };
593 Some(res)
594 }
595}
596#[derive(Clone, Copy, Default)]
597pub struct IterableRouteAttrs<'a> {
598 buf: &'a [u8],
599 pos: usize,
600 orig_loc: usize,
601}
602impl<'a> IterableRouteAttrs<'a> {
603 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
604 Self {
605 buf,
606 pos: 0,
607 orig_loc,
608 }
609 }
610 pub fn get_buf(&self) -> &'a [u8] {
611 self.buf
612 }
613}
614impl<'a> Iterator for IterableRouteAttrs<'a> {
615 type Item = Result<RouteAttrs<'a>, ErrorContext>;
616 fn next(&mut self) -> Option<Self::Item> {
617 if self.buf.len() == self.pos {
618 return None;
619 }
620 let pos = self.pos;
621 let mut r#type = None;
622 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
623 r#type = Some(header.r#type);
624 let res = match header.r#type {
625 1u16 => RouteAttrs::Dst({
626 let res = Some(next);
627 let Some(val) = res else { break };
628 val
629 }),
630 2u16 => RouteAttrs::Src({
631 let res = Some(next);
632 let Some(val) = res else { break };
633 val
634 }),
635 3u16 => RouteAttrs::Iif({
636 let res = parse_u32(next);
637 let Some(val) = res else { break };
638 val
639 }),
640 4u16 => RouteAttrs::Oif({
641 let res = parse_u32(next);
642 let Some(val) = res else { break };
643 val
644 }),
645 5u16 => RouteAttrs::Gateway({
646 let res = Some(next);
647 let Some(val) = res else { break };
648 val
649 }),
650 6u16 => RouteAttrs::Priority({
651 let res = parse_u32(next);
652 let Some(val) = res else { break };
653 val
654 }),
655 7u16 => RouteAttrs::Prefsrc({
656 let res = Some(next);
657 let Some(val) = res else { break };
658 val
659 }),
660 8u16 => RouteAttrs::Metrics({
661 let res = Some(IterableMetrics::with_loc(next, self.orig_loc));
662 let Some(val) = res else { break };
663 val
664 }),
665 9u16 => RouteAttrs::Multipath({
666 let res = Some(next);
667 let Some(val) = res else { break };
668 val
669 }),
670 10u16 => RouteAttrs::Protoinfo({
671 let res = Some(next);
672 let Some(val) = res else { break };
673 val
674 }),
675 11u16 => RouteAttrs::Flow({
676 let res = parse_u32(next);
677 let Some(val) = res else { break };
678 val
679 }),
680 12u16 => RouteAttrs::Cacheinfo({
681 let res = PushRtaCacheinfo::new_from_slice(next);
682 let Some(val) = res else { break };
683 val
684 }),
685 13u16 => RouteAttrs::Session({
686 let res = Some(next);
687 let Some(val) = res else { break };
688 val
689 }),
690 14u16 => RouteAttrs::MpAlgo({
691 let res = Some(next);
692 let Some(val) = res else { break };
693 val
694 }),
695 15u16 => RouteAttrs::Table({
696 let res = parse_u32(next);
697 let Some(val) = res else { break };
698 val
699 }),
700 16u16 => RouteAttrs::Mark({
701 let res = parse_u32(next);
702 let Some(val) = res else { break };
703 val
704 }),
705 17u16 => RouteAttrs::MfcStats({
706 let res = Some(next);
707 let Some(val) = res else { break };
708 val
709 }),
710 18u16 => RouteAttrs::Via({
711 let res = Some(next);
712 let Some(val) = res else { break };
713 val
714 }),
715 19u16 => RouteAttrs::Newdst({
716 let res = Some(next);
717 let Some(val) = res else { break };
718 val
719 }),
720 20u16 => RouteAttrs::Pref({
721 let res = parse_u8(next);
722 let Some(val) = res else { break };
723 val
724 }),
725 21u16 => RouteAttrs::EncapType({
726 let res = parse_u16(next);
727 let Some(val) = res else { break };
728 val
729 }),
730 22u16 => RouteAttrs::Encap({
731 let res = Some(next);
732 let Some(val) = res else { break };
733 val
734 }),
735 23u16 => RouteAttrs::Expires({
736 let res = parse_u32(next);
737 let Some(val) = res else { break };
738 val
739 }),
740 24u16 => RouteAttrs::Pad({
741 let res = Some(next);
742 let Some(val) = res else { break };
743 val
744 }),
745 25u16 => RouteAttrs::Uid({
746 let res = parse_u32(next);
747 let Some(val) = res else { break };
748 val
749 }),
750 26u16 => RouteAttrs::TtlPropagate({
751 let res = parse_u8(next);
752 let Some(val) = res else { break };
753 val
754 }),
755 27u16 => RouteAttrs::IpProto({
756 let res = parse_u8(next);
757 let Some(val) = res else { break };
758 val
759 }),
760 28u16 => RouteAttrs::Sport({
761 let res = parse_u16(next);
762 let Some(val) = res else { break };
763 val
764 }),
765 29u16 => RouteAttrs::Dport({
766 let res = parse_u16(next);
767 let Some(val) = res else { break };
768 val
769 }),
770 30u16 => RouteAttrs::NhId({
771 let res = parse_u32(next);
772 let Some(val) = res else { break };
773 val
774 }),
775 31u16 => RouteAttrs::Flowlabel({
776 let res = parse_be_u32(next);
777 let Some(val) = res else { break };
778 val
779 }),
780 n => {
781 if cfg!(any(test, feature = "deny-unknown-attrs")) {
782 break;
783 } else {
784 continue;
785 }
786 }
787 };
788 return Some(Ok(res));
789 }
790 Some(Err(ErrorContext::new(
791 "RouteAttrs",
792 r#type.and_then(|t| RouteAttrs::attr_from_type(t)),
793 self.orig_loc,
794 self.buf.as_ptr().wrapping_add(pos) as usize,
795 )))
796 }
797}
798impl<'a> std::fmt::Debug for IterableRouteAttrs<'_> {
799 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
800 let mut fmt = f.debug_struct("RouteAttrs");
801 for attr in self.clone() {
802 let attr = match attr {
803 Ok(a) => a,
804 Err(err) => {
805 fmt.finish()?;
806 f.write_str("Err(")?;
807 err.fmt(f)?;
808 return f.write_str(")");
809 }
810 };
811 match attr {
812 RouteAttrs::Dst(val) => fmt.field("Dst", &val),
813 RouteAttrs::Src(val) => fmt.field("Src", &val),
814 RouteAttrs::Iif(val) => fmt.field("Iif", &val),
815 RouteAttrs::Oif(val) => fmt.field("Oif", &val),
816 RouteAttrs::Gateway(val) => fmt.field("Gateway", &val),
817 RouteAttrs::Priority(val) => fmt.field("Priority", &val),
818 RouteAttrs::Prefsrc(val) => fmt.field("Prefsrc", &val),
819 RouteAttrs::Metrics(val) => fmt.field("Metrics", &val),
820 RouteAttrs::Multipath(val) => fmt.field("Multipath", &val),
821 RouteAttrs::Protoinfo(val) => fmt.field("Protoinfo", &val),
822 RouteAttrs::Flow(val) => fmt.field("Flow", &val),
823 RouteAttrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
824 RouteAttrs::Session(val) => fmt.field("Session", &val),
825 RouteAttrs::MpAlgo(val) => fmt.field("MpAlgo", &val),
826 RouteAttrs::Table(val) => fmt.field("Table", &val),
827 RouteAttrs::Mark(val) => fmt.field("Mark", &val),
828 RouteAttrs::MfcStats(val) => fmt.field("MfcStats", &val),
829 RouteAttrs::Via(val) => fmt.field("Via", &val),
830 RouteAttrs::Newdst(val) => fmt.field("Newdst", &val),
831 RouteAttrs::Pref(val) => fmt.field("Pref", &val),
832 RouteAttrs::EncapType(val) => fmt.field("EncapType", &val),
833 RouteAttrs::Encap(val) => fmt.field("Encap", &val),
834 RouteAttrs::Expires(val) => fmt.field("Expires", &val),
835 RouteAttrs::Pad(val) => fmt.field("Pad", &val),
836 RouteAttrs::Uid(val) => fmt.field("Uid", &val),
837 RouteAttrs::TtlPropagate(val) => fmt.field("TtlPropagate", &val),
838 RouteAttrs::IpProto(val) => fmt.field("IpProto", &val),
839 RouteAttrs::Sport(val) => fmt.field("Sport", &val),
840 RouteAttrs::Dport(val) => fmt.field("Dport", &val),
841 RouteAttrs::NhId(val) => fmt.field("NhId", &val),
842 RouteAttrs::Flowlabel(val) => fmt.field("Flowlabel", &val),
843 };
844 }
845 fmt.finish()
846 }
847}
848impl IterableRouteAttrs<'_> {
849 pub fn lookup_attr(
850 &self,
851 offset: usize,
852 missing_type: Option<u16>,
853 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
854 let mut stack = Vec::new();
855 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
856 if cur == offset {
857 stack.push(("RouteAttrs", offset));
858 return (
859 stack,
860 missing_type.and_then(|t| RouteAttrs::attr_from_type(t)),
861 );
862 }
863 if cur > offset || cur + self.buf.len() < offset {
864 return (stack, None);
865 }
866 let mut attrs = self.clone();
867 let mut last_off = cur + attrs.pos;
868 let mut missing = None;
869 while let Some(attr) = attrs.next() {
870 let Ok(attr) = attr else { break };
871 match attr {
872 RouteAttrs::Dst(val) => {
873 if last_off == offset {
874 stack.push(("Dst", last_off));
875 break;
876 }
877 }
878 RouteAttrs::Src(val) => {
879 if last_off == offset {
880 stack.push(("Src", last_off));
881 break;
882 }
883 }
884 RouteAttrs::Iif(val) => {
885 if last_off == offset {
886 stack.push(("Iif", last_off));
887 break;
888 }
889 }
890 RouteAttrs::Oif(val) => {
891 if last_off == offset {
892 stack.push(("Oif", last_off));
893 break;
894 }
895 }
896 RouteAttrs::Gateway(val) => {
897 if last_off == offset {
898 stack.push(("Gateway", last_off));
899 break;
900 }
901 }
902 RouteAttrs::Priority(val) => {
903 if last_off == offset {
904 stack.push(("Priority", last_off));
905 break;
906 }
907 }
908 RouteAttrs::Prefsrc(val) => {
909 if last_off == offset {
910 stack.push(("Prefsrc", last_off));
911 break;
912 }
913 }
914 RouteAttrs::Metrics(val) => {
915 (stack, missing) = val.lookup_attr(offset, missing_type);
916 if !stack.is_empty() {
917 break;
918 }
919 }
920 RouteAttrs::Multipath(val) => {
921 if last_off == offset {
922 stack.push(("Multipath", last_off));
923 break;
924 }
925 }
926 RouteAttrs::Protoinfo(val) => {
927 if last_off == offset {
928 stack.push(("Protoinfo", last_off));
929 break;
930 }
931 }
932 RouteAttrs::Flow(val) => {
933 if last_off == offset {
934 stack.push(("Flow", last_off));
935 break;
936 }
937 }
938 RouteAttrs::Cacheinfo(val) => {
939 if last_off == offset {
940 stack.push(("Cacheinfo", last_off));
941 break;
942 }
943 }
944 RouteAttrs::Session(val) => {
945 if last_off == offset {
946 stack.push(("Session", last_off));
947 break;
948 }
949 }
950 RouteAttrs::MpAlgo(val) => {
951 if last_off == offset {
952 stack.push(("MpAlgo", last_off));
953 break;
954 }
955 }
956 RouteAttrs::Table(val) => {
957 if last_off == offset {
958 stack.push(("Table", last_off));
959 break;
960 }
961 }
962 RouteAttrs::Mark(val) => {
963 if last_off == offset {
964 stack.push(("Mark", last_off));
965 break;
966 }
967 }
968 RouteAttrs::MfcStats(val) => {
969 if last_off == offset {
970 stack.push(("MfcStats", last_off));
971 break;
972 }
973 }
974 RouteAttrs::Via(val) => {
975 if last_off == offset {
976 stack.push(("Via", last_off));
977 break;
978 }
979 }
980 RouteAttrs::Newdst(val) => {
981 if last_off == offset {
982 stack.push(("Newdst", last_off));
983 break;
984 }
985 }
986 RouteAttrs::Pref(val) => {
987 if last_off == offset {
988 stack.push(("Pref", last_off));
989 break;
990 }
991 }
992 RouteAttrs::EncapType(val) => {
993 if last_off == offset {
994 stack.push(("EncapType", last_off));
995 break;
996 }
997 }
998 RouteAttrs::Encap(val) => {
999 if last_off == offset {
1000 stack.push(("Encap", last_off));
1001 break;
1002 }
1003 }
1004 RouteAttrs::Expires(val) => {
1005 if last_off == offset {
1006 stack.push(("Expires", last_off));
1007 break;
1008 }
1009 }
1010 RouteAttrs::Pad(val) => {
1011 if last_off == offset {
1012 stack.push(("Pad", last_off));
1013 break;
1014 }
1015 }
1016 RouteAttrs::Uid(val) => {
1017 if last_off == offset {
1018 stack.push(("Uid", last_off));
1019 break;
1020 }
1021 }
1022 RouteAttrs::TtlPropagate(val) => {
1023 if last_off == offset {
1024 stack.push(("TtlPropagate", last_off));
1025 break;
1026 }
1027 }
1028 RouteAttrs::IpProto(val) => {
1029 if last_off == offset {
1030 stack.push(("IpProto", last_off));
1031 break;
1032 }
1033 }
1034 RouteAttrs::Sport(val) => {
1035 if last_off == offset {
1036 stack.push(("Sport", last_off));
1037 break;
1038 }
1039 }
1040 RouteAttrs::Dport(val) => {
1041 if last_off == offset {
1042 stack.push(("Dport", last_off));
1043 break;
1044 }
1045 }
1046 RouteAttrs::NhId(val) => {
1047 if last_off == offset {
1048 stack.push(("NhId", last_off));
1049 break;
1050 }
1051 }
1052 RouteAttrs::Flowlabel(val) => {
1053 if last_off == offset {
1054 stack.push(("Flowlabel", last_off));
1055 break;
1056 }
1057 }
1058 _ => {}
1059 };
1060 last_off = cur + attrs.pos;
1061 }
1062 if !stack.is_empty() {
1063 stack.push(("RouteAttrs", cur));
1064 }
1065 (stack, missing)
1066 }
1067}
1068#[derive(Clone)]
1069pub enum Metrics<'a> {
1070 Lock(u32),
1071 Mtu(u32),
1072 Window(u32),
1073 Rtt(u32),
1074 Rttvar(u32),
1075 Ssthresh(u32),
1076 Cwnd(u32),
1077 Advmss(u32),
1078 Reordering(u32),
1079 Hoplimit(u32),
1080 Initcwnd(u32),
1081 Features(u32),
1082 RtoMin(u32),
1083 Initrwnd(u32),
1084 Quickack(u32),
1085 CcAlgo(&'a CStr),
1086 FastopenNoCookie(u32),
1087}
1088impl<'a> IterableMetrics<'a> {
1089 pub fn get_lock(&self) -> Result<u32, ErrorContext> {
1090 let mut iter = self.clone();
1091 iter.pos = 0;
1092 for attr in iter {
1093 if let Metrics::Lock(val) = attr? {
1094 return Ok(val);
1095 }
1096 }
1097 Err(ErrorContext::new_missing(
1098 "Metrics",
1099 "Lock",
1100 self.orig_loc,
1101 self.buf.as_ptr() as usize,
1102 ))
1103 }
1104 pub fn get_mtu(&self) -> Result<u32, ErrorContext> {
1105 let mut iter = self.clone();
1106 iter.pos = 0;
1107 for attr in iter {
1108 if let Metrics::Mtu(val) = attr? {
1109 return Ok(val);
1110 }
1111 }
1112 Err(ErrorContext::new_missing(
1113 "Metrics",
1114 "Mtu",
1115 self.orig_loc,
1116 self.buf.as_ptr() as usize,
1117 ))
1118 }
1119 pub fn get_window(&self) -> Result<u32, ErrorContext> {
1120 let mut iter = self.clone();
1121 iter.pos = 0;
1122 for attr in iter {
1123 if let Metrics::Window(val) = attr? {
1124 return Ok(val);
1125 }
1126 }
1127 Err(ErrorContext::new_missing(
1128 "Metrics",
1129 "Window",
1130 self.orig_loc,
1131 self.buf.as_ptr() as usize,
1132 ))
1133 }
1134 pub fn get_rtt(&self) -> Result<u32, ErrorContext> {
1135 let mut iter = self.clone();
1136 iter.pos = 0;
1137 for attr in iter {
1138 if let Metrics::Rtt(val) = attr? {
1139 return Ok(val);
1140 }
1141 }
1142 Err(ErrorContext::new_missing(
1143 "Metrics",
1144 "Rtt",
1145 self.orig_loc,
1146 self.buf.as_ptr() as usize,
1147 ))
1148 }
1149 pub fn get_rttvar(&self) -> Result<u32, ErrorContext> {
1150 let mut iter = self.clone();
1151 iter.pos = 0;
1152 for attr in iter {
1153 if let Metrics::Rttvar(val) = attr? {
1154 return Ok(val);
1155 }
1156 }
1157 Err(ErrorContext::new_missing(
1158 "Metrics",
1159 "Rttvar",
1160 self.orig_loc,
1161 self.buf.as_ptr() as usize,
1162 ))
1163 }
1164 pub fn get_ssthresh(&self) -> Result<u32, ErrorContext> {
1165 let mut iter = self.clone();
1166 iter.pos = 0;
1167 for attr in iter {
1168 if let Metrics::Ssthresh(val) = attr? {
1169 return Ok(val);
1170 }
1171 }
1172 Err(ErrorContext::new_missing(
1173 "Metrics",
1174 "Ssthresh",
1175 self.orig_loc,
1176 self.buf.as_ptr() as usize,
1177 ))
1178 }
1179 pub fn get_cwnd(&self) -> Result<u32, ErrorContext> {
1180 let mut iter = self.clone();
1181 iter.pos = 0;
1182 for attr in iter {
1183 if let Metrics::Cwnd(val) = attr? {
1184 return Ok(val);
1185 }
1186 }
1187 Err(ErrorContext::new_missing(
1188 "Metrics",
1189 "Cwnd",
1190 self.orig_loc,
1191 self.buf.as_ptr() as usize,
1192 ))
1193 }
1194 pub fn get_advmss(&self) -> Result<u32, ErrorContext> {
1195 let mut iter = self.clone();
1196 iter.pos = 0;
1197 for attr in iter {
1198 if let Metrics::Advmss(val) = attr? {
1199 return Ok(val);
1200 }
1201 }
1202 Err(ErrorContext::new_missing(
1203 "Metrics",
1204 "Advmss",
1205 self.orig_loc,
1206 self.buf.as_ptr() as usize,
1207 ))
1208 }
1209 pub fn get_reordering(&self) -> Result<u32, ErrorContext> {
1210 let mut iter = self.clone();
1211 iter.pos = 0;
1212 for attr in iter {
1213 if let Metrics::Reordering(val) = attr? {
1214 return Ok(val);
1215 }
1216 }
1217 Err(ErrorContext::new_missing(
1218 "Metrics",
1219 "Reordering",
1220 self.orig_loc,
1221 self.buf.as_ptr() as usize,
1222 ))
1223 }
1224 pub fn get_hoplimit(&self) -> Result<u32, ErrorContext> {
1225 let mut iter = self.clone();
1226 iter.pos = 0;
1227 for attr in iter {
1228 if let Metrics::Hoplimit(val) = attr? {
1229 return Ok(val);
1230 }
1231 }
1232 Err(ErrorContext::new_missing(
1233 "Metrics",
1234 "Hoplimit",
1235 self.orig_loc,
1236 self.buf.as_ptr() as usize,
1237 ))
1238 }
1239 pub fn get_initcwnd(&self) -> Result<u32, ErrorContext> {
1240 let mut iter = self.clone();
1241 iter.pos = 0;
1242 for attr in iter {
1243 if let Metrics::Initcwnd(val) = attr? {
1244 return Ok(val);
1245 }
1246 }
1247 Err(ErrorContext::new_missing(
1248 "Metrics",
1249 "Initcwnd",
1250 self.orig_loc,
1251 self.buf.as_ptr() as usize,
1252 ))
1253 }
1254 pub fn get_features(&self) -> Result<u32, ErrorContext> {
1255 let mut iter = self.clone();
1256 iter.pos = 0;
1257 for attr in iter {
1258 if let Metrics::Features(val) = attr? {
1259 return Ok(val);
1260 }
1261 }
1262 Err(ErrorContext::new_missing(
1263 "Metrics",
1264 "Features",
1265 self.orig_loc,
1266 self.buf.as_ptr() as usize,
1267 ))
1268 }
1269 pub fn get_rto_min(&self) -> Result<u32, ErrorContext> {
1270 let mut iter = self.clone();
1271 iter.pos = 0;
1272 for attr in iter {
1273 if let Metrics::RtoMin(val) = attr? {
1274 return Ok(val);
1275 }
1276 }
1277 Err(ErrorContext::new_missing(
1278 "Metrics",
1279 "RtoMin",
1280 self.orig_loc,
1281 self.buf.as_ptr() as usize,
1282 ))
1283 }
1284 pub fn get_initrwnd(&self) -> Result<u32, ErrorContext> {
1285 let mut iter = self.clone();
1286 iter.pos = 0;
1287 for attr in iter {
1288 if let Metrics::Initrwnd(val) = attr? {
1289 return Ok(val);
1290 }
1291 }
1292 Err(ErrorContext::new_missing(
1293 "Metrics",
1294 "Initrwnd",
1295 self.orig_loc,
1296 self.buf.as_ptr() as usize,
1297 ))
1298 }
1299 pub fn get_quickack(&self) -> Result<u32, ErrorContext> {
1300 let mut iter = self.clone();
1301 iter.pos = 0;
1302 for attr in iter {
1303 if let Metrics::Quickack(val) = attr? {
1304 return Ok(val);
1305 }
1306 }
1307 Err(ErrorContext::new_missing(
1308 "Metrics",
1309 "Quickack",
1310 self.orig_loc,
1311 self.buf.as_ptr() as usize,
1312 ))
1313 }
1314 pub fn get_cc_algo(&self) -> Result<&'a CStr, ErrorContext> {
1315 let mut iter = self.clone();
1316 iter.pos = 0;
1317 for attr in iter {
1318 if let Metrics::CcAlgo(val) = attr? {
1319 return Ok(val);
1320 }
1321 }
1322 Err(ErrorContext::new_missing(
1323 "Metrics",
1324 "CcAlgo",
1325 self.orig_loc,
1326 self.buf.as_ptr() as usize,
1327 ))
1328 }
1329 pub fn get_fastopen_no_cookie(&self) -> Result<u32, ErrorContext> {
1330 let mut iter = self.clone();
1331 iter.pos = 0;
1332 for attr in iter {
1333 if let Metrics::FastopenNoCookie(val) = attr? {
1334 return Ok(val);
1335 }
1336 }
1337 Err(ErrorContext::new_missing(
1338 "Metrics",
1339 "FastopenNoCookie",
1340 self.orig_loc,
1341 self.buf.as_ptr() as usize,
1342 ))
1343 }
1344}
1345impl<'a> Metrics<'a> {
1346 pub fn new(buf: &'a [u8]) -> IterableMetrics<'a> {
1347 IterableMetrics::with_loc(buf, buf.as_ptr() as usize)
1348 }
1349 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1350 let res = match r#type {
1351 0u16 => "Unspec",
1352 1u16 => "Lock",
1353 2u16 => "Mtu",
1354 3u16 => "Window",
1355 4u16 => "Rtt",
1356 5u16 => "Rttvar",
1357 6u16 => "Ssthresh",
1358 7u16 => "Cwnd",
1359 8u16 => "Advmss",
1360 9u16 => "Reordering",
1361 10u16 => "Hoplimit",
1362 11u16 => "Initcwnd",
1363 12u16 => "Features",
1364 13u16 => "RtoMin",
1365 14u16 => "Initrwnd",
1366 15u16 => "Quickack",
1367 16u16 => "CcAlgo",
1368 17u16 => "FastopenNoCookie",
1369 _ => return None,
1370 };
1371 Some(res)
1372 }
1373}
1374#[derive(Clone, Copy, Default)]
1375pub struct IterableMetrics<'a> {
1376 buf: &'a [u8],
1377 pos: usize,
1378 orig_loc: usize,
1379}
1380impl<'a> IterableMetrics<'a> {
1381 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1382 Self {
1383 buf,
1384 pos: 0,
1385 orig_loc,
1386 }
1387 }
1388 pub fn get_buf(&self) -> &'a [u8] {
1389 self.buf
1390 }
1391}
1392impl<'a> Iterator for IterableMetrics<'a> {
1393 type Item = Result<Metrics<'a>, ErrorContext>;
1394 fn next(&mut self) -> Option<Self::Item> {
1395 if self.buf.len() == self.pos {
1396 return None;
1397 }
1398 let pos = self.pos;
1399 let mut r#type = None;
1400 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
1401 r#type = Some(header.r#type);
1402 let res = match header.r#type {
1403 1u16 => Metrics::Lock({
1404 let res = parse_u32(next);
1405 let Some(val) = res else { break };
1406 val
1407 }),
1408 2u16 => Metrics::Mtu({
1409 let res = parse_u32(next);
1410 let Some(val) = res else { break };
1411 val
1412 }),
1413 3u16 => Metrics::Window({
1414 let res = parse_u32(next);
1415 let Some(val) = res else { break };
1416 val
1417 }),
1418 4u16 => Metrics::Rtt({
1419 let res = parse_u32(next);
1420 let Some(val) = res else { break };
1421 val
1422 }),
1423 5u16 => Metrics::Rttvar({
1424 let res = parse_u32(next);
1425 let Some(val) = res else { break };
1426 val
1427 }),
1428 6u16 => Metrics::Ssthresh({
1429 let res = parse_u32(next);
1430 let Some(val) = res else { break };
1431 val
1432 }),
1433 7u16 => Metrics::Cwnd({
1434 let res = parse_u32(next);
1435 let Some(val) = res else { break };
1436 val
1437 }),
1438 8u16 => Metrics::Advmss({
1439 let res = parse_u32(next);
1440 let Some(val) = res else { break };
1441 val
1442 }),
1443 9u16 => Metrics::Reordering({
1444 let res = parse_u32(next);
1445 let Some(val) = res else { break };
1446 val
1447 }),
1448 10u16 => Metrics::Hoplimit({
1449 let res = parse_u32(next);
1450 let Some(val) = res else { break };
1451 val
1452 }),
1453 11u16 => Metrics::Initcwnd({
1454 let res = parse_u32(next);
1455 let Some(val) = res else { break };
1456 val
1457 }),
1458 12u16 => Metrics::Features({
1459 let res = parse_u32(next);
1460 let Some(val) = res else { break };
1461 val
1462 }),
1463 13u16 => Metrics::RtoMin({
1464 let res = parse_u32(next);
1465 let Some(val) = res else { break };
1466 val
1467 }),
1468 14u16 => Metrics::Initrwnd({
1469 let res = parse_u32(next);
1470 let Some(val) = res else { break };
1471 val
1472 }),
1473 15u16 => Metrics::Quickack({
1474 let res = parse_u32(next);
1475 let Some(val) = res else { break };
1476 val
1477 }),
1478 16u16 => Metrics::CcAlgo({
1479 let res = CStr::from_bytes_with_nul(next).ok();
1480 let Some(val) = res else { break };
1481 val
1482 }),
1483 17u16 => Metrics::FastopenNoCookie({
1484 let res = parse_u32(next);
1485 let Some(val) = res else { break };
1486 val
1487 }),
1488 n => {
1489 if cfg!(any(test, feature = "deny-unknown-attrs")) {
1490 break;
1491 } else {
1492 continue;
1493 }
1494 }
1495 };
1496 return Some(Ok(res));
1497 }
1498 Some(Err(ErrorContext::new(
1499 "Metrics",
1500 r#type.and_then(|t| Metrics::attr_from_type(t)),
1501 self.orig_loc,
1502 self.buf.as_ptr().wrapping_add(pos) as usize,
1503 )))
1504 }
1505}
1506impl<'a> std::fmt::Debug for IterableMetrics<'_> {
1507 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1508 let mut fmt = f.debug_struct("Metrics");
1509 for attr in self.clone() {
1510 let attr = match attr {
1511 Ok(a) => a,
1512 Err(err) => {
1513 fmt.finish()?;
1514 f.write_str("Err(")?;
1515 err.fmt(f)?;
1516 return f.write_str(")");
1517 }
1518 };
1519 match attr {
1520 Metrics::Lock(val) => fmt.field("Lock", &val),
1521 Metrics::Mtu(val) => fmt.field("Mtu", &val),
1522 Metrics::Window(val) => fmt.field("Window", &val),
1523 Metrics::Rtt(val) => fmt.field("Rtt", &val),
1524 Metrics::Rttvar(val) => fmt.field("Rttvar", &val),
1525 Metrics::Ssthresh(val) => fmt.field("Ssthresh", &val),
1526 Metrics::Cwnd(val) => fmt.field("Cwnd", &val),
1527 Metrics::Advmss(val) => fmt.field("Advmss", &val),
1528 Metrics::Reordering(val) => fmt.field("Reordering", &val),
1529 Metrics::Hoplimit(val) => fmt.field("Hoplimit", &val),
1530 Metrics::Initcwnd(val) => fmt.field("Initcwnd", &val),
1531 Metrics::Features(val) => fmt.field("Features", &val),
1532 Metrics::RtoMin(val) => fmt.field("RtoMin", &val),
1533 Metrics::Initrwnd(val) => fmt.field("Initrwnd", &val),
1534 Metrics::Quickack(val) => fmt.field("Quickack", &val),
1535 Metrics::CcAlgo(val) => fmt.field("CcAlgo", &val),
1536 Metrics::FastopenNoCookie(val) => fmt.field("FastopenNoCookie", &val),
1537 };
1538 }
1539 fmt.finish()
1540 }
1541}
1542impl IterableMetrics<'_> {
1543 pub fn lookup_attr(
1544 &self,
1545 offset: usize,
1546 missing_type: Option<u16>,
1547 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1548 let mut stack = Vec::new();
1549 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1550 if cur == offset {
1551 stack.push(("Metrics", offset));
1552 return (stack, missing_type.and_then(|t| Metrics::attr_from_type(t)));
1553 }
1554 if cur > offset || cur + self.buf.len() < offset {
1555 return (stack, None);
1556 }
1557 let mut attrs = self.clone();
1558 let mut last_off = cur + attrs.pos;
1559 while let Some(attr) = attrs.next() {
1560 let Ok(attr) = attr else { break };
1561 match attr {
1562 Metrics::Lock(val) => {
1563 if last_off == offset {
1564 stack.push(("Lock", last_off));
1565 break;
1566 }
1567 }
1568 Metrics::Mtu(val) => {
1569 if last_off == offset {
1570 stack.push(("Mtu", last_off));
1571 break;
1572 }
1573 }
1574 Metrics::Window(val) => {
1575 if last_off == offset {
1576 stack.push(("Window", last_off));
1577 break;
1578 }
1579 }
1580 Metrics::Rtt(val) => {
1581 if last_off == offset {
1582 stack.push(("Rtt", last_off));
1583 break;
1584 }
1585 }
1586 Metrics::Rttvar(val) => {
1587 if last_off == offset {
1588 stack.push(("Rttvar", last_off));
1589 break;
1590 }
1591 }
1592 Metrics::Ssthresh(val) => {
1593 if last_off == offset {
1594 stack.push(("Ssthresh", last_off));
1595 break;
1596 }
1597 }
1598 Metrics::Cwnd(val) => {
1599 if last_off == offset {
1600 stack.push(("Cwnd", last_off));
1601 break;
1602 }
1603 }
1604 Metrics::Advmss(val) => {
1605 if last_off == offset {
1606 stack.push(("Advmss", last_off));
1607 break;
1608 }
1609 }
1610 Metrics::Reordering(val) => {
1611 if last_off == offset {
1612 stack.push(("Reordering", last_off));
1613 break;
1614 }
1615 }
1616 Metrics::Hoplimit(val) => {
1617 if last_off == offset {
1618 stack.push(("Hoplimit", last_off));
1619 break;
1620 }
1621 }
1622 Metrics::Initcwnd(val) => {
1623 if last_off == offset {
1624 stack.push(("Initcwnd", last_off));
1625 break;
1626 }
1627 }
1628 Metrics::Features(val) => {
1629 if last_off == offset {
1630 stack.push(("Features", last_off));
1631 break;
1632 }
1633 }
1634 Metrics::RtoMin(val) => {
1635 if last_off == offset {
1636 stack.push(("RtoMin", last_off));
1637 break;
1638 }
1639 }
1640 Metrics::Initrwnd(val) => {
1641 if last_off == offset {
1642 stack.push(("Initrwnd", last_off));
1643 break;
1644 }
1645 }
1646 Metrics::Quickack(val) => {
1647 if last_off == offset {
1648 stack.push(("Quickack", last_off));
1649 break;
1650 }
1651 }
1652 Metrics::CcAlgo(val) => {
1653 if last_off == offset {
1654 stack.push(("CcAlgo", last_off));
1655 break;
1656 }
1657 }
1658 Metrics::FastopenNoCookie(val) => {
1659 if last_off == offset {
1660 stack.push(("FastopenNoCookie", last_off));
1661 break;
1662 }
1663 }
1664 _ => {}
1665 };
1666 last_off = cur + attrs.pos;
1667 }
1668 if !stack.is_empty() {
1669 stack.push(("Metrics", cur));
1670 }
1671 (stack, None)
1672 }
1673}
1674pub struct PushRouteAttrs<Prev: Rec> {
1675 pub(crate) prev: Option<Prev>,
1676 pub(crate) header_offset: Option<usize>,
1677}
1678impl<Prev: Rec> Rec for PushRouteAttrs<Prev> {
1679 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1680 self.prev.as_mut().unwrap().as_rec_mut()
1681 }
1682}
1683impl<Prev: Rec> PushRouteAttrs<Prev> {
1684 pub fn new(prev: Prev) -> Self {
1685 Self {
1686 prev: Some(prev),
1687 header_offset: None,
1688 }
1689 }
1690 pub fn end_nested(mut self) -> Prev {
1691 let mut prev = self.prev.take().unwrap();
1692 if let Some(header_offset) = &self.header_offset {
1693 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1694 }
1695 prev
1696 }
1697 pub fn push_dst(mut self, value: &[u8]) -> Self {
1698 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
1699 self.as_rec_mut().extend(value);
1700 self
1701 }
1702 pub fn push_src(mut self, value: &[u8]) -> Self {
1703 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
1704 self.as_rec_mut().extend(value);
1705 self
1706 }
1707 pub fn push_iif(mut self, value: u32) -> Self {
1708 push_header(self.as_rec_mut(), 3u16, 4 as u16);
1709 self.as_rec_mut().extend(value.to_ne_bytes());
1710 self
1711 }
1712 pub fn push_oif(mut self, value: u32) -> Self {
1713 push_header(self.as_rec_mut(), 4u16, 4 as u16);
1714 self.as_rec_mut().extend(value.to_ne_bytes());
1715 self
1716 }
1717 pub fn push_gateway(mut self, value: &[u8]) -> Self {
1718 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
1719 self.as_rec_mut().extend(value);
1720 self
1721 }
1722 pub fn push_priority(mut self, value: u32) -> Self {
1723 push_header(self.as_rec_mut(), 6u16, 4 as u16);
1724 self.as_rec_mut().extend(value.to_ne_bytes());
1725 self
1726 }
1727 pub fn push_prefsrc(mut self, value: &[u8]) -> Self {
1728 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
1729 self.as_rec_mut().extend(value);
1730 self
1731 }
1732 pub fn nested_metrics(mut self) -> PushMetrics<Self> {
1733 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
1734 PushMetrics {
1735 prev: Some(self),
1736 header_offset: Some(header_offset),
1737 }
1738 }
1739 pub fn push_multipath(mut self, value: &[u8]) -> Self {
1740 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
1741 self.as_rec_mut().extend(value);
1742 self
1743 }
1744 pub fn push_protoinfo(mut self, value: &[u8]) -> Self {
1745 push_header(self.as_rec_mut(), 10u16, value.len() as u16);
1746 self.as_rec_mut().extend(value);
1747 self
1748 }
1749 pub fn push_flow(mut self, value: u32) -> Self {
1750 push_header(self.as_rec_mut(), 11u16, 4 as u16);
1751 self.as_rec_mut().extend(value.to_ne_bytes());
1752 self
1753 }
1754 pub fn push_cacheinfo(mut self, value: PushRtaCacheinfo) -> Self {
1755 push_header(self.as_rec_mut(), 12u16, value.as_slice().len() as u16);
1756 self.as_rec_mut().extend(value.as_slice());
1757 self
1758 }
1759 pub fn push_session(mut self, value: &[u8]) -> Self {
1760 push_header(self.as_rec_mut(), 13u16, value.len() as u16);
1761 self.as_rec_mut().extend(value);
1762 self
1763 }
1764 pub fn push_mp_algo(mut self, value: &[u8]) -> Self {
1765 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
1766 self.as_rec_mut().extend(value);
1767 self
1768 }
1769 pub fn push_table(mut self, value: u32) -> Self {
1770 push_header(self.as_rec_mut(), 15u16, 4 as u16);
1771 self.as_rec_mut().extend(value.to_ne_bytes());
1772 self
1773 }
1774 pub fn push_mark(mut self, value: u32) -> Self {
1775 push_header(self.as_rec_mut(), 16u16, 4 as u16);
1776 self.as_rec_mut().extend(value.to_ne_bytes());
1777 self
1778 }
1779 pub fn push_mfc_stats(mut self, value: &[u8]) -> Self {
1780 push_header(self.as_rec_mut(), 17u16, value.len() as u16);
1781 self.as_rec_mut().extend(value);
1782 self
1783 }
1784 pub fn push_via(mut self, value: &[u8]) -> Self {
1785 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
1786 self.as_rec_mut().extend(value);
1787 self
1788 }
1789 pub fn push_newdst(mut self, value: &[u8]) -> Self {
1790 push_header(self.as_rec_mut(), 19u16, value.len() as u16);
1791 self.as_rec_mut().extend(value);
1792 self
1793 }
1794 pub fn push_pref(mut self, value: u8) -> Self {
1795 push_header(self.as_rec_mut(), 20u16, 1 as u16);
1796 self.as_rec_mut().extend(value.to_ne_bytes());
1797 self
1798 }
1799 pub fn push_encap_type(mut self, value: u16) -> Self {
1800 push_header(self.as_rec_mut(), 21u16, 2 as u16);
1801 self.as_rec_mut().extend(value.to_ne_bytes());
1802 self
1803 }
1804 pub fn push_encap(mut self, value: &[u8]) -> Self {
1805 push_header(self.as_rec_mut(), 22u16, value.len() as u16);
1806 self.as_rec_mut().extend(value);
1807 self
1808 }
1809 pub fn push_expires(mut self, value: u32) -> Self {
1810 push_header(self.as_rec_mut(), 23u16, 4 as u16);
1811 self.as_rec_mut().extend(value.to_ne_bytes());
1812 self
1813 }
1814 pub fn push_pad(mut self, value: &[u8]) -> Self {
1815 push_header(self.as_rec_mut(), 24u16, value.len() as u16);
1816 self.as_rec_mut().extend(value);
1817 self
1818 }
1819 pub fn push_uid(mut self, value: u32) -> Self {
1820 push_header(self.as_rec_mut(), 25u16, 4 as u16);
1821 self.as_rec_mut().extend(value.to_ne_bytes());
1822 self
1823 }
1824 pub fn push_ttl_propagate(mut self, value: u8) -> Self {
1825 push_header(self.as_rec_mut(), 26u16, 1 as u16);
1826 self.as_rec_mut().extend(value.to_ne_bytes());
1827 self
1828 }
1829 pub fn push_ip_proto(mut self, value: u8) -> Self {
1830 push_header(self.as_rec_mut(), 27u16, 1 as u16);
1831 self.as_rec_mut().extend(value.to_ne_bytes());
1832 self
1833 }
1834 pub fn push_sport(mut self, value: u16) -> Self {
1835 push_header(self.as_rec_mut(), 28u16, 2 as u16);
1836 self.as_rec_mut().extend(value.to_ne_bytes());
1837 self
1838 }
1839 pub fn push_dport(mut self, value: u16) -> Self {
1840 push_header(self.as_rec_mut(), 29u16, 2 as u16);
1841 self.as_rec_mut().extend(value.to_ne_bytes());
1842 self
1843 }
1844 pub fn push_nh_id(mut self, value: u32) -> Self {
1845 push_header(self.as_rec_mut(), 30u16, 4 as u16);
1846 self.as_rec_mut().extend(value.to_ne_bytes());
1847 self
1848 }
1849 pub fn push_flowlabel(mut self, value: u32) -> Self {
1850 push_header(self.as_rec_mut(), 31u16, 4 as u16);
1851 self.as_rec_mut().extend(value.to_be_bytes());
1852 self
1853 }
1854}
1855impl<Prev: Rec> Drop for PushRouteAttrs<Prev> {
1856 fn drop(&mut self) {
1857 if let Some(prev) = &mut self.prev {
1858 if let Some(header_offset) = &self.header_offset {
1859 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1860 }
1861 }
1862 }
1863}
1864pub struct PushMetrics<Prev: Rec> {
1865 pub(crate) prev: Option<Prev>,
1866 pub(crate) header_offset: Option<usize>,
1867}
1868impl<Prev: Rec> Rec for PushMetrics<Prev> {
1869 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1870 self.prev.as_mut().unwrap().as_rec_mut()
1871 }
1872}
1873impl<Prev: Rec> PushMetrics<Prev> {
1874 pub fn new(prev: Prev) -> Self {
1875 Self {
1876 prev: Some(prev),
1877 header_offset: None,
1878 }
1879 }
1880 pub fn end_nested(mut self) -> Prev {
1881 let mut prev = self.prev.take().unwrap();
1882 if let Some(header_offset) = &self.header_offset {
1883 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1884 }
1885 prev
1886 }
1887 pub fn push_lock(mut self, value: u32) -> Self {
1888 push_header(self.as_rec_mut(), 1u16, 4 as u16);
1889 self.as_rec_mut().extend(value.to_ne_bytes());
1890 self
1891 }
1892 pub fn push_mtu(mut self, value: u32) -> Self {
1893 push_header(self.as_rec_mut(), 2u16, 4 as u16);
1894 self.as_rec_mut().extend(value.to_ne_bytes());
1895 self
1896 }
1897 pub fn push_window(mut self, value: u32) -> Self {
1898 push_header(self.as_rec_mut(), 3u16, 4 as u16);
1899 self.as_rec_mut().extend(value.to_ne_bytes());
1900 self
1901 }
1902 pub fn push_rtt(mut self, value: u32) -> Self {
1903 push_header(self.as_rec_mut(), 4u16, 4 as u16);
1904 self.as_rec_mut().extend(value.to_ne_bytes());
1905 self
1906 }
1907 pub fn push_rttvar(mut self, value: u32) -> Self {
1908 push_header(self.as_rec_mut(), 5u16, 4 as u16);
1909 self.as_rec_mut().extend(value.to_ne_bytes());
1910 self
1911 }
1912 pub fn push_ssthresh(mut self, value: u32) -> Self {
1913 push_header(self.as_rec_mut(), 6u16, 4 as u16);
1914 self.as_rec_mut().extend(value.to_ne_bytes());
1915 self
1916 }
1917 pub fn push_cwnd(mut self, value: u32) -> Self {
1918 push_header(self.as_rec_mut(), 7u16, 4 as u16);
1919 self.as_rec_mut().extend(value.to_ne_bytes());
1920 self
1921 }
1922 pub fn push_advmss(mut self, value: u32) -> Self {
1923 push_header(self.as_rec_mut(), 8u16, 4 as u16);
1924 self.as_rec_mut().extend(value.to_ne_bytes());
1925 self
1926 }
1927 pub fn push_reordering(mut self, value: u32) -> Self {
1928 push_header(self.as_rec_mut(), 9u16, 4 as u16);
1929 self.as_rec_mut().extend(value.to_ne_bytes());
1930 self
1931 }
1932 pub fn push_hoplimit(mut self, value: u32) -> Self {
1933 push_header(self.as_rec_mut(), 10u16, 4 as u16);
1934 self.as_rec_mut().extend(value.to_ne_bytes());
1935 self
1936 }
1937 pub fn push_initcwnd(mut self, value: u32) -> Self {
1938 push_header(self.as_rec_mut(), 11u16, 4 as u16);
1939 self.as_rec_mut().extend(value.to_ne_bytes());
1940 self
1941 }
1942 pub fn push_features(mut self, value: u32) -> Self {
1943 push_header(self.as_rec_mut(), 12u16, 4 as u16);
1944 self.as_rec_mut().extend(value.to_ne_bytes());
1945 self
1946 }
1947 pub fn push_rto_min(mut self, value: u32) -> Self {
1948 push_header(self.as_rec_mut(), 13u16, 4 as u16);
1949 self.as_rec_mut().extend(value.to_ne_bytes());
1950 self
1951 }
1952 pub fn push_initrwnd(mut self, value: u32) -> Self {
1953 push_header(self.as_rec_mut(), 14u16, 4 as u16);
1954 self.as_rec_mut().extend(value.to_ne_bytes());
1955 self
1956 }
1957 pub fn push_quickack(mut self, value: u32) -> Self {
1958 push_header(self.as_rec_mut(), 15u16, 4 as u16);
1959 self.as_rec_mut().extend(value.to_ne_bytes());
1960 self
1961 }
1962 pub fn push_cc_algo(mut self, value: &CStr) -> Self {
1963 push_header(
1964 self.as_rec_mut(),
1965 16u16,
1966 value.to_bytes_with_nul().len() as u16,
1967 );
1968 self.as_rec_mut().extend(value.to_bytes_with_nul());
1969 self
1970 }
1971 pub fn push_cc_algo_bytes(mut self, value: &[u8]) -> Self {
1972 push_header(self.as_rec_mut(), 16u16, (value.len() + 1) as u16);
1973 self.as_rec_mut().extend(value);
1974 self.as_rec_mut().push(0);
1975 self
1976 }
1977 pub fn push_fastopen_no_cookie(mut self, value: u32) -> Self {
1978 push_header(self.as_rec_mut(), 17u16, 4 as u16);
1979 self.as_rec_mut().extend(value.to_ne_bytes());
1980 self
1981 }
1982}
1983impl<Prev: Rec> Drop for PushMetrics<Prev> {
1984 fn drop(&mut self) {
1985 if let Some(prev) = &mut self.prev {
1986 if let Some(header_offset) = &self.header_offset {
1987 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1988 }
1989 }
1990 }
1991}
1992#[derive(Clone)]
1993pub struct PushRtmsg {
1994 pub(crate) buf: [u8; 12usize],
1995}
1996#[doc = "Create zero-initialized struct"]
1997impl Default for PushRtmsg {
1998 fn default() -> Self {
1999 Self {
2000 buf: [0u8; 12usize],
2001 }
2002 }
2003}
2004impl PushRtmsg {
2005 #[doc = "Create zero-initialized struct"]
2006 pub fn new() -> Self {
2007 Default::default()
2008 }
2009 #[doc = "Copy from contents from other slice"]
2010 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2011 if other.len() != Self::len() {
2012 return None;
2013 }
2014 let mut buf = [0u8; Self::len()];
2015 buf.clone_from_slice(other);
2016 Some(Self { buf })
2017 }
2018 pub fn as_slice(&self) -> &[u8] {
2019 &self.buf
2020 }
2021 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2022 &mut self.buf
2023 }
2024 pub const fn len() -> usize {
2025 12usize
2026 }
2027 pub fn rtm_family(&self) -> u8 {
2028 parse_u8(&self.buf[0usize..1usize]).unwrap()
2029 }
2030 pub fn set_rtm_family(&mut self, value: u8) {
2031 self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
2032 }
2033 pub fn rtm_dst_len(&self) -> u8 {
2034 parse_u8(&self.buf[1usize..2usize]).unwrap()
2035 }
2036 pub fn set_rtm_dst_len(&mut self, value: u8) {
2037 self.buf[1usize..2usize].copy_from_slice(&value.to_ne_bytes())
2038 }
2039 pub fn rtm_src_len(&self) -> u8 {
2040 parse_u8(&self.buf[2usize..3usize]).unwrap()
2041 }
2042 pub fn set_rtm_src_len(&mut self, value: u8) {
2043 self.buf[2usize..3usize].copy_from_slice(&value.to_ne_bytes())
2044 }
2045 pub fn rtm_tos(&self) -> u8 {
2046 parse_u8(&self.buf[3usize..4usize]).unwrap()
2047 }
2048 pub fn set_rtm_tos(&mut self, value: u8) {
2049 self.buf[3usize..4usize].copy_from_slice(&value.to_ne_bytes())
2050 }
2051 pub fn rtm_table(&self) -> u8 {
2052 parse_u8(&self.buf[4usize..5usize]).unwrap()
2053 }
2054 pub fn set_rtm_table(&mut self, value: u8) {
2055 self.buf[4usize..5usize].copy_from_slice(&value.to_ne_bytes())
2056 }
2057 pub fn rtm_protocol(&self) -> u8 {
2058 parse_u8(&self.buf[5usize..6usize]).unwrap()
2059 }
2060 pub fn set_rtm_protocol(&mut self, value: u8) {
2061 self.buf[5usize..6usize].copy_from_slice(&value.to_ne_bytes())
2062 }
2063 pub fn rtm_scope(&self) -> u8 {
2064 parse_u8(&self.buf[6usize..7usize]).unwrap()
2065 }
2066 pub fn set_rtm_scope(&mut self, value: u8) {
2067 self.buf[6usize..7usize].copy_from_slice(&value.to_ne_bytes())
2068 }
2069 #[doc = "Associated type: \"RtmType\" (enum)"]
2070 pub fn rtm_type(&self) -> u8 {
2071 parse_u8(&self.buf[7usize..8usize]).unwrap()
2072 }
2073 #[doc = "Associated type: \"RtmType\" (enum)"]
2074 pub fn set_rtm_type(&mut self, value: u8) {
2075 self.buf[7usize..8usize].copy_from_slice(&value.to_ne_bytes())
2076 }
2077 pub fn rtm_flags(&self) -> u32 {
2078 parse_u32(&self.buf[8usize..12usize]).unwrap()
2079 }
2080 pub fn set_rtm_flags(&mut self, value: u32) {
2081 self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
2082 }
2083}
2084impl std::fmt::Debug for PushRtmsg {
2085 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2086 fmt.debug_struct("Rtmsg")
2087 .field("rtm_family", &self.rtm_family())
2088 .field("rtm_dst_len", &self.rtm_dst_len())
2089 .field("rtm_src_len", &self.rtm_src_len())
2090 .field("rtm_tos", &self.rtm_tos())
2091 .field("rtm_table", &self.rtm_table())
2092 .field("rtm_protocol", &self.rtm_protocol())
2093 .field("rtm_scope", &self.rtm_scope())
2094 .field("rtm_type", &self.rtm_type())
2095 .field("rtm_flags", &self.rtm_flags())
2096 .finish()
2097 }
2098}
2099#[derive(Clone)]
2100pub struct PushRtaCacheinfo {
2101 pub(crate) buf: [u8; 20usize],
2102}
2103#[doc = "Create zero-initialized struct"]
2104impl Default for PushRtaCacheinfo {
2105 fn default() -> Self {
2106 Self {
2107 buf: [0u8; 20usize],
2108 }
2109 }
2110}
2111impl PushRtaCacheinfo {
2112 #[doc = "Create zero-initialized struct"]
2113 pub fn new() -> Self {
2114 Default::default()
2115 }
2116 #[doc = "Copy from contents from other slice"]
2117 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2118 if other.len() != Self::len() {
2119 return None;
2120 }
2121 let mut buf = [0u8; Self::len()];
2122 buf.clone_from_slice(other);
2123 Some(Self { buf })
2124 }
2125 pub fn as_slice(&self) -> &[u8] {
2126 &self.buf
2127 }
2128 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2129 &mut self.buf
2130 }
2131 pub const fn len() -> usize {
2132 20usize
2133 }
2134 pub fn rta_clntref(&self) -> u32 {
2135 parse_u32(&self.buf[0usize..4usize]).unwrap()
2136 }
2137 pub fn set_rta_clntref(&mut self, value: u32) {
2138 self.buf[0usize..4usize].copy_from_slice(&value.to_ne_bytes())
2139 }
2140 pub fn rta_lastuse(&self) -> u32 {
2141 parse_u32(&self.buf[4usize..8usize]).unwrap()
2142 }
2143 pub fn set_rta_lastuse(&mut self, value: u32) {
2144 self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2145 }
2146 pub fn rta_expires(&self) -> u32 {
2147 parse_u32(&self.buf[8usize..12usize]).unwrap()
2148 }
2149 pub fn set_rta_expires(&mut self, value: u32) {
2150 self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
2151 }
2152 pub fn rta_error(&self) -> u32 {
2153 parse_u32(&self.buf[12usize..16usize]).unwrap()
2154 }
2155 pub fn set_rta_error(&mut self, value: u32) {
2156 self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
2157 }
2158 pub fn rta_used(&self) -> u32 {
2159 parse_u32(&self.buf[16usize..20usize]).unwrap()
2160 }
2161 pub fn set_rta_used(&mut self, value: u32) {
2162 self.buf[16usize..20usize].copy_from_slice(&value.to_ne_bytes())
2163 }
2164}
2165impl std::fmt::Debug for PushRtaCacheinfo {
2166 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2167 fmt.debug_struct("RtaCacheinfo")
2168 .field("rta_clntref", &self.rta_clntref())
2169 .field("rta_lastuse", &self.rta_lastuse())
2170 .field("rta_expires", &self.rta_expires())
2171 .field("rta_error", &self.rta_error())
2172 .field("rta_used", &self.rta_used())
2173 .finish()
2174 }
2175}
2176#[doc = "Dump route information."]
2177pub struct PushOpGetrouteDumpRequest<Prev: Rec> {
2178 pub(crate) prev: Option<Prev>,
2179 pub(crate) header_offset: Option<usize>,
2180}
2181impl<Prev: Rec> Rec for PushOpGetrouteDumpRequest<Prev> {
2182 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2183 self.prev.as_mut().unwrap().as_rec_mut()
2184 }
2185}
2186impl<Prev: Rec> PushOpGetrouteDumpRequest<Prev> {
2187 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
2188 Self::write_header(&mut prev, header);
2189 Self::new_without_header(prev)
2190 }
2191 fn new_without_header(prev: Prev) -> Self {
2192 Self {
2193 prev: Some(prev),
2194 header_offset: None,
2195 }
2196 }
2197 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
2198 prev.as_rec_mut().extend(header.as_slice());
2199 }
2200 pub fn end_nested(mut self) -> Prev {
2201 let mut prev = self.prev.take().unwrap();
2202 if let Some(header_offset) = &self.header_offset {
2203 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2204 }
2205 prev
2206 }
2207}
2208impl<Prev: Rec> Drop for PushOpGetrouteDumpRequest<Prev> {
2209 fn drop(&mut self) {
2210 if let Some(prev) = &mut self.prev {
2211 if let Some(header_offset) = &self.header_offset {
2212 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2213 }
2214 }
2215 }
2216}
2217#[doc = "Dump route information."]
2218#[derive(Clone)]
2219pub enum OpGetrouteDumpRequest {}
2220impl<'a> IterableOpGetrouteDumpRequest<'a> {}
2221impl OpGetrouteDumpRequest {
2222 pub fn new(buf: &'_ [u8]) -> (PushRtmsg, IterableOpGetrouteDumpRequest<'_>) {
2223 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
2224 (
2225 PushRtmsg::new_from_slice(header).unwrap_or_default(),
2226 IterableOpGetrouteDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
2227 )
2228 }
2229 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2230 RouteAttrs::attr_from_type(r#type)
2231 }
2232}
2233#[derive(Clone, Copy, Default)]
2234pub struct IterableOpGetrouteDumpRequest<'a> {
2235 buf: &'a [u8],
2236 pos: usize,
2237 orig_loc: usize,
2238}
2239impl<'a> IterableOpGetrouteDumpRequest<'a> {
2240 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2241 Self {
2242 buf,
2243 pos: 0,
2244 orig_loc,
2245 }
2246 }
2247 pub fn get_buf(&self) -> &'a [u8] {
2248 self.buf
2249 }
2250}
2251impl<'a> Iterator for IterableOpGetrouteDumpRequest<'a> {
2252 type Item = Result<OpGetrouteDumpRequest, ErrorContext>;
2253 fn next(&mut self) -> Option<Self::Item> {
2254 if self.buf.len() == self.pos {
2255 return None;
2256 }
2257 let pos = self.pos;
2258 let mut r#type = None;
2259 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
2260 r#type = Some(header.r#type);
2261 let res = match header.r#type {
2262 n => {
2263 if cfg!(any(test, feature = "deny-unknown-attrs")) {
2264 break;
2265 } else {
2266 continue;
2267 }
2268 }
2269 };
2270 return Some(Ok(res));
2271 }
2272 Some(Err(ErrorContext::new(
2273 "OpGetrouteDumpRequest",
2274 r#type.and_then(|t| OpGetrouteDumpRequest::attr_from_type(t)),
2275 self.orig_loc,
2276 self.buf.as_ptr().wrapping_add(pos) as usize,
2277 )))
2278 }
2279}
2280impl std::fmt::Debug for IterableOpGetrouteDumpRequest<'_> {
2281 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2282 let mut fmt = f.debug_struct("OpGetrouteDumpRequest");
2283 for attr in self.clone() {
2284 let attr = match attr {
2285 Ok(a) => a,
2286 Err(err) => {
2287 fmt.finish()?;
2288 f.write_str("Err(")?;
2289 err.fmt(f)?;
2290 return f.write_str(")");
2291 }
2292 };
2293 match attr {};
2294 }
2295 fmt.finish()
2296 }
2297}
2298impl IterableOpGetrouteDumpRequest<'_> {
2299 pub fn lookup_attr(
2300 &self,
2301 offset: usize,
2302 missing_type: Option<u16>,
2303 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2304 let mut stack = Vec::new();
2305 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2306 if cur == offset + PushRtmsg::len() {
2307 stack.push(("OpGetrouteDumpRequest", offset));
2308 return (
2309 stack,
2310 missing_type.and_then(|t| OpGetrouteDumpRequest::attr_from_type(t)),
2311 );
2312 }
2313 (stack, None)
2314 }
2315}
2316#[doc = "Dump route information."]
2317pub struct PushOpGetrouteDumpReply<Prev: Rec> {
2318 pub(crate) prev: Option<Prev>,
2319 pub(crate) header_offset: Option<usize>,
2320}
2321impl<Prev: Rec> Rec for PushOpGetrouteDumpReply<Prev> {
2322 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2323 self.prev.as_mut().unwrap().as_rec_mut()
2324 }
2325}
2326impl<Prev: Rec> PushOpGetrouteDumpReply<Prev> {
2327 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
2328 Self::write_header(&mut prev, header);
2329 Self::new_without_header(prev)
2330 }
2331 fn new_without_header(prev: Prev) -> Self {
2332 Self {
2333 prev: Some(prev),
2334 header_offset: None,
2335 }
2336 }
2337 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
2338 prev.as_rec_mut().extend(header.as_slice());
2339 }
2340 pub fn end_nested(mut self) -> Prev {
2341 let mut prev = self.prev.take().unwrap();
2342 if let Some(header_offset) = &self.header_offset {
2343 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2344 }
2345 prev
2346 }
2347 pub fn push_dst(mut self, value: &[u8]) -> Self {
2348 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
2349 self.as_rec_mut().extend(value);
2350 self
2351 }
2352 pub fn push_src(mut self, value: &[u8]) -> Self {
2353 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
2354 self.as_rec_mut().extend(value);
2355 self
2356 }
2357 pub fn push_iif(mut self, value: u32) -> Self {
2358 push_header(self.as_rec_mut(), 3u16, 4 as u16);
2359 self.as_rec_mut().extend(value.to_ne_bytes());
2360 self
2361 }
2362 pub fn push_oif(mut self, value: u32) -> Self {
2363 push_header(self.as_rec_mut(), 4u16, 4 as u16);
2364 self.as_rec_mut().extend(value.to_ne_bytes());
2365 self
2366 }
2367 pub fn push_gateway(mut self, value: &[u8]) -> Self {
2368 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
2369 self.as_rec_mut().extend(value);
2370 self
2371 }
2372 pub fn push_priority(mut self, value: u32) -> Self {
2373 push_header(self.as_rec_mut(), 6u16, 4 as u16);
2374 self.as_rec_mut().extend(value.to_ne_bytes());
2375 self
2376 }
2377 pub fn push_prefsrc(mut self, value: &[u8]) -> Self {
2378 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
2379 self.as_rec_mut().extend(value);
2380 self
2381 }
2382 pub fn nested_metrics(mut self) -> PushMetrics<Self> {
2383 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
2384 PushMetrics {
2385 prev: Some(self),
2386 header_offset: Some(header_offset),
2387 }
2388 }
2389 pub fn push_multipath(mut self, value: &[u8]) -> Self {
2390 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
2391 self.as_rec_mut().extend(value);
2392 self
2393 }
2394 pub fn push_flow(mut self, value: u32) -> Self {
2395 push_header(self.as_rec_mut(), 11u16, 4 as u16);
2396 self.as_rec_mut().extend(value.to_ne_bytes());
2397 self
2398 }
2399 pub fn push_cacheinfo(mut self, value: PushRtaCacheinfo) -> Self {
2400 push_header(self.as_rec_mut(), 12u16, value.as_slice().len() as u16);
2401 self.as_rec_mut().extend(value.as_slice());
2402 self
2403 }
2404 pub fn push_table(mut self, value: u32) -> Self {
2405 push_header(self.as_rec_mut(), 15u16, 4 as u16);
2406 self.as_rec_mut().extend(value.to_ne_bytes());
2407 self
2408 }
2409 pub fn push_mark(mut self, value: u32) -> Self {
2410 push_header(self.as_rec_mut(), 16u16, 4 as u16);
2411 self.as_rec_mut().extend(value.to_ne_bytes());
2412 self
2413 }
2414 pub fn push_mfc_stats(mut self, value: &[u8]) -> Self {
2415 push_header(self.as_rec_mut(), 17u16, value.len() as u16);
2416 self.as_rec_mut().extend(value);
2417 self
2418 }
2419 pub fn push_via(mut self, value: &[u8]) -> Self {
2420 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
2421 self.as_rec_mut().extend(value);
2422 self
2423 }
2424 pub fn push_newdst(mut self, value: &[u8]) -> Self {
2425 push_header(self.as_rec_mut(), 19u16, value.len() as u16);
2426 self.as_rec_mut().extend(value);
2427 self
2428 }
2429 pub fn push_pref(mut self, value: u8) -> Self {
2430 push_header(self.as_rec_mut(), 20u16, 1 as u16);
2431 self.as_rec_mut().extend(value.to_ne_bytes());
2432 self
2433 }
2434 pub fn push_encap_type(mut self, value: u16) -> Self {
2435 push_header(self.as_rec_mut(), 21u16, 2 as u16);
2436 self.as_rec_mut().extend(value.to_ne_bytes());
2437 self
2438 }
2439 pub fn push_encap(mut self, value: &[u8]) -> Self {
2440 push_header(self.as_rec_mut(), 22u16, value.len() as u16);
2441 self.as_rec_mut().extend(value);
2442 self
2443 }
2444 pub fn push_expires(mut self, value: u32) -> Self {
2445 push_header(self.as_rec_mut(), 23u16, 4 as u16);
2446 self.as_rec_mut().extend(value.to_ne_bytes());
2447 self
2448 }
2449 pub fn push_pad(mut self, value: &[u8]) -> Self {
2450 push_header(self.as_rec_mut(), 24u16, value.len() as u16);
2451 self.as_rec_mut().extend(value);
2452 self
2453 }
2454 pub fn push_uid(mut self, value: u32) -> Self {
2455 push_header(self.as_rec_mut(), 25u16, 4 as u16);
2456 self.as_rec_mut().extend(value.to_ne_bytes());
2457 self
2458 }
2459 pub fn push_ttl_propagate(mut self, value: u8) -> Self {
2460 push_header(self.as_rec_mut(), 26u16, 1 as u16);
2461 self.as_rec_mut().extend(value.to_ne_bytes());
2462 self
2463 }
2464 pub fn push_ip_proto(mut self, value: u8) -> Self {
2465 push_header(self.as_rec_mut(), 27u16, 1 as u16);
2466 self.as_rec_mut().extend(value.to_ne_bytes());
2467 self
2468 }
2469 pub fn push_sport(mut self, value: u16) -> Self {
2470 push_header(self.as_rec_mut(), 28u16, 2 as u16);
2471 self.as_rec_mut().extend(value.to_ne_bytes());
2472 self
2473 }
2474 pub fn push_dport(mut self, value: u16) -> Self {
2475 push_header(self.as_rec_mut(), 29u16, 2 as u16);
2476 self.as_rec_mut().extend(value.to_ne_bytes());
2477 self
2478 }
2479 pub fn push_nh_id(mut self, value: u32) -> Self {
2480 push_header(self.as_rec_mut(), 30u16, 4 as u16);
2481 self.as_rec_mut().extend(value.to_ne_bytes());
2482 self
2483 }
2484 pub fn push_flowlabel(mut self, value: u32) -> Self {
2485 push_header(self.as_rec_mut(), 31u16, 4 as u16);
2486 self.as_rec_mut().extend(value.to_be_bytes());
2487 self
2488 }
2489}
2490impl<Prev: Rec> Drop for PushOpGetrouteDumpReply<Prev> {
2491 fn drop(&mut self) {
2492 if let Some(prev) = &mut self.prev {
2493 if let Some(header_offset) = &self.header_offset {
2494 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2495 }
2496 }
2497 }
2498}
2499#[doc = "Dump route information."]
2500#[derive(Clone)]
2501pub enum OpGetrouteDumpReply<'a> {
2502 Dst(&'a [u8]),
2503 Src(&'a [u8]),
2504 Iif(u32),
2505 Oif(u32),
2506 Gateway(&'a [u8]),
2507 Priority(u32),
2508 Prefsrc(&'a [u8]),
2509 Metrics(IterableMetrics<'a>),
2510 Multipath(&'a [u8]),
2511 Flow(u32),
2512 Cacheinfo(PushRtaCacheinfo),
2513 Table(u32),
2514 Mark(u32),
2515 MfcStats(&'a [u8]),
2516 Via(&'a [u8]),
2517 Newdst(&'a [u8]),
2518 Pref(u8),
2519 EncapType(u16),
2520 Encap(&'a [u8]),
2521 Expires(u32),
2522 Pad(&'a [u8]),
2523 Uid(u32),
2524 TtlPropagate(u8),
2525 IpProto(u8),
2526 Sport(u16),
2527 Dport(u16),
2528 NhId(u32),
2529 Flowlabel(u32),
2530}
2531impl<'a> IterableOpGetrouteDumpReply<'a> {
2532 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
2533 let mut iter = self.clone();
2534 iter.pos = 0;
2535 for attr in iter {
2536 if let OpGetrouteDumpReply::Dst(val) = attr? {
2537 return Ok(val);
2538 }
2539 }
2540 Err(ErrorContext::new_missing(
2541 "OpGetrouteDumpReply",
2542 "Dst",
2543 self.orig_loc,
2544 self.buf.as_ptr() as usize,
2545 ))
2546 }
2547 pub fn get_src(&self) -> Result<&'a [u8], ErrorContext> {
2548 let mut iter = self.clone();
2549 iter.pos = 0;
2550 for attr in iter {
2551 if let OpGetrouteDumpReply::Src(val) = attr? {
2552 return Ok(val);
2553 }
2554 }
2555 Err(ErrorContext::new_missing(
2556 "OpGetrouteDumpReply",
2557 "Src",
2558 self.orig_loc,
2559 self.buf.as_ptr() as usize,
2560 ))
2561 }
2562 pub fn get_iif(&self) -> Result<u32, ErrorContext> {
2563 let mut iter = self.clone();
2564 iter.pos = 0;
2565 for attr in iter {
2566 if let OpGetrouteDumpReply::Iif(val) = attr? {
2567 return Ok(val);
2568 }
2569 }
2570 Err(ErrorContext::new_missing(
2571 "OpGetrouteDumpReply",
2572 "Iif",
2573 self.orig_loc,
2574 self.buf.as_ptr() as usize,
2575 ))
2576 }
2577 pub fn get_oif(&self) -> Result<u32, ErrorContext> {
2578 let mut iter = self.clone();
2579 iter.pos = 0;
2580 for attr in iter {
2581 if let OpGetrouteDumpReply::Oif(val) = attr? {
2582 return Ok(val);
2583 }
2584 }
2585 Err(ErrorContext::new_missing(
2586 "OpGetrouteDumpReply",
2587 "Oif",
2588 self.orig_loc,
2589 self.buf.as_ptr() as usize,
2590 ))
2591 }
2592 pub fn get_gateway(&self) -> Result<&'a [u8], ErrorContext> {
2593 let mut iter = self.clone();
2594 iter.pos = 0;
2595 for attr in iter {
2596 if let OpGetrouteDumpReply::Gateway(val) = attr? {
2597 return Ok(val);
2598 }
2599 }
2600 Err(ErrorContext::new_missing(
2601 "OpGetrouteDumpReply",
2602 "Gateway",
2603 self.orig_loc,
2604 self.buf.as_ptr() as usize,
2605 ))
2606 }
2607 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
2608 let mut iter = self.clone();
2609 iter.pos = 0;
2610 for attr in iter {
2611 if let OpGetrouteDumpReply::Priority(val) = attr? {
2612 return Ok(val);
2613 }
2614 }
2615 Err(ErrorContext::new_missing(
2616 "OpGetrouteDumpReply",
2617 "Priority",
2618 self.orig_loc,
2619 self.buf.as_ptr() as usize,
2620 ))
2621 }
2622 pub fn get_prefsrc(&self) -> Result<&'a [u8], ErrorContext> {
2623 let mut iter = self.clone();
2624 iter.pos = 0;
2625 for attr in iter {
2626 if let OpGetrouteDumpReply::Prefsrc(val) = attr? {
2627 return Ok(val);
2628 }
2629 }
2630 Err(ErrorContext::new_missing(
2631 "OpGetrouteDumpReply",
2632 "Prefsrc",
2633 self.orig_loc,
2634 self.buf.as_ptr() as usize,
2635 ))
2636 }
2637 pub fn get_metrics(&self) -> Result<IterableMetrics<'a>, ErrorContext> {
2638 let mut iter = self.clone();
2639 iter.pos = 0;
2640 for attr in iter {
2641 if let OpGetrouteDumpReply::Metrics(val) = attr? {
2642 return Ok(val);
2643 }
2644 }
2645 Err(ErrorContext::new_missing(
2646 "OpGetrouteDumpReply",
2647 "Metrics",
2648 self.orig_loc,
2649 self.buf.as_ptr() as usize,
2650 ))
2651 }
2652 pub fn get_multipath(&self) -> Result<&'a [u8], ErrorContext> {
2653 let mut iter = self.clone();
2654 iter.pos = 0;
2655 for attr in iter {
2656 if let OpGetrouteDumpReply::Multipath(val) = attr? {
2657 return Ok(val);
2658 }
2659 }
2660 Err(ErrorContext::new_missing(
2661 "OpGetrouteDumpReply",
2662 "Multipath",
2663 self.orig_loc,
2664 self.buf.as_ptr() as usize,
2665 ))
2666 }
2667 pub fn get_flow(&self) -> Result<u32, ErrorContext> {
2668 let mut iter = self.clone();
2669 iter.pos = 0;
2670 for attr in iter {
2671 if let OpGetrouteDumpReply::Flow(val) = attr? {
2672 return Ok(val);
2673 }
2674 }
2675 Err(ErrorContext::new_missing(
2676 "OpGetrouteDumpReply",
2677 "Flow",
2678 self.orig_loc,
2679 self.buf.as_ptr() as usize,
2680 ))
2681 }
2682 pub fn get_cacheinfo(&self) -> Result<PushRtaCacheinfo, ErrorContext> {
2683 let mut iter = self.clone();
2684 iter.pos = 0;
2685 for attr in iter {
2686 if let OpGetrouteDumpReply::Cacheinfo(val) = attr? {
2687 return Ok(val);
2688 }
2689 }
2690 Err(ErrorContext::new_missing(
2691 "OpGetrouteDumpReply",
2692 "Cacheinfo",
2693 self.orig_loc,
2694 self.buf.as_ptr() as usize,
2695 ))
2696 }
2697 pub fn get_table(&self) -> Result<u32, ErrorContext> {
2698 let mut iter = self.clone();
2699 iter.pos = 0;
2700 for attr in iter {
2701 if let OpGetrouteDumpReply::Table(val) = attr? {
2702 return Ok(val);
2703 }
2704 }
2705 Err(ErrorContext::new_missing(
2706 "OpGetrouteDumpReply",
2707 "Table",
2708 self.orig_loc,
2709 self.buf.as_ptr() as usize,
2710 ))
2711 }
2712 pub fn get_mark(&self) -> Result<u32, ErrorContext> {
2713 let mut iter = self.clone();
2714 iter.pos = 0;
2715 for attr in iter {
2716 if let OpGetrouteDumpReply::Mark(val) = attr? {
2717 return Ok(val);
2718 }
2719 }
2720 Err(ErrorContext::new_missing(
2721 "OpGetrouteDumpReply",
2722 "Mark",
2723 self.orig_loc,
2724 self.buf.as_ptr() as usize,
2725 ))
2726 }
2727 pub fn get_mfc_stats(&self) -> Result<&'a [u8], ErrorContext> {
2728 let mut iter = self.clone();
2729 iter.pos = 0;
2730 for attr in iter {
2731 if let OpGetrouteDumpReply::MfcStats(val) = attr? {
2732 return Ok(val);
2733 }
2734 }
2735 Err(ErrorContext::new_missing(
2736 "OpGetrouteDumpReply",
2737 "MfcStats",
2738 self.orig_loc,
2739 self.buf.as_ptr() as usize,
2740 ))
2741 }
2742 pub fn get_via(&self) -> Result<&'a [u8], ErrorContext> {
2743 let mut iter = self.clone();
2744 iter.pos = 0;
2745 for attr in iter {
2746 if let OpGetrouteDumpReply::Via(val) = attr? {
2747 return Ok(val);
2748 }
2749 }
2750 Err(ErrorContext::new_missing(
2751 "OpGetrouteDumpReply",
2752 "Via",
2753 self.orig_loc,
2754 self.buf.as_ptr() as usize,
2755 ))
2756 }
2757 pub fn get_newdst(&self) -> Result<&'a [u8], ErrorContext> {
2758 let mut iter = self.clone();
2759 iter.pos = 0;
2760 for attr in iter {
2761 if let OpGetrouteDumpReply::Newdst(val) = attr? {
2762 return Ok(val);
2763 }
2764 }
2765 Err(ErrorContext::new_missing(
2766 "OpGetrouteDumpReply",
2767 "Newdst",
2768 self.orig_loc,
2769 self.buf.as_ptr() as usize,
2770 ))
2771 }
2772 pub fn get_pref(&self) -> Result<u8, ErrorContext> {
2773 let mut iter = self.clone();
2774 iter.pos = 0;
2775 for attr in iter {
2776 if let OpGetrouteDumpReply::Pref(val) = attr? {
2777 return Ok(val);
2778 }
2779 }
2780 Err(ErrorContext::new_missing(
2781 "OpGetrouteDumpReply",
2782 "Pref",
2783 self.orig_loc,
2784 self.buf.as_ptr() as usize,
2785 ))
2786 }
2787 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
2788 let mut iter = self.clone();
2789 iter.pos = 0;
2790 for attr in iter {
2791 if let OpGetrouteDumpReply::EncapType(val) = attr? {
2792 return Ok(val);
2793 }
2794 }
2795 Err(ErrorContext::new_missing(
2796 "OpGetrouteDumpReply",
2797 "EncapType",
2798 self.orig_loc,
2799 self.buf.as_ptr() as usize,
2800 ))
2801 }
2802 pub fn get_encap(&self) -> Result<&'a [u8], ErrorContext> {
2803 let mut iter = self.clone();
2804 iter.pos = 0;
2805 for attr in iter {
2806 if let OpGetrouteDumpReply::Encap(val) = attr? {
2807 return Ok(val);
2808 }
2809 }
2810 Err(ErrorContext::new_missing(
2811 "OpGetrouteDumpReply",
2812 "Encap",
2813 self.orig_loc,
2814 self.buf.as_ptr() as usize,
2815 ))
2816 }
2817 pub fn get_expires(&self) -> Result<u32, ErrorContext> {
2818 let mut iter = self.clone();
2819 iter.pos = 0;
2820 for attr in iter {
2821 if let OpGetrouteDumpReply::Expires(val) = attr? {
2822 return Ok(val);
2823 }
2824 }
2825 Err(ErrorContext::new_missing(
2826 "OpGetrouteDumpReply",
2827 "Expires",
2828 self.orig_loc,
2829 self.buf.as_ptr() as usize,
2830 ))
2831 }
2832 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
2833 let mut iter = self.clone();
2834 iter.pos = 0;
2835 for attr in iter {
2836 if let OpGetrouteDumpReply::Pad(val) = attr? {
2837 return Ok(val);
2838 }
2839 }
2840 Err(ErrorContext::new_missing(
2841 "OpGetrouteDumpReply",
2842 "Pad",
2843 self.orig_loc,
2844 self.buf.as_ptr() as usize,
2845 ))
2846 }
2847 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
2848 let mut iter = self.clone();
2849 iter.pos = 0;
2850 for attr in iter {
2851 if let OpGetrouteDumpReply::Uid(val) = attr? {
2852 return Ok(val);
2853 }
2854 }
2855 Err(ErrorContext::new_missing(
2856 "OpGetrouteDumpReply",
2857 "Uid",
2858 self.orig_loc,
2859 self.buf.as_ptr() as usize,
2860 ))
2861 }
2862 pub fn get_ttl_propagate(&self) -> Result<u8, ErrorContext> {
2863 let mut iter = self.clone();
2864 iter.pos = 0;
2865 for attr in iter {
2866 if let OpGetrouteDumpReply::TtlPropagate(val) = attr? {
2867 return Ok(val);
2868 }
2869 }
2870 Err(ErrorContext::new_missing(
2871 "OpGetrouteDumpReply",
2872 "TtlPropagate",
2873 self.orig_loc,
2874 self.buf.as_ptr() as usize,
2875 ))
2876 }
2877 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
2878 let mut iter = self.clone();
2879 iter.pos = 0;
2880 for attr in iter {
2881 if let OpGetrouteDumpReply::IpProto(val) = attr? {
2882 return Ok(val);
2883 }
2884 }
2885 Err(ErrorContext::new_missing(
2886 "OpGetrouteDumpReply",
2887 "IpProto",
2888 self.orig_loc,
2889 self.buf.as_ptr() as usize,
2890 ))
2891 }
2892 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
2893 let mut iter = self.clone();
2894 iter.pos = 0;
2895 for attr in iter {
2896 if let OpGetrouteDumpReply::Sport(val) = attr? {
2897 return Ok(val);
2898 }
2899 }
2900 Err(ErrorContext::new_missing(
2901 "OpGetrouteDumpReply",
2902 "Sport",
2903 self.orig_loc,
2904 self.buf.as_ptr() as usize,
2905 ))
2906 }
2907 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
2908 let mut iter = self.clone();
2909 iter.pos = 0;
2910 for attr in iter {
2911 if let OpGetrouteDumpReply::Dport(val) = attr? {
2912 return Ok(val);
2913 }
2914 }
2915 Err(ErrorContext::new_missing(
2916 "OpGetrouteDumpReply",
2917 "Dport",
2918 self.orig_loc,
2919 self.buf.as_ptr() as usize,
2920 ))
2921 }
2922 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
2923 let mut iter = self.clone();
2924 iter.pos = 0;
2925 for attr in iter {
2926 if let OpGetrouteDumpReply::NhId(val) = attr? {
2927 return Ok(val);
2928 }
2929 }
2930 Err(ErrorContext::new_missing(
2931 "OpGetrouteDumpReply",
2932 "NhId",
2933 self.orig_loc,
2934 self.buf.as_ptr() as usize,
2935 ))
2936 }
2937 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
2938 let mut iter = self.clone();
2939 iter.pos = 0;
2940 for attr in iter {
2941 if let OpGetrouteDumpReply::Flowlabel(val) = attr? {
2942 return Ok(val);
2943 }
2944 }
2945 Err(ErrorContext::new_missing(
2946 "OpGetrouteDumpReply",
2947 "Flowlabel",
2948 self.orig_loc,
2949 self.buf.as_ptr() as usize,
2950 ))
2951 }
2952}
2953impl<'a> OpGetrouteDumpReply<'a> {
2954 pub fn new(buf: &'a [u8]) -> (PushRtmsg, IterableOpGetrouteDumpReply<'a>) {
2955 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
2956 (
2957 PushRtmsg::new_from_slice(header).unwrap_or_default(),
2958 IterableOpGetrouteDumpReply::with_loc(attrs, buf.as_ptr() as usize),
2959 )
2960 }
2961 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2962 RouteAttrs::attr_from_type(r#type)
2963 }
2964}
2965#[derive(Clone, Copy, Default)]
2966pub struct IterableOpGetrouteDumpReply<'a> {
2967 buf: &'a [u8],
2968 pos: usize,
2969 orig_loc: usize,
2970}
2971impl<'a> IterableOpGetrouteDumpReply<'a> {
2972 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2973 Self {
2974 buf,
2975 pos: 0,
2976 orig_loc,
2977 }
2978 }
2979 pub fn get_buf(&self) -> &'a [u8] {
2980 self.buf
2981 }
2982}
2983impl<'a> Iterator for IterableOpGetrouteDumpReply<'a> {
2984 type Item = Result<OpGetrouteDumpReply<'a>, ErrorContext>;
2985 fn next(&mut self) -> Option<Self::Item> {
2986 if self.buf.len() == self.pos {
2987 return None;
2988 }
2989 let pos = self.pos;
2990 let mut r#type = None;
2991 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
2992 r#type = Some(header.r#type);
2993 let res = match header.r#type {
2994 1u16 => OpGetrouteDumpReply::Dst({
2995 let res = Some(next);
2996 let Some(val) = res else { break };
2997 val
2998 }),
2999 2u16 => OpGetrouteDumpReply::Src({
3000 let res = Some(next);
3001 let Some(val) = res else { break };
3002 val
3003 }),
3004 3u16 => OpGetrouteDumpReply::Iif({
3005 let res = parse_u32(next);
3006 let Some(val) = res else { break };
3007 val
3008 }),
3009 4u16 => OpGetrouteDumpReply::Oif({
3010 let res = parse_u32(next);
3011 let Some(val) = res else { break };
3012 val
3013 }),
3014 5u16 => OpGetrouteDumpReply::Gateway({
3015 let res = Some(next);
3016 let Some(val) = res else { break };
3017 val
3018 }),
3019 6u16 => OpGetrouteDumpReply::Priority({
3020 let res = parse_u32(next);
3021 let Some(val) = res else { break };
3022 val
3023 }),
3024 7u16 => OpGetrouteDumpReply::Prefsrc({
3025 let res = Some(next);
3026 let Some(val) = res else { break };
3027 val
3028 }),
3029 8u16 => OpGetrouteDumpReply::Metrics({
3030 let res = Some(IterableMetrics::with_loc(next, self.orig_loc));
3031 let Some(val) = res else { break };
3032 val
3033 }),
3034 9u16 => OpGetrouteDumpReply::Multipath({
3035 let res = Some(next);
3036 let Some(val) = res else { break };
3037 val
3038 }),
3039 11u16 => OpGetrouteDumpReply::Flow({
3040 let res = parse_u32(next);
3041 let Some(val) = res else { break };
3042 val
3043 }),
3044 12u16 => OpGetrouteDumpReply::Cacheinfo({
3045 let res = PushRtaCacheinfo::new_from_slice(next);
3046 let Some(val) = res else { break };
3047 val
3048 }),
3049 15u16 => OpGetrouteDumpReply::Table({
3050 let res = parse_u32(next);
3051 let Some(val) = res else { break };
3052 val
3053 }),
3054 16u16 => OpGetrouteDumpReply::Mark({
3055 let res = parse_u32(next);
3056 let Some(val) = res else { break };
3057 val
3058 }),
3059 17u16 => OpGetrouteDumpReply::MfcStats({
3060 let res = Some(next);
3061 let Some(val) = res else { break };
3062 val
3063 }),
3064 18u16 => OpGetrouteDumpReply::Via({
3065 let res = Some(next);
3066 let Some(val) = res else { break };
3067 val
3068 }),
3069 19u16 => OpGetrouteDumpReply::Newdst({
3070 let res = Some(next);
3071 let Some(val) = res else { break };
3072 val
3073 }),
3074 20u16 => OpGetrouteDumpReply::Pref({
3075 let res = parse_u8(next);
3076 let Some(val) = res else { break };
3077 val
3078 }),
3079 21u16 => OpGetrouteDumpReply::EncapType({
3080 let res = parse_u16(next);
3081 let Some(val) = res else { break };
3082 val
3083 }),
3084 22u16 => OpGetrouteDumpReply::Encap({
3085 let res = Some(next);
3086 let Some(val) = res else { break };
3087 val
3088 }),
3089 23u16 => OpGetrouteDumpReply::Expires({
3090 let res = parse_u32(next);
3091 let Some(val) = res else { break };
3092 val
3093 }),
3094 24u16 => OpGetrouteDumpReply::Pad({
3095 let res = Some(next);
3096 let Some(val) = res else { break };
3097 val
3098 }),
3099 25u16 => OpGetrouteDumpReply::Uid({
3100 let res = parse_u32(next);
3101 let Some(val) = res else { break };
3102 val
3103 }),
3104 26u16 => OpGetrouteDumpReply::TtlPropagate({
3105 let res = parse_u8(next);
3106 let Some(val) = res else { break };
3107 val
3108 }),
3109 27u16 => OpGetrouteDumpReply::IpProto({
3110 let res = parse_u8(next);
3111 let Some(val) = res else { break };
3112 val
3113 }),
3114 28u16 => OpGetrouteDumpReply::Sport({
3115 let res = parse_u16(next);
3116 let Some(val) = res else { break };
3117 val
3118 }),
3119 29u16 => OpGetrouteDumpReply::Dport({
3120 let res = parse_u16(next);
3121 let Some(val) = res else { break };
3122 val
3123 }),
3124 30u16 => OpGetrouteDumpReply::NhId({
3125 let res = parse_u32(next);
3126 let Some(val) = res else { break };
3127 val
3128 }),
3129 31u16 => OpGetrouteDumpReply::Flowlabel({
3130 let res = parse_be_u32(next);
3131 let Some(val) = res else { break };
3132 val
3133 }),
3134 n => {
3135 if cfg!(any(test, feature = "deny-unknown-attrs")) {
3136 break;
3137 } else {
3138 continue;
3139 }
3140 }
3141 };
3142 return Some(Ok(res));
3143 }
3144 Some(Err(ErrorContext::new(
3145 "OpGetrouteDumpReply",
3146 r#type.and_then(|t| OpGetrouteDumpReply::attr_from_type(t)),
3147 self.orig_loc,
3148 self.buf.as_ptr().wrapping_add(pos) as usize,
3149 )))
3150 }
3151}
3152impl<'a> std::fmt::Debug for IterableOpGetrouteDumpReply<'_> {
3153 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3154 let mut fmt = f.debug_struct("OpGetrouteDumpReply");
3155 for attr in self.clone() {
3156 let attr = match attr {
3157 Ok(a) => a,
3158 Err(err) => {
3159 fmt.finish()?;
3160 f.write_str("Err(")?;
3161 err.fmt(f)?;
3162 return f.write_str(")");
3163 }
3164 };
3165 match attr {
3166 OpGetrouteDumpReply::Dst(val) => fmt.field("Dst", &val),
3167 OpGetrouteDumpReply::Src(val) => fmt.field("Src", &val),
3168 OpGetrouteDumpReply::Iif(val) => fmt.field("Iif", &val),
3169 OpGetrouteDumpReply::Oif(val) => fmt.field("Oif", &val),
3170 OpGetrouteDumpReply::Gateway(val) => fmt.field("Gateway", &val),
3171 OpGetrouteDumpReply::Priority(val) => fmt.field("Priority", &val),
3172 OpGetrouteDumpReply::Prefsrc(val) => fmt.field("Prefsrc", &val),
3173 OpGetrouteDumpReply::Metrics(val) => fmt.field("Metrics", &val),
3174 OpGetrouteDumpReply::Multipath(val) => fmt.field("Multipath", &val),
3175 OpGetrouteDumpReply::Flow(val) => fmt.field("Flow", &val),
3176 OpGetrouteDumpReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
3177 OpGetrouteDumpReply::Table(val) => fmt.field("Table", &val),
3178 OpGetrouteDumpReply::Mark(val) => fmt.field("Mark", &val),
3179 OpGetrouteDumpReply::MfcStats(val) => fmt.field("MfcStats", &val),
3180 OpGetrouteDumpReply::Via(val) => fmt.field("Via", &val),
3181 OpGetrouteDumpReply::Newdst(val) => fmt.field("Newdst", &val),
3182 OpGetrouteDumpReply::Pref(val) => fmt.field("Pref", &val),
3183 OpGetrouteDumpReply::EncapType(val) => fmt.field("EncapType", &val),
3184 OpGetrouteDumpReply::Encap(val) => fmt.field("Encap", &val),
3185 OpGetrouteDumpReply::Expires(val) => fmt.field("Expires", &val),
3186 OpGetrouteDumpReply::Pad(val) => fmt.field("Pad", &val),
3187 OpGetrouteDumpReply::Uid(val) => fmt.field("Uid", &val),
3188 OpGetrouteDumpReply::TtlPropagate(val) => fmt.field("TtlPropagate", &val),
3189 OpGetrouteDumpReply::IpProto(val) => fmt.field("IpProto", &val),
3190 OpGetrouteDumpReply::Sport(val) => fmt.field("Sport", &val),
3191 OpGetrouteDumpReply::Dport(val) => fmt.field("Dport", &val),
3192 OpGetrouteDumpReply::NhId(val) => fmt.field("NhId", &val),
3193 OpGetrouteDumpReply::Flowlabel(val) => fmt.field("Flowlabel", &val),
3194 };
3195 }
3196 fmt.finish()
3197 }
3198}
3199impl IterableOpGetrouteDumpReply<'_> {
3200 pub fn lookup_attr(
3201 &self,
3202 offset: usize,
3203 missing_type: Option<u16>,
3204 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3205 let mut stack = Vec::new();
3206 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3207 if cur == offset + PushRtmsg::len() {
3208 stack.push(("OpGetrouteDumpReply", offset));
3209 return (
3210 stack,
3211 missing_type.and_then(|t| OpGetrouteDumpReply::attr_from_type(t)),
3212 );
3213 }
3214 if cur > offset || cur + self.buf.len() < offset {
3215 return (stack, None);
3216 }
3217 let mut attrs = self.clone();
3218 let mut last_off = cur + attrs.pos;
3219 let mut missing = None;
3220 while let Some(attr) = attrs.next() {
3221 let Ok(attr) = attr else { break };
3222 match attr {
3223 OpGetrouteDumpReply::Dst(val) => {
3224 if last_off == offset {
3225 stack.push(("Dst", last_off));
3226 break;
3227 }
3228 }
3229 OpGetrouteDumpReply::Src(val) => {
3230 if last_off == offset {
3231 stack.push(("Src", last_off));
3232 break;
3233 }
3234 }
3235 OpGetrouteDumpReply::Iif(val) => {
3236 if last_off == offset {
3237 stack.push(("Iif", last_off));
3238 break;
3239 }
3240 }
3241 OpGetrouteDumpReply::Oif(val) => {
3242 if last_off == offset {
3243 stack.push(("Oif", last_off));
3244 break;
3245 }
3246 }
3247 OpGetrouteDumpReply::Gateway(val) => {
3248 if last_off == offset {
3249 stack.push(("Gateway", last_off));
3250 break;
3251 }
3252 }
3253 OpGetrouteDumpReply::Priority(val) => {
3254 if last_off == offset {
3255 stack.push(("Priority", last_off));
3256 break;
3257 }
3258 }
3259 OpGetrouteDumpReply::Prefsrc(val) => {
3260 if last_off == offset {
3261 stack.push(("Prefsrc", last_off));
3262 break;
3263 }
3264 }
3265 OpGetrouteDumpReply::Metrics(val) => {
3266 (stack, missing) = val.lookup_attr(offset, missing_type);
3267 if !stack.is_empty() {
3268 break;
3269 }
3270 }
3271 OpGetrouteDumpReply::Multipath(val) => {
3272 if last_off == offset {
3273 stack.push(("Multipath", last_off));
3274 break;
3275 }
3276 }
3277 OpGetrouteDumpReply::Flow(val) => {
3278 if last_off == offset {
3279 stack.push(("Flow", last_off));
3280 break;
3281 }
3282 }
3283 OpGetrouteDumpReply::Cacheinfo(val) => {
3284 if last_off == offset {
3285 stack.push(("Cacheinfo", last_off));
3286 break;
3287 }
3288 }
3289 OpGetrouteDumpReply::Table(val) => {
3290 if last_off == offset {
3291 stack.push(("Table", last_off));
3292 break;
3293 }
3294 }
3295 OpGetrouteDumpReply::Mark(val) => {
3296 if last_off == offset {
3297 stack.push(("Mark", last_off));
3298 break;
3299 }
3300 }
3301 OpGetrouteDumpReply::MfcStats(val) => {
3302 if last_off == offset {
3303 stack.push(("MfcStats", last_off));
3304 break;
3305 }
3306 }
3307 OpGetrouteDumpReply::Via(val) => {
3308 if last_off == offset {
3309 stack.push(("Via", last_off));
3310 break;
3311 }
3312 }
3313 OpGetrouteDumpReply::Newdst(val) => {
3314 if last_off == offset {
3315 stack.push(("Newdst", last_off));
3316 break;
3317 }
3318 }
3319 OpGetrouteDumpReply::Pref(val) => {
3320 if last_off == offset {
3321 stack.push(("Pref", last_off));
3322 break;
3323 }
3324 }
3325 OpGetrouteDumpReply::EncapType(val) => {
3326 if last_off == offset {
3327 stack.push(("EncapType", last_off));
3328 break;
3329 }
3330 }
3331 OpGetrouteDumpReply::Encap(val) => {
3332 if last_off == offset {
3333 stack.push(("Encap", last_off));
3334 break;
3335 }
3336 }
3337 OpGetrouteDumpReply::Expires(val) => {
3338 if last_off == offset {
3339 stack.push(("Expires", last_off));
3340 break;
3341 }
3342 }
3343 OpGetrouteDumpReply::Pad(val) => {
3344 if last_off == offset {
3345 stack.push(("Pad", last_off));
3346 break;
3347 }
3348 }
3349 OpGetrouteDumpReply::Uid(val) => {
3350 if last_off == offset {
3351 stack.push(("Uid", last_off));
3352 break;
3353 }
3354 }
3355 OpGetrouteDumpReply::TtlPropagate(val) => {
3356 if last_off == offset {
3357 stack.push(("TtlPropagate", last_off));
3358 break;
3359 }
3360 }
3361 OpGetrouteDumpReply::IpProto(val) => {
3362 if last_off == offset {
3363 stack.push(("IpProto", last_off));
3364 break;
3365 }
3366 }
3367 OpGetrouteDumpReply::Sport(val) => {
3368 if last_off == offset {
3369 stack.push(("Sport", last_off));
3370 break;
3371 }
3372 }
3373 OpGetrouteDumpReply::Dport(val) => {
3374 if last_off == offset {
3375 stack.push(("Dport", last_off));
3376 break;
3377 }
3378 }
3379 OpGetrouteDumpReply::NhId(val) => {
3380 if last_off == offset {
3381 stack.push(("NhId", last_off));
3382 break;
3383 }
3384 }
3385 OpGetrouteDumpReply::Flowlabel(val) => {
3386 if last_off == offset {
3387 stack.push(("Flowlabel", last_off));
3388 break;
3389 }
3390 }
3391 _ => {}
3392 };
3393 last_off = cur + attrs.pos;
3394 }
3395 if !stack.is_empty() {
3396 stack.push(("OpGetrouteDumpReply", cur));
3397 }
3398 (stack, missing)
3399 }
3400}
3401#[derive(Debug)]
3402pub struct RequestOpGetrouteDumpRequest<'r> {
3403 request: Request<'r>,
3404}
3405impl<'r> RequestOpGetrouteDumpRequest<'r> {
3406 pub fn new(mut request: Request<'r>, header: &PushRtmsg) -> Self {
3407 PushOpGetrouteDumpRequest::write_header(&mut request.buf_mut(), header);
3408 Self {
3409 request: request.set_dump(),
3410 }
3411 }
3412 pub fn encode(&mut self) -> PushOpGetrouteDumpRequest<&mut Vec<u8>> {
3413 PushOpGetrouteDumpRequest::new_without_header(self.request.buf_mut())
3414 }
3415 pub fn into_encoder(self) -> PushOpGetrouteDumpRequest<RequestBuf<'r>> {
3416 PushOpGetrouteDumpRequest::new_without_header(self.request.buf)
3417 }
3418}
3419impl NetlinkRequest for RequestOpGetrouteDumpRequest<'_> {
3420 type ReplyType<'buf> = (PushRtmsg, IterableOpGetrouteDumpReply<'buf>);
3421 fn protocol(&self) -> Protocol {
3422 Protocol::Raw {
3423 protonum: 0u16,
3424 request_type: 26u16,
3425 }
3426 }
3427 fn flags(&self) -> u16 {
3428 self.request.flags
3429 }
3430 fn payload(&self) -> &[u8] {
3431 self.request.buf()
3432 }
3433 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3434 OpGetrouteDumpReply::new(buf)
3435 }
3436 fn lookup(
3437 buf: &[u8],
3438 offset: usize,
3439 missing_type: Option<u16>,
3440 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3441 OpGetrouteDumpRequest::new(buf)
3442 .1
3443 .lookup_attr(offset, missing_type)
3444 }
3445}
3446#[doc = "Dump route information."]
3447pub struct PushOpGetrouteDoRequest<Prev: Rec> {
3448 pub(crate) prev: Option<Prev>,
3449 pub(crate) header_offset: Option<usize>,
3450}
3451impl<Prev: Rec> Rec for PushOpGetrouteDoRequest<Prev> {
3452 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3453 self.prev.as_mut().unwrap().as_rec_mut()
3454 }
3455}
3456impl<Prev: Rec> PushOpGetrouteDoRequest<Prev> {
3457 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
3458 Self::write_header(&mut prev, header);
3459 Self::new_without_header(prev)
3460 }
3461 fn new_without_header(prev: Prev) -> Self {
3462 Self {
3463 prev: Some(prev),
3464 header_offset: None,
3465 }
3466 }
3467 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
3468 prev.as_rec_mut().extend(header.as_slice());
3469 }
3470 pub fn end_nested(mut self) -> Prev {
3471 let mut prev = self.prev.take().unwrap();
3472 if let Some(header_offset) = &self.header_offset {
3473 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3474 }
3475 prev
3476 }
3477 pub fn push_dst(mut self, value: &[u8]) -> Self {
3478 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
3479 self.as_rec_mut().extend(value);
3480 self
3481 }
3482 pub fn push_src(mut self, value: &[u8]) -> Self {
3483 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
3484 self.as_rec_mut().extend(value);
3485 self
3486 }
3487 pub fn push_iif(mut self, value: u32) -> Self {
3488 push_header(self.as_rec_mut(), 3u16, 4 as u16);
3489 self.as_rec_mut().extend(value.to_ne_bytes());
3490 self
3491 }
3492 pub fn push_oif(mut self, value: u32) -> Self {
3493 push_header(self.as_rec_mut(), 4u16, 4 as u16);
3494 self.as_rec_mut().extend(value.to_ne_bytes());
3495 self
3496 }
3497 pub fn push_mark(mut self, value: u32) -> Self {
3498 push_header(self.as_rec_mut(), 16u16, 4 as u16);
3499 self.as_rec_mut().extend(value.to_ne_bytes());
3500 self
3501 }
3502 pub fn push_uid(mut self, value: u32) -> Self {
3503 push_header(self.as_rec_mut(), 25u16, 4 as u16);
3504 self.as_rec_mut().extend(value.to_ne_bytes());
3505 self
3506 }
3507 pub fn push_ip_proto(mut self, value: u8) -> Self {
3508 push_header(self.as_rec_mut(), 27u16, 1 as u16);
3509 self.as_rec_mut().extend(value.to_ne_bytes());
3510 self
3511 }
3512 pub fn push_sport(mut self, value: u16) -> Self {
3513 push_header(self.as_rec_mut(), 28u16, 2 as u16);
3514 self.as_rec_mut().extend(value.to_ne_bytes());
3515 self
3516 }
3517 pub fn push_dport(mut self, value: u16) -> Self {
3518 push_header(self.as_rec_mut(), 29u16, 2 as u16);
3519 self.as_rec_mut().extend(value.to_ne_bytes());
3520 self
3521 }
3522 pub fn push_flowlabel(mut self, value: u32) -> Self {
3523 push_header(self.as_rec_mut(), 31u16, 4 as u16);
3524 self.as_rec_mut().extend(value.to_be_bytes());
3525 self
3526 }
3527}
3528impl<Prev: Rec> Drop for PushOpGetrouteDoRequest<Prev> {
3529 fn drop(&mut self) {
3530 if let Some(prev) = &mut self.prev {
3531 if let Some(header_offset) = &self.header_offset {
3532 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3533 }
3534 }
3535 }
3536}
3537#[doc = "Dump route information."]
3538#[derive(Clone)]
3539pub enum OpGetrouteDoRequest<'a> {
3540 Dst(&'a [u8]),
3541 Src(&'a [u8]),
3542 Iif(u32),
3543 Oif(u32),
3544 Mark(u32),
3545 Uid(u32),
3546 IpProto(u8),
3547 Sport(u16),
3548 Dport(u16),
3549 Flowlabel(u32),
3550}
3551impl<'a> IterableOpGetrouteDoRequest<'a> {
3552 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
3553 let mut iter = self.clone();
3554 iter.pos = 0;
3555 for attr in iter {
3556 if let OpGetrouteDoRequest::Dst(val) = attr? {
3557 return Ok(val);
3558 }
3559 }
3560 Err(ErrorContext::new_missing(
3561 "OpGetrouteDoRequest",
3562 "Dst",
3563 self.orig_loc,
3564 self.buf.as_ptr() as usize,
3565 ))
3566 }
3567 pub fn get_src(&self) -> Result<&'a [u8], ErrorContext> {
3568 let mut iter = self.clone();
3569 iter.pos = 0;
3570 for attr in iter {
3571 if let OpGetrouteDoRequest::Src(val) = attr? {
3572 return Ok(val);
3573 }
3574 }
3575 Err(ErrorContext::new_missing(
3576 "OpGetrouteDoRequest",
3577 "Src",
3578 self.orig_loc,
3579 self.buf.as_ptr() as usize,
3580 ))
3581 }
3582 pub fn get_iif(&self) -> Result<u32, ErrorContext> {
3583 let mut iter = self.clone();
3584 iter.pos = 0;
3585 for attr in iter {
3586 if let OpGetrouteDoRequest::Iif(val) = attr? {
3587 return Ok(val);
3588 }
3589 }
3590 Err(ErrorContext::new_missing(
3591 "OpGetrouteDoRequest",
3592 "Iif",
3593 self.orig_loc,
3594 self.buf.as_ptr() as usize,
3595 ))
3596 }
3597 pub fn get_oif(&self) -> Result<u32, ErrorContext> {
3598 let mut iter = self.clone();
3599 iter.pos = 0;
3600 for attr in iter {
3601 if let OpGetrouteDoRequest::Oif(val) = attr? {
3602 return Ok(val);
3603 }
3604 }
3605 Err(ErrorContext::new_missing(
3606 "OpGetrouteDoRequest",
3607 "Oif",
3608 self.orig_loc,
3609 self.buf.as_ptr() as usize,
3610 ))
3611 }
3612 pub fn get_mark(&self) -> Result<u32, ErrorContext> {
3613 let mut iter = self.clone();
3614 iter.pos = 0;
3615 for attr in iter {
3616 if let OpGetrouteDoRequest::Mark(val) = attr? {
3617 return Ok(val);
3618 }
3619 }
3620 Err(ErrorContext::new_missing(
3621 "OpGetrouteDoRequest",
3622 "Mark",
3623 self.orig_loc,
3624 self.buf.as_ptr() as usize,
3625 ))
3626 }
3627 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
3628 let mut iter = self.clone();
3629 iter.pos = 0;
3630 for attr in iter {
3631 if let OpGetrouteDoRequest::Uid(val) = attr? {
3632 return Ok(val);
3633 }
3634 }
3635 Err(ErrorContext::new_missing(
3636 "OpGetrouteDoRequest",
3637 "Uid",
3638 self.orig_loc,
3639 self.buf.as_ptr() as usize,
3640 ))
3641 }
3642 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
3643 let mut iter = self.clone();
3644 iter.pos = 0;
3645 for attr in iter {
3646 if let OpGetrouteDoRequest::IpProto(val) = attr? {
3647 return Ok(val);
3648 }
3649 }
3650 Err(ErrorContext::new_missing(
3651 "OpGetrouteDoRequest",
3652 "IpProto",
3653 self.orig_loc,
3654 self.buf.as_ptr() as usize,
3655 ))
3656 }
3657 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
3658 let mut iter = self.clone();
3659 iter.pos = 0;
3660 for attr in iter {
3661 if let OpGetrouteDoRequest::Sport(val) = attr? {
3662 return Ok(val);
3663 }
3664 }
3665 Err(ErrorContext::new_missing(
3666 "OpGetrouteDoRequest",
3667 "Sport",
3668 self.orig_loc,
3669 self.buf.as_ptr() as usize,
3670 ))
3671 }
3672 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
3673 let mut iter = self.clone();
3674 iter.pos = 0;
3675 for attr in iter {
3676 if let OpGetrouteDoRequest::Dport(val) = attr? {
3677 return Ok(val);
3678 }
3679 }
3680 Err(ErrorContext::new_missing(
3681 "OpGetrouteDoRequest",
3682 "Dport",
3683 self.orig_loc,
3684 self.buf.as_ptr() as usize,
3685 ))
3686 }
3687 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
3688 let mut iter = self.clone();
3689 iter.pos = 0;
3690 for attr in iter {
3691 if let OpGetrouteDoRequest::Flowlabel(val) = attr? {
3692 return Ok(val);
3693 }
3694 }
3695 Err(ErrorContext::new_missing(
3696 "OpGetrouteDoRequest",
3697 "Flowlabel",
3698 self.orig_loc,
3699 self.buf.as_ptr() as usize,
3700 ))
3701 }
3702}
3703impl<'a> OpGetrouteDoRequest<'a> {
3704 pub fn new(buf: &'a [u8]) -> (PushRtmsg, IterableOpGetrouteDoRequest<'a>) {
3705 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
3706 (
3707 PushRtmsg::new_from_slice(header).unwrap_or_default(),
3708 IterableOpGetrouteDoRequest::with_loc(attrs, buf.as_ptr() as usize),
3709 )
3710 }
3711 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3712 RouteAttrs::attr_from_type(r#type)
3713 }
3714}
3715#[derive(Clone, Copy, Default)]
3716pub struct IterableOpGetrouteDoRequest<'a> {
3717 buf: &'a [u8],
3718 pos: usize,
3719 orig_loc: usize,
3720}
3721impl<'a> IterableOpGetrouteDoRequest<'a> {
3722 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3723 Self {
3724 buf,
3725 pos: 0,
3726 orig_loc,
3727 }
3728 }
3729 pub fn get_buf(&self) -> &'a [u8] {
3730 self.buf
3731 }
3732}
3733impl<'a> Iterator for IterableOpGetrouteDoRequest<'a> {
3734 type Item = Result<OpGetrouteDoRequest<'a>, ErrorContext>;
3735 fn next(&mut self) -> Option<Self::Item> {
3736 if self.buf.len() == self.pos {
3737 return None;
3738 }
3739 let pos = self.pos;
3740 let mut r#type = None;
3741 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
3742 r#type = Some(header.r#type);
3743 let res = match header.r#type {
3744 1u16 => OpGetrouteDoRequest::Dst({
3745 let res = Some(next);
3746 let Some(val) = res else { break };
3747 val
3748 }),
3749 2u16 => OpGetrouteDoRequest::Src({
3750 let res = Some(next);
3751 let Some(val) = res else { break };
3752 val
3753 }),
3754 3u16 => OpGetrouteDoRequest::Iif({
3755 let res = parse_u32(next);
3756 let Some(val) = res else { break };
3757 val
3758 }),
3759 4u16 => OpGetrouteDoRequest::Oif({
3760 let res = parse_u32(next);
3761 let Some(val) = res else { break };
3762 val
3763 }),
3764 16u16 => OpGetrouteDoRequest::Mark({
3765 let res = parse_u32(next);
3766 let Some(val) = res else { break };
3767 val
3768 }),
3769 25u16 => OpGetrouteDoRequest::Uid({
3770 let res = parse_u32(next);
3771 let Some(val) = res else { break };
3772 val
3773 }),
3774 27u16 => OpGetrouteDoRequest::IpProto({
3775 let res = parse_u8(next);
3776 let Some(val) = res else { break };
3777 val
3778 }),
3779 28u16 => OpGetrouteDoRequest::Sport({
3780 let res = parse_u16(next);
3781 let Some(val) = res else { break };
3782 val
3783 }),
3784 29u16 => OpGetrouteDoRequest::Dport({
3785 let res = parse_u16(next);
3786 let Some(val) = res else { break };
3787 val
3788 }),
3789 31u16 => OpGetrouteDoRequest::Flowlabel({
3790 let res = parse_be_u32(next);
3791 let Some(val) = res else { break };
3792 val
3793 }),
3794 n => {
3795 if cfg!(any(test, feature = "deny-unknown-attrs")) {
3796 break;
3797 } else {
3798 continue;
3799 }
3800 }
3801 };
3802 return Some(Ok(res));
3803 }
3804 Some(Err(ErrorContext::new(
3805 "OpGetrouteDoRequest",
3806 r#type.and_then(|t| OpGetrouteDoRequest::attr_from_type(t)),
3807 self.orig_loc,
3808 self.buf.as_ptr().wrapping_add(pos) as usize,
3809 )))
3810 }
3811}
3812impl<'a> std::fmt::Debug for IterableOpGetrouteDoRequest<'_> {
3813 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3814 let mut fmt = f.debug_struct("OpGetrouteDoRequest");
3815 for attr in self.clone() {
3816 let attr = match attr {
3817 Ok(a) => a,
3818 Err(err) => {
3819 fmt.finish()?;
3820 f.write_str("Err(")?;
3821 err.fmt(f)?;
3822 return f.write_str(")");
3823 }
3824 };
3825 match attr {
3826 OpGetrouteDoRequest::Dst(val) => fmt.field("Dst", &val),
3827 OpGetrouteDoRequest::Src(val) => fmt.field("Src", &val),
3828 OpGetrouteDoRequest::Iif(val) => fmt.field("Iif", &val),
3829 OpGetrouteDoRequest::Oif(val) => fmt.field("Oif", &val),
3830 OpGetrouteDoRequest::Mark(val) => fmt.field("Mark", &val),
3831 OpGetrouteDoRequest::Uid(val) => fmt.field("Uid", &val),
3832 OpGetrouteDoRequest::IpProto(val) => fmt.field("IpProto", &val),
3833 OpGetrouteDoRequest::Sport(val) => fmt.field("Sport", &val),
3834 OpGetrouteDoRequest::Dport(val) => fmt.field("Dport", &val),
3835 OpGetrouteDoRequest::Flowlabel(val) => fmt.field("Flowlabel", &val),
3836 };
3837 }
3838 fmt.finish()
3839 }
3840}
3841impl IterableOpGetrouteDoRequest<'_> {
3842 pub fn lookup_attr(
3843 &self,
3844 offset: usize,
3845 missing_type: Option<u16>,
3846 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3847 let mut stack = Vec::new();
3848 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3849 if cur == offset + PushRtmsg::len() {
3850 stack.push(("OpGetrouteDoRequest", offset));
3851 return (
3852 stack,
3853 missing_type.and_then(|t| OpGetrouteDoRequest::attr_from_type(t)),
3854 );
3855 }
3856 if cur > offset || cur + self.buf.len() < offset {
3857 return (stack, None);
3858 }
3859 let mut attrs = self.clone();
3860 let mut last_off = cur + attrs.pos;
3861 while let Some(attr) = attrs.next() {
3862 let Ok(attr) = attr else { break };
3863 match attr {
3864 OpGetrouteDoRequest::Dst(val) => {
3865 if last_off == offset {
3866 stack.push(("Dst", last_off));
3867 break;
3868 }
3869 }
3870 OpGetrouteDoRequest::Src(val) => {
3871 if last_off == offset {
3872 stack.push(("Src", last_off));
3873 break;
3874 }
3875 }
3876 OpGetrouteDoRequest::Iif(val) => {
3877 if last_off == offset {
3878 stack.push(("Iif", last_off));
3879 break;
3880 }
3881 }
3882 OpGetrouteDoRequest::Oif(val) => {
3883 if last_off == offset {
3884 stack.push(("Oif", last_off));
3885 break;
3886 }
3887 }
3888 OpGetrouteDoRequest::Mark(val) => {
3889 if last_off == offset {
3890 stack.push(("Mark", last_off));
3891 break;
3892 }
3893 }
3894 OpGetrouteDoRequest::Uid(val) => {
3895 if last_off == offset {
3896 stack.push(("Uid", last_off));
3897 break;
3898 }
3899 }
3900 OpGetrouteDoRequest::IpProto(val) => {
3901 if last_off == offset {
3902 stack.push(("IpProto", last_off));
3903 break;
3904 }
3905 }
3906 OpGetrouteDoRequest::Sport(val) => {
3907 if last_off == offset {
3908 stack.push(("Sport", last_off));
3909 break;
3910 }
3911 }
3912 OpGetrouteDoRequest::Dport(val) => {
3913 if last_off == offset {
3914 stack.push(("Dport", last_off));
3915 break;
3916 }
3917 }
3918 OpGetrouteDoRequest::Flowlabel(val) => {
3919 if last_off == offset {
3920 stack.push(("Flowlabel", last_off));
3921 break;
3922 }
3923 }
3924 _ => {}
3925 };
3926 last_off = cur + attrs.pos;
3927 }
3928 if !stack.is_empty() {
3929 stack.push(("OpGetrouteDoRequest", cur));
3930 }
3931 (stack, None)
3932 }
3933}
3934#[doc = "Dump route information."]
3935pub struct PushOpGetrouteDoReply<Prev: Rec> {
3936 pub(crate) prev: Option<Prev>,
3937 pub(crate) header_offset: Option<usize>,
3938}
3939impl<Prev: Rec> Rec for PushOpGetrouteDoReply<Prev> {
3940 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3941 self.prev.as_mut().unwrap().as_rec_mut()
3942 }
3943}
3944impl<Prev: Rec> PushOpGetrouteDoReply<Prev> {
3945 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
3946 Self::write_header(&mut prev, header);
3947 Self::new_without_header(prev)
3948 }
3949 fn new_without_header(prev: Prev) -> Self {
3950 Self {
3951 prev: Some(prev),
3952 header_offset: None,
3953 }
3954 }
3955 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
3956 prev.as_rec_mut().extend(header.as_slice());
3957 }
3958 pub fn end_nested(mut self) -> Prev {
3959 let mut prev = self.prev.take().unwrap();
3960 if let Some(header_offset) = &self.header_offset {
3961 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3962 }
3963 prev
3964 }
3965 pub fn push_dst(mut self, value: &[u8]) -> Self {
3966 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
3967 self.as_rec_mut().extend(value);
3968 self
3969 }
3970 pub fn push_src(mut self, value: &[u8]) -> Self {
3971 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
3972 self.as_rec_mut().extend(value);
3973 self
3974 }
3975 pub fn push_iif(mut self, value: u32) -> Self {
3976 push_header(self.as_rec_mut(), 3u16, 4 as u16);
3977 self.as_rec_mut().extend(value.to_ne_bytes());
3978 self
3979 }
3980 pub fn push_oif(mut self, value: u32) -> Self {
3981 push_header(self.as_rec_mut(), 4u16, 4 as u16);
3982 self.as_rec_mut().extend(value.to_ne_bytes());
3983 self
3984 }
3985 pub fn push_gateway(mut self, value: &[u8]) -> Self {
3986 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
3987 self.as_rec_mut().extend(value);
3988 self
3989 }
3990 pub fn push_priority(mut self, value: u32) -> Self {
3991 push_header(self.as_rec_mut(), 6u16, 4 as u16);
3992 self.as_rec_mut().extend(value.to_ne_bytes());
3993 self
3994 }
3995 pub fn push_prefsrc(mut self, value: &[u8]) -> Self {
3996 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
3997 self.as_rec_mut().extend(value);
3998 self
3999 }
4000 pub fn nested_metrics(mut self) -> PushMetrics<Self> {
4001 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
4002 PushMetrics {
4003 prev: Some(self),
4004 header_offset: Some(header_offset),
4005 }
4006 }
4007 pub fn push_multipath(mut self, value: &[u8]) -> Self {
4008 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
4009 self.as_rec_mut().extend(value);
4010 self
4011 }
4012 pub fn push_flow(mut self, value: u32) -> Self {
4013 push_header(self.as_rec_mut(), 11u16, 4 as u16);
4014 self.as_rec_mut().extend(value.to_ne_bytes());
4015 self
4016 }
4017 pub fn push_cacheinfo(mut self, value: PushRtaCacheinfo) -> Self {
4018 push_header(self.as_rec_mut(), 12u16, value.as_slice().len() as u16);
4019 self.as_rec_mut().extend(value.as_slice());
4020 self
4021 }
4022 pub fn push_table(mut self, value: u32) -> Self {
4023 push_header(self.as_rec_mut(), 15u16, 4 as u16);
4024 self.as_rec_mut().extend(value.to_ne_bytes());
4025 self
4026 }
4027 pub fn push_mark(mut self, value: u32) -> Self {
4028 push_header(self.as_rec_mut(), 16u16, 4 as u16);
4029 self.as_rec_mut().extend(value.to_ne_bytes());
4030 self
4031 }
4032 pub fn push_mfc_stats(mut self, value: &[u8]) -> Self {
4033 push_header(self.as_rec_mut(), 17u16, value.len() as u16);
4034 self.as_rec_mut().extend(value);
4035 self
4036 }
4037 pub fn push_via(mut self, value: &[u8]) -> Self {
4038 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
4039 self.as_rec_mut().extend(value);
4040 self
4041 }
4042 pub fn push_newdst(mut self, value: &[u8]) -> Self {
4043 push_header(self.as_rec_mut(), 19u16, value.len() as u16);
4044 self.as_rec_mut().extend(value);
4045 self
4046 }
4047 pub fn push_pref(mut self, value: u8) -> Self {
4048 push_header(self.as_rec_mut(), 20u16, 1 as u16);
4049 self.as_rec_mut().extend(value.to_ne_bytes());
4050 self
4051 }
4052 pub fn push_encap_type(mut self, value: u16) -> Self {
4053 push_header(self.as_rec_mut(), 21u16, 2 as u16);
4054 self.as_rec_mut().extend(value.to_ne_bytes());
4055 self
4056 }
4057 pub fn push_encap(mut self, value: &[u8]) -> Self {
4058 push_header(self.as_rec_mut(), 22u16, value.len() as u16);
4059 self.as_rec_mut().extend(value);
4060 self
4061 }
4062 pub fn push_expires(mut self, value: u32) -> Self {
4063 push_header(self.as_rec_mut(), 23u16, 4 as u16);
4064 self.as_rec_mut().extend(value.to_ne_bytes());
4065 self
4066 }
4067 pub fn push_pad(mut self, value: &[u8]) -> Self {
4068 push_header(self.as_rec_mut(), 24u16, value.len() as u16);
4069 self.as_rec_mut().extend(value);
4070 self
4071 }
4072 pub fn push_uid(mut self, value: u32) -> Self {
4073 push_header(self.as_rec_mut(), 25u16, 4 as u16);
4074 self.as_rec_mut().extend(value.to_ne_bytes());
4075 self
4076 }
4077 pub fn push_ttl_propagate(mut self, value: u8) -> Self {
4078 push_header(self.as_rec_mut(), 26u16, 1 as u16);
4079 self.as_rec_mut().extend(value.to_ne_bytes());
4080 self
4081 }
4082 pub fn push_ip_proto(mut self, value: u8) -> Self {
4083 push_header(self.as_rec_mut(), 27u16, 1 as u16);
4084 self.as_rec_mut().extend(value.to_ne_bytes());
4085 self
4086 }
4087 pub fn push_sport(mut self, value: u16) -> Self {
4088 push_header(self.as_rec_mut(), 28u16, 2 as u16);
4089 self.as_rec_mut().extend(value.to_ne_bytes());
4090 self
4091 }
4092 pub fn push_dport(mut self, value: u16) -> Self {
4093 push_header(self.as_rec_mut(), 29u16, 2 as u16);
4094 self.as_rec_mut().extend(value.to_ne_bytes());
4095 self
4096 }
4097 pub fn push_nh_id(mut self, value: u32) -> Self {
4098 push_header(self.as_rec_mut(), 30u16, 4 as u16);
4099 self.as_rec_mut().extend(value.to_ne_bytes());
4100 self
4101 }
4102 pub fn push_flowlabel(mut self, value: u32) -> Self {
4103 push_header(self.as_rec_mut(), 31u16, 4 as u16);
4104 self.as_rec_mut().extend(value.to_be_bytes());
4105 self
4106 }
4107}
4108impl<Prev: Rec> Drop for PushOpGetrouteDoReply<Prev> {
4109 fn drop(&mut self) {
4110 if let Some(prev) = &mut self.prev {
4111 if let Some(header_offset) = &self.header_offset {
4112 finalize_nested_header(prev.as_rec_mut(), *header_offset);
4113 }
4114 }
4115 }
4116}
4117#[doc = "Dump route information."]
4118#[derive(Clone)]
4119pub enum OpGetrouteDoReply<'a> {
4120 Dst(&'a [u8]),
4121 Src(&'a [u8]),
4122 Iif(u32),
4123 Oif(u32),
4124 Gateway(&'a [u8]),
4125 Priority(u32),
4126 Prefsrc(&'a [u8]),
4127 Metrics(IterableMetrics<'a>),
4128 Multipath(&'a [u8]),
4129 Flow(u32),
4130 Cacheinfo(PushRtaCacheinfo),
4131 Table(u32),
4132 Mark(u32),
4133 MfcStats(&'a [u8]),
4134 Via(&'a [u8]),
4135 Newdst(&'a [u8]),
4136 Pref(u8),
4137 EncapType(u16),
4138 Encap(&'a [u8]),
4139 Expires(u32),
4140 Pad(&'a [u8]),
4141 Uid(u32),
4142 TtlPropagate(u8),
4143 IpProto(u8),
4144 Sport(u16),
4145 Dport(u16),
4146 NhId(u32),
4147 Flowlabel(u32),
4148}
4149impl<'a> IterableOpGetrouteDoReply<'a> {
4150 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4151 let mut iter = self.clone();
4152 iter.pos = 0;
4153 for attr in iter {
4154 if let OpGetrouteDoReply::Dst(val) = attr? {
4155 return Ok(val);
4156 }
4157 }
4158 Err(ErrorContext::new_missing(
4159 "OpGetrouteDoReply",
4160 "Dst",
4161 self.orig_loc,
4162 self.buf.as_ptr() as usize,
4163 ))
4164 }
4165 pub fn get_src(&self) -> Result<&'a [u8], ErrorContext> {
4166 let mut iter = self.clone();
4167 iter.pos = 0;
4168 for attr in iter {
4169 if let OpGetrouteDoReply::Src(val) = attr? {
4170 return Ok(val);
4171 }
4172 }
4173 Err(ErrorContext::new_missing(
4174 "OpGetrouteDoReply",
4175 "Src",
4176 self.orig_loc,
4177 self.buf.as_ptr() as usize,
4178 ))
4179 }
4180 pub fn get_iif(&self) -> Result<u32, ErrorContext> {
4181 let mut iter = self.clone();
4182 iter.pos = 0;
4183 for attr in iter {
4184 if let OpGetrouteDoReply::Iif(val) = attr? {
4185 return Ok(val);
4186 }
4187 }
4188 Err(ErrorContext::new_missing(
4189 "OpGetrouteDoReply",
4190 "Iif",
4191 self.orig_loc,
4192 self.buf.as_ptr() as usize,
4193 ))
4194 }
4195 pub fn get_oif(&self) -> Result<u32, ErrorContext> {
4196 let mut iter = self.clone();
4197 iter.pos = 0;
4198 for attr in iter {
4199 if let OpGetrouteDoReply::Oif(val) = attr? {
4200 return Ok(val);
4201 }
4202 }
4203 Err(ErrorContext::new_missing(
4204 "OpGetrouteDoReply",
4205 "Oif",
4206 self.orig_loc,
4207 self.buf.as_ptr() as usize,
4208 ))
4209 }
4210 pub fn get_gateway(&self) -> Result<&'a [u8], ErrorContext> {
4211 let mut iter = self.clone();
4212 iter.pos = 0;
4213 for attr in iter {
4214 if let OpGetrouteDoReply::Gateway(val) = attr? {
4215 return Ok(val);
4216 }
4217 }
4218 Err(ErrorContext::new_missing(
4219 "OpGetrouteDoReply",
4220 "Gateway",
4221 self.orig_loc,
4222 self.buf.as_ptr() as usize,
4223 ))
4224 }
4225 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
4226 let mut iter = self.clone();
4227 iter.pos = 0;
4228 for attr in iter {
4229 if let OpGetrouteDoReply::Priority(val) = attr? {
4230 return Ok(val);
4231 }
4232 }
4233 Err(ErrorContext::new_missing(
4234 "OpGetrouteDoReply",
4235 "Priority",
4236 self.orig_loc,
4237 self.buf.as_ptr() as usize,
4238 ))
4239 }
4240 pub fn get_prefsrc(&self) -> Result<&'a [u8], ErrorContext> {
4241 let mut iter = self.clone();
4242 iter.pos = 0;
4243 for attr in iter {
4244 if let OpGetrouteDoReply::Prefsrc(val) = attr? {
4245 return Ok(val);
4246 }
4247 }
4248 Err(ErrorContext::new_missing(
4249 "OpGetrouteDoReply",
4250 "Prefsrc",
4251 self.orig_loc,
4252 self.buf.as_ptr() as usize,
4253 ))
4254 }
4255 pub fn get_metrics(&self) -> Result<IterableMetrics<'a>, ErrorContext> {
4256 let mut iter = self.clone();
4257 iter.pos = 0;
4258 for attr in iter {
4259 if let OpGetrouteDoReply::Metrics(val) = attr? {
4260 return Ok(val);
4261 }
4262 }
4263 Err(ErrorContext::new_missing(
4264 "OpGetrouteDoReply",
4265 "Metrics",
4266 self.orig_loc,
4267 self.buf.as_ptr() as usize,
4268 ))
4269 }
4270 pub fn get_multipath(&self) -> Result<&'a [u8], ErrorContext> {
4271 let mut iter = self.clone();
4272 iter.pos = 0;
4273 for attr in iter {
4274 if let OpGetrouteDoReply::Multipath(val) = attr? {
4275 return Ok(val);
4276 }
4277 }
4278 Err(ErrorContext::new_missing(
4279 "OpGetrouteDoReply",
4280 "Multipath",
4281 self.orig_loc,
4282 self.buf.as_ptr() as usize,
4283 ))
4284 }
4285 pub fn get_flow(&self) -> Result<u32, ErrorContext> {
4286 let mut iter = self.clone();
4287 iter.pos = 0;
4288 for attr in iter {
4289 if let OpGetrouteDoReply::Flow(val) = attr? {
4290 return Ok(val);
4291 }
4292 }
4293 Err(ErrorContext::new_missing(
4294 "OpGetrouteDoReply",
4295 "Flow",
4296 self.orig_loc,
4297 self.buf.as_ptr() as usize,
4298 ))
4299 }
4300 pub fn get_cacheinfo(&self) -> Result<PushRtaCacheinfo, ErrorContext> {
4301 let mut iter = self.clone();
4302 iter.pos = 0;
4303 for attr in iter {
4304 if let OpGetrouteDoReply::Cacheinfo(val) = attr? {
4305 return Ok(val);
4306 }
4307 }
4308 Err(ErrorContext::new_missing(
4309 "OpGetrouteDoReply",
4310 "Cacheinfo",
4311 self.orig_loc,
4312 self.buf.as_ptr() as usize,
4313 ))
4314 }
4315 pub fn get_table(&self) -> Result<u32, ErrorContext> {
4316 let mut iter = self.clone();
4317 iter.pos = 0;
4318 for attr in iter {
4319 if let OpGetrouteDoReply::Table(val) = attr? {
4320 return Ok(val);
4321 }
4322 }
4323 Err(ErrorContext::new_missing(
4324 "OpGetrouteDoReply",
4325 "Table",
4326 self.orig_loc,
4327 self.buf.as_ptr() as usize,
4328 ))
4329 }
4330 pub fn get_mark(&self) -> Result<u32, ErrorContext> {
4331 let mut iter = self.clone();
4332 iter.pos = 0;
4333 for attr in iter {
4334 if let OpGetrouteDoReply::Mark(val) = attr? {
4335 return Ok(val);
4336 }
4337 }
4338 Err(ErrorContext::new_missing(
4339 "OpGetrouteDoReply",
4340 "Mark",
4341 self.orig_loc,
4342 self.buf.as_ptr() as usize,
4343 ))
4344 }
4345 pub fn get_mfc_stats(&self) -> Result<&'a [u8], ErrorContext> {
4346 let mut iter = self.clone();
4347 iter.pos = 0;
4348 for attr in iter {
4349 if let OpGetrouteDoReply::MfcStats(val) = attr? {
4350 return Ok(val);
4351 }
4352 }
4353 Err(ErrorContext::new_missing(
4354 "OpGetrouteDoReply",
4355 "MfcStats",
4356 self.orig_loc,
4357 self.buf.as_ptr() as usize,
4358 ))
4359 }
4360 pub fn get_via(&self) -> Result<&'a [u8], ErrorContext> {
4361 let mut iter = self.clone();
4362 iter.pos = 0;
4363 for attr in iter {
4364 if let OpGetrouteDoReply::Via(val) = attr? {
4365 return Ok(val);
4366 }
4367 }
4368 Err(ErrorContext::new_missing(
4369 "OpGetrouteDoReply",
4370 "Via",
4371 self.orig_loc,
4372 self.buf.as_ptr() as usize,
4373 ))
4374 }
4375 pub fn get_newdst(&self) -> Result<&'a [u8], ErrorContext> {
4376 let mut iter = self.clone();
4377 iter.pos = 0;
4378 for attr in iter {
4379 if let OpGetrouteDoReply::Newdst(val) = attr? {
4380 return Ok(val);
4381 }
4382 }
4383 Err(ErrorContext::new_missing(
4384 "OpGetrouteDoReply",
4385 "Newdst",
4386 self.orig_loc,
4387 self.buf.as_ptr() as usize,
4388 ))
4389 }
4390 pub fn get_pref(&self) -> Result<u8, ErrorContext> {
4391 let mut iter = self.clone();
4392 iter.pos = 0;
4393 for attr in iter {
4394 if let OpGetrouteDoReply::Pref(val) = attr? {
4395 return Ok(val);
4396 }
4397 }
4398 Err(ErrorContext::new_missing(
4399 "OpGetrouteDoReply",
4400 "Pref",
4401 self.orig_loc,
4402 self.buf.as_ptr() as usize,
4403 ))
4404 }
4405 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
4406 let mut iter = self.clone();
4407 iter.pos = 0;
4408 for attr in iter {
4409 if let OpGetrouteDoReply::EncapType(val) = attr? {
4410 return Ok(val);
4411 }
4412 }
4413 Err(ErrorContext::new_missing(
4414 "OpGetrouteDoReply",
4415 "EncapType",
4416 self.orig_loc,
4417 self.buf.as_ptr() as usize,
4418 ))
4419 }
4420 pub fn get_encap(&self) -> Result<&'a [u8], ErrorContext> {
4421 let mut iter = self.clone();
4422 iter.pos = 0;
4423 for attr in iter {
4424 if let OpGetrouteDoReply::Encap(val) = attr? {
4425 return Ok(val);
4426 }
4427 }
4428 Err(ErrorContext::new_missing(
4429 "OpGetrouteDoReply",
4430 "Encap",
4431 self.orig_loc,
4432 self.buf.as_ptr() as usize,
4433 ))
4434 }
4435 pub fn get_expires(&self) -> Result<u32, ErrorContext> {
4436 let mut iter = self.clone();
4437 iter.pos = 0;
4438 for attr in iter {
4439 if let OpGetrouteDoReply::Expires(val) = attr? {
4440 return Ok(val);
4441 }
4442 }
4443 Err(ErrorContext::new_missing(
4444 "OpGetrouteDoReply",
4445 "Expires",
4446 self.orig_loc,
4447 self.buf.as_ptr() as usize,
4448 ))
4449 }
4450 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
4451 let mut iter = self.clone();
4452 iter.pos = 0;
4453 for attr in iter {
4454 if let OpGetrouteDoReply::Pad(val) = attr? {
4455 return Ok(val);
4456 }
4457 }
4458 Err(ErrorContext::new_missing(
4459 "OpGetrouteDoReply",
4460 "Pad",
4461 self.orig_loc,
4462 self.buf.as_ptr() as usize,
4463 ))
4464 }
4465 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
4466 let mut iter = self.clone();
4467 iter.pos = 0;
4468 for attr in iter {
4469 if let OpGetrouteDoReply::Uid(val) = attr? {
4470 return Ok(val);
4471 }
4472 }
4473 Err(ErrorContext::new_missing(
4474 "OpGetrouteDoReply",
4475 "Uid",
4476 self.orig_loc,
4477 self.buf.as_ptr() as usize,
4478 ))
4479 }
4480 pub fn get_ttl_propagate(&self) -> Result<u8, ErrorContext> {
4481 let mut iter = self.clone();
4482 iter.pos = 0;
4483 for attr in iter {
4484 if let OpGetrouteDoReply::TtlPropagate(val) = attr? {
4485 return Ok(val);
4486 }
4487 }
4488 Err(ErrorContext::new_missing(
4489 "OpGetrouteDoReply",
4490 "TtlPropagate",
4491 self.orig_loc,
4492 self.buf.as_ptr() as usize,
4493 ))
4494 }
4495 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
4496 let mut iter = self.clone();
4497 iter.pos = 0;
4498 for attr in iter {
4499 if let OpGetrouteDoReply::IpProto(val) = attr? {
4500 return Ok(val);
4501 }
4502 }
4503 Err(ErrorContext::new_missing(
4504 "OpGetrouteDoReply",
4505 "IpProto",
4506 self.orig_loc,
4507 self.buf.as_ptr() as usize,
4508 ))
4509 }
4510 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
4511 let mut iter = self.clone();
4512 iter.pos = 0;
4513 for attr in iter {
4514 if let OpGetrouteDoReply::Sport(val) = attr? {
4515 return Ok(val);
4516 }
4517 }
4518 Err(ErrorContext::new_missing(
4519 "OpGetrouteDoReply",
4520 "Sport",
4521 self.orig_loc,
4522 self.buf.as_ptr() as usize,
4523 ))
4524 }
4525 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
4526 let mut iter = self.clone();
4527 iter.pos = 0;
4528 for attr in iter {
4529 if let OpGetrouteDoReply::Dport(val) = attr? {
4530 return Ok(val);
4531 }
4532 }
4533 Err(ErrorContext::new_missing(
4534 "OpGetrouteDoReply",
4535 "Dport",
4536 self.orig_loc,
4537 self.buf.as_ptr() as usize,
4538 ))
4539 }
4540 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
4541 let mut iter = self.clone();
4542 iter.pos = 0;
4543 for attr in iter {
4544 if let OpGetrouteDoReply::NhId(val) = attr? {
4545 return Ok(val);
4546 }
4547 }
4548 Err(ErrorContext::new_missing(
4549 "OpGetrouteDoReply",
4550 "NhId",
4551 self.orig_loc,
4552 self.buf.as_ptr() as usize,
4553 ))
4554 }
4555 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
4556 let mut iter = self.clone();
4557 iter.pos = 0;
4558 for attr in iter {
4559 if let OpGetrouteDoReply::Flowlabel(val) = attr? {
4560 return Ok(val);
4561 }
4562 }
4563 Err(ErrorContext::new_missing(
4564 "OpGetrouteDoReply",
4565 "Flowlabel",
4566 self.orig_loc,
4567 self.buf.as_ptr() as usize,
4568 ))
4569 }
4570}
4571impl<'a> OpGetrouteDoReply<'a> {
4572 pub fn new(buf: &'a [u8]) -> (PushRtmsg, IterableOpGetrouteDoReply<'a>) {
4573 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
4574 (
4575 PushRtmsg::new_from_slice(header).unwrap_or_default(),
4576 IterableOpGetrouteDoReply::with_loc(attrs, buf.as_ptr() as usize),
4577 )
4578 }
4579 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4580 RouteAttrs::attr_from_type(r#type)
4581 }
4582}
4583#[derive(Clone, Copy, Default)]
4584pub struct IterableOpGetrouteDoReply<'a> {
4585 buf: &'a [u8],
4586 pos: usize,
4587 orig_loc: usize,
4588}
4589impl<'a> IterableOpGetrouteDoReply<'a> {
4590 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4591 Self {
4592 buf,
4593 pos: 0,
4594 orig_loc,
4595 }
4596 }
4597 pub fn get_buf(&self) -> &'a [u8] {
4598 self.buf
4599 }
4600}
4601impl<'a> Iterator for IterableOpGetrouteDoReply<'a> {
4602 type Item = Result<OpGetrouteDoReply<'a>, ErrorContext>;
4603 fn next(&mut self) -> Option<Self::Item> {
4604 if self.buf.len() == self.pos {
4605 return None;
4606 }
4607 let pos = self.pos;
4608 let mut r#type = None;
4609 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
4610 r#type = Some(header.r#type);
4611 let res = match header.r#type {
4612 1u16 => OpGetrouteDoReply::Dst({
4613 let res = Some(next);
4614 let Some(val) = res else { break };
4615 val
4616 }),
4617 2u16 => OpGetrouteDoReply::Src({
4618 let res = Some(next);
4619 let Some(val) = res else { break };
4620 val
4621 }),
4622 3u16 => OpGetrouteDoReply::Iif({
4623 let res = parse_u32(next);
4624 let Some(val) = res else { break };
4625 val
4626 }),
4627 4u16 => OpGetrouteDoReply::Oif({
4628 let res = parse_u32(next);
4629 let Some(val) = res else { break };
4630 val
4631 }),
4632 5u16 => OpGetrouteDoReply::Gateway({
4633 let res = Some(next);
4634 let Some(val) = res else { break };
4635 val
4636 }),
4637 6u16 => OpGetrouteDoReply::Priority({
4638 let res = parse_u32(next);
4639 let Some(val) = res else { break };
4640 val
4641 }),
4642 7u16 => OpGetrouteDoReply::Prefsrc({
4643 let res = Some(next);
4644 let Some(val) = res else { break };
4645 val
4646 }),
4647 8u16 => OpGetrouteDoReply::Metrics({
4648 let res = Some(IterableMetrics::with_loc(next, self.orig_loc));
4649 let Some(val) = res else { break };
4650 val
4651 }),
4652 9u16 => OpGetrouteDoReply::Multipath({
4653 let res = Some(next);
4654 let Some(val) = res else { break };
4655 val
4656 }),
4657 11u16 => OpGetrouteDoReply::Flow({
4658 let res = parse_u32(next);
4659 let Some(val) = res else { break };
4660 val
4661 }),
4662 12u16 => OpGetrouteDoReply::Cacheinfo({
4663 let res = PushRtaCacheinfo::new_from_slice(next);
4664 let Some(val) = res else { break };
4665 val
4666 }),
4667 15u16 => OpGetrouteDoReply::Table({
4668 let res = parse_u32(next);
4669 let Some(val) = res else { break };
4670 val
4671 }),
4672 16u16 => OpGetrouteDoReply::Mark({
4673 let res = parse_u32(next);
4674 let Some(val) = res else { break };
4675 val
4676 }),
4677 17u16 => OpGetrouteDoReply::MfcStats({
4678 let res = Some(next);
4679 let Some(val) = res else { break };
4680 val
4681 }),
4682 18u16 => OpGetrouteDoReply::Via({
4683 let res = Some(next);
4684 let Some(val) = res else { break };
4685 val
4686 }),
4687 19u16 => OpGetrouteDoReply::Newdst({
4688 let res = Some(next);
4689 let Some(val) = res else { break };
4690 val
4691 }),
4692 20u16 => OpGetrouteDoReply::Pref({
4693 let res = parse_u8(next);
4694 let Some(val) = res else { break };
4695 val
4696 }),
4697 21u16 => OpGetrouteDoReply::EncapType({
4698 let res = parse_u16(next);
4699 let Some(val) = res else { break };
4700 val
4701 }),
4702 22u16 => OpGetrouteDoReply::Encap({
4703 let res = Some(next);
4704 let Some(val) = res else { break };
4705 val
4706 }),
4707 23u16 => OpGetrouteDoReply::Expires({
4708 let res = parse_u32(next);
4709 let Some(val) = res else { break };
4710 val
4711 }),
4712 24u16 => OpGetrouteDoReply::Pad({
4713 let res = Some(next);
4714 let Some(val) = res else { break };
4715 val
4716 }),
4717 25u16 => OpGetrouteDoReply::Uid({
4718 let res = parse_u32(next);
4719 let Some(val) = res else { break };
4720 val
4721 }),
4722 26u16 => OpGetrouteDoReply::TtlPropagate({
4723 let res = parse_u8(next);
4724 let Some(val) = res else { break };
4725 val
4726 }),
4727 27u16 => OpGetrouteDoReply::IpProto({
4728 let res = parse_u8(next);
4729 let Some(val) = res else { break };
4730 val
4731 }),
4732 28u16 => OpGetrouteDoReply::Sport({
4733 let res = parse_u16(next);
4734 let Some(val) = res else { break };
4735 val
4736 }),
4737 29u16 => OpGetrouteDoReply::Dport({
4738 let res = parse_u16(next);
4739 let Some(val) = res else { break };
4740 val
4741 }),
4742 30u16 => OpGetrouteDoReply::NhId({
4743 let res = parse_u32(next);
4744 let Some(val) = res else { break };
4745 val
4746 }),
4747 31u16 => OpGetrouteDoReply::Flowlabel({
4748 let res = parse_be_u32(next);
4749 let Some(val) = res else { break };
4750 val
4751 }),
4752 n => {
4753 if cfg!(any(test, feature = "deny-unknown-attrs")) {
4754 break;
4755 } else {
4756 continue;
4757 }
4758 }
4759 };
4760 return Some(Ok(res));
4761 }
4762 Some(Err(ErrorContext::new(
4763 "OpGetrouteDoReply",
4764 r#type.and_then(|t| OpGetrouteDoReply::attr_from_type(t)),
4765 self.orig_loc,
4766 self.buf.as_ptr().wrapping_add(pos) as usize,
4767 )))
4768 }
4769}
4770impl<'a> std::fmt::Debug for IterableOpGetrouteDoReply<'_> {
4771 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4772 let mut fmt = f.debug_struct("OpGetrouteDoReply");
4773 for attr in self.clone() {
4774 let attr = match attr {
4775 Ok(a) => a,
4776 Err(err) => {
4777 fmt.finish()?;
4778 f.write_str("Err(")?;
4779 err.fmt(f)?;
4780 return f.write_str(")");
4781 }
4782 };
4783 match attr {
4784 OpGetrouteDoReply::Dst(val) => fmt.field("Dst", &val),
4785 OpGetrouteDoReply::Src(val) => fmt.field("Src", &val),
4786 OpGetrouteDoReply::Iif(val) => fmt.field("Iif", &val),
4787 OpGetrouteDoReply::Oif(val) => fmt.field("Oif", &val),
4788 OpGetrouteDoReply::Gateway(val) => fmt.field("Gateway", &val),
4789 OpGetrouteDoReply::Priority(val) => fmt.field("Priority", &val),
4790 OpGetrouteDoReply::Prefsrc(val) => fmt.field("Prefsrc", &val),
4791 OpGetrouteDoReply::Metrics(val) => fmt.field("Metrics", &val),
4792 OpGetrouteDoReply::Multipath(val) => fmt.field("Multipath", &val),
4793 OpGetrouteDoReply::Flow(val) => fmt.field("Flow", &val),
4794 OpGetrouteDoReply::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
4795 OpGetrouteDoReply::Table(val) => fmt.field("Table", &val),
4796 OpGetrouteDoReply::Mark(val) => fmt.field("Mark", &val),
4797 OpGetrouteDoReply::MfcStats(val) => fmt.field("MfcStats", &val),
4798 OpGetrouteDoReply::Via(val) => fmt.field("Via", &val),
4799 OpGetrouteDoReply::Newdst(val) => fmt.field("Newdst", &val),
4800 OpGetrouteDoReply::Pref(val) => fmt.field("Pref", &val),
4801 OpGetrouteDoReply::EncapType(val) => fmt.field("EncapType", &val),
4802 OpGetrouteDoReply::Encap(val) => fmt.field("Encap", &val),
4803 OpGetrouteDoReply::Expires(val) => fmt.field("Expires", &val),
4804 OpGetrouteDoReply::Pad(val) => fmt.field("Pad", &val),
4805 OpGetrouteDoReply::Uid(val) => fmt.field("Uid", &val),
4806 OpGetrouteDoReply::TtlPropagate(val) => fmt.field("TtlPropagate", &val),
4807 OpGetrouteDoReply::IpProto(val) => fmt.field("IpProto", &val),
4808 OpGetrouteDoReply::Sport(val) => fmt.field("Sport", &val),
4809 OpGetrouteDoReply::Dport(val) => fmt.field("Dport", &val),
4810 OpGetrouteDoReply::NhId(val) => fmt.field("NhId", &val),
4811 OpGetrouteDoReply::Flowlabel(val) => fmt.field("Flowlabel", &val),
4812 };
4813 }
4814 fmt.finish()
4815 }
4816}
4817impl IterableOpGetrouteDoReply<'_> {
4818 pub fn lookup_attr(
4819 &self,
4820 offset: usize,
4821 missing_type: Option<u16>,
4822 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4823 let mut stack = Vec::new();
4824 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4825 if cur == offset + PushRtmsg::len() {
4826 stack.push(("OpGetrouteDoReply", offset));
4827 return (
4828 stack,
4829 missing_type.and_then(|t| OpGetrouteDoReply::attr_from_type(t)),
4830 );
4831 }
4832 if cur > offset || cur + self.buf.len() < offset {
4833 return (stack, None);
4834 }
4835 let mut attrs = self.clone();
4836 let mut last_off = cur + attrs.pos;
4837 let mut missing = None;
4838 while let Some(attr) = attrs.next() {
4839 let Ok(attr) = attr else { break };
4840 match attr {
4841 OpGetrouteDoReply::Dst(val) => {
4842 if last_off == offset {
4843 stack.push(("Dst", last_off));
4844 break;
4845 }
4846 }
4847 OpGetrouteDoReply::Src(val) => {
4848 if last_off == offset {
4849 stack.push(("Src", last_off));
4850 break;
4851 }
4852 }
4853 OpGetrouteDoReply::Iif(val) => {
4854 if last_off == offset {
4855 stack.push(("Iif", last_off));
4856 break;
4857 }
4858 }
4859 OpGetrouteDoReply::Oif(val) => {
4860 if last_off == offset {
4861 stack.push(("Oif", last_off));
4862 break;
4863 }
4864 }
4865 OpGetrouteDoReply::Gateway(val) => {
4866 if last_off == offset {
4867 stack.push(("Gateway", last_off));
4868 break;
4869 }
4870 }
4871 OpGetrouteDoReply::Priority(val) => {
4872 if last_off == offset {
4873 stack.push(("Priority", last_off));
4874 break;
4875 }
4876 }
4877 OpGetrouteDoReply::Prefsrc(val) => {
4878 if last_off == offset {
4879 stack.push(("Prefsrc", last_off));
4880 break;
4881 }
4882 }
4883 OpGetrouteDoReply::Metrics(val) => {
4884 (stack, missing) = val.lookup_attr(offset, missing_type);
4885 if !stack.is_empty() {
4886 break;
4887 }
4888 }
4889 OpGetrouteDoReply::Multipath(val) => {
4890 if last_off == offset {
4891 stack.push(("Multipath", last_off));
4892 break;
4893 }
4894 }
4895 OpGetrouteDoReply::Flow(val) => {
4896 if last_off == offset {
4897 stack.push(("Flow", last_off));
4898 break;
4899 }
4900 }
4901 OpGetrouteDoReply::Cacheinfo(val) => {
4902 if last_off == offset {
4903 stack.push(("Cacheinfo", last_off));
4904 break;
4905 }
4906 }
4907 OpGetrouteDoReply::Table(val) => {
4908 if last_off == offset {
4909 stack.push(("Table", last_off));
4910 break;
4911 }
4912 }
4913 OpGetrouteDoReply::Mark(val) => {
4914 if last_off == offset {
4915 stack.push(("Mark", last_off));
4916 break;
4917 }
4918 }
4919 OpGetrouteDoReply::MfcStats(val) => {
4920 if last_off == offset {
4921 stack.push(("MfcStats", last_off));
4922 break;
4923 }
4924 }
4925 OpGetrouteDoReply::Via(val) => {
4926 if last_off == offset {
4927 stack.push(("Via", last_off));
4928 break;
4929 }
4930 }
4931 OpGetrouteDoReply::Newdst(val) => {
4932 if last_off == offset {
4933 stack.push(("Newdst", last_off));
4934 break;
4935 }
4936 }
4937 OpGetrouteDoReply::Pref(val) => {
4938 if last_off == offset {
4939 stack.push(("Pref", last_off));
4940 break;
4941 }
4942 }
4943 OpGetrouteDoReply::EncapType(val) => {
4944 if last_off == offset {
4945 stack.push(("EncapType", last_off));
4946 break;
4947 }
4948 }
4949 OpGetrouteDoReply::Encap(val) => {
4950 if last_off == offset {
4951 stack.push(("Encap", last_off));
4952 break;
4953 }
4954 }
4955 OpGetrouteDoReply::Expires(val) => {
4956 if last_off == offset {
4957 stack.push(("Expires", last_off));
4958 break;
4959 }
4960 }
4961 OpGetrouteDoReply::Pad(val) => {
4962 if last_off == offset {
4963 stack.push(("Pad", last_off));
4964 break;
4965 }
4966 }
4967 OpGetrouteDoReply::Uid(val) => {
4968 if last_off == offset {
4969 stack.push(("Uid", last_off));
4970 break;
4971 }
4972 }
4973 OpGetrouteDoReply::TtlPropagate(val) => {
4974 if last_off == offset {
4975 stack.push(("TtlPropagate", last_off));
4976 break;
4977 }
4978 }
4979 OpGetrouteDoReply::IpProto(val) => {
4980 if last_off == offset {
4981 stack.push(("IpProto", last_off));
4982 break;
4983 }
4984 }
4985 OpGetrouteDoReply::Sport(val) => {
4986 if last_off == offset {
4987 stack.push(("Sport", last_off));
4988 break;
4989 }
4990 }
4991 OpGetrouteDoReply::Dport(val) => {
4992 if last_off == offset {
4993 stack.push(("Dport", last_off));
4994 break;
4995 }
4996 }
4997 OpGetrouteDoReply::NhId(val) => {
4998 if last_off == offset {
4999 stack.push(("NhId", last_off));
5000 break;
5001 }
5002 }
5003 OpGetrouteDoReply::Flowlabel(val) => {
5004 if last_off == offset {
5005 stack.push(("Flowlabel", last_off));
5006 break;
5007 }
5008 }
5009 _ => {}
5010 };
5011 last_off = cur + attrs.pos;
5012 }
5013 if !stack.is_empty() {
5014 stack.push(("OpGetrouteDoReply", cur));
5015 }
5016 (stack, missing)
5017 }
5018}
5019#[derive(Debug)]
5020pub struct RequestOpGetrouteDoRequest<'r> {
5021 request: Request<'r>,
5022}
5023impl<'r> RequestOpGetrouteDoRequest<'r> {
5024 pub fn new(mut request: Request<'r>, header: &PushRtmsg) -> Self {
5025 PushOpGetrouteDoRequest::write_header(&mut request.buf_mut(), header);
5026 Self { request: request }
5027 }
5028 pub fn encode(&mut self) -> PushOpGetrouteDoRequest<&mut Vec<u8>> {
5029 PushOpGetrouteDoRequest::new_without_header(self.request.buf_mut())
5030 }
5031 pub fn into_encoder(self) -> PushOpGetrouteDoRequest<RequestBuf<'r>> {
5032 PushOpGetrouteDoRequest::new_without_header(self.request.buf)
5033 }
5034}
5035impl NetlinkRequest for RequestOpGetrouteDoRequest<'_> {
5036 type ReplyType<'buf> = (PushRtmsg, IterableOpGetrouteDoReply<'buf>);
5037 fn protocol(&self) -> Protocol {
5038 Protocol::Raw {
5039 protonum: 0u16,
5040 request_type: 26u16,
5041 }
5042 }
5043 fn flags(&self) -> u16 {
5044 self.request.flags
5045 }
5046 fn payload(&self) -> &[u8] {
5047 self.request.buf()
5048 }
5049 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5050 OpGetrouteDoReply::new(buf)
5051 }
5052 fn lookup(
5053 buf: &[u8],
5054 offset: usize,
5055 missing_type: Option<u16>,
5056 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5057 OpGetrouteDoRequest::new(buf)
5058 .1
5059 .lookup_attr(offset, missing_type)
5060 }
5061}
5062#[doc = "Create a new route"]
5063pub struct PushOpNewrouteDoRequest<Prev: Rec> {
5064 pub(crate) prev: Option<Prev>,
5065 pub(crate) header_offset: Option<usize>,
5066}
5067impl<Prev: Rec> Rec for PushOpNewrouteDoRequest<Prev> {
5068 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
5069 self.prev.as_mut().unwrap().as_rec_mut()
5070 }
5071}
5072impl<Prev: Rec> PushOpNewrouteDoRequest<Prev> {
5073 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
5074 Self::write_header(&mut prev, header);
5075 Self::new_without_header(prev)
5076 }
5077 fn new_without_header(prev: Prev) -> Self {
5078 Self {
5079 prev: Some(prev),
5080 header_offset: None,
5081 }
5082 }
5083 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
5084 prev.as_rec_mut().extend(header.as_slice());
5085 }
5086 pub fn end_nested(mut self) -> Prev {
5087 let mut prev = self.prev.take().unwrap();
5088 if let Some(header_offset) = &self.header_offset {
5089 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5090 }
5091 prev
5092 }
5093 pub fn push_dst(mut self, value: &[u8]) -> Self {
5094 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
5095 self.as_rec_mut().extend(value);
5096 self
5097 }
5098 pub fn push_src(mut self, value: &[u8]) -> Self {
5099 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
5100 self.as_rec_mut().extend(value);
5101 self
5102 }
5103 pub fn push_iif(mut self, value: u32) -> Self {
5104 push_header(self.as_rec_mut(), 3u16, 4 as u16);
5105 self.as_rec_mut().extend(value.to_ne_bytes());
5106 self
5107 }
5108 pub fn push_oif(mut self, value: u32) -> Self {
5109 push_header(self.as_rec_mut(), 4u16, 4 as u16);
5110 self.as_rec_mut().extend(value.to_ne_bytes());
5111 self
5112 }
5113 pub fn push_gateway(mut self, value: &[u8]) -> Self {
5114 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
5115 self.as_rec_mut().extend(value);
5116 self
5117 }
5118 pub fn push_priority(mut self, value: u32) -> Self {
5119 push_header(self.as_rec_mut(), 6u16, 4 as u16);
5120 self.as_rec_mut().extend(value.to_ne_bytes());
5121 self
5122 }
5123 pub fn push_prefsrc(mut self, value: &[u8]) -> Self {
5124 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
5125 self.as_rec_mut().extend(value);
5126 self
5127 }
5128 pub fn nested_metrics(mut self) -> PushMetrics<Self> {
5129 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
5130 PushMetrics {
5131 prev: Some(self),
5132 header_offset: Some(header_offset),
5133 }
5134 }
5135 pub fn push_multipath(mut self, value: &[u8]) -> Self {
5136 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
5137 self.as_rec_mut().extend(value);
5138 self
5139 }
5140 pub fn push_flow(mut self, value: u32) -> Self {
5141 push_header(self.as_rec_mut(), 11u16, 4 as u16);
5142 self.as_rec_mut().extend(value.to_ne_bytes());
5143 self
5144 }
5145 pub fn push_cacheinfo(mut self, value: PushRtaCacheinfo) -> Self {
5146 push_header(self.as_rec_mut(), 12u16, value.as_slice().len() as u16);
5147 self.as_rec_mut().extend(value.as_slice());
5148 self
5149 }
5150 pub fn push_table(mut self, value: u32) -> Self {
5151 push_header(self.as_rec_mut(), 15u16, 4 as u16);
5152 self.as_rec_mut().extend(value.to_ne_bytes());
5153 self
5154 }
5155 pub fn push_mark(mut self, value: u32) -> Self {
5156 push_header(self.as_rec_mut(), 16u16, 4 as u16);
5157 self.as_rec_mut().extend(value.to_ne_bytes());
5158 self
5159 }
5160 pub fn push_mfc_stats(mut self, value: &[u8]) -> Self {
5161 push_header(self.as_rec_mut(), 17u16, value.len() as u16);
5162 self.as_rec_mut().extend(value);
5163 self
5164 }
5165 pub fn push_via(mut self, value: &[u8]) -> Self {
5166 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
5167 self.as_rec_mut().extend(value);
5168 self
5169 }
5170 pub fn push_newdst(mut self, value: &[u8]) -> Self {
5171 push_header(self.as_rec_mut(), 19u16, value.len() as u16);
5172 self.as_rec_mut().extend(value);
5173 self
5174 }
5175 pub fn push_pref(mut self, value: u8) -> Self {
5176 push_header(self.as_rec_mut(), 20u16, 1 as u16);
5177 self.as_rec_mut().extend(value.to_ne_bytes());
5178 self
5179 }
5180 pub fn push_encap_type(mut self, value: u16) -> Self {
5181 push_header(self.as_rec_mut(), 21u16, 2 as u16);
5182 self.as_rec_mut().extend(value.to_ne_bytes());
5183 self
5184 }
5185 pub fn push_encap(mut self, value: &[u8]) -> Self {
5186 push_header(self.as_rec_mut(), 22u16, value.len() as u16);
5187 self.as_rec_mut().extend(value);
5188 self
5189 }
5190 pub fn push_expires(mut self, value: u32) -> Self {
5191 push_header(self.as_rec_mut(), 23u16, 4 as u16);
5192 self.as_rec_mut().extend(value.to_ne_bytes());
5193 self
5194 }
5195 pub fn push_pad(mut self, value: &[u8]) -> Self {
5196 push_header(self.as_rec_mut(), 24u16, value.len() as u16);
5197 self.as_rec_mut().extend(value);
5198 self
5199 }
5200 pub fn push_uid(mut self, value: u32) -> Self {
5201 push_header(self.as_rec_mut(), 25u16, 4 as u16);
5202 self.as_rec_mut().extend(value.to_ne_bytes());
5203 self
5204 }
5205 pub fn push_ttl_propagate(mut self, value: u8) -> Self {
5206 push_header(self.as_rec_mut(), 26u16, 1 as u16);
5207 self.as_rec_mut().extend(value.to_ne_bytes());
5208 self
5209 }
5210 pub fn push_ip_proto(mut self, value: u8) -> Self {
5211 push_header(self.as_rec_mut(), 27u16, 1 as u16);
5212 self.as_rec_mut().extend(value.to_ne_bytes());
5213 self
5214 }
5215 pub fn push_sport(mut self, value: u16) -> Self {
5216 push_header(self.as_rec_mut(), 28u16, 2 as u16);
5217 self.as_rec_mut().extend(value.to_ne_bytes());
5218 self
5219 }
5220 pub fn push_dport(mut self, value: u16) -> Self {
5221 push_header(self.as_rec_mut(), 29u16, 2 as u16);
5222 self.as_rec_mut().extend(value.to_ne_bytes());
5223 self
5224 }
5225 pub fn push_nh_id(mut self, value: u32) -> Self {
5226 push_header(self.as_rec_mut(), 30u16, 4 as u16);
5227 self.as_rec_mut().extend(value.to_ne_bytes());
5228 self
5229 }
5230 pub fn push_flowlabel(mut self, value: u32) -> Self {
5231 push_header(self.as_rec_mut(), 31u16, 4 as u16);
5232 self.as_rec_mut().extend(value.to_be_bytes());
5233 self
5234 }
5235}
5236impl<Prev: Rec> Drop for PushOpNewrouteDoRequest<Prev> {
5237 fn drop(&mut self) {
5238 if let Some(prev) = &mut self.prev {
5239 if let Some(header_offset) = &self.header_offset {
5240 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5241 }
5242 }
5243 }
5244}
5245#[doc = "Create a new route"]
5246#[derive(Clone)]
5247pub enum OpNewrouteDoRequest<'a> {
5248 Dst(&'a [u8]),
5249 Src(&'a [u8]),
5250 Iif(u32),
5251 Oif(u32),
5252 Gateway(&'a [u8]),
5253 Priority(u32),
5254 Prefsrc(&'a [u8]),
5255 Metrics(IterableMetrics<'a>),
5256 Multipath(&'a [u8]),
5257 Flow(u32),
5258 Cacheinfo(PushRtaCacheinfo),
5259 Table(u32),
5260 Mark(u32),
5261 MfcStats(&'a [u8]),
5262 Via(&'a [u8]),
5263 Newdst(&'a [u8]),
5264 Pref(u8),
5265 EncapType(u16),
5266 Encap(&'a [u8]),
5267 Expires(u32),
5268 Pad(&'a [u8]),
5269 Uid(u32),
5270 TtlPropagate(u8),
5271 IpProto(u8),
5272 Sport(u16),
5273 Dport(u16),
5274 NhId(u32),
5275 Flowlabel(u32),
5276}
5277impl<'a> IterableOpNewrouteDoRequest<'a> {
5278 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
5279 let mut iter = self.clone();
5280 iter.pos = 0;
5281 for attr in iter {
5282 if let OpNewrouteDoRequest::Dst(val) = attr? {
5283 return Ok(val);
5284 }
5285 }
5286 Err(ErrorContext::new_missing(
5287 "OpNewrouteDoRequest",
5288 "Dst",
5289 self.orig_loc,
5290 self.buf.as_ptr() as usize,
5291 ))
5292 }
5293 pub fn get_src(&self) -> Result<&'a [u8], ErrorContext> {
5294 let mut iter = self.clone();
5295 iter.pos = 0;
5296 for attr in iter {
5297 if let OpNewrouteDoRequest::Src(val) = attr? {
5298 return Ok(val);
5299 }
5300 }
5301 Err(ErrorContext::new_missing(
5302 "OpNewrouteDoRequest",
5303 "Src",
5304 self.orig_loc,
5305 self.buf.as_ptr() as usize,
5306 ))
5307 }
5308 pub fn get_iif(&self) -> Result<u32, ErrorContext> {
5309 let mut iter = self.clone();
5310 iter.pos = 0;
5311 for attr in iter {
5312 if let OpNewrouteDoRequest::Iif(val) = attr? {
5313 return Ok(val);
5314 }
5315 }
5316 Err(ErrorContext::new_missing(
5317 "OpNewrouteDoRequest",
5318 "Iif",
5319 self.orig_loc,
5320 self.buf.as_ptr() as usize,
5321 ))
5322 }
5323 pub fn get_oif(&self) -> Result<u32, ErrorContext> {
5324 let mut iter = self.clone();
5325 iter.pos = 0;
5326 for attr in iter {
5327 if let OpNewrouteDoRequest::Oif(val) = attr? {
5328 return Ok(val);
5329 }
5330 }
5331 Err(ErrorContext::new_missing(
5332 "OpNewrouteDoRequest",
5333 "Oif",
5334 self.orig_loc,
5335 self.buf.as_ptr() as usize,
5336 ))
5337 }
5338 pub fn get_gateway(&self) -> Result<&'a [u8], ErrorContext> {
5339 let mut iter = self.clone();
5340 iter.pos = 0;
5341 for attr in iter {
5342 if let OpNewrouteDoRequest::Gateway(val) = attr? {
5343 return Ok(val);
5344 }
5345 }
5346 Err(ErrorContext::new_missing(
5347 "OpNewrouteDoRequest",
5348 "Gateway",
5349 self.orig_loc,
5350 self.buf.as_ptr() as usize,
5351 ))
5352 }
5353 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
5354 let mut iter = self.clone();
5355 iter.pos = 0;
5356 for attr in iter {
5357 if let OpNewrouteDoRequest::Priority(val) = attr? {
5358 return Ok(val);
5359 }
5360 }
5361 Err(ErrorContext::new_missing(
5362 "OpNewrouteDoRequest",
5363 "Priority",
5364 self.orig_loc,
5365 self.buf.as_ptr() as usize,
5366 ))
5367 }
5368 pub fn get_prefsrc(&self) -> Result<&'a [u8], ErrorContext> {
5369 let mut iter = self.clone();
5370 iter.pos = 0;
5371 for attr in iter {
5372 if let OpNewrouteDoRequest::Prefsrc(val) = attr? {
5373 return Ok(val);
5374 }
5375 }
5376 Err(ErrorContext::new_missing(
5377 "OpNewrouteDoRequest",
5378 "Prefsrc",
5379 self.orig_loc,
5380 self.buf.as_ptr() as usize,
5381 ))
5382 }
5383 pub fn get_metrics(&self) -> Result<IterableMetrics<'a>, ErrorContext> {
5384 let mut iter = self.clone();
5385 iter.pos = 0;
5386 for attr in iter {
5387 if let OpNewrouteDoRequest::Metrics(val) = attr? {
5388 return Ok(val);
5389 }
5390 }
5391 Err(ErrorContext::new_missing(
5392 "OpNewrouteDoRequest",
5393 "Metrics",
5394 self.orig_loc,
5395 self.buf.as_ptr() as usize,
5396 ))
5397 }
5398 pub fn get_multipath(&self) -> Result<&'a [u8], ErrorContext> {
5399 let mut iter = self.clone();
5400 iter.pos = 0;
5401 for attr in iter {
5402 if let OpNewrouteDoRequest::Multipath(val) = attr? {
5403 return Ok(val);
5404 }
5405 }
5406 Err(ErrorContext::new_missing(
5407 "OpNewrouteDoRequest",
5408 "Multipath",
5409 self.orig_loc,
5410 self.buf.as_ptr() as usize,
5411 ))
5412 }
5413 pub fn get_flow(&self) -> Result<u32, ErrorContext> {
5414 let mut iter = self.clone();
5415 iter.pos = 0;
5416 for attr in iter {
5417 if let OpNewrouteDoRequest::Flow(val) = attr? {
5418 return Ok(val);
5419 }
5420 }
5421 Err(ErrorContext::new_missing(
5422 "OpNewrouteDoRequest",
5423 "Flow",
5424 self.orig_loc,
5425 self.buf.as_ptr() as usize,
5426 ))
5427 }
5428 pub fn get_cacheinfo(&self) -> Result<PushRtaCacheinfo, ErrorContext> {
5429 let mut iter = self.clone();
5430 iter.pos = 0;
5431 for attr in iter {
5432 if let OpNewrouteDoRequest::Cacheinfo(val) = attr? {
5433 return Ok(val);
5434 }
5435 }
5436 Err(ErrorContext::new_missing(
5437 "OpNewrouteDoRequest",
5438 "Cacheinfo",
5439 self.orig_loc,
5440 self.buf.as_ptr() as usize,
5441 ))
5442 }
5443 pub fn get_table(&self) -> Result<u32, ErrorContext> {
5444 let mut iter = self.clone();
5445 iter.pos = 0;
5446 for attr in iter {
5447 if let OpNewrouteDoRequest::Table(val) = attr? {
5448 return Ok(val);
5449 }
5450 }
5451 Err(ErrorContext::new_missing(
5452 "OpNewrouteDoRequest",
5453 "Table",
5454 self.orig_loc,
5455 self.buf.as_ptr() as usize,
5456 ))
5457 }
5458 pub fn get_mark(&self) -> Result<u32, ErrorContext> {
5459 let mut iter = self.clone();
5460 iter.pos = 0;
5461 for attr in iter {
5462 if let OpNewrouteDoRequest::Mark(val) = attr? {
5463 return Ok(val);
5464 }
5465 }
5466 Err(ErrorContext::new_missing(
5467 "OpNewrouteDoRequest",
5468 "Mark",
5469 self.orig_loc,
5470 self.buf.as_ptr() as usize,
5471 ))
5472 }
5473 pub fn get_mfc_stats(&self) -> Result<&'a [u8], ErrorContext> {
5474 let mut iter = self.clone();
5475 iter.pos = 0;
5476 for attr in iter {
5477 if let OpNewrouteDoRequest::MfcStats(val) = attr? {
5478 return Ok(val);
5479 }
5480 }
5481 Err(ErrorContext::new_missing(
5482 "OpNewrouteDoRequest",
5483 "MfcStats",
5484 self.orig_loc,
5485 self.buf.as_ptr() as usize,
5486 ))
5487 }
5488 pub fn get_via(&self) -> Result<&'a [u8], ErrorContext> {
5489 let mut iter = self.clone();
5490 iter.pos = 0;
5491 for attr in iter {
5492 if let OpNewrouteDoRequest::Via(val) = attr? {
5493 return Ok(val);
5494 }
5495 }
5496 Err(ErrorContext::new_missing(
5497 "OpNewrouteDoRequest",
5498 "Via",
5499 self.orig_loc,
5500 self.buf.as_ptr() as usize,
5501 ))
5502 }
5503 pub fn get_newdst(&self) -> Result<&'a [u8], ErrorContext> {
5504 let mut iter = self.clone();
5505 iter.pos = 0;
5506 for attr in iter {
5507 if let OpNewrouteDoRequest::Newdst(val) = attr? {
5508 return Ok(val);
5509 }
5510 }
5511 Err(ErrorContext::new_missing(
5512 "OpNewrouteDoRequest",
5513 "Newdst",
5514 self.orig_loc,
5515 self.buf.as_ptr() as usize,
5516 ))
5517 }
5518 pub fn get_pref(&self) -> Result<u8, ErrorContext> {
5519 let mut iter = self.clone();
5520 iter.pos = 0;
5521 for attr in iter {
5522 if let OpNewrouteDoRequest::Pref(val) = attr? {
5523 return Ok(val);
5524 }
5525 }
5526 Err(ErrorContext::new_missing(
5527 "OpNewrouteDoRequest",
5528 "Pref",
5529 self.orig_loc,
5530 self.buf.as_ptr() as usize,
5531 ))
5532 }
5533 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
5534 let mut iter = self.clone();
5535 iter.pos = 0;
5536 for attr in iter {
5537 if let OpNewrouteDoRequest::EncapType(val) = attr? {
5538 return Ok(val);
5539 }
5540 }
5541 Err(ErrorContext::new_missing(
5542 "OpNewrouteDoRequest",
5543 "EncapType",
5544 self.orig_loc,
5545 self.buf.as_ptr() as usize,
5546 ))
5547 }
5548 pub fn get_encap(&self) -> Result<&'a [u8], ErrorContext> {
5549 let mut iter = self.clone();
5550 iter.pos = 0;
5551 for attr in iter {
5552 if let OpNewrouteDoRequest::Encap(val) = attr? {
5553 return Ok(val);
5554 }
5555 }
5556 Err(ErrorContext::new_missing(
5557 "OpNewrouteDoRequest",
5558 "Encap",
5559 self.orig_loc,
5560 self.buf.as_ptr() as usize,
5561 ))
5562 }
5563 pub fn get_expires(&self) -> Result<u32, ErrorContext> {
5564 let mut iter = self.clone();
5565 iter.pos = 0;
5566 for attr in iter {
5567 if let OpNewrouteDoRequest::Expires(val) = attr? {
5568 return Ok(val);
5569 }
5570 }
5571 Err(ErrorContext::new_missing(
5572 "OpNewrouteDoRequest",
5573 "Expires",
5574 self.orig_loc,
5575 self.buf.as_ptr() as usize,
5576 ))
5577 }
5578 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
5579 let mut iter = self.clone();
5580 iter.pos = 0;
5581 for attr in iter {
5582 if let OpNewrouteDoRequest::Pad(val) = attr? {
5583 return Ok(val);
5584 }
5585 }
5586 Err(ErrorContext::new_missing(
5587 "OpNewrouteDoRequest",
5588 "Pad",
5589 self.orig_loc,
5590 self.buf.as_ptr() as usize,
5591 ))
5592 }
5593 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
5594 let mut iter = self.clone();
5595 iter.pos = 0;
5596 for attr in iter {
5597 if let OpNewrouteDoRequest::Uid(val) = attr? {
5598 return Ok(val);
5599 }
5600 }
5601 Err(ErrorContext::new_missing(
5602 "OpNewrouteDoRequest",
5603 "Uid",
5604 self.orig_loc,
5605 self.buf.as_ptr() as usize,
5606 ))
5607 }
5608 pub fn get_ttl_propagate(&self) -> Result<u8, ErrorContext> {
5609 let mut iter = self.clone();
5610 iter.pos = 0;
5611 for attr in iter {
5612 if let OpNewrouteDoRequest::TtlPropagate(val) = attr? {
5613 return Ok(val);
5614 }
5615 }
5616 Err(ErrorContext::new_missing(
5617 "OpNewrouteDoRequest",
5618 "TtlPropagate",
5619 self.orig_loc,
5620 self.buf.as_ptr() as usize,
5621 ))
5622 }
5623 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
5624 let mut iter = self.clone();
5625 iter.pos = 0;
5626 for attr in iter {
5627 if let OpNewrouteDoRequest::IpProto(val) = attr? {
5628 return Ok(val);
5629 }
5630 }
5631 Err(ErrorContext::new_missing(
5632 "OpNewrouteDoRequest",
5633 "IpProto",
5634 self.orig_loc,
5635 self.buf.as_ptr() as usize,
5636 ))
5637 }
5638 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
5639 let mut iter = self.clone();
5640 iter.pos = 0;
5641 for attr in iter {
5642 if let OpNewrouteDoRequest::Sport(val) = attr? {
5643 return Ok(val);
5644 }
5645 }
5646 Err(ErrorContext::new_missing(
5647 "OpNewrouteDoRequest",
5648 "Sport",
5649 self.orig_loc,
5650 self.buf.as_ptr() as usize,
5651 ))
5652 }
5653 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
5654 let mut iter = self.clone();
5655 iter.pos = 0;
5656 for attr in iter {
5657 if let OpNewrouteDoRequest::Dport(val) = attr? {
5658 return Ok(val);
5659 }
5660 }
5661 Err(ErrorContext::new_missing(
5662 "OpNewrouteDoRequest",
5663 "Dport",
5664 self.orig_loc,
5665 self.buf.as_ptr() as usize,
5666 ))
5667 }
5668 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
5669 let mut iter = self.clone();
5670 iter.pos = 0;
5671 for attr in iter {
5672 if let OpNewrouteDoRequest::NhId(val) = attr? {
5673 return Ok(val);
5674 }
5675 }
5676 Err(ErrorContext::new_missing(
5677 "OpNewrouteDoRequest",
5678 "NhId",
5679 self.orig_loc,
5680 self.buf.as_ptr() as usize,
5681 ))
5682 }
5683 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
5684 let mut iter = self.clone();
5685 iter.pos = 0;
5686 for attr in iter {
5687 if let OpNewrouteDoRequest::Flowlabel(val) = attr? {
5688 return Ok(val);
5689 }
5690 }
5691 Err(ErrorContext::new_missing(
5692 "OpNewrouteDoRequest",
5693 "Flowlabel",
5694 self.orig_loc,
5695 self.buf.as_ptr() as usize,
5696 ))
5697 }
5698}
5699impl<'a> OpNewrouteDoRequest<'a> {
5700 pub fn new(buf: &'a [u8]) -> (PushRtmsg, IterableOpNewrouteDoRequest<'a>) {
5701 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
5702 (
5703 PushRtmsg::new_from_slice(header).unwrap_or_default(),
5704 IterableOpNewrouteDoRequest::with_loc(attrs, buf.as_ptr() as usize),
5705 )
5706 }
5707 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5708 RouteAttrs::attr_from_type(r#type)
5709 }
5710}
5711#[derive(Clone, Copy, Default)]
5712pub struct IterableOpNewrouteDoRequest<'a> {
5713 buf: &'a [u8],
5714 pos: usize,
5715 orig_loc: usize,
5716}
5717impl<'a> IterableOpNewrouteDoRequest<'a> {
5718 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5719 Self {
5720 buf,
5721 pos: 0,
5722 orig_loc,
5723 }
5724 }
5725 pub fn get_buf(&self) -> &'a [u8] {
5726 self.buf
5727 }
5728}
5729impl<'a> Iterator for IterableOpNewrouteDoRequest<'a> {
5730 type Item = Result<OpNewrouteDoRequest<'a>, ErrorContext>;
5731 fn next(&mut self) -> Option<Self::Item> {
5732 if self.buf.len() == self.pos {
5733 return None;
5734 }
5735 let pos = self.pos;
5736 let mut r#type = None;
5737 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
5738 r#type = Some(header.r#type);
5739 let res = match header.r#type {
5740 1u16 => OpNewrouteDoRequest::Dst({
5741 let res = Some(next);
5742 let Some(val) = res else { break };
5743 val
5744 }),
5745 2u16 => OpNewrouteDoRequest::Src({
5746 let res = Some(next);
5747 let Some(val) = res else { break };
5748 val
5749 }),
5750 3u16 => OpNewrouteDoRequest::Iif({
5751 let res = parse_u32(next);
5752 let Some(val) = res else { break };
5753 val
5754 }),
5755 4u16 => OpNewrouteDoRequest::Oif({
5756 let res = parse_u32(next);
5757 let Some(val) = res else { break };
5758 val
5759 }),
5760 5u16 => OpNewrouteDoRequest::Gateway({
5761 let res = Some(next);
5762 let Some(val) = res else { break };
5763 val
5764 }),
5765 6u16 => OpNewrouteDoRequest::Priority({
5766 let res = parse_u32(next);
5767 let Some(val) = res else { break };
5768 val
5769 }),
5770 7u16 => OpNewrouteDoRequest::Prefsrc({
5771 let res = Some(next);
5772 let Some(val) = res else { break };
5773 val
5774 }),
5775 8u16 => OpNewrouteDoRequest::Metrics({
5776 let res = Some(IterableMetrics::with_loc(next, self.orig_loc));
5777 let Some(val) = res else { break };
5778 val
5779 }),
5780 9u16 => OpNewrouteDoRequest::Multipath({
5781 let res = Some(next);
5782 let Some(val) = res else { break };
5783 val
5784 }),
5785 11u16 => OpNewrouteDoRequest::Flow({
5786 let res = parse_u32(next);
5787 let Some(val) = res else { break };
5788 val
5789 }),
5790 12u16 => OpNewrouteDoRequest::Cacheinfo({
5791 let res = PushRtaCacheinfo::new_from_slice(next);
5792 let Some(val) = res else { break };
5793 val
5794 }),
5795 15u16 => OpNewrouteDoRequest::Table({
5796 let res = parse_u32(next);
5797 let Some(val) = res else { break };
5798 val
5799 }),
5800 16u16 => OpNewrouteDoRequest::Mark({
5801 let res = parse_u32(next);
5802 let Some(val) = res else { break };
5803 val
5804 }),
5805 17u16 => OpNewrouteDoRequest::MfcStats({
5806 let res = Some(next);
5807 let Some(val) = res else { break };
5808 val
5809 }),
5810 18u16 => OpNewrouteDoRequest::Via({
5811 let res = Some(next);
5812 let Some(val) = res else { break };
5813 val
5814 }),
5815 19u16 => OpNewrouteDoRequest::Newdst({
5816 let res = Some(next);
5817 let Some(val) = res else { break };
5818 val
5819 }),
5820 20u16 => OpNewrouteDoRequest::Pref({
5821 let res = parse_u8(next);
5822 let Some(val) = res else { break };
5823 val
5824 }),
5825 21u16 => OpNewrouteDoRequest::EncapType({
5826 let res = parse_u16(next);
5827 let Some(val) = res else { break };
5828 val
5829 }),
5830 22u16 => OpNewrouteDoRequest::Encap({
5831 let res = Some(next);
5832 let Some(val) = res else { break };
5833 val
5834 }),
5835 23u16 => OpNewrouteDoRequest::Expires({
5836 let res = parse_u32(next);
5837 let Some(val) = res else { break };
5838 val
5839 }),
5840 24u16 => OpNewrouteDoRequest::Pad({
5841 let res = Some(next);
5842 let Some(val) = res else { break };
5843 val
5844 }),
5845 25u16 => OpNewrouteDoRequest::Uid({
5846 let res = parse_u32(next);
5847 let Some(val) = res else { break };
5848 val
5849 }),
5850 26u16 => OpNewrouteDoRequest::TtlPropagate({
5851 let res = parse_u8(next);
5852 let Some(val) = res else { break };
5853 val
5854 }),
5855 27u16 => OpNewrouteDoRequest::IpProto({
5856 let res = parse_u8(next);
5857 let Some(val) = res else { break };
5858 val
5859 }),
5860 28u16 => OpNewrouteDoRequest::Sport({
5861 let res = parse_u16(next);
5862 let Some(val) = res else { break };
5863 val
5864 }),
5865 29u16 => OpNewrouteDoRequest::Dport({
5866 let res = parse_u16(next);
5867 let Some(val) = res else { break };
5868 val
5869 }),
5870 30u16 => OpNewrouteDoRequest::NhId({
5871 let res = parse_u32(next);
5872 let Some(val) = res else { break };
5873 val
5874 }),
5875 31u16 => OpNewrouteDoRequest::Flowlabel({
5876 let res = parse_be_u32(next);
5877 let Some(val) = res else { break };
5878 val
5879 }),
5880 n => {
5881 if cfg!(any(test, feature = "deny-unknown-attrs")) {
5882 break;
5883 } else {
5884 continue;
5885 }
5886 }
5887 };
5888 return Some(Ok(res));
5889 }
5890 Some(Err(ErrorContext::new(
5891 "OpNewrouteDoRequest",
5892 r#type.and_then(|t| OpNewrouteDoRequest::attr_from_type(t)),
5893 self.orig_loc,
5894 self.buf.as_ptr().wrapping_add(pos) as usize,
5895 )))
5896 }
5897}
5898impl<'a> std::fmt::Debug for IterableOpNewrouteDoRequest<'_> {
5899 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5900 let mut fmt = f.debug_struct("OpNewrouteDoRequest");
5901 for attr in self.clone() {
5902 let attr = match attr {
5903 Ok(a) => a,
5904 Err(err) => {
5905 fmt.finish()?;
5906 f.write_str("Err(")?;
5907 err.fmt(f)?;
5908 return f.write_str(")");
5909 }
5910 };
5911 match attr {
5912 OpNewrouteDoRequest::Dst(val) => fmt.field("Dst", &val),
5913 OpNewrouteDoRequest::Src(val) => fmt.field("Src", &val),
5914 OpNewrouteDoRequest::Iif(val) => fmt.field("Iif", &val),
5915 OpNewrouteDoRequest::Oif(val) => fmt.field("Oif", &val),
5916 OpNewrouteDoRequest::Gateway(val) => fmt.field("Gateway", &val),
5917 OpNewrouteDoRequest::Priority(val) => fmt.field("Priority", &val),
5918 OpNewrouteDoRequest::Prefsrc(val) => fmt.field("Prefsrc", &val),
5919 OpNewrouteDoRequest::Metrics(val) => fmt.field("Metrics", &val),
5920 OpNewrouteDoRequest::Multipath(val) => fmt.field("Multipath", &val),
5921 OpNewrouteDoRequest::Flow(val) => fmt.field("Flow", &val),
5922 OpNewrouteDoRequest::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
5923 OpNewrouteDoRequest::Table(val) => fmt.field("Table", &val),
5924 OpNewrouteDoRequest::Mark(val) => fmt.field("Mark", &val),
5925 OpNewrouteDoRequest::MfcStats(val) => fmt.field("MfcStats", &val),
5926 OpNewrouteDoRequest::Via(val) => fmt.field("Via", &val),
5927 OpNewrouteDoRequest::Newdst(val) => fmt.field("Newdst", &val),
5928 OpNewrouteDoRequest::Pref(val) => fmt.field("Pref", &val),
5929 OpNewrouteDoRequest::EncapType(val) => fmt.field("EncapType", &val),
5930 OpNewrouteDoRequest::Encap(val) => fmt.field("Encap", &val),
5931 OpNewrouteDoRequest::Expires(val) => fmt.field("Expires", &val),
5932 OpNewrouteDoRequest::Pad(val) => fmt.field("Pad", &val),
5933 OpNewrouteDoRequest::Uid(val) => fmt.field("Uid", &val),
5934 OpNewrouteDoRequest::TtlPropagate(val) => fmt.field("TtlPropagate", &val),
5935 OpNewrouteDoRequest::IpProto(val) => fmt.field("IpProto", &val),
5936 OpNewrouteDoRequest::Sport(val) => fmt.field("Sport", &val),
5937 OpNewrouteDoRequest::Dport(val) => fmt.field("Dport", &val),
5938 OpNewrouteDoRequest::NhId(val) => fmt.field("NhId", &val),
5939 OpNewrouteDoRequest::Flowlabel(val) => fmt.field("Flowlabel", &val),
5940 };
5941 }
5942 fmt.finish()
5943 }
5944}
5945impl IterableOpNewrouteDoRequest<'_> {
5946 pub fn lookup_attr(
5947 &self,
5948 offset: usize,
5949 missing_type: Option<u16>,
5950 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5951 let mut stack = Vec::new();
5952 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5953 if cur == offset + PushRtmsg::len() {
5954 stack.push(("OpNewrouteDoRequest", offset));
5955 return (
5956 stack,
5957 missing_type.and_then(|t| OpNewrouteDoRequest::attr_from_type(t)),
5958 );
5959 }
5960 if cur > offset || cur + self.buf.len() < offset {
5961 return (stack, None);
5962 }
5963 let mut attrs = self.clone();
5964 let mut last_off = cur + attrs.pos;
5965 let mut missing = None;
5966 while let Some(attr) = attrs.next() {
5967 let Ok(attr) = attr else { break };
5968 match attr {
5969 OpNewrouteDoRequest::Dst(val) => {
5970 if last_off == offset {
5971 stack.push(("Dst", last_off));
5972 break;
5973 }
5974 }
5975 OpNewrouteDoRequest::Src(val) => {
5976 if last_off == offset {
5977 stack.push(("Src", last_off));
5978 break;
5979 }
5980 }
5981 OpNewrouteDoRequest::Iif(val) => {
5982 if last_off == offset {
5983 stack.push(("Iif", last_off));
5984 break;
5985 }
5986 }
5987 OpNewrouteDoRequest::Oif(val) => {
5988 if last_off == offset {
5989 stack.push(("Oif", last_off));
5990 break;
5991 }
5992 }
5993 OpNewrouteDoRequest::Gateway(val) => {
5994 if last_off == offset {
5995 stack.push(("Gateway", last_off));
5996 break;
5997 }
5998 }
5999 OpNewrouteDoRequest::Priority(val) => {
6000 if last_off == offset {
6001 stack.push(("Priority", last_off));
6002 break;
6003 }
6004 }
6005 OpNewrouteDoRequest::Prefsrc(val) => {
6006 if last_off == offset {
6007 stack.push(("Prefsrc", last_off));
6008 break;
6009 }
6010 }
6011 OpNewrouteDoRequest::Metrics(val) => {
6012 (stack, missing) = val.lookup_attr(offset, missing_type);
6013 if !stack.is_empty() {
6014 break;
6015 }
6016 }
6017 OpNewrouteDoRequest::Multipath(val) => {
6018 if last_off == offset {
6019 stack.push(("Multipath", last_off));
6020 break;
6021 }
6022 }
6023 OpNewrouteDoRequest::Flow(val) => {
6024 if last_off == offset {
6025 stack.push(("Flow", last_off));
6026 break;
6027 }
6028 }
6029 OpNewrouteDoRequest::Cacheinfo(val) => {
6030 if last_off == offset {
6031 stack.push(("Cacheinfo", last_off));
6032 break;
6033 }
6034 }
6035 OpNewrouteDoRequest::Table(val) => {
6036 if last_off == offset {
6037 stack.push(("Table", last_off));
6038 break;
6039 }
6040 }
6041 OpNewrouteDoRequest::Mark(val) => {
6042 if last_off == offset {
6043 stack.push(("Mark", last_off));
6044 break;
6045 }
6046 }
6047 OpNewrouteDoRequest::MfcStats(val) => {
6048 if last_off == offset {
6049 stack.push(("MfcStats", last_off));
6050 break;
6051 }
6052 }
6053 OpNewrouteDoRequest::Via(val) => {
6054 if last_off == offset {
6055 stack.push(("Via", last_off));
6056 break;
6057 }
6058 }
6059 OpNewrouteDoRequest::Newdst(val) => {
6060 if last_off == offset {
6061 stack.push(("Newdst", last_off));
6062 break;
6063 }
6064 }
6065 OpNewrouteDoRequest::Pref(val) => {
6066 if last_off == offset {
6067 stack.push(("Pref", last_off));
6068 break;
6069 }
6070 }
6071 OpNewrouteDoRequest::EncapType(val) => {
6072 if last_off == offset {
6073 stack.push(("EncapType", last_off));
6074 break;
6075 }
6076 }
6077 OpNewrouteDoRequest::Encap(val) => {
6078 if last_off == offset {
6079 stack.push(("Encap", last_off));
6080 break;
6081 }
6082 }
6083 OpNewrouteDoRequest::Expires(val) => {
6084 if last_off == offset {
6085 stack.push(("Expires", last_off));
6086 break;
6087 }
6088 }
6089 OpNewrouteDoRequest::Pad(val) => {
6090 if last_off == offset {
6091 stack.push(("Pad", last_off));
6092 break;
6093 }
6094 }
6095 OpNewrouteDoRequest::Uid(val) => {
6096 if last_off == offset {
6097 stack.push(("Uid", last_off));
6098 break;
6099 }
6100 }
6101 OpNewrouteDoRequest::TtlPropagate(val) => {
6102 if last_off == offset {
6103 stack.push(("TtlPropagate", last_off));
6104 break;
6105 }
6106 }
6107 OpNewrouteDoRequest::IpProto(val) => {
6108 if last_off == offset {
6109 stack.push(("IpProto", last_off));
6110 break;
6111 }
6112 }
6113 OpNewrouteDoRequest::Sport(val) => {
6114 if last_off == offset {
6115 stack.push(("Sport", last_off));
6116 break;
6117 }
6118 }
6119 OpNewrouteDoRequest::Dport(val) => {
6120 if last_off == offset {
6121 stack.push(("Dport", last_off));
6122 break;
6123 }
6124 }
6125 OpNewrouteDoRequest::NhId(val) => {
6126 if last_off == offset {
6127 stack.push(("NhId", last_off));
6128 break;
6129 }
6130 }
6131 OpNewrouteDoRequest::Flowlabel(val) => {
6132 if last_off == offset {
6133 stack.push(("Flowlabel", last_off));
6134 break;
6135 }
6136 }
6137 _ => {}
6138 };
6139 last_off = cur + attrs.pos;
6140 }
6141 if !stack.is_empty() {
6142 stack.push(("OpNewrouteDoRequest", cur));
6143 }
6144 (stack, missing)
6145 }
6146}
6147#[doc = "Create a new route"]
6148pub struct PushOpNewrouteDoReply<Prev: Rec> {
6149 pub(crate) prev: Option<Prev>,
6150 pub(crate) header_offset: Option<usize>,
6151}
6152impl<Prev: Rec> Rec for PushOpNewrouteDoReply<Prev> {
6153 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6154 self.prev.as_mut().unwrap().as_rec_mut()
6155 }
6156}
6157impl<Prev: Rec> PushOpNewrouteDoReply<Prev> {
6158 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
6159 Self::write_header(&mut prev, header);
6160 Self::new_without_header(prev)
6161 }
6162 fn new_without_header(prev: Prev) -> Self {
6163 Self {
6164 prev: Some(prev),
6165 header_offset: None,
6166 }
6167 }
6168 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
6169 prev.as_rec_mut().extend(header.as_slice());
6170 }
6171 pub fn end_nested(mut self) -> Prev {
6172 let mut prev = self.prev.take().unwrap();
6173 if let Some(header_offset) = &self.header_offset {
6174 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6175 }
6176 prev
6177 }
6178}
6179impl<Prev: Rec> Drop for PushOpNewrouteDoReply<Prev> {
6180 fn drop(&mut self) {
6181 if let Some(prev) = &mut self.prev {
6182 if let Some(header_offset) = &self.header_offset {
6183 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6184 }
6185 }
6186 }
6187}
6188#[doc = "Create a new route"]
6189#[derive(Clone)]
6190pub enum OpNewrouteDoReply {}
6191impl<'a> IterableOpNewrouteDoReply<'a> {}
6192impl OpNewrouteDoReply {
6193 pub fn new(buf: &'_ [u8]) -> (PushRtmsg, IterableOpNewrouteDoReply<'_>) {
6194 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
6195 (
6196 PushRtmsg::new_from_slice(header).unwrap_or_default(),
6197 IterableOpNewrouteDoReply::with_loc(attrs, buf.as_ptr() as usize),
6198 )
6199 }
6200 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6201 RouteAttrs::attr_from_type(r#type)
6202 }
6203}
6204#[derive(Clone, Copy, Default)]
6205pub struct IterableOpNewrouteDoReply<'a> {
6206 buf: &'a [u8],
6207 pos: usize,
6208 orig_loc: usize,
6209}
6210impl<'a> IterableOpNewrouteDoReply<'a> {
6211 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6212 Self {
6213 buf,
6214 pos: 0,
6215 orig_loc,
6216 }
6217 }
6218 pub fn get_buf(&self) -> &'a [u8] {
6219 self.buf
6220 }
6221}
6222impl<'a> Iterator for IterableOpNewrouteDoReply<'a> {
6223 type Item = Result<OpNewrouteDoReply, ErrorContext>;
6224 fn next(&mut self) -> Option<Self::Item> {
6225 if self.buf.len() == self.pos {
6226 return None;
6227 }
6228 let pos = self.pos;
6229 let mut r#type = None;
6230 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
6231 r#type = Some(header.r#type);
6232 let res = match header.r#type {
6233 n => {
6234 if cfg!(any(test, feature = "deny-unknown-attrs")) {
6235 break;
6236 } else {
6237 continue;
6238 }
6239 }
6240 };
6241 return Some(Ok(res));
6242 }
6243 Some(Err(ErrorContext::new(
6244 "OpNewrouteDoReply",
6245 r#type.and_then(|t| OpNewrouteDoReply::attr_from_type(t)),
6246 self.orig_loc,
6247 self.buf.as_ptr().wrapping_add(pos) as usize,
6248 )))
6249 }
6250}
6251impl std::fmt::Debug for IterableOpNewrouteDoReply<'_> {
6252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6253 let mut fmt = f.debug_struct("OpNewrouteDoReply");
6254 for attr in self.clone() {
6255 let attr = match attr {
6256 Ok(a) => a,
6257 Err(err) => {
6258 fmt.finish()?;
6259 f.write_str("Err(")?;
6260 err.fmt(f)?;
6261 return f.write_str(")");
6262 }
6263 };
6264 match attr {};
6265 }
6266 fmt.finish()
6267 }
6268}
6269impl IterableOpNewrouteDoReply<'_> {
6270 pub fn lookup_attr(
6271 &self,
6272 offset: usize,
6273 missing_type: Option<u16>,
6274 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6275 let mut stack = Vec::new();
6276 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6277 if cur == offset + PushRtmsg::len() {
6278 stack.push(("OpNewrouteDoReply", offset));
6279 return (
6280 stack,
6281 missing_type.and_then(|t| OpNewrouteDoReply::attr_from_type(t)),
6282 );
6283 }
6284 (stack, None)
6285 }
6286}
6287#[derive(Debug)]
6288pub struct RequestOpNewrouteDoRequest<'r> {
6289 request: Request<'r>,
6290}
6291impl<'r> RequestOpNewrouteDoRequest<'r> {
6292 pub fn new(mut request: Request<'r>, header: &PushRtmsg) -> Self {
6293 PushOpNewrouteDoRequest::write_header(&mut request.buf_mut(), header);
6294 Self { request: request }
6295 }
6296 pub fn encode(&mut self) -> PushOpNewrouteDoRequest<&mut Vec<u8>> {
6297 PushOpNewrouteDoRequest::new_without_header(self.request.buf_mut())
6298 }
6299 pub fn into_encoder(self) -> PushOpNewrouteDoRequest<RequestBuf<'r>> {
6300 PushOpNewrouteDoRequest::new_without_header(self.request.buf)
6301 }
6302}
6303impl NetlinkRequest for RequestOpNewrouteDoRequest<'_> {
6304 type ReplyType<'buf> = (PushRtmsg, IterableOpNewrouteDoReply<'buf>);
6305 fn protocol(&self) -> Protocol {
6306 Protocol::Raw {
6307 protonum: 0u16,
6308 request_type: 24u16,
6309 }
6310 }
6311 fn flags(&self) -> u16 {
6312 self.request.flags
6313 }
6314 fn payload(&self) -> &[u8] {
6315 self.request.buf()
6316 }
6317 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6318 OpNewrouteDoReply::new(buf)
6319 }
6320 fn lookup(
6321 buf: &[u8],
6322 offset: usize,
6323 missing_type: Option<u16>,
6324 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6325 OpNewrouteDoRequest::new(buf)
6326 .1
6327 .lookup_attr(offset, missing_type)
6328 }
6329}
6330#[doc = "Delete an existing route"]
6331pub struct PushOpDelrouteDoRequest<Prev: Rec> {
6332 pub(crate) prev: Option<Prev>,
6333 pub(crate) header_offset: Option<usize>,
6334}
6335impl<Prev: Rec> Rec for PushOpDelrouteDoRequest<Prev> {
6336 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6337 self.prev.as_mut().unwrap().as_rec_mut()
6338 }
6339}
6340impl<Prev: Rec> PushOpDelrouteDoRequest<Prev> {
6341 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
6342 Self::write_header(&mut prev, header);
6343 Self::new_without_header(prev)
6344 }
6345 fn new_without_header(prev: Prev) -> Self {
6346 Self {
6347 prev: Some(prev),
6348 header_offset: None,
6349 }
6350 }
6351 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
6352 prev.as_rec_mut().extend(header.as_slice());
6353 }
6354 pub fn end_nested(mut self) -> Prev {
6355 let mut prev = self.prev.take().unwrap();
6356 if let Some(header_offset) = &self.header_offset {
6357 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6358 }
6359 prev
6360 }
6361 pub fn push_dst(mut self, value: &[u8]) -> Self {
6362 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
6363 self.as_rec_mut().extend(value);
6364 self
6365 }
6366 pub fn push_src(mut self, value: &[u8]) -> Self {
6367 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
6368 self.as_rec_mut().extend(value);
6369 self
6370 }
6371 pub fn push_iif(mut self, value: u32) -> Self {
6372 push_header(self.as_rec_mut(), 3u16, 4 as u16);
6373 self.as_rec_mut().extend(value.to_ne_bytes());
6374 self
6375 }
6376 pub fn push_oif(mut self, value: u32) -> Self {
6377 push_header(self.as_rec_mut(), 4u16, 4 as u16);
6378 self.as_rec_mut().extend(value.to_ne_bytes());
6379 self
6380 }
6381 pub fn push_gateway(mut self, value: &[u8]) -> Self {
6382 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
6383 self.as_rec_mut().extend(value);
6384 self
6385 }
6386 pub fn push_priority(mut self, value: u32) -> Self {
6387 push_header(self.as_rec_mut(), 6u16, 4 as u16);
6388 self.as_rec_mut().extend(value.to_ne_bytes());
6389 self
6390 }
6391 pub fn push_prefsrc(mut self, value: &[u8]) -> Self {
6392 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
6393 self.as_rec_mut().extend(value);
6394 self
6395 }
6396 pub fn nested_metrics(mut self) -> PushMetrics<Self> {
6397 let header_offset = push_nested_header(self.as_rec_mut(), 8u16);
6398 PushMetrics {
6399 prev: Some(self),
6400 header_offset: Some(header_offset),
6401 }
6402 }
6403 pub fn push_multipath(mut self, value: &[u8]) -> Self {
6404 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
6405 self.as_rec_mut().extend(value);
6406 self
6407 }
6408 pub fn push_flow(mut self, value: u32) -> Self {
6409 push_header(self.as_rec_mut(), 11u16, 4 as u16);
6410 self.as_rec_mut().extend(value.to_ne_bytes());
6411 self
6412 }
6413 pub fn push_cacheinfo(mut self, value: PushRtaCacheinfo) -> Self {
6414 push_header(self.as_rec_mut(), 12u16, value.as_slice().len() as u16);
6415 self.as_rec_mut().extend(value.as_slice());
6416 self
6417 }
6418 pub fn push_table(mut self, value: u32) -> Self {
6419 push_header(self.as_rec_mut(), 15u16, 4 as u16);
6420 self.as_rec_mut().extend(value.to_ne_bytes());
6421 self
6422 }
6423 pub fn push_mark(mut self, value: u32) -> Self {
6424 push_header(self.as_rec_mut(), 16u16, 4 as u16);
6425 self.as_rec_mut().extend(value.to_ne_bytes());
6426 self
6427 }
6428 pub fn push_mfc_stats(mut self, value: &[u8]) -> Self {
6429 push_header(self.as_rec_mut(), 17u16, value.len() as u16);
6430 self.as_rec_mut().extend(value);
6431 self
6432 }
6433 pub fn push_via(mut self, value: &[u8]) -> Self {
6434 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
6435 self.as_rec_mut().extend(value);
6436 self
6437 }
6438 pub fn push_newdst(mut self, value: &[u8]) -> Self {
6439 push_header(self.as_rec_mut(), 19u16, value.len() as u16);
6440 self.as_rec_mut().extend(value);
6441 self
6442 }
6443 pub fn push_pref(mut self, value: u8) -> Self {
6444 push_header(self.as_rec_mut(), 20u16, 1 as u16);
6445 self.as_rec_mut().extend(value.to_ne_bytes());
6446 self
6447 }
6448 pub fn push_encap_type(mut self, value: u16) -> Self {
6449 push_header(self.as_rec_mut(), 21u16, 2 as u16);
6450 self.as_rec_mut().extend(value.to_ne_bytes());
6451 self
6452 }
6453 pub fn push_encap(mut self, value: &[u8]) -> Self {
6454 push_header(self.as_rec_mut(), 22u16, value.len() as u16);
6455 self.as_rec_mut().extend(value);
6456 self
6457 }
6458 pub fn push_expires(mut self, value: u32) -> Self {
6459 push_header(self.as_rec_mut(), 23u16, 4 as u16);
6460 self.as_rec_mut().extend(value.to_ne_bytes());
6461 self
6462 }
6463 pub fn push_pad(mut self, value: &[u8]) -> Self {
6464 push_header(self.as_rec_mut(), 24u16, value.len() as u16);
6465 self.as_rec_mut().extend(value);
6466 self
6467 }
6468 pub fn push_uid(mut self, value: u32) -> Self {
6469 push_header(self.as_rec_mut(), 25u16, 4 as u16);
6470 self.as_rec_mut().extend(value.to_ne_bytes());
6471 self
6472 }
6473 pub fn push_ttl_propagate(mut self, value: u8) -> Self {
6474 push_header(self.as_rec_mut(), 26u16, 1 as u16);
6475 self.as_rec_mut().extend(value.to_ne_bytes());
6476 self
6477 }
6478 pub fn push_ip_proto(mut self, value: u8) -> Self {
6479 push_header(self.as_rec_mut(), 27u16, 1 as u16);
6480 self.as_rec_mut().extend(value.to_ne_bytes());
6481 self
6482 }
6483 pub fn push_sport(mut self, value: u16) -> Self {
6484 push_header(self.as_rec_mut(), 28u16, 2 as u16);
6485 self.as_rec_mut().extend(value.to_ne_bytes());
6486 self
6487 }
6488 pub fn push_dport(mut self, value: u16) -> Self {
6489 push_header(self.as_rec_mut(), 29u16, 2 as u16);
6490 self.as_rec_mut().extend(value.to_ne_bytes());
6491 self
6492 }
6493 pub fn push_nh_id(mut self, value: u32) -> Self {
6494 push_header(self.as_rec_mut(), 30u16, 4 as u16);
6495 self.as_rec_mut().extend(value.to_ne_bytes());
6496 self
6497 }
6498 pub fn push_flowlabel(mut self, value: u32) -> Self {
6499 push_header(self.as_rec_mut(), 31u16, 4 as u16);
6500 self.as_rec_mut().extend(value.to_be_bytes());
6501 self
6502 }
6503}
6504impl<Prev: Rec> Drop for PushOpDelrouteDoRequest<Prev> {
6505 fn drop(&mut self) {
6506 if let Some(prev) = &mut self.prev {
6507 if let Some(header_offset) = &self.header_offset {
6508 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6509 }
6510 }
6511 }
6512}
6513#[doc = "Delete an existing route"]
6514#[derive(Clone)]
6515pub enum OpDelrouteDoRequest<'a> {
6516 Dst(&'a [u8]),
6517 Src(&'a [u8]),
6518 Iif(u32),
6519 Oif(u32),
6520 Gateway(&'a [u8]),
6521 Priority(u32),
6522 Prefsrc(&'a [u8]),
6523 Metrics(IterableMetrics<'a>),
6524 Multipath(&'a [u8]),
6525 Flow(u32),
6526 Cacheinfo(PushRtaCacheinfo),
6527 Table(u32),
6528 Mark(u32),
6529 MfcStats(&'a [u8]),
6530 Via(&'a [u8]),
6531 Newdst(&'a [u8]),
6532 Pref(u8),
6533 EncapType(u16),
6534 Encap(&'a [u8]),
6535 Expires(u32),
6536 Pad(&'a [u8]),
6537 Uid(u32),
6538 TtlPropagate(u8),
6539 IpProto(u8),
6540 Sport(u16),
6541 Dport(u16),
6542 NhId(u32),
6543 Flowlabel(u32),
6544}
6545impl<'a> IterableOpDelrouteDoRequest<'a> {
6546 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
6547 let mut iter = self.clone();
6548 iter.pos = 0;
6549 for attr in iter {
6550 if let OpDelrouteDoRequest::Dst(val) = attr? {
6551 return Ok(val);
6552 }
6553 }
6554 Err(ErrorContext::new_missing(
6555 "OpDelrouteDoRequest",
6556 "Dst",
6557 self.orig_loc,
6558 self.buf.as_ptr() as usize,
6559 ))
6560 }
6561 pub fn get_src(&self) -> Result<&'a [u8], ErrorContext> {
6562 let mut iter = self.clone();
6563 iter.pos = 0;
6564 for attr in iter {
6565 if let OpDelrouteDoRequest::Src(val) = attr? {
6566 return Ok(val);
6567 }
6568 }
6569 Err(ErrorContext::new_missing(
6570 "OpDelrouteDoRequest",
6571 "Src",
6572 self.orig_loc,
6573 self.buf.as_ptr() as usize,
6574 ))
6575 }
6576 pub fn get_iif(&self) -> Result<u32, ErrorContext> {
6577 let mut iter = self.clone();
6578 iter.pos = 0;
6579 for attr in iter {
6580 if let OpDelrouteDoRequest::Iif(val) = attr? {
6581 return Ok(val);
6582 }
6583 }
6584 Err(ErrorContext::new_missing(
6585 "OpDelrouteDoRequest",
6586 "Iif",
6587 self.orig_loc,
6588 self.buf.as_ptr() as usize,
6589 ))
6590 }
6591 pub fn get_oif(&self) -> Result<u32, ErrorContext> {
6592 let mut iter = self.clone();
6593 iter.pos = 0;
6594 for attr in iter {
6595 if let OpDelrouteDoRequest::Oif(val) = attr? {
6596 return Ok(val);
6597 }
6598 }
6599 Err(ErrorContext::new_missing(
6600 "OpDelrouteDoRequest",
6601 "Oif",
6602 self.orig_loc,
6603 self.buf.as_ptr() as usize,
6604 ))
6605 }
6606 pub fn get_gateway(&self) -> Result<&'a [u8], ErrorContext> {
6607 let mut iter = self.clone();
6608 iter.pos = 0;
6609 for attr in iter {
6610 if let OpDelrouteDoRequest::Gateway(val) = attr? {
6611 return Ok(val);
6612 }
6613 }
6614 Err(ErrorContext::new_missing(
6615 "OpDelrouteDoRequest",
6616 "Gateway",
6617 self.orig_loc,
6618 self.buf.as_ptr() as usize,
6619 ))
6620 }
6621 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
6622 let mut iter = self.clone();
6623 iter.pos = 0;
6624 for attr in iter {
6625 if let OpDelrouteDoRequest::Priority(val) = attr? {
6626 return Ok(val);
6627 }
6628 }
6629 Err(ErrorContext::new_missing(
6630 "OpDelrouteDoRequest",
6631 "Priority",
6632 self.orig_loc,
6633 self.buf.as_ptr() as usize,
6634 ))
6635 }
6636 pub fn get_prefsrc(&self) -> Result<&'a [u8], ErrorContext> {
6637 let mut iter = self.clone();
6638 iter.pos = 0;
6639 for attr in iter {
6640 if let OpDelrouteDoRequest::Prefsrc(val) = attr? {
6641 return Ok(val);
6642 }
6643 }
6644 Err(ErrorContext::new_missing(
6645 "OpDelrouteDoRequest",
6646 "Prefsrc",
6647 self.orig_loc,
6648 self.buf.as_ptr() as usize,
6649 ))
6650 }
6651 pub fn get_metrics(&self) -> Result<IterableMetrics<'a>, ErrorContext> {
6652 let mut iter = self.clone();
6653 iter.pos = 0;
6654 for attr in iter {
6655 if let OpDelrouteDoRequest::Metrics(val) = attr? {
6656 return Ok(val);
6657 }
6658 }
6659 Err(ErrorContext::new_missing(
6660 "OpDelrouteDoRequest",
6661 "Metrics",
6662 self.orig_loc,
6663 self.buf.as_ptr() as usize,
6664 ))
6665 }
6666 pub fn get_multipath(&self) -> Result<&'a [u8], ErrorContext> {
6667 let mut iter = self.clone();
6668 iter.pos = 0;
6669 for attr in iter {
6670 if let OpDelrouteDoRequest::Multipath(val) = attr? {
6671 return Ok(val);
6672 }
6673 }
6674 Err(ErrorContext::new_missing(
6675 "OpDelrouteDoRequest",
6676 "Multipath",
6677 self.orig_loc,
6678 self.buf.as_ptr() as usize,
6679 ))
6680 }
6681 pub fn get_flow(&self) -> Result<u32, ErrorContext> {
6682 let mut iter = self.clone();
6683 iter.pos = 0;
6684 for attr in iter {
6685 if let OpDelrouteDoRequest::Flow(val) = attr? {
6686 return Ok(val);
6687 }
6688 }
6689 Err(ErrorContext::new_missing(
6690 "OpDelrouteDoRequest",
6691 "Flow",
6692 self.orig_loc,
6693 self.buf.as_ptr() as usize,
6694 ))
6695 }
6696 pub fn get_cacheinfo(&self) -> Result<PushRtaCacheinfo, ErrorContext> {
6697 let mut iter = self.clone();
6698 iter.pos = 0;
6699 for attr in iter {
6700 if let OpDelrouteDoRequest::Cacheinfo(val) = attr? {
6701 return Ok(val);
6702 }
6703 }
6704 Err(ErrorContext::new_missing(
6705 "OpDelrouteDoRequest",
6706 "Cacheinfo",
6707 self.orig_loc,
6708 self.buf.as_ptr() as usize,
6709 ))
6710 }
6711 pub fn get_table(&self) -> Result<u32, ErrorContext> {
6712 let mut iter = self.clone();
6713 iter.pos = 0;
6714 for attr in iter {
6715 if let OpDelrouteDoRequest::Table(val) = attr? {
6716 return Ok(val);
6717 }
6718 }
6719 Err(ErrorContext::new_missing(
6720 "OpDelrouteDoRequest",
6721 "Table",
6722 self.orig_loc,
6723 self.buf.as_ptr() as usize,
6724 ))
6725 }
6726 pub fn get_mark(&self) -> Result<u32, ErrorContext> {
6727 let mut iter = self.clone();
6728 iter.pos = 0;
6729 for attr in iter {
6730 if let OpDelrouteDoRequest::Mark(val) = attr? {
6731 return Ok(val);
6732 }
6733 }
6734 Err(ErrorContext::new_missing(
6735 "OpDelrouteDoRequest",
6736 "Mark",
6737 self.orig_loc,
6738 self.buf.as_ptr() as usize,
6739 ))
6740 }
6741 pub fn get_mfc_stats(&self) -> Result<&'a [u8], ErrorContext> {
6742 let mut iter = self.clone();
6743 iter.pos = 0;
6744 for attr in iter {
6745 if let OpDelrouteDoRequest::MfcStats(val) = attr? {
6746 return Ok(val);
6747 }
6748 }
6749 Err(ErrorContext::new_missing(
6750 "OpDelrouteDoRequest",
6751 "MfcStats",
6752 self.orig_loc,
6753 self.buf.as_ptr() as usize,
6754 ))
6755 }
6756 pub fn get_via(&self) -> Result<&'a [u8], ErrorContext> {
6757 let mut iter = self.clone();
6758 iter.pos = 0;
6759 for attr in iter {
6760 if let OpDelrouteDoRequest::Via(val) = attr? {
6761 return Ok(val);
6762 }
6763 }
6764 Err(ErrorContext::new_missing(
6765 "OpDelrouteDoRequest",
6766 "Via",
6767 self.orig_loc,
6768 self.buf.as_ptr() as usize,
6769 ))
6770 }
6771 pub fn get_newdst(&self) -> Result<&'a [u8], ErrorContext> {
6772 let mut iter = self.clone();
6773 iter.pos = 0;
6774 for attr in iter {
6775 if let OpDelrouteDoRequest::Newdst(val) = attr? {
6776 return Ok(val);
6777 }
6778 }
6779 Err(ErrorContext::new_missing(
6780 "OpDelrouteDoRequest",
6781 "Newdst",
6782 self.orig_loc,
6783 self.buf.as_ptr() as usize,
6784 ))
6785 }
6786 pub fn get_pref(&self) -> Result<u8, ErrorContext> {
6787 let mut iter = self.clone();
6788 iter.pos = 0;
6789 for attr in iter {
6790 if let OpDelrouteDoRequest::Pref(val) = attr? {
6791 return Ok(val);
6792 }
6793 }
6794 Err(ErrorContext::new_missing(
6795 "OpDelrouteDoRequest",
6796 "Pref",
6797 self.orig_loc,
6798 self.buf.as_ptr() as usize,
6799 ))
6800 }
6801 pub fn get_encap_type(&self) -> Result<u16, ErrorContext> {
6802 let mut iter = self.clone();
6803 iter.pos = 0;
6804 for attr in iter {
6805 if let OpDelrouteDoRequest::EncapType(val) = attr? {
6806 return Ok(val);
6807 }
6808 }
6809 Err(ErrorContext::new_missing(
6810 "OpDelrouteDoRequest",
6811 "EncapType",
6812 self.orig_loc,
6813 self.buf.as_ptr() as usize,
6814 ))
6815 }
6816 pub fn get_encap(&self) -> Result<&'a [u8], ErrorContext> {
6817 let mut iter = self.clone();
6818 iter.pos = 0;
6819 for attr in iter {
6820 if let OpDelrouteDoRequest::Encap(val) = attr? {
6821 return Ok(val);
6822 }
6823 }
6824 Err(ErrorContext::new_missing(
6825 "OpDelrouteDoRequest",
6826 "Encap",
6827 self.orig_loc,
6828 self.buf.as_ptr() as usize,
6829 ))
6830 }
6831 pub fn get_expires(&self) -> Result<u32, ErrorContext> {
6832 let mut iter = self.clone();
6833 iter.pos = 0;
6834 for attr in iter {
6835 if let OpDelrouteDoRequest::Expires(val) = attr? {
6836 return Ok(val);
6837 }
6838 }
6839 Err(ErrorContext::new_missing(
6840 "OpDelrouteDoRequest",
6841 "Expires",
6842 self.orig_loc,
6843 self.buf.as_ptr() as usize,
6844 ))
6845 }
6846 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
6847 let mut iter = self.clone();
6848 iter.pos = 0;
6849 for attr in iter {
6850 if let OpDelrouteDoRequest::Pad(val) = attr? {
6851 return Ok(val);
6852 }
6853 }
6854 Err(ErrorContext::new_missing(
6855 "OpDelrouteDoRequest",
6856 "Pad",
6857 self.orig_loc,
6858 self.buf.as_ptr() as usize,
6859 ))
6860 }
6861 pub fn get_uid(&self) -> Result<u32, ErrorContext> {
6862 let mut iter = self.clone();
6863 iter.pos = 0;
6864 for attr in iter {
6865 if let OpDelrouteDoRequest::Uid(val) = attr? {
6866 return Ok(val);
6867 }
6868 }
6869 Err(ErrorContext::new_missing(
6870 "OpDelrouteDoRequest",
6871 "Uid",
6872 self.orig_loc,
6873 self.buf.as_ptr() as usize,
6874 ))
6875 }
6876 pub fn get_ttl_propagate(&self) -> Result<u8, ErrorContext> {
6877 let mut iter = self.clone();
6878 iter.pos = 0;
6879 for attr in iter {
6880 if let OpDelrouteDoRequest::TtlPropagate(val) = attr? {
6881 return Ok(val);
6882 }
6883 }
6884 Err(ErrorContext::new_missing(
6885 "OpDelrouteDoRequest",
6886 "TtlPropagate",
6887 self.orig_loc,
6888 self.buf.as_ptr() as usize,
6889 ))
6890 }
6891 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
6892 let mut iter = self.clone();
6893 iter.pos = 0;
6894 for attr in iter {
6895 if let OpDelrouteDoRequest::IpProto(val) = attr? {
6896 return Ok(val);
6897 }
6898 }
6899 Err(ErrorContext::new_missing(
6900 "OpDelrouteDoRequest",
6901 "IpProto",
6902 self.orig_loc,
6903 self.buf.as_ptr() as usize,
6904 ))
6905 }
6906 pub fn get_sport(&self) -> Result<u16, ErrorContext> {
6907 let mut iter = self.clone();
6908 iter.pos = 0;
6909 for attr in iter {
6910 if let OpDelrouteDoRequest::Sport(val) = attr? {
6911 return Ok(val);
6912 }
6913 }
6914 Err(ErrorContext::new_missing(
6915 "OpDelrouteDoRequest",
6916 "Sport",
6917 self.orig_loc,
6918 self.buf.as_ptr() as usize,
6919 ))
6920 }
6921 pub fn get_dport(&self) -> Result<u16, ErrorContext> {
6922 let mut iter = self.clone();
6923 iter.pos = 0;
6924 for attr in iter {
6925 if let OpDelrouteDoRequest::Dport(val) = attr? {
6926 return Ok(val);
6927 }
6928 }
6929 Err(ErrorContext::new_missing(
6930 "OpDelrouteDoRequest",
6931 "Dport",
6932 self.orig_loc,
6933 self.buf.as_ptr() as usize,
6934 ))
6935 }
6936 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
6937 let mut iter = self.clone();
6938 iter.pos = 0;
6939 for attr in iter {
6940 if let OpDelrouteDoRequest::NhId(val) = attr? {
6941 return Ok(val);
6942 }
6943 }
6944 Err(ErrorContext::new_missing(
6945 "OpDelrouteDoRequest",
6946 "NhId",
6947 self.orig_loc,
6948 self.buf.as_ptr() as usize,
6949 ))
6950 }
6951 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
6952 let mut iter = self.clone();
6953 iter.pos = 0;
6954 for attr in iter {
6955 if let OpDelrouteDoRequest::Flowlabel(val) = attr? {
6956 return Ok(val);
6957 }
6958 }
6959 Err(ErrorContext::new_missing(
6960 "OpDelrouteDoRequest",
6961 "Flowlabel",
6962 self.orig_loc,
6963 self.buf.as_ptr() as usize,
6964 ))
6965 }
6966}
6967impl<'a> OpDelrouteDoRequest<'a> {
6968 pub fn new(buf: &'a [u8]) -> (PushRtmsg, IterableOpDelrouteDoRequest<'a>) {
6969 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
6970 (
6971 PushRtmsg::new_from_slice(header).unwrap_or_default(),
6972 IterableOpDelrouteDoRequest::with_loc(attrs, buf.as_ptr() as usize),
6973 )
6974 }
6975 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6976 RouteAttrs::attr_from_type(r#type)
6977 }
6978}
6979#[derive(Clone, Copy, Default)]
6980pub struct IterableOpDelrouteDoRequest<'a> {
6981 buf: &'a [u8],
6982 pos: usize,
6983 orig_loc: usize,
6984}
6985impl<'a> IterableOpDelrouteDoRequest<'a> {
6986 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6987 Self {
6988 buf,
6989 pos: 0,
6990 orig_loc,
6991 }
6992 }
6993 pub fn get_buf(&self) -> &'a [u8] {
6994 self.buf
6995 }
6996}
6997impl<'a> Iterator for IterableOpDelrouteDoRequest<'a> {
6998 type Item = Result<OpDelrouteDoRequest<'a>, ErrorContext>;
6999 fn next(&mut self) -> Option<Self::Item> {
7000 if self.buf.len() == self.pos {
7001 return None;
7002 }
7003 let pos = self.pos;
7004 let mut r#type = None;
7005 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
7006 r#type = Some(header.r#type);
7007 let res = match header.r#type {
7008 1u16 => OpDelrouteDoRequest::Dst({
7009 let res = Some(next);
7010 let Some(val) = res else { break };
7011 val
7012 }),
7013 2u16 => OpDelrouteDoRequest::Src({
7014 let res = Some(next);
7015 let Some(val) = res else { break };
7016 val
7017 }),
7018 3u16 => OpDelrouteDoRequest::Iif({
7019 let res = parse_u32(next);
7020 let Some(val) = res else { break };
7021 val
7022 }),
7023 4u16 => OpDelrouteDoRequest::Oif({
7024 let res = parse_u32(next);
7025 let Some(val) = res else { break };
7026 val
7027 }),
7028 5u16 => OpDelrouteDoRequest::Gateway({
7029 let res = Some(next);
7030 let Some(val) = res else { break };
7031 val
7032 }),
7033 6u16 => OpDelrouteDoRequest::Priority({
7034 let res = parse_u32(next);
7035 let Some(val) = res else { break };
7036 val
7037 }),
7038 7u16 => OpDelrouteDoRequest::Prefsrc({
7039 let res = Some(next);
7040 let Some(val) = res else { break };
7041 val
7042 }),
7043 8u16 => OpDelrouteDoRequest::Metrics({
7044 let res = Some(IterableMetrics::with_loc(next, self.orig_loc));
7045 let Some(val) = res else { break };
7046 val
7047 }),
7048 9u16 => OpDelrouteDoRequest::Multipath({
7049 let res = Some(next);
7050 let Some(val) = res else { break };
7051 val
7052 }),
7053 11u16 => OpDelrouteDoRequest::Flow({
7054 let res = parse_u32(next);
7055 let Some(val) = res else { break };
7056 val
7057 }),
7058 12u16 => OpDelrouteDoRequest::Cacheinfo({
7059 let res = PushRtaCacheinfo::new_from_slice(next);
7060 let Some(val) = res else { break };
7061 val
7062 }),
7063 15u16 => OpDelrouteDoRequest::Table({
7064 let res = parse_u32(next);
7065 let Some(val) = res else { break };
7066 val
7067 }),
7068 16u16 => OpDelrouteDoRequest::Mark({
7069 let res = parse_u32(next);
7070 let Some(val) = res else { break };
7071 val
7072 }),
7073 17u16 => OpDelrouteDoRequest::MfcStats({
7074 let res = Some(next);
7075 let Some(val) = res else { break };
7076 val
7077 }),
7078 18u16 => OpDelrouteDoRequest::Via({
7079 let res = Some(next);
7080 let Some(val) = res else { break };
7081 val
7082 }),
7083 19u16 => OpDelrouteDoRequest::Newdst({
7084 let res = Some(next);
7085 let Some(val) = res else { break };
7086 val
7087 }),
7088 20u16 => OpDelrouteDoRequest::Pref({
7089 let res = parse_u8(next);
7090 let Some(val) = res else { break };
7091 val
7092 }),
7093 21u16 => OpDelrouteDoRequest::EncapType({
7094 let res = parse_u16(next);
7095 let Some(val) = res else { break };
7096 val
7097 }),
7098 22u16 => OpDelrouteDoRequest::Encap({
7099 let res = Some(next);
7100 let Some(val) = res else { break };
7101 val
7102 }),
7103 23u16 => OpDelrouteDoRequest::Expires({
7104 let res = parse_u32(next);
7105 let Some(val) = res else { break };
7106 val
7107 }),
7108 24u16 => OpDelrouteDoRequest::Pad({
7109 let res = Some(next);
7110 let Some(val) = res else { break };
7111 val
7112 }),
7113 25u16 => OpDelrouteDoRequest::Uid({
7114 let res = parse_u32(next);
7115 let Some(val) = res else { break };
7116 val
7117 }),
7118 26u16 => OpDelrouteDoRequest::TtlPropagate({
7119 let res = parse_u8(next);
7120 let Some(val) = res else { break };
7121 val
7122 }),
7123 27u16 => OpDelrouteDoRequest::IpProto({
7124 let res = parse_u8(next);
7125 let Some(val) = res else { break };
7126 val
7127 }),
7128 28u16 => OpDelrouteDoRequest::Sport({
7129 let res = parse_u16(next);
7130 let Some(val) = res else { break };
7131 val
7132 }),
7133 29u16 => OpDelrouteDoRequest::Dport({
7134 let res = parse_u16(next);
7135 let Some(val) = res else { break };
7136 val
7137 }),
7138 30u16 => OpDelrouteDoRequest::NhId({
7139 let res = parse_u32(next);
7140 let Some(val) = res else { break };
7141 val
7142 }),
7143 31u16 => OpDelrouteDoRequest::Flowlabel({
7144 let res = parse_be_u32(next);
7145 let Some(val) = res else { break };
7146 val
7147 }),
7148 n => {
7149 if cfg!(any(test, feature = "deny-unknown-attrs")) {
7150 break;
7151 } else {
7152 continue;
7153 }
7154 }
7155 };
7156 return Some(Ok(res));
7157 }
7158 Some(Err(ErrorContext::new(
7159 "OpDelrouteDoRequest",
7160 r#type.and_then(|t| OpDelrouteDoRequest::attr_from_type(t)),
7161 self.orig_loc,
7162 self.buf.as_ptr().wrapping_add(pos) as usize,
7163 )))
7164 }
7165}
7166impl<'a> std::fmt::Debug for IterableOpDelrouteDoRequest<'_> {
7167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7168 let mut fmt = f.debug_struct("OpDelrouteDoRequest");
7169 for attr in self.clone() {
7170 let attr = match attr {
7171 Ok(a) => a,
7172 Err(err) => {
7173 fmt.finish()?;
7174 f.write_str("Err(")?;
7175 err.fmt(f)?;
7176 return f.write_str(")");
7177 }
7178 };
7179 match attr {
7180 OpDelrouteDoRequest::Dst(val) => fmt.field("Dst", &val),
7181 OpDelrouteDoRequest::Src(val) => fmt.field("Src", &val),
7182 OpDelrouteDoRequest::Iif(val) => fmt.field("Iif", &val),
7183 OpDelrouteDoRequest::Oif(val) => fmt.field("Oif", &val),
7184 OpDelrouteDoRequest::Gateway(val) => fmt.field("Gateway", &val),
7185 OpDelrouteDoRequest::Priority(val) => fmt.field("Priority", &val),
7186 OpDelrouteDoRequest::Prefsrc(val) => fmt.field("Prefsrc", &val),
7187 OpDelrouteDoRequest::Metrics(val) => fmt.field("Metrics", &val),
7188 OpDelrouteDoRequest::Multipath(val) => fmt.field("Multipath", &val),
7189 OpDelrouteDoRequest::Flow(val) => fmt.field("Flow", &val),
7190 OpDelrouteDoRequest::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
7191 OpDelrouteDoRequest::Table(val) => fmt.field("Table", &val),
7192 OpDelrouteDoRequest::Mark(val) => fmt.field("Mark", &val),
7193 OpDelrouteDoRequest::MfcStats(val) => fmt.field("MfcStats", &val),
7194 OpDelrouteDoRequest::Via(val) => fmt.field("Via", &val),
7195 OpDelrouteDoRequest::Newdst(val) => fmt.field("Newdst", &val),
7196 OpDelrouteDoRequest::Pref(val) => fmt.field("Pref", &val),
7197 OpDelrouteDoRequest::EncapType(val) => fmt.field("EncapType", &val),
7198 OpDelrouteDoRequest::Encap(val) => fmt.field("Encap", &val),
7199 OpDelrouteDoRequest::Expires(val) => fmt.field("Expires", &val),
7200 OpDelrouteDoRequest::Pad(val) => fmt.field("Pad", &val),
7201 OpDelrouteDoRequest::Uid(val) => fmt.field("Uid", &val),
7202 OpDelrouteDoRequest::TtlPropagate(val) => fmt.field("TtlPropagate", &val),
7203 OpDelrouteDoRequest::IpProto(val) => fmt.field("IpProto", &val),
7204 OpDelrouteDoRequest::Sport(val) => fmt.field("Sport", &val),
7205 OpDelrouteDoRequest::Dport(val) => fmt.field("Dport", &val),
7206 OpDelrouteDoRequest::NhId(val) => fmt.field("NhId", &val),
7207 OpDelrouteDoRequest::Flowlabel(val) => fmt.field("Flowlabel", &val),
7208 };
7209 }
7210 fmt.finish()
7211 }
7212}
7213impl IterableOpDelrouteDoRequest<'_> {
7214 pub fn lookup_attr(
7215 &self,
7216 offset: usize,
7217 missing_type: Option<u16>,
7218 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7219 let mut stack = Vec::new();
7220 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
7221 if cur == offset + PushRtmsg::len() {
7222 stack.push(("OpDelrouteDoRequest", offset));
7223 return (
7224 stack,
7225 missing_type.and_then(|t| OpDelrouteDoRequest::attr_from_type(t)),
7226 );
7227 }
7228 if cur > offset || cur + self.buf.len() < offset {
7229 return (stack, None);
7230 }
7231 let mut attrs = self.clone();
7232 let mut last_off = cur + attrs.pos;
7233 let mut missing = None;
7234 while let Some(attr) = attrs.next() {
7235 let Ok(attr) = attr else { break };
7236 match attr {
7237 OpDelrouteDoRequest::Dst(val) => {
7238 if last_off == offset {
7239 stack.push(("Dst", last_off));
7240 break;
7241 }
7242 }
7243 OpDelrouteDoRequest::Src(val) => {
7244 if last_off == offset {
7245 stack.push(("Src", last_off));
7246 break;
7247 }
7248 }
7249 OpDelrouteDoRequest::Iif(val) => {
7250 if last_off == offset {
7251 stack.push(("Iif", last_off));
7252 break;
7253 }
7254 }
7255 OpDelrouteDoRequest::Oif(val) => {
7256 if last_off == offset {
7257 stack.push(("Oif", last_off));
7258 break;
7259 }
7260 }
7261 OpDelrouteDoRequest::Gateway(val) => {
7262 if last_off == offset {
7263 stack.push(("Gateway", last_off));
7264 break;
7265 }
7266 }
7267 OpDelrouteDoRequest::Priority(val) => {
7268 if last_off == offset {
7269 stack.push(("Priority", last_off));
7270 break;
7271 }
7272 }
7273 OpDelrouteDoRequest::Prefsrc(val) => {
7274 if last_off == offset {
7275 stack.push(("Prefsrc", last_off));
7276 break;
7277 }
7278 }
7279 OpDelrouteDoRequest::Metrics(val) => {
7280 (stack, missing) = val.lookup_attr(offset, missing_type);
7281 if !stack.is_empty() {
7282 break;
7283 }
7284 }
7285 OpDelrouteDoRequest::Multipath(val) => {
7286 if last_off == offset {
7287 stack.push(("Multipath", last_off));
7288 break;
7289 }
7290 }
7291 OpDelrouteDoRequest::Flow(val) => {
7292 if last_off == offset {
7293 stack.push(("Flow", last_off));
7294 break;
7295 }
7296 }
7297 OpDelrouteDoRequest::Cacheinfo(val) => {
7298 if last_off == offset {
7299 stack.push(("Cacheinfo", last_off));
7300 break;
7301 }
7302 }
7303 OpDelrouteDoRequest::Table(val) => {
7304 if last_off == offset {
7305 stack.push(("Table", last_off));
7306 break;
7307 }
7308 }
7309 OpDelrouteDoRequest::Mark(val) => {
7310 if last_off == offset {
7311 stack.push(("Mark", last_off));
7312 break;
7313 }
7314 }
7315 OpDelrouteDoRequest::MfcStats(val) => {
7316 if last_off == offset {
7317 stack.push(("MfcStats", last_off));
7318 break;
7319 }
7320 }
7321 OpDelrouteDoRequest::Via(val) => {
7322 if last_off == offset {
7323 stack.push(("Via", last_off));
7324 break;
7325 }
7326 }
7327 OpDelrouteDoRequest::Newdst(val) => {
7328 if last_off == offset {
7329 stack.push(("Newdst", last_off));
7330 break;
7331 }
7332 }
7333 OpDelrouteDoRequest::Pref(val) => {
7334 if last_off == offset {
7335 stack.push(("Pref", last_off));
7336 break;
7337 }
7338 }
7339 OpDelrouteDoRequest::EncapType(val) => {
7340 if last_off == offset {
7341 stack.push(("EncapType", last_off));
7342 break;
7343 }
7344 }
7345 OpDelrouteDoRequest::Encap(val) => {
7346 if last_off == offset {
7347 stack.push(("Encap", last_off));
7348 break;
7349 }
7350 }
7351 OpDelrouteDoRequest::Expires(val) => {
7352 if last_off == offset {
7353 stack.push(("Expires", last_off));
7354 break;
7355 }
7356 }
7357 OpDelrouteDoRequest::Pad(val) => {
7358 if last_off == offset {
7359 stack.push(("Pad", last_off));
7360 break;
7361 }
7362 }
7363 OpDelrouteDoRequest::Uid(val) => {
7364 if last_off == offset {
7365 stack.push(("Uid", last_off));
7366 break;
7367 }
7368 }
7369 OpDelrouteDoRequest::TtlPropagate(val) => {
7370 if last_off == offset {
7371 stack.push(("TtlPropagate", last_off));
7372 break;
7373 }
7374 }
7375 OpDelrouteDoRequest::IpProto(val) => {
7376 if last_off == offset {
7377 stack.push(("IpProto", last_off));
7378 break;
7379 }
7380 }
7381 OpDelrouteDoRequest::Sport(val) => {
7382 if last_off == offset {
7383 stack.push(("Sport", last_off));
7384 break;
7385 }
7386 }
7387 OpDelrouteDoRequest::Dport(val) => {
7388 if last_off == offset {
7389 stack.push(("Dport", last_off));
7390 break;
7391 }
7392 }
7393 OpDelrouteDoRequest::NhId(val) => {
7394 if last_off == offset {
7395 stack.push(("NhId", last_off));
7396 break;
7397 }
7398 }
7399 OpDelrouteDoRequest::Flowlabel(val) => {
7400 if last_off == offset {
7401 stack.push(("Flowlabel", last_off));
7402 break;
7403 }
7404 }
7405 _ => {}
7406 };
7407 last_off = cur + attrs.pos;
7408 }
7409 if !stack.is_empty() {
7410 stack.push(("OpDelrouteDoRequest", cur));
7411 }
7412 (stack, missing)
7413 }
7414}
7415#[doc = "Delete an existing route"]
7416pub struct PushOpDelrouteDoReply<Prev: Rec> {
7417 pub(crate) prev: Option<Prev>,
7418 pub(crate) header_offset: Option<usize>,
7419}
7420impl<Prev: Rec> Rec for PushOpDelrouteDoReply<Prev> {
7421 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
7422 self.prev.as_mut().unwrap().as_rec_mut()
7423 }
7424}
7425impl<Prev: Rec> PushOpDelrouteDoReply<Prev> {
7426 pub fn new(mut prev: Prev, header: &PushRtmsg) -> Self {
7427 Self::write_header(&mut prev, header);
7428 Self::new_without_header(prev)
7429 }
7430 fn new_without_header(prev: Prev) -> Self {
7431 Self {
7432 prev: Some(prev),
7433 header_offset: None,
7434 }
7435 }
7436 fn write_header(prev: &mut Prev, header: &PushRtmsg) {
7437 prev.as_rec_mut().extend(header.as_slice());
7438 }
7439 pub fn end_nested(mut self) -> Prev {
7440 let mut prev = self.prev.take().unwrap();
7441 if let Some(header_offset) = &self.header_offset {
7442 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7443 }
7444 prev
7445 }
7446}
7447impl<Prev: Rec> Drop for PushOpDelrouteDoReply<Prev> {
7448 fn drop(&mut self) {
7449 if let Some(prev) = &mut self.prev {
7450 if let Some(header_offset) = &self.header_offset {
7451 finalize_nested_header(prev.as_rec_mut(), *header_offset);
7452 }
7453 }
7454 }
7455}
7456#[doc = "Delete an existing route"]
7457#[derive(Clone)]
7458pub enum OpDelrouteDoReply {}
7459impl<'a> IterableOpDelrouteDoReply<'a> {}
7460impl OpDelrouteDoReply {
7461 pub fn new(buf: &'_ [u8]) -> (PushRtmsg, IterableOpDelrouteDoReply<'_>) {
7462 let (header, attrs) = buf.split_at(buf.len().min(PushRtmsg::len()));
7463 (
7464 PushRtmsg::new_from_slice(header).unwrap_or_default(),
7465 IterableOpDelrouteDoReply::with_loc(attrs, buf.as_ptr() as usize),
7466 )
7467 }
7468 fn attr_from_type(r#type: u16) -> Option<&'static str> {
7469 RouteAttrs::attr_from_type(r#type)
7470 }
7471}
7472#[derive(Clone, Copy, Default)]
7473pub struct IterableOpDelrouteDoReply<'a> {
7474 buf: &'a [u8],
7475 pos: usize,
7476 orig_loc: usize,
7477}
7478impl<'a> IterableOpDelrouteDoReply<'a> {
7479 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
7480 Self {
7481 buf,
7482 pos: 0,
7483 orig_loc,
7484 }
7485 }
7486 pub fn get_buf(&self) -> &'a [u8] {
7487 self.buf
7488 }
7489}
7490impl<'a> Iterator for IterableOpDelrouteDoReply<'a> {
7491 type Item = Result<OpDelrouteDoReply, ErrorContext>;
7492 fn next(&mut self) -> Option<Self::Item> {
7493 if self.buf.len() == self.pos {
7494 return None;
7495 }
7496 let pos = self.pos;
7497 let mut r#type = None;
7498 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
7499 r#type = Some(header.r#type);
7500 let res = match header.r#type {
7501 n => {
7502 if cfg!(any(test, feature = "deny-unknown-attrs")) {
7503 break;
7504 } else {
7505 continue;
7506 }
7507 }
7508 };
7509 return Some(Ok(res));
7510 }
7511 Some(Err(ErrorContext::new(
7512 "OpDelrouteDoReply",
7513 r#type.and_then(|t| OpDelrouteDoReply::attr_from_type(t)),
7514 self.orig_loc,
7515 self.buf.as_ptr().wrapping_add(pos) as usize,
7516 )))
7517 }
7518}
7519impl std::fmt::Debug for IterableOpDelrouteDoReply<'_> {
7520 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7521 let mut fmt = f.debug_struct("OpDelrouteDoReply");
7522 for attr in self.clone() {
7523 let attr = match attr {
7524 Ok(a) => a,
7525 Err(err) => {
7526 fmt.finish()?;
7527 f.write_str("Err(")?;
7528 err.fmt(f)?;
7529 return f.write_str(")");
7530 }
7531 };
7532 match attr {};
7533 }
7534 fmt.finish()
7535 }
7536}
7537impl IterableOpDelrouteDoReply<'_> {
7538 pub fn lookup_attr(
7539 &self,
7540 offset: usize,
7541 missing_type: Option<u16>,
7542 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7543 let mut stack = Vec::new();
7544 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
7545 if cur == offset + PushRtmsg::len() {
7546 stack.push(("OpDelrouteDoReply", offset));
7547 return (
7548 stack,
7549 missing_type.and_then(|t| OpDelrouteDoReply::attr_from_type(t)),
7550 );
7551 }
7552 (stack, None)
7553 }
7554}
7555#[derive(Debug)]
7556pub struct RequestOpDelrouteDoRequest<'r> {
7557 request: Request<'r>,
7558}
7559impl<'r> RequestOpDelrouteDoRequest<'r> {
7560 pub fn new(mut request: Request<'r>, header: &PushRtmsg) -> Self {
7561 PushOpDelrouteDoRequest::write_header(&mut request.buf_mut(), header);
7562 Self { request: request }
7563 }
7564 pub fn encode(&mut self) -> PushOpDelrouteDoRequest<&mut Vec<u8>> {
7565 PushOpDelrouteDoRequest::new_without_header(self.request.buf_mut())
7566 }
7567 pub fn into_encoder(self) -> PushOpDelrouteDoRequest<RequestBuf<'r>> {
7568 PushOpDelrouteDoRequest::new_without_header(self.request.buf)
7569 }
7570}
7571impl NetlinkRequest for RequestOpDelrouteDoRequest<'_> {
7572 type ReplyType<'buf> = (PushRtmsg, IterableOpDelrouteDoReply<'buf>);
7573 fn protocol(&self) -> Protocol {
7574 Protocol::Raw {
7575 protonum: 0u16,
7576 request_type: 25u16,
7577 }
7578 }
7579 fn flags(&self) -> u16 {
7580 self.request.flags
7581 }
7582 fn payload(&self) -> &[u8] {
7583 self.request.buf()
7584 }
7585 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
7586 OpDelrouteDoReply::new(buf)
7587 }
7588 fn lookup(
7589 buf: &[u8],
7590 offset: usize,
7591 missing_type: Option<u16>,
7592 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
7593 OpDelrouteDoRequest::new(buf)
7594 .1
7595 .lookup_attr(offset, missing_type)
7596 }
7597}
7598#[derive(Debug)]
7599pub struct ChainedFinal<'a> {
7600 inner: Chained<'a>,
7601}
7602#[derive(Debug)]
7603pub struct Chained<'a> {
7604 buf: RequestBuf<'a>,
7605 first_seq: u32,
7606 lookups: Vec<(&'static str, LookupFn)>,
7607 last_header_offset: usize,
7608 last_kind: Option<RequestInfo>,
7609}
7610impl<'a> ChainedFinal<'a> {
7611 pub fn into_chained(self) -> Chained<'a> {
7612 self.inner
7613 }
7614 pub fn buf(&self) -> &Vec<u8> {
7615 self.inner.buf()
7616 }
7617 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
7618 self.inner.buf_mut()
7619 }
7620 fn get_index(&self, seq: u32) -> Option<u32> {
7621 let min = self.inner.first_seq;
7622 let max = min.wrapping_add(self.inner.lookups.len() as u32);
7623 return if min <= max {
7624 (min..max).contains(&seq).then(|| seq - min)
7625 } else if min <= seq {
7626 Some(seq - min)
7627 } else if seq < max {
7628 Some(u32::MAX - min + seq)
7629 } else {
7630 None
7631 };
7632 }
7633}
7634impl crate::traits::NetlinkChained for ChainedFinal<'_> {
7635 fn protonum(&self) -> u16 {
7636 PROTONUM
7637 }
7638 fn payload(&self) -> &[u8] {
7639 self.buf()
7640 }
7641 fn chain_len(&self) -> usize {
7642 self.inner.lookups.len()
7643 }
7644 fn get_index(&self, seq: u32) -> Option<usize> {
7645 self.get_index(seq).map(|n| n as usize)
7646 }
7647 fn name(&self, index: usize) -> &'static str {
7648 self.inner.lookups[index].0
7649 }
7650 fn lookup(&self, index: usize) -> LookupFn {
7651 self.inner.lookups[index].1
7652 }
7653}
7654impl Chained<'static> {
7655 pub fn new(first_seq: u32) -> Self {
7656 Self::new_from_buf(Vec::new(), first_seq)
7657 }
7658 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
7659 Self {
7660 buf: RequestBuf::Own(buf),
7661 first_seq,
7662 lookups: Vec::new(),
7663 last_header_offset: 0,
7664 last_kind: None,
7665 }
7666 }
7667 pub fn into_buf(self) -> Vec<u8> {
7668 match self.buf {
7669 RequestBuf::Own(buf) => buf,
7670 _ => unreachable!(),
7671 }
7672 }
7673}
7674impl<'a> Chained<'a> {
7675 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
7676 Self {
7677 buf: RequestBuf::Ref(buf),
7678 first_seq,
7679 lookups: Vec::new(),
7680 last_header_offset: 0,
7681 last_kind: None,
7682 }
7683 }
7684 pub fn finalize(mut self) -> ChainedFinal<'a> {
7685 self.update_header();
7686 ChainedFinal { inner: self }
7687 }
7688 pub fn request(&mut self) -> Request<'_> {
7689 self.update_header();
7690 self.last_header_offset = self.buf().len();
7691 self.buf_mut()
7692 .extend_from_slice(PushNlmsghdr::new().as_slice());
7693 let mut request = Request::new_extend(self.buf.buf_mut());
7694 self.last_kind = None;
7695 request.writeback = Some(&mut self.last_kind);
7696 request
7697 }
7698 pub fn buf(&self) -> &Vec<u8> {
7699 self.buf.buf()
7700 }
7701 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
7702 self.buf.buf_mut()
7703 }
7704 fn update_header(&mut self) {
7705 let Some(RequestInfo {
7706 protocol,
7707 flags,
7708 name,
7709 lookup,
7710 }) = self.last_kind
7711 else {
7712 if !self.buf().is_empty() {
7713 assert_eq!(
7714 self.last_header_offset + PushNlmsghdr::len(),
7715 self.buf().len()
7716 );
7717 self.buf.buf_mut().truncate(self.last_header_offset);
7718 }
7719 return;
7720 };
7721 let header_offset = self.last_header_offset;
7722 let request_type = match protocol {
7723 Protocol::Raw { request_type, .. } => request_type,
7724 Protocol::Generic(_) => unreachable!(),
7725 };
7726 let index = self.lookups.len();
7727 let seq = self.first_seq.wrapping_add(index as u32);
7728 self.lookups.push((name, lookup));
7729 let buf = self.buf_mut();
7730 align(buf);
7731 let mut header = PushNlmsghdr::new();
7732 header.set_len((buf.len() - header_offset) as u32);
7733 header.set_type(request_type);
7734 header.set_flags(flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16);
7735 header.set_seq(seq);
7736 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
7737 }
7738}
7739use crate::traits::LookupFn;
7740use crate::utils::RequestBuf;
7741#[derive(Debug)]
7742pub struct Request<'buf> {
7743 buf: RequestBuf<'buf>,
7744 flags: u16,
7745 writeback: Option<&'buf mut Option<RequestInfo>>,
7746}
7747#[allow(unused)]
7748#[derive(Debug, Clone)]
7749pub struct RequestInfo {
7750 protocol: Protocol,
7751 flags: u16,
7752 name: &'static str,
7753 lookup: LookupFn,
7754}
7755impl Request<'static> {
7756 pub fn new() -> Self {
7757 Self::new_from_buf(Vec::new())
7758 }
7759 pub fn new_from_buf(buf: Vec<u8>) -> Self {
7760 Self {
7761 flags: 0,
7762 buf: RequestBuf::Own(buf),
7763 writeback: None,
7764 }
7765 }
7766 pub fn into_buf(self) -> Vec<u8> {
7767 match self.buf {
7768 RequestBuf::Own(buf) => buf,
7769 _ => unreachable!(),
7770 }
7771 }
7772}
7773impl<'buf> Request<'buf> {
7774 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
7775 buf.clear();
7776 Self::new_extend(buf)
7777 }
7778 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
7779 Self {
7780 flags: 0,
7781 buf: RequestBuf::Ref(buf),
7782 writeback: None,
7783 }
7784 }
7785 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
7786 let Some(writeback) = &mut self.writeback else {
7787 return;
7788 };
7789 **writeback = Some(RequestInfo {
7790 protocol,
7791 flags: self.flags,
7792 name,
7793 lookup,
7794 })
7795 }
7796 pub fn buf(&self) -> &Vec<u8> {
7797 self.buf.buf()
7798 }
7799 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
7800 self.buf.buf_mut()
7801 }
7802 #[doc = "Set `NLM_F_CREATE` flag"]
7803 pub fn set_create(mut self) -> Self {
7804 self.flags |= consts::NLM_F_CREATE as u16;
7805 self
7806 }
7807 #[doc = "Set `NLM_F_EXCL` flag"]
7808 pub fn set_excl(mut self) -> Self {
7809 self.flags |= consts::NLM_F_EXCL as u16;
7810 self
7811 }
7812 #[doc = "Set `NLM_F_REPLACE` flag"]
7813 pub fn set_replace(mut self) -> Self {
7814 self.flags |= consts::NLM_F_REPLACE as u16;
7815 self
7816 }
7817 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
7818 pub fn set_change(self) -> Self {
7819 self.set_create().set_replace()
7820 }
7821 #[doc = "Set `NLM_F_APPEND` flag"]
7822 pub fn set_append(mut self) -> Self {
7823 self.flags |= consts::NLM_F_APPEND as u16;
7824 self
7825 }
7826 #[doc = "Set `NLM_F_DUMP` flag"]
7827 fn set_dump(mut self) -> Self {
7828 self.flags |= consts::NLM_F_DUMP as u16;
7829 self
7830 }
7831 pub fn op_getroute_dump_request(
7832 self,
7833 header: &PushRtmsg,
7834 ) -> RequestOpGetrouteDumpRequest<'buf> {
7835 let mut res = RequestOpGetrouteDumpRequest::new(self, header);
7836 res.request.do_writeback(
7837 res.protocol(),
7838 "op-getroute-dump-request",
7839 RequestOpGetrouteDumpRequest::lookup,
7840 );
7841 res
7842 }
7843 pub fn op_getroute_do_request(self, header: &PushRtmsg) -> RequestOpGetrouteDoRequest<'buf> {
7844 let mut res = RequestOpGetrouteDoRequest::new(self, header);
7845 res.request.do_writeback(
7846 res.protocol(),
7847 "op-getroute-do-request",
7848 RequestOpGetrouteDoRequest::lookup,
7849 );
7850 res
7851 }
7852 pub fn op_newroute_do_request(self, header: &PushRtmsg) -> RequestOpNewrouteDoRequest<'buf> {
7853 let mut res = RequestOpNewrouteDoRequest::new(self, header);
7854 res.request.do_writeback(
7855 res.protocol(),
7856 "op-newroute-do-request",
7857 RequestOpNewrouteDoRequest::lookup,
7858 );
7859 res
7860 }
7861 pub fn op_delroute_do_request(self, header: &PushRtmsg) -> RequestOpDelrouteDoRequest<'buf> {
7862 let mut res = RequestOpDelrouteDoRequest::new(self, header);
7863 res.request.do_writeback(
7864 res.protocol(),
7865 "op-delroute-do-request",
7866 RequestOpDelrouteDoRequest::lookup,
7867 );
7868 res
7869 }
7870}