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::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "rt-rule";
17pub const PROTONAME_CSTR: &CStr = c"rt-rule";
18pub const PROTONUM: u16 = 0u16;
19#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
20#[derive(Debug, Clone, Copy)]
21pub enum FrAct {
22 Unspec = 0,
23 ToTbl = 1,
24 Goto = 2,
25 Nop = 3,
26 Res3 = 4,
27 Res4 = 5,
28 Blackhole = 6,
29 Unreachable = 7,
30 Prohibit = 8,
31}
32impl FrAct {
33 pub fn from_value(value: u64) -> Option<Self> {
34 Some(match value {
35 0 => Self::Unspec,
36 1 => Self::ToTbl,
37 2 => Self::Goto,
38 3 => Self::Nop,
39 4 => Self::Res3,
40 5 => Self::Res4,
41 6 => Self::Blackhole,
42 7 => Self::Unreachable,
43 8 => Self::Prohibit,
44 _ => return None,
45 })
46 }
47}
48#[repr(C, packed(4))]
49pub struct Rtgenmsg {
50 pub family: u8,
51 pub _pad: [u8; 3usize],
52}
53impl Clone for Rtgenmsg {
54 fn clone(&self) -> Self {
55 Self::new_from_array(*self.as_array())
56 }
57}
58#[doc = "Create zero-initialized struct"]
59impl Default for Rtgenmsg {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64impl Rtgenmsg {
65 #[doc = "Create zero-initialized struct"]
66 pub fn new() -> Self {
67 Self::new_from_array([0u8; Self::len()])
68 }
69 #[doc = "Copy from contents from slice"]
70 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
71 if other.len() != Self::len() {
72 return None;
73 }
74 let mut buf = [0u8; Self::len()];
75 buf.clone_from_slice(other);
76 Some(Self::new_from_array(buf))
77 }
78 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
79 pub fn new_from_zeroed(other: &[u8]) -> Self {
80 let mut buf = [0u8; Self::len()];
81 let len = buf.len().min(other.len());
82 buf[..len].clone_from_slice(&other[..len]);
83 Self::new_from_array(buf)
84 }
85 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
86 unsafe { std::mem::transmute(buf) }
87 }
88 pub fn as_slice(&self) -> &[u8] {
89 unsafe {
90 let ptr: *const u8 = std::mem::transmute(self as *const Self);
91 std::slice::from_raw_parts(ptr, Self::len())
92 }
93 }
94 pub fn from_slice(buf: &[u8]) -> &Self {
95 assert!(buf.len() >= Self::len());
96 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
97 unsafe { std::mem::transmute(buf.as_ptr()) }
98 }
99 pub fn as_array(&self) -> &[u8; 4usize] {
100 unsafe { std::mem::transmute(self) }
101 }
102 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
103 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
104 unsafe { std::mem::transmute(buf) }
105 }
106 pub fn into_array(self) -> [u8; 4usize] {
107 unsafe { std::mem::transmute(self) }
108 }
109 pub const fn len() -> usize {
110 const _: () = assert!(std::mem::size_of::<Rtgenmsg>() == 4usize);
111 4usize
112 }
113}
114impl std::fmt::Debug for Rtgenmsg {
115 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 fmt.debug_struct("Rtgenmsg")
117 .field("family", &self.family)
118 .finish()
119 }
120}
121#[repr(C, packed(4))]
122pub struct FibRuleHdr {
123 pub family: u8,
124 pub dst_len: u8,
125 pub src_len: u8,
126 pub tos: u8,
127 pub table: u8,
128 pub _res1: [u8; 1usize],
129 pub _res2: [u8; 1usize],
130 #[doc = "Associated type: [`FrAct`] (enum)"]
131 pub action: u8,
132 pub flags: u32,
133}
134impl Clone for FibRuleHdr {
135 fn clone(&self) -> Self {
136 Self::new_from_array(*self.as_array())
137 }
138}
139#[doc = "Create zero-initialized struct"]
140impl Default for FibRuleHdr {
141 fn default() -> Self {
142 Self::new()
143 }
144}
145impl FibRuleHdr {
146 #[doc = "Create zero-initialized struct"]
147 pub fn new() -> Self {
148 Self::new_from_array([0u8; Self::len()])
149 }
150 #[doc = "Copy from contents from slice"]
151 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
152 if other.len() != Self::len() {
153 return None;
154 }
155 let mut buf = [0u8; Self::len()];
156 buf.clone_from_slice(other);
157 Some(Self::new_from_array(buf))
158 }
159 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
160 pub fn new_from_zeroed(other: &[u8]) -> Self {
161 let mut buf = [0u8; Self::len()];
162 let len = buf.len().min(other.len());
163 buf[..len].clone_from_slice(&other[..len]);
164 Self::new_from_array(buf)
165 }
166 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
167 unsafe { std::mem::transmute(buf) }
168 }
169 pub fn as_slice(&self) -> &[u8] {
170 unsafe {
171 let ptr: *const u8 = std::mem::transmute(self as *const Self);
172 std::slice::from_raw_parts(ptr, Self::len())
173 }
174 }
175 pub fn from_slice(buf: &[u8]) -> &Self {
176 assert!(buf.len() >= Self::len());
177 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
178 unsafe { std::mem::transmute(buf.as_ptr()) }
179 }
180 pub fn as_array(&self) -> &[u8; 12usize] {
181 unsafe { std::mem::transmute(self) }
182 }
183 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
184 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
185 unsafe { std::mem::transmute(buf) }
186 }
187 pub fn into_array(self) -> [u8; 12usize] {
188 unsafe { std::mem::transmute(self) }
189 }
190 pub const fn len() -> usize {
191 const _: () = assert!(std::mem::size_of::<FibRuleHdr>() == 12usize);
192 12usize
193 }
194}
195impl std::fmt::Debug for FibRuleHdr {
196 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 fmt.debug_struct("FibRuleHdr")
198 .field("family", &self.family)
199 .field("dst_len", &self.dst_len)
200 .field("src_len", &self.src_len)
201 .field("tos", &self.tos)
202 .field("table", &self.table)
203 .field("action", &FormatEnum(self.action.into(), FrAct::from_value))
204 .field("flags", &self.flags)
205 .finish()
206 }
207}
208#[derive(Debug)]
209#[repr(C, packed(4))]
210pub struct FibRulePortRange {
211 pub start: u16,
212 pub end: u16,
213}
214impl Clone for FibRulePortRange {
215 fn clone(&self) -> Self {
216 Self::new_from_array(*self.as_array())
217 }
218}
219#[doc = "Create zero-initialized struct"]
220impl Default for FibRulePortRange {
221 fn default() -> Self {
222 Self::new()
223 }
224}
225impl FibRulePortRange {
226 #[doc = "Create zero-initialized struct"]
227 pub fn new() -> Self {
228 Self::new_from_array([0u8; Self::len()])
229 }
230 #[doc = "Copy from contents from slice"]
231 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
232 if other.len() != Self::len() {
233 return None;
234 }
235 let mut buf = [0u8; Self::len()];
236 buf.clone_from_slice(other);
237 Some(Self::new_from_array(buf))
238 }
239 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
240 pub fn new_from_zeroed(other: &[u8]) -> Self {
241 let mut buf = [0u8; Self::len()];
242 let len = buf.len().min(other.len());
243 buf[..len].clone_from_slice(&other[..len]);
244 Self::new_from_array(buf)
245 }
246 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
247 unsafe { std::mem::transmute(buf) }
248 }
249 pub fn as_slice(&self) -> &[u8] {
250 unsafe {
251 let ptr: *const u8 = std::mem::transmute(self as *const Self);
252 std::slice::from_raw_parts(ptr, Self::len())
253 }
254 }
255 pub fn from_slice(buf: &[u8]) -> &Self {
256 assert!(buf.len() >= Self::len());
257 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
258 unsafe { std::mem::transmute(buf.as_ptr()) }
259 }
260 pub fn as_array(&self) -> &[u8; 4usize] {
261 unsafe { std::mem::transmute(self) }
262 }
263 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
264 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
265 unsafe { std::mem::transmute(buf) }
266 }
267 pub fn into_array(self) -> [u8; 4usize] {
268 unsafe { std::mem::transmute(self) }
269 }
270 pub const fn len() -> usize {
271 const _: () = assert!(std::mem::size_of::<FibRulePortRange>() == 4usize);
272 4usize
273 }
274}
275#[derive(Debug)]
276#[repr(C, packed(4))]
277pub struct FibRuleUidRange {
278 pub start: u32,
279 pub end: u32,
280}
281impl Clone for FibRuleUidRange {
282 fn clone(&self) -> Self {
283 Self::new_from_array(*self.as_array())
284 }
285}
286#[doc = "Create zero-initialized struct"]
287impl Default for FibRuleUidRange {
288 fn default() -> Self {
289 Self::new()
290 }
291}
292impl FibRuleUidRange {
293 #[doc = "Create zero-initialized struct"]
294 pub fn new() -> Self {
295 Self::new_from_array([0u8; Self::len()])
296 }
297 #[doc = "Copy from contents from slice"]
298 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
299 if other.len() != Self::len() {
300 return None;
301 }
302 let mut buf = [0u8; Self::len()];
303 buf.clone_from_slice(other);
304 Some(Self::new_from_array(buf))
305 }
306 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
307 pub fn new_from_zeroed(other: &[u8]) -> Self {
308 let mut buf = [0u8; Self::len()];
309 let len = buf.len().min(other.len());
310 buf[..len].clone_from_slice(&other[..len]);
311 Self::new_from_array(buf)
312 }
313 pub fn new_from_array(buf: [u8; 8usize]) -> Self {
314 unsafe { std::mem::transmute(buf) }
315 }
316 pub fn as_slice(&self) -> &[u8] {
317 unsafe {
318 let ptr: *const u8 = std::mem::transmute(self as *const Self);
319 std::slice::from_raw_parts(ptr, Self::len())
320 }
321 }
322 pub fn from_slice(buf: &[u8]) -> &Self {
323 assert!(buf.len() >= Self::len());
324 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
325 unsafe { std::mem::transmute(buf.as_ptr()) }
326 }
327 pub fn as_array(&self) -> &[u8; 8usize] {
328 unsafe { std::mem::transmute(self) }
329 }
330 pub fn from_array(buf: &[u8; 8usize]) -> &Self {
331 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
332 unsafe { std::mem::transmute(buf) }
333 }
334 pub fn into_array(self) -> [u8; 8usize] {
335 unsafe { std::mem::transmute(self) }
336 }
337 pub const fn len() -> usize {
338 const _: () = assert!(std::mem::size_of::<FibRuleUidRange>() == 8usize);
339 8usize
340 }
341}
342#[derive(Clone)]
343pub enum FibRuleAttrs<'a> {
344 Dst(std::net::IpAddr),
345 Src(std::net::IpAddr),
346 Iifname(&'a CStr),
347 Goto(u32),
348 Unused2(&'a [u8]),
349 Priority(u32),
350 Unused3(&'a [u8]),
351 Unused4(&'a [u8]),
352 Unused5(&'a [u8]),
353 Fwmark(u32),
354 Flow(u32),
355 TunId(u64),
356 SuppressIfgroup(u32),
357 SuppressPrefixlen(u32),
358 Table(u32),
359 Fwmask(u32),
360 Oifname(&'a CStr),
361 Pad(&'a [u8]),
362 L3mdev(u8),
363 UidRange(FibRuleUidRange),
364 Protocol(u8),
365 IpProto(u8),
366 SportRange(FibRulePortRange),
367 DportRange(FibRulePortRange),
368 Dscp(u8),
369 Flowlabel(u32),
370 FlowlabelMask(u32),
371 SportMask(u16),
372 DportMask(u16),
373 DscpMask(u8),
374}
375impl<'a> IterableFibRuleAttrs<'a> {
376 pub fn get_dst(&self) -> Result<std::net::IpAddr, ErrorContext> {
377 let mut iter = self.clone();
378 iter.pos = 0;
379 for attr in iter {
380 if let FibRuleAttrs::Dst(val) = attr? {
381 return Ok(val);
382 }
383 }
384 Err(ErrorContext::new_missing(
385 "FibRuleAttrs",
386 "Dst",
387 self.orig_loc,
388 self.buf.as_ptr() as usize,
389 ))
390 }
391 pub fn get_src(&self) -> Result<std::net::IpAddr, ErrorContext> {
392 let mut iter = self.clone();
393 iter.pos = 0;
394 for attr in iter {
395 if let FibRuleAttrs::Src(val) = attr? {
396 return Ok(val);
397 }
398 }
399 Err(ErrorContext::new_missing(
400 "FibRuleAttrs",
401 "Src",
402 self.orig_loc,
403 self.buf.as_ptr() as usize,
404 ))
405 }
406 pub fn get_iifname(&self) -> Result<&'a CStr, ErrorContext> {
407 let mut iter = self.clone();
408 iter.pos = 0;
409 for attr in iter {
410 if let FibRuleAttrs::Iifname(val) = attr? {
411 return Ok(val);
412 }
413 }
414 Err(ErrorContext::new_missing(
415 "FibRuleAttrs",
416 "Iifname",
417 self.orig_loc,
418 self.buf.as_ptr() as usize,
419 ))
420 }
421 pub fn get_goto(&self) -> Result<u32, ErrorContext> {
422 let mut iter = self.clone();
423 iter.pos = 0;
424 for attr in iter {
425 if let FibRuleAttrs::Goto(val) = attr? {
426 return Ok(val);
427 }
428 }
429 Err(ErrorContext::new_missing(
430 "FibRuleAttrs",
431 "Goto",
432 self.orig_loc,
433 self.buf.as_ptr() as usize,
434 ))
435 }
436 pub fn get_unused2(&self) -> Result<&'a [u8], ErrorContext> {
437 let mut iter = self.clone();
438 iter.pos = 0;
439 for attr in iter {
440 if let FibRuleAttrs::Unused2(val) = attr? {
441 return Ok(val);
442 }
443 }
444 Err(ErrorContext::new_missing(
445 "FibRuleAttrs",
446 "Unused2",
447 self.orig_loc,
448 self.buf.as_ptr() as usize,
449 ))
450 }
451 pub fn get_priority(&self) -> Result<u32, ErrorContext> {
452 let mut iter = self.clone();
453 iter.pos = 0;
454 for attr in iter {
455 if let FibRuleAttrs::Priority(val) = attr? {
456 return Ok(val);
457 }
458 }
459 Err(ErrorContext::new_missing(
460 "FibRuleAttrs",
461 "Priority",
462 self.orig_loc,
463 self.buf.as_ptr() as usize,
464 ))
465 }
466 pub fn get_unused3(&self) -> Result<&'a [u8], ErrorContext> {
467 let mut iter = self.clone();
468 iter.pos = 0;
469 for attr in iter {
470 if let FibRuleAttrs::Unused3(val) = attr? {
471 return Ok(val);
472 }
473 }
474 Err(ErrorContext::new_missing(
475 "FibRuleAttrs",
476 "Unused3",
477 self.orig_loc,
478 self.buf.as_ptr() as usize,
479 ))
480 }
481 pub fn get_unused4(&self) -> Result<&'a [u8], ErrorContext> {
482 let mut iter = self.clone();
483 iter.pos = 0;
484 for attr in iter {
485 if let FibRuleAttrs::Unused4(val) = attr? {
486 return Ok(val);
487 }
488 }
489 Err(ErrorContext::new_missing(
490 "FibRuleAttrs",
491 "Unused4",
492 self.orig_loc,
493 self.buf.as_ptr() as usize,
494 ))
495 }
496 pub fn get_unused5(&self) -> Result<&'a [u8], ErrorContext> {
497 let mut iter = self.clone();
498 iter.pos = 0;
499 for attr in iter {
500 if let FibRuleAttrs::Unused5(val) = attr? {
501 return Ok(val);
502 }
503 }
504 Err(ErrorContext::new_missing(
505 "FibRuleAttrs",
506 "Unused5",
507 self.orig_loc,
508 self.buf.as_ptr() as usize,
509 ))
510 }
511 pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
512 let mut iter = self.clone();
513 iter.pos = 0;
514 for attr in iter {
515 if let FibRuleAttrs::Fwmark(val) = attr? {
516 return Ok(val);
517 }
518 }
519 Err(ErrorContext::new_missing(
520 "FibRuleAttrs",
521 "Fwmark",
522 self.orig_loc,
523 self.buf.as_ptr() as usize,
524 ))
525 }
526 pub fn get_flow(&self) -> Result<u32, ErrorContext> {
527 let mut iter = self.clone();
528 iter.pos = 0;
529 for attr in iter {
530 if let FibRuleAttrs::Flow(val) = attr? {
531 return Ok(val);
532 }
533 }
534 Err(ErrorContext::new_missing(
535 "FibRuleAttrs",
536 "Flow",
537 self.orig_loc,
538 self.buf.as_ptr() as usize,
539 ))
540 }
541 pub fn get_tun_id(&self) -> Result<u64, ErrorContext> {
542 let mut iter = self.clone();
543 iter.pos = 0;
544 for attr in iter {
545 if let FibRuleAttrs::TunId(val) = attr? {
546 return Ok(val);
547 }
548 }
549 Err(ErrorContext::new_missing(
550 "FibRuleAttrs",
551 "TunId",
552 self.orig_loc,
553 self.buf.as_ptr() as usize,
554 ))
555 }
556 pub fn get_suppress_ifgroup(&self) -> Result<u32, ErrorContext> {
557 let mut iter = self.clone();
558 iter.pos = 0;
559 for attr in iter {
560 if let FibRuleAttrs::SuppressIfgroup(val) = attr? {
561 return Ok(val);
562 }
563 }
564 Err(ErrorContext::new_missing(
565 "FibRuleAttrs",
566 "SuppressIfgroup",
567 self.orig_loc,
568 self.buf.as_ptr() as usize,
569 ))
570 }
571 pub fn get_suppress_prefixlen(&self) -> Result<u32, ErrorContext> {
572 let mut iter = self.clone();
573 iter.pos = 0;
574 for attr in iter {
575 if let FibRuleAttrs::SuppressPrefixlen(val) = attr? {
576 return Ok(val);
577 }
578 }
579 Err(ErrorContext::new_missing(
580 "FibRuleAttrs",
581 "SuppressPrefixlen",
582 self.orig_loc,
583 self.buf.as_ptr() as usize,
584 ))
585 }
586 pub fn get_table(&self) -> Result<u32, ErrorContext> {
587 let mut iter = self.clone();
588 iter.pos = 0;
589 for attr in iter {
590 if let FibRuleAttrs::Table(val) = attr? {
591 return Ok(val);
592 }
593 }
594 Err(ErrorContext::new_missing(
595 "FibRuleAttrs",
596 "Table",
597 self.orig_loc,
598 self.buf.as_ptr() as usize,
599 ))
600 }
601 pub fn get_fwmask(&self) -> Result<u32, ErrorContext> {
602 let mut iter = self.clone();
603 iter.pos = 0;
604 for attr in iter {
605 if let FibRuleAttrs::Fwmask(val) = attr? {
606 return Ok(val);
607 }
608 }
609 Err(ErrorContext::new_missing(
610 "FibRuleAttrs",
611 "Fwmask",
612 self.orig_loc,
613 self.buf.as_ptr() as usize,
614 ))
615 }
616 pub fn get_oifname(&self) -> Result<&'a CStr, ErrorContext> {
617 let mut iter = self.clone();
618 iter.pos = 0;
619 for attr in iter {
620 if let FibRuleAttrs::Oifname(val) = attr? {
621 return Ok(val);
622 }
623 }
624 Err(ErrorContext::new_missing(
625 "FibRuleAttrs",
626 "Oifname",
627 self.orig_loc,
628 self.buf.as_ptr() as usize,
629 ))
630 }
631 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
632 let mut iter = self.clone();
633 iter.pos = 0;
634 for attr in iter {
635 if let FibRuleAttrs::Pad(val) = attr? {
636 return Ok(val);
637 }
638 }
639 Err(ErrorContext::new_missing(
640 "FibRuleAttrs",
641 "Pad",
642 self.orig_loc,
643 self.buf.as_ptr() as usize,
644 ))
645 }
646 pub fn get_l3mdev(&self) -> Result<u8, ErrorContext> {
647 let mut iter = self.clone();
648 iter.pos = 0;
649 for attr in iter {
650 if let FibRuleAttrs::L3mdev(val) = attr? {
651 return Ok(val);
652 }
653 }
654 Err(ErrorContext::new_missing(
655 "FibRuleAttrs",
656 "L3mdev",
657 self.orig_loc,
658 self.buf.as_ptr() as usize,
659 ))
660 }
661 pub fn get_uid_range(&self) -> Result<FibRuleUidRange, ErrorContext> {
662 let mut iter = self.clone();
663 iter.pos = 0;
664 for attr in iter {
665 if let FibRuleAttrs::UidRange(val) = attr? {
666 return Ok(val);
667 }
668 }
669 Err(ErrorContext::new_missing(
670 "FibRuleAttrs",
671 "UidRange",
672 self.orig_loc,
673 self.buf.as_ptr() as usize,
674 ))
675 }
676 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
677 let mut iter = self.clone();
678 iter.pos = 0;
679 for attr in iter {
680 if let FibRuleAttrs::Protocol(val) = attr? {
681 return Ok(val);
682 }
683 }
684 Err(ErrorContext::new_missing(
685 "FibRuleAttrs",
686 "Protocol",
687 self.orig_loc,
688 self.buf.as_ptr() as usize,
689 ))
690 }
691 pub fn get_ip_proto(&self) -> Result<u8, ErrorContext> {
692 let mut iter = self.clone();
693 iter.pos = 0;
694 for attr in iter {
695 if let FibRuleAttrs::IpProto(val) = attr? {
696 return Ok(val);
697 }
698 }
699 Err(ErrorContext::new_missing(
700 "FibRuleAttrs",
701 "IpProto",
702 self.orig_loc,
703 self.buf.as_ptr() as usize,
704 ))
705 }
706 pub fn get_sport_range(&self) -> Result<FibRulePortRange, ErrorContext> {
707 let mut iter = self.clone();
708 iter.pos = 0;
709 for attr in iter {
710 if let FibRuleAttrs::SportRange(val) = attr? {
711 return Ok(val);
712 }
713 }
714 Err(ErrorContext::new_missing(
715 "FibRuleAttrs",
716 "SportRange",
717 self.orig_loc,
718 self.buf.as_ptr() as usize,
719 ))
720 }
721 pub fn get_dport_range(&self) -> Result<FibRulePortRange, ErrorContext> {
722 let mut iter = self.clone();
723 iter.pos = 0;
724 for attr in iter {
725 if let FibRuleAttrs::DportRange(val) = attr? {
726 return Ok(val);
727 }
728 }
729 Err(ErrorContext::new_missing(
730 "FibRuleAttrs",
731 "DportRange",
732 self.orig_loc,
733 self.buf.as_ptr() as usize,
734 ))
735 }
736 pub fn get_dscp(&self) -> Result<u8, ErrorContext> {
737 let mut iter = self.clone();
738 iter.pos = 0;
739 for attr in iter {
740 if let FibRuleAttrs::Dscp(val) = attr? {
741 return Ok(val);
742 }
743 }
744 Err(ErrorContext::new_missing(
745 "FibRuleAttrs",
746 "Dscp",
747 self.orig_loc,
748 self.buf.as_ptr() as usize,
749 ))
750 }
751 pub fn get_flowlabel(&self) -> Result<u32, ErrorContext> {
752 let mut iter = self.clone();
753 iter.pos = 0;
754 for attr in iter {
755 if let FibRuleAttrs::Flowlabel(val) = attr? {
756 return Ok(val);
757 }
758 }
759 Err(ErrorContext::new_missing(
760 "FibRuleAttrs",
761 "Flowlabel",
762 self.orig_loc,
763 self.buf.as_ptr() as usize,
764 ))
765 }
766 pub fn get_flowlabel_mask(&self) -> Result<u32, ErrorContext> {
767 let mut iter = self.clone();
768 iter.pos = 0;
769 for attr in iter {
770 if let FibRuleAttrs::FlowlabelMask(val) = attr? {
771 return Ok(val);
772 }
773 }
774 Err(ErrorContext::new_missing(
775 "FibRuleAttrs",
776 "FlowlabelMask",
777 self.orig_loc,
778 self.buf.as_ptr() as usize,
779 ))
780 }
781 pub fn get_sport_mask(&self) -> Result<u16, ErrorContext> {
782 let mut iter = self.clone();
783 iter.pos = 0;
784 for attr in iter {
785 if let FibRuleAttrs::SportMask(val) = attr? {
786 return Ok(val);
787 }
788 }
789 Err(ErrorContext::new_missing(
790 "FibRuleAttrs",
791 "SportMask",
792 self.orig_loc,
793 self.buf.as_ptr() as usize,
794 ))
795 }
796 pub fn get_dport_mask(&self) -> Result<u16, ErrorContext> {
797 let mut iter = self.clone();
798 iter.pos = 0;
799 for attr in iter {
800 if let FibRuleAttrs::DportMask(val) = attr? {
801 return Ok(val);
802 }
803 }
804 Err(ErrorContext::new_missing(
805 "FibRuleAttrs",
806 "DportMask",
807 self.orig_loc,
808 self.buf.as_ptr() as usize,
809 ))
810 }
811 pub fn get_dscp_mask(&self) -> Result<u8, ErrorContext> {
812 let mut iter = self.clone();
813 iter.pos = 0;
814 for attr in iter {
815 if let FibRuleAttrs::DscpMask(val) = attr? {
816 return Ok(val);
817 }
818 }
819 Err(ErrorContext::new_missing(
820 "FibRuleAttrs",
821 "DscpMask",
822 self.orig_loc,
823 self.buf.as_ptr() as usize,
824 ))
825 }
826}
827impl FibRuleAttrs<'_> {
828 pub fn new<'a>(buf: &'a [u8]) -> IterableFibRuleAttrs<'a> {
829 IterableFibRuleAttrs::with_loc(buf, buf.as_ptr() as usize)
830 }
831 fn attr_from_type(r#type: u16) -> Option<&'static str> {
832 let res = match r#type {
833 1u16 => "Dst",
834 2u16 => "Src",
835 3u16 => "Iifname",
836 4u16 => "Goto",
837 5u16 => "Unused2",
838 6u16 => "Priority",
839 7u16 => "Unused3",
840 8u16 => "Unused4",
841 9u16 => "Unused5",
842 10u16 => "Fwmark",
843 11u16 => "Flow",
844 12u16 => "TunId",
845 13u16 => "SuppressIfgroup",
846 14u16 => "SuppressPrefixlen",
847 15u16 => "Table",
848 16u16 => "Fwmask",
849 17u16 => "Oifname",
850 18u16 => "Pad",
851 19u16 => "L3mdev",
852 20u16 => "UidRange",
853 21u16 => "Protocol",
854 22u16 => "IpProto",
855 23u16 => "SportRange",
856 24u16 => "DportRange",
857 25u16 => "Dscp",
858 26u16 => "Flowlabel",
859 27u16 => "FlowlabelMask",
860 28u16 => "SportMask",
861 29u16 => "DportMask",
862 30u16 => "DscpMask",
863 _ => return None,
864 };
865 Some(res)
866 }
867}
868#[derive(Clone, Copy, Default)]
869pub struct IterableFibRuleAttrs<'a> {
870 buf: &'a [u8],
871 pos: usize,
872 orig_loc: usize,
873}
874impl<'a> IterableFibRuleAttrs<'a> {
875 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
876 Self {
877 buf,
878 pos: 0,
879 orig_loc,
880 }
881 }
882 pub fn get_buf(&self) -> &'a [u8] {
883 self.buf
884 }
885}
886impl<'a> Iterator for IterableFibRuleAttrs<'a> {
887 type Item = Result<FibRuleAttrs<'a>, ErrorContext>;
888 fn next(&mut self) -> Option<Self::Item> {
889 let pos = self.pos;
890 let mut r#type;
891 loop {
892 r#type = None;
893 if self.buf.len() == self.pos {
894 return None;
895 }
896 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
897 break;
898 };
899 r#type = Some(header.r#type);
900 let res = match header.r#type {
901 1u16 => FibRuleAttrs::Dst({
902 let res = parse_ip(next);
903 let Some(val) = res else { break };
904 val
905 }),
906 2u16 => FibRuleAttrs::Src({
907 let res = parse_ip(next);
908 let Some(val) = res else { break };
909 val
910 }),
911 3u16 => FibRuleAttrs::Iifname({
912 let res = CStr::from_bytes_with_nul(next).ok();
913 let Some(val) = res else { break };
914 val
915 }),
916 4u16 => FibRuleAttrs::Goto({
917 let res = parse_u32(next);
918 let Some(val) = res else { break };
919 val
920 }),
921 5u16 => FibRuleAttrs::Unused2({
922 let res = Some(next);
923 let Some(val) = res else { break };
924 val
925 }),
926 6u16 => FibRuleAttrs::Priority({
927 let res = parse_u32(next);
928 let Some(val) = res else { break };
929 val
930 }),
931 7u16 => FibRuleAttrs::Unused3({
932 let res = Some(next);
933 let Some(val) = res else { break };
934 val
935 }),
936 8u16 => FibRuleAttrs::Unused4({
937 let res = Some(next);
938 let Some(val) = res else { break };
939 val
940 }),
941 9u16 => FibRuleAttrs::Unused5({
942 let res = Some(next);
943 let Some(val) = res else { break };
944 val
945 }),
946 10u16 => FibRuleAttrs::Fwmark({
947 let res = parse_u32(next);
948 let Some(val) = res else { break };
949 val
950 }),
951 11u16 => FibRuleAttrs::Flow({
952 let res = parse_u32(next);
953 let Some(val) = res else { break };
954 val
955 }),
956 12u16 => FibRuleAttrs::TunId({
957 let res = parse_u64(next);
958 let Some(val) = res else { break };
959 val
960 }),
961 13u16 => FibRuleAttrs::SuppressIfgroup({
962 let res = parse_u32(next);
963 let Some(val) = res else { break };
964 val
965 }),
966 14u16 => FibRuleAttrs::SuppressPrefixlen({
967 let res = parse_u32(next);
968 let Some(val) = res else { break };
969 val
970 }),
971 15u16 => FibRuleAttrs::Table({
972 let res = parse_u32(next);
973 let Some(val) = res else { break };
974 val
975 }),
976 16u16 => FibRuleAttrs::Fwmask({
977 let res = parse_u32(next);
978 let Some(val) = res else { break };
979 val
980 }),
981 17u16 => FibRuleAttrs::Oifname({
982 let res = CStr::from_bytes_with_nul(next).ok();
983 let Some(val) = res else { break };
984 val
985 }),
986 18u16 => FibRuleAttrs::Pad({
987 let res = Some(next);
988 let Some(val) = res else { break };
989 val
990 }),
991 19u16 => FibRuleAttrs::L3mdev({
992 let res = parse_u8(next);
993 let Some(val) = res else { break };
994 val
995 }),
996 20u16 => FibRuleAttrs::UidRange({
997 let res = Some(FibRuleUidRange::new_from_zeroed(next));
998 let Some(val) = res else { break };
999 val
1000 }),
1001 21u16 => FibRuleAttrs::Protocol({
1002 let res = parse_u8(next);
1003 let Some(val) = res else { break };
1004 val
1005 }),
1006 22u16 => FibRuleAttrs::IpProto({
1007 let res = parse_u8(next);
1008 let Some(val) = res else { break };
1009 val
1010 }),
1011 23u16 => FibRuleAttrs::SportRange({
1012 let res = Some(FibRulePortRange::new_from_zeroed(next));
1013 let Some(val) = res else { break };
1014 val
1015 }),
1016 24u16 => FibRuleAttrs::DportRange({
1017 let res = Some(FibRulePortRange::new_from_zeroed(next));
1018 let Some(val) = res else { break };
1019 val
1020 }),
1021 25u16 => FibRuleAttrs::Dscp({
1022 let res = parse_u8(next);
1023 let Some(val) = res else { break };
1024 val
1025 }),
1026 26u16 => FibRuleAttrs::Flowlabel({
1027 let res = parse_be_u32(next);
1028 let Some(val) = res else { break };
1029 val
1030 }),
1031 27u16 => FibRuleAttrs::FlowlabelMask({
1032 let res = parse_be_u32(next);
1033 let Some(val) = res else { break };
1034 val
1035 }),
1036 28u16 => FibRuleAttrs::SportMask({
1037 let res = parse_u16(next);
1038 let Some(val) = res else { break };
1039 val
1040 }),
1041 29u16 => FibRuleAttrs::DportMask({
1042 let res = parse_u16(next);
1043 let Some(val) = res else { break };
1044 val
1045 }),
1046 30u16 => FibRuleAttrs::DscpMask({
1047 let res = parse_u8(next);
1048 let Some(val) = res else { break };
1049 val
1050 }),
1051 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1052 n => continue,
1053 };
1054 return Some(Ok(res));
1055 }
1056 Some(Err(ErrorContext::new(
1057 "FibRuleAttrs",
1058 r#type.and_then(|t| FibRuleAttrs::attr_from_type(t)),
1059 self.orig_loc,
1060 self.buf.as_ptr().wrapping_add(pos) as usize,
1061 )))
1062 }
1063}
1064impl<'a> std::fmt::Debug for IterableFibRuleAttrs<'_> {
1065 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1066 let mut fmt = f.debug_struct("FibRuleAttrs");
1067 for attr in self.clone() {
1068 let attr = match attr {
1069 Ok(a) => a,
1070 Err(err) => {
1071 fmt.finish()?;
1072 f.write_str("Err(")?;
1073 err.fmt(f)?;
1074 return f.write_str(")");
1075 }
1076 };
1077 match attr {
1078 FibRuleAttrs::Dst(val) => fmt.field("Dst", &val),
1079 FibRuleAttrs::Src(val) => fmt.field("Src", &val),
1080 FibRuleAttrs::Iifname(val) => fmt.field("Iifname", &val),
1081 FibRuleAttrs::Goto(val) => fmt.field("Goto", &val),
1082 FibRuleAttrs::Unused2(val) => fmt.field("Unused2", &val),
1083 FibRuleAttrs::Priority(val) => fmt.field("Priority", &val),
1084 FibRuleAttrs::Unused3(val) => fmt.field("Unused3", &val),
1085 FibRuleAttrs::Unused4(val) => fmt.field("Unused4", &val),
1086 FibRuleAttrs::Unused5(val) => fmt.field("Unused5", &val),
1087 FibRuleAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
1088 FibRuleAttrs::Flow(val) => fmt.field("Flow", &val),
1089 FibRuleAttrs::TunId(val) => fmt.field("TunId", &val),
1090 FibRuleAttrs::SuppressIfgroup(val) => fmt.field("SuppressIfgroup", &val),
1091 FibRuleAttrs::SuppressPrefixlen(val) => fmt.field("SuppressPrefixlen", &val),
1092 FibRuleAttrs::Table(val) => fmt.field("Table", &val),
1093 FibRuleAttrs::Fwmask(val) => fmt.field("Fwmask", &val),
1094 FibRuleAttrs::Oifname(val) => fmt.field("Oifname", &val),
1095 FibRuleAttrs::Pad(val) => fmt.field("Pad", &val),
1096 FibRuleAttrs::L3mdev(val) => fmt.field("L3mdev", &val),
1097 FibRuleAttrs::UidRange(val) => fmt.field("UidRange", &val),
1098 FibRuleAttrs::Protocol(val) => fmt.field("Protocol", &val),
1099 FibRuleAttrs::IpProto(val) => fmt.field("IpProto", &val),
1100 FibRuleAttrs::SportRange(val) => fmt.field("SportRange", &val),
1101 FibRuleAttrs::DportRange(val) => fmt.field("DportRange", &val),
1102 FibRuleAttrs::Dscp(val) => fmt.field("Dscp", &val),
1103 FibRuleAttrs::Flowlabel(val) => fmt.field("Flowlabel", &val),
1104 FibRuleAttrs::FlowlabelMask(val) => fmt.field("FlowlabelMask", &val),
1105 FibRuleAttrs::SportMask(val) => fmt.field("SportMask", &val),
1106 FibRuleAttrs::DportMask(val) => fmt.field("DportMask", &val),
1107 FibRuleAttrs::DscpMask(val) => fmt.field("DscpMask", &val),
1108 };
1109 }
1110 fmt.finish()
1111 }
1112}
1113impl IterableFibRuleAttrs<'_> {
1114 pub fn lookup_attr(
1115 &self,
1116 offset: usize,
1117 missing_type: Option<u16>,
1118 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1119 let mut stack = Vec::new();
1120 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1121 if missing_type.is_some() && cur == offset {
1122 stack.push(("FibRuleAttrs", offset));
1123 return (
1124 stack,
1125 missing_type.and_then(|t| FibRuleAttrs::attr_from_type(t)),
1126 );
1127 }
1128 if cur > offset || cur + self.buf.len() < offset {
1129 return (stack, None);
1130 }
1131 let mut attrs = self.clone();
1132 let mut last_off = cur + attrs.pos;
1133 while let Some(attr) = attrs.next() {
1134 let Ok(attr) = attr else { break };
1135 match attr {
1136 FibRuleAttrs::Dst(val) => {
1137 if last_off == offset {
1138 stack.push(("Dst", last_off));
1139 break;
1140 }
1141 }
1142 FibRuleAttrs::Src(val) => {
1143 if last_off == offset {
1144 stack.push(("Src", last_off));
1145 break;
1146 }
1147 }
1148 FibRuleAttrs::Iifname(val) => {
1149 if last_off == offset {
1150 stack.push(("Iifname", last_off));
1151 break;
1152 }
1153 }
1154 FibRuleAttrs::Goto(val) => {
1155 if last_off == offset {
1156 stack.push(("Goto", last_off));
1157 break;
1158 }
1159 }
1160 FibRuleAttrs::Unused2(val) => {
1161 if last_off == offset {
1162 stack.push(("Unused2", last_off));
1163 break;
1164 }
1165 }
1166 FibRuleAttrs::Priority(val) => {
1167 if last_off == offset {
1168 stack.push(("Priority", last_off));
1169 break;
1170 }
1171 }
1172 FibRuleAttrs::Unused3(val) => {
1173 if last_off == offset {
1174 stack.push(("Unused3", last_off));
1175 break;
1176 }
1177 }
1178 FibRuleAttrs::Unused4(val) => {
1179 if last_off == offset {
1180 stack.push(("Unused4", last_off));
1181 break;
1182 }
1183 }
1184 FibRuleAttrs::Unused5(val) => {
1185 if last_off == offset {
1186 stack.push(("Unused5", last_off));
1187 break;
1188 }
1189 }
1190 FibRuleAttrs::Fwmark(val) => {
1191 if last_off == offset {
1192 stack.push(("Fwmark", last_off));
1193 break;
1194 }
1195 }
1196 FibRuleAttrs::Flow(val) => {
1197 if last_off == offset {
1198 stack.push(("Flow", last_off));
1199 break;
1200 }
1201 }
1202 FibRuleAttrs::TunId(val) => {
1203 if last_off == offset {
1204 stack.push(("TunId", last_off));
1205 break;
1206 }
1207 }
1208 FibRuleAttrs::SuppressIfgroup(val) => {
1209 if last_off == offset {
1210 stack.push(("SuppressIfgroup", last_off));
1211 break;
1212 }
1213 }
1214 FibRuleAttrs::SuppressPrefixlen(val) => {
1215 if last_off == offset {
1216 stack.push(("SuppressPrefixlen", last_off));
1217 break;
1218 }
1219 }
1220 FibRuleAttrs::Table(val) => {
1221 if last_off == offset {
1222 stack.push(("Table", last_off));
1223 break;
1224 }
1225 }
1226 FibRuleAttrs::Fwmask(val) => {
1227 if last_off == offset {
1228 stack.push(("Fwmask", last_off));
1229 break;
1230 }
1231 }
1232 FibRuleAttrs::Oifname(val) => {
1233 if last_off == offset {
1234 stack.push(("Oifname", last_off));
1235 break;
1236 }
1237 }
1238 FibRuleAttrs::Pad(val) => {
1239 if last_off == offset {
1240 stack.push(("Pad", last_off));
1241 break;
1242 }
1243 }
1244 FibRuleAttrs::L3mdev(val) => {
1245 if last_off == offset {
1246 stack.push(("L3mdev", last_off));
1247 break;
1248 }
1249 }
1250 FibRuleAttrs::UidRange(val) => {
1251 if last_off == offset {
1252 stack.push(("UidRange", last_off));
1253 break;
1254 }
1255 }
1256 FibRuleAttrs::Protocol(val) => {
1257 if last_off == offset {
1258 stack.push(("Protocol", last_off));
1259 break;
1260 }
1261 }
1262 FibRuleAttrs::IpProto(val) => {
1263 if last_off == offset {
1264 stack.push(("IpProto", last_off));
1265 break;
1266 }
1267 }
1268 FibRuleAttrs::SportRange(val) => {
1269 if last_off == offset {
1270 stack.push(("SportRange", last_off));
1271 break;
1272 }
1273 }
1274 FibRuleAttrs::DportRange(val) => {
1275 if last_off == offset {
1276 stack.push(("DportRange", last_off));
1277 break;
1278 }
1279 }
1280 FibRuleAttrs::Dscp(val) => {
1281 if last_off == offset {
1282 stack.push(("Dscp", last_off));
1283 break;
1284 }
1285 }
1286 FibRuleAttrs::Flowlabel(val) => {
1287 if last_off == offset {
1288 stack.push(("Flowlabel", last_off));
1289 break;
1290 }
1291 }
1292 FibRuleAttrs::FlowlabelMask(val) => {
1293 if last_off == offset {
1294 stack.push(("FlowlabelMask", last_off));
1295 break;
1296 }
1297 }
1298 FibRuleAttrs::SportMask(val) => {
1299 if last_off == offset {
1300 stack.push(("SportMask", last_off));
1301 break;
1302 }
1303 }
1304 FibRuleAttrs::DportMask(val) => {
1305 if last_off == offset {
1306 stack.push(("DportMask", last_off));
1307 break;
1308 }
1309 }
1310 FibRuleAttrs::DscpMask(val) => {
1311 if last_off == offset {
1312 stack.push(("DscpMask", last_off));
1313 break;
1314 }
1315 }
1316 _ => {}
1317 };
1318 last_off = cur + attrs.pos;
1319 }
1320 if !stack.is_empty() {
1321 stack.push(("FibRuleAttrs", cur));
1322 }
1323 (stack, None)
1324 }
1325}
1326pub struct PushFibRuleAttrs<Prev: Rec> {
1327 pub(crate) prev: Option<Prev>,
1328 pub(crate) header_offset: Option<usize>,
1329}
1330impl<Prev: Rec> Rec for PushFibRuleAttrs<Prev> {
1331 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1332 self.prev.as_mut().unwrap().as_rec_mut()
1333 }
1334 fn as_rec(&self) -> &Vec<u8> {
1335 self.prev.as_ref().unwrap().as_rec()
1336 }
1337}
1338impl<Prev: Rec> PushFibRuleAttrs<Prev> {
1339 pub fn new(prev: Prev) -> Self {
1340 Self {
1341 prev: Some(prev),
1342 header_offset: None,
1343 }
1344 }
1345 pub fn end_nested(mut self) -> Prev {
1346 let mut prev = self.prev.take().unwrap();
1347 if let Some(header_offset) = &self.header_offset {
1348 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1349 }
1350 prev
1351 }
1352 pub fn push_dst(mut self, value: std::net::IpAddr) -> Self {
1353 push_header(self.as_rec_mut(), 1u16, {
1354 match &value {
1355 IpAddr::V4(_) => 4,
1356 IpAddr::V6(_) => 16,
1357 }
1358 } as u16);
1359 encode_ip(self.as_rec_mut(), value);
1360 self
1361 }
1362 pub fn push_src(mut self, value: std::net::IpAddr) -> Self {
1363 push_header(self.as_rec_mut(), 2u16, {
1364 match &value {
1365 IpAddr::V4(_) => 4,
1366 IpAddr::V6(_) => 16,
1367 }
1368 } as u16);
1369 encode_ip(self.as_rec_mut(), value);
1370 self
1371 }
1372 pub fn push_iifname(mut self, value: &CStr) -> Self {
1373 push_header(
1374 self.as_rec_mut(),
1375 3u16,
1376 value.to_bytes_with_nul().len() as u16,
1377 );
1378 self.as_rec_mut().extend(value.to_bytes_with_nul());
1379 self
1380 }
1381 pub fn push_iifname_bytes(mut self, value: &[u8]) -> Self {
1382 push_header(self.as_rec_mut(), 3u16, (value.len() + 1) as u16);
1383 self.as_rec_mut().extend(value);
1384 self.as_rec_mut().push(0);
1385 self
1386 }
1387 pub fn push_goto(mut self, value: u32) -> Self {
1388 push_header(self.as_rec_mut(), 4u16, 4 as u16);
1389 self.as_rec_mut().extend(value.to_ne_bytes());
1390 self
1391 }
1392 pub fn push_unused2(mut self, value: &[u8]) -> Self {
1393 push_header(self.as_rec_mut(), 5u16, value.len() as u16);
1394 self.as_rec_mut().extend(value);
1395 self
1396 }
1397 pub fn push_priority(mut self, value: u32) -> Self {
1398 push_header(self.as_rec_mut(), 6u16, 4 as u16);
1399 self.as_rec_mut().extend(value.to_ne_bytes());
1400 self
1401 }
1402 pub fn push_unused3(mut self, value: &[u8]) -> Self {
1403 push_header(self.as_rec_mut(), 7u16, value.len() as u16);
1404 self.as_rec_mut().extend(value);
1405 self
1406 }
1407 pub fn push_unused4(mut self, value: &[u8]) -> Self {
1408 push_header(self.as_rec_mut(), 8u16, value.len() as u16);
1409 self.as_rec_mut().extend(value);
1410 self
1411 }
1412 pub fn push_unused5(mut self, value: &[u8]) -> Self {
1413 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
1414 self.as_rec_mut().extend(value);
1415 self
1416 }
1417 pub fn push_fwmark(mut self, value: u32) -> Self {
1418 push_header(self.as_rec_mut(), 10u16, 4 as u16);
1419 self.as_rec_mut().extend(value.to_ne_bytes());
1420 self
1421 }
1422 pub fn push_flow(mut self, value: u32) -> Self {
1423 push_header(self.as_rec_mut(), 11u16, 4 as u16);
1424 self.as_rec_mut().extend(value.to_ne_bytes());
1425 self
1426 }
1427 pub fn push_tun_id(mut self, value: u64) -> Self {
1428 push_header(self.as_rec_mut(), 12u16, 8 as u16);
1429 self.as_rec_mut().extend(value.to_ne_bytes());
1430 self
1431 }
1432 pub fn push_suppress_ifgroup(mut self, value: u32) -> Self {
1433 push_header(self.as_rec_mut(), 13u16, 4 as u16);
1434 self.as_rec_mut().extend(value.to_ne_bytes());
1435 self
1436 }
1437 pub fn push_suppress_prefixlen(mut self, value: u32) -> Self {
1438 push_header(self.as_rec_mut(), 14u16, 4 as u16);
1439 self.as_rec_mut().extend(value.to_ne_bytes());
1440 self
1441 }
1442 pub fn push_table(mut self, value: u32) -> Self {
1443 push_header(self.as_rec_mut(), 15u16, 4 as u16);
1444 self.as_rec_mut().extend(value.to_ne_bytes());
1445 self
1446 }
1447 pub fn push_fwmask(mut self, value: u32) -> Self {
1448 push_header(self.as_rec_mut(), 16u16, 4 as u16);
1449 self.as_rec_mut().extend(value.to_ne_bytes());
1450 self
1451 }
1452 pub fn push_oifname(mut self, value: &CStr) -> Self {
1453 push_header(
1454 self.as_rec_mut(),
1455 17u16,
1456 value.to_bytes_with_nul().len() as u16,
1457 );
1458 self.as_rec_mut().extend(value.to_bytes_with_nul());
1459 self
1460 }
1461 pub fn push_oifname_bytes(mut self, value: &[u8]) -> Self {
1462 push_header(self.as_rec_mut(), 17u16, (value.len() + 1) as u16);
1463 self.as_rec_mut().extend(value);
1464 self.as_rec_mut().push(0);
1465 self
1466 }
1467 pub fn push_pad(mut self, value: &[u8]) -> Self {
1468 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
1469 self.as_rec_mut().extend(value);
1470 self
1471 }
1472 pub fn push_l3mdev(mut self, value: u8) -> Self {
1473 push_header(self.as_rec_mut(), 19u16, 1 as u16);
1474 self.as_rec_mut().extend(value.to_ne_bytes());
1475 self
1476 }
1477 pub fn push_uid_range(mut self, value: FibRuleUidRange) -> Self {
1478 push_header(self.as_rec_mut(), 20u16, value.as_slice().len() as u16);
1479 self.as_rec_mut().extend(value.as_slice());
1480 self
1481 }
1482 pub fn push_protocol(mut self, value: u8) -> Self {
1483 push_header(self.as_rec_mut(), 21u16, 1 as u16);
1484 self.as_rec_mut().extend(value.to_ne_bytes());
1485 self
1486 }
1487 pub fn push_ip_proto(mut self, value: u8) -> Self {
1488 push_header(self.as_rec_mut(), 22u16, 1 as u16);
1489 self.as_rec_mut().extend(value.to_ne_bytes());
1490 self
1491 }
1492 pub fn push_sport_range(mut self, value: FibRulePortRange) -> Self {
1493 push_header(self.as_rec_mut(), 23u16, value.as_slice().len() as u16);
1494 self.as_rec_mut().extend(value.as_slice());
1495 self
1496 }
1497 pub fn push_dport_range(mut self, value: FibRulePortRange) -> Self {
1498 push_header(self.as_rec_mut(), 24u16, value.as_slice().len() as u16);
1499 self.as_rec_mut().extend(value.as_slice());
1500 self
1501 }
1502 pub fn push_dscp(mut self, value: u8) -> Self {
1503 push_header(self.as_rec_mut(), 25u16, 1 as u16);
1504 self.as_rec_mut().extend(value.to_ne_bytes());
1505 self
1506 }
1507 pub fn push_flowlabel(mut self, value: u32) -> Self {
1508 push_header(self.as_rec_mut(), 26u16, 4 as u16);
1509 self.as_rec_mut().extend(value.to_be_bytes());
1510 self
1511 }
1512 pub fn push_flowlabel_mask(mut self, value: u32) -> Self {
1513 push_header(self.as_rec_mut(), 27u16, 4 as u16);
1514 self.as_rec_mut().extend(value.to_be_bytes());
1515 self
1516 }
1517 pub fn push_sport_mask(mut self, value: u16) -> Self {
1518 push_header(self.as_rec_mut(), 28u16, 2 as u16);
1519 self.as_rec_mut().extend(value.to_ne_bytes());
1520 self
1521 }
1522 pub fn push_dport_mask(mut self, value: u16) -> Self {
1523 push_header(self.as_rec_mut(), 29u16, 2 as u16);
1524 self.as_rec_mut().extend(value.to_ne_bytes());
1525 self
1526 }
1527 pub fn push_dscp_mask(mut self, value: u8) -> Self {
1528 push_header(self.as_rec_mut(), 30u16, 1 as u16);
1529 self.as_rec_mut().extend(value.to_ne_bytes());
1530 self
1531 }
1532}
1533impl<Prev: Rec> Drop for PushFibRuleAttrs<Prev> {
1534 fn drop(&mut self) {
1535 if let Some(prev) = &mut self.prev {
1536 if let Some(header_offset) = &self.header_offset {
1537 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1538 }
1539 }
1540 }
1541}
1542#[doc = "Add new FIB rule\nRequest attributes:\n- [.push_iifname()](PushFibRuleAttrs::push_iifname)\n- [.push_goto()](PushFibRuleAttrs::push_goto)\n- [.push_priority()](PushFibRuleAttrs::push_priority)\n- [.push_fwmark()](PushFibRuleAttrs::push_fwmark)\n- [.push_flow()](PushFibRuleAttrs::push_flow)\n- [.push_tun_id()](PushFibRuleAttrs::push_tun_id)\n- [.push_suppress_ifgroup()](PushFibRuleAttrs::push_suppress_ifgroup)\n- [.push_suppress_prefixlen()](PushFibRuleAttrs::push_suppress_prefixlen)\n- [.push_table()](PushFibRuleAttrs::push_table)\n- [.push_fwmask()](PushFibRuleAttrs::push_fwmask)\n- [.push_oifname()](PushFibRuleAttrs::push_oifname)\n- [.push_l3mdev()](PushFibRuleAttrs::push_l3mdev)\n- [.push_uid_range()](PushFibRuleAttrs::push_uid_range)\n- [.push_protocol()](PushFibRuleAttrs::push_protocol)\n- [.push_ip_proto()](PushFibRuleAttrs::push_ip_proto)\n- [.push_sport_range()](PushFibRuleAttrs::push_sport_range)\n- [.push_dport_range()](PushFibRuleAttrs::push_dport_range)\n- [.push_dscp()](PushFibRuleAttrs::push_dscp)\n- [.push_flowlabel()](PushFibRuleAttrs::push_flowlabel)\n- [.push_flowlabel_mask()](PushFibRuleAttrs::push_flowlabel_mask)\n- [.push_sport_mask()](PushFibRuleAttrs::push_sport_mask)\n- [.push_dport_mask()](PushFibRuleAttrs::push_dport_mask)\n- [.push_dscp_mask()](PushFibRuleAttrs::push_dscp_mask)\n"]
1543#[derive(Debug)]
1544pub struct OpNewruleDo<'r> {
1545 request: Request<'r>,
1546}
1547impl<'r> OpNewruleDo<'r> {
1548 pub fn new(mut request: Request<'r>, header: &FibRuleHdr) -> Self {
1549 Self::write_header(request.buf_mut(), header);
1550 Self { request: request }
1551 }
1552 pub fn encode_request<'buf>(
1553 buf: &'buf mut Vec<u8>,
1554 header: &FibRuleHdr,
1555 ) -> PushFibRuleAttrs<&'buf mut Vec<u8>> {
1556 Self::write_header(buf, header);
1557 PushFibRuleAttrs::new(buf)
1558 }
1559 pub fn encode(&mut self) -> PushFibRuleAttrs<&mut Vec<u8>> {
1560 PushFibRuleAttrs::new(self.request.buf_mut())
1561 }
1562 pub fn into_encoder(self) -> PushFibRuleAttrs<RequestBuf<'r>> {
1563 PushFibRuleAttrs::new(self.request.buf)
1564 }
1565 pub fn decode_request<'a>(buf: &'a [u8]) -> (FibRuleHdr, IterableFibRuleAttrs<'a>) {
1566 let (header, attrs) = buf.split_at(buf.len().min(FibRuleHdr::len()));
1567 (
1568 FibRuleHdr::new_from_slice(header).unwrap_or_default(),
1569 IterableFibRuleAttrs::with_loc(attrs, buf.as_ptr() as usize),
1570 )
1571 }
1572 fn write_header<Prev: Rec>(prev: &mut Prev, header: &FibRuleHdr) {
1573 prev.as_rec_mut().extend(header.as_slice());
1574 }
1575}
1576impl NetlinkRequest for OpNewruleDo<'_> {
1577 fn protocol(&self) -> Protocol {
1578 Protocol::Raw {
1579 protonum: 0u16,
1580 request_type: 32u16,
1581 }
1582 }
1583 fn flags(&self) -> u16 {
1584 self.request.flags
1585 }
1586 fn payload(&self) -> &[u8] {
1587 self.request.buf()
1588 }
1589 type ReplyType<'buf> = (FibRuleHdr, IterableFibRuleAttrs<'buf>);
1590 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1591 Self::decode_request(buf)
1592 }
1593 fn lookup(
1594 buf: &[u8],
1595 offset: usize,
1596 missing_type: Option<u16>,
1597 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1598 Self::decode_request(buf)
1599 .1
1600 .lookup_attr(offset, missing_type)
1601 }
1602}
1603#[doc = "Remove an existing FIB rule\nRequest attributes:\n- [.push_iifname()](PushFibRuleAttrs::push_iifname)\n- [.push_goto()](PushFibRuleAttrs::push_goto)\n- [.push_priority()](PushFibRuleAttrs::push_priority)\n- [.push_fwmark()](PushFibRuleAttrs::push_fwmark)\n- [.push_flow()](PushFibRuleAttrs::push_flow)\n- [.push_tun_id()](PushFibRuleAttrs::push_tun_id)\n- [.push_suppress_ifgroup()](PushFibRuleAttrs::push_suppress_ifgroup)\n- [.push_suppress_prefixlen()](PushFibRuleAttrs::push_suppress_prefixlen)\n- [.push_table()](PushFibRuleAttrs::push_table)\n- [.push_fwmask()](PushFibRuleAttrs::push_fwmask)\n- [.push_oifname()](PushFibRuleAttrs::push_oifname)\n- [.push_l3mdev()](PushFibRuleAttrs::push_l3mdev)\n- [.push_uid_range()](PushFibRuleAttrs::push_uid_range)\n- [.push_protocol()](PushFibRuleAttrs::push_protocol)\n- [.push_ip_proto()](PushFibRuleAttrs::push_ip_proto)\n- [.push_sport_range()](PushFibRuleAttrs::push_sport_range)\n- [.push_dport_range()](PushFibRuleAttrs::push_dport_range)\n- [.push_dscp()](PushFibRuleAttrs::push_dscp)\n- [.push_flowlabel()](PushFibRuleAttrs::push_flowlabel)\n- [.push_flowlabel_mask()](PushFibRuleAttrs::push_flowlabel_mask)\n- [.push_sport_mask()](PushFibRuleAttrs::push_sport_mask)\n- [.push_dport_mask()](PushFibRuleAttrs::push_dport_mask)\n- [.push_dscp_mask()](PushFibRuleAttrs::push_dscp_mask)\n"]
1604#[derive(Debug)]
1605pub struct OpDelruleDo<'r> {
1606 request: Request<'r>,
1607}
1608impl<'r> OpDelruleDo<'r> {
1609 pub fn new(mut request: Request<'r>, header: &FibRuleHdr) -> Self {
1610 Self::write_header(request.buf_mut(), header);
1611 Self { request: request }
1612 }
1613 pub fn encode_request<'buf>(
1614 buf: &'buf mut Vec<u8>,
1615 header: &FibRuleHdr,
1616 ) -> PushFibRuleAttrs<&'buf mut Vec<u8>> {
1617 Self::write_header(buf, header);
1618 PushFibRuleAttrs::new(buf)
1619 }
1620 pub fn encode(&mut self) -> PushFibRuleAttrs<&mut Vec<u8>> {
1621 PushFibRuleAttrs::new(self.request.buf_mut())
1622 }
1623 pub fn into_encoder(self) -> PushFibRuleAttrs<RequestBuf<'r>> {
1624 PushFibRuleAttrs::new(self.request.buf)
1625 }
1626 pub fn decode_request<'a>(buf: &'a [u8]) -> (FibRuleHdr, IterableFibRuleAttrs<'a>) {
1627 let (header, attrs) = buf.split_at(buf.len().min(FibRuleHdr::len()));
1628 (
1629 FibRuleHdr::new_from_slice(header).unwrap_or_default(),
1630 IterableFibRuleAttrs::with_loc(attrs, buf.as_ptr() as usize),
1631 )
1632 }
1633 fn write_header<Prev: Rec>(prev: &mut Prev, header: &FibRuleHdr) {
1634 prev.as_rec_mut().extend(header.as_slice());
1635 }
1636}
1637impl NetlinkRequest for OpDelruleDo<'_> {
1638 fn protocol(&self) -> Protocol {
1639 Protocol::Raw {
1640 protonum: 0u16,
1641 request_type: 33u16,
1642 }
1643 }
1644 fn flags(&self) -> u16 {
1645 self.request.flags
1646 }
1647 fn payload(&self) -> &[u8] {
1648 self.request.buf()
1649 }
1650 type ReplyType<'buf> = (FibRuleHdr, IterableFibRuleAttrs<'buf>);
1651 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1652 Self::decode_request(buf)
1653 }
1654 fn lookup(
1655 buf: &[u8],
1656 offset: usize,
1657 missing_type: Option<u16>,
1658 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1659 Self::decode_request(buf)
1660 .1
1661 .lookup_attr(offset, missing_type)
1662 }
1663}
1664#[doc = "Dump all FIB rules\n\nReply attributes:\n- [.get_iifname()](IterableFibRuleAttrs::get_iifname)\n- [.get_goto()](IterableFibRuleAttrs::get_goto)\n- [.get_priority()](IterableFibRuleAttrs::get_priority)\n- [.get_fwmark()](IterableFibRuleAttrs::get_fwmark)\n- [.get_flow()](IterableFibRuleAttrs::get_flow)\n- [.get_tun_id()](IterableFibRuleAttrs::get_tun_id)\n- [.get_suppress_ifgroup()](IterableFibRuleAttrs::get_suppress_ifgroup)\n- [.get_suppress_prefixlen()](IterableFibRuleAttrs::get_suppress_prefixlen)\n- [.get_table()](IterableFibRuleAttrs::get_table)\n- [.get_fwmask()](IterableFibRuleAttrs::get_fwmask)\n- [.get_oifname()](IterableFibRuleAttrs::get_oifname)\n- [.get_l3mdev()](IterableFibRuleAttrs::get_l3mdev)\n- [.get_uid_range()](IterableFibRuleAttrs::get_uid_range)\n- [.get_protocol()](IterableFibRuleAttrs::get_protocol)\n- [.get_ip_proto()](IterableFibRuleAttrs::get_ip_proto)\n- [.get_sport_range()](IterableFibRuleAttrs::get_sport_range)\n- [.get_dport_range()](IterableFibRuleAttrs::get_dport_range)\n- [.get_dscp()](IterableFibRuleAttrs::get_dscp)\n- [.get_flowlabel()](IterableFibRuleAttrs::get_flowlabel)\n- [.get_flowlabel_mask()](IterableFibRuleAttrs::get_flowlabel_mask)\n- [.get_sport_mask()](IterableFibRuleAttrs::get_sport_mask)\n- [.get_dport_mask()](IterableFibRuleAttrs::get_dport_mask)\n- [.get_dscp_mask()](IterableFibRuleAttrs::get_dscp_mask)\n"]
1665#[derive(Debug)]
1666pub struct OpGetruleDump<'r> {
1667 request: Request<'r>,
1668}
1669impl<'r> OpGetruleDump<'r> {
1670 pub fn new(mut request: Request<'r>, header: &FibRuleHdr) -> Self {
1671 Self::write_header(request.buf_mut(), header);
1672 Self {
1673 request: request.set_dump(),
1674 }
1675 }
1676 pub fn encode_request<'buf>(
1677 buf: &'buf mut Vec<u8>,
1678 header: &FibRuleHdr,
1679 ) -> PushFibRuleAttrs<&'buf mut Vec<u8>> {
1680 Self::write_header(buf, header);
1681 PushFibRuleAttrs::new(buf)
1682 }
1683 pub fn encode(&mut self) -> PushFibRuleAttrs<&mut Vec<u8>> {
1684 PushFibRuleAttrs::new(self.request.buf_mut())
1685 }
1686 pub fn into_encoder(self) -> PushFibRuleAttrs<RequestBuf<'r>> {
1687 PushFibRuleAttrs::new(self.request.buf)
1688 }
1689 pub fn decode_request<'a>(buf: &'a [u8]) -> (FibRuleHdr, IterableFibRuleAttrs<'a>) {
1690 let (header, attrs) = buf.split_at(buf.len().min(FibRuleHdr::len()));
1691 (
1692 FibRuleHdr::new_from_slice(header).unwrap_or_default(),
1693 IterableFibRuleAttrs::with_loc(attrs, buf.as_ptr() as usize),
1694 )
1695 }
1696 fn write_header<Prev: Rec>(prev: &mut Prev, header: &FibRuleHdr) {
1697 prev.as_rec_mut().extend(header.as_slice());
1698 }
1699}
1700impl NetlinkRequest for OpGetruleDump<'_> {
1701 fn protocol(&self) -> Protocol {
1702 Protocol::Raw {
1703 protonum: 0u16,
1704 request_type: 34u16,
1705 }
1706 }
1707 fn flags(&self) -> u16 {
1708 self.request.flags
1709 }
1710 fn payload(&self) -> &[u8] {
1711 self.request.buf()
1712 }
1713 type ReplyType<'buf> = (FibRuleHdr, IterableFibRuleAttrs<'buf>);
1714 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1715 Self::decode_request(buf)
1716 }
1717 fn lookup(
1718 buf: &[u8],
1719 offset: usize,
1720 missing_type: Option<u16>,
1721 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1722 Self::decode_request(buf)
1723 .1
1724 .lookup_attr(offset, missing_type)
1725 }
1726}
1727#[derive(Debug)]
1728pub struct ChainedFinal<'a> {
1729 inner: Chained<'a>,
1730}
1731#[derive(Debug)]
1732pub struct Chained<'a> {
1733 buf: RequestBuf<'a>,
1734 first_seq: u32,
1735 lookups: Vec<(&'static str, LookupFn)>,
1736 last_header_offset: usize,
1737 last_kind: Option<RequestInfo>,
1738}
1739impl<'a> ChainedFinal<'a> {
1740 pub fn into_chained(self) -> Chained<'a> {
1741 self.inner
1742 }
1743 pub fn buf(&self) -> &Vec<u8> {
1744 self.inner.buf()
1745 }
1746 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1747 self.inner.buf_mut()
1748 }
1749 fn get_index(&self, seq: u32) -> Option<u32> {
1750 let min = self.inner.first_seq;
1751 let max = min.wrapping_add(self.inner.lookups.len() as u32);
1752 return if min <= max {
1753 (min..max).contains(&seq).then(|| seq - min)
1754 } else if min <= seq {
1755 Some(seq - min)
1756 } else if seq < max {
1757 Some(u32::MAX - min + seq)
1758 } else {
1759 None
1760 };
1761 }
1762}
1763impl crate::traits::NetlinkChained for ChainedFinal<'_> {
1764 fn protonum(&self) -> u16 {
1765 PROTONUM
1766 }
1767 fn payload(&self) -> &[u8] {
1768 self.buf()
1769 }
1770 fn chain_len(&self) -> usize {
1771 self.inner.lookups.len()
1772 }
1773 fn get_index(&self, seq: u32) -> Option<usize> {
1774 self.get_index(seq).map(|n| n as usize)
1775 }
1776 fn name(&self, index: usize) -> &'static str {
1777 self.inner.lookups[index].0
1778 }
1779 fn lookup(&self, index: usize) -> LookupFn {
1780 self.inner.lookups[index].1
1781 }
1782}
1783impl Chained<'static> {
1784 pub fn new(first_seq: u32) -> Self {
1785 Self::new_from_buf(Vec::new(), first_seq)
1786 }
1787 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
1788 Self {
1789 buf: RequestBuf::Own(buf),
1790 first_seq,
1791 lookups: Vec::new(),
1792 last_header_offset: 0,
1793 last_kind: None,
1794 }
1795 }
1796 pub fn into_buf(self) -> Vec<u8> {
1797 match self.buf {
1798 RequestBuf::Own(buf) => buf,
1799 _ => unreachable!(),
1800 }
1801 }
1802}
1803impl<'a> Chained<'a> {
1804 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
1805 Self {
1806 buf: RequestBuf::Ref(buf),
1807 first_seq,
1808 lookups: Vec::new(),
1809 last_header_offset: 0,
1810 last_kind: None,
1811 }
1812 }
1813 pub fn finalize(mut self) -> ChainedFinal<'a> {
1814 self.update_header();
1815 ChainedFinal { inner: self }
1816 }
1817 pub fn request(&mut self) -> Request<'_> {
1818 self.update_header();
1819 self.last_header_offset = self.buf().len();
1820 self.buf_mut().extend_from_slice(Nlmsghdr::new().as_slice());
1821 let mut request = Request::new_extend(self.buf.buf_mut());
1822 self.last_kind = None;
1823 request.writeback = Some(&mut self.last_kind);
1824 request
1825 }
1826 pub fn buf(&self) -> &Vec<u8> {
1827 self.buf.buf()
1828 }
1829 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1830 self.buf.buf_mut()
1831 }
1832 fn update_header(&mut self) {
1833 let Some(RequestInfo {
1834 protocol,
1835 flags,
1836 name,
1837 lookup,
1838 }) = self.last_kind
1839 else {
1840 if !self.buf().is_empty() {
1841 assert_eq!(self.last_header_offset + Nlmsghdr::len(), self.buf().len());
1842 self.buf.buf_mut().truncate(self.last_header_offset);
1843 }
1844 return;
1845 };
1846 let header_offset = self.last_header_offset;
1847 let request_type = match protocol {
1848 Protocol::Raw { request_type, .. } => request_type,
1849 Protocol::Generic(_) => unreachable!(),
1850 };
1851 let index = self.lookups.len();
1852 let seq = self.first_seq.wrapping_add(index as u32);
1853 self.lookups.push((name, lookup));
1854 let buf = self.buf_mut();
1855 align(buf);
1856 let header = Nlmsghdr {
1857 len: (buf.len() - header_offset) as u32,
1858 r#type: request_type,
1859 flags: flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16,
1860 seq,
1861 pid: 0,
1862 };
1863 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
1864 }
1865}
1866use crate::traits::LookupFn;
1867use crate::utils::RequestBuf;
1868#[derive(Debug)]
1869pub struct Request<'buf> {
1870 buf: RequestBuf<'buf>,
1871 flags: u16,
1872 writeback: Option<&'buf mut Option<RequestInfo>>,
1873}
1874#[allow(unused)]
1875#[derive(Debug, Clone)]
1876pub struct RequestInfo {
1877 protocol: Protocol,
1878 flags: u16,
1879 name: &'static str,
1880 lookup: LookupFn,
1881}
1882impl Request<'static> {
1883 pub fn new() -> Self {
1884 Self::new_from_buf(Vec::new())
1885 }
1886 pub fn new_from_buf(buf: Vec<u8>) -> Self {
1887 Self {
1888 flags: 0,
1889 buf: RequestBuf::Own(buf),
1890 writeback: None,
1891 }
1892 }
1893 pub fn into_buf(self) -> Vec<u8> {
1894 match self.buf {
1895 RequestBuf::Own(buf) => buf,
1896 _ => unreachable!(),
1897 }
1898 }
1899}
1900impl<'buf> Request<'buf> {
1901 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1902 buf.clear();
1903 Self::new_extend(buf)
1904 }
1905 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1906 Self {
1907 flags: 0,
1908 buf: RequestBuf::Ref(buf),
1909 writeback: None,
1910 }
1911 }
1912 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1913 let Some(writeback) = &mut self.writeback else {
1914 return;
1915 };
1916 **writeback = Some(RequestInfo {
1917 protocol,
1918 flags: self.flags,
1919 name,
1920 lookup,
1921 })
1922 }
1923 pub fn buf(&self) -> &Vec<u8> {
1924 self.buf.buf()
1925 }
1926 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1927 self.buf.buf_mut()
1928 }
1929 #[doc = "Set `NLM_F_CREATE` flag"]
1930 pub fn set_create(mut self) -> Self {
1931 self.flags |= consts::NLM_F_CREATE as u16;
1932 self
1933 }
1934 #[doc = "Set `NLM_F_EXCL` flag"]
1935 pub fn set_excl(mut self) -> Self {
1936 self.flags |= consts::NLM_F_EXCL as u16;
1937 self
1938 }
1939 #[doc = "Set `NLM_F_REPLACE` flag"]
1940 pub fn set_replace(mut self) -> Self {
1941 self.flags |= consts::NLM_F_REPLACE as u16;
1942 self
1943 }
1944 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1945 pub fn set_change(self) -> Self {
1946 self.set_create().set_replace()
1947 }
1948 #[doc = "Set `NLM_F_APPEND` flag"]
1949 pub fn set_append(mut self) -> Self {
1950 self.flags |= consts::NLM_F_APPEND as u16;
1951 self
1952 }
1953 #[doc = "Set `self.flags |= flags`"]
1954 pub fn set_flags(mut self, flags: u16) -> Self {
1955 self.flags |= flags;
1956 self
1957 }
1958 #[doc = "Set `self.flags ^= self.flags & flags`"]
1959 pub fn unset_flags(mut self, flags: u16) -> Self {
1960 self.flags ^= self.flags & flags;
1961 self
1962 }
1963 #[doc = "Set `NLM_F_DUMP` flag"]
1964 fn set_dump(mut self) -> Self {
1965 self.flags |= consts::NLM_F_DUMP as u16;
1966 self
1967 }
1968 #[doc = "Add new FIB rule\nRequest attributes:\n- [.push_iifname()](PushFibRuleAttrs::push_iifname)\n- [.push_goto()](PushFibRuleAttrs::push_goto)\n- [.push_priority()](PushFibRuleAttrs::push_priority)\n- [.push_fwmark()](PushFibRuleAttrs::push_fwmark)\n- [.push_flow()](PushFibRuleAttrs::push_flow)\n- [.push_tun_id()](PushFibRuleAttrs::push_tun_id)\n- [.push_suppress_ifgroup()](PushFibRuleAttrs::push_suppress_ifgroup)\n- [.push_suppress_prefixlen()](PushFibRuleAttrs::push_suppress_prefixlen)\n- [.push_table()](PushFibRuleAttrs::push_table)\n- [.push_fwmask()](PushFibRuleAttrs::push_fwmask)\n- [.push_oifname()](PushFibRuleAttrs::push_oifname)\n- [.push_l3mdev()](PushFibRuleAttrs::push_l3mdev)\n- [.push_uid_range()](PushFibRuleAttrs::push_uid_range)\n- [.push_protocol()](PushFibRuleAttrs::push_protocol)\n- [.push_ip_proto()](PushFibRuleAttrs::push_ip_proto)\n- [.push_sport_range()](PushFibRuleAttrs::push_sport_range)\n- [.push_dport_range()](PushFibRuleAttrs::push_dport_range)\n- [.push_dscp()](PushFibRuleAttrs::push_dscp)\n- [.push_flowlabel()](PushFibRuleAttrs::push_flowlabel)\n- [.push_flowlabel_mask()](PushFibRuleAttrs::push_flowlabel_mask)\n- [.push_sport_mask()](PushFibRuleAttrs::push_sport_mask)\n- [.push_dport_mask()](PushFibRuleAttrs::push_dport_mask)\n- [.push_dscp_mask()](PushFibRuleAttrs::push_dscp_mask)\n"]
1969 pub fn op_newrule_do(self, header: &FibRuleHdr) -> OpNewruleDo<'buf> {
1970 let mut res = OpNewruleDo::new(self, header);
1971 res.request
1972 .do_writeback(res.protocol(), "op-newrule-do", OpNewruleDo::lookup);
1973 res
1974 }
1975 #[doc = "Remove an existing FIB rule\nRequest attributes:\n- [.push_iifname()](PushFibRuleAttrs::push_iifname)\n- [.push_goto()](PushFibRuleAttrs::push_goto)\n- [.push_priority()](PushFibRuleAttrs::push_priority)\n- [.push_fwmark()](PushFibRuleAttrs::push_fwmark)\n- [.push_flow()](PushFibRuleAttrs::push_flow)\n- [.push_tun_id()](PushFibRuleAttrs::push_tun_id)\n- [.push_suppress_ifgroup()](PushFibRuleAttrs::push_suppress_ifgroup)\n- [.push_suppress_prefixlen()](PushFibRuleAttrs::push_suppress_prefixlen)\n- [.push_table()](PushFibRuleAttrs::push_table)\n- [.push_fwmask()](PushFibRuleAttrs::push_fwmask)\n- [.push_oifname()](PushFibRuleAttrs::push_oifname)\n- [.push_l3mdev()](PushFibRuleAttrs::push_l3mdev)\n- [.push_uid_range()](PushFibRuleAttrs::push_uid_range)\n- [.push_protocol()](PushFibRuleAttrs::push_protocol)\n- [.push_ip_proto()](PushFibRuleAttrs::push_ip_proto)\n- [.push_sport_range()](PushFibRuleAttrs::push_sport_range)\n- [.push_dport_range()](PushFibRuleAttrs::push_dport_range)\n- [.push_dscp()](PushFibRuleAttrs::push_dscp)\n- [.push_flowlabel()](PushFibRuleAttrs::push_flowlabel)\n- [.push_flowlabel_mask()](PushFibRuleAttrs::push_flowlabel_mask)\n- [.push_sport_mask()](PushFibRuleAttrs::push_sport_mask)\n- [.push_dport_mask()](PushFibRuleAttrs::push_dport_mask)\n- [.push_dscp_mask()](PushFibRuleAttrs::push_dscp_mask)\n"]
1976 pub fn op_delrule_do(self, header: &FibRuleHdr) -> OpDelruleDo<'buf> {
1977 let mut res = OpDelruleDo::new(self, header);
1978 res.request
1979 .do_writeback(res.protocol(), "op-delrule-do", OpDelruleDo::lookup);
1980 res
1981 }
1982 #[doc = "Dump all FIB rules\n\nReply attributes:\n- [.get_iifname()](IterableFibRuleAttrs::get_iifname)\n- [.get_goto()](IterableFibRuleAttrs::get_goto)\n- [.get_priority()](IterableFibRuleAttrs::get_priority)\n- [.get_fwmark()](IterableFibRuleAttrs::get_fwmark)\n- [.get_flow()](IterableFibRuleAttrs::get_flow)\n- [.get_tun_id()](IterableFibRuleAttrs::get_tun_id)\n- [.get_suppress_ifgroup()](IterableFibRuleAttrs::get_suppress_ifgroup)\n- [.get_suppress_prefixlen()](IterableFibRuleAttrs::get_suppress_prefixlen)\n- [.get_table()](IterableFibRuleAttrs::get_table)\n- [.get_fwmask()](IterableFibRuleAttrs::get_fwmask)\n- [.get_oifname()](IterableFibRuleAttrs::get_oifname)\n- [.get_l3mdev()](IterableFibRuleAttrs::get_l3mdev)\n- [.get_uid_range()](IterableFibRuleAttrs::get_uid_range)\n- [.get_protocol()](IterableFibRuleAttrs::get_protocol)\n- [.get_ip_proto()](IterableFibRuleAttrs::get_ip_proto)\n- [.get_sport_range()](IterableFibRuleAttrs::get_sport_range)\n- [.get_dport_range()](IterableFibRuleAttrs::get_dport_range)\n- [.get_dscp()](IterableFibRuleAttrs::get_dscp)\n- [.get_flowlabel()](IterableFibRuleAttrs::get_flowlabel)\n- [.get_flowlabel_mask()](IterableFibRuleAttrs::get_flowlabel_mask)\n- [.get_sport_mask()](IterableFibRuleAttrs::get_sport_mask)\n- [.get_dport_mask()](IterableFibRuleAttrs::get_dport_mask)\n- [.get_dscp_mask()](IterableFibRuleAttrs::get_dscp_mask)\n"]
1983 pub fn op_getrule_dump(self, header: &FibRuleHdr) -> OpGetruleDump<'buf> {
1984 let mut res = OpGetruleDump::new(self, header);
1985 res.request
1986 .do_writeback(res.protocol(), "op-getrule-dump", OpGetruleDump::lookup);
1987 res
1988 }
1989}
1990#[cfg(test)]
1991mod generated_tests {
1992 use super::*;
1993 #[test]
1994 fn tests() {
1995 let _ = IterableFibRuleAttrs::get_dport_mask;
1996 let _ = IterableFibRuleAttrs::get_dport_range;
1997 let _ = IterableFibRuleAttrs::get_dscp;
1998 let _ = IterableFibRuleAttrs::get_dscp_mask;
1999 let _ = IterableFibRuleAttrs::get_flow;
2000 let _ = IterableFibRuleAttrs::get_flowlabel;
2001 let _ = IterableFibRuleAttrs::get_flowlabel_mask;
2002 let _ = IterableFibRuleAttrs::get_fwmark;
2003 let _ = IterableFibRuleAttrs::get_fwmask;
2004 let _ = IterableFibRuleAttrs::get_goto;
2005 let _ = IterableFibRuleAttrs::get_iifname;
2006 let _ = IterableFibRuleAttrs::get_ip_proto;
2007 let _ = IterableFibRuleAttrs::get_l3mdev;
2008 let _ = IterableFibRuleAttrs::get_oifname;
2009 let _ = IterableFibRuleAttrs::get_priority;
2010 let _ = IterableFibRuleAttrs::get_protocol;
2011 let _ = IterableFibRuleAttrs::get_sport_mask;
2012 let _ = IterableFibRuleAttrs::get_sport_range;
2013 let _ = IterableFibRuleAttrs::get_suppress_ifgroup;
2014 let _ = IterableFibRuleAttrs::get_suppress_prefixlen;
2015 let _ = IterableFibRuleAttrs::get_table;
2016 let _ = IterableFibRuleAttrs::get_tun_id;
2017 let _ = IterableFibRuleAttrs::get_uid_range;
2018 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dport_mask;
2019 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dport_range;
2020 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dscp;
2021 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dscp_mask;
2022 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_flow;
2023 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_flowlabel;
2024 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_flowlabel_mask;
2025 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_fwmark;
2026 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_fwmask;
2027 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_goto;
2028 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_iifname;
2029 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_ip_proto;
2030 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_l3mdev;
2031 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_oifname;
2032 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_priority;
2033 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_protocol;
2034 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_sport_mask;
2035 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_sport_range;
2036 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_suppress_ifgroup;
2037 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_suppress_prefixlen;
2038 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_table;
2039 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_tun_id;
2040 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_uid_range;
2041 }
2042}