Skip to main content

netlink_bindings/rt-rule/
mod.rs

1#![doc = "FIB rule management 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-rule";
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 FrAct {
21    Unspec = 0,
22    ToTbl = 1,
23    Goto = 2,
24    Nop = 3,
25    Res3 = 4,
26    Res4 = 5,
27    Blackhole = 6,
28    Unreachable = 7,
29    Prohibit = 8,
30}
31impl FrAct {
32    pub fn from_value(value: u64) -> Option<Self> {
33        Some(match value {
34            0 => Self::Unspec,
35            1 => Self::ToTbl,
36            2 => Self::Goto,
37            3 => Self::Nop,
38            4 => Self::Res3,
39            5 => Self::Res4,
40            6 => Self::Blackhole,
41            7 => Self::Unreachable,
42            8 => Self::Prohibit,
43            _ => return None,
44        })
45    }
46}
47#[derive(Clone)]
48pub enum FibRuleAttrs<'a> {
49    Dst(u32),
50    Src(u32),
51    Iifname(&'a CStr),
52    Goto(u32),
53    Unused2(&'a [u8]),
54    Priority(u32),
55    Unused3(&'a [u8]),
56    Unused4(&'a [u8]),
57    Unused5(&'a [u8]),
58    Fwmark(u32),
59    Flow(u32),
60    TunId(u64),
61    SuppressIfgroup(u32),
62    SuppressPrefixlen(u32),
63    Table(u32),
64    Fwmask(u32),
65    Oifname(&'a CStr),
66    Pad(&'a [u8]),
67    L3mdev(u8),
68    UidRange(PushFibRuleUidRange),
69    Protocol(u8),
70    IpProto(u8),
71    SportRange(PushFibRulePortRange),
72    DportRange(PushFibRulePortRange),
73    Dscp(u8),
74    Flowlabel(u32),
75    FlowlabelMask(u32),
76    SportMask(u16),
77    DportMask(u16),
78    DscpMask(u8),
79}
80impl<'a> IterableFibRuleAttrs<'a> {
81    pub fn get_dst(&self) -> Result<u32, ErrorContext> {
82        let mut iter = self.clone();
83        iter.pos = 0;
84        for attr in iter {
85            if let FibRuleAttrs::Dst(val) = attr? {
86                return Ok(val);
87            }
88        }
89        Err(ErrorContext::new_missing(
90            "FibRuleAttrs",
91            "Dst",
92            self.orig_loc,
93            self.buf.as_ptr() as usize,
94        ))
95    }
96    pub fn get_src(&self) -> Result<u32, ErrorContext> {
97        let mut iter = self.clone();
98        iter.pos = 0;
99        for attr in iter {
100            if let FibRuleAttrs::Src(val) = attr? {
101                return Ok(val);
102            }
103        }
104        Err(ErrorContext::new_missing(
105            "FibRuleAttrs",
106            "Src",
107            self.orig_loc,
108            self.buf.as_ptr() as usize,
109        ))
110    }
111    pub fn get_iifname(&self) -> Result<&'a CStr, ErrorContext> {
112        let mut iter = self.clone();
113        iter.pos = 0;
114        for attr in iter {
115            if let FibRuleAttrs::Iifname(val) = attr? {
116                return Ok(val);
117            }
118        }
119        Err(ErrorContext::new_missing(
120            "FibRuleAttrs",
121            "Iifname",
122            self.orig_loc,
123            self.buf.as_ptr() as usize,
124        ))
125    }
126    pub fn get_goto(&self) -> Result<u32, ErrorContext> {
127        let mut iter = self.clone();
128        iter.pos = 0;
129        for attr in iter {
130            if let FibRuleAttrs::Goto(val) = attr? {
131                return Ok(val);
132            }
133        }
134        Err(ErrorContext::new_missing(
135            "FibRuleAttrs",
136            "Goto",
137            self.orig_loc,
138            self.buf.as_ptr() as usize,
139        ))
140    }
141    pub fn get_unused2(&self) -> Result<&'a [u8], ErrorContext> {
142        let mut iter = self.clone();
143        iter.pos = 0;
144        for attr in iter {
145            if let FibRuleAttrs::Unused2(val) = attr? {
146                return Ok(val);
147            }
148        }
149        Err(ErrorContext::new_missing(
150            "FibRuleAttrs",
151            "Unused2",
152            self.orig_loc,
153            self.buf.as_ptr() as usize,
154        ))
155    }
156    pub fn get_priority(&self) -> Result<u32, ErrorContext> {
157        let mut iter = self.clone();
158        iter.pos = 0;
159        for attr in iter {
160            if let FibRuleAttrs::Priority(val) = attr? {
161                return Ok(val);
162            }
163        }
164        Err(ErrorContext::new_missing(
165            "FibRuleAttrs",
166            "Priority",
167            self.orig_loc,
168            self.buf.as_ptr() as usize,
169        ))
170    }
171    pub fn get_unused3(&self) -> Result<&'a [u8], ErrorContext> {
172        let mut iter = self.clone();
173        iter.pos = 0;
174        for attr in iter {
175            if let FibRuleAttrs::Unused3(val) = attr? {
176                return Ok(val);
177            }
178        }
179        Err(ErrorContext::new_missing(
180            "FibRuleAttrs",
181            "Unused3",
182            self.orig_loc,
183            self.buf.as_ptr() as usize,
184        ))
185    }
186    pub fn get_unused4(&self) -> Result<&'a [u8], ErrorContext> {
187        let mut iter = self.clone();
188        iter.pos = 0;
189        for attr in iter {
190            if let FibRuleAttrs::Unused4(val) = attr? {
191                return Ok(val);
192            }
193        }
194        Err(ErrorContext::new_missing(
195            "FibRuleAttrs",
196            "Unused4",
197            self.orig_loc,
198            self.buf.as_ptr() as usize,
199        ))
200    }
201    pub fn get_unused5(&self) -> Result<&'a [u8], ErrorContext> {
202        let mut iter = self.clone();
203        iter.pos = 0;
204        for attr in iter {
205            if let FibRuleAttrs::Unused5(val) = attr? {
206                return Ok(val);
207            }
208        }
209        Err(ErrorContext::new_missing(
210            "FibRuleAttrs",
211            "Unused5",
212            self.orig_loc,
213            self.buf.as_ptr() as usize,
214        ))
215    }
216    pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
217        let mut iter = self.clone();
218        iter.pos = 0;
219        for attr in iter {
220            if let FibRuleAttrs::Fwmark(val) = attr? {
221                return Ok(val);
222            }
223        }
224        Err(ErrorContext::new_missing(
225            "FibRuleAttrs",
226            "Fwmark",
227            self.orig_loc,
228            self.buf.as_ptr() as usize,
229        ))
230    }
231    pub fn get_flow(&self) -> Result<u32, ErrorContext> {
232        let mut iter = self.clone();
233        iter.pos = 0;
234        for attr in iter {
235            if let FibRuleAttrs::Flow(val) = attr? {
236                return Ok(val);
237            }
238        }
239        Err(ErrorContext::new_missing(
240            "FibRuleAttrs",
241            "Flow",
242            self.orig_loc,
243            self.buf.as_ptr() as usize,
244        ))
245    }
246    pub fn get_tun_id(&self) -> Result<u64, ErrorContext> {
247        let mut iter = self.clone();
248        iter.pos = 0;
249        for attr in iter {
250            if let FibRuleAttrs::TunId(val) = attr? {
251                return Ok(val);
252            }
253        }
254        Err(ErrorContext::new_missing(
255            "FibRuleAttrs",
256            "TunId",
257            self.orig_loc,
258            self.buf.as_ptr() as usize,
259        ))
260    }
261    pub fn get_suppress_ifgroup(&self) -> Result<u32, ErrorContext> {
262        let mut iter = self.clone();
263        iter.pos = 0;
264        for attr in iter {
265            if let FibRuleAttrs::SuppressIfgroup(val) = attr? {
266                return Ok(val);
267            }
268        }
269        Err(ErrorContext::new_missing(
270            "FibRuleAttrs",
271            "SuppressIfgroup",
272            self.orig_loc,
273            self.buf.as_ptr() as usize,
274        ))
275    }
276    pub fn get_suppress_prefixlen(&self) -> Result<u32, ErrorContext> {
277        let mut iter = self.clone();
278        iter.pos = 0;
279        for attr in iter {
280            if let FibRuleAttrs::SuppressPrefixlen(val) = attr? {
281                return Ok(val);
282            }
283        }
284        Err(ErrorContext::new_missing(
285            "FibRuleAttrs",
286            "SuppressPrefixlen",
287            self.orig_loc,
288            self.buf.as_ptr() as usize,
289        ))
290    }
291    pub fn get_table(&self) -> Result<u32, ErrorContext> {
292        let mut iter = self.clone();
293        iter.pos = 0;
294        for attr in iter {
295            if let FibRuleAttrs::Table(val) = attr? {
296                return Ok(val);
297            }
298        }
299        Err(ErrorContext::new_missing(
300            "FibRuleAttrs",
301            "Table",
302            self.orig_loc,
303            self.buf.as_ptr() as usize,
304        ))
305    }
306    pub fn get_fwmask(&self) -> Result<u32, ErrorContext> {
307        let mut iter = self.clone();
308        iter.pos = 0;
309        for attr in iter {
310            if let FibRuleAttrs::Fwmask(val) = attr? {
311                return Ok(val);
312            }
313        }
314        Err(ErrorContext::new_missing(
315            "FibRuleAttrs",
316            "Fwmask",
317            self.orig_loc,
318            self.buf.as_ptr() as usize,
319        ))
320    }
321    pub fn get_oifname(&self) -> Result<&'a CStr, ErrorContext> {
322        let mut iter = self.clone();
323        iter.pos = 0;
324        for attr in iter {
325            if let FibRuleAttrs::Oifname(val) = attr? {
326                return Ok(val);
327            }
328        }
329        Err(ErrorContext::new_missing(
330            "FibRuleAttrs",
331            "Oifname",
332            self.orig_loc,
333            self.buf.as_ptr() as usize,
334        ))
335    }
336    pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
337        let mut iter = self.clone();
338        iter.pos = 0;
339        for attr in iter {
340            if let FibRuleAttrs::Pad(val) = attr? {
341                return Ok(val);
342            }
343        }
344        Err(ErrorContext::new_missing(
345            "FibRuleAttrs",
346            "Pad",
347            self.orig_loc,
348            self.buf.as_ptr() as usize,
349        ))
350    }
351    pub fn get_l3mdev(&self) -> Result<u8, ErrorContext> {
352        let mut iter = self.clone();
353        iter.pos = 0;
354        for attr in iter {
355            if let FibRuleAttrs::L3mdev(val) = attr? {
356                return Ok(val);
357            }
358        }
359        Err(ErrorContext::new_missing(
360            "FibRuleAttrs",
361            "L3mdev",
362            self.orig_loc,
363            self.buf.as_ptr() as usize,
364        ))
365    }
366    pub fn get_uid_range(&self) -> Result<PushFibRuleUidRange, ErrorContext> {
367        let mut iter = self.clone();
368        iter.pos = 0;
369        for attr in iter {
370            if let FibRuleAttrs::UidRange(val) = attr? {
371                return Ok(val);
372            }
373        }
374        Err(ErrorContext::new_missing(
375            "FibRuleAttrs",
376            "UidRange",
377            self.orig_loc,
378            self.buf.as_ptr() as usize,
379        ))
380    }
381    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
382        let mut iter = self.clone();
383        iter.pos = 0;
384        for attr in iter {
385            if let FibRuleAttrs::Protocol(val) = attr? {
386                return Ok(val);
387            }
388        }
389        Err(ErrorContext::new_missing(
390            "FibRuleAttrs",
391            "Protocol",
392            self.orig_loc,
393            self.buf.as_ptr() as usize,
394        ))
395    }
396    pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
397        let mut iter = self.clone();
398        iter.pos = 0;
399        for attr in iter {
400            if let FibRuleAttrs::IpProto(val) = attr? {
401                return Ok(val);
402            }
403        }
404        Err(ErrorContext::new_missing(
405            "FibRuleAttrs",
406            "IpProto",
407            self.orig_loc,
408            self.buf.as_ptr() as usize,
409        ))
410    }
411    pub fn get_sport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
412        let mut iter = self.clone();
413        iter.pos = 0;
414        for attr in iter {
415            if let FibRuleAttrs::SportRange(val) = attr? {
416                return Ok(val);
417            }
418        }
419        Err(ErrorContext::new_missing(
420            "FibRuleAttrs",
421            "SportRange",
422            self.orig_loc,
423            self.buf.as_ptr() as usize,
424        ))
425    }
426    pub fn get_dport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
427        let mut iter = self.clone();
428        iter.pos = 0;
429        for attr in iter {
430            if let FibRuleAttrs::DportRange(val) = attr? {
431                return Ok(val);
432            }
433        }
434        Err(ErrorContext::new_missing(
435            "FibRuleAttrs",
436            "DportRange",
437            self.orig_loc,
438            self.buf.as_ptr() as usize,
439        ))
440    }
441    pub fn get_dscp(&self) -> Result<u8, ErrorContext> {
442        let mut iter = self.clone();
443        iter.pos = 0;
444        for attr in iter {
445            if let FibRuleAttrs::Dscp(val) = attr? {
446                return Ok(val);
447            }
448        }
449        Err(ErrorContext::new_missing(
450            "FibRuleAttrs",
451            "Dscp",
452            self.orig_loc,
453            self.buf.as_ptr() as usize,
454        ))
455    }
456    pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
457        let mut iter = self.clone();
458        iter.pos = 0;
459        for attr in iter {
460            if let FibRuleAttrs::Flowlabel(val) = attr? {
461                return Ok(val);
462            }
463        }
464        Err(ErrorContext::new_missing(
465            "FibRuleAttrs",
466            "Flowlabel",
467            self.orig_loc,
468            self.buf.as_ptr() as usize,
469        ))
470    }
471    pub fn get_flowlabel_mask(&self) -> Result<u32, ErrorContext> {
472        let mut iter = self.clone();
473        iter.pos = 0;
474        for attr in iter {
475            if let FibRuleAttrs::FlowlabelMask(val) = attr? {
476                return Ok(val);
477            }
478        }
479        Err(ErrorContext::new_missing(
480            "FibRuleAttrs",
481            "FlowlabelMask",
482            self.orig_loc,
483            self.buf.as_ptr() as usize,
484        ))
485    }
486    pub fn get_sport_mask(&self) -> Result<u16, ErrorContext> {
487        let mut iter = self.clone();
488        iter.pos = 0;
489        for attr in iter {
490            if let FibRuleAttrs::SportMask(val) = attr? {
491                return Ok(val);
492            }
493        }
494        Err(ErrorContext::new_missing(
495            "FibRuleAttrs",
496            "SportMask",
497            self.orig_loc,
498            self.buf.as_ptr() as usize,
499        ))
500    }
501    pub fn get_dport_mask(&self) -> Result<u16, ErrorContext> {
502        let mut iter = self.clone();
503        iter.pos = 0;
504        for attr in iter {
505            if let FibRuleAttrs::DportMask(val) = attr? {
506                return Ok(val);
507            }
508        }
509        Err(ErrorContext::new_missing(
510            "FibRuleAttrs",
511            "DportMask",
512            self.orig_loc,
513            self.buf.as_ptr() as usize,
514        ))
515    }
516    pub fn get_dscp_mask(&self) -> Result<u8, ErrorContext> {
517        let mut iter = self.clone();
518        iter.pos = 0;
519        for attr in iter {
520            if let FibRuleAttrs::DscpMask(val) = attr? {
521                return Ok(val);
522            }
523        }
524        Err(ErrorContext::new_missing(
525            "FibRuleAttrs",
526            "DscpMask",
527            self.orig_loc,
528            self.buf.as_ptr() as usize,
529        ))
530    }
531}
532impl FibRuleAttrs<'_> {
533    pub fn new<'a>(buf: &'a [u8]) -> IterableFibRuleAttrs<'a> {
534        IterableFibRuleAttrs::with_loc(buf, buf.as_ptr() as usize)
535    }
536    fn attr_from_type(r#type: u16) -> Option<&'static str> {
537        let res = match r#type {
538            1u16 => "Dst",
539            2u16 => "Src",
540            3u16 => "Iifname",
541            4u16 => "Goto",
542            5u16 => "Unused2",
543            6u16 => "Priority",
544            7u16 => "Unused3",
545            8u16 => "Unused4",
546            9u16 => "Unused5",
547            10u16 => "Fwmark",
548            11u16 => "Flow",
549            12u16 => "TunId",
550            13u16 => "SuppressIfgroup",
551            14u16 => "SuppressPrefixlen",
552            15u16 => "Table",
553            16u16 => "Fwmask",
554            17u16 => "Oifname",
555            18u16 => "Pad",
556            19u16 => "L3mdev",
557            20u16 => "UidRange",
558            21u16 => "Protocol",
559            22u16 => "IpProto",
560            23u16 => "SportRange",
561            24u16 => "DportRange",
562            25u16 => "Dscp",
563            26u16 => "Flowlabel",
564            27u16 => "FlowlabelMask",
565            28u16 => "SportMask",
566            29u16 => "DportMask",
567            30u16 => "DscpMask",
568            _ => return None,
569        };
570        Some(res)
571    }
572}
573#[derive(Clone, Copy, Default)]
574pub struct IterableFibRuleAttrs<'a> {
575    buf: &'a [u8],
576    pos: usize,
577    orig_loc: usize,
578}
579impl<'a> IterableFibRuleAttrs<'a> {
580    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
581        Self {
582            buf,
583            pos: 0,
584            orig_loc,
585        }
586    }
587    pub fn get_buf(&self) -> &'a [u8] {
588        self.buf
589    }
590}
591impl<'a> Iterator for IterableFibRuleAttrs<'a> {
592    type Item = Result<FibRuleAttrs<'a>, ErrorContext>;
593    fn next(&mut self) -> Option<Self::Item> {
594        let pos = self.pos;
595        let mut r#type;
596        loop {
597            r#type = None;
598            if self.buf.len() == self.pos {
599                return None;
600            }
601            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
602                break;
603            };
604            r#type = Some(header.r#type);
605            let res = match header.r#type {
606                1u16 => FibRuleAttrs::Dst({
607                    let res = parse_u32(next);
608                    let Some(val) = res else { break };
609                    val
610                }),
611                2u16 => FibRuleAttrs::Src({
612                    let res = parse_u32(next);
613                    let Some(val) = res else { break };
614                    val
615                }),
616                3u16 => FibRuleAttrs::Iifname({
617                    let res = CStr::from_bytes_with_nul(next).ok();
618                    let Some(val) = res else { break };
619                    val
620                }),
621                4u16 => FibRuleAttrs::Goto({
622                    let res = parse_u32(next);
623                    let Some(val) = res else { break };
624                    val
625                }),
626                5u16 => FibRuleAttrs::Unused2({
627                    let res = Some(next);
628                    let Some(val) = res else { break };
629                    val
630                }),
631                6u16 => FibRuleAttrs::Priority({
632                    let res = parse_u32(next);
633                    let Some(val) = res else { break };
634                    val
635                }),
636                7u16 => FibRuleAttrs::Unused3({
637                    let res = Some(next);
638                    let Some(val) = res else { break };
639                    val
640                }),
641                8u16 => FibRuleAttrs::Unused4({
642                    let res = Some(next);
643                    let Some(val) = res else { break };
644                    val
645                }),
646                9u16 => FibRuleAttrs::Unused5({
647                    let res = Some(next);
648                    let Some(val) = res else { break };
649                    val
650                }),
651                10u16 => FibRuleAttrs::Fwmark({
652                    let res = parse_u32(next);
653                    let Some(val) = res else { break };
654                    val
655                }),
656                11u16 => FibRuleAttrs::Flow({
657                    let res = parse_u32(next);
658                    let Some(val) = res else { break };
659                    val
660                }),
661                12u16 => FibRuleAttrs::TunId({
662                    let res = parse_u64(next);
663                    let Some(val) = res else { break };
664                    val
665                }),
666                13u16 => FibRuleAttrs::SuppressIfgroup({
667                    let res = parse_u32(next);
668                    let Some(val) = res else { break };
669                    val
670                }),
671                14u16 => FibRuleAttrs::SuppressPrefixlen({
672                    let res = parse_u32(next);
673                    let Some(val) = res else { break };
674                    val
675                }),
676                15u16 => FibRuleAttrs::Table({
677                    let res = parse_u32(next);
678                    let Some(val) = res else { break };
679                    val
680                }),
681                16u16 => FibRuleAttrs::Fwmask({
682                    let res = parse_u32(next);
683                    let Some(val) = res else { break };
684                    val
685                }),
686                17u16 => FibRuleAttrs::Oifname({
687                    let res = CStr::from_bytes_with_nul(next).ok();
688                    let Some(val) = res else { break };
689                    val
690                }),
691                18u16 => FibRuleAttrs::Pad({
692                    let res = Some(next);
693                    let Some(val) = res else { break };
694                    val
695                }),
696                19u16 => FibRuleAttrs::L3mdev({
697                    let res = parse_u8(next);
698                    let Some(val) = res else { break };
699                    val
700                }),
701                20u16 => FibRuleAttrs::UidRange({
702                    let res = PushFibRuleUidRange::new_from_slice(next);
703                    let Some(val) = res else { break };
704                    val
705                }),
706                21u16 => FibRuleAttrs::Protocol({
707                    let res = parse_u8(next);
708                    let Some(val) = res else { break };
709                    val
710                }),
711                22u16 => FibRuleAttrs::IpProto({
712                    let res = parse_u8(next);
713                    let Some(val) = res else { break };
714                    val
715                }),
716                23u16 => FibRuleAttrs::SportRange({
717                    let res = PushFibRulePortRange::new_from_slice(next);
718                    let Some(val) = res else { break };
719                    val
720                }),
721                24u16 => FibRuleAttrs::DportRange({
722                    let res = PushFibRulePortRange::new_from_slice(next);
723                    let Some(val) = res else { break };
724                    val
725                }),
726                25u16 => FibRuleAttrs::Dscp({
727                    let res = parse_u8(next);
728                    let Some(val) = res else { break };
729                    val
730                }),
731                26u16 => FibRuleAttrs::Flowlabel({
732                    let res = parse_be_u32(next);
733                    let Some(val) = res else { break };
734                    val
735                }),
736                27u16 => FibRuleAttrs::FlowlabelMask({
737                    let res = parse_be_u32(next);
738                    let Some(val) = res else { break };
739                    val
740                }),
741                28u16 => FibRuleAttrs::SportMask({
742                    let res = parse_u16(next);
743                    let Some(val) = res else { break };
744                    val
745                }),
746                29u16 => FibRuleAttrs::DportMask({
747                    let res = parse_u16(next);
748                    let Some(val) = res else { break };
749                    val
750                }),
751                30u16 => FibRuleAttrs::DscpMask({
752                    let res = parse_u8(next);
753                    let Some(val) = res else { break };
754                    val
755                }),
756                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
757                n => continue,
758            };
759            return Some(Ok(res));
760        }
761        Some(Err(ErrorContext::new(
762            "FibRuleAttrs",
763            r#type.and_then(|t| FibRuleAttrs::attr_from_type(t)),
764            self.orig_loc,
765            self.buf.as_ptr().wrapping_add(pos) as usize,
766        )))
767    }
768}
769impl<'a> std::fmt::Debug for IterableFibRuleAttrs<'_> {
770    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
771        let mut fmt = f.debug_struct("FibRuleAttrs");
772        for attr in self.clone() {
773            let attr = match attr {
774                Ok(a) => a,
775                Err(err) => {
776                    fmt.finish()?;
777                    f.write_str("Err(")?;
778                    err.fmt(f)?;
779                    return f.write_str(")");
780                }
781            };
782            match attr {
783                FibRuleAttrs::Dst(val) => fmt.field("Dst", &val),
784                FibRuleAttrs::Src(val) => fmt.field("Src", &val),
785                FibRuleAttrs::Iifname(val) => fmt.field("Iifname", &val),
786                FibRuleAttrs::Goto(val) => fmt.field("Goto", &val),
787                FibRuleAttrs::Unused2(val) => fmt.field("Unused2", &val),
788                FibRuleAttrs::Priority(val) => fmt.field("Priority", &val),
789                FibRuleAttrs::Unused3(val) => fmt.field("Unused3", &val),
790                FibRuleAttrs::Unused4(val) => fmt.field("Unused4", &val),
791                FibRuleAttrs::Unused5(val) => fmt.field("Unused5", &val),
792                FibRuleAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
793                FibRuleAttrs::Flow(val) => fmt.field("Flow", &val),
794                FibRuleAttrs::TunId(val) => fmt.field("TunId", &val),
795                FibRuleAttrs::SuppressIfgroup(val) => fmt.field("SuppressIfgroup", &val),
796                FibRuleAttrs::SuppressPrefixlen(val) => fmt.field("SuppressPrefixlen", &val),
797                FibRuleAttrs::Table(val) => fmt.field("Table", &val),
798                FibRuleAttrs::Fwmask(val) => fmt.field("Fwmask", &val),
799                FibRuleAttrs::Oifname(val) => fmt.field("Oifname", &val),
800                FibRuleAttrs::Pad(val) => fmt.field("Pad", &val),
801                FibRuleAttrs::L3mdev(val) => fmt.field("L3mdev", &val),
802                FibRuleAttrs::UidRange(val) => fmt.field("UidRange", &val),
803                FibRuleAttrs::Protocol(val) => fmt.field("Protocol", &val),
804                FibRuleAttrs::IpProto(val) => fmt.field("IpProto", &val),
805                FibRuleAttrs::SportRange(val) => fmt.field("SportRange", &val),
806                FibRuleAttrs::DportRange(val) => fmt.field("DportRange", &val),
807                FibRuleAttrs::Dscp(val) => fmt.field("Dscp", &val),
808                FibRuleAttrs::Flowlabel(val) => fmt.field("Flowlabel", &val),
809                FibRuleAttrs::FlowlabelMask(val) => fmt.field("FlowlabelMask", &val),
810                FibRuleAttrs::SportMask(val) => fmt.field("SportMask", &val),
811                FibRuleAttrs::DportMask(val) => fmt.field("DportMask", &val),
812                FibRuleAttrs::DscpMask(val) => fmt.field("DscpMask", &val),
813            };
814        }
815        fmt.finish()
816    }
817}
818impl IterableFibRuleAttrs<'_> {
819    pub fn lookup_attr(
820        &self,
821        offset: usize,
822        missing_type: Option<u16>,
823    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
824        let mut stack = Vec::new();
825        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
826        if cur == offset {
827            stack.push(("FibRuleAttrs", offset));
828            return (
829                stack,
830                missing_type.and_then(|t| FibRuleAttrs::attr_from_type(t)),
831            );
832        }
833        if cur > offset || cur + self.buf.len() < offset {
834            return (stack, None);
835        }
836        let mut attrs = self.clone();
837        let mut last_off = cur + attrs.pos;
838        while let Some(attr) = attrs.next() {
839            let Ok(attr) = attr else { break };
840            match attr {
841                FibRuleAttrs::Dst(val) => {
842                    if last_off == offset {
843                        stack.push(("Dst", last_off));
844                        break;
845                    }
846                }
847                FibRuleAttrs::Src(val) => {
848                    if last_off == offset {
849                        stack.push(("Src", last_off));
850                        break;
851                    }
852                }
853                FibRuleAttrs::Iifname(val) => {
854                    if last_off == offset {
855                        stack.push(("Iifname", last_off));
856                        break;
857                    }
858                }
859                FibRuleAttrs::Goto(val) => {
860                    if last_off == offset {
861                        stack.push(("Goto", last_off));
862                        break;
863                    }
864                }
865                FibRuleAttrs::Unused2(val) => {
866                    if last_off == offset {
867                        stack.push(("Unused2", last_off));
868                        break;
869                    }
870                }
871                FibRuleAttrs::Priority(val) => {
872                    if last_off == offset {
873                        stack.push(("Priority", last_off));
874                        break;
875                    }
876                }
877                FibRuleAttrs::Unused3(val) => {
878                    if last_off == offset {
879                        stack.push(("Unused3", last_off));
880                        break;
881                    }
882                }
883                FibRuleAttrs::Unused4(val) => {
884                    if last_off == offset {
885                        stack.push(("Unused4", last_off));
886                        break;
887                    }
888                }
889                FibRuleAttrs::Unused5(val) => {
890                    if last_off == offset {
891                        stack.push(("Unused5", last_off));
892                        break;
893                    }
894                }
895                FibRuleAttrs::Fwmark(val) => {
896                    if last_off == offset {
897                        stack.push(("Fwmark", last_off));
898                        break;
899                    }
900                }
901                FibRuleAttrs::Flow(val) => {
902                    if last_off == offset {
903                        stack.push(("Flow", last_off));
904                        break;
905                    }
906                }
907                FibRuleAttrs::TunId(val) => {
908                    if last_off == offset {
909                        stack.push(("TunId", last_off));
910                        break;
911                    }
912                }
913                FibRuleAttrs::SuppressIfgroup(val) => {
914                    if last_off == offset {
915                        stack.push(("SuppressIfgroup", last_off));
916                        break;
917                    }
918                }
919                FibRuleAttrs::SuppressPrefixlen(val) => {
920                    if last_off == offset {
921                        stack.push(("SuppressPrefixlen", last_off));
922                        break;
923                    }
924                }
925                FibRuleAttrs::Table(val) => {
926                    if last_off == offset {
927                        stack.push(("Table", last_off));
928                        break;
929                    }
930                }
931                FibRuleAttrs::Fwmask(val) => {
932                    if last_off == offset {
933                        stack.push(("Fwmask", last_off));
934                        break;
935                    }
936                }
937                FibRuleAttrs::Oifname(val) => {
938                    if last_off == offset {
939                        stack.push(("Oifname", last_off));
940                        break;
941                    }
942                }
943                FibRuleAttrs::Pad(val) => {
944                    if last_off == offset {
945                        stack.push(("Pad", last_off));
946                        break;
947                    }
948                }
949                FibRuleAttrs::L3mdev(val) => {
950                    if last_off == offset {
951                        stack.push(("L3mdev", last_off));
952                        break;
953                    }
954                }
955                FibRuleAttrs::UidRange(val) => {
956                    if last_off == offset {
957                        stack.push(("UidRange", last_off));
958                        break;
959                    }
960                }
961                FibRuleAttrs::Protocol(val) => {
962                    if last_off == offset {
963                        stack.push(("Protocol", last_off));
964                        break;
965                    }
966                }
967                FibRuleAttrs::IpProto(val) => {
968                    if last_off == offset {
969                        stack.push(("IpProto", last_off));
970                        break;
971                    }
972                }
973                FibRuleAttrs::SportRange(val) => {
974                    if last_off == offset {
975                        stack.push(("SportRange", last_off));
976                        break;
977                    }
978                }
979                FibRuleAttrs::DportRange(val) => {
980                    if last_off == offset {
981                        stack.push(("DportRange", last_off));
982                        break;
983                    }
984                }
985                FibRuleAttrs::Dscp(val) => {
986                    if last_off == offset {
987                        stack.push(("Dscp", last_off));
988                        break;
989                    }
990                }
991                FibRuleAttrs::Flowlabel(val) => {
992                    if last_off == offset {
993                        stack.push(("Flowlabel", last_off));
994                        break;
995                    }
996                }
997                FibRuleAttrs::FlowlabelMask(val) => {
998                    if last_off == offset {
999                        stack.push(("FlowlabelMask", last_off));
1000                        break;
1001                    }
1002                }
1003                FibRuleAttrs::SportMask(val) => {
1004                    if last_off == offset {
1005                        stack.push(("SportMask", last_off));
1006                        break;
1007                    }
1008                }
1009                FibRuleAttrs::DportMask(val) => {
1010                    if last_off == offset {
1011                        stack.push(("DportMask", last_off));
1012                        break;
1013                    }
1014                }
1015                FibRuleAttrs::DscpMask(val) => {
1016                    if last_off == offset {
1017                        stack.push(("DscpMask", last_off));
1018                        break;
1019                    }
1020                }
1021                _ => {}
1022            };
1023            last_off = cur + attrs.pos;
1024        }
1025        if !stack.is_empty() {
1026            stack.push(("FibRuleAttrs", cur));
1027        }
1028        (stack, None)
1029    }
1030}
1031pub struct PushFibRuleAttrs<Prev: Rec> {
1032    pub(crate) prev: Option<Prev>,
1033    pub(crate) header_offset: Option<usize>,
1034}
1035impl<Prev: Rec> Rec for PushFibRuleAttrs<Prev> {
1036    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1037        self.prev.as_mut().unwrap().as_rec_mut()
1038    }
1039    fn as_rec(&self) -> &Vec<u8> {
1040        self.prev.as_ref().unwrap().as_rec()
1041    }
1042}
1043impl<Prev: Rec> PushFibRuleAttrs<Prev> {
1044    pub fn new(prev: Prev) -> Self {
1045        Self {
1046            prev: Some(prev),
1047            header_offset: None,
1048        }
1049    }
1050    pub fn end_nested(mut self) -> Prev {
1051        let mut prev = self.prev.take().unwrap();
1052        if let Some(header_offset) = &self.header_offset {
1053            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1054        }
1055        prev
1056    }
1057    pub fn push_dst(mut self, value: u32) -> Self {
1058        push_header(self.as_rec_mut(), 1u16, 4 as u16);
1059        self.as_rec_mut().extend(value.to_ne_bytes());
1060        self
1061    }
1062    pub fn push_src(mut self, value: u32) -> Self {
1063        push_header(self.as_rec_mut(), 2u16, 4 as u16);
1064        self.as_rec_mut().extend(value.to_ne_bytes());
1065        self
1066    }
1067    pub fn push_iifname(mut self, value: &CStr) -> Self {
1068        push_header(
1069            self.as_rec_mut(),
1070            3u16,
1071            value.to_bytes_with_nul().len() as u16,
1072        );
1073        self.as_rec_mut().extend(value.to_bytes_with_nul());
1074        self
1075    }
1076    pub fn push_iifname_bytes(mut self, value: &[u8]) -> Self {
1077        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
1078        self.as_rec_mut().extend(value);
1079        self.as_rec_mut().push(0);
1080        self
1081    }
1082    pub fn push_goto(mut self, value: u32) -> Self {
1083        push_header(self.as_rec_mut(), 4u16, 4 as u16);
1084        self.as_rec_mut().extend(value.to_ne_bytes());
1085        self
1086    }
1087    pub fn push_unused2(mut self, value: &[u8]) -> Self {
1088        push_header(self.as_rec_mut(), 5u16, value.len() as u16);
1089        self.as_rec_mut().extend(value);
1090        self
1091    }
1092    pub fn push_priority(mut self, value: u32) -> Self {
1093        push_header(self.as_rec_mut(), 6u16, 4 as u16);
1094        self.as_rec_mut().extend(value.to_ne_bytes());
1095        self
1096    }
1097    pub fn push_unused3(mut self, value: &[u8]) -> Self {
1098        push_header(self.as_rec_mut(), 7u16, value.len() as u16);
1099        self.as_rec_mut().extend(value);
1100        self
1101    }
1102    pub fn push_unused4(mut self, value: &[u8]) -> Self {
1103        push_header(self.as_rec_mut(), 8u16, value.len() as u16);
1104        self.as_rec_mut().extend(value);
1105        self
1106    }
1107    pub fn push_unused5(mut self, value: &[u8]) -> Self {
1108        push_header(self.as_rec_mut(), 9u16, value.len() as u16);
1109        self.as_rec_mut().extend(value);
1110        self
1111    }
1112    pub fn push_fwmark(mut self, value: u32) -> Self {
1113        push_header(self.as_rec_mut(), 10u16, 4 as u16);
1114        self.as_rec_mut().extend(value.to_ne_bytes());
1115        self
1116    }
1117    pub fn push_flow(mut self, value: u32) -> Self {
1118        push_header(self.as_rec_mut(), 11u16, 4 as u16);
1119        self.as_rec_mut().extend(value.to_ne_bytes());
1120        self
1121    }
1122    pub fn push_tun_id(mut self, value: u64) -> Self {
1123        push_header(self.as_rec_mut(), 12u16, 8 as u16);
1124        self.as_rec_mut().extend(value.to_ne_bytes());
1125        self
1126    }
1127    pub fn push_suppress_ifgroup(mut self, value: u32) -> Self {
1128        push_header(self.as_rec_mut(), 13u16, 4 as u16);
1129        self.as_rec_mut().extend(value.to_ne_bytes());
1130        self
1131    }
1132    pub fn push_suppress_prefixlen(mut self, value: u32) -> Self {
1133        push_header(self.as_rec_mut(), 14u16, 4 as u16);
1134        self.as_rec_mut().extend(value.to_ne_bytes());
1135        self
1136    }
1137    pub fn push_table(mut self, value: u32) -> Self {
1138        push_header(self.as_rec_mut(), 15u16, 4 as u16);
1139        self.as_rec_mut().extend(value.to_ne_bytes());
1140        self
1141    }
1142    pub fn push_fwmask(mut self, value: u32) -> Self {
1143        push_header(self.as_rec_mut(), 16u16, 4 as u16);
1144        self.as_rec_mut().extend(value.to_ne_bytes());
1145        self
1146    }
1147    pub fn push_oifname(mut self, value: &CStr) -> Self {
1148        push_header(
1149            self.as_rec_mut(),
1150            17u16,
1151            value.to_bytes_with_nul().len() as u16,
1152        );
1153        self.as_rec_mut().extend(value.to_bytes_with_nul());
1154        self
1155    }
1156    pub fn push_oifname_bytes(mut self, value: &[u8]) -> Self {
1157        push_header(self.as_rec_mut(), 17u16, (value.len() + 1) as u16);
1158        self.as_rec_mut().extend(value);
1159        self.as_rec_mut().push(0);
1160        self
1161    }
1162    pub fn push_pad(mut self, value: &[u8]) -> Self {
1163        push_header(self.as_rec_mut(), 18u16, value.len() as u16);
1164        self.as_rec_mut().extend(value);
1165        self
1166    }
1167    pub fn push_l3mdev(mut self, value: u8) -> Self {
1168        push_header(self.as_rec_mut(), 19u16, 1 as u16);
1169        self.as_rec_mut().extend(value.to_ne_bytes());
1170        self
1171    }
1172    pub fn push_uid_range(mut self, value: PushFibRuleUidRange) -> Self {
1173        push_header(self.as_rec_mut(), 20u16, value.as_slice().len() as u16);
1174        self.as_rec_mut().extend(value.as_slice());
1175        self
1176    }
1177    pub fn push_protocol(mut self, value: u8) -> Self {
1178        push_header(self.as_rec_mut(), 21u16, 1 as u16);
1179        self.as_rec_mut().extend(value.to_ne_bytes());
1180        self
1181    }
1182    pub fn push_ip_proto(mut self, value: u8) -> Self {
1183        push_header(self.as_rec_mut(), 22u16, 1 as u16);
1184        self.as_rec_mut().extend(value.to_ne_bytes());
1185        self
1186    }
1187    pub fn push_sport_range(mut self, value: PushFibRulePortRange) -> Self {
1188        push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
1189        self.as_rec_mut().extend(value.as_slice());
1190        self
1191    }
1192    pub fn push_dport_range(mut self, value: PushFibRulePortRange) -> Self {
1193        push_header(self.as_rec_mut(), 24u16, value.as_slice().len() as u16);
1194        self.as_rec_mut().extend(value.as_slice());
1195        self
1196    }
1197    pub fn push_dscp(mut self, value: u8) -> Self {
1198        push_header(self.as_rec_mut(), 25u16, 1 as u16);
1199        self.as_rec_mut().extend(value.to_ne_bytes());
1200        self
1201    }
1202    pub fn push_flowlabel(mut self, value: u32) -> Self {
1203        push_header(self.as_rec_mut(), 26u16, 4 as u16);
1204        self.as_rec_mut().extend(value.to_be_bytes());
1205        self
1206    }
1207    pub fn push_flowlabel_mask(mut self, value: u32) -> Self {
1208        push_header(self.as_rec_mut(), 27u16, 4 as u16);
1209        self.as_rec_mut().extend(value.to_be_bytes());
1210        self
1211    }
1212    pub fn push_sport_mask(mut self, value: u16) -> Self {
1213        push_header(self.as_rec_mut(), 28u16, 2 as u16);
1214        self.as_rec_mut().extend(value.to_ne_bytes());
1215        self
1216    }
1217    pub fn push_dport_mask(mut self, value: u16) -> Self {
1218        push_header(self.as_rec_mut(), 29u16, 2 as u16);
1219        self.as_rec_mut().extend(value.to_ne_bytes());
1220        self
1221    }
1222    pub fn push_dscp_mask(mut self, value: u8) -> Self {
1223        push_header(self.as_rec_mut(), 30u16, 1 as u16);
1224        self.as_rec_mut().extend(value.to_ne_bytes());
1225        self
1226    }
1227}
1228impl<Prev: Rec> Drop for PushFibRuleAttrs<Prev> {
1229    fn drop(&mut self) {
1230        if let Some(prev) = &mut self.prev {
1231            if let Some(header_offset) = &self.header_offset {
1232                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1233            }
1234        }
1235    }
1236}
1237#[derive(Clone)]
1238pub struct PushRtgenmsg {
1239    pub(crate) buf: [u8; 4usize],
1240}
1241#[doc = "Create zero-initialized struct"]
1242impl Default for PushRtgenmsg {
1243    fn default() -> Self {
1244        Self { buf: [0u8; 4usize] }
1245    }
1246}
1247impl PushRtgenmsg {
1248    #[doc = "Create zero-initialized struct"]
1249    pub fn new() -> Self {
1250        Default::default()
1251    }
1252    #[doc = "Copy from contents from other slice"]
1253    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1254        if other.len() != Self::len() {
1255            return None;
1256        }
1257        let mut buf = [0u8; Self::len()];
1258        buf.clone_from_slice(other);
1259        Some(Self { buf })
1260    }
1261    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1262    pub fn new_from_zeroed(other: &[u8]) -> Self {
1263        let mut buf = [0u8; Self::len()];
1264        let len = buf.len().min(other.len());
1265        buf[..len].clone_from_slice(&other[..len]);
1266        Self { buf }
1267    }
1268    pub fn as_slice(&self) -> &[u8] {
1269        &self.buf
1270    }
1271    pub fn as_mut_slice(&mut self) -> &mut [u8] {
1272        &mut self.buf
1273    }
1274    pub const fn len() -> usize {
1275        4usize
1276    }
1277    pub fn family(&self) -> u8 {
1278        parse_u8(&self.buf[0usize..1usize]).unwrap()
1279    }
1280    pub fn set_family(&mut self, value: u8) {
1281        self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
1282    }
1283}
1284impl std::fmt::Debug for PushRtgenmsg {
1285    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1286        fmt.debug_struct("Rtgenmsg")
1287            .field("family", &self.family())
1288            .finish()
1289    }
1290}
1291#[derive(Clone)]
1292pub struct PushFibRuleHdr {
1293    pub(crate) buf: [u8; 12usize],
1294}
1295#[doc = "Create zero-initialized struct"]
1296impl Default for PushFibRuleHdr {
1297    fn default() -> Self {
1298        Self {
1299            buf: [0u8; 12usize],
1300        }
1301    }
1302}
1303impl PushFibRuleHdr {
1304    #[doc = "Create zero-initialized struct"]
1305    pub fn new() -> Self {
1306        Default::default()
1307    }
1308    #[doc = "Copy from contents from other slice"]
1309    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1310        if other.len() != Self::len() {
1311            return None;
1312        }
1313        let mut buf = [0u8; Self::len()];
1314        buf.clone_from_slice(other);
1315        Some(Self { buf })
1316    }
1317    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1318    pub fn new_from_zeroed(other: &[u8]) -> Self {
1319        let mut buf = [0u8; Self::len()];
1320        let len = buf.len().min(other.len());
1321        buf[..len].clone_from_slice(&other[..len]);
1322        Self { buf }
1323    }
1324    pub fn as_slice(&self) -> &[u8] {
1325        &self.buf
1326    }
1327    pub fn as_mut_slice(&mut self) -> &mut [u8] {
1328        &mut self.buf
1329    }
1330    pub const fn len() -> usize {
1331        12usize
1332    }
1333    pub fn family(&self) -> u8 {
1334        parse_u8(&self.buf[0usize..1usize]).unwrap()
1335    }
1336    pub fn set_family(&mut self, value: u8) {
1337        self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
1338    }
1339    pub fn dst_len(&self) -> u8 {
1340        parse_u8(&self.buf[1usize..2usize]).unwrap()
1341    }
1342    pub fn set_dst_len(&mut self, value: u8) {
1343        self.buf[1usize..2usize].copy_from_slice(&value.to_ne_bytes())
1344    }
1345    pub fn src_len(&self) -> u8 {
1346        parse_u8(&self.buf[2usize..3usize]).unwrap()
1347    }
1348    pub fn set_src_len(&mut self, value: u8) {
1349        self.buf[2usize..3usize].copy_from_slice(&value.to_ne_bytes())
1350    }
1351    pub fn tos(&self) -> u8 {
1352        parse_u8(&self.buf[3usize..4usize]).unwrap()
1353    }
1354    pub fn set_tos(&mut self, value: u8) {
1355        self.buf[3usize..4usize].copy_from_slice(&value.to_ne_bytes())
1356    }
1357    pub fn table(&self) -> u8 {
1358        parse_u8(&self.buf[4usize..5usize]).unwrap()
1359    }
1360    pub fn set_table(&mut self, value: u8) {
1361        self.buf[4usize..5usize].copy_from_slice(&value.to_ne_bytes())
1362    }
1363    #[doc = "Associated type: \"FrAct\" (enum)"]
1364    pub fn action(&self) -> u8 {
1365        parse_u8(&self.buf[7usize..8usize]).unwrap()
1366    }
1367    #[doc = "Associated type: \"FrAct\" (enum)"]
1368    pub fn set_action(&mut self, value: u8) {
1369        self.buf[7usize..8usize].copy_from_slice(&value.to_ne_bytes())
1370    }
1371    pub fn flags(&self) -> u32 {
1372        parse_u32(&self.buf[8usize..12usize]).unwrap()
1373    }
1374    pub fn set_flags(&mut self, value: u32) {
1375        self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
1376    }
1377}
1378impl std::fmt::Debug for PushFibRuleHdr {
1379    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1380        fmt.debug_struct("FibRuleHdr")
1381            .field("family", &self.family())
1382            .field("dst_len", &self.dst_len())
1383            .field("src_len", &self.src_len())
1384            .field("tos", &self.tos())
1385            .field("table", &self.table())
1386            .field(
1387                "action",
1388                &FormatEnum(self.action().into(), FrAct::from_value),
1389            )
1390            .field("flags", &self.flags())
1391            .finish()
1392    }
1393}
1394#[derive(Clone)]
1395pub struct PushFibRulePortRange {
1396    pub(crate) buf: [u8; 4usize],
1397}
1398#[doc = "Create zero-initialized struct"]
1399impl Default for PushFibRulePortRange {
1400    fn default() -> Self {
1401        Self { buf: [0u8; 4usize] }
1402    }
1403}
1404impl PushFibRulePortRange {
1405    #[doc = "Create zero-initialized struct"]
1406    pub fn new() -> Self {
1407        Default::default()
1408    }
1409    #[doc = "Copy from contents from other slice"]
1410    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1411        if other.len() != Self::len() {
1412            return None;
1413        }
1414        let mut buf = [0u8; Self::len()];
1415        buf.clone_from_slice(other);
1416        Some(Self { buf })
1417    }
1418    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1419    pub fn new_from_zeroed(other: &[u8]) -> Self {
1420        let mut buf = [0u8; Self::len()];
1421        let len = buf.len().min(other.len());
1422        buf[..len].clone_from_slice(&other[..len]);
1423        Self { buf }
1424    }
1425    pub fn as_slice(&self) -> &[u8] {
1426        &self.buf
1427    }
1428    pub fn as_mut_slice(&mut self) -> &mut [u8] {
1429        &mut self.buf
1430    }
1431    pub const fn len() -> usize {
1432        4usize
1433    }
1434    pub fn start(&self) -> u16 {
1435        parse_u16(&self.buf[0usize..2usize]).unwrap()
1436    }
1437    pub fn set_start(&mut self, value: u16) {
1438        self.buf[0usize..2usize].copy_from_slice(&value.to_ne_bytes())
1439    }
1440    pub fn end(&self) -> u16 {
1441        parse_u16(&self.buf[2usize..4usize]).unwrap()
1442    }
1443    pub fn set_end(&mut self, value: u16) {
1444        self.buf[2usize..4usize].copy_from_slice(&value.to_ne_bytes())
1445    }
1446}
1447impl std::fmt::Debug for PushFibRulePortRange {
1448    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1449        fmt.debug_struct("FibRulePortRange")
1450            .field("start", &self.start())
1451            .field("end", &self.end())
1452            .finish()
1453    }
1454}
1455#[derive(Clone)]
1456pub struct PushFibRuleUidRange {
1457    pub(crate) buf: [u8; 8usize],
1458}
1459#[doc = "Create zero-initialized struct"]
1460impl Default for PushFibRuleUidRange {
1461    fn default() -> Self {
1462        Self { buf: [0u8; 8usize] }
1463    }
1464}
1465impl PushFibRuleUidRange {
1466    #[doc = "Create zero-initialized struct"]
1467    pub fn new() -> Self {
1468        Default::default()
1469    }
1470    #[doc = "Copy from contents from other slice"]
1471    pub fn new_from_slice(other: &[u8]) -> Option<Self> {
1472        if other.len() != Self::len() {
1473            return None;
1474        }
1475        let mut buf = [0u8; Self::len()];
1476        buf.clone_from_slice(other);
1477        Some(Self { buf })
1478    }
1479    #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
1480    pub fn new_from_zeroed(other: &[u8]) -> Self {
1481        let mut buf = [0u8; Self::len()];
1482        let len = buf.len().min(other.len());
1483        buf[..len].clone_from_slice(&other[..len]);
1484        Self { buf }
1485    }
1486    pub fn as_slice(&self) -> &[u8] {
1487        &self.buf
1488    }
1489    pub fn as_mut_slice(&mut self) -> &mut [u8] {
1490        &mut self.buf
1491    }
1492    pub const fn len() -> usize {
1493        8usize
1494    }
1495    pub fn start(&self) -> u32 {
1496        parse_u32(&self.buf[0usize..4usize]).unwrap()
1497    }
1498    pub fn set_start(&mut self, value: u32) {
1499        self.buf[0usize..4usize].copy_from_slice(&value.to_ne_bytes())
1500    }
1501    pub fn end(&self) -> u32 {
1502        parse_u32(&self.buf[4usize..8usize]).unwrap()
1503    }
1504    pub fn set_end(&mut self, value: u32) {
1505        self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
1506    }
1507}
1508impl std::fmt::Debug for PushFibRuleUidRange {
1509    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1510        fmt.debug_struct("FibRuleUidRange")
1511            .field("start", &self.start())
1512            .field("end", &self.end())
1513            .finish()
1514    }
1515}
1516#[doc = "Add new FIB rule"]
1517pub struct PushOpNewruleDoRequest<Prev: Rec> {
1518    pub(crate) prev: Option<Prev>,
1519    pub(crate) header_offset: Option<usize>,
1520}
1521impl<Prev: Rec> Rec for PushOpNewruleDoRequest<Prev> {
1522    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1523        self.prev.as_mut().unwrap().as_rec_mut()
1524    }
1525    fn as_rec(&self) -> &Vec<u8> {
1526        self.prev.as_ref().unwrap().as_rec()
1527    }
1528}
1529impl<Prev: Rec> PushOpNewruleDoRequest<Prev> {
1530    pub fn new(mut prev: Prev, header: &PushFibRuleHdr) -> Self {
1531        Self::write_header(&mut prev, header);
1532        Self::new_without_header(prev)
1533    }
1534    fn new_without_header(prev: Prev) -> Self {
1535        Self {
1536            prev: Some(prev),
1537            header_offset: None,
1538        }
1539    }
1540    fn write_header(prev: &mut Prev, header: &PushFibRuleHdr) {
1541        prev.as_rec_mut().extend(header.as_slice());
1542    }
1543    pub fn end_nested(mut self) -> Prev {
1544        let mut prev = self.prev.take().unwrap();
1545        if let Some(header_offset) = &self.header_offset {
1546            finalize_nested_header(prev.as_rec_mut(), *header_offset);
1547        }
1548        prev
1549    }
1550    pub fn push_iifname(mut self, value: &CStr) -> Self {
1551        push_header(
1552            self.as_rec_mut(),
1553            3u16,
1554            value.to_bytes_with_nul().len() as u16,
1555        );
1556        self.as_rec_mut().extend(value.to_bytes_with_nul());
1557        self
1558    }
1559    pub fn push_iifname_bytes(mut self, value: &[u8]) -> Self {
1560        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
1561        self.as_rec_mut().extend(value);
1562        self.as_rec_mut().push(0);
1563        self
1564    }
1565    pub fn push_goto(mut self, value: u32) -> Self {
1566        push_header(self.as_rec_mut(), 4u16, 4 as u16);
1567        self.as_rec_mut().extend(value.to_ne_bytes());
1568        self
1569    }
1570    pub fn push_priority(mut self, value: u32) -> Self {
1571        push_header(self.as_rec_mut(), 6u16, 4 as u16);
1572        self.as_rec_mut().extend(value.to_ne_bytes());
1573        self
1574    }
1575    pub fn push_fwmark(mut self, value: u32) -> Self {
1576        push_header(self.as_rec_mut(), 10u16, 4 as u16);
1577        self.as_rec_mut().extend(value.to_ne_bytes());
1578        self
1579    }
1580    pub fn push_flow(mut self, value: u32) -> Self {
1581        push_header(self.as_rec_mut(), 11u16, 4 as u16);
1582        self.as_rec_mut().extend(value.to_ne_bytes());
1583        self
1584    }
1585    pub fn push_tun_id(mut self, value: u64) -> Self {
1586        push_header(self.as_rec_mut(), 12u16, 8 as u16);
1587        self.as_rec_mut().extend(value.to_ne_bytes());
1588        self
1589    }
1590    pub fn push_suppress_ifgroup(mut self, value: u32) -> Self {
1591        push_header(self.as_rec_mut(), 13u16, 4 as u16);
1592        self.as_rec_mut().extend(value.to_ne_bytes());
1593        self
1594    }
1595    pub fn push_suppress_prefixlen(mut self, value: u32) -> Self {
1596        push_header(self.as_rec_mut(), 14u16, 4 as u16);
1597        self.as_rec_mut().extend(value.to_ne_bytes());
1598        self
1599    }
1600    pub fn push_table(mut self, value: u32) -> Self {
1601        push_header(self.as_rec_mut(), 15u16, 4 as u16);
1602        self.as_rec_mut().extend(value.to_ne_bytes());
1603        self
1604    }
1605    pub fn push_fwmask(mut self, value: u32) -> Self {
1606        push_header(self.as_rec_mut(), 16u16, 4 as u16);
1607        self.as_rec_mut().extend(value.to_ne_bytes());
1608        self
1609    }
1610    pub fn push_oifname(mut self, value: &CStr) -> Self {
1611        push_header(
1612            self.as_rec_mut(),
1613            17u16,
1614            value.to_bytes_with_nul().len() as u16,
1615        );
1616        self.as_rec_mut().extend(value.to_bytes_with_nul());
1617        self
1618    }
1619    pub fn push_oifname_bytes(mut self, value: &[u8]) -> Self {
1620        push_header(self.as_rec_mut(), 17u16, (value.len() + 1) as u16);
1621        self.as_rec_mut().extend(value);
1622        self.as_rec_mut().push(0);
1623        self
1624    }
1625    pub fn push_l3mdev(mut self, value: u8) -> Self {
1626        push_header(self.as_rec_mut(), 19u16, 1 as u16);
1627        self.as_rec_mut().extend(value.to_ne_bytes());
1628        self
1629    }
1630    pub fn push_uid_range(mut self, value: PushFibRuleUidRange) -> Self {
1631        push_header(self.as_rec_mut(), 20u16, value.as_slice().len() as u16);
1632        self.as_rec_mut().extend(value.as_slice());
1633        self
1634    }
1635    pub fn push_protocol(mut self, value: u8) -> Self {
1636        push_header(self.as_rec_mut(), 21u16, 1 as u16);
1637        self.as_rec_mut().extend(value.to_ne_bytes());
1638        self
1639    }
1640    pub fn push_ip_proto(mut self, value: u8) -> Self {
1641        push_header(self.as_rec_mut(), 22u16, 1 as u16);
1642        self.as_rec_mut().extend(value.to_ne_bytes());
1643        self
1644    }
1645    pub fn push_sport_range(mut self, value: PushFibRulePortRange) -> Self {
1646        push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
1647        self.as_rec_mut().extend(value.as_slice());
1648        self
1649    }
1650    pub fn push_dport_range(mut self, value: PushFibRulePortRange) -> Self {
1651        push_header(self.as_rec_mut(), 24u16, value.as_slice().len() as u16);
1652        self.as_rec_mut().extend(value.as_slice());
1653        self
1654    }
1655    pub fn push_dscp(mut self, value: u8) -> Self {
1656        push_header(self.as_rec_mut(), 25u16, 1 as u16);
1657        self.as_rec_mut().extend(value.to_ne_bytes());
1658        self
1659    }
1660    pub fn push_flowlabel(mut self, value: u32) -> Self {
1661        push_header(self.as_rec_mut(), 26u16, 4 as u16);
1662        self.as_rec_mut().extend(value.to_be_bytes());
1663        self
1664    }
1665    pub fn push_flowlabel_mask(mut self, value: u32) -> Self {
1666        push_header(self.as_rec_mut(), 27u16, 4 as u16);
1667        self.as_rec_mut().extend(value.to_be_bytes());
1668        self
1669    }
1670    pub fn push_sport_mask(mut self, value: u16) -> Self {
1671        push_header(self.as_rec_mut(), 28u16, 2 as u16);
1672        self.as_rec_mut().extend(value.to_ne_bytes());
1673        self
1674    }
1675    pub fn push_dport_mask(mut self, value: u16) -> Self {
1676        push_header(self.as_rec_mut(), 29u16, 2 as u16);
1677        self.as_rec_mut().extend(value.to_ne_bytes());
1678        self
1679    }
1680    pub fn push_dscp_mask(mut self, value: u8) -> Self {
1681        push_header(self.as_rec_mut(), 30u16, 1 as u16);
1682        self.as_rec_mut().extend(value.to_ne_bytes());
1683        self
1684    }
1685}
1686impl<Prev: Rec> Drop for PushOpNewruleDoRequest<Prev> {
1687    fn drop(&mut self) {
1688        if let Some(prev) = &mut self.prev {
1689            if let Some(header_offset) = &self.header_offset {
1690                finalize_nested_header(prev.as_rec_mut(), *header_offset);
1691            }
1692        }
1693    }
1694}
1695#[doc = "Add new FIB rule"]
1696#[derive(Clone)]
1697pub enum OpNewruleDoRequest<'a> {
1698    Iifname(&'a CStr),
1699    Goto(u32),
1700    Priority(u32),
1701    Fwmark(u32),
1702    Flow(u32),
1703    TunId(u64),
1704    SuppressIfgroup(u32),
1705    SuppressPrefixlen(u32),
1706    Table(u32),
1707    Fwmask(u32),
1708    Oifname(&'a CStr),
1709    L3mdev(u8),
1710    UidRange(PushFibRuleUidRange),
1711    Protocol(u8),
1712    IpProto(u8),
1713    SportRange(PushFibRulePortRange),
1714    DportRange(PushFibRulePortRange),
1715    Dscp(u8),
1716    Flowlabel(u32),
1717    FlowlabelMask(u32),
1718    SportMask(u16),
1719    DportMask(u16),
1720    DscpMask(u8),
1721}
1722impl<'a> IterableOpNewruleDoRequest<'a> {
1723    pub fn get_iifname(&self) -> Result<&'a CStr, ErrorContext> {
1724        let mut iter = self.clone();
1725        iter.pos = 0;
1726        for attr in iter {
1727            if let OpNewruleDoRequest::Iifname(val) = attr? {
1728                return Ok(val);
1729            }
1730        }
1731        Err(ErrorContext::new_missing(
1732            "OpNewruleDoRequest",
1733            "Iifname",
1734            self.orig_loc,
1735            self.buf.as_ptr() as usize,
1736        ))
1737    }
1738    pub fn get_goto(&self) -> Result<u32, ErrorContext> {
1739        let mut iter = self.clone();
1740        iter.pos = 0;
1741        for attr in iter {
1742            if let OpNewruleDoRequest::Goto(val) = attr? {
1743                return Ok(val);
1744            }
1745        }
1746        Err(ErrorContext::new_missing(
1747            "OpNewruleDoRequest",
1748            "Goto",
1749            self.orig_loc,
1750            self.buf.as_ptr() as usize,
1751        ))
1752    }
1753    pub fn get_priority(&self) -> Result<u32, ErrorContext> {
1754        let mut iter = self.clone();
1755        iter.pos = 0;
1756        for attr in iter {
1757            if let OpNewruleDoRequest::Priority(val) = attr? {
1758                return Ok(val);
1759            }
1760        }
1761        Err(ErrorContext::new_missing(
1762            "OpNewruleDoRequest",
1763            "Priority",
1764            self.orig_loc,
1765            self.buf.as_ptr() as usize,
1766        ))
1767    }
1768    pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
1769        let mut iter = self.clone();
1770        iter.pos = 0;
1771        for attr in iter {
1772            if let OpNewruleDoRequest::Fwmark(val) = attr? {
1773                return Ok(val);
1774            }
1775        }
1776        Err(ErrorContext::new_missing(
1777            "OpNewruleDoRequest",
1778            "Fwmark",
1779            self.orig_loc,
1780            self.buf.as_ptr() as usize,
1781        ))
1782    }
1783    pub fn get_flow(&self) -> Result<u32, ErrorContext> {
1784        let mut iter = self.clone();
1785        iter.pos = 0;
1786        for attr in iter {
1787            if let OpNewruleDoRequest::Flow(val) = attr? {
1788                return Ok(val);
1789            }
1790        }
1791        Err(ErrorContext::new_missing(
1792            "OpNewruleDoRequest",
1793            "Flow",
1794            self.orig_loc,
1795            self.buf.as_ptr() as usize,
1796        ))
1797    }
1798    pub fn get_tun_id(&self) -> Result<u64, ErrorContext> {
1799        let mut iter = self.clone();
1800        iter.pos = 0;
1801        for attr in iter {
1802            if let OpNewruleDoRequest::TunId(val) = attr? {
1803                return Ok(val);
1804            }
1805        }
1806        Err(ErrorContext::new_missing(
1807            "OpNewruleDoRequest",
1808            "TunId",
1809            self.orig_loc,
1810            self.buf.as_ptr() as usize,
1811        ))
1812    }
1813    pub fn get_suppress_ifgroup(&self) -> Result<u32, ErrorContext> {
1814        let mut iter = self.clone();
1815        iter.pos = 0;
1816        for attr in iter {
1817            if let OpNewruleDoRequest::SuppressIfgroup(val) = attr? {
1818                return Ok(val);
1819            }
1820        }
1821        Err(ErrorContext::new_missing(
1822            "OpNewruleDoRequest",
1823            "SuppressIfgroup",
1824            self.orig_loc,
1825            self.buf.as_ptr() as usize,
1826        ))
1827    }
1828    pub fn get_suppress_prefixlen(&self) -> Result<u32, ErrorContext> {
1829        let mut iter = self.clone();
1830        iter.pos = 0;
1831        for attr in iter {
1832            if let OpNewruleDoRequest::SuppressPrefixlen(val) = attr? {
1833                return Ok(val);
1834            }
1835        }
1836        Err(ErrorContext::new_missing(
1837            "OpNewruleDoRequest",
1838            "SuppressPrefixlen",
1839            self.orig_loc,
1840            self.buf.as_ptr() as usize,
1841        ))
1842    }
1843    pub fn get_table(&self) -> Result<u32, ErrorContext> {
1844        let mut iter = self.clone();
1845        iter.pos = 0;
1846        for attr in iter {
1847            if let OpNewruleDoRequest::Table(val) = attr? {
1848                return Ok(val);
1849            }
1850        }
1851        Err(ErrorContext::new_missing(
1852            "OpNewruleDoRequest",
1853            "Table",
1854            self.orig_loc,
1855            self.buf.as_ptr() as usize,
1856        ))
1857    }
1858    pub fn get_fwmask(&self) -> Result<u32, ErrorContext> {
1859        let mut iter = self.clone();
1860        iter.pos = 0;
1861        for attr in iter {
1862            if let OpNewruleDoRequest::Fwmask(val) = attr? {
1863                return Ok(val);
1864            }
1865        }
1866        Err(ErrorContext::new_missing(
1867            "OpNewruleDoRequest",
1868            "Fwmask",
1869            self.orig_loc,
1870            self.buf.as_ptr() as usize,
1871        ))
1872    }
1873    pub fn get_oifname(&self) -> Result<&'a CStr, ErrorContext> {
1874        let mut iter = self.clone();
1875        iter.pos = 0;
1876        for attr in iter {
1877            if let OpNewruleDoRequest::Oifname(val) = attr? {
1878                return Ok(val);
1879            }
1880        }
1881        Err(ErrorContext::new_missing(
1882            "OpNewruleDoRequest",
1883            "Oifname",
1884            self.orig_loc,
1885            self.buf.as_ptr() as usize,
1886        ))
1887    }
1888    pub fn get_l3mdev(&self) -> Result<u8, ErrorContext> {
1889        let mut iter = self.clone();
1890        iter.pos = 0;
1891        for attr in iter {
1892            if let OpNewruleDoRequest::L3mdev(val) = attr? {
1893                return Ok(val);
1894            }
1895        }
1896        Err(ErrorContext::new_missing(
1897            "OpNewruleDoRequest",
1898            "L3mdev",
1899            self.orig_loc,
1900            self.buf.as_ptr() as usize,
1901        ))
1902    }
1903    pub fn get_uid_range(&self) -> Result<PushFibRuleUidRange, ErrorContext> {
1904        let mut iter = self.clone();
1905        iter.pos = 0;
1906        for attr in iter {
1907            if let OpNewruleDoRequest::UidRange(val) = attr? {
1908                return Ok(val);
1909            }
1910        }
1911        Err(ErrorContext::new_missing(
1912            "OpNewruleDoRequest",
1913            "UidRange",
1914            self.orig_loc,
1915            self.buf.as_ptr() as usize,
1916        ))
1917    }
1918    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
1919        let mut iter = self.clone();
1920        iter.pos = 0;
1921        for attr in iter {
1922            if let OpNewruleDoRequest::Protocol(val) = attr? {
1923                return Ok(val);
1924            }
1925        }
1926        Err(ErrorContext::new_missing(
1927            "OpNewruleDoRequest",
1928            "Protocol",
1929            self.orig_loc,
1930            self.buf.as_ptr() as usize,
1931        ))
1932    }
1933    pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
1934        let mut iter = self.clone();
1935        iter.pos = 0;
1936        for attr in iter {
1937            if let OpNewruleDoRequest::IpProto(val) = attr? {
1938                return Ok(val);
1939            }
1940        }
1941        Err(ErrorContext::new_missing(
1942            "OpNewruleDoRequest",
1943            "IpProto",
1944            self.orig_loc,
1945            self.buf.as_ptr() as usize,
1946        ))
1947    }
1948    pub fn get_sport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
1949        let mut iter = self.clone();
1950        iter.pos = 0;
1951        for attr in iter {
1952            if let OpNewruleDoRequest::SportRange(val) = attr? {
1953                return Ok(val);
1954            }
1955        }
1956        Err(ErrorContext::new_missing(
1957            "OpNewruleDoRequest",
1958            "SportRange",
1959            self.orig_loc,
1960            self.buf.as_ptr() as usize,
1961        ))
1962    }
1963    pub fn get_dport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
1964        let mut iter = self.clone();
1965        iter.pos = 0;
1966        for attr in iter {
1967            if let OpNewruleDoRequest::DportRange(val) = attr? {
1968                return Ok(val);
1969            }
1970        }
1971        Err(ErrorContext::new_missing(
1972            "OpNewruleDoRequest",
1973            "DportRange",
1974            self.orig_loc,
1975            self.buf.as_ptr() as usize,
1976        ))
1977    }
1978    pub fn get_dscp(&self) -> Result<u8, ErrorContext> {
1979        let mut iter = self.clone();
1980        iter.pos = 0;
1981        for attr in iter {
1982            if let OpNewruleDoRequest::Dscp(val) = attr? {
1983                return Ok(val);
1984            }
1985        }
1986        Err(ErrorContext::new_missing(
1987            "OpNewruleDoRequest",
1988            "Dscp",
1989            self.orig_loc,
1990            self.buf.as_ptr() as usize,
1991        ))
1992    }
1993    pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
1994        let mut iter = self.clone();
1995        iter.pos = 0;
1996        for attr in iter {
1997            if let OpNewruleDoRequest::Flowlabel(val) = attr? {
1998                return Ok(val);
1999            }
2000        }
2001        Err(ErrorContext::new_missing(
2002            "OpNewruleDoRequest",
2003            "Flowlabel",
2004            self.orig_loc,
2005            self.buf.as_ptr() as usize,
2006        ))
2007    }
2008    pub fn get_flowlabel_mask(&self) -> Result<u32, ErrorContext> {
2009        let mut iter = self.clone();
2010        iter.pos = 0;
2011        for attr in iter {
2012            if let OpNewruleDoRequest::FlowlabelMask(val) = attr? {
2013                return Ok(val);
2014            }
2015        }
2016        Err(ErrorContext::new_missing(
2017            "OpNewruleDoRequest",
2018            "FlowlabelMask",
2019            self.orig_loc,
2020            self.buf.as_ptr() as usize,
2021        ))
2022    }
2023    pub fn get_sport_mask(&self) -> Result<u16, ErrorContext> {
2024        let mut iter = self.clone();
2025        iter.pos = 0;
2026        for attr in iter {
2027            if let OpNewruleDoRequest::SportMask(val) = attr? {
2028                return Ok(val);
2029            }
2030        }
2031        Err(ErrorContext::new_missing(
2032            "OpNewruleDoRequest",
2033            "SportMask",
2034            self.orig_loc,
2035            self.buf.as_ptr() as usize,
2036        ))
2037    }
2038    pub fn get_dport_mask(&self) -> Result<u16, ErrorContext> {
2039        let mut iter = self.clone();
2040        iter.pos = 0;
2041        for attr in iter {
2042            if let OpNewruleDoRequest::DportMask(val) = attr? {
2043                return Ok(val);
2044            }
2045        }
2046        Err(ErrorContext::new_missing(
2047            "OpNewruleDoRequest",
2048            "DportMask",
2049            self.orig_loc,
2050            self.buf.as_ptr() as usize,
2051        ))
2052    }
2053    pub fn get_dscp_mask(&self) -> Result<u8, ErrorContext> {
2054        let mut iter = self.clone();
2055        iter.pos = 0;
2056        for attr in iter {
2057            if let OpNewruleDoRequest::DscpMask(val) = attr? {
2058                return Ok(val);
2059            }
2060        }
2061        Err(ErrorContext::new_missing(
2062            "OpNewruleDoRequest",
2063            "DscpMask",
2064            self.orig_loc,
2065            self.buf.as_ptr() as usize,
2066        ))
2067    }
2068}
2069impl OpNewruleDoRequest<'_> {
2070    pub fn new<'a>(buf: &'a [u8]) -> (PushFibRuleHdr, IterableOpNewruleDoRequest<'a>) {
2071        let (header, attrs) = buf.split_at(buf.len().min(PushFibRuleHdr::len()));
2072        (
2073            PushFibRuleHdr::new_from_slice(header).unwrap_or_default(),
2074            IterableOpNewruleDoRequest::with_loc(attrs, buf.as_ptr() as usize),
2075        )
2076    }
2077    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2078        FibRuleAttrs::attr_from_type(r#type)
2079    }
2080}
2081#[derive(Clone, Copy, Default)]
2082pub struct IterableOpNewruleDoRequest<'a> {
2083    buf: &'a [u8],
2084    pos: usize,
2085    orig_loc: usize,
2086}
2087impl<'a> IterableOpNewruleDoRequest<'a> {
2088    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2089        Self {
2090            buf,
2091            pos: 0,
2092            orig_loc,
2093        }
2094    }
2095    pub fn get_buf(&self) -> &'a [u8] {
2096        self.buf
2097    }
2098}
2099impl<'a> Iterator for IterableOpNewruleDoRequest<'a> {
2100    type Item = Result<OpNewruleDoRequest<'a>, ErrorContext>;
2101    fn next(&mut self) -> Option<Self::Item> {
2102        let pos = self.pos;
2103        let mut r#type;
2104        loop {
2105            r#type = None;
2106            if self.buf.len() == self.pos {
2107                return None;
2108            }
2109            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2110                break;
2111            };
2112            r#type = Some(header.r#type);
2113            let res = match header.r#type {
2114                3u16 => OpNewruleDoRequest::Iifname({
2115                    let res = CStr::from_bytes_with_nul(next).ok();
2116                    let Some(val) = res else { break };
2117                    val
2118                }),
2119                4u16 => OpNewruleDoRequest::Goto({
2120                    let res = parse_u32(next);
2121                    let Some(val) = res else { break };
2122                    val
2123                }),
2124                6u16 => OpNewruleDoRequest::Priority({
2125                    let res = parse_u32(next);
2126                    let Some(val) = res else { break };
2127                    val
2128                }),
2129                10u16 => OpNewruleDoRequest::Fwmark({
2130                    let res = parse_u32(next);
2131                    let Some(val) = res else { break };
2132                    val
2133                }),
2134                11u16 => OpNewruleDoRequest::Flow({
2135                    let res = parse_u32(next);
2136                    let Some(val) = res else { break };
2137                    val
2138                }),
2139                12u16 => OpNewruleDoRequest::TunId({
2140                    let res = parse_u64(next);
2141                    let Some(val) = res else { break };
2142                    val
2143                }),
2144                13u16 => OpNewruleDoRequest::SuppressIfgroup({
2145                    let res = parse_u32(next);
2146                    let Some(val) = res else { break };
2147                    val
2148                }),
2149                14u16 => OpNewruleDoRequest::SuppressPrefixlen({
2150                    let res = parse_u32(next);
2151                    let Some(val) = res else { break };
2152                    val
2153                }),
2154                15u16 => OpNewruleDoRequest::Table({
2155                    let res = parse_u32(next);
2156                    let Some(val) = res else { break };
2157                    val
2158                }),
2159                16u16 => OpNewruleDoRequest::Fwmask({
2160                    let res = parse_u32(next);
2161                    let Some(val) = res else { break };
2162                    val
2163                }),
2164                17u16 => OpNewruleDoRequest::Oifname({
2165                    let res = CStr::from_bytes_with_nul(next).ok();
2166                    let Some(val) = res else { break };
2167                    val
2168                }),
2169                19u16 => OpNewruleDoRequest::L3mdev({
2170                    let res = parse_u8(next);
2171                    let Some(val) = res else { break };
2172                    val
2173                }),
2174                20u16 => OpNewruleDoRequest::UidRange({
2175                    let res = PushFibRuleUidRange::new_from_slice(next);
2176                    let Some(val) = res else { break };
2177                    val
2178                }),
2179                21u16 => OpNewruleDoRequest::Protocol({
2180                    let res = parse_u8(next);
2181                    let Some(val) = res else { break };
2182                    val
2183                }),
2184                22u16 => OpNewruleDoRequest::IpProto({
2185                    let res = parse_u8(next);
2186                    let Some(val) = res else { break };
2187                    val
2188                }),
2189                23u16 => OpNewruleDoRequest::SportRange({
2190                    let res = PushFibRulePortRange::new_from_slice(next);
2191                    let Some(val) = res else { break };
2192                    val
2193                }),
2194                24u16 => OpNewruleDoRequest::DportRange({
2195                    let res = PushFibRulePortRange::new_from_slice(next);
2196                    let Some(val) = res else { break };
2197                    val
2198                }),
2199                25u16 => OpNewruleDoRequest::Dscp({
2200                    let res = parse_u8(next);
2201                    let Some(val) = res else { break };
2202                    val
2203                }),
2204                26u16 => OpNewruleDoRequest::Flowlabel({
2205                    let res = parse_be_u32(next);
2206                    let Some(val) = res else { break };
2207                    val
2208                }),
2209                27u16 => OpNewruleDoRequest::FlowlabelMask({
2210                    let res = parse_be_u32(next);
2211                    let Some(val) = res else { break };
2212                    val
2213                }),
2214                28u16 => OpNewruleDoRequest::SportMask({
2215                    let res = parse_u16(next);
2216                    let Some(val) = res else { break };
2217                    val
2218                }),
2219                29u16 => OpNewruleDoRequest::DportMask({
2220                    let res = parse_u16(next);
2221                    let Some(val) = res else { break };
2222                    val
2223                }),
2224                30u16 => OpNewruleDoRequest::DscpMask({
2225                    let res = parse_u8(next);
2226                    let Some(val) = res else { break };
2227                    val
2228                }),
2229                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2230                n => continue,
2231            };
2232            return Some(Ok(res));
2233        }
2234        Some(Err(ErrorContext::new(
2235            "OpNewruleDoRequest",
2236            r#type.and_then(|t| OpNewruleDoRequest::attr_from_type(t)),
2237            self.orig_loc,
2238            self.buf.as_ptr().wrapping_add(pos) as usize,
2239        )))
2240    }
2241}
2242impl<'a> std::fmt::Debug for IterableOpNewruleDoRequest<'_> {
2243    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2244        let mut fmt = f.debug_struct("OpNewruleDoRequest");
2245        for attr in self.clone() {
2246            let attr = match attr {
2247                Ok(a) => a,
2248                Err(err) => {
2249                    fmt.finish()?;
2250                    f.write_str("Err(")?;
2251                    err.fmt(f)?;
2252                    return f.write_str(")");
2253                }
2254            };
2255            match attr {
2256                OpNewruleDoRequest::Iifname(val) => fmt.field("Iifname", &val),
2257                OpNewruleDoRequest::Goto(val) => fmt.field("Goto", &val),
2258                OpNewruleDoRequest::Priority(val) => fmt.field("Priority", &val),
2259                OpNewruleDoRequest::Fwmark(val) => fmt.field("Fwmark", &val),
2260                OpNewruleDoRequest::Flow(val) => fmt.field("Flow", &val),
2261                OpNewruleDoRequest::TunId(val) => fmt.field("TunId", &val),
2262                OpNewruleDoRequest::SuppressIfgroup(val) => fmt.field("SuppressIfgroup", &val),
2263                OpNewruleDoRequest::SuppressPrefixlen(val) => fmt.field("SuppressPrefixlen", &val),
2264                OpNewruleDoRequest::Table(val) => fmt.field("Table", &val),
2265                OpNewruleDoRequest::Fwmask(val) => fmt.field("Fwmask", &val),
2266                OpNewruleDoRequest::Oifname(val) => fmt.field("Oifname", &val),
2267                OpNewruleDoRequest::L3mdev(val) => fmt.field("L3mdev", &val),
2268                OpNewruleDoRequest::UidRange(val) => fmt.field("UidRange", &val),
2269                OpNewruleDoRequest::Protocol(val) => fmt.field("Protocol", &val),
2270                OpNewruleDoRequest::IpProto(val) => fmt.field("IpProto", &val),
2271                OpNewruleDoRequest::SportRange(val) => fmt.field("SportRange", &val),
2272                OpNewruleDoRequest::DportRange(val) => fmt.field("DportRange", &val),
2273                OpNewruleDoRequest::Dscp(val) => fmt.field("Dscp", &val),
2274                OpNewruleDoRequest::Flowlabel(val) => fmt.field("Flowlabel", &val),
2275                OpNewruleDoRequest::FlowlabelMask(val) => fmt.field("FlowlabelMask", &val),
2276                OpNewruleDoRequest::SportMask(val) => fmt.field("SportMask", &val),
2277                OpNewruleDoRequest::DportMask(val) => fmt.field("DportMask", &val),
2278                OpNewruleDoRequest::DscpMask(val) => fmt.field("DscpMask", &val),
2279            };
2280        }
2281        fmt.finish()
2282    }
2283}
2284impl IterableOpNewruleDoRequest<'_> {
2285    pub fn lookup_attr(
2286        &self,
2287        offset: usize,
2288        missing_type: Option<u16>,
2289    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2290        let mut stack = Vec::new();
2291        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2292        if cur == offset + PushFibRuleHdr::len() {
2293            stack.push(("OpNewruleDoRequest", offset));
2294            return (
2295                stack,
2296                missing_type.and_then(|t| OpNewruleDoRequest::attr_from_type(t)),
2297            );
2298        }
2299        if cur > offset || cur + self.buf.len() < offset {
2300            return (stack, None);
2301        }
2302        let mut attrs = self.clone();
2303        let mut last_off = cur + attrs.pos;
2304        while let Some(attr) = attrs.next() {
2305            let Ok(attr) = attr else { break };
2306            match attr {
2307                OpNewruleDoRequest::Iifname(val) => {
2308                    if last_off == offset {
2309                        stack.push(("Iifname", last_off));
2310                        break;
2311                    }
2312                }
2313                OpNewruleDoRequest::Goto(val) => {
2314                    if last_off == offset {
2315                        stack.push(("Goto", last_off));
2316                        break;
2317                    }
2318                }
2319                OpNewruleDoRequest::Priority(val) => {
2320                    if last_off == offset {
2321                        stack.push(("Priority", last_off));
2322                        break;
2323                    }
2324                }
2325                OpNewruleDoRequest::Fwmark(val) => {
2326                    if last_off == offset {
2327                        stack.push(("Fwmark", last_off));
2328                        break;
2329                    }
2330                }
2331                OpNewruleDoRequest::Flow(val) => {
2332                    if last_off == offset {
2333                        stack.push(("Flow", last_off));
2334                        break;
2335                    }
2336                }
2337                OpNewruleDoRequest::TunId(val) => {
2338                    if last_off == offset {
2339                        stack.push(("TunId", last_off));
2340                        break;
2341                    }
2342                }
2343                OpNewruleDoRequest::SuppressIfgroup(val) => {
2344                    if last_off == offset {
2345                        stack.push(("SuppressIfgroup", last_off));
2346                        break;
2347                    }
2348                }
2349                OpNewruleDoRequest::SuppressPrefixlen(val) => {
2350                    if last_off == offset {
2351                        stack.push(("SuppressPrefixlen", last_off));
2352                        break;
2353                    }
2354                }
2355                OpNewruleDoRequest::Table(val) => {
2356                    if last_off == offset {
2357                        stack.push(("Table", last_off));
2358                        break;
2359                    }
2360                }
2361                OpNewruleDoRequest::Fwmask(val) => {
2362                    if last_off == offset {
2363                        stack.push(("Fwmask", last_off));
2364                        break;
2365                    }
2366                }
2367                OpNewruleDoRequest::Oifname(val) => {
2368                    if last_off == offset {
2369                        stack.push(("Oifname", last_off));
2370                        break;
2371                    }
2372                }
2373                OpNewruleDoRequest::L3mdev(val) => {
2374                    if last_off == offset {
2375                        stack.push(("L3mdev", last_off));
2376                        break;
2377                    }
2378                }
2379                OpNewruleDoRequest::UidRange(val) => {
2380                    if last_off == offset {
2381                        stack.push(("UidRange", last_off));
2382                        break;
2383                    }
2384                }
2385                OpNewruleDoRequest::Protocol(val) => {
2386                    if last_off == offset {
2387                        stack.push(("Protocol", last_off));
2388                        break;
2389                    }
2390                }
2391                OpNewruleDoRequest::IpProto(val) => {
2392                    if last_off == offset {
2393                        stack.push(("IpProto", last_off));
2394                        break;
2395                    }
2396                }
2397                OpNewruleDoRequest::SportRange(val) => {
2398                    if last_off == offset {
2399                        stack.push(("SportRange", last_off));
2400                        break;
2401                    }
2402                }
2403                OpNewruleDoRequest::DportRange(val) => {
2404                    if last_off == offset {
2405                        stack.push(("DportRange", last_off));
2406                        break;
2407                    }
2408                }
2409                OpNewruleDoRequest::Dscp(val) => {
2410                    if last_off == offset {
2411                        stack.push(("Dscp", last_off));
2412                        break;
2413                    }
2414                }
2415                OpNewruleDoRequest::Flowlabel(val) => {
2416                    if last_off == offset {
2417                        stack.push(("Flowlabel", last_off));
2418                        break;
2419                    }
2420                }
2421                OpNewruleDoRequest::FlowlabelMask(val) => {
2422                    if last_off == offset {
2423                        stack.push(("FlowlabelMask", last_off));
2424                        break;
2425                    }
2426                }
2427                OpNewruleDoRequest::SportMask(val) => {
2428                    if last_off == offset {
2429                        stack.push(("SportMask", last_off));
2430                        break;
2431                    }
2432                }
2433                OpNewruleDoRequest::DportMask(val) => {
2434                    if last_off == offset {
2435                        stack.push(("DportMask", last_off));
2436                        break;
2437                    }
2438                }
2439                OpNewruleDoRequest::DscpMask(val) => {
2440                    if last_off == offset {
2441                        stack.push(("DscpMask", last_off));
2442                        break;
2443                    }
2444                }
2445                _ => {}
2446            };
2447            last_off = cur + attrs.pos;
2448        }
2449        if !stack.is_empty() {
2450            stack.push(("OpNewruleDoRequest", cur));
2451        }
2452        (stack, None)
2453    }
2454}
2455#[doc = "Add new FIB rule"]
2456pub struct PushOpNewruleDoReply<Prev: Rec> {
2457    pub(crate) prev: Option<Prev>,
2458    pub(crate) header_offset: Option<usize>,
2459}
2460impl<Prev: Rec> Rec for PushOpNewruleDoReply<Prev> {
2461    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2462        self.prev.as_mut().unwrap().as_rec_mut()
2463    }
2464    fn as_rec(&self) -> &Vec<u8> {
2465        self.prev.as_ref().unwrap().as_rec()
2466    }
2467}
2468impl<Prev: Rec> PushOpNewruleDoReply<Prev> {
2469    pub fn new(mut prev: Prev, header: &PushFibRuleHdr) -> Self {
2470        Self::write_header(&mut prev, header);
2471        Self::new_without_header(prev)
2472    }
2473    fn new_without_header(prev: Prev) -> Self {
2474        Self {
2475            prev: Some(prev),
2476            header_offset: None,
2477        }
2478    }
2479    fn write_header(prev: &mut Prev, header: &PushFibRuleHdr) {
2480        prev.as_rec_mut().extend(header.as_slice());
2481    }
2482    pub fn end_nested(mut self) -> Prev {
2483        let mut prev = self.prev.take().unwrap();
2484        if let Some(header_offset) = &self.header_offset {
2485            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2486        }
2487        prev
2488    }
2489}
2490impl<Prev: Rec> Drop for PushOpNewruleDoReply<Prev> {
2491    fn drop(&mut self) {
2492        if let Some(prev) = &mut self.prev {
2493            if let Some(header_offset) = &self.header_offset {
2494                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2495            }
2496        }
2497    }
2498}
2499#[doc = "Add new FIB rule"]
2500#[derive(Clone)]
2501pub enum OpNewruleDoReply {}
2502impl<'a> IterableOpNewruleDoReply<'a> {}
2503impl OpNewruleDoReply {
2504    pub fn new<'a>(buf: &'a [u8]) -> (PushFibRuleHdr, IterableOpNewruleDoReply<'a>) {
2505        let (header, attrs) = buf.split_at(buf.len().min(PushFibRuleHdr::len()));
2506        (
2507            PushFibRuleHdr::new_from_slice(header).unwrap_or_default(),
2508            IterableOpNewruleDoReply::with_loc(attrs, buf.as_ptr() as usize),
2509        )
2510    }
2511    fn attr_from_type(r#type: u16) -> Option<&'static str> {
2512        FibRuleAttrs::attr_from_type(r#type)
2513    }
2514}
2515#[derive(Clone, Copy, Default)]
2516pub struct IterableOpNewruleDoReply<'a> {
2517    buf: &'a [u8],
2518    pos: usize,
2519    orig_loc: usize,
2520}
2521impl<'a> IterableOpNewruleDoReply<'a> {
2522    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2523        Self {
2524            buf,
2525            pos: 0,
2526            orig_loc,
2527        }
2528    }
2529    pub fn get_buf(&self) -> &'a [u8] {
2530        self.buf
2531    }
2532}
2533impl<'a> Iterator for IterableOpNewruleDoReply<'a> {
2534    type Item = Result<OpNewruleDoReply, ErrorContext>;
2535    fn next(&mut self) -> Option<Self::Item> {
2536        let pos = self.pos;
2537        let mut r#type;
2538        loop {
2539            r#type = None;
2540            if self.buf.len() == self.pos {
2541                return None;
2542            }
2543            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
2544                break;
2545            };
2546            r#type = Some(header.r#type);
2547            let res = match header.r#type {
2548                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2549                n => continue,
2550            };
2551            return Some(Ok(res));
2552        }
2553        Some(Err(ErrorContext::new(
2554            "OpNewruleDoReply",
2555            r#type.and_then(|t| OpNewruleDoReply::attr_from_type(t)),
2556            self.orig_loc,
2557            self.buf.as_ptr().wrapping_add(pos) as usize,
2558        )))
2559    }
2560}
2561impl std::fmt::Debug for IterableOpNewruleDoReply<'_> {
2562    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2563        let mut fmt = f.debug_struct("OpNewruleDoReply");
2564        for attr in self.clone() {
2565            let attr = match attr {
2566                Ok(a) => a,
2567                Err(err) => {
2568                    fmt.finish()?;
2569                    f.write_str("Err(")?;
2570                    err.fmt(f)?;
2571                    return f.write_str(")");
2572                }
2573            };
2574            match attr {};
2575        }
2576        fmt.finish()
2577    }
2578}
2579impl IterableOpNewruleDoReply<'_> {
2580    pub fn lookup_attr(
2581        &self,
2582        offset: usize,
2583        missing_type: Option<u16>,
2584    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2585        let mut stack = Vec::new();
2586        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2587        if cur == offset + PushFibRuleHdr::len() {
2588            stack.push(("OpNewruleDoReply", offset));
2589            return (
2590                stack,
2591                missing_type.and_then(|t| OpNewruleDoReply::attr_from_type(t)),
2592            );
2593        }
2594        (stack, None)
2595    }
2596}
2597#[derive(Debug)]
2598pub struct RequestOpNewruleDoRequest<'r> {
2599    request: Request<'r>,
2600}
2601impl<'r> RequestOpNewruleDoRequest<'r> {
2602    pub fn new(mut request: Request<'r>, header: &PushFibRuleHdr) -> Self {
2603        PushOpNewruleDoRequest::write_header(&mut request.buf_mut(), header);
2604        Self { request: request }
2605    }
2606    pub fn encode(&mut self) -> PushOpNewruleDoRequest<&mut Vec<u8>> {
2607        PushOpNewruleDoRequest::new_without_header(self.request.buf_mut())
2608    }
2609    pub fn into_encoder(self) -> PushOpNewruleDoRequest<RequestBuf<'r>> {
2610        PushOpNewruleDoRequest::new_without_header(self.request.buf)
2611    }
2612    pub fn decode_request<'buf>(
2613        buf: &'buf [u8],
2614    ) -> (PushFibRuleHdr, IterableOpNewruleDoRequest<'buf>) {
2615        OpNewruleDoRequest::new(buf)
2616    }
2617}
2618impl NetlinkRequest for RequestOpNewruleDoRequest<'_> {
2619    fn protocol(&self) -> Protocol {
2620        Protocol::Raw {
2621            protonum: 0u16,
2622            request_type: 32u16,
2623        }
2624    }
2625    fn flags(&self) -> u16 {
2626        self.request.flags
2627    }
2628    fn payload(&self) -> &[u8] {
2629        self.request.buf()
2630    }
2631    type ReplyType<'buf> = (PushFibRuleHdr, IterableOpNewruleDoReply<'buf>);
2632    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2633        OpNewruleDoReply::new(buf)
2634    }
2635    fn lookup(
2636        buf: &[u8],
2637        offset: usize,
2638        missing_type: Option<u16>,
2639    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2640        OpNewruleDoRequest::new(buf)
2641            .1
2642            .lookup_attr(offset, missing_type)
2643    }
2644}
2645#[doc = "Remove an existing FIB rule"]
2646pub struct PushOpDelruleDoRequest<Prev: Rec> {
2647    pub(crate) prev: Option<Prev>,
2648    pub(crate) header_offset: Option<usize>,
2649}
2650impl<Prev: Rec> Rec for PushOpDelruleDoRequest<Prev> {
2651    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2652        self.prev.as_mut().unwrap().as_rec_mut()
2653    }
2654    fn as_rec(&self) -> &Vec<u8> {
2655        self.prev.as_ref().unwrap().as_rec()
2656    }
2657}
2658impl<Prev: Rec> PushOpDelruleDoRequest<Prev> {
2659    pub fn new(mut prev: Prev, header: &PushFibRuleHdr) -> Self {
2660        Self::write_header(&mut prev, header);
2661        Self::new_without_header(prev)
2662    }
2663    fn new_without_header(prev: Prev) -> Self {
2664        Self {
2665            prev: Some(prev),
2666            header_offset: None,
2667        }
2668    }
2669    fn write_header(prev: &mut Prev, header: &PushFibRuleHdr) {
2670        prev.as_rec_mut().extend(header.as_slice());
2671    }
2672    pub fn end_nested(mut self) -> Prev {
2673        let mut prev = self.prev.take().unwrap();
2674        if let Some(header_offset) = &self.header_offset {
2675            finalize_nested_header(prev.as_rec_mut(), *header_offset);
2676        }
2677        prev
2678    }
2679    pub fn push_iifname(mut self, value: &CStr) -> Self {
2680        push_header(
2681            self.as_rec_mut(),
2682            3u16,
2683            value.to_bytes_with_nul().len() as u16,
2684        );
2685        self.as_rec_mut().extend(value.to_bytes_with_nul());
2686        self
2687    }
2688    pub fn push_iifname_bytes(mut self, value: &[u8]) -> Self {
2689        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
2690        self.as_rec_mut().extend(value);
2691        self.as_rec_mut().push(0);
2692        self
2693    }
2694    pub fn push_goto(mut self, value: u32) -> Self {
2695        push_header(self.as_rec_mut(), 4u16, 4 as u16);
2696        self.as_rec_mut().extend(value.to_ne_bytes());
2697        self
2698    }
2699    pub fn push_priority(mut self, value: u32) -> Self {
2700        push_header(self.as_rec_mut(), 6u16, 4 as u16);
2701        self.as_rec_mut().extend(value.to_ne_bytes());
2702        self
2703    }
2704    pub fn push_fwmark(mut self, value: u32) -> Self {
2705        push_header(self.as_rec_mut(), 10u16, 4 as u16);
2706        self.as_rec_mut().extend(value.to_ne_bytes());
2707        self
2708    }
2709    pub fn push_flow(mut self, value: u32) -> Self {
2710        push_header(self.as_rec_mut(), 11u16, 4 as u16);
2711        self.as_rec_mut().extend(value.to_ne_bytes());
2712        self
2713    }
2714    pub fn push_tun_id(mut self, value: u64) -> Self {
2715        push_header(self.as_rec_mut(), 12u16, 8 as u16);
2716        self.as_rec_mut().extend(value.to_ne_bytes());
2717        self
2718    }
2719    pub fn push_suppress_ifgroup(mut self, value: u32) -> Self {
2720        push_header(self.as_rec_mut(), 13u16, 4 as u16);
2721        self.as_rec_mut().extend(value.to_ne_bytes());
2722        self
2723    }
2724    pub fn push_suppress_prefixlen(mut self, value: u32) -> Self {
2725        push_header(self.as_rec_mut(), 14u16, 4 as u16);
2726        self.as_rec_mut().extend(value.to_ne_bytes());
2727        self
2728    }
2729    pub fn push_table(mut self, value: u32) -> Self {
2730        push_header(self.as_rec_mut(), 15u16, 4 as u16);
2731        self.as_rec_mut().extend(value.to_ne_bytes());
2732        self
2733    }
2734    pub fn push_fwmask(mut self, value: u32) -> Self {
2735        push_header(self.as_rec_mut(), 16u16, 4 as u16);
2736        self.as_rec_mut().extend(value.to_ne_bytes());
2737        self
2738    }
2739    pub fn push_oifname(mut self, value: &CStr) -> Self {
2740        push_header(
2741            self.as_rec_mut(),
2742            17u16,
2743            value.to_bytes_with_nul().len() as u16,
2744        );
2745        self.as_rec_mut().extend(value.to_bytes_with_nul());
2746        self
2747    }
2748    pub fn push_oifname_bytes(mut self, value: &[u8]) -> Self {
2749        push_header(self.as_rec_mut(), 17u16, (value.len() + 1) as u16);
2750        self.as_rec_mut().extend(value);
2751        self.as_rec_mut().push(0);
2752        self
2753    }
2754    pub fn push_l3mdev(mut self, value: u8) -> Self {
2755        push_header(self.as_rec_mut(), 19u16, 1 as u16);
2756        self.as_rec_mut().extend(value.to_ne_bytes());
2757        self
2758    }
2759    pub fn push_uid_range(mut self, value: PushFibRuleUidRange) -> Self {
2760        push_header(self.as_rec_mut(), 20u16, value.as_slice().len() as u16);
2761        self.as_rec_mut().extend(value.as_slice());
2762        self
2763    }
2764    pub fn push_protocol(mut self, value: u8) -> Self {
2765        push_header(self.as_rec_mut(), 21u16, 1 as u16);
2766        self.as_rec_mut().extend(value.to_ne_bytes());
2767        self
2768    }
2769    pub fn push_ip_proto(mut self, value: u8) -> Self {
2770        push_header(self.as_rec_mut(), 22u16, 1 as u16);
2771        self.as_rec_mut().extend(value.to_ne_bytes());
2772        self
2773    }
2774    pub fn push_sport_range(mut self, value: PushFibRulePortRange) -> Self {
2775        push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
2776        self.as_rec_mut().extend(value.as_slice());
2777        self
2778    }
2779    pub fn push_dport_range(mut self, value: PushFibRulePortRange) -> Self {
2780        push_header(self.as_rec_mut(), 24u16, value.as_slice().len() as u16);
2781        self.as_rec_mut().extend(value.as_slice());
2782        self
2783    }
2784    pub fn push_dscp(mut self, value: u8) -> Self {
2785        push_header(self.as_rec_mut(), 25u16, 1 as u16);
2786        self.as_rec_mut().extend(value.to_ne_bytes());
2787        self
2788    }
2789    pub fn push_flowlabel(mut self, value: u32) -> Self {
2790        push_header(self.as_rec_mut(), 26u16, 4 as u16);
2791        self.as_rec_mut().extend(value.to_be_bytes());
2792        self
2793    }
2794    pub fn push_flowlabel_mask(mut self, value: u32) -> Self {
2795        push_header(self.as_rec_mut(), 27u16, 4 as u16);
2796        self.as_rec_mut().extend(value.to_be_bytes());
2797        self
2798    }
2799    pub fn push_sport_mask(mut self, value: u16) -> Self {
2800        push_header(self.as_rec_mut(), 28u16, 2 as u16);
2801        self.as_rec_mut().extend(value.to_ne_bytes());
2802        self
2803    }
2804    pub fn push_dport_mask(mut self, value: u16) -> Self {
2805        push_header(self.as_rec_mut(), 29u16, 2 as u16);
2806        self.as_rec_mut().extend(value.to_ne_bytes());
2807        self
2808    }
2809    pub fn push_dscp_mask(mut self, value: u8) -> Self {
2810        push_header(self.as_rec_mut(), 30u16, 1 as u16);
2811        self.as_rec_mut().extend(value.to_ne_bytes());
2812        self
2813    }
2814}
2815impl<Prev: Rec> Drop for PushOpDelruleDoRequest<Prev> {
2816    fn drop(&mut self) {
2817        if let Some(prev) = &mut self.prev {
2818            if let Some(header_offset) = &self.header_offset {
2819                finalize_nested_header(prev.as_rec_mut(), *header_offset);
2820            }
2821        }
2822    }
2823}
2824#[doc = "Remove an existing FIB rule"]
2825#[derive(Clone)]
2826pub enum OpDelruleDoRequest<'a> {
2827    Iifname(&'a CStr),
2828    Goto(u32),
2829    Priority(u32),
2830    Fwmark(u32),
2831    Flow(u32),
2832    TunId(u64),
2833    SuppressIfgroup(u32),
2834    SuppressPrefixlen(u32),
2835    Table(u32),
2836    Fwmask(u32),
2837    Oifname(&'a CStr),
2838    L3mdev(u8),
2839    UidRange(PushFibRuleUidRange),
2840    Protocol(u8),
2841    IpProto(u8),
2842    SportRange(PushFibRulePortRange),
2843    DportRange(PushFibRulePortRange),
2844    Dscp(u8),
2845    Flowlabel(u32),
2846    FlowlabelMask(u32),
2847    SportMask(u16),
2848    DportMask(u16),
2849    DscpMask(u8),
2850}
2851impl<'a> IterableOpDelruleDoRequest<'a> {
2852    pub fn get_iifname(&self) -> Result<&'a CStr, ErrorContext> {
2853        let mut iter = self.clone();
2854        iter.pos = 0;
2855        for attr in iter {
2856            if let OpDelruleDoRequest::Iifname(val) = attr? {
2857                return Ok(val);
2858            }
2859        }
2860        Err(ErrorContext::new_missing(
2861            "OpDelruleDoRequest",
2862            "Iifname",
2863            self.orig_loc,
2864            self.buf.as_ptr() as usize,
2865        ))
2866    }
2867    pub fn get_goto(&self) -> Result<u32, ErrorContext> {
2868        let mut iter = self.clone();
2869        iter.pos = 0;
2870        for attr in iter {
2871            if let OpDelruleDoRequest::Goto(val) = attr? {
2872                return Ok(val);
2873            }
2874        }
2875        Err(ErrorContext::new_missing(
2876            "OpDelruleDoRequest",
2877            "Goto",
2878            self.orig_loc,
2879            self.buf.as_ptr() as usize,
2880        ))
2881    }
2882    pub fn get_priority(&self) -> Result<u32, ErrorContext> {
2883        let mut iter = self.clone();
2884        iter.pos = 0;
2885        for attr in iter {
2886            if let OpDelruleDoRequest::Priority(val) = attr? {
2887                return Ok(val);
2888            }
2889        }
2890        Err(ErrorContext::new_missing(
2891            "OpDelruleDoRequest",
2892            "Priority",
2893            self.orig_loc,
2894            self.buf.as_ptr() as usize,
2895        ))
2896    }
2897    pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
2898        let mut iter = self.clone();
2899        iter.pos = 0;
2900        for attr in iter {
2901            if let OpDelruleDoRequest::Fwmark(val) = attr? {
2902                return Ok(val);
2903            }
2904        }
2905        Err(ErrorContext::new_missing(
2906            "OpDelruleDoRequest",
2907            "Fwmark",
2908            self.orig_loc,
2909            self.buf.as_ptr() as usize,
2910        ))
2911    }
2912    pub fn get_flow(&self) -> Result<u32, ErrorContext> {
2913        let mut iter = self.clone();
2914        iter.pos = 0;
2915        for attr in iter {
2916            if let OpDelruleDoRequest::Flow(val) = attr? {
2917                return Ok(val);
2918            }
2919        }
2920        Err(ErrorContext::new_missing(
2921            "OpDelruleDoRequest",
2922            "Flow",
2923            self.orig_loc,
2924            self.buf.as_ptr() as usize,
2925        ))
2926    }
2927    pub fn get_tun_id(&self) -> Result<u64, ErrorContext> {
2928        let mut iter = self.clone();
2929        iter.pos = 0;
2930        for attr in iter {
2931            if let OpDelruleDoRequest::TunId(val) = attr? {
2932                return Ok(val);
2933            }
2934        }
2935        Err(ErrorContext::new_missing(
2936            "OpDelruleDoRequest",
2937            "TunId",
2938            self.orig_loc,
2939            self.buf.as_ptr() as usize,
2940        ))
2941    }
2942    pub fn get_suppress_ifgroup(&self) -> Result<u32, ErrorContext> {
2943        let mut iter = self.clone();
2944        iter.pos = 0;
2945        for attr in iter {
2946            if let OpDelruleDoRequest::SuppressIfgroup(val) = attr? {
2947                return Ok(val);
2948            }
2949        }
2950        Err(ErrorContext::new_missing(
2951            "OpDelruleDoRequest",
2952            "SuppressIfgroup",
2953            self.orig_loc,
2954            self.buf.as_ptr() as usize,
2955        ))
2956    }
2957    pub fn get_suppress_prefixlen(&self) -> Result<u32, ErrorContext> {
2958        let mut iter = self.clone();
2959        iter.pos = 0;
2960        for attr in iter {
2961            if let OpDelruleDoRequest::SuppressPrefixlen(val) = attr? {
2962                return Ok(val);
2963            }
2964        }
2965        Err(ErrorContext::new_missing(
2966            "OpDelruleDoRequest",
2967            "SuppressPrefixlen",
2968            self.orig_loc,
2969            self.buf.as_ptr() as usize,
2970        ))
2971    }
2972    pub fn get_table(&self) -> Result<u32, ErrorContext> {
2973        let mut iter = self.clone();
2974        iter.pos = 0;
2975        for attr in iter {
2976            if let OpDelruleDoRequest::Table(val) = attr? {
2977                return Ok(val);
2978            }
2979        }
2980        Err(ErrorContext::new_missing(
2981            "OpDelruleDoRequest",
2982            "Table",
2983            self.orig_loc,
2984            self.buf.as_ptr() as usize,
2985        ))
2986    }
2987    pub fn get_fwmask(&self) -> Result<u32, ErrorContext> {
2988        let mut iter = self.clone();
2989        iter.pos = 0;
2990        for attr in iter {
2991            if let OpDelruleDoRequest::Fwmask(val) = attr? {
2992                return Ok(val);
2993            }
2994        }
2995        Err(ErrorContext::new_missing(
2996            "OpDelruleDoRequest",
2997            "Fwmask",
2998            self.orig_loc,
2999            self.buf.as_ptr() as usize,
3000        ))
3001    }
3002    pub fn get_oifname(&self) -> Result<&'a CStr, ErrorContext> {
3003        let mut iter = self.clone();
3004        iter.pos = 0;
3005        for attr in iter {
3006            if let OpDelruleDoRequest::Oifname(val) = attr? {
3007                return Ok(val);
3008            }
3009        }
3010        Err(ErrorContext::new_missing(
3011            "OpDelruleDoRequest",
3012            "Oifname",
3013            self.orig_loc,
3014            self.buf.as_ptr() as usize,
3015        ))
3016    }
3017    pub fn get_l3mdev(&self) -> Result<u8, ErrorContext> {
3018        let mut iter = self.clone();
3019        iter.pos = 0;
3020        for attr in iter {
3021            if let OpDelruleDoRequest::L3mdev(val) = attr? {
3022                return Ok(val);
3023            }
3024        }
3025        Err(ErrorContext::new_missing(
3026            "OpDelruleDoRequest",
3027            "L3mdev",
3028            self.orig_loc,
3029            self.buf.as_ptr() as usize,
3030        ))
3031    }
3032    pub fn get_uid_range(&self) -> Result<PushFibRuleUidRange, ErrorContext> {
3033        let mut iter = self.clone();
3034        iter.pos = 0;
3035        for attr in iter {
3036            if let OpDelruleDoRequest::UidRange(val) = attr? {
3037                return Ok(val);
3038            }
3039        }
3040        Err(ErrorContext::new_missing(
3041            "OpDelruleDoRequest",
3042            "UidRange",
3043            self.orig_loc,
3044            self.buf.as_ptr() as usize,
3045        ))
3046    }
3047    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
3048        let mut iter = self.clone();
3049        iter.pos = 0;
3050        for attr in iter {
3051            if let OpDelruleDoRequest::Protocol(val) = attr? {
3052                return Ok(val);
3053            }
3054        }
3055        Err(ErrorContext::new_missing(
3056            "OpDelruleDoRequest",
3057            "Protocol",
3058            self.orig_loc,
3059            self.buf.as_ptr() as usize,
3060        ))
3061    }
3062    pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
3063        let mut iter = self.clone();
3064        iter.pos = 0;
3065        for attr in iter {
3066            if let OpDelruleDoRequest::IpProto(val) = attr? {
3067                return Ok(val);
3068            }
3069        }
3070        Err(ErrorContext::new_missing(
3071            "OpDelruleDoRequest",
3072            "IpProto",
3073            self.orig_loc,
3074            self.buf.as_ptr() as usize,
3075        ))
3076    }
3077    pub fn get_sport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
3078        let mut iter = self.clone();
3079        iter.pos = 0;
3080        for attr in iter {
3081            if let OpDelruleDoRequest::SportRange(val) = attr? {
3082                return Ok(val);
3083            }
3084        }
3085        Err(ErrorContext::new_missing(
3086            "OpDelruleDoRequest",
3087            "SportRange",
3088            self.orig_loc,
3089            self.buf.as_ptr() as usize,
3090        ))
3091    }
3092    pub fn get_dport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
3093        let mut iter = self.clone();
3094        iter.pos = 0;
3095        for attr in iter {
3096            if let OpDelruleDoRequest::DportRange(val) = attr? {
3097                return Ok(val);
3098            }
3099        }
3100        Err(ErrorContext::new_missing(
3101            "OpDelruleDoRequest",
3102            "DportRange",
3103            self.orig_loc,
3104            self.buf.as_ptr() as usize,
3105        ))
3106    }
3107    pub fn get_dscp(&self) -> Result<u8, ErrorContext> {
3108        let mut iter = self.clone();
3109        iter.pos = 0;
3110        for attr in iter {
3111            if let OpDelruleDoRequest::Dscp(val) = attr? {
3112                return Ok(val);
3113            }
3114        }
3115        Err(ErrorContext::new_missing(
3116            "OpDelruleDoRequest",
3117            "Dscp",
3118            self.orig_loc,
3119            self.buf.as_ptr() as usize,
3120        ))
3121    }
3122    pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
3123        let mut iter = self.clone();
3124        iter.pos = 0;
3125        for attr in iter {
3126            if let OpDelruleDoRequest::Flowlabel(val) = attr? {
3127                return Ok(val);
3128            }
3129        }
3130        Err(ErrorContext::new_missing(
3131            "OpDelruleDoRequest",
3132            "Flowlabel",
3133            self.orig_loc,
3134            self.buf.as_ptr() as usize,
3135        ))
3136    }
3137    pub fn get_flowlabel_mask(&self) -> Result<u32, ErrorContext> {
3138        let mut iter = self.clone();
3139        iter.pos = 0;
3140        for attr in iter {
3141            if let OpDelruleDoRequest::FlowlabelMask(val) = attr? {
3142                return Ok(val);
3143            }
3144        }
3145        Err(ErrorContext::new_missing(
3146            "OpDelruleDoRequest",
3147            "FlowlabelMask",
3148            self.orig_loc,
3149            self.buf.as_ptr() as usize,
3150        ))
3151    }
3152    pub fn get_sport_mask(&self) -> Result<u16, ErrorContext> {
3153        let mut iter = self.clone();
3154        iter.pos = 0;
3155        for attr in iter {
3156            if let OpDelruleDoRequest::SportMask(val) = attr? {
3157                return Ok(val);
3158            }
3159        }
3160        Err(ErrorContext::new_missing(
3161            "OpDelruleDoRequest",
3162            "SportMask",
3163            self.orig_loc,
3164            self.buf.as_ptr() as usize,
3165        ))
3166    }
3167    pub fn get_dport_mask(&self) -> Result<u16, ErrorContext> {
3168        let mut iter = self.clone();
3169        iter.pos = 0;
3170        for attr in iter {
3171            if let OpDelruleDoRequest::DportMask(val) = attr? {
3172                return Ok(val);
3173            }
3174        }
3175        Err(ErrorContext::new_missing(
3176            "OpDelruleDoRequest",
3177            "DportMask",
3178            self.orig_loc,
3179            self.buf.as_ptr() as usize,
3180        ))
3181    }
3182    pub fn get_dscp_mask(&self) -> Result<u8, ErrorContext> {
3183        let mut iter = self.clone();
3184        iter.pos = 0;
3185        for attr in iter {
3186            if let OpDelruleDoRequest::DscpMask(val) = attr? {
3187                return Ok(val);
3188            }
3189        }
3190        Err(ErrorContext::new_missing(
3191            "OpDelruleDoRequest",
3192            "DscpMask",
3193            self.orig_loc,
3194            self.buf.as_ptr() as usize,
3195        ))
3196    }
3197}
3198impl OpDelruleDoRequest<'_> {
3199    pub fn new<'a>(buf: &'a [u8]) -> (PushFibRuleHdr, IterableOpDelruleDoRequest<'a>) {
3200        let (header, attrs) = buf.split_at(buf.len().min(PushFibRuleHdr::len()));
3201        (
3202            PushFibRuleHdr::new_from_slice(header).unwrap_or_default(),
3203            IterableOpDelruleDoRequest::with_loc(attrs, buf.as_ptr() as usize),
3204        )
3205    }
3206    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3207        FibRuleAttrs::attr_from_type(r#type)
3208    }
3209}
3210#[derive(Clone, Copy, Default)]
3211pub struct IterableOpDelruleDoRequest<'a> {
3212    buf: &'a [u8],
3213    pos: usize,
3214    orig_loc: usize,
3215}
3216impl<'a> IterableOpDelruleDoRequest<'a> {
3217    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3218        Self {
3219            buf,
3220            pos: 0,
3221            orig_loc,
3222        }
3223    }
3224    pub fn get_buf(&self) -> &'a [u8] {
3225        self.buf
3226    }
3227}
3228impl<'a> Iterator for IterableOpDelruleDoRequest<'a> {
3229    type Item = Result<OpDelruleDoRequest<'a>, ErrorContext>;
3230    fn next(&mut self) -> Option<Self::Item> {
3231        let pos = self.pos;
3232        let mut r#type;
3233        loop {
3234            r#type = None;
3235            if self.buf.len() == self.pos {
3236                return None;
3237            }
3238            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3239                break;
3240            };
3241            r#type = Some(header.r#type);
3242            let res = match header.r#type {
3243                3u16 => OpDelruleDoRequest::Iifname({
3244                    let res = CStr::from_bytes_with_nul(next).ok();
3245                    let Some(val) = res else { break };
3246                    val
3247                }),
3248                4u16 => OpDelruleDoRequest::Goto({
3249                    let res = parse_u32(next);
3250                    let Some(val) = res else { break };
3251                    val
3252                }),
3253                6u16 => OpDelruleDoRequest::Priority({
3254                    let res = parse_u32(next);
3255                    let Some(val) = res else { break };
3256                    val
3257                }),
3258                10u16 => OpDelruleDoRequest::Fwmark({
3259                    let res = parse_u32(next);
3260                    let Some(val) = res else { break };
3261                    val
3262                }),
3263                11u16 => OpDelruleDoRequest::Flow({
3264                    let res = parse_u32(next);
3265                    let Some(val) = res else { break };
3266                    val
3267                }),
3268                12u16 => OpDelruleDoRequest::TunId({
3269                    let res = parse_u64(next);
3270                    let Some(val) = res else { break };
3271                    val
3272                }),
3273                13u16 => OpDelruleDoRequest::SuppressIfgroup({
3274                    let res = parse_u32(next);
3275                    let Some(val) = res else { break };
3276                    val
3277                }),
3278                14u16 => OpDelruleDoRequest::SuppressPrefixlen({
3279                    let res = parse_u32(next);
3280                    let Some(val) = res else { break };
3281                    val
3282                }),
3283                15u16 => OpDelruleDoRequest::Table({
3284                    let res = parse_u32(next);
3285                    let Some(val) = res else { break };
3286                    val
3287                }),
3288                16u16 => OpDelruleDoRequest::Fwmask({
3289                    let res = parse_u32(next);
3290                    let Some(val) = res else { break };
3291                    val
3292                }),
3293                17u16 => OpDelruleDoRequest::Oifname({
3294                    let res = CStr::from_bytes_with_nul(next).ok();
3295                    let Some(val) = res else { break };
3296                    val
3297                }),
3298                19u16 => OpDelruleDoRequest::L3mdev({
3299                    let res = parse_u8(next);
3300                    let Some(val) = res else { break };
3301                    val
3302                }),
3303                20u16 => OpDelruleDoRequest::UidRange({
3304                    let res = PushFibRuleUidRange::new_from_slice(next);
3305                    let Some(val) = res else { break };
3306                    val
3307                }),
3308                21u16 => OpDelruleDoRequest::Protocol({
3309                    let res = parse_u8(next);
3310                    let Some(val) = res else { break };
3311                    val
3312                }),
3313                22u16 => OpDelruleDoRequest::IpProto({
3314                    let res = parse_u8(next);
3315                    let Some(val) = res else { break };
3316                    val
3317                }),
3318                23u16 => OpDelruleDoRequest::SportRange({
3319                    let res = PushFibRulePortRange::new_from_slice(next);
3320                    let Some(val) = res else { break };
3321                    val
3322                }),
3323                24u16 => OpDelruleDoRequest::DportRange({
3324                    let res = PushFibRulePortRange::new_from_slice(next);
3325                    let Some(val) = res else { break };
3326                    val
3327                }),
3328                25u16 => OpDelruleDoRequest::Dscp({
3329                    let res = parse_u8(next);
3330                    let Some(val) = res else { break };
3331                    val
3332                }),
3333                26u16 => OpDelruleDoRequest::Flowlabel({
3334                    let res = parse_be_u32(next);
3335                    let Some(val) = res else { break };
3336                    val
3337                }),
3338                27u16 => OpDelruleDoRequest::FlowlabelMask({
3339                    let res = parse_be_u32(next);
3340                    let Some(val) = res else { break };
3341                    val
3342                }),
3343                28u16 => OpDelruleDoRequest::SportMask({
3344                    let res = parse_u16(next);
3345                    let Some(val) = res else { break };
3346                    val
3347                }),
3348                29u16 => OpDelruleDoRequest::DportMask({
3349                    let res = parse_u16(next);
3350                    let Some(val) = res else { break };
3351                    val
3352                }),
3353                30u16 => OpDelruleDoRequest::DscpMask({
3354                    let res = parse_u8(next);
3355                    let Some(val) = res else { break };
3356                    val
3357                }),
3358                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3359                n => continue,
3360            };
3361            return Some(Ok(res));
3362        }
3363        Some(Err(ErrorContext::new(
3364            "OpDelruleDoRequest",
3365            r#type.and_then(|t| OpDelruleDoRequest::attr_from_type(t)),
3366            self.orig_loc,
3367            self.buf.as_ptr().wrapping_add(pos) as usize,
3368        )))
3369    }
3370}
3371impl<'a> std::fmt::Debug for IterableOpDelruleDoRequest<'_> {
3372    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3373        let mut fmt = f.debug_struct("OpDelruleDoRequest");
3374        for attr in self.clone() {
3375            let attr = match attr {
3376                Ok(a) => a,
3377                Err(err) => {
3378                    fmt.finish()?;
3379                    f.write_str("Err(")?;
3380                    err.fmt(f)?;
3381                    return f.write_str(")");
3382                }
3383            };
3384            match attr {
3385                OpDelruleDoRequest::Iifname(val) => fmt.field("Iifname", &val),
3386                OpDelruleDoRequest::Goto(val) => fmt.field("Goto", &val),
3387                OpDelruleDoRequest::Priority(val) => fmt.field("Priority", &val),
3388                OpDelruleDoRequest::Fwmark(val) => fmt.field("Fwmark", &val),
3389                OpDelruleDoRequest::Flow(val) => fmt.field("Flow", &val),
3390                OpDelruleDoRequest::TunId(val) => fmt.field("TunId", &val),
3391                OpDelruleDoRequest::SuppressIfgroup(val) => fmt.field("SuppressIfgroup", &val),
3392                OpDelruleDoRequest::SuppressPrefixlen(val) => fmt.field("SuppressPrefixlen", &val),
3393                OpDelruleDoRequest::Table(val) => fmt.field("Table", &val),
3394                OpDelruleDoRequest::Fwmask(val) => fmt.field("Fwmask", &val),
3395                OpDelruleDoRequest::Oifname(val) => fmt.field("Oifname", &val),
3396                OpDelruleDoRequest::L3mdev(val) => fmt.field("L3mdev", &val),
3397                OpDelruleDoRequest::UidRange(val) => fmt.field("UidRange", &val),
3398                OpDelruleDoRequest::Protocol(val) => fmt.field("Protocol", &val),
3399                OpDelruleDoRequest::IpProto(val) => fmt.field("IpProto", &val),
3400                OpDelruleDoRequest::SportRange(val) => fmt.field("SportRange", &val),
3401                OpDelruleDoRequest::DportRange(val) => fmt.field("DportRange", &val),
3402                OpDelruleDoRequest::Dscp(val) => fmt.field("Dscp", &val),
3403                OpDelruleDoRequest::Flowlabel(val) => fmt.field("Flowlabel", &val),
3404                OpDelruleDoRequest::FlowlabelMask(val) => fmt.field("FlowlabelMask", &val),
3405                OpDelruleDoRequest::SportMask(val) => fmt.field("SportMask", &val),
3406                OpDelruleDoRequest::DportMask(val) => fmt.field("DportMask", &val),
3407                OpDelruleDoRequest::DscpMask(val) => fmt.field("DscpMask", &val),
3408            };
3409        }
3410        fmt.finish()
3411    }
3412}
3413impl IterableOpDelruleDoRequest<'_> {
3414    pub fn lookup_attr(
3415        &self,
3416        offset: usize,
3417        missing_type: Option<u16>,
3418    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3419        let mut stack = Vec::new();
3420        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3421        if cur == offset + PushFibRuleHdr::len() {
3422            stack.push(("OpDelruleDoRequest", offset));
3423            return (
3424                stack,
3425                missing_type.and_then(|t| OpDelruleDoRequest::attr_from_type(t)),
3426            );
3427        }
3428        if cur > offset || cur + self.buf.len() < offset {
3429            return (stack, None);
3430        }
3431        let mut attrs = self.clone();
3432        let mut last_off = cur + attrs.pos;
3433        while let Some(attr) = attrs.next() {
3434            let Ok(attr) = attr else { break };
3435            match attr {
3436                OpDelruleDoRequest::Iifname(val) => {
3437                    if last_off == offset {
3438                        stack.push(("Iifname", last_off));
3439                        break;
3440                    }
3441                }
3442                OpDelruleDoRequest::Goto(val) => {
3443                    if last_off == offset {
3444                        stack.push(("Goto", last_off));
3445                        break;
3446                    }
3447                }
3448                OpDelruleDoRequest::Priority(val) => {
3449                    if last_off == offset {
3450                        stack.push(("Priority", last_off));
3451                        break;
3452                    }
3453                }
3454                OpDelruleDoRequest::Fwmark(val) => {
3455                    if last_off == offset {
3456                        stack.push(("Fwmark", last_off));
3457                        break;
3458                    }
3459                }
3460                OpDelruleDoRequest::Flow(val) => {
3461                    if last_off == offset {
3462                        stack.push(("Flow", last_off));
3463                        break;
3464                    }
3465                }
3466                OpDelruleDoRequest::TunId(val) => {
3467                    if last_off == offset {
3468                        stack.push(("TunId", last_off));
3469                        break;
3470                    }
3471                }
3472                OpDelruleDoRequest::SuppressIfgroup(val) => {
3473                    if last_off == offset {
3474                        stack.push(("SuppressIfgroup", last_off));
3475                        break;
3476                    }
3477                }
3478                OpDelruleDoRequest::SuppressPrefixlen(val) => {
3479                    if last_off == offset {
3480                        stack.push(("SuppressPrefixlen", last_off));
3481                        break;
3482                    }
3483                }
3484                OpDelruleDoRequest::Table(val) => {
3485                    if last_off == offset {
3486                        stack.push(("Table", last_off));
3487                        break;
3488                    }
3489                }
3490                OpDelruleDoRequest::Fwmask(val) => {
3491                    if last_off == offset {
3492                        stack.push(("Fwmask", last_off));
3493                        break;
3494                    }
3495                }
3496                OpDelruleDoRequest::Oifname(val) => {
3497                    if last_off == offset {
3498                        stack.push(("Oifname", last_off));
3499                        break;
3500                    }
3501                }
3502                OpDelruleDoRequest::L3mdev(val) => {
3503                    if last_off == offset {
3504                        stack.push(("L3mdev", last_off));
3505                        break;
3506                    }
3507                }
3508                OpDelruleDoRequest::UidRange(val) => {
3509                    if last_off == offset {
3510                        stack.push(("UidRange", last_off));
3511                        break;
3512                    }
3513                }
3514                OpDelruleDoRequest::Protocol(val) => {
3515                    if last_off == offset {
3516                        stack.push(("Protocol", last_off));
3517                        break;
3518                    }
3519                }
3520                OpDelruleDoRequest::IpProto(val) => {
3521                    if last_off == offset {
3522                        stack.push(("IpProto", last_off));
3523                        break;
3524                    }
3525                }
3526                OpDelruleDoRequest::SportRange(val) => {
3527                    if last_off == offset {
3528                        stack.push(("SportRange", last_off));
3529                        break;
3530                    }
3531                }
3532                OpDelruleDoRequest::DportRange(val) => {
3533                    if last_off == offset {
3534                        stack.push(("DportRange", last_off));
3535                        break;
3536                    }
3537                }
3538                OpDelruleDoRequest::Dscp(val) => {
3539                    if last_off == offset {
3540                        stack.push(("Dscp", last_off));
3541                        break;
3542                    }
3543                }
3544                OpDelruleDoRequest::Flowlabel(val) => {
3545                    if last_off == offset {
3546                        stack.push(("Flowlabel", last_off));
3547                        break;
3548                    }
3549                }
3550                OpDelruleDoRequest::FlowlabelMask(val) => {
3551                    if last_off == offset {
3552                        stack.push(("FlowlabelMask", last_off));
3553                        break;
3554                    }
3555                }
3556                OpDelruleDoRequest::SportMask(val) => {
3557                    if last_off == offset {
3558                        stack.push(("SportMask", last_off));
3559                        break;
3560                    }
3561                }
3562                OpDelruleDoRequest::DportMask(val) => {
3563                    if last_off == offset {
3564                        stack.push(("DportMask", last_off));
3565                        break;
3566                    }
3567                }
3568                OpDelruleDoRequest::DscpMask(val) => {
3569                    if last_off == offset {
3570                        stack.push(("DscpMask", last_off));
3571                        break;
3572                    }
3573                }
3574                _ => {}
3575            };
3576            last_off = cur + attrs.pos;
3577        }
3578        if !stack.is_empty() {
3579            stack.push(("OpDelruleDoRequest", cur));
3580        }
3581        (stack, None)
3582    }
3583}
3584#[doc = "Remove an existing FIB rule"]
3585pub struct PushOpDelruleDoReply<Prev: Rec> {
3586    pub(crate) prev: Option<Prev>,
3587    pub(crate) header_offset: Option<usize>,
3588}
3589impl<Prev: Rec> Rec for PushOpDelruleDoReply<Prev> {
3590    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3591        self.prev.as_mut().unwrap().as_rec_mut()
3592    }
3593    fn as_rec(&self) -> &Vec<u8> {
3594        self.prev.as_ref().unwrap().as_rec()
3595    }
3596}
3597impl<Prev: Rec> PushOpDelruleDoReply<Prev> {
3598    pub fn new(mut prev: Prev, header: &PushFibRuleHdr) -> Self {
3599        Self::write_header(&mut prev, header);
3600        Self::new_without_header(prev)
3601    }
3602    fn new_without_header(prev: Prev) -> Self {
3603        Self {
3604            prev: Some(prev),
3605            header_offset: None,
3606        }
3607    }
3608    fn write_header(prev: &mut Prev, header: &PushFibRuleHdr) {
3609        prev.as_rec_mut().extend(header.as_slice());
3610    }
3611    pub fn end_nested(mut self) -> Prev {
3612        let mut prev = self.prev.take().unwrap();
3613        if let Some(header_offset) = &self.header_offset {
3614            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3615        }
3616        prev
3617    }
3618}
3619impl<Prev: Rec> Drop for PushOpDelruleDoReply<Prev> {
3620    fn drop(&mut self) {
3621        if let Some(prev) = &mut self.prev {
3622            if let Some(header_offset) = &self.header_offset {
3623                finalize_nested_header(prev.as_rec_mut(), *header_offset);
3624            }
3625        }
3626    }
3627}
3628#[doc = "Remove an existing FIB rule"]
3629#[derive(Clone)]
3630pub enum OpDelruleDoReply {}
3631impl<'a> IterableOpDelruleDoReply<'a> {}
3632impl OpDelruleDoReply {
3633    pub fn new<'a>(buf: &'a [u8]) -> (PushFibRuleHdr, IterableOpDelruleDoReply<'a>) {
3634        let (header, attrs) = buf.split_at(buf.len().min(PushFibRuleHdr::len()));
3635        (
3636            PushFibRuleHdr::new_from_slice(header).unwrap_or_default(),
3637            IterableOpDelruleDoReply::with_loc(attrs, buf.as_ptr() as usize),
3638        )
3639    }
3640    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3641        FibRuleAttrs::attr_from_type(r#type)
3642    }
3643}
3644#[derive(Clone, Copy, Default)]
3645pub struct IterableOpDelruleDoReply<'a> {
3646    buf: &'a [u8],
3647    pos: usize,
3648    orig_loc: usize,
3649}
3650impl<'a> IterableOpDelruleDoReply<'a> {
3651    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3652        Self {
3653            buf,
3654            pos: 0,
3655            orig_loc,
3656        }
3657    }
3658    pub fn get_buf(&self) -> &'a [u8] {
3659        self.buf
3660    }
3661}
3662impl<'a> Iterator for IterableOpDelruleDoReply<'a> {
3663    type Item = Result<OpDelruleDoReply, ErrorContext>;
3664    fn next(&mut self) -> Option<Self::Item> {
3665        let pos = self.pos;
3666        let mut r#type;
3667        loop {
3668            r#type = None;
3669            if self.buf.len() == self.pos {
3670                return None;
3671            }
3672            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3673                break;
3674            };
3675            r#type = Some(header.r#type);
3676            let res = match header.r#type {
3677                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3678                n => continue,
3679            };
3680            return Some(Ok(res));
3681        }
3682        Some(Err(ErrorContext::new(
3683            "OpDelruleDoReply",
3684            r#type.and_then(|t| OpDelruleDoReply::attr_from_type(t)),
3685            self.orig_loc,
3686            self.buf.as_ptr().wrapping_add(pos) as usize,
3687        )))
3688    }
3689}
3690impl std::fmt::Debug for IterableOpDelruleDoReply<'_> {
3691    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3692        let mut fmt = f.debug_struct("OpDelruleDoReply");
3693        for attr in self.clone() {
3694            let attr = match attr {
3695                Ok(a) => a,
3696                Err(err) => {
3697                    fmt.finish()?;
3698                    f.write_str("Err(")?;
3699                    err.fmt(f)?;
3700                    return f.write_str(")");
3701                }
3702            };
3703            match attr {};
3704        }
3705        fmt.finish()
3706    }
3707}
3708impl IterableOpDelruleDoReply<'_> {
3709    pub fn lookup_attr(
3710        &self,
3711        offset: usize,
3712        missing_type: Option<u16>,
3713    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3714        let mut stack = Vec::new();
3715        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3716        if cur == offset + PushFibRuleHdr::len() {
3717            stack.push(("OpDelruleDoReply", offset));
3718            return (
3719                stack,
3720                missing_type.and_then(|t| OpDelruleDoReply::attr_from_type(t)),
3721            );
3722        }
3723        (stack, None)
3724    }
3725}
3726#[derive(Debug)]
3727pub struct RequestOpDelruleDoRequest<'r> {
3728    request: Request<'r>,
3729}
3730impl<'r> RequestOpDelruleDoRequest<'r> {
3731    pub fn new(mut request: Request<'r>, header: &PushFibRuleHdr) -> Self {
3732        PushOpDelruleDoRequest::write_header(&mut request.buf_mut(), header);
3733        Self { request: request }
3734    }
3735    pub fn encode(&mut self) -> PushOpDelruleDoRequest<&mut Vec<u8>> {
3736        PushOpDelruleDoRequest::new_without_header(self.request.buf_mut())
3737    }
3738    pub fn into_encoder(self) -> PushOpDelruleDoRequest<RequestBuf<'r>> {
3739        PushOpDelruleDoRequest::new_without_header(self.request.buf)
3740    }
3741    pub fn decode_request<'buf>(
3742        buf: &'buf [u8],
3743    ) -> (PushFibRuleHdr, IterableOpDelruleDoRequest<'buf>) {
3744        OpDelruleDoRequest::new(buf)
3745    }
3746}
3747impl NetlinkRequest for RequestOpDelruleDoRequest<'_> {
3748    fn protocol(&self) -> Protocol {
3749        Protocol::Raw {
3750            protonum: 0u16,
3751            request_type: 33u16,
3752        }
3753    }
3754    fn flags(&self) -> u16 {
3755        self.request.flags
3756    }
3757    fn payload(&self) -> &[u8] {
3758        self.request.buf()
3759    }
3760    type ReplyType<'buf> = (PushFibRuleHdr, IterableOpDelruleDoReply<'buf>);
3761    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3762        OpDelruleDoReply::new(buf)
3763    }
3764    fn lookup(
3765        buf: &[u8],
3766        offset: usize,
3767        missing_type: Option<u16>,
3768    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3769        OpDelruleDoRequest::new(buf)
3770            .1
3771            .lookup_attr(offset, missing_type)
3772    }
3773}
3774#[doc = "Dump all FIB rules"]
3775pub struct PushOpGetruleDumpRequest<Prev: Rec> {
3776    pub(crate) prev: Option<Prev>,
3777    pub(crate) header_offset: Option<usize>,
3778}
3779impl<Prev: Rec> Rec for PushOpGetruleDumpRequest<Prev> {
3780    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3781        self.prev.as_mut().unwrap().as_rec_mut()
3782    }
3783    fn as_rec(&self) -> &Vec<u8> {
3784        self.prev.as_ref().unwrap().as_rec()
3785    }
3786}
3787impl<Prev: Rec> PushOpGetruleDumpRequest<Prev> {
3788    pub fn new(mut prev: Prev, header: &PushFibRuleHdr) -> Self {
3789        Self::write_header(&mut prev, header);
3790        Self::new_without_header(prev)
3791    }
3792    fn new_without_header(prev: Prev) -> Self {
3793        Self {
3794            prev: Some(prev),
3795            header_offset: None,
3796        }
3797    }
3798    fn write_header(prev: &mut Prev, header: &PushFibRuleHdr) {
3799        prev.as_rec_mut().extend(header.as_slice());
3800    }
3801    pub fn end_nested(mut self) -> Prev {
3802        let mut prev = self.prev.take().unwrap();
3803        if let Some(header_offset) = &self.header_offset {
3804            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3805        }
3806        prev
3807    }
3808}
3809impl<Prev: Rec> Drop for PushOpGetruleDumpRequest<Prev> {
3810    fn drop(&mut self) {
3811        if let Some(prev) = &mut self.prev {
3812            if let Some(header_offset) = &self.header_offset {
3813                finalize_nested_header(prev.as_rec_mut(), *header_offset);
3814            }
3815        }
3816    }
3817}
3818#[doc = "Dump all FIB rules"]
3819#[derive(Clone)]
3820pub enum OpGetruleDumpRequest {}
3821impl<'a> IterableOpGetruleDumpRequest<'a> {}
3822impl OpGetruleDumpRequest {
3823    pub fn new<'a>(buf: &'a [u8]) -> (PushFibRuleHdr, IterableOpGetruleDumpRequest<'a>) {
3824        let (header, attrs) = buf.split_at(buf.len().min(PushFibRuleHdr::len()));
3825        (
3826            PushFibRuleHdr::new_from_slice(header).unwrap_or_default(),
3827            IterableOpGetruleDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
3828        )
3829    }
3830    fn attr_from_type(r#type: u16) -> Option<&'static str> {
3831        FibRuleAttrs::attr_from_type(r#type)
3832    }
3833}
3834#[derive(Clone, Copy, Default)]
3835pub struct IterableOpGetruleDumpRequest<'a> {
3836    buf: &'a [u8],
3837    pos: usize,
3838    orig_loc: usize,
3839}
3840impl<'a> IterableOpGetruleDumpRequest<'a> {
3841    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3842        Self {
3843            buf,
3844            pos: 0,
3845            orig_loc,
3846        }
3847    }
3848    pub fn get_buf(&self) -> &'a [u8] {
3849        self.buf
3850    }
3851}
3852impl<'a> Iterator for IterableOpGetruleDumpRequest<'a> {
3853    type Item = Result<OpGetruleDumpRequest, ErrorContext>;
3854    fn next(&mut self) -> Option<Self::Item> {
3855        let pos = self.pos;
3856        let mut r#type;
3857        loop {
3858            r#type = None;
3859            if self.buf.len() == self.pos {
3860                return None;
3861            }
3862            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
3863                break;
3864            };
3865            r#type = Some(header.r#type);
3866            let res = match header.r#type {
3867                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
3868                n => continue,
3869            };
3870            return Some(Ok(res));
3871        }
3872        Some(Err(ErrorContext::new(
3873            "OpGetruleDumpRequest",
3874            r#type.and_then(|t| OpGetruleDumpRequest::attr_from_type(t)),
3875            self.orig_loc,
3876            self.buf.as_ptr().wrapping_add(pos) as usize,
3877        )))
3878    }
3879}
3880impl std::fmt::Debug for IterableOpGetruleDumpRequest<'_> {
3881    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3882        let mut fmt = f.debug_struct("OpGetruleDumpRequest");
3883        for attr in self.clone() {
3884            let attr = match attr {
3885                Ok(a) => a,
3886                Err(err) => {
3887                    fmt.finish()?;
3888                    f.write_str("Err(")?;
3889                    err.fmt(f)?;
3890                    return f.write_str(")");
3891                }
3892            };
3893            match attr {};
3894        }
3895        fmt.finish()
3896    }
3897}
3898impl IterableOpGetruleDumpRequest<'_> {
3899    pub fn lookup_attr(
3900        &self,
3901        offset: usize,
3902        missing_type: Option<u16>,
3903    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3904        let mut stack = Vec::new();
3905        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3906        if cur == offset + PushFibRuleHdr::len() {
3907            stack.push(("OpGetruleDumpRequest", offset));
3908            return (
3909                stack,
3910                missing_type.and_then(|t| OpGetruleDumpRequest::attr_from_type(t)),
3911            );
3912        }
3913        (stack, None)
3914    }
3915}
3916#[doc = "Dump all FIB rules"]
3917pub struct PushOpGetruleDumpReply<Prev: Rec> {
3918    pub(crate) prev: Option<Prev>,
3919    pub(crate) header_offset: Option<usize>,
3920}
3921impl<Prev: Rec> Rec for PushOpGetruleDumpReply<Prev> {
3922    fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3923        self.prev.as_mut().unwrap().as_rec_mut()
3924    }
3925    fn as_rec(&self) -> &Vec<u8> {
3926        self.prev.as_ref().unwrap().as_rec()
3927    }
3928}
3929impl<Prev: Rec> PushOpGetruleDumpReply<Prev> {
3930    pub fn new(mut prev: Prev, header: &PushFibRuleHdr) -> Self {
3931        Self::write_header(&mut prev, header);
3932        Self::new_without_header(prev)
3933    }
3934    fn new_without_header(prev: Prev) -> Self {
3935        Self {
3936            prev: Some(prev),
3937            header_offset: None,
3938        }
3939    }
3940    fn write_header(prev: &mut Prev, header: &PushFibRuleHdr) {
3941        prev.as_rec_mut().extend(header.as_slice());
3942    }
3943    pub fn end_nested(mut self) -> Prev {
3944        let mut prev = self.prev.take().unwrap();
3945        if let Some(header_offset) = &self.header_offset {
3946            finalize_nested_header(prev.as_rec_mut(), *header_offset);
3947        }
3948        prev
3949    }
3950    pub fn push_iifname(mut self, value: &CStr) -> Self {
3951        push_header(
3952            self.as_rec_mut(),
3953            3u16,
3954            value.to_bytes_with_nul().len() as u16,
3955        );
3956        self.as_rec_mut().extend(value.to_bytes_with_nul());
3957        self
3958    }
3959    pub fn push_iifname_bytes(mut self, value: &[u8]) -> Self {
3960        push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
3961        self.as_rec_mut().extend(value);
3962        self.as_rec_mut().push(0);
3963        self
3964    }
3965    pub fn push_goto(mut self, value: u32) -> Self {
3966        push_header(self.as_rec_mut(), 4u16, 4 as u16);
3967        self.as_rec_mut().extend(value.to_ne_bytes());
3968        self
3969    }
3970    pub fn push_priority(mut self, value: u32) -> Self {
3971        push_header(self.as_rec_mut(), 6u16, 4 as u16);
3972        self.as_rec_mut().extend(value.to_ne_bytes());
3973        self
3974    }
3975    pub fn push_fwmark(mut self, value: u32) -> Self {
3976        push_header(self.as_rec_mut(), 10u16, 4 as u16);
3977        self.as_rec_mut().extend(value.to_ne_bytes());
3978        self
3979    }
3980    pub fn push_flow(mut self, value: u32) -> Self {
3981        push_header(self.as_rec_mut(), 11u16, 4 as u16);
3982        self.as_rec_mut().extend(value.to_ne_bytes());
3983        self
3984    }
3985    pub fn push_tun_id(mut self, value: u64) -> Self {
3986        push_header(self.as_rec_mut(), 12u16, 8 as u16);
3987        self.as_rec_mut().extend(value.to_ne_bytes());
3988        self
3989    }
3990    pub fn push_suppress_ifgroup(mut self, value: u32) -> Self {
3991        push_header(self.as_rec_mut(), 13u16, 4 as u16);
3992        self.as_rec_mut().extend(value.to_ne_bytes());
3993        self
3994    }
3995    pub fn push_suppress_prefixlen(mut self, value: u32) -> Self {
3996        push_header(self.as_rec_mut(), 14u16, 4 as u16);
3997        self.as_rec_mut().extend(value.to_ne_bytes());
3998        self
3999    }
4000    pub fn push_table(mut self, value: u32) -> Self {
4001        push_header(self.as_rec_mut(), 15u16, 4 as u16);
4002        self.as_rec_mut().extend(value.to_ne_bytes());
4003        self
4004    }
4005    pub fn push_fwmask(mut self, value: u32) -> Self {
4006        push_header(self.as_rec_mut(), 16u16, 4 as u16);
4007        self.as_rec_mut().extend(value.to_ne_bytes());
4008        self
4009    }
4010    pub fn push_oifname(mut self, value: &CStr) -> Self {
4011        push_header(
4012            self.as_rec_mut(),
4013            17u16,
4014            value.to_bytes_with_nul().len() as u16,
4015        );
4016        self.as_rec_mut().extend(value.to_bytes_with_nul());
4017        self
4018    }
4019    pub fn push_oifname_bytes(mut self, value: &[u8]) -> Self {
4020        push_header(self.as_rec_mut(), 17u16, (value.len() + 1) as u16);
4021        self.as_rec_mut().extend(value);
4022        self.as_rec_mut().push(0);
4023        self
4024    }
4025    pub fn push_l3mdev(mut self, value: u8) -> Self {
4026        push_header(self.as_rec_mut(), 19u16, 1 as u16);
4027        self.as_rec_mut().extend(value.to_ne_bytes());
4028        self
4029    }
4030    pub fn push_uid_range(mut self, value: PushFibRuleUidRange) -> Self {
4031        push_header(self.as_rec_mut(), 20u16, value.as_slice().len() as u16);
4032        self.as_rec_mut().extend(value.as_slice());
4033        self
4034    }
4035    pub fn push_protocol(mut self, value: u8) -> Self {
4036        push_header(self.as_rec_mut(), 21u16, 1 as u16);
4037        self.as_rec_mut().extend(value.to_ne_bytes());
4038        self
4039    }
4040    pub fn push_ip_proto(mut self, value: u8) -> Self {
4041        push_header(self.as_rec_mut(), 22u16, 1 as u16);
4042        self.as_rec_mut().extend(value.to_ne_bytes());
4043        self
4044    }
4045    pub fn push_sport_range(mut self, value: PushFibRulePortRange) -> Self {
4046        push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
4047        self.as_rec_mut().extend(value.as_slice());
4048        self
4049    }
4050    pub fn push_dport_range(mut self, value: PushFibRulePortRange) -> Self {
4051        push_header(self.as_rec_mut(), 24u16, value.as_slice().len() as u16);
4052        self.as_rec_mut().extend(value.as_slice());
4053        self
4054    }
4055    pub fn push_dscp(mut self, value: u8) -> Self {
4056        push_header(self.as_rec_mut(), 25u16, 1 as u16);
4057        self.as_rec_mut().extend(value.to_ne_bytes());
4058        self
4059    }
4060    pub fn push_flowlabel(mut self, value: u32) -> Self {
4061        push_header(self.as_rec_mut(), 26u16, 4 as u16);
4062        self.as_rec_mut().extend(value.to_be_bytes());
4063        self
4064    }
4065    pub fn push_flowlabel_mask(mut self, value: u32) -> Self {
4066        push_header(self.as_rec_mut(), 27u16, 4 as u16);
4067        self.as_rec_mut().extend(value.to_be_bytes());
4068        self
4069    }
4070    pub fn push_sport_mask(mut self, value: u16) -> Self {
4071        push_header(self.as_rec_mut(), 28u16, 2 as u16);
4072        self.as_rec_mut().extend(value.to_ne_bytes());
4073        self
4074    }
4075    pub fn push_dport_mask(mut self, value: u16) -> Self {
4076        push_header(self.as_rec_mut(), 29u16, 2 as u16);
4077        self.as_rec_mut().extend(value.to_ne_bytes());
4078        self
4079    }
4080    pub fn push_dscp_mask(mut self, value: u8) -> Self {
4081        push_header(self.as_rec_mut(), 30u16, 1 as u16);
4082        self.as_rec_mut().extend(value.to_ne_bytes());
4083        self
4084    }
4085}
4086impl<Prev: Rec> Drop for PushOpGetruleDumpReply<Prev> {
4087    fn drop(&mut self) {
4088        if let Some(prev) = &mut self.prev {
4089            if let Some(header_offset) = &self.header_offset {
4090                finalize_nested_header(prev.as_rec_mut(), *header_offset);
4091            }
4092        }
4093    }
4094}
4095#[doc = "Dump all FIB rules"]
4096#[derive(Clone)]
4097pub enum OpGetruleDumpReply<'a> {
4098    Iifname(&'a CStr),
4099    Goto(u32),
4100    Priority(u32),
4101    Fwmark(u32),
4102    Flow(u32),
4103    TunId(u64),
4104    SuppressIfgroup(u32),
4105    SuppressPrefixlen(u32),
4106    Table(u32),
4107    Fwmask(u32),
4108    Oifname(&'a CStr),
4109    L3mdev(u8),
4110    UidRange(PushFibRuleUidRange),
4111    Protocol(u8),
4112    IpProto(u8),
4113    SportRange(PushFibRulePortRange),
4114    DportRange(PushFibRulePortRange),
4115    Dscp(u8),
4116    Flowlabel(u32),
4117    FlowlabelMask(u32),
4118    SportMask(u16),
4119    DportMask(u16),
4120    DscpMask(u8),
4121}
4122impl<'a> IterableOpGetruleDumpReply<'a> {
4123    pub fn get_iifname(&self) -> Result<&'a CStr, ErrorContext> {
4124        let mut iter = self.clone();
4125        iter.pos = 0;
4126        for attr in iter {
4127            if let OpGetruleDumpReply::Iifname(val) = attr? {
4128                return Ok(val);
4129            }
4130        }
4131        Err(ErrorContext::new_missing(
4132            "OpGetruleDumpReply",
4133            "Iifname",
4134            self.orig_loc,
4135            self.buf.as_ptr() as usize,
4136        ))
4137    }
4138    pub fn get_goto(&self) -> Result<u32, ErrorContext> {
4139        let mut iter = self.clone();
4140        iter.pos = 0;
4141        for attr in iter {
4142            if let OpGetruleDumpReply::Goto(val) = attr? {
4143                return Ok(val);
4144            }
4145        }
4146        Err(ErrorContext::new_missing(
4147            "OpGetruleDumpReply",
4148            "Goto",
4149            self.orig_loc,
4150            self.buf.as_ptr() as usize,
4151        ))
4152    }
4153    pub fn get_priority(&self) -> Result<u32, ErrorContext> {
4154        let mut iter = self.clone();
4155        iter.pos = 0;
4156        for attr in iter {
4157            if let OpGetruleDumpReply::Priority(val) = attr? {
4158                return Ok(val);
4159            }
4160        }
4161        Err(ErrorContext::new_missing(
4162            "OpGetruleDumpReply",
4163            "Priority",
4164            self.orig_loc,
4165            self.buf.as_ptr() as usize,
4166        ))
4167    }
4168    pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
4169        let mut iter = self.clone();
4170        iter.pos = 0;
4171        for attr in iter {
4172            if let OpGetruleDumpReply::Fwmark(val) = attr? {
4173                return Ok(val);
4174            }
4175        }
4176        Err(ErrorContext::new_missing(
4177            "OpGetruleDumpReply",
4178            "Fwmark",
4179            self.orig_loc,
4180            self.buf.as_ptr() as usize,
4181        ))
4182    }
4183    pub fn get_flow(&self) -> Result<u32, ErrorContext> {
4184        let mut iter = self.clone();
4185        iter.pos = 0;
4186        for attr in iter {
4187            if let OpGetruleDumpReply::Flow(val) = attr? {
4188                return Ok(val);
4189            }
4190        }
4191        Err(ErrorContext::new_missing(
4192            "OpGetruleDumpReply",
4193            "Flow",
4194            self.orig_loc,
4195            self.buf.as_ptr() as usize,
4196        ))
4197    }
4198    pub fn get_tun_id(&self) -> Result<u64, ErrorContext> {
4199        let mut iter = self.clone();
4200        iter.pos = 0;
4201        for attr in iter {
4202            if let OpGetruleDumpReply::TunId(val) = attr? {
4203                return Ok(val);
4204            }
4205        }
4206        Err(ErrorContext::new_missing(
4207            "OpGetruleDumpReply",
4208            "TunId",
4209            self.orig_loc,
4210            self.buf.as_ptr() as usize,
4211        ))
4212    }
4213    pub fn get_suppress_ifgroup(&self) -> Result<u32, ErrorContext> {
4214        let mut iter = self.clone();
4215        iter.pos = 0;
4216        for attr in iter {
4217            if let OpGetruleDumpReply::SuppressIfgroup(val) = attr? {
4218                return Ok(val);
4219            }
4220        }
4221        Err(ErrorContext::new_missing(
4222            "OpGetruleDumpReply",
4223            "SuppressIfgroup",
4224            self.orig_loc,
4225            self.buf.as_ptr() as usize,
4226        ))
4227    }
4228    pub fn get_suppress_prefixlen(&self) -> Result<u32, ErrorContext> {
4229        let mut iter = self.clone();
4230        iter.pos = 0;
4231        for attr in iter {
4232            if let OpGetruleDumpReply::SuppressPrefixlen(val) = attr? {
4233                return Ok(val);
4234            }
4235        }
4236        Err(ErrorContext::new_missing(
4237            "OpGetruleDumpReply",
4238            "SuppressPrefixlen",
4239            self.orig_loc,
4240            self.buf.as_ptr() as usize,
4241        ))
4242    }
4243    pub fn get_table(&self) -> Result<u32, ErrorContext> {
4244        let mut iter = self.clone();
4245        iter.pos = 0;
4246        for attr in iter {
4247            if let OpGetruleDumpReply::Table(val) = attr? {
4248                return Ok(val);
4249            }
4250        }
4251        Err(ErrorContext::new_missing(
4252            "OpGetruleDumpReply",
4253            "Table",
4254            self.orig_loc,
4255            self.buf.as_ptr() as usize,
4256        ))
4257    }
4258    pub fn get_fwmask(&self) -> Result<u32, ErrorContext> {
4259        let mut iter = self.clone();
4260        iter.pos = 0;
4261        for attr in iter {
4262            if let OpGetruleDumpReply::Fwmask(val) = attr? {
4263                return Ok(val);
4264            }
4265        }
4266        Err(ErrorContext::new_missing(
4267            "OpGetruleDumpReply",
4268            "Fwmask",
4269            self.orig_loc,
4270            self.buf.as_ptr() as usize,
4271        ))
4272    }
4273    pub fn get_oifname(&self) -> Result<&'a CStr, ErrorContext> {
4274        let mut iter = self.clone();
4275        iter.pos = 0;
4276        for attr in iter {
4277            if let OpGetruleDumpReply::Oifname(val) = attr? {
4278                return Ok(val);
4279            }
4280        }
4281        Err(ErrorContext::new_missing(
4282            "OpGetruleDumpReply",
4283            "Oifname",
4284            self.orig_loc,
4285            self.buf.as_ptr() as usize,
4286        ))
4287    }
4288    pub fn get_l3mdev(&self) -> Result<u8, ErrorContext> {
4289        let mut iter = self.clone();
4290        iter.pos = 0;
4291        for attr in iter {
4292            if let OpGetruleDumpReply::L3mdev(val) = attr? {
4293                return Ok(val);
4294            }
4295        }
4296        Err(ErrorContext::new_missing(
4297            "OpGetruleDumpReply",
4298            "L3mdev",
4299            self.orig_loc,
4300            self.buf.as_ptr() as usize,
4301        ))
4302    }
4303    pub fn get_uid_range(&self) -> Result<PushFibRuleUidRange, ErrorContext> {
4304        let mut iter = self.clone();
4305        iter.pos = 0;
4306        for attr in iter {
4307            if let OpGetruleDumpReply::UidRange(val) = attr? {
4308                return Ok(val);
4309            }
4310        }
4311        Err(ErrorContext::new_missing(
4312            "OpGetruleDumpReply",
4313            "UidRange",
4314            self.orig_loc,
4315            self.buf.as_ptr() as usize,
4316        ))
4317    }
4318    pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
4319        let mut iter = self.clone();
4320        iter.pos = 0;
4321        for attr in iter {
4322            if let OpGetruleDumpReply::Protocol(val) = attr? {
4323                return Ok(val);
4324            }
4325        }
4326        Err(ErrorContext::new_missing(
4327            "OpGetruleDumpReply",
4328            "Protocol",
4329            self.orig_loc,
4330            self.buf.as_ptr() as usize,
4331        ))
4332    }
4333    pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
4334        let mut iter = self.clone();
4335        iter.pos = 0;
4336        for attr in iter {
4337            if let OpGetruleDumpReply::IpProto(val) = attr? {
4338                return Ok(val);
4339            }
4340        }
4341        Err(ErrorContext::new_missing(
4342            "OpGetruleDumpReply",
4343            "IpProto",
4344            self.orig_loc,
4345            self.buf.as_ptr() as usize,
4346        ))
4347    }
4348    pub fn get_sport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
4349        let mut iter = self.clone();
4350        iter.pos = 0;
4351        for attr in iter {
4352            if let OpGetruleDumpReply::SportRange(val) = attr? {
4353                return Ok(val);
4354            }
4355        }
4356        Err(ErrorContext::new_missing(
4357            "OpGetruleDumpReply",
4358            "SportRange",
4359            self.orig_loc,
4360            self.buf.as_ptr() as usize,
4361        ))
4362    }
4363    pub fn get_dport_range(&self) -> Result<PushFibRulePortRange, ErrorContext> {
4364        let mut iter = self.clone();
4365        iter.pos = 0;
4366        for attr in iter {
4367            if let OpGetruleDumpReply::DportRange(val) = attr? {
4368                return Ok(val);
4369            }
4370        }
4371        Err(ErrorContext::new_missing(
4372            "OpGetruleDumpReply",
4373            "DportRange",
4374            self.orig_loc,
4375            self.buf.as_ptr() as usize,
4376        ))
4377    }
4378    pub fn get_dscp(&self) -> Result<u8, ErrorContext> {
4379        let mut iter = self.clone();
4380        iter.pos = 0;
4381        for attr in iter {
4382            if let OpGetruleDumpReply::Dscp(val) = attr? {
4383                return Ok(val);
4384            }
4385        }
4386        Err(ErrorContext::new_missing(
4387            "OpGetruleDumpReply",
4388            "Dscp",
4389            self.orig_loc,
4390            self.buf.as_ptr() as usize,
4391        ))
4392    }
4393    pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
4394        let mut iter = self.clone();
4395        iter.pos = 0;
4396        for attr in iter {
4397            if let OpGetruleDumpReply::Flowlabel(val) = attr? {
4398                return Ok(val);
4399            }
4400        }
4401        Err(ErrorContext::new_missing(
4402            "OpGetruleDumpReply",
4403            "Flowlabel",
4404            self.orig_loc,
4405            self.buf.as_ptr() as usize,
4406        ))
4407    }
4408    pub fn get_flowlabel_mask(&self) -> Result<u32, ErrorContext> {
4409        let mut iter = self.clone();
4410        iter.pos = 0;
4411        for attr in iter {
4412            if let OpGetruleDumpReply::FlowlabelMask(val) = attr? {
4413                return Ok(val);
4414            }
4415        }
4416        Err(ErrorContext::new_missing(
4417            "OpGetruleDumpReply",
4418            "FlowlabelMask",
4419            self.orig_loc,
4420            self.buf.as_ptr() as usize,
4421        ))
4422    }
4423    pub fn get_sport_mask(&self) -> Result<u16, ErrorContext> {
4424        let mut iter = self.clone();
4425        iter.pos = 0;
4426        for attr in iter {
4427            if let OpGetruleDumpReply::SportMask(val) = attr? {
4428                return Ok(val);
4429            }
4430        }
4431        Err(ErrorContext::new_missing(
4432            "OpGetruleDumpReply",
4433            "SportMask",
4434            self.orig_loc,
4435            self.buf.as_ptr() as usize,
4436        ))
4437    }
4438    pub fn get_dport_mask(&self) -> Result<u16, ErrorContext> {
4439        let mut iter = self.clone();
4440        iter.pos = 0;
4441        for attr in iter {
4442            if let OpGetruleDumpReply::DportMask(val) = attr? {
4443                return Ok(val);
4444            }
4445        }
4446        Err(ErrorContext::new_missing(
4447            "OpGetruleDumpReply",
4448            "DportMask",
4449            self.orig_loc,
4450            self.buf.as_ptr() as usize,
4451        ))
4452    }
4453    pub fn get_dscp_mask(&self) -> Result<u8, ErrorContext> {
4454        let mut iter = self.clone();
4455        iter.pos = 0;
4456        for attr in iter {
4457            if let OpGetruleDumpReply::DscpMask(val) = attr? {
4458                return Ok(val);
4459            }
4460        }
4461        Err(ErrorContext::new_missing(
4462            "OpGetruleDumpReply",
4463            "DscpMask",
4464            self.orig_loc,
4465            self.buf.as_ptr() as usize,
4466        ))
4467    }
4468}
4469impl OpGetruleDumpReply<'_> {
4470    pub fn new<'a>(buf: &'a [u8]) -> (PushFibRuleHdr, IterableOpGetruleDumpReply<'a>) {
4471        let (header, attrs) = buf.split_at(buf.len().min(PushFibRuleHdr::len()));
4472        (
4473            PushFibRuleHdr::new_from_slice(header).unwrap_or_default(),
4474            IterableOpGetruleDumpReply::with_loc(attrs, buf.as_ptr() as usize),
4475        )
4476    }
4477    fn attr_from_type(r#type: u16) -> Option<&'static str> {
4478        FibRuleAttrs::attr_from_type(r#type)
4479    }
4480}
4481#[derive(Clone, Copy, Default)]
4482pub struct IterableOpGetruleDumpReply<'a> {
4483    buf: &'a [u8],
4484    pos: usize,
4485    orig_loc: usize,
4486}
4487impl<'a> IterableOpGetruleDumpReply<'a> {
4488    fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4489        Self {
4490            buf,
4491            pos: 0,
4492            orig_loc,
4493        }
4494    }
4495    pub fn get_buf(&self) -> &'a [u8] {
4496        self.buf
4497    }
4498}
4499impl<'a> Iterator for IterableOpGetruleDumpReply<'a> {
4500    type Item = Result<OpGetruleDumpReply<'a>, ErrorContext>;
4501    fn next(&mut self) -> Option<Self::Item> {
4502        let pos = self.pos;
4503        let mut r#type;
4504        loop {
4505            r#type = None;
4506            if self.buf.len() == self.pos {
4507                return None;
4508            }
4509            let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
4510                break;
4511            };
4512            r#type = Some(header.r#type);
4513            let res = match header.r#type {
4514                3u16 => OpGetruleDumpReply::Iifname({
4515                    let res = CStr::from_bytes_with_nul(next).ok();
4516                    let Some(val) = res else { break };
4517                    val
4518                }),
4519                4u16 => OpGetruleDumpReply::Goto({
4520                    let res = parse_u32(next);
4521                    let Some(val) = res else { break };
4522                    val
4523                }),
4524                6u16 => OpGetruleDumpReply::Priority({
4525                    let res = parse_u32(next);
4526                    let Some(val) = res else { break };
4527                    val
4528                }),
4529                10u16 => OpGetruleDumpReply::Fwmark({
4530                    let res = parse_u32(next);
4531                    let Some(val) = res else { break };
4532                    val
4533                }),
4534                11u16 => OpGetruleDumpReply::Flow({
4535                    let res = parse_u32(next);
4536                    let Some(val) = res else { break };
4537                    val
4538                }),
4539                12u16 => OpGetruleDumpReply::TunId({
4540                    let res = parse_u64(next);
4541                    let Some(val) = res else { break };
4542                    val
4543                }),
4544                13u16 => OpGetruleDumpReply::SuppressIfgroup({
4545                    let res = parse_u32(next);
4546                    let Some(val) = res else { break };
4547                    val
4548                }),
4549                14u16 => OpGetruleDumpReply::SuppressPrefixlen({
4550                    let res = parse_u32(next);
4551                    let Some(val) = res else { break };
4552                    val
4553                }),
4554                15u16 => OpGetruleDumpReply::Table({
4555                    let res = parse_u32(next);
4556                    let Some(val) = res else { break };
4557                    val
4558                }),
4559                16u16 => OpGetruleDumpReply::Fwmask({
4560                    let res = parse_u32(next);
4561                    let Some(val) = res else { break };
4562                    val
4563                }),
4564                17u16 => OpGetruleDumpReply::Oifname({
4565                    let res = CStr::from_bytes_with_nul(next).ok();
4566                    let Some(val) = res else { break };
4567                    val
4568                }),
4569                19u16 => OpGetruleDumpReply::L3mdev({
4570                    let res = parse_u8(next);
4571                    let Some(val) = res else { break };
4572                    val
4573                }),
4574                20u16 => OpGetruleDumpReply::UidRange({
4575                    let res = PushFibRuleUidRange::new_from_slice(next);
4576                    let Some(val) = res else { break };
4577                    val
4578                }),
4579                21u16 => OpGetruleDumpReply::Protocol({
4580                    let res = parse_u8(next);
4581                    let Some(val) = res else { break };
4582                    val
4583                }),
4584                22u16 => OpGetruleDumpReply::IpProto({
4585                    let res = parse_u8(next);
4586                    let Some(val) = res else { break };
4587                    val
4588                }),
4589                23u16 => OpGetruleDumpReply::SportRange({
4590                    let res = PushFibRulePortRange::new_from_slice(next);
4591                    let Some(val) = res else { break };
4592                    val
4593                }),
4594                24u16 => OpGetruleDumpReply::DportRange({
4595                    let res = PushFibRulePortRange::new_from_slice(next);
4596                    let Some(val) = res else { break };
4597                    val
4598                }),
4599                25u16 => OpGetruleDumpReply::Dscp({
4600                    let res = parse_u8(next);
4601                    let Some(val) = res else { break };
4602                    val
4603                }),
4604                26u16 => OpGetruleDumpReply::Flowlabel({
4605                    let res = parse_be_u32(next);
4606                    let Some(val) = res else { break };
4607                    val
4608                }),
4609                27u16 => OpGetruleDumpReply::FlowlabelMask({
4610                    let res = parse_be_u32(next);
4611                    let Some(val) = res else { break };
4612                    val
4613                }),
4614                28u16 => OpGetruleDumpReply::SportMask({
4615                    let res = parse_u16(next);
4616                    let Some(val) = res else { break };
4617                    val
4618                }),
4619                29u16 => OpGetruleDumpReply::DportMask({
4620                    let res = parse_u16(next);
4621                    let Some(val) = res else { break };
4622                    val
4623                }),
4624                30u16 => OpGetruleDumpReply::DscpMask({
4625                    let res = parse_u8(next);
4626                    let Some(val) = res else { break };
4627                    val
4628                }),
4629                n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
4630                n => continue,
4631            };
4632            return Some(Ok(res));
4633        }
4634        Some(Err(ErrorContext::new(
4635            "OpGetruleDumpReply",
4636            r#type.and_then(|t| OpGetruleDumpReply::attr_from_type(t)),
4637            self.orig_loc,
4638            self.buf.as_ptr().wrapping_add(pos) as usize,
4639        )))
4640    }
4641}
4642impl<'a> std::fmt::Debug for IterableOpGetruleDumpReply<'_> {
4643    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4644        let mut fmt = f.debug_struct("OpGetruleDumpReply");
4645        for attr in self.clone() {
4646            let attr = match attr {
4647                Ok(a) => a,
4648                Err(err) => {
4649                    fmt.finish()?;
4650                    f.write_str("Err(")?;
4651                    err.fmt(f)?;
4652                    return f.write_str(")");
4653                }
4654            };
4655            match attr {
4656                OpGetruleDumpReply::Iifname(val) => fmt.field("Iifname", &val),
4657                OpGetruleDumpReply::Goto(val) => fmt.field("Goto", &val),
4658                OpGetruleDumpReply::Priority(val) => fmt.field("Priority", &val),
4659                OpGetruleDumpReply::Fwmark(val) => fmt.field("Fwmark", &val),
4660                OpGetruleDumpReply::Flow(val) => fmt.field("Flow", &val),
4661                OpGetruleDumpReply::TunId(val) => fmt.field("TunId", &val),
4662                OpGetruleDumpReply::SuppressIfgroup(val) => fmt.field("SuppressIfgroup", &val),
4663                OpGetruleDumpReply::SuppressPrefixlen(val) => fmt.field("SuppressPrefixlen", &val),
4664                OpGetruleDumpReply::Table(val) => fmt.field("Table", &val),
4665                OpGetruleDumpReply::Fwmask(val) => fmt.field("Fwmask", &val),
4666                OpGetruleDumpReply::Oifname(val) => fmt.field("Oifname", &val),
4667                OpGetruleDumpReply::L3mdev(val) => fmt.field("L3mdev", &val),
4668                OpGetruleDumpReply::UidRange(val) => fmt.field("UidRange", &val),
4669                OpGetruleDumpReply::Protocol(val) => fmt.field("Protocol", &val),
4670                OpGetruleDumpReply::IpProto(val) => fmt.field("IpProto", &val),
4671                OpGetruleDumpReply::SportRange(val) => fmt.field("SportRange", &val),
4672                OpGetruleDumpReply::DportRange(val) => fmt.field("DportRange", &val),
4673                OpGetruleDumpReply::Dscp(val) => fmt.field("Dscp", &val),
4674                OpGetruleDumpReply::Flowlabel(val) => fmt.field("Flowlabel", &val),
4675                OpGetruleDumpReply::FlowlabelMask(val) => fmt.field("FlowlabelMask", &val),
4676                OpGetruleDumpReply::SportMask(val) => fmt.field("SportMask", &val),
4677                OpGetruleDumpReply::DportMask(val) => fmt.field("DportMask", &val),
4678                OpGetruleDumpReply::DscpMask(val) => fmt.field("DscpMask", &val),
4679            };
4680        }
4681        fmt.finish()
4682    }
4683}
4684impl IterableOpGetruleDumpReply<'_> {
4685    pub fn lookup_attr(
4686        &self,
4687        offset: usize,
4688        missing_type: Option<u16>,
4689    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4690        let mut stack = Vec::new();
4691        let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4692        if cur == offset + PushFibRuleHdr::len() {
4693            stack.push(("OpGetruleDumpReply", offset));
4694            return (
4695                stack,
4696                missing_type.and_then(|t| OpGetruleDumpReply::attr_from_type(t)),
4697            );
4698        }
4699        if cur > offset || cur + self.buf.len() < offset {
4700            return (stack, None);
4701        }
4702        let mut attrs = self.clone();
4703        let mut last_off = cur + attrs.pos;
4704        while let Some(attr) = attrs.next() {
4705            let Ok(attr) = attr else { break };
4706            match attr {
4707                OpGetruleDumpReply::Iifname(val) => {
4708                    if last_off == offset {
4709                        stack.push(("Iifname", last_off));
4710                        break;
4711                    }
4712                }
4713                OpGetruleDumpReply::Goto(val) => {
4714                    if last_off == offset {
4715                        stack.push(("Goto", last_off));
4716                        break;
4717                    }
4718                }
4719                OpGetruleDumpReply::Priority(val) => {
4720                    if last_off == offset {
4721                        stack.push(("Priority", last_off));
4722                        break;
4723                    }
4724                }
4725                OpGetruleDumpReply::Fwmark(val) => {
4726                    if last_off == offset {
4727                        stack.push(("Fwmark", last_off));
4728                        break;
4729                    }
4730                }
4731                OpGetruleDumpReply::Flow(val) => {
4732                    if last_off == offset {
4733                        stack.push(("Flow", last_off));
4734                        break;
4735                    }
4736                }
4737                OpGetruleDumpReply::TunId(val) => {
4738                    if last_off == offset {
4739                        stack.push(("TunId", last_off));
4740                        break;
4741                    }
4742                }
4743                OpGetruleDumpReply::SuppressIfgroup(val) => {
4744                    if last_off == offset {
4745                        stack.push(("SuppressIfgroup", last_off));
4746                        break;
4747                    }
4748                }
4749                OpGetruleDumpReply::SuppressPrefixlen(val) => {
4750                    if last_off == offset {
4751                        stack.push(("SuppressPrefixlen", last_off));
4752                        break;
4753                    }
4754                }
4755                OpGetruleDumpReply::Table(val) => {
4756                    if last_off == offset {
4757                        stack.push(("Table", last_off));
4758                        break;
4759                    }
4760                }
4761                OpGetruleDumpReply::Fwmask(val) => {
4762                    if last_off == offset {
4763                        stack.push(("Fwmask", last_off));
4764                        break;
4765                    }
4766                }
4767                OpGetruleDumpReply::Oifname(val) => {
4768                    if last_off == offset {
4769                        stack.push(("Oifname", last_off));
4770                        break;
4771                    }
4772                }
4773                OpGetruleDumpReply::L3mdev(val) => {
4774                    if last_off == offset {
4775                        stack.push(("L3mdev", last_off));
4776                        break;
4777                    }
4778                }
4779                OpGetruleDumpReply::UidRange(val) => {
4780                    if last_off == offset {
4781                        stack.push(("UidRange", last_off));
4782                        break;
4783                    }
4784                }
4785                OpGetruleDumpReply::Protocol(val) => {
4786                    if last_off == offset {
4787                        stack.push(("Protocol", last_off));
4788                        break;
4789                    }
4790                }
4791                OpGetruleDumpReply::IpProto(val) => {
4792                    if last_off == offset {
4793                        stack.push(("IpProto", last_off));
4794                        break;
4795                    }
4796                }
4797                OpGetruleDumpReply::SportRange(val) => {
4798                    if last_off == offset {
4799                        stack.push(("SportRange", last_off));
4800                        break;
4801                    }
4802                }
4803                OpGetruleDumpReply::DportRange(val) => {
4804                    if last_off == offset {
4805                        stack.push(("DportRange", last_off));
4806                        break;
4807                    }
4808                }
4809                OpGetruleDumpReply::Dscp(val) => {
4810                    if last_off == offset {
4811                        stack.push(("Dscp", last_off));
4812                        break;
4813                    }
4814                }
4815                OpGetruleDumpReply::Flowlabel(val) => {
4816                    if last_off == offset {
4817                        stack.push(("Flowlabel", last_off));
4818                        break;
4819                    }
4820                }
4821                OpGetruleDumpReply::FlowlabelMask(val) => {
4822                    if last_off == offset {
4823                        stack.push(("FlowlabelMask", last_off));
4824                        break;
4825                    }
4826                }
4827                OpGetruleDumpReply::SportMask(val) => {
4828                    if last_off == offset {
4829                        stack.push(("SportMask", last_off));
4830                        break;
4831                    }
4832                }
4833                OpGetruleDumpReply::DportMask(val) => {
4834                    if last_off == offset {
4835                        stack.push(("DportMask", last_off));
4836                        break;
4837                    }
4838                }
4839                OpGetruleDumpReply::DscpMask(val) => {
4840                    if last_off == offset {
4841                        stack.push(("DscpMask", last_off));
4842                        break;
4843                    }
4844                }
4845                _ => {}
4846            };
4847            last_off = cur + attrs.pos;
4848        }
4849        if !stack.is_empty() {
4850            stack.push(("OpGetruleDumpReply", cur));
4851        }
4852        (stack, None)
4853    }
4854}
4855#[derive(Debug)]
4856pub struct RequestOpGetruleDumpRequest<'r> {
4857    request: Request<'r>,
4858}
4859impl<'r> RequestOpGetruleDumpRequest<'r> {
4860    pub fn new(mut request: Request<'r>, header: &PushFibRuleHdr) -> Self {
4861        PushOpGetruleDumpRequest::write_header(&mut request.buf_mut(), header);
4862        Self {
4863            request: request.set_dump(),
4864        }
4865    }
4866    pub fn encode(&mut self) -> PushOpGetruleDumpRequest<&mut Vec<u8>> {
4867        PushOpGetruleDumpRequest::new_without_header(self.request.buf_mut())
4868    }
4869    pub fn into_encoder(self) -> PushOpGetruleDumpRequest<RequestBuf<'r>> {
4870        PushOpGetruleDumpRequest::new_without_header(self.request.buf)
4871    }
4872    pub fn decode_request<'buf>(
4873        buf: &'buf [u8],
4874    ) -> (PushFibRuleHdr, IterableOpGetruleDumpRequest<'buf>) {
4875        OpGetruleDumpRequest::new(buf)
4876    }
4877}
4878impl NetlinkRequest for RequestOpGetruleDumpRequest<'_> {
4879    fn protocol(&self) -> Protocol {
4880        Protocol::Raw {
4881            protonum: 0u16,
4882            request_type: 34u16,
4883        }
4884    }
4885    fn flags(&self) -> u16 {
4886        self.request.flags
4887    }
4888    fn payload(&self) -> &[u8] {
4889        self.request.buf()
4890    }
4891    type ReplyType<'buf> = (PushFibRuleHdr, IterableOpGetruleDumpReply<'buf>);
4892    fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
4893        OpGetruleDumpReply::new(buf)
4894    }
4895    fn lookup(
4896        buf: &[u8],
4897        offset: usize,
4898        missing_type: Option<u16>,
4899    ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4900        OpGetruleDumpRequest::new(buf)
4901            .1
4902            .lookup_attr(offset, missing_type)
4903    }
4904}
4905#[derive(Debug)]
4906pub struct ChainedFinal<'a> {
4907    inner: Chained<'a>,
4908}
4909#[derive(Debug)]
4910pub struct Chained<'a> {
4911    buf: RequestBuf<'a>,
4912    first_seq: u32,
4913    lookups: Vec<(&'static str, LookupFn)>,
4914    last_header_offset: usize,
4915    last_kind: Option<RequestInfo>,
4916}
4917impl<'a> ChainedFinal<'a> {
4918    pub fn into_chained(self) -> Chained<'a> {
4919        self.inner
4920    }
4921    pub fn buf(&self) -> &Vec<u8> {
4922        self.inner.buf()
4923    }
4924    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
4925        self.inner.buf_mut()
4926    }
4927    fn get_index(&self, seq: u32) -> Option<u32> {
4928        let min = self.inner.first_seq;
4929        let max = min.wrapping_add(self.inner.lookups.len() as u32);
4930        return if min <= max {
4931            (min..max).contains(&seq).then(|| seq - min)
4932        } else if min <= seq {
4933            Some(seq - min)
4934        } else if seq < max {
4935            Some(u32::MAX - min + seq)
4936        } else {
4937            None
4938        };
4939    }
4940}
4941impl crate::traits::NetlinkChained for ChainedFinal<'_> {
4942    fn protonum(&self) -> u16 {
4943        PROTONUM
4944    }
4945    fn payload(&self) -> &[u8] {
4946        self.buf()
4947    }
4948    fn chain_len(&self) -> usize {
4949        self.inner.lookups.len()
4950    }
4951    fn get_index(&self, seq: u32) -> Option<usize> {
4952        self.get_index(seq).map(|n| n as usize)
4953    }
4954    fn name(&self, index: usize) -> &'static str {
4955        self.inner.lookups[index].0
4956    }
4957    fn lookup(&self, index: usize) -> LookupFn {
4958        self.inner.lookups[index].1
4959    }
4960}
4961impl Chained<'static> {
4962    pub fn new(first_seq: u32) -> Self {
4963        Self::new_from_buf(Vec::new(), first_seq)
4964    }
4965    pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
4966        Self {
4967            buf: RequestBuf::Own(buf),
4968            first_seq,
4969            lookups: Vec::new(),
4970            last_header_offset: 0,
4971            last_kind: None,
4972        }
4973    }
4974    pub fn into_buf(self) -> Vec<u8> {
4975        match self.buf {
4976            RequestBuf::Own(buf) => buf,
4977            _ => unreachable!(),
4978        }
4979    }
4980}
4981impl<'a> Chained<'a> {
4982    pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
4983        Self {
4984            buf: RequestBuf::Ref(buf),
4985            first_seq,
4986            lookups: Vec::new(),
4987            last_header_offset: 0,
4988            last_kind: None,
4989        }
4990    }
4991    pub fn finalize(mut self) -> ChainedFinal<'a> {
4992        self.update_header();
4993        ChainedFinal { inner: self }
4994    }
4995    pub fn request(&mut self) -> Request<'_> {
4996        self.update_header();
4997        self.last_header_offset = self.buf().len();
4998        self.buf_mut()
4999            .extend_from_slice(PushNlmsghdr::new().as_slice());
5000        let mut request = Request::new_extend(self.buf.buf_mut());
5001        self.last_kind = None;
5002        request.writeback = Some(&mut self.last_kind);
5003        request
5004    }
5005    pub fn buf(&self) -> &Vec<u8> {
5006        self.buf.buf()
5007    }
5008    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
5009        self.buf.buf_mut()
5010    }
5011    fn update_header(&mut self) {
5012        let Some(RequestInfo {
5013            protocol,
5014            flags,
5015            name,
5016            lookup,
5017        }) = self.last_kind
5018        else {
5019            if !self.buf().is_empty() {
5020                assert_eq!(
5021                    self.last_header_offset + PushNlmsghdr::len(),
5022                    self.buf().len()
5023                );
5024                self.buf.buf_mut().truncate(self.last_header_offset);
5025            }
5026            return;
5027        };
5028        let header_offset = self.last_header_offset;
5029        let request_type = match protocol {
5030            Protocol::Raw { request_type, .. } => request_type,
5031            Protocol::Generic(_) => unreachable!(),
5032        };
5033        let index = self.lookups.len();
5034        let seq = self.first_seq.wrapping_add(index as u32);
5035        self.lookups.push((name, lookup));
5036        let buf = self.buf_mut();
5037        align(buf);
5038        let mut header = PushNlmsghdr::new();
5039        header.set_len((buf.len() - header_offset) as u32);
5040        header.set_type(request_type);
5041        header.set_flags(flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16);
5042        header.set_seq(seq);
5043        buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
5044    }
5045}
5046use crate::traits::LookupFn;
5047use crate::utils::RequestBuf;
5048#[derive(Debug)]
5049pub struct Request<'buf> {
5050    buf: RequestBuf<'buf>,
5051    flags: u16,
5052    writeback: Option<&'buf mut Option<RequestInfo>>,
5053}
5054#[allow(unused)]
5055#[derive(Debug, Clone)]
5056pub struct RequestInfo {
5057    protocol: Protocol,
5058    flags: u16,
5059    name: &'static str,
5060    lookup: LookupFn,
5061}
5062impl Request<'static> {
5063    pub fn new() -> Self {
5064        Self::new_from_buf(Vec::new())
5065    }
5066    pub fn new_from_buf(buf: Vec<u8>) -> Self {
5067        Self {
5068            flags: 0,
5069            buf: RequestBuf::Own(buf),
5070            writeback: None,
5071        }
5072    }
5073    pub fn into_buf(self) -> Vec<u8> {
5074        match self.buf {
5075            RequestBuf::Own(buf) => buf,
5076            _ => unreachable!(),
5077        }
5078    }
5079}
5080impl<'buf> Request<'buf> {
5081    pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
5082        buf.clear();
5083        Self::new_extend(buf)
5084    }
5085    pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
5086        Self {
5087            flags: 0,
5088            buf: RequestBuf::Ref(buf),
5089            writeback: None,
5090        }
5091    }
5092    fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
5093        let Some(writeback) = &mut self.writeback else {
5094            return;
5095        };
5096        **writeback = Some(RequestInfo {
5097            protocol,
5098            flags: self.flags,
5099            name,
5100            lookup,
5101        })
5102    }
5103    pub fn buf(&self) -> &Vec<u8> {
5104        self.buf.buf()
5105    }
5106    pub fn buf_mut(&mut self) -> &mut Vec<u8> {
5107        self.buf.buf_mut()
5108    }
5109    #[doc = "Set `NLM_F_CREATE` flag"]
5110    pub fn set_create(mut self) -> Self {
5111        self.flags |= consts::NLM_F_CREATE as u16;
5112        self
5113    }
5114    #[doc = "Set `NLM_F_EXCL` flag"]
5115    pub fn set_excl(mut self) -> Self {
5116        self.flags |= consts::NLM_F_EXCL as u16;
5117        self
5118    }
5119    #[doc = "Set `NLM_F_REPLACE` flag"]
5120    pub fn set_replace(mut self) -> Self {
5121        self.flags |= consts::NLM_F_REPLACE as u16;
5122        self
5123    }
5124    #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
5125    pub fn set_change(self) -> Self {
5126        self.set_create().set_replace()
5127    }
5128    #[doc = "Set `NLM_F_APPEND` flag"]
5129    pub fn set_append(mut self) -> Self {
5130        self.flags |= consts::NLM_F_APPEND as u16;
5131        self
5132    }
5133    #[doc = "Set `NLM_F_DUMP` flag"]
5134    fn set_dump(mut self) -> Self {
5135        self.flags |= consts::NLM_F_DUMP as u16;
5136        self
5137    }
5138    pub fn op_newrule_do_request(self, header: &PushFibRuleHdr) -> RequestOpNewruleDoRequest<'buf> {
5139        let mut res = RequestOpNewruleDoRequest::new(self, header);
5140        res.request.do_writeback(
5141            res.protocol(),
5142            "op-newrule-do-request",
5143            RequestOpNewruleDoRequest::lookup,
5144        );
5145        res
5146    }
5147    pub fn op_delrule_do_request(self, header: &PushFibRuleHdr) -> RequestOpDelruleDoRequest<'buf> {
5148        let mut res = RequestOpDelruleDoRequest::new(self, header);
5149        res.request.do_writeback(
5150            res.protocol(),
5151            "op-delrule-do-request",
5152            RequestOpDelruleDoRequest::lookup,
5153        );
5154        res
5155    }
5156    pub fn op_getrule_dump_request(
5157        self,
5158        header: &PushFibRuleHdr,
5159    ) -> RequestOpGetruleDumpRequest<'buf> {
5160        let mut res = RequestOpGetruleDumpRequest::new(self, header);
5161        res.request.do_writeback(
5162            res.protocol(),
5163            "op-getrule-dump-request",
5164            RequestOpGetruleDumpRequest::lookup,
5165        );
5166        res
5167    }
5168}