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