Skip to main content

netlink_bindings/rt-route/
mod.rs

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}