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