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