1#![doc = "FIB rule management over rtnetlink.\n"]
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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 Ok(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 mut pos;
890 let mut r#type;
891 loop {
892 pos = self.pos;
893 r#type = None;
894 if self.buf.len() == self.pos {
895 return None;
896 }
897 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
898 self.pos = self.buf.len();
899 break;
900 };
901 r#type = Some(header.r#type);
902 let res = match header.r#type {
903 1u16 => FibRuleAttrs::Dst({
904 let res = parse_ip(next);
905 let Some(val) = res else { break };
906 val
907 }),
908 2u16 => FibRuleAttrs::Src({
909 let res = parse_ip(next);
910 let Some(val) = res else { break };
911 val
912 }),
913 3u16 => FibRuleAttrs::Iifname({
914 let res = CStr::from_bytes_with_nul(next).ok();
915 let Some(val) = res else { break };
916 val
917 }),
918 4u16 => FibRuleAttrs::Goto({
919 let res = parse_u32(next);
920 let Some(val) = res else { break };
921 val
922 }),
923 5u16 => FibRuleAttrs::Unused2({
924 let res = Some(next);
925 let Some(val) = res else { break };
926 val
927 }),
928 6u16 => FibRuleAttrs::Priority({
929 let res = parse_u32(next);
930 let Some(val) = res else { break };
931 val
932 }),
933 7u16 => FibRuleAttrs::Unused3({
934 let res = Some(next);
935 let Some(val) = res else { break };
936 val
937 }),
938 8u16 => FibRuleAttrs::Unused4({
939 let res = Some(next);
940 let Some(val) = res else { break };
941 val
942 }),
943 9u16 => FibRuleAttrs::Unused5({
944 let res = Some(next);
945 let Some(val) = res else { break };
946 val
947 }),
948 10u16 => FibRuleAttrs::Fwmark({
949 let res = parse_u32(next);
950 let Some(val) = res else { break };
951 val
952 }),
953 11u16 => FibRuleAttrs::Flow({
954 let res = parse_u32(next);
955 let Some(val) = res else { break };
956 val
957 }),
958 12u16 => FibRuleAttrs::TunId({
959 let res = parse_u64(next);
960 let Some(val) = res else { break };
961 val
962 }),
963 13u16 => FibRuleAttrs::SuppressIfgroup({
964 let res = parse_u32(next);
965 let Some(val) = res else { break };
966 val
967 }),
968 14u16 => FibRuleAttrs::SuppressPrefixlen({
969 let res = parse_u32(next);
970 let Some(val) = res else { break };
971 val
972 }),
973 15u16 => FibRuleAttrs::Table({
974 let res = parse_u32(next);
975 let Some(val) = res else { break };
976 val
977 }),
978 16u16 => FibRuleAttrs::Fwmask({
979 let res = parse_u32(next);
980 let Some(val) = res else { break };
981 val
982 }),
983 17u16 => FibRuleAttrs::Oifname({
984 let res = CStr::from_bytes_with_nul(next).ok();
985 let Some(val) = res else { break };
986 val
987 }),
988 18u16 => FibRuleAttrs::Pad({
989 let res = Some(next);
990 let Some(val) = res else { break };
991 val
992 }),
993 19u16 => FibRuleAttrs::L3mdev({
994 let res = parse_u8(next);
995 let Some(val) = res else { break };
996 val
997 }),
998 20u16 => FibRuleAttrs::UidRange({
999 let res = Some(FibRuleUidRange::new_from_zeroed(next));
1000 let Some(val) = res else { break };
1001 val
1002 }),
1003 21u16 => FibRuleAttrs::Protocol({
1004 let res = parse_u8(next);
1005 let Some(val) = res else { break };
1006 val
1007 }),
1008 22u16 => FibRuleAttrs::IpProto({
1009 let res = parse_u8(next);
1010 let Some(val) = res else { break };
1011 val
1012 }),
1013 23u16 => FibRuleAttrs::SportRange({
1014 let res = Some(FibRulePortRange::new_from_zeroed(next));
1015 let Some(val) = res else { break };
1016 val
1017 }),
1018 24u16 => FibRuleAttrs::DportRange({
1019 let res = Some(FibRulePortRange::new_from_zeroed(next));
1020 let Some(val) = res else { break };
1021 val
1022 }),
1023 25u16 => FibRuleAttrs::Dscp({
1024 let res = parse_u8(next);
1025 let Some(val) = res else { break };
1026 val
1027 }),
1028 26u16 => FibRuleAttrs::Flowlabel({
1029 let res = parse_be_u32(next);
1030 let Some(val) = res else { break };
1031 val
1032 }),
1033 27u16 => FibRuleAttrs::FlowlabelMask({
1034 let res = parse_be_u32(next);
1035 let Some(val) = res else { break };
1036 val
1037 }),
1038 28u16 => FibRuleAttrs::SportMask({
1039 let res = parse_u16(next);
1040 let Some(val) = res else { break };
1041 val
1042 }),
1043 29u16 => FibRuleAttrs::DportMask({
1044 let res = parse_u16(next);
1045 let Some(val) = res else { break };
1046 val
1047 }),
1048 30u16 => FibRuleAttrs::DscpMask({
1049 let res = parse_u8(next);
1050 let Some(val) = res else { break };
1051 val
1052 }),
1053 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1054 n => continue,
1055 };
1056 return Some(Ok(res));
1057 }
1058 Some(Err(ErrorContext::new(
1059 "FibRuleAttrs",
1060 r#type.and_then(|t| FibRuleAttrs::attr_from_type(t)),
1061 self.orig_loc,
1062 self.buf.as_ptr().wrapping_add(pos) as usize,
1063 )))
1064 }
1065}
1066impl<'a> std::fmt::Debug for IterableFibRuleAttrs<'_> {
1067 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1068 let mut fmt = f.debug_struct("FibRuleAttrs");
1069 for attr in self.clone() {
1070 let attr = match attr {
1071 Ok(a) => a,
1072 Err(err) => {
1073 fmt.finish()?;
1074 f.write_str("Err(")?;
1075 err.fmt(f)?;
1076 return f.write_str(")");
1077 }
1078 };
1079 match attr {
1080 FibRuleAttrs::Dst(val) => fmt.field("Dst", &val),
1081 FibRuleAttrs::Src(val) => fmt.field("Src", &val),
1082 FibRuleAttrs::Iifname(val) => fmt.field("Iifname", &val),
1083 FibRuleAttrs::Goto(val) => fmt.field("Goto", &val),
1084 FibRuleAttrs::Unused2(val) => fmt.field("Unused2", &val),
1085 FibRuleAttrs::Priority(val) => fmt.field("Priority", &val),
1086 FibRuleAttrs::Unused3(val) => fmt.field("Unused3", &val),
1087 FibRuleAttrs::Unused4(val) => fmt.field("Unused4", &val),
1088 FibRuleAttrs::Unused5(val) => fmt.field("Unused5", &val),
1089 FibRuleAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
1090 FibRuleAttrs::Flow(val) => fmt.field("Flow", &val),
1091 FibRuleAttrs::TunId(val) => fmt.field("TunId", &val),
1092 FibRuleAttrs::SuppressIfgroup(val) => fmt.field("SuppressIfgroup", &val),
1093 FibRuleAttrs::SuppressPrefixlen(val) => fmt.field("SuppressPrefixlen", &val),
1094 FibRuleAttrs::Table(val) => fmt.field("Table", &val),
1095 FibRuleAttrs::Fwmask(val) => fmt.field("Fwmask", &val),
1096 FibRuleAttrs::Oifname(val) => fmt.field("Oifname", &val),
1097 FibRuleAttrs::Pad(val) => fmt.field("Pad", &val),
1098 FibRuleAttrs::L3mdev(val) => fmt.field("L3mdev", &val),
1099 FibRuleAttrs::UidRange(val) => fmt.field("UidRange", &val),
1100 FibRuleAttrs::Protocol(val) => fmt.field("Protocol", &val),
1101 FibRuleAttrs::IpProto(val) => fmt.field("IpProto", &val),
1102 FibRuleAttrs::SportRange(val) => fmt.field("SportRange", &val),
1103 FibRuleAttrs::DportRange(val) => fmt.field("DportRange", &val),
1104 FibRuleAttrs::Dscp(val) => fmt.field("Dscp", &val),
1105 FibRuleAttrs::Flowlabel(val) => fmt.field("Flowlabel", &val),
1106 FibRuleAttrs::FlowlabelMask(val) => fmt.field("FlowlabelMask", &val),
1107 FibRuleAttrs::SportMask(val) => fmt.field("SportMask", &val),
1108 FibRuleAttrs::DportMask(val) => fmt.field("DportMask", &val),
1109 FibRuleAttrs::DscpMask(val) => fmt.field("DscpMask", &val),
1110 };
1111 }
1112 fmt.finish()
1113 }
1114}
1115impl IterableFibRuleAttrs<'_> {
1116 pub fn lookup_attr(
1117 &self,
1118 offset: usize,
1119 missing_type: Option<u16>,
1120 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1121 let mut stack = Vec::new();
1122 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1123 if missing_type.is_some() && cur == offset {
1124 stack.push(("FibRuleAttrs", offset));
1125 return (
1126 stack,
1127 missing_type.and_then(|t| FibRuleAttrs::attr_from_type(t)),
1128 );
1129 }
1130 if cur > offset || cur + self.buf.len() < offset {
1131 return (stack, None);
1132 }
1133 let mut attrs = self.clone();
1134 let mut last_off = cur + attrs.pos;
1135 while let Some(attr) = attrs.next() {
1136 let Ok(attr) = attr else { break };
1137 match attr {
1138 FibRuleAttrs::Dst(val) => {
1139 if last_off == offset {
1140 stack.push(("Dst", last_off));
1141 break;
1142 }
1143 }
1144 FibRuleAttrs::Src(val) => {
1145 if last_off == offset {
1146 stack.push(("Src", last_off));
1147 break;
1148 }
1149 }
1150 FibRuleAttrs::Iifname(val) => {
1151 if last_off == offset {
1152 stack.push(("Iifname", last_off));
1153 break;
1154 }
1155 }
1156 FibRuleAttrs::Goto(val) => {
1157 if last_off == offset {
1158 stack.push(("Goto", last_off));
1159 break;
1160 }
1161 }
1162 FibRuleAttrs::Unused2(val) => {
1163 if last_off == offset {
1164 stack.push(("Unused2", last_off));
1165 break;
1166 }
1167 }
1168 FibRuleAttrs::Priority(val) => {
1169 if last_off == offset {
1170 stack.push(("Priority", last_off));
1171 break;
1172 }
1173 }
1174 FibRuleAttrs::Unused3(val) => {
1175 if last_off == offset {
1176 stack.push(("Unused3", last_off));
1177 break;
1178 }
1179 }
1180 FibRuleAttrs::Unused4(val) => {
1181 if last_off == offset {
1182 stack.push(("Unused4", last_off));
1183 break;
1184 }
1185 }
1186 FibRuleAttrs::Unused5(val) => {
1187 if last_off == offset {
1188 stack.push(("Unused5", last_off));
1189 break;
1190 }
1191 }
1192 FibRuleAttrs::Fwmark(val) => {
1193 if last_off == offset {
1194 stack.push(("Fwmark", last_off));
1195 break;
1196 }
1197 }
1198 FibRuleAttrs::Flow(val) => {
1199 if last_off == offset {
1200 stack.push(("Flow", last_off));
1201 break;
1202 }
1203 }
1204 FibRuleAttrs::TunId(val) => {
1205 if last_off == offset {
1206 stack.push(("TunId", last_off));
1207 break;
1208 }
1209 }
1210 FibRuleAttrs::SuppressIfgroup(val) => {
1211 if last_off == offset {
1212 stack.push(("SuppressIfgroup", last_off));
1213 break;
1214 }
1215 }
1216 FibRuleAttrs::SuppressPrefixlen(val) => {
1217 if last_off == offset {
1218 stack.push(("SuppressPrefixlen", last_off));
1219 break;
1220 }
1221 }
1222 FibRuleAttrs::Table(val) => {
1223 if last_off == offset {
1224 stack.push(("Table", last_off));
1225 break;
1226 }
1227 }
1228 FibRuleAttrs::Fwmask(val) => {
1229 if last_off == offset {
1230 stack.push(("Fwmask", last_off));
1231 break;
1232 }
1233 }
1234 FibRuleAttrs::Oifname(val) => {
1235 if last_off == offset {
1236 stack.push(("Oifname", last_off));
1237 break;
1238 }
1239 }
1240 FibRuleAttrs::Pad(val) => {
1241 if last_off == offset {
1242 stack.push(("Pad", last_off));
1243 break;
1244 }
1245 }
1246 FibRuleAttrs::L3mdev(val) => {
1247 if last_off == offset {
1248 stack.push(("L3mdev", last_off));
1249 break;
1250 }
1251 }
1252 FibRuleAttrs::UidRange(val) => {
1253 if last_off == offset {
1254 stack.push(("UidRange", last_off));
1255 break;
1256 }
1257 }
1258 FibRuleAttrs::Protocol(val) => {
1259 if last_off == offset {
1260 stack.push(("Protocol", last_off));
1261 break;
1262 }
1263 }
1264 FibRuleAttrs::IpProto(val) => {
1265 if last_off == offset {
1266 stack.push(("IpProto", last_off));
1267 break;
1268 }
1269 }
1270 FibRuleAttrs::SportRange(val) => {
1271 if last_off == offset {
1272 stack.push(("SportRange", last_off));
1273 break;
1274 }
1275 }
1276 FibRuleAttrs::DportRange(val) => {
1277 if last_off == offset {
1278 stack.push(("DportRange", last_off));
1279 break;
1280 }
1281 }
1282 FibRuleAttrs::Dscp(val) => {
1283 if last_off == offset {
1284 stack.push(("Dscp", last_off));
1285 break;
1286 }
1287 }
1288 FibRuleAttrs::Flowlabel(val) => {
1289 if last_off == offset {
1290 stack.push(("Flowlabel", last_off));
1291 break;
1292 }
1293 }
1294 FibRuleAttrs::FlowlabelMask(val) => {
1295 if last_off == offset {
1296 stack.push(("FlowlabelMask", last_off));
1297 break;
1298 }
1299 }
1300 FibRuleAttrs::SportMask(val) => {
1301 if last_off == offset {
1302 stack.push(("SportMask", last_off));
1303 break;
1304 }
1305 }
1306 FibRuleAttrs::DportMask(val) => {
1307 if last_off == offset {
1308 stack.push(("DportMask", last_off));
1309 break;
1310 }
1311 }
1312 FibRuleAttrs::DscpMask(val) => {
1313 if last_off == offset {
1314 stack.push(("DscpMask", last_off));
1315 break;
1316 }
1317 }
1318 _ => {}
1319 };
1320 last_off = cur + attrs.pos;
1321 }
1322 if !stack.is_empty() {
1323 stack.push(("FibRuleAttrs", cur));
1324 }
1325 (stack, None)
1326 }
1327}
1328pub struct PushFibRuleAttrs<Prev: Pusher> {
1329 pub(crate) prev: Option<Prev>,
1330 pub(crate) header_offset: Option<usize>,
1331}
1332impl<Prev: Pusher> Pusher for PushFibRuleAttrs<Prev> {
1333 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1334 self.prev.as_mut().unwrap().as_vec_mut()
1335 }
1336 fn as_vec(&self) -> &Vec<u8> {
1337 self.prev.as_ref().unwrap().as_vec()
1338 }
1339}
1340impl<Prev: Pusher> PushFibRuleAttrs<Prev> {
1341 pub fn new(prev: Prev) -> Self {
1342 Self {
1343 prev: Some(prev),
1344 header_offset: None,
1345 }
1346 }
1347 pub fn end_nested(mut self) -> Prev {
1348 let mut prev = self.prev.take().unwrap();
1349 if let Some(header_offset) = &self.header_offset {
1350 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1351 }
1352 prev
1353 }
1354 pub fn push_dst(mut self, value: std::net::IpAddr) -> Self {
1355 push_header(self.as_vec_mut(), 1u16, {
1356 match &value {
1357 IpAddr::V4(_) => 4,
1358 IpAddr::V6(_) => 16,
1359 }
1360 } as u16);
1361 encode_ip(self.as_vec_mut(), value);
1362 self
1363 }
1364 pub fn push_src(mut self, value: std::net::IpAddr) -> Self {
1365 push_header(self.as_vec_mut(), 2u16, {
1366 match &value {
1367 IpAddr::V4(_) => 4,
1368 IpAddr::V6(_) => 16,
1369 }
1370 } as u16);
1371 encode_ip(self.as_vec_mut(), value);
1372 self
1373 }
1374 pub fn push_iifname(mut self, value: &CStr) -> Self {
1375 push_header(
1376 self.as_vec_mut(),
1377 3u16,
1378 value.to_bytes_with_nul().len() as u16,
1379 );
1380 self.as_vec_mut().extend(value.to_bytes_with_nul());
1381 self
1382 }
1383 pub fn push_iifname_bytes(mut self, value: &[u8]) -> Self {
1384 push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
1385 self.as_vec_mut().extend(value);
1386 self.as_vec_mut().push(0);
1387 self
1388 }
1389 pub fn push_goto(mut self, value: u32) -> Self {
1390 push_header(self.as_vec_mut(), 4u16, 4 as u16);
1391 self.as_vec_mut().extend(value.to_ne_bytes());
1392 self
1393 }
1394 pub fn push_unused2(mut self, value: &[u8]) -> Self {
1395 push_header(self.as_vec_mut(), 5u16, value.len() as u16);
1396 self.as_vec_mut().extend(value);
1397 self
1398 }
1399 pub fn push_priority(mut self, value: u32) -> Self {
1400 push_header(self.as_vec_mut(), 6u16, 4 as u16);
1401 self.as_vec_mut().extend(value.to_ne_bytes());
1402 self
1403 }
1404 pub fn push_unused3(mut self, value: &[u8]) -> Self {
1405 push_header(self.as_vec_mut(), 7u16, value.len() as u16);
1406 self.as_vec_mut().extend(value);
1407 self
1408 }
1409 pub fn push_unused4(mut self, value: &[u8]) -> Self {
1410 push_header(self.as_vec_mut(), 8u16, value.len() as u16);
1411 self.as_vec_mut().extend(value);
1412 self
1413 }
1414 pub fn push_unused5(mut self, value: &[u8]) -> Self {
1415 push_header(self.as_vec_mut(), 9u16, value.len() as u16);
1416 self.as_vec_mut().extend(value);
1417 self
1418 }
1419 pub fn push_fwmark(mut self, value: u32) -> Self {
1420 push_header(self.as_vec_mut(), 10u16, 4 as u16);
1421 self.as_vec_mut().extend(value.to_ne_bytes());
1422 self
1423 }
1424 pub fn push_flow(mut self, value: u32) -> Self {
1425 push_header(self.as_vec_mut(), 11u16, 4 as u16);
1426 self.as_vec_mut().extend(value.to_ne_bytes());
1427 self
1428 }
1429 pub fn push_tun_id(mut self, value: u64) -> Self {
1430 push_header(self.as_vec_mut(), 12u16, 8 as u16);
1431 self.as_vec_mut().extend(value.to_ne_bytes());
1432 self
1433 }
1434 pub fn push_suppress_ifgroup(mut self, value: u32) -> Self {
1435 push_header(self.as_vec_mut(), 13u16, 4 as u16);
1436 self.as_vec_mut().extend(value.to_ne_bytes());
1437 self
1438 }
1439 pub fn push_suppress_prefixlen(mut self, value: u32) -> Self {
1440 push_header(self.as_vec_mut(), 14u16, 4 as u16);
1441 self.as_vec_mut().extend(value.to_ne_bytes());
1442 self
1443 }
1444 pub fn push_table(mut self, value: u32) -> Self {
1445 push_header(self.as_vec_mut(), 15u16, 4 as u16);
1446 self.as_vec_mut().extend(value.to_ne_bytes());
1447 self
1448 }
1449 pub fn push_fwmask(mut self, value: u32) -> Self {
1450 push_header(self.as_vec_mut(), 16u16, 4 as u16);
1451 self.as_vec_mut().extend(value.to_ne_bytes());
1452 self
1453 }
1454 pub fn push_oifname(mut self, value: &CStr) -> Self {
1455 push_header(
1456 self.as_vec_mut(),
1457 17u16,
1458 value.to_bytes_with_nul().len() as u16,
1459 );
1460 self.as_vec_mut().extend(value.to_bytes_with_nul());
1461 self
1462 }
1463 pub fn push_oifname_bytes(mut self, value: &[u8]) -> Self {
1464 push_header(self.as_vec_mut(), 17u16, (value.len() + 1) as u16);
1465 self.as_vec_mut().extend(value);
1466 self.as_vec_mut().push(0);
1467 self
1468 }
1469 pub fn push_pad(mut self, value: &[u8]) -> Self {
1470 push_header(self.as_vec_mut(), 18u16, value.len() as u16);
1471 self.as_vec_mut().extend(value);
1472 self
1473 }
1474 pub fn push_l3mdev(mut self, value: u8) -> Self {
1475 push_header(self.as_vec_mut(), 19u16, 1 as u16);
1476 self.as_vec_mut().extend(value.to_ne_bytes());
1477 self
1478 }
1479 pub fn push_uid_range(mut self, value: FibRuleUidRange) -> Self {
1480 push_header(self.as_vec_mut(), 20u16, value.as_slice().len() as u16);
1481 self.as_vec_mut().extend(value.as_slice());
1482 self
1483 }
1484 pub fn push_protocol(mut self, value: u8) -> Self {
1485 push_header(self.as_vec_mut(), 21u16, 1 as u16);
1486 self.as_vec_mut().extend(value.to_ne_bytes());
1487 self
1488 }
1489 pub fn push_ip_proto(mut self, value: u8) -> Self {
1490 push_header(self.as_vec_mut(), 22u16, 1 as u16);
1491 self.as_vec_mut().extend(value.to_ne_bytes());
1492 self
1493 }
1494 pub fn push_sport_range(mut self, value: FibRulePortRange) -> Self {
1495 push_header(self.as_vec_mut(), 23u16, value.as_slice().len() as u16);
1496 self.as_vec_mut().extend(value.as_slice());
1497 self
1498 }
1499 pub fn push_dport_range(mut self, value: FibRulePortRange) -> Self {
1500 push_header(self.as_vec_mut(), 24u16, value.as_slice().len() as u16);
1501 self.as_vec_mut().extend(value.as_slice());
1502 self
1503 }
1504 pub fn push_dscp(mut self, value: u8) -> Self {
1505 push_header(self.as_vec_mut(), 25u16, 1 as u16);
1506 self.as_vec_mut().extend(value.to_ne_bytes());
1507 self
1508 }
1509 pub fn push_flowlabel(mut self, value: u32) -> Self {
1510 push_header(self.as_vec_mut(), 26u16, 4 as u16);
1511 self.as_vec_mut().extend(value.to_be_bytes());
1512 self
1513 }
1514 pub fn push_flowlabel_mask(mut self, value: u32) -> Self {
1515 push_header(self.as_vec_mut(), 27u16, 4 as u16);
1516 self.as_vec_mut().extend(value.to_be_bytes());
1517 self
1518 }
1519 pub fn push_sport_mask(mut self, value: u16) -> Self {
1520 push_header(self.as_vec_mut(), 28u16, 2 as u16);
1521 self.as_vec_mut().extend(value.to_ne_bytes());
1522 self
1523 }
1524 pub fn push_dport_mask(mut self, value: u16) -> Self {
1525 push_header(self.as_vec_mut(), 29u16, 2 as u16);
1526 self.as_vec_mut().extend(value.to_ne_bytes());
1527 self
1528 }
1529 pub fn push_dscp_mask(mut self, value: u8) -> Self {
1530 push_header(self.as_vec_mut(), 30u16, 1 as u16);
1531 self.as_vec_mut().extend(value.to_ne_bytes());
1532 self
1533 }
1534}
1535impl<Prev: Pusher> Drop for PushFibRuleAttrs<Prev> {
1536 fn drop(&mut self) {
1537 if let Some(prev) = &mut self.prev {
1538 if let Some(header_offset) = &self.header_offset {
1539 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1540 }
1541 }
1542 }
1543}
1544#[doc = "Add new FIB rule\n\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\n"]
1545#[derive(Debug)]
1546pub struct OpNewruleDo<'r> {
1547 request: Request<'r>,
1548}
1549impl<'r> OpNewruleDo<'r> {
1550 pub fn new(mut request: Request<'r>, header: &FibRuleHdr) -> Self {
1551 Self::write_header(request.buf_mut(), header);
1552 Self { request: request }
1553 }
1554 pub fn encode_request<'buf>(
1555 buf: &'buf mut Vec<u8>,
1556 header: &FibRuleHdr,
1557 ) -> PushFibRuleAttrs<&'buf mut Vec<u8>> {
1558 Self::write_header(buf, header);
1559 PushFibRuleAttrs::new(buf)
1560 }
1561 pub fn encode(&mut self) -> PushFibRuleAttrs<&mut Vec<u8>> {
1562 PushFibRuleAttrs::new(self.request.buf_mut())
1563 }
1564 pub fn into_encoder(self) -> PushFibRuleAttrs<RequestBuf<'r>> {
1565 PushFibRuleAttrs::new(self.request.buf)
1566 }
1567 pub fn decode_request<'a>(buf: &'a [u8]) -> (FibRuleHdr, IterableFibRuleAttrs<'a>) {
1568 let (header, attrs) = buf.split_at(buf.len().min(FibRuleHdr::len()));
1569 (
1570 FibRuleHdr::new_from_slice(header).unwrap_or_default(),
1571 IterableFibRuleAttrs::with_loc(attrs, buf.as_ptr() as usize),
1572 )
1573 }
1574 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &FibRuleHdr) {
1575 prev.as_vec_mut().extend(header.as_slice());
1576 }
1577}
1578impl NetlinkRequest for OpNewruleDo<'_> {
1579 fn protocol(&self) -> Protocol {
1580 Protocol::Raw {
1581 protonum: 0u16,
1582 request_type: 32u16,
1583 }
1584 }
1585 fn flags(&self) -> u16 {
1586 self.request.flags
1587 }
1588 fn payload(&self) -> &[u8] {
1589 self.request.buf()
1590 }
1591 type ReplyType<'buf> = (FibRuleHdr, IterableFibRuleAttrs<'buf>);
1592 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1593 Self::decode_request(buf)
1594 }
1595 fn lookup(
1596 buf: &[u8],
1597 offset: usize,
1598 missing_type: Option<u16>,
1599 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1600 Self::decode_request(buf)
1601 .1
1602 .lookup_attr(offset, missing_type)
1603 }
1604}
1605#[doc = "Remove an existing FIB rule\n\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\n"]
1606#[derive(Debug)]
1607pub struct OpDelruleDo<'r> {
1608 request: Request<'r>,
1609}
1610impl<'r> OpDelruleDo<'r> {
1611 pub fn new(mut request: Request<'r>, header: &FibRuleHdr) -> Self {
1612 Self::write_header(request.buf_mut(), header);
1613 Self { request: request }
1614 }
1615 pub fn encode_request<'buf>(
1616 buf: &'buf mut Vec<u8>,
1617 header: &FibRuleHdr,
1618 ) -> PushFibRuleAttrs<&'buf mut Vec<u8>> {
1619 Self::write_header(buf, header);
1620 PushFibRuleAttrs::new(buf)
1621 }
1622 pub fn encode(&mut self) -> PushFibRuleAttrs<&mut Vec<u8>> {
1623 PushFibRuleAttrs::new(self.request.buf_mut())
1624 }
1625 pub fn into_encoder(self) -> PushFibRuleAttrs<RequestBuf<'r>> {
1626 PushFibRuleAttrs::new(self.request.buf)
1627 }
1628 pub fn decode_request<'a>(buf: &'a [u8]) -> (FibRuleHdr, IterableFibRuleAttrs<'a>) {
1629 let (header, attrs) = buf.split_at(buf.len().min(FibRuleHdr::len()));
1630 (
1631 FibRuleHdr::new_from_slice(header).unwrap_or_default(),
1632 IterableFibRuleAttrs::with_loc(attrs, buf.as_ptr() as usize),
1633 )
1634 }
1635 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &FibRuleHdr) {
1636 prev.as_vec_mut().extend(header.as_slice());
1637 }
1638}
1639impl NetlinkRequest for OpDelruleDo<'_> {
1640 fn protocol(&self) -> Protocol {
1641 Protocol::Raw {
1642 protonum: 0u16,
1643 request_type: 33u16,
1644 }
1645 }
1646 fn flags(&self) -> u16 {
1647 self.request.flags
1648 }
1649 fn payload(&self) -> &[u8] {
1650 self.request.buf()
1651 }
1652 type ReplyType<'buf> = (FibRuleHdr, IterableFibRuleAttrs<'buf>);
1653 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1654 Self::decode_request(buf)
1655 }
1656 fn lookup(
1657 buf: &[u8],
1658 offset: usize,
1659 missing_type: Option<u16>,
1660 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1661 Self::decode_request(buf)
1662 .1
1663 .lookup_attr(offset, missing_type)
1664 }
1665}
1666#[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\n"]
1667#[derive(Debug)]
1668pub struct OpGetruleDump<'r> {
1669 request: Request<'r>,
1670}
1671impl<'r> OpGetruleDump<'r> {
1672 pub fn new(mut request: Request<'r>, header: &FibRuleHdr) -> Self {
1673 Self::write_header(request.buf_mut(), header);
1674 Self {
1675 request: request.set_dump(),
1676 }
1677 }
1678 pub fn encode_request<'buf>(
1679 buf: &'buf mut Vec<u8>,
1680 header: &FibRuleHdr,
1681 ) -> PushFibRuleAttrs<&'buf mut Vec<u8>> {
1682 Self::write_header(buf, header);
1683 PushFibRuleAttrs::new(buf)
1684 }
1685 pub fn encode(&mut self) -> PushFibRuleAttrs<&mut Vec<u8>> {
1686 PushFibRuleAttrs::new(self.request.buf_mut())
1687 }
1688 pub fn into_encoder(self) -> PushFibRuleAttrs<RequestBuf<'r>> {
1689 PushFibRuleAttrs::new(self.request.buf)
1690 }
1691 pub fn decode_request<'a>(buf: &'a [u8]) -> (FibRuleHdr, IterableFibRuleAttrs<'a>) {
1692 let (header, attrs) = buf.split_at(buf.len().min(FibRuleHdr::len()));
1693 (
1694 FibRuleHdr::new_from_slice(header).unwrap_or_default(),
1695 IterableFibRuleAttrs::with_loc(attrs, buf.as_ptr() as usize),
1696 )
1697 }
1698 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &FibRuleHdr) {
1699 prev.as_vec_mut().extend(header.as_slice());
1700 }
1701}
1702impl NetlinkRequest for OpGetruleDump<'_> {
1703 fn protocol(&self) -> Protocol {
1704 Protocol::Raw {
1705 protonum: 0u16,
1706 request_type: 34u16,
1707 }
1708 }
1709 fn flags(&self) -> u16 {
1710 self.request.flags
1711 }
1712 fn payload(&self) -> &[u8] {
1713 self.request.buf()
1714 }
1715 type ReplyType<'buf> = (FibRuleHdr, IterableFibRuleAttrs<'buf>);
1716 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1717 Self::decode_request(buf)
1718 }
1719 fn lookup(
1720 buf: &[u8],
1721 offset: usize,
1722 missing_type: Option<u16>,
1723 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1724 Self::decode_request(buf)
1725 .1
1726 .lookup_attr(offset, missing_type)
1727 }
1728}
1729#[derive(Debug)]
1730pub struct ChainedFinal<'a> {
1731 inner: Chained<'a>,
1732}
1733#[derive(Debug)]
1734pub struct Chained<'a> {
1735 buf: RequestBuf<'a>,
1736 first_seq: u32,
1737 lookups: Vec<(&'static str, LookupFn)>,
1738 last_header_offset: usize,
1739 last_kind: Option<RequestInfo>,
1740}
1741impl<'a> ChainedFinal<'a> {
1742 pub fn into_chained(self) -> Chained<'a> {
1743 self.inner
1744 }
1745 pub fn buf(&self) -> &Vec<u8> {
1746 self.inner.buf()
1747 }
1748 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1749 self.inner.buf_mut()
1750 }
1751 fn get_index(&self, seq: u32) -> Option<u32> {
1752 let min = self.inner.first_seq;
1753 let max = min.wrapping_add(self.inner.lookups.len() as u32);
1754 return if min <= max {
1755 (min..max).contains(&seq).then(|| seq - min)
1756 } else if min <= seq {
1757 Some(seq - min)
1758 } else if seq < max {
1759 Some(u32::MAX - min + seq)
1760 } else {
1761 None
1762 };
1763 }
1764}
1765impl crate::traits::NetlinkChained for ChainedFinal<'_> {
1766 fn protonum(&self) -> u16 {
1767 PROTONUM
1768 }
1769 fn payload(&self) -> &[u8] {
1770 self.buf()
1771 }
1772 fn chain_len(&self) -> usize {
1773 self.inner.lookups.len()
1774 }
1775 fn get_index(&self, seq: u32) -> Option<usize> {
1776 self.get_index(seq).map(|n| n as usize)
1777 }
1778 fn name(&self, index: usize) -> &'static str {
1779 self.inner.lookups[index].0
1780 }
1781 fn lookup(&self, index: usize) -> LookupFn {
1782 self.inner.lookups[index].1
1783 }
1784}
1785impl Chained<'static> {
1786 pub fn new(first_seq: u32) -> Self {
1787 Self::new_from_buf(Vec::new(), first_seq)
1788 }
1789 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
1790 Self {
1791 buf: RequestBuf::Own(buf),
1792 first_seq,
1793 lookups: Vec::new(),
1794 last_header_offset: 0,
1795 last_kind: None,
1796 }
1797 }
1798 pub fn into_buf(self) -> Vec<u8> {
1799 match self.buf {
1800 RequestBuf::Own(buf) => buf,
1801 _ => unreachable!(),
1802 }
1803 }
1804}
1805impl<'a> Chained<'a> {
1806 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
1807 Self {
1808 buf: RequestBuf::Ref(buf),
1809 first_seq,
1810 lookups: Vec::new(),
1811 last_header_offset: 0,
1812 last_kind: None,
1813 }
1814 }
1815 pub fn finalize(mut self) -> ChainedFinal<'a> {
1816 self.update_header();
1817 ChainedFinal { inner: self }
1818 }
1819 pub fn request(&mut self) -> Request<'_> {
1820 self.update_header();
1821 self.last_header_offset = self.buf().len();
1822 self.buf_mut().extend_from_slice(Nlmsghdr::new().as_slice());
1823 let mut request = Request::new_extend(self.buf.buf_mut());
1824 self.last_kind = None;
1825 request.writeback = Some(&mut self.last_kind);
1826 request
1827 }
1828 pub fn buf(&self) -> &Vec<u8> {
1829 self.buf.buf()
1830 }
1831 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1832 self.buf.buf_mut()
1833 }
1834 fn update_header(&mut self) {
1835 let Some(RequestInfo {
1836 protocol,
1837 flags,
1838 name,
1839 lookup,
1840 }) = self.last_kind
1841 else {
1842 if !self.buf().is_empty() {
1843 assert_eq!(self.last_header_offset + Nlmsghdr::len(), self.buf().len());
1844 self.buf.buf_mut().truncate(self.last_header_offset);
1845 }
1846 return;
1847 };
1848 let header_offset = self.last_header_offset;
1849 let request_type = match protocol {
1850 Protocol::Raw { request_type, .. } => request_type,
1851 Protocol::Generic(_) => unreachable!(),
1852 };
1853 let index = self.lookups.len();
1854 let seq = self.first_seq.wrapping_add(index as u32);
1855 self.lookups.push((name, lookup));
1856 let buf = self.buf_mut();
1857 align(buf);
1858 let header = Nlmsghdr {
1859 len: (buf.len() - header_offset) as u32,
1860 r#type: request_type,
1861 flags: flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16,
1862 seq,
1863 pid: 0,
1864 };
1865 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
1866 }
1867}
1868use crate::traits::LookupFn;
1869use crate::utils::RequestBuf;
1870#[derive(Debug)]
1871pub struct Request<'buf> {
1872 buf: RequestBuf<'buf>,
1873 flags: u16,
1874 writeback: Option<&'buf mut Option<RequestInfo>>,
1875}
1876#[allow(unused)]
1877#[derive(Debug, Clone)]
1878pub struct RequestInfo {
1879 protocol: Protocol,
1880 flags: u16,
1881 name: &'static str,
1882 lookup: LookupFn,
1883}
1884impl Request<'static> {
1885 pub fn new() -> Self {
1886 Self::new_from_buf(Vec::new())
1887 }
1888 pub fn new_from_buf(buf: Vec<u8>) -> Self {
1889 Self {
1890 flags: 0,
1891 buf: RequestBuf::Own(buf),
1892 writeback: None,
1893 }
1894 }
1895 pub fn into_buf(self) -> Vec<u8> {
1896 match self.buf {
1897 RequestBuf::Own(buf) => buf,
1898 _ => unreachable!(),
1899 }
1900 }
1901}
1902impl<'buf> Request<'buf> {
1903 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
1904 buf.clear();
1905 Self::new_extend(buf)
1906 }
1907 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
1908 Self {
1909 flags: 0,
1910 buf: RequestBuf::Ref(buf),
1911 writeback: None,
1912 }
1913 }
1914 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
1915 let Some(writeback) = &mut self.writeback else {
1916 return;
1917 };
1918 **writeback = Some(RequestInfo {
1919 protocol,
1920 flags: self.flags,
1921 name,
1922 lookup,
1923 })
1924 }
1925 pub fn buf(&self) -> &Vec<u8> {
1926 self.buf.buf()
1927 }
1928 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
1929 self.buf.buf_mut()
1930 }
1931 #[doc = "Set `NLM_F_CREATE` flag"]
1932 pub fn set_create(mut self) -> Self {
1933 self.flags |= consts::NLM_F_CREATE as u16;
1934 self
1935 }
1936 #[doc = "Set `NLM_F_EXCL` flag"]
1937 pub fn set_excl(mut self) -> Self {
1938 self.flags |= consts::NLM_F_EXCL as u16;
1939 self
1940 }
1941 #[doc = "Set `NLM_F_REPLACE` flag"]
1942 pub fn set_replace(mut self) -> Self {
1943 self.flags |= consts::NLM_F_REPLACE as u16;
1944 self
1945 }
1946 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
1947 pub fn set_change(self) -> Self {
1948 self.set_create().set_replace()
1949 }
1950 #[doc = "Set `NLM_F_APPEND` flag"]
1951 pub fn set_append(mut self) -> Self {
1952 self.flags |= consts::NLM_F_APPEND as u16;
1953 self
1954 }
1955 #[doc = "Set `self.flags |= flags`"]
1956 pub fn set_flags(mut self, flags: u16) -> Self {
1957 self.flags |= flags;
1958 self
1959 }
1960 #[doc = "Set `self.flags ^= self.flags & flags`"]
1961 pub fn unset_flags(mut self, flags: u16) -> Self {
1962 self.flags ^= self.flags & flags;
1963 self
1964 }
1965 #[doc = "Set `NLM_F_DUMP` flag"]
1966 fn set_dump(mut self) -> Self {
1967 self.flags |= consts::NLM_F_DUMP as u16;
1968 self
1969 }
1970 #[doc = "Add new FIB rule\n\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\n"]
1971 pub fn op_newrule_do(self, header: &FibRuleHdr) -> OpNewruleDo<'buf> {
1972 let mut res = OpNewruleDo::new(self, header);
1973 res.request
1974 .do_writeback(res.protocol(), "op-newrule-do", OpNewruleDo::lookup);
1975 res
1976 }
1977 #[doc = "Remove an existing FIB rule\n\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\n"]
1978 pub fn op_delrule_do(self, header: &FibRuleHdr) -> OpDelruleDo<'buf> {
1979 let mut res = OpDelruleDo::new(self, header);
1980 res.request
1981 .do_writeback(res.protocol(), "op-delrule-do", OpDelruleDo::lookup);
1982 res
1983 }
1984 #[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\n"]
1985 pub fn op_getrule_dump(self, header: &FibRuleHdr) -> OpGetruleDump<'buf> {
1986 let mut res = OpGetruleDump::new(self, header);
1987 res.request
1988 .do_writeback(res.protocol(), "op-getrule-dump", OpGetruleDump::lookup);
1989 res
1990 }
1991}
1992#[cfg(test)]
1993mod generated_tests {
1994 use super::*;
1995 #[test]
1996 fn tests() {
1997 let _ = IterableFibRuleAttrs::get_dport_mask;
1998 let _ = IterableFibRuleAttrs::get_dport_range;
1999 let _ = IterableFibRuleAttrs::get_dscp;
2000 let _ = IterableFibRuleAttrs::get_dscp_mask;
2001 let _ = IterableFibRuleAttrs::get_flow;
2002 let _ = IterableFibRuleAttrs::get_flowlabel;
2003 let _ = IterableFibRuleAttrs::get_flowlabel_mask;
2004 let _ = IterableFibRuleAttrs::get_fwmark;
2005 let _ = IterableFibRuleAttrs::get_fwmask;
2006 let _ = IterableFibRuleAttrs::get_goto;
2007 let _ = IterableFibRuleAttrs::get_iifname;
2008 let _ = IterableFibRuleAttrs::get_ip_proto;
2009 let _ = IterableFibRuleAttrs::get_l3mdev;
2010 let _ = IterableFibRuleAttrs::get_oifname;
2011 let _ = IterableFibRuleAttrs::get_priority;
2012 let _ = IterableFibRuleAttrs::get_protocol;
2013 let _ = IterableFibRuleAttrs::get_sport_mask;
2014 let _ = IterableFibRuleAttrs::get_sport_range;
2015 let _ = IterableFibRuleAttrs::get_suppress_ifgroup;
2016 let _ = IterableFibRuleAttrs::get_suppress_prefixlen;
2017 let _ = IterableFibRuleAttrs::get_table;
2018 let _ = IterableFibRuleAttrs::get_tun_id;
2019 let _ = IterableFibRuleAttrs::get_uid_range;
2020 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dport_mask;
2021 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dport_range;
2022 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dscp;
2023 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_dscp_mask;
2024 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_flow;
2025 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_flowlabel;
2026 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_flowlabel_mask;
2027 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_fwmark;
2028 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_fwmask;
2029 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_goto;
2030 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_iifname;
2031 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_ip_proto;
2032 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_l3mdev;
2033 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_oifname;
2034 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_priority;
2035 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_protocol;
2036 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_sport_mask;
2037 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_sport_range;
2038 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_suppress_ifgroup;
2039 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_suppress_prefixlen;
2040 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_table;
2041 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_tun_id;
2042 let _ = PushFibRuleAttrs::<&mut Vec<u8>>::push_uid_range;
2043 }
2044}