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