1#![doc = "IP neighbour management over rtnetlink."]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{PushBuiltinBitfield32, PushBuiltinNfgenmsg, PushDummy, PushNlmsghdr};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &CStr = c"rt-neigh";
17pub const PROTONUM: u16 = 0u16;
18#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
19#[derive(Debug, Clone, Copy)]
20pub enum NudState {
21 Incomplete = 1 << 0,
22 Reachable = 1 << 1,
23 Stale = 1 << 2,
24 Delay = 1 << 3,
25 Probe = 1 << 4,
26 Failed = 1 << 5,
27 Noarp = 1 << 6,
28 Permanent = 1 << 7,
29}
30impl NudState {
31 pub fn from_value(value: u64) -> Option<Self> {
32 Some(match value {
33 n if n == 1 << 0 => Self::Incomplete,
34 n if n == 1 << 1 => Self::Reachable,
35 n if n == 1 << 2 => Self::Stale,
36 n if n == 1 << 3 => Self::Delay,
37 n if n == 1 << 4 => Self::Probe,
38 n if n == 1 << 5 => Self::Failed,
39 n if n == 1 << 6 => Self::Noarp,
40 n if n == 1 << 7 => Self::Permanent,
41 _ => return None,
42 })
43 }
44}
45#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
46#[derive(Debug, Clone, Copy)]
47pub enum NtfFlags {
48 Use = 1 << 0,
49 _Self = 1 << 1,
50 Master = 1 << 2,
51 Proxy = 1 << 3,
52 ExtLearned = 1 << 4,
53 Offloaded = 1 << 5,
54 Sticky = 1 << 6,
55 Router = 1 << 7,
56}
57impl NtfFlags {
58 pub fn from_value(value: u64) -> Option<Self> {
59 Some(match value {
60 n if n == 1 << 0 => Self::Use,
61 n if n == 1 << 1 => Self::_Self,
62 n if n == 1 << 2 => Self::Master,
63 n if n == 1 << 3 => Self::Proxy,
64 n if n == 1 << 4 => Self::ExtLearned,
65 n if n == 1 << 5 => Self::Offloaded,
66 n if n == 1 << 6 => Self::Sticky,
67 n if n == 1 << 7 => Self::Router,
68 _ => return None,
69 })
70 }
71}
72#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
73#[derive(Debug, Clone, Copy)]
74pub enum NtfExtFlags {
75 Managed = 1 << 0,
76 Locked = 1 << 1,
77 ExtValidated = 1 << 2,
78}
79impl NtfExtFlags {
80 pub fn from_value(value: u64) -> Option<Self> {
81 Some(match value {
82 n if n == 1 << 0 => Self::Managed,
83 n if n == 1 << 1 => Self::Locked,
84 n if n == 1 << 2 => Self::ExtValidated,
85 _ => return None,
86 })
87 }
88}
89#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
90#[derive(Debug, Clone, Copy)]
91pub enum RtmType {
92 Unspec = 0,
93 Unicast = 1,
94 Local = 2,
95 Broadcast = 3,
96 Anycast = 4,
97 Multicast = 5,
98 Blackhole = 6,
99 Unreachable = 7,
100 Prohibit = 8,
101 Throw = 9,
102 Nat = 10,
103 Xresolve = 11,
104}
105impl RtmType {
106 pub fn from_value(value: u64) -> Option<Self> {
107 Some(match value {
108 0 => Self::Unspec,
109 1 => Self::Unicast,
110 2 => Self::Local,
111 3 => Self::Broadcast,
112 4 => Self::Anycast,
113 5 => Self::Multicast,
114 6 => Self::Blackhole,
115 7 => Self::Unreachable,
116 8 => Self::Prohibit,
117 9 => Self::Throw,
118 10 => Self::Nat,
119 11 => Self::Xresolve,
120 _ => return None,
121 })
122 }
123}
124#[derive(Clone)]
125pub enum NeighbourAttrs<'a> {
126 Unspec(&'a [u8]),
127 Dst(&'a [u8]),
128 Lladdr(&'a [u8]),
129 Cacheinfo(PushNdaCacheinfo),
130 Probes(u32),
131 Vlan(u16),
132 Port(u16),
133 Vni(u32),
134 Ifindex(u32),
135 Master(u32),
136 LinkNetnsid(i32),
137 SrcVni(u32),
138 Protocol(u8),
139 NhId(u32),
140 FdbExtAttrs(&'a [u8]),
141 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
142 FlagsExt(u32),
143 NdmStateMask(u16),
144 NdmFlagsMask(u8),
145}
146impl<'a> IterableNeighbourAttrs<'a> {
147 pub fn get_unspec(&self) -> Result<&'a [u8], ErrorContext> {
148 let mut iter = self.clone();
149 iter.pos = 0;
150 for attr in iter {
151 if let NeighbourAttrs::Unspec(val) = attr? {
152 return Ok(val);
153 }
154 }
155 Err(ErrorContext::new_missing(
156 "NeighbourAttrs",
157 "Unspec",
158 self.orig_loc,
159 self.buf.as_ptr() as usize,
160 ))
161 }
162 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
163 let mut iter = self.clone();
164 iter.pos = 0;
165 for attr in iter {
166 if let NeighbourAttrs::Dst(val) = attr? {
167 return Ok(val);
168 }
169 }
170 Err(ErrorContext::new_missing(
171 "NeighbourAttrs",
172 "Dst",
173 self.orig_loc,
174 self.buf.as_ptr() as usize,
175 ))
176 }
177 pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
178 let mut iter = self.clone();
179 iter.pos = 0;
180 for attr in iter {
181 if let NeighbourAttrs::Lladdr(val) = attr? {
182 return Ok(val);
183 }
184 }
185 Err(ErrorContext::new_missing(
186 "NeighbourAttrs",
187 "Lladdr",
188 self.orig_loc,
189 self.buf.as_ptr() as usize,
190 ))
191 }
192 pub fn get_cacheinfo(&self) -> Result<PushNdaCacheinfo, ErrorContext> {
193 let mut iter = self.clone();
194 iter.pos = 0;
195 for attr in iter {
196 if let NeighbourAttrs::Cacheinfo(val) = attr? {
197 return Ok(val);
198 }
199 }
200 Err(ErrorContext::new_missing(
201 "NeighbourAttrs",
202 "Cacheinfo",
203 self.orig_loc,
204 self.buf.as_ptr() as usize,
205 ))
206 }
207 pub fn get_probes(&self) -> Result<u32, ErrorContext> {
208 let mut iter = self.clone();
209 iter.pos = 0;
210 for attr in iter {
211 if let NeighbourAttrs::Probes(val) = attr? {
212 return Ok(val);
213 }
214 }
215 Err(ErrorContext::new_missing(
216 "NeighbourAttrs",
217 "Probes",
218 self.orig_loc,
219 self.buf.as_ptr() as usize,
220 ))
221 }
222 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
223 let mut iter = self.clone();
224 iter.pos = 0;
225 for attr in iter {
226 if let NeighbourAttrs::Vlan(val) = attr? {
227 return Ok(val);
228 }
229 }
230 Err(ErrorContext::new_missing(
231 "NeighbourAttrs",
232 "Vlan",
233 self.orig_loc,
234 self.buf.as_ptr() as usize,
235 ))
236 }
237 pub fn get_port(&self) -> Result<u16, ErrorContext> {
238 let mut iter = self.clone();
239 iter.pos = 0;
240 for attr in iter {
241 if let NeighbourAttrs::Port(val) = attr? {
242 return Ok(val);
243 }
244 }
245 Err(ErrorContext::new_missing(
246 "NeighbourAttrs",
247 "Port",
248 self.orig_loc,
249 self.buf.as_ptr() as usize,
250 ))
251 }
252 pub fn get_vni(&self) -> Result<u32, ErrorContext> {
253 let mut iter = self.clone();
254 iter.pos = 0;
255 for attr in iter {
256 if let NeighbourAttrs::Vni(val) = attr? {
257 return Ok(val);
258 }
259 }
260 Err(ErrorContext::new_missing(
261 "NeighbourAttrs",
262 "Vni",
263 self.orig_loc,
264 self.buf.as_ptr() as usize,
265 ))
266 }
267 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
268 let mut iter = self.clone();
269 iter.pos = 0;
270 for attr in iter {
271 if let NeighbourAttrs::Ifindex(val) = attr? {
272 return Ok(val);
273 }
274 }
275 Err(ErrorContext::new_missing(
276 "NeighbourAttrs",
277 "Ifindex",
278 self.orig_loc,
279 self.buf.as_ptr() as usize,
280 ))
281 }
282 pub fn get_master(&self) -> Result<u32, ErrorContext> {
283 let mut iter = self.clone();
284 iter.pos = 0;
285 for attr in iter {
286 if let NeighbourAttrs::Master(val) = attr? {
287 return Ok(val);
288 }
289 }
290 Err(ErrorContext::new_missing(
291 "NeighbourAttrs",
292 "Master",
293 self.orig_loc,
294 self.buf.as_ptr() as usize,
295 ))
296 }
297 pub fn get_link_netnsid(&self) -> Result<i32, ErrorContext> {
298 let mut iter = self.clone();
299 iter.pos = 0;
300 for attr in iter {
301 if let NeighbourAttrs::LinkNetnsid(val) = attr? {
302 return Ok(val);
303 }
304 }
305 Err(ErrorContext::new_missing(
306 "NeighbourAttrs",
307 "LinkNetnsid",
308 self.orig_loc,
309 self.buf.as_ptr() as usize,
310 ))
311 }
312 pub fn get_src_vni(&self) -> Result<u32, ErrorContext> {
313 let mut iter = self.clone();
314 iter.pos = 0;
315 for attr in iter {
316 if let NeighbourAttrs::SrcVni(val) = attr? {
317 return Ok(val);
318 }
319 }
320 Err(ErrorContext::new_missing(
321 "NeighbourAttrs",
322 "SrcVni",
323 self.orig_loc,
324 self.buf.as_ptr() as usize,
325 ))
326 }
327 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
328 let mut iter = self.clone();
329 iter.pos = 0;
330 for attr in iter {
331 if let NeighbourAttrs::Protocol(val) = attr? {
332 return Ok(val);
333 }
334 }
335 Err(ErrorContext::new_missing(
336 "NeighbourAttrs",
337 "Protocol",
338 self.orig_loc,
339 self.buf.as_ptr() as usize,
340 ))
341 }
342 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
343 let mut iter = self.clone();
344 iter.pos = 0;
345 for attr in iter {
346 if let NeighbourAttrs::NhId(val) = attr? {
347 return Ok(val);
348 }
349 }
350 Err(ErrorContext::new_missing(
351 "NeighbourAttrs",
352 "NhId",
353 self.orig_loc,
354 self.buf.as_ptr() as usize,
355 ))
356 }
357 pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
358 let mut iter = self.clone();
359 iter.pos = 0;
360 for attr in iter {
361 if let NeighbourAttrs::FdbExtAttrs(val) = attr? {
362 return Ok(val);
363 }
364 }
365 Err(ErrorContext::new_missing(
366 "NeighbourAttrs",
367 "FdbExtAttrs",
368 self.orig_loc,
369 self.buf.as_ptr() as usize,
370 ))
371 }
372 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
373 pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
374 let mut iter = self.clone();
375 iter.pos = 0;
376 for attr in iter {
377 if let NeighbourAttrs::FlagsExt(val) = attr? {
378 return Ok(val);
379 }
380 }
381 Err(ErrorContext::new_missing(
382 "NeighbourAttrs",
383 "FlagsExt",
384 self.orig_loc,
385 self.buf.as_ptr() as usize,
386 ))
387 }
388 pub fn get_ndm_state_mask(&self) -> Result<u16, ErrorContext> {
389 let mut iter = self.clone();
390 iter.pos = 0;
391 for attr in iter {
392 if let NeighbourAttrs::NdmStateMask(val) = attr? {
393 return Ok(val);
394 }
395 }
396 Err(ErrorContext::new_missing(
397 "NeighbourAttrs",
398 "NdmStateMask",
399 self.orig_loc,
400 self.buf.as_ptr() as usize,
401 ))
402 }
403 pub fn get_ndm_flags_mask(&self) -> Result<u8, ErrorContext> {
404 let mut iter = self.clone();
405 iter.pos = 0;
406 for attr in iter {
407 if let NeighbourAttrs::NdmFlagsMask(val) = attr? {
408 return Ok(val);
409 }
410 }
411 Err(ErrorContext::new_missing(
412 "NeighbourAttrs",
413 "NdmFlagsMask",
414 self.orig_loc,
415 self.buf.as_ptr() as usize,
416 ))
417 }
418}
419impl<'a> NeighbourAttrs<'a> {
420 pub fn new(buf: &'a [u8]) -> IterableNeighbourAttrs<'a> {
421 IterableNeighbourAttrs::with_loc(buf, buf.as_ptr() as usize)
422 }
423 fn attr_from_type(r#type: u16) -> Option<&'static str> {
424 let res = match r#type {
425 0u16 => "Unspec",
426 1u16 => "Dst",
427 2u16 => "Lladdr",
428 3u16 => "Cacheinfo",
429 4u16 => "Probes",
430 5u16 => "Vlan",
431 6u16 => "Port",
432 7u16 => "Vni",
433 8u16 => "Ifindex",
434 9u16 => "Master",
435 10u16 => "LinkNetnsid",
436 11u16 => "SrcVni",
437 12u16 => "Protocol",
438 13u16 => "NhId",
439 14u16 => "FdbExtAttrs",
440 15u16 => "FlagsExt",
441 16u16 => "NdmStateMask",
442 17u16 => "NdmFlagsMask",
443 _ => return None,
444 };
445 Some(res)
446 }
447}
448#[derive(Clone, Copy, Default)]
449pub struct IterableNeighbourAttrs<'a> {
450 buf: &'a [u8],
451 pos: usize,
452 orig_loc: usize,
453}
454impl<'a> IterableNeighbourAttrs<'a> {
455 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
456 Self {
457 buf,
458 pos: 0,
459 orig_loc,
460 }
461 }
462 pub fn get_buf(&self) -> &'a [u8] {
463 self.buf
464 }
465}
466impl<'a> Iterator for IterableNeighbourAttrs<'a> {
467 type Item = Result<NeighbourAttrs<'a>, ErrorContext>;
468 fn next(&mut self) -> Option<Self::Item> {
469 if self.buf.len() == self.pos {
470 return None;
471 }
472 let pos = self.pos;
473 let mut r#type = None;
474 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
475 r#type = Some(header.r#type);
476 let res = match header.r#type {
477 0u16 => NeighbourAttrs::Unspec({
478 let res = Some(next);
479 let Some(val) = res else { break };
480 val
481 }),
482 1u16 => NeighbourAttrs::Dst({
483 let res = Some(next);
484 let Some(val) = res else { break };
485 val
486 }),
487 2u16 => NeighbourAttrs::Lladdr({
488 let res = Some(next);
489 let Some(val) = res else { break };
490 val
491 }),
492 3u16 => NeighbourAttrs::Cacheinfo({
493 let res = PushNdaCacheinfo::new_from_slice(next);
494 let Some(val) = res else { break };
495 val
496 }),
497 4u16 => NeighbourAttrs::Probes({
498 let res = parse_u32(next);
499 let Some(val) = res else { break };
500 val
501 }),
502 5u16 => NeighbourAttrs::Vlan({
503 let res = parse_u16(next);
504 let Some(val) = res else { break };
505 val
506 }),
507 6u16 => NeighbourAttrs::Port({
508 let res = parse_u16(next);
509 let Some(val) = res else { break };
510 val
511 }),
512 7u16 => NeighbourAttrs::Vni({
513 let res = parse_u32(next);
514 let Some(val) = res else { break };
515 val
516 }),
517 8u16 => NeighbourAttrs::Ifindex({
518 let res = parse_u32(next);
519 let Some(val) = res else { break };
520 val
521 }),
522 9u16 => NeighbourAttrs::Master({
523 let res = parse_u32(next);
524 let Some(val) = res else { break };
525 val
526 }),
527 10u16 => NeighbourAttrs::LinkNetnsid({
528 let res = parse_i32(next);
529 let Some(val) = res else { break };
530 val
531 }),
532 11u16 => NeighbourAttrs::SrcVni({
533 let res = parse_u32(next);
534 let Some(val) = res else { break };
535 val
536 }),
537 12u16 => NeighbourAttrs::Protocol({
538 let res = parse_u8(next);
539 let Some(val) = res else { break };
540 val
541 }),
542 13u16 => NeighbourAttrs::NhId({
543 let res = parse_u32(next);
544 let Some(val) = res else { break };
545 val
546 }),
547 14u16 => NeighbourAttrs::FdbExtAttrs({
548 let res = Some(next);
549 let Some(val) = res else { break };
550 val
551 }),
552 15u16 => NeighbourAttrs::FlagsExt({
553 let res = parse_u32(next);
554 let Some(val) = res else { break };
555 val
556 }),
557 16u16 => NeighbourAttrs::NdmStateMask({
558 let res = parse_u16(next);
559 let Some(val) = res else { break };
560 val
561 }),
562 17u16 => NeighbourAttrs::NdmFlagsMask({
563 let res = parse_u8(next);
564 let Some(val) = res else { break };
565 val
566 }),
567 n => {
568 if cfg!(any(test, feature = "deny-unknown-attrs")) {
569 break;
570 } else {
571 continue;
572 }
573 }
574 };
575 return Some(Ok(res));
576 }
577 Some(Err(ErrorContext::new(
578 "NeighbourAttrs",
579 r#type.and_then(|t| NeighbourAttrs::attr_from_type(t)),
580 self.orig_loc,
581 self.buf.as_ptr().wrapping_add(pos) as usize,
582 )))
583 }
584}
585impl<'a> std::fmt::Debug for IterableNeighbourAttrs<'_> {
586 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
587 let mut fmt = f.debug_struct("NeighbourAttrs");
588 for attr in self.clone() {
589 let attr = match attr {
590 Ok(a) => a,
591 Err(err) => {
592 fmt.finish()?;
593 f.write_str("Err(")?;
594 err.fmt(f)?;
595 return f.write_str(")");
596 }
597 };
598 match attr {
599 NeighbourAttrs::Unspec(val) => fmt.field("Unspec", &val),
600 NeighbourAttrs::Dst(val) => fmt.field("Dst", &val),
601 NeighbourAttrs::Lladdr(val) => fmt.field("Lladdr", &val),
602 NeighbourAttrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
603 NeighbourAttrs::Probes(val) => fmt.field("Probes", &val),
604 NeighbourAttrs::Vlan(val) => fmt.field("Vlan", &val),
605 NeighbourAttrs::Port(val) => fmt.field("Port", &val),
606 NeighbourAttrs::Vni(val) => fmt.field("Vni", &val),
607 NeighbourAttrs::Ifindex(val) => fmt.field("Ifindex", &val),
608 NeighbourAttrs::Master(val) => fmt.field("Master", &val),
609 NeighbourAttrs::LinkNetnsid(val) => fmt.field("LinkNetnsid", &val),
610 NeighbourAttrs::SrcVni(val) => fmt.field("SrcVni", &val),
611 NeighbourAttrs::Protocol(val) => fmt.field("Protocol", &val),
612 NeighbourAttrs::NhId(val) => fmt.field("NhId", &val),
613 NeighbourAttrs::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
614 NeighbourAttrs::FlagsExt(val) => fmt.field(
615 "FlagsExt",
616 &FormatFlags(val.into(), NtfExtFlags::from_value),
617 ),
618 NeighbourAttrs::NdmStateMask(val) => fmt.field("NdmStateMask", &val),
619 NeighbourAttrs::NdmFlagsMask(val) => fmt.field("NdmFlagsMask", &val),
620 };
621 }
622 fmt.finish()
623 }
624}
625impl IterableNeighbourAttrs<'_> {
626 pub fn lookup_attr(
627 &self,
628 offset: usize,
629 missing_type: Option<u16>,
630 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
631 let mut stack = Vec::new();
632 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
633 if cur == offset {
634 stack.push(("NeighbourAttrs", offset));
635 return (
636 stack,
637 missing_type.and_then(|t| NeighbourAttrs::attr_from_type(t)),
638 );
639 }
640 if cur > offset || cur + self.buf.len() < offset {
641 return (stack, None);
642 }
643 let mut attrs = self.clone();
644 let mut last_off = cur + attrs.pos;
645 while let Some(attr) = attrs.next() {
646 let Ok(attr) = attr else { break };
647 match attr {
648 NeighbourAttrs::Unspec(val) => {
649 if last_off == offset {
650 stack.push(("Unspec", last_off));
651 break;
652 }
653 }
654 NeighbourAttrs::Dst(val) => {
655 if last_off == offset {
656 stack.push(("Dst", last_off));
657 break;
658 }
659 }
660 NeighbourAttrs::Lladdr(val) => {
661 if last_off == offset {
662 stack.push(("Lladdr", last_off));
663 break;
664 }
665 }
666 NeighbourAttrs::Cacheinfo(val) => {
667 if last_off == offset {
668 stack.push(("Cacheinfo", last_off));
669 break;
670 }
671 }
672 NeighbourAttrs::Probes(val) => {
673 if last_off == offset {
674 stack.push(("Probes", last_off));
675 break;
676 }
677 }
678 NeighbourAttrs::Vlan(val) => {
679 if last_off == offset {
680 stack.push(("Vlan", last_off));
681 break;
682 }
683 }
684 NeighbourAttrs::Port(val) => {
685 if last_off == offset {
686 stack.push(("Port", last_off));
687 break;
688 }
689 }
690 NeighbourAttrs::Vni(val) => {
691 if last_off == offset {
692 stack.push(("Vni", last_off));
693 break;
694 }
695 }
696 NeighbourAttrs::Ifindex(val) => {
697 if last_off == offset {
698 stack.push(("Ifindex", last_off));
699 break;
700 }
701 }
702 NeighbourAttrs::Master(val) => {
703 if last_off == offset {
704 stack.push(("Master", last_off));
705 break;
706 }
707 }
708 NeighbourAttrs::LinkNetnsid(val) => {
709 if last_off == offset {
710 stack.push(("LinkNetnsid", last_off));
711 break;
712 }
713 }
714 NeighbourAttrs::SrcVni(val) => {
715 if last_off == offset {
716 stack.push(("SrcVni", last_off));
717 break;
718 }
719 }
720 NeighbourAttrs::Protocol(val) => {
721 if last_off == offset {
722 stack.push(("Protocol", last_off));
723 break;
724 }
725 }
726 NeighbourAttrs::NhId(val) => {
727 if last_off == offset {
728 stack.push(("NhId", last_off));
729 break;
730 }
731 }
732 NeighbourAttrs::FdbExtAttrs(val) => {
733 if last_off == offset {
734 stack.push(("FdbExtAttrs", last_off));
735 break;
736 }
737 }
738 NeighbourAttrs::FlagsExt(val) => {
739 if last_off == offset {
740 stack.push(("FlagsExt", last_off));
741 break;
742 }
743 }
744 NeighbourAttrs::NdmStateMask(val) => {
745 if last_off == offset {
746 stack.push(("NdmStateMask", last_off));
747 break;
748 }
749 }
750 NeighbourAttrs::NdmFlagsMask(val) => {
751 if last_off == offset {
752 stack.push(("NdmFlagsMask", last_off));
753 break;
754 }
755 }
756 _ => {}
757 };
758 last_off = cur + attrs.pos;
759 }
760 if !stack.is_empty() {
761 stack.push(("NeighbourAttrs", cur));
762 }
763 (stack, None)
764 }
765}
766#[derive(Clone)]
767pub enum NdtAttrs<'a> {
768 Name(&'a CStr),
769 Thresh1(u32),
770 Thresh2(u32),
771 Thresh3(u32),
772 Config(PushNdtConfig),
773 Parms(IterableNdtpaAttrs<'a>),
774 Stats(PushNdtStats),
775 GcInterval(u64),
776 Pad(&'a [u8]),
777}
778impl<'a> IterableNdtAttrs<'a> {
779 pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
780 let mut iter = self.clone();
781 iter.pos = 0;
782 for attr in iter {
783 if let NdtAttrs::Name(val) = attr? {
784 return Ok(val);
785 }
786 }
787 Err(ErrorContext::new_missing(
788 "NdtAttrs",
789 "Name",
790 self.orig_loc,
791 self.buf.as_ptr() as usize,
792 ))
793 }
794 pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
795 let mut iter = self.clone();
796 iter.pos = 0;
797 for attr in iter {
798 if let NdtAttrs::Thresh1(val) = attr? {
799 return Ok(val);
800 }
801 }
802 Err(ErrorContext::new_missing(
803 "NdtAttrs",
804 "Thresh1",
805 self.orig_loc,
806 self.buf.as_ptr() as usize,
807 ))
808 }
809 pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
810 let mut iter = self.clone();
811 iter.pos = 0;
812 for attr in iter {
813 if let NdtAttrs::Thresh2(val) = attr? {
814 return Ok(val);
815 }
816 }
817 Err(ErrorContext::new_missing(
818 "NdtAttrs",
819 "Thresh2",
820 self.orig_loc,
821 self.buf.as_ptr() as usize,
822 ))
823 }
824 pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
825 let mut iter = self.clone();
826 iter.pos = 0;
827 for attr in iter {
828 if let NdtAttrs::Thresh3(val) = attr? {
829 return Ok(val);
830 }
831 }
832 Err(ErrorContext::new_missing(
833 "NdtAttrs",
834 "Thresh3",
835 self.orig_loc,
836 self.buf.as_ptr() as usize,
837 ))
838 }
839 pub fn get_config(&self) -> Result<PushNdtConfig, ErrorContext> {
840 let mut iter = self.clone();
841 iter.pos = 0;
842 for attr in iter {
843 if let NdtAttrs::Config(val) = attr? {
844 return Ok(val);
845 }
846 }
847 Err(ErrorContext::new_missing(
848 "NdtAttrs",
849 "Config",
850 self.orig_loc,
851 self.buf.as_ptr() as usize,
852 ))
853 }
854 pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
855 let mut iter = self.clone();
856 iter.pos = 0;
857 for attr in iter {
858 if let NdtAttrs::Parms(val) = attr? {
859 return Ok(val);
860 }
861 }
862 Err(ErrorContext::new_missing(
863 "NdtAttrs",
864 "Parms",
865 self.orig_loc,
866 self.buf.as_ptr() as usize,
867 ))
868 }
869 pub fn get_stats(&self) -> Result<PushNdtStats, ErrorContext> {
870 let mut iter = self.clone();
871 iter.pos = 0;
872 for attr in iter {
873 if let NdtAttrs::Stats(val) = attr? {
874 return Ok(val);
875 }
876 }
877 Err(ErrorContext::new_missing(
878 "NdtAttrs",
879 "Stats",
880 self.orig_loc,
881 self.buf.as_ptr() as usize,
882 ))
883 }
884 pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
885 let mut iter = self.clone();
886 iter.pos = 0;
887 for attr in iter {
888 if let NdtAttrs::GcInterval(val) = attr? {
889 return Ok(val);
890 }
891 }
892 Err(ErrorContext::new_missing(
893 "NdtAttrs",
894 "GcInterval",
895 self.orig_loc,
896 self.buf.as_ptr() as usize,
897 ))
898 }
899 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
900 let mut iter = self.clone();
901 iter.pos = 0;
902 for attr in iter {
903 if let NdtAttrs::Pad(val) = attr? {
904 return Ok(val);
905 }
906 }
907 Err(ErrorContext::new_missing(
908 "NdtAttrs",
909 "Pad",
910 self.orig_loc,
911 self.buf.as_ptr() as usize,
912 ))
913 }
914}
915impl<'a> NdtAttrs<'a> {
916 pub fn new(buf: &'a [u8]) -> IterableNdtAttrs<'a> {
917 IterableNdtAttrs::with_loc(buf, buf.as_ptr() as usize)
918 }
919 fn attr_from_type(r#type: u16) -> Option<&'static str> {
920 let res = match r#type {
921 1u16 => "Name",
922 2u16 => "Thresh1",
923 3u16 => "Thresh2",
924 4u16 => "Thresh3",
925 5u16 => "Config",
926 6u16 => "Parms",
927 7u16 => "Stats",
928 8u16 => "GcInterval",
929 9u16 => "Pad",
930 _ => return None,
931 };
932 Some(res)
933 }
934}
935#[derive(Clone, Copy, Default)]
936pub struct IterableNdtAttrs<'a> {
937 buf: &'a [u8],
938 pos: usize,
939 orig_loc: usize,
940}
941impl<'a> IterableNdtAttrs<'a> {
942 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
943 Self {
944 buf,
945 pos: 0,
946 orig_loc,
947 }
948 }
949 pub fn get_buf(&self) -> &'a [u8] {
950 self.buf
951 }
952}
953impl<'a> Iterator for IterableNdtAttrs<'a> {
954 type Item = Result<NdtAttrs<'a>, ErrorContext>;
955 fn next(&mut self) -> Option<Self::Item> {
956 if self.buf.len() == self.pos {
957 return None;
958 }
959 let pos = self.pos;
960 let mut r#type = None;
961 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
962 r#type = Some(header.r#type);
963 let res = match header.r#type {
964 1u16 => NdtAttrs::Name({
965 let res = CStr::from_bytes_with_nul(next).ok();
966 let Some(val) = res else { break };
967 val
968 }),
969 2u16 => NdtAttrs::Thresh1({
970 let res = parse_u32(next);
971 let Some(val) = res else { break };
972 val
973 }),
974 3u16 => NdtAttrs::Thresh2({
975 let res = parse_u32(next);
976 let Some(val) = res else { break };
977 val
978 }),
979 4u16 => NdtAttrs::Thresh3({
980 let res = parse_u32(next);
981 let Some(val) = res else { break };
982 val
983 }),
984 5u16 => NdtAttrs::Config({
985 let res = PushNdtConfig::new_from_slice(next);
986 let Some(val) = res else { break };
987 val
988 }),
989 6u16 => NdtAttrs::Parms({
990 let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
991 let Some(val) = res else { break };
992 val
993 }),
994 7u16 => NdtAttrs::Stats({
995 let res = PushNdtStats::new_from_slice(next);
996 let Some(val) = res else { break };
997 val
998 }),
999 8u16 => NdtAttrs::GcInterval({
1000 let res = parse_u64(next);
1001 let Some(val) = res else { break };
1002 val
1003 }),
1004 9u16 => NdtAttrs::Pad({
1005 let res = Some(next);
1006 let Some(val) = res else { break };
1007 val
1008 }),
1009 n => {
1010 if cfg!(any(test, feature = "deny-unknown-attrs")) {
1011 break;
1012 } else {
1013 continue;
1014 }
1015 }
1016 };
1017 return Some(Ok(res));
1018 }
1019 Some(Err(ErrorContext::new(
1020 "NdtAttrs",
1021 r#type.and_then(|t| NdtAttrs::attr_from_type(t)),
1022 self.orig_loc,
1023 self.buf.as_ptr().wrapping_add(pos) as usize,
1024 )))
1025 }
1026}
1027impl<'a> std::fmt::Debug for IterableNdtAttrs<'_> {
1028 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1029 let mut fmt = f.debug_struct("NdtAttrs");
1030 for attr in self.clone() {
1031 let attr = match attr {
1032 Ok(a) => a,
1033 Err(err) => {
1034 fmt.finish()?;
1035 f.write_str("Err(")?;
1036 err.fmt(f)?;
1037 return f.write_str(")");
1038 }
1039 };
1040 match attr {
1041 NdtAttrs::Name(val) => fmt.field("Name", &val),
1042 NdtAttrs::Thresh1(val) => fmt.field("Thresh1", &val),
1043 NdtAttrs::Thresh2(val) => fmt.field("Thresh2", &val),
1044 NdtAttrs::Thresh3(val) => fmt.field("Thresh3", &val),
1045 NdtAttrs::Config(val) => fmt.field("Config", &val),
1046 NdtAttrs::Parms(val) => fmt.field("Parms", &val),
1047 NdtAttrs::Stats(val) => fmt.field("Stats", &val),
1048 NdtAttrs::GcInterval(val) => fmt.field("GcInterval", &val),
1049 NdtAttrs::Pad(val) => fmt.field("Pad", &val),
1050 };
1051 }
1052 fmt.finish()
1053 }
1054}
1055impl IterableNdtAttrs<'_> {
1056 pub fn lookup_attr(
1057 &self,
1058 offset: usize,
1059 missing_type: Option<u16>,
1060 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1061 let mut stack = Vec::new();
1062 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1063 if cur == offset {
1064 stack.push(("NdtAttrs", offset));
1065 return (
1066 stack,
1067 missing_type.and_then(|t| NdtAttrs::attr_from_type(t)),
1068 );
1069 }
1070 if cur > offset || cur + self.buf.len() < offset {
1071 return (stack, None);
1072 }
1073 let mut attrs = self.clone();
1074 let mut last_off = cur + attrs.pos;
1075 let mut missing = None;
1076 while let Some(attr) = attrs.next() {
1077 let Ok(attr) = attr else { break };
1078 match attr {
1079 NdtAttrs::Name(val) => {
1080 if last_off == offset {
1081 stack.push(("Name", last_off));
1082 break;
1083 }
1084 }
1085 NdtAttrs::Thresh1(val) => {
1086 if last_off == offset {
1087 stack.push(("Thresh1", last_off));
1088 break;
1089 }
1090 }
1091 NdtAttrs::Thresh2(val) => {
1092 if last_off == offset {
1093 stack.push(("Thresh2", last_off));
1094 break;
1095 }
1096 }
1097 NdtAttrs::Thresh3(val) => {
1098 if last_off == offset {
1099 stack.push(("Thresh3", last_off));
1100 break;
1101 }
1102 }
1103 NdtAttrs::Config(val) => {
1104 if last_off == offset {
1105 stack.push(("Config", last_off));
1106 break;
1107 }
1108 }
1109 NdtAttrs::Parms(val) => {
1110 (stack, missing) = val.lookup_attr(offset, missing_type);
1111 if !stack.is_empty() {
1112 break;
1113 }
1114 }
1115 NdtAttrs::Stats(val) => {
1116 if last_off == offset {
1117 stack.push(("Stats", last_off));
1118 break;
1119 }
1120 }
1121 NdtAttrs::GcInterval(val) => {
1122 if last_off == offset {
1123 stack.push(("GcInterval", last_off));
1124 break;
1125 }
1126 }
1127 NdtAttrs::Pad(val) => {
1128 if last_off == offset {
1129 stack.push(("Pad", last_off));
1130 break;
1131 }
1132 }
1133 _ => {}
1134 };
1135 last_off = cur + attrs.pos;
1136 }
1137 if !stack.is_empty() {
1138 stack.push(("NdtAttrs", cur));
1139 }
1140 (stack, missing)
1141 }
1142}
1143#[derive(Clone)]
1144pub enum NdtpaAttrs<'a> {
1145 Ifindex(u32),
1146 Refcnt(u32),
1147 ReachableTime(u64),
1148 BaseReachableTime(u64),
1149 RetransTime(u64),
1150 GcStaletime(u64),
1151 DelayProbeTime(u64),
1152 QueueLen(u32),
1153 AppProbes(u32),
1154 UcastProbes(u32),
1155 McastProbes(u32),
1156 AnycastDelay(u64),
1157 ProxyDelay(u64),
1158 ProxyQlen(u32),
1159 Locktime(u64),
1160 QueueLenbytes(u32),
1161 McastReprobes(u32),
1162 Pad(&'a [u8]),
1163 IntervalProbeTimeMs(u64),
1164}
1165impl<'a> IterableNdtpaAttrs<'a> {
1166 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
1167 let mut iter = self.clone();
1168 iter.pos = 0;
1169 for attr in iter {
1170 if let NdtpaAttrs::Ifindex(val) = attr? {
1171 return Ok(val);
1172 }
1173 }
1174 Err(ErrorContext::new_missing(
1175 "NdtpaAttrs",
1176 "Ifindex",
1177 self.orig_loc,
1178 self.buf.as_ptr() as usize,
1179 ))
1180 }
1181 pub fn get_refcnt(&self) -> Result<u32, ErrorContext> {
1182 let mut iter = self.clone();
1183 iter.pos = 0;
1184 for attr in iter {
1185 if let NdtpaAttrs::Refcnt(val) = attr? {
1186 return Ok(val);
1187 }
1188 }
1189 Err(ErrorContext::new_missing(
1190 "NdtpaAttrs",
1191 "Refcnt",
1192 self.orig_loc,
1193 self.buf.as_ptr() as usize,
1194 ))
1195 }
1196 pub fn get_reachable_time(&self) -> Result<u64, ErrorContext> {
1197 let mut iter = self.clone();
1198 iter.pos = 0;
1199 for attr in iter {
1200 if let NdtpaAttrs::ReachableTime(val) = attr? {
1201 return Ok(val);
1202 }
1203 }
1204 Err(ErrorContext::new_missing(
1205 "NdtpaAttrs",
1206 "ReachableTime",
1207 self.orig_loc,
1208 self.buf.as_ptr() as usize,
1209 ))
1210 }
1211 pub fn get_base_reachable_time(&self) -> Result<u64, ErrorContext> {
1212 let mut iter = self.clone();
1213 iter.pos = 0;
1214 for attr in iter {
1215 if let NdtpaAttrs::BaseReachableTime(val) = attr? {
1216 return Ok(val);
1217 }
1218 }
1219 Err(ErrorContext::new_missing(
1220 "NdtpaAttrs",
1221 "BaseReachableTime",
1222 self.orig_loc,
1223 self.buf.as_ptr() as usize,
1224 ))
1225 }
1226 pub fn get_retrans_time(&self) -> Result<u64, ErrorContext> {
1227 let mut iter = self.clone();
1228 iter.pos = 0;
1229 for attr in iter {
1230 if let NdtpaAttrs::RetransTime(val) = attr? {
1231 return Ok(val);
1232 }
1233 }
1234 Err(ErrorContext::new_missing(
1235 "NdtpaAttrs",
1236 "RetransTime",
1237 self.orig_loc,
1238 self.buf.as_ptr() as usize,
1239 ))
1240 }
1241 pub fn get_gc_staletime(&self) -> Result<u64, ErrorContext> {
1242 let mut iter = self.clone();
1243 iter.pos = 0;
1244 for attr in iter {
1245 if let NdtpaAttrs::GcStaletime(val) = attr? {
1246 return Ok(val);
1247 }
1248 }
1249 Err(ErrorContext::new_missing(
1250 "NdtpaAttrs",
1251 "GcStaletime",
1252 self.orig_loc,
1253 self.buf.as_ptr() as usize,
1254 ))
1255 }
1256 pub fn get_delay_probe_time(&self) -> Result<u64, ErrorContext> {
1257 let mut iter = self.clone();
1258 iter.pos = 0;
1259 for attr in iter {
1260 if let NdtpaAttrs::DelayProbeTime(val) = attr? {
1261 return Ok(val);
1262 }
1263 }
1264 Err(ErrorContext::new_missing(
1265 "NdtpaAttrs",
1266 "DelayProbeTime",
1267 self.orig_loc,
1268 self.buf.as_ptr() as usize,
1269 ))
1270 }
1271 pub fn get_queue_len(&self) -> Result<u32, ErrorContext> {
1272 let mut iter = self.clone();
1273 iter.pos = 0;
1274 for attr in iter {
1275 if let NdtpaAttrs::QueueLen(val) = attr? {
1276 return Ok(val);
1277 }
1278 }
1279 Err(ErrorContext::new_missing(
1280 "NdtpaAttrs",
1281 "QueueLen",
1282 self.orig_loc,
1283 self.buf.as_ptr() as usize,
1284 ))
1285 }
1286 pub fn get_app_probes(&self) -> Result<u32, ErrorContext> {
1287 let mut iter = self.clone();
1288 iter.pos = 0;
1289 for attr in iter {
1290 if let NdtpaAttrs::AppProbes(val) = attr? {
1291 return Ok(val);
1292 }
1293 }
1294 Err(ErrorContext::new_missing(
1295 "NdtpaAttrs",
1296 "AppProbes",
1297 self.orig_loc,
1298 self.buf.as_ptr() as usize,
1299 ))
1300 }
1301 pub fn get_ucast_probes(&self) -> Result<u32, ErrorContext> {
1302 let mut iter = self.clone();
1303 iter.pos = 0;
1304 for attr in iter {
1305 if let NdtpaAttrs::UcastProbes(val) = attr? {
1306 return Ok(val);
1307 }
1308 }
1309 Err(ErrorContext::new_missing(
1310 "NdtpaAttrs",
1311 "UcastProbes",
1312 self.orig_loc,
1313 self.buf.as_ptr() as usize,
1314 ))
1315 }
1316 pub fn get_mcast_probes(&self) -> Result<u32, ErrorContext> {
1317 let mut iter = self.clone();
1318 iter.pos = 0;
1319 for attr in iter {
1320 if let NdtpaAttrs::McastProbes(val) = attr? {
1321 return Ok(val);
1322 }
1323 }
1324 Err(ErrorContext::new_missing(
1325 "NdtpaAttrs",
1326 "McastProbes",
1327 self.orig_loc,
1328 self.buf.as_ptr() as usize,
1329 ))
1330 }
1331 pub fn get_anycast_delay(&self) -> Result<u64, ErrorContext> {
1332 let mut iter = self.clone();
1333 iter.pos = 0;
1334 for attr in iter {
1335 if let NdtpaAttrs::AnycastDelay(val) = attr? {
1336 return Ok(val);
1337 }
1338 }
1339 Err(ErrorContext::new_missing(
1340 "NdtpaAttrs",
1341 "AnycastDelay",
1342 self.orig_loc,
1343 self.buf.as_ptr() as usize,
1344 ))
1345 }
1346 pub fn get_proxy_delay(&self) -> Result<u64, ErrorContext> {
1347 let mut iter = self.clone();
1348 iter.pos = 0;
1349 for attr in iter {
1350 if let NdtpaAttrs::ProxyDelay(val) = attr? {
1351 return Ok(val);
1352 }
1353 }
1354 Err(ErrorContext::new_missing(
1355 "NdtpaAttrs",
1356 "ProxyDelay",
1357 self.orig_loc,
1358 self.buf.as_ptr() as usize,
1359 ))
1360 }
1361 pub fn get_proxy_qlen(&self) -> Result<u32, ErrorContext> {
1362 let mut iter = self.clone();
1363 iter.pos = 0;
1364 for attr in iter {
1365 if let NdtpaAttrs::ProxyQlen(val) = attr? {
1366 return Ok(val);
1367 }
1368 }
1369 Err(ErrorContext::new_missing(
1370 "NdtpaAttrs",
1371 "ProxyQlen",
1372 self.orig_loc,
1373 self.buf.as_ptr() as usize,
1374 ))
1375 }
1376 pub fn get_locktime(&self) -> Result<u64, ErrorContext> {
1377 let mut iter = self.clone();
1378 iter.pos = 0;
1379 for attr in iter {
1380 if let NdtpaAttrs::Locktime(val) = attr? {
1381 return Ok(val);
1382 }
1383 }
1384 Err(ErrorContext::new_missing(
1385 "NdtpaAttrs",
1386 "Locktime",
1387 self.orig_loc,
1388 self.buf.as_ptr() as usize,
1389 ))
1390 }
1391 pub fn get_queue_lenbytes(&self) -> Result<u32, ErrorContext> {
1392 let mut iter = self.clone();
1393 iter.pos = 0;
1394 for attr in iter {
1395 if let NdtpaAttrs::QueueLenbytes(val) = attr? {
1396 return Ok(val);
1397 }
1398 }
1399 Err(ErrorContext::new_missing(
1400 "NdtpaAttrs",
1401 "QueueLenbytes",
1402 self.orig_loc,
1403 self.buf.as_ptr() as usize,
1404 ))
1405 }
1406 pub fn get_mcast_reprobes(&self) -> Result<u32, ErrorContext> {
1407 let mut iter = self.clone();
1408 iter.pos = 0;
1409 for attr in iter {
1410 if let NdtpaAttrs::McastReprobes(val) = attr? {
1411 return Ok(val);
1412 }
1413 }
1414 Err(ErrorContext::new_missing(
1415 "NdtpaAttrs",
1416 "McastReprobes",
1417 self.orig_loc,
1418 self.buf.as_ptr() as usize,
1419 ))
1420 }
1421 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
1422 let mut iter = self.clone();
1423 iter.pos = 0;
1424 for attr in iter {
1425 if let NdtpaAttrs::Pad(val) = attr? {
1426 return Ok(val);
1427 }
1428 }
1429 Err(ErrorContext::new_missing(
1430 "NdtpaAttrs",
1431 "Pad",
1432 self.orig_loc,
1433 self.buf.as_ptr() as usize,
1434 ))
1435 }
1436 pub fn get_interval_probe_time_ms(&self) -> Result<u64, ErrorContext> {
1437 let mut iter = self.clone();
1438 iter.pos = 0;
1439 for attr in iter {
1440 if let NdtpaAttrs::IntervalProbeTimeMs(val) = attr? {
1441 return Ok(val);
1442 }
1443 }
1444 Err(ErrorContext::new_missing(
1445 "NdtpaAttrs",
1446 "IntervalProbeTimeMs",
1447 self.orig_loc,
1448 self.buf.as_ptr() as usize,
1449 ))
1450 }
1451}
1452impl<'a> NdtpaAttrs<'a> {
1453 pub fn new(buf: &'a [u8]) -> IterableNdtpaAttrs<'a> {
1454 IterableNdtpaAttrs::with_loc(buf, buf.as_ptr() as usize)
1455 }
1456 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1457 let res = match r#type {
1458 1u16 => "Ifindex",
1459 2u16 => "Refcnt",
1460 3u16 => "ReachableTime",
1461 4u16 => "BaseReachableTime",
1462 5u16 => "RetransTime",
1463 6u16 => "GcStaletime",
1464 7u16 => "DelayProbeTime",
1465 8u16 => "QueueLen",
1466 9u16 => "AppProbes",
1467 10u16 => "UcastProbes",
1468 11u16 => "McastProbes",
1469 12u16 => "AnycastDelay",
1470 13u16 => "ProxyDelay",
1471 14u16 => "ProxyQlen",
1472 15u16 => "Locktime",
1473 16u16 => "QueueLenbytes",
1474 17u16 => "McastReprobes",
1475 18u16 => "Pad",
1476 19u16 => "IntervalProbeTimeMs",
1477 _ => return None,
1478 };
1479 Some(res)
1480 }
1481}
1482#[derive(Clone, Copy, Default)]
1483pub struct IterableNdtpaAttrs<'a> {
1484 buf: &'a [u8],
1485 pos: usize,
1486 orig_loc: usize,
1487}
1488impl<'a> IterableNdtpaAttrs<'a> {
1489 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1490 Self {
1491 buf,
1492 pos: 0,
1493 orig_loc,
1494 }
1495 }
1496 pub fn get_buf(&self) -> &'a [u8] {
1497 self.buf
1498 }
1499}
1500impl<'a> Iterator for IterableNdtpaAttrs<'a> {
1501 type Item = Result<NdtpaAttrs<'a>, ErrorContext>;
1502 fn next(&mut self) -> Option<Self::Item> {
1503 if self.buf.len() == self.pos {
1504 return None;
1505 }
1506 let pos = self.pos;
1507 let mut r#type = None;
1508 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
1509 r#type = Some(header.r#type);
1510 let res = match header.r#type {
1511 1u16 => NdtpaAttrs::Ifindex({
1512 let res = parse_u32(next);
1513 let Some(val) = res else { break };
1514 val
1515 }),
1516 2u16 => NdtpaAttrs::Refcnt({
1517 let res = parse_u32(next);
1518 let Some(val) = res else { break };
1519 val
1520 }),
1521 3u16 => NdtpaAttrs::ReachableTime({
1522 let res = parse_u64(next);
1523 let Some(val) = res else { break };
1524 val
1525 }),
1526 4u16 => NdtpaAttrs::BaseReachableTime({
1527 let res = parse_u64(next);
1528 let Some(val) = res else { break };
1529 val
1530 }),
1531 5u16 => NdtpaAttrs::RetransTime({
1532 let res = parse_u64(next);
1533 let Some(val) = res else { break };
1534 val
1535 }),
1536 6u16 => NdtpaAttrs::GcStaletime({
1537 let res = parse_u64(next);
1538 let Some(val) = res else { break };
1539 val
1540 }),
1541 7u16 => NdtpaAttrs::DelayProbeTime({
1542 let res = parse_u64(next);
1543 let Some(val) = res else { break };
1544 val
1545 }),
1546 8u16 => NdtpaAttrs::QueueLen({
1547 let res = parse_u32(next);
1548 let Some(val) = res else { break };
1549 val
1550 }),
1551 9u16 => NdtpaAttrs::AppProbes({
1552 let res = parse_u32(next);
1553 let Some(val) = res else { break };
1554 val
1555 }),
1556 10u16 => NdtpaAttrs::UcastProbes({
1557 let res = parse_u32(next);
1558 let Some(val) = res else { break };
1559 val
1560 }),
1561 11u16 => NdtpaAttrs::McastProbes({
1562 let res = parse_u32(next);
1563 let Some(val) = res else { break };
1564 val
1565 }),
1566 12u16 => NdtpaAttrs::AnycastDelay({
1567 let res = parse_u64(next);
1568 let Some(val) = res else { break };
1569 val
1570 }),
1571 13u16 => NdtpaAttrs::ProxyDelay({
1572 let res = parse_u64(next);
1573 let Some(val) = res else { break };
1574 val
1575 }),
1576 14u16 => NdtpaAttrs::ProxyQlen({
1577 let res = parse_u32(next);
1578 let Some(val) = res else { break };
1579 val
1580 }),
1581 15u16 => NdtpaAttrs::Locktime({
1582 let res = parse_u64(next);
1583 let Some(val) = res else { break };
1584 val
1585 }),
1586 16u16 => NdtpaAttrs::QueueLenbytes({
1587 let res = parse_u32(next);
1588 let Some(val) = res else { break };
1589 val
1590 }),
1591 17u16 => NdtpaAttrs::McastReprobes({
1592 let res = parse_u32(next);
1593 let Some(val) = res else { break };
1594 val
1595 }),
1596 18u16 => NdtpaAttrs::Pad({
1597 let res = Some(next);
1598 let Some(val) = res else { break };
1599 val
1600 }),
1601 19u16 => NdtpaAttrs::IntervalProbeTimeMs({
1602 let res = parse_u64(next);
1603 let Some(val) = res else { break };
1604 val
1605 }),
1606 n => {
1607 if cfg!(any(test, feature = "deny-unknown-attrs")) {
1608 break;
1609 } else {
1610 continue;
1611 }
1612 }
1613 };
1614 return Some(Ok(res));
1615 }
1616 Some(Err(ErrorContext::new(
1617 "NdtpaAttrs",
1618 r#type.and_then(|t| NdtpaAttrs::attr_from_type(t)),
1619 self.orig_loc,
1620 self.buf.as_ptr().wrapping_add(pos) as usize,
1621 )))
1622 }
1623}
1624impl<'a> std::fmt::Debug for IterableNdtpaAttrs<'_> {
1625 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1626 let mut fmt = f.debug_struct("NdtpaAttrs");
1627 for attr in self.clone() {
1628 let attr = match attr {
1629 Ok(a) => a,
1630 Err(err) => {
1631 fmt.finish()?;
1632 f.write_str("Err(")?;
1633 err.fmt(f)?;
1634 return f.write_str(")");
1635 }
1636 };
1637 match attr {
1638 NdtpaAttrs::Ifindex(val) => fmt.field("Ifindex", &val),
1639 NdtpaAttrs::Refcnt(val) => fmt.field("Refcnt", &val),
1640 NdtpaAttrs::ReachableTime(val) => fmt.field("ReachableTime", &val),
1641 NdtpaAttrs::BaseReachableTime(val) => fmt.field("BaseReachableTime", &val),
1642 NdtpaAttrs::RetransTime(val) => fmt.field("RetransTime", &val),
1643 NdtpaAttrs::GcStaletime(val) => fmt.field("GcStaletime", &val),
1644 NdtpaAttrs::DelayProbeTime(val) => fmt.field("DelayProbeTime", &val),
1645 NdtpaAttrs::QueueLen(val) => fmt.field("QueueLen", &val),
1646 NdtpaAttrs::AppProbes(val) => fmt.field("AppProbes", &val),
1647 NdtpaAttrs::UcastProbes(val) => fmt.field("UcastProbes", &val),
1648 NdtpaAttrs::McastProbes(val) => fmt.field("McastProbes", &val),
1649 NdtpaAttrs::AnycastDelay(val) => fmt.field("AnycastDelay", &val),
1650 NdtpaAttrs::ProxyDelay(val) => fmt.field("ProxyDelay", &val),
1651 NdtpaAttrs::ProxyQlen(val) => fmt.field("ProxyQlen", &val),
1652 NdtpaAttrs::Locktime(val) => fmt.field("Locktime", &val),
1653 NdtpaAttrs::QueueLenbytes(val) => fmt.field("QueueLenbytes", &val),
1654 NdtpaAttrs::McastReprobes(val) => fmt.field("McastReprobes", &val),
1655 NdtpaAttrs::Pad(val) => fmt.field("Pad", &val),
1656 NdtpaAttrs::IntervalProbeTimeMs(val) => fmt.field("IntervalProbeTimeMs", &val),
1657 };
1658 }
1659 fmt.finish()
1660 }
1661}
1662impl IterableNdtpaAttrs<'_> {
1663 pub fn lookup_attr(
1664 &self,
1665 offset: usize,
1666 missing_type: Option<u16>,
1667 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1668 let mut stack = Vec::new();
1669 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1670 if cur == offset {
1671 stack.push(("NdtpaAttrs", offset));
1672 return (
1673 stack,
1674 missing_type.and_then(|t| NdtpaAttrs::attr_from_type(t)),
1675 );
1676 }
1677 if cur > offset || cur + self.buf.len() < offset {
1678 return (stack, None);
1679 }
1680 let mut attrs = self.clone();
1681 let mut last_off = cur + attrs.pos;
1682 while let Some(attr) = attrs.next() {
1683 let Ok(attr) = attr else { break };
1684 match attr {
1685 NdtpaAttrs::Ifindex(val) => {
1686 if last_off == offset {
1687 stack.push(("Ifindex", last_off));
1688 break;
1689 }
1690 }
1691 NdtpaAttrs::Refcnt(val) => {
1692 if last_off == offset {
1693 stack.push(("Refcnt", last_off));
1694 break;
1695 }
1696 }
1697 NdtpaAttrs::ReachableTime(val) => {
1698 if last_off == offset {
1699 stack.push(("ReachableTime", last_off));
1700 break;
1701 }
1702 }
1703 NdtpaAttrs::BaseReachableTime(val) => {
1704 if last_off == offset {
1705 stack.push(("BaseReachableTime", last_off));
1706 break;
1707 }
1708 }
1709 NdtpaAttrs::RetransTime(val) => {
1710 if last_off == offset {
1711 stack.push(("RetransTime", last_off));
1712 break;
1713 }
1714 }
1715 NdtpaAttrs::GcStaletime(val) => {
1716 if last_off == offset {
1717 stack.push(("GcStaletime", last_off));
1718 break;
1719 }
1720 }
1721 NdtpaAttrs::DelayProbeTime(val) => {
1722 if last_off == offset {
1723 stack.push(("DelayProbeTime", last_off));
1724 break;
1725 }
1726 }
1727 NdtpaAttrs::QueueLen(val) => {
1728 if last_off == offset {
1729 stack.push(("QueueLen", last_off));
1730 break;
1731 }
1732 }
1733 NdtpaAttrs::AppProbes(val) => {
1734 if last_off == offset {
1735 stack.push(("AppProbes", last_off));
1736 break;
1737 }
1738 }
1739 NdtpaAttrs::UcastProbes(val) => {
1740 if last_off == offset {
1741 stack.push(("UcastProbes", last_off));
1742 break;
1743 }
1744 }
1745 NdtpaAttrs::McastProbes(val) => {
1746 if last_off == offset {
1747 stack.push(("McastProbes", last_off));
1748 break;
1749 }
1750 }
1751 NdtpaAttrs::AnycastDelay(val) => {
1752 if last_off == offset {
1753 stack.push(("AnycastDelay", last_off));
1754 break;
1755 }
1756 }
1757 NdtpaAttrs::ProxyDelay(val) => {
1758 if last_off == offset {
1759 stack.push(("ProxyDelay", last_off));
1760 break;
1761 }
1762 }
1763 NdtpaAttrs::ProxyQlen(val) => {
1764 if last_off == offset {
1765 stack.push(("ProxyQlen", last_off));
1766 break;
1767 }
1768 }
1769 NdtpaAttrs::Locktime(val) => {
1770 if last_off == offset {
1771 stack.push(("Locktime", last_off));
1772 break;
1773 }
1774 }
1775 NdtpaAttrs::QueueLenbytes(val) => {
1776 if last_off == offset {
1777 stack.push(("QueueLenbytes", last_off));
1778 break;
1779 }
1780 }
1781 NdtpaAttrs::McastReprobes(val) => {
1782 if last_off == offset {
1783 stack.push(("McastReprobes", last_off));
1784 break;
1785 }
1786 }
1787 NdtpaAttrs::Pad(val) => {
1788 if last_off == offset {
1789 stack.push(("Pad", last_off));
1790 break;
1791 }
1792 }
1793 NdtpaAttrs::IntervalProbeTimeMs(val) => {
1794 if last_off == offset {
1795 stack.push(("IntervalProbeTimeMs", last_off));
1796 break;
1797 }
1798 }
1799 _ => {}
1800 };
1801 last_off = cur + attrs.pos;
1802 }
1803 if !stack.is_empty() {
1804 stack.push(("NdtpaAttrs", cur));
1805 }
1806 (stack, None)
1807 }
1808}
1809pub struct PushNeighbourAttrs<Prev: Rec> {
1810 pub(crate) prev: Option<Prev>,
1811 pub(crate) header_offset: Option<usize>,
1812}
1813impl<Prev: Rec> Rec for PushNeighbourAttrs<Prev> {
1814 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1815 self.prev.as_mut().unwrap().as_rec_mut()
1816 }
1817}
1818impl<Prev: Rec> PushNeighbourAttrs<Prev> {
1819 pub fn new(prev: Prev) -> Self {
1820 Self {
1821 prev: Some(prev),
1822 header_offset: None,
1823 }
1824 }
1825 pub fn end_nested(mut self) -> Prev {
1826 let mut prev = self.prev.take().unwrap();
1827 if let Some(header_offset) = &self.header_offset {
1828 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1829 }
1830 prev
1831 }
1832 pub fn push_unspec(mut self, value: &[u8]) -> Self {
1833 push_header(self.as_rec_mut(), 0u16, value.len() as u16);
1834 self.as_rec_mut().extend(value);
1835 self
1836 }
1837 pub fn push_dst(mut self, value: &[u8]) -> Self {
1838 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
1839 self.as_rec_mut().extend(value);
1840 self
1841 }
1842 pub fn push_lladdr(mut self, value: &[u8]) -> Self {
1843 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
1844 self.as_rec_mut().extend(value);
1845 self
1846 }
1847 pub fn push_cacheinfo(mut self, value: PushNdaCacheinfo) -> Self {
1848 push_header(self.as_rec_mut(), 3u16, value.as_slice().len() as u16);
1849 self.as_rec_mut().extend(value.as_slice());
1850 self
1851 }
1852 pub fn push_probes(mut self, value: u32) -> Self {
1853 push_header(self.as_rec_mut(), 4u16, 4 as u16);
1854 self.as_rec_mut().extend(value.to_ne_bytes());
1855 self
1856 }
1857 pub fn push_vlan(mut self, value: u16) -> Self {
1858 push_header(self.as_rec_mut(), 5u16, 2 as u16);
1859 self.as_rec_mut().extend(value.to_ne_bytes());
1860 self
1861 }
1862 pub fn push_port(mut self, value: u16) -> Self {
1863 push_header(self.as_rec_mut(), 6u16, 2 as u16);
1864 self.as_rec_mut().extend(value.to_ne_bytes());
1865 self
1866 }
1867 pub fn push_vni(mut self, value: u32) -> Self {
1868 push_header(self.as_rec_mut(), 7u16, 4 as u16);
1869 self.as_rec_mut().extend(value.to_ne_bytes());
1870 self
1871 }
1872 pub fn push_ifindex(mut self, value: u32) -> Self {
1873 push_header(self.as_rec_mut(), 8u16, 4 as u16);
1874 self.as_rec_mut().extend(value.to_ne_bytes());
1875 self
1876 }
1877 pub fn push_master(mut self, value: u32) -> Self {
1878 push_header(self.as_rec_mut(), 9u16, 4 as u16);
1879 self.as_rec_mut().extend(value.to_ne_bytes());
1880 self
1881 }
1882 pub fn push_link_netnsid(mut self, value: i32) -> Self {
1883 push_header(self.as_rec_mut(), 10u16, 4 as u16);
1884 self.as_rec_mut().extend(value.to_ne_bytes());
1885 self
1886 }
1887 pub fn push_src_vni(mut self, value: u32) -> Self {
1888 push_header(self.as_rec_mut(), 11u16, 4 as u16);
1889 self.as_rec_mut().extend(value.to_ne_bytes());
1890 self
1891 }
1892 pub fn push_protocol(mut self, value: u8) -> Self {
1893 push_header(self.as_rec_mut(), 12u16, 1 as u16);
1894 self.as_rec_mut().extend(value.to_ne_bytes());
1895 self
1896 }
1897 pub fn push_nh_id(mut self, value: u32) -> Self {
1898 push_header(self.as_rec_mut(), 13u16, 4 as u16);
1899 self.as_rec_mut().extend(value.to_ne_bytes());
1900 self
1901 }
1902 pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
1903 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
1904 self.as_rec_mut().extend(value);
1905 self
1906 }
1907 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
1908 pub fn push_flags_ext(mut self, value: u32) -> Self {
1909 push_header(self.as_rec_mut(), 15u16, 4 as u16);
1910 self.as_rec_mut().extend(value.to_ne_bytes());
1911 self
1912 }
1913 pub fn push_ndm_state_mask(mut self, value: u16) -> Self {
1914 push_header(self.as_rec_mut(), 16u16, 2 as u16);
1915 self.as_rec_mut().extend(value.to_ne_bytes());
1916 self
1917 }
1918 pub fn push_ndm_flags_mask(mut self, value: u8) -> Self {
1919 push_header(self.as_rec_mut(), 17u16, 1 as u16);
1920 self.as_rec_mut().extend(value.to_ne_bytes());
1921 self
1922 }
1923}
1924impl<Prev: Rec> Drop for PushNeighbourAttrs<Prev> {
1925 fn drop(&mut self) {
1926 if let Some(prev) = &mut self.prev {
1927 if let Some(header_offset) = &self.header_offset {
1928 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1929 }
1930 }
1931 }
1932}
1933pub struct PushNdtAttrs<Prev: Rec> {
1934 pub(crate) prev: Option<Prev>,
1935 pub(crate) header_offset: Option<usize>,
1936}
1937impl<Prev: Rec> Rec for PushNdtAttrs<Prev> {
1938 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
1939 self.prev.as_mut().unwrap().as_rec_mut()
1940 }
1941}
1942impl<Prev: Rec> PushNdtAttrs<Prev> {
1943 pub fn new(prev: Prev) -> Self {
1944 Self {
1945 prev: Some(prev),
1946 header_offset: None,
1947 }
1948 }
1949 pub fn end_nested(mut self) -> Prev {
1950 let mut prev = self.prev.take().unwrap();
1951 if let Some(header_offset) = &self.header_offset {
1952 finalize_nested_header(prev.as_rec_mut(), *header_offset);
1953 }
1954 prev
1955 }
1956 pub fn push_name(mut self, value: &CStr) -> Self {
1957 push_header(
1958 self.as_rec_mut(),
1959 1u16,
1960 value.to_bytes_with_nul().len() as u16,
1961 );
1962 self.as_rec_mut().extend(value.to_bytes_with_nul());
1963 self
1964 }
1965 pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
1966 push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
1967 self.as_rec_mut().extend(value);
1968 self.as_rec_mut().push(0);
1969 self
1970 }
1971 pub fn push_thresh1(mut self, value: u32) -> Self {
1972 push_header(self.as_rec_mut(), 2u16, 4 as u16);
1973 self.as_rec_mut().extend(value.to_ne_bytes());
1974 self
1975 }
1976 pub fn push_thresh2(mut self, value: u32) -> Self {
1977 push_header(self.as_rec_mut(), 3u16, 4 as u16);
1978 self.as_rec_mut().extend(value.to_ne_bytes());
1979 self
1980 }
1981 pub fn push_thresh3(mut self, value: u32) -> Self {
1982 push_header(self.as_rec_mut(), 4u16, 4 as u16);
1983 self.as_rec_mut().extend(value.to_ne_bytes());
1984 self
1985 }
1986 pub fn push_config(mut self, value: PushNdtConfig) -> Self {
1987 push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
1988 self.as_rec_mut().extend(value.as_slice());
1989 self
1990 }
1991 pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
1992 let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
1993 PushNdtpaAttrs {
1994 prev: Some(self),
1995 header_offset: Some(header_offset),
1996 }
1997 }
1998 pub fn push_stats(mut self, value: PushNdtStats) -> Self {
1999 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
2000 self.as_rec_mut().extend(value.as_slice());
2001 self
2002 }
2003 pub fn push_gc_interval(mut self, value: u64) -> Self {
2004 push_header(self.as_rec_mut(), 8u16, 8 as u16);
2005 self.as_rec_mut().extend(value.to_ne_bytes());
2006 self
2007 }
2008 pub fn push_pad(mut self, value: &[u8]) -> Self {
2009 push_header(self.as_rec_mut(), 9u16, value.len() as u16);
2010 self.as_rec_mut().extend(value);
2011 self
2012 }
2013}
2014impl<Prev: Rec> Drop for PushNdtAttrs<Prev> {
2015 fn drop(&mut self) {
2016 if let Some(prev) = &mut self.prev {
2017 if let Some(header_offset) = &self.header_offset {
2018 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2019 }
2020 }
2021 }
2022}
2023pub struct PushNdtpaAttrs<Prev: Rec> {
2024 pub(crate) prev: Option<Prev>,
2025 pub(crate) header_offset: Option<usize>,
2026}
2027impl<Prev: Rec> Rec for PushNdtpaAttrs<Prev> {
2028 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2029 self.prev.as_mut().unwrap().as_rec_mut()
2030 }
2031}
2032impl<Prev: Rec> PushNdtpaAttrs<Prev> {
2033 pub fn new(prev: Prev) -> Self {
2034 Self {
2035 prev: Some(prev),
2036 header_offset: None,
2037 }
2038 }
2039 pub fn end_nested(mut self) -> Prev {
2040 let mut prev = self.prev.take().unwrap();
2041 if let Some(header_offset) = &self.header_offset {
2042 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2043 }
2044 prev
2045 }
2046 pub fn push_ifindex(mut self, value: u32) -> Self {
2047 push_header(self.as_rec_mut(), 1u16, 4 as u16);
2048 self.as_rec_mut().extend(value.to_ne_bytes());
2049 self
2050 }
2051 pub fn push_refcnt(mut self, value: u32) -> Self {
2052 push_header(self.as_rec_mut(), 2u16, 4 as u16);
2053 self.as_rec_mut().extend(value.to_ne_bytes());
2054 self
2055 }
2056 pub fn push_reachable_time(mut self, value: u64) -> Self {
2057 push_header(self.as_rec_mut(), 3u16, 8 as u16);
2058 self.as_rec_mut().extend(value.to_ne_bytes());
2059 self
2060 }
2061 pub fn push_base_reachable_time(mut self, value: u64) -> Self {
2062 push_header(self.as_rec_mut(), 4u16, 8 as u16);
2063 self.as_rec_mut().extend(value.to_ne_bytes());
2064 self
2065 }
2066 pub fn push_retrans_time(mut self, value: u64) -> Self {
2067 push_header(self.as_rec_mut(), 5u16, 8 as u16);
2068 self.as_rec_mut().extend(value.to_ne_bytes());
2069 self
2070 }
2071 pub fn push_gc_staletime(mut self, value: u64) -> Self {
2072 push_header(self.as_rec_mut(), 6u16, 8 as u16);
2073 self.as_rec_mut().extend(value.to_ne_bytes());
2074 self
2075 }
2076 pub fn push_delay_probe_time(mut self, value: u64) -> Self {
2077 push_header(self.as_rec_mut(), 7u16, 8 as u16);
2078 self.as_rec_mut().extend(value.to_ne_bytes());
2079 self
2080 }
2081 pub fn push_queue_len(mut self, value: u32) -> Self {
2082 push_header(self.as_rec_mut(), 8u16, 4 as u16);
2083 self.as_rec_mut().extend(value.to_ne_bytes());
2084 self
2085 }
2086 pub fn push_app_probes(mut self, value: u32) -> Self {
2087 push_header(self.as_rec_mut(), 9u16, 4 as u16);
2088 self.as_rec_mut().extend(value.to_ne_bytes());
2089 self
2090 }
2091 pub fn push_ucast_probes(mut self, value: u32) -> Self {
2092 push_header(self.as_rec_mut(), 10u16, 4 as u16);
2093 self.as_rec_mut().extend(value.to_ne_bytes());
2094 self
2095 }
2096 pub fn push_mcast_probes(mut self, value: u32) -> Self {
2097 push_header(self.as_rec_mut(), 11u16, 4 as u16);
2098 self.as_rec_mut().extend(value.to_ne_bytes());
2099 self
2100 }
2101 pub fn push_anycast_delay(mut self, value: u64) -> Self {
2102 push_header(self.as_rec_mut(), 12u16, 8 as u16);
2103 self.as_rec_mut().extend(value.to_ne_bytes());
2104 self
2105 }
2106 pub fn push_proxy_delay(mut self, value: u64) -> Self {
2107 push_header(self.as_rec_mut(), 13u16, 8 as u16);
2108 self.as_rec_mut().extend(value.to_ne_bytes());
2109 self
2110 }
2111 pub fn push_proxy_qlen(mut self, value: u32) -> Self {
2112 push_header(self.as_rec_mut(), 14u16, 4 as u16);
2113 self.as_rec_mut().extend(value.to_ne_bytes());
2114 self
2115 }
2116 pub fn push_locktime(mut self, value: u64) -> Self {
2117 push_header(self.as_rec_mut(), 15u16, 8 as u16);
2118 self.as_rec_mut().extend(value.to_ne_bytes());
2119 self
2120 }
2121 pub fn push_queue_lenbytes(mut self, value: u32) -> Self {
2122 push_header(self.as_rec_mut(), 16u16, 4 as u16);
2123 self.as_rec_mut().extend(value.to_ne_bytes());
2124 self
2125 }
2126 pub fn push_mcast_reprobes(mut self, value: u32) -> Self {
2127 push_header(self.as_rec_mut(), 17u16, 4 as u16);
2128 self.as_rec_mut().extend(value.to_ne_bytes());
2129 self
2130 }
2131 pub fn push_pad(mut self, value: &[u8]) -> Self {
2132 push_header(self.as_rec_mut(), 18u16, value.len() as u16);
2133 self.as_rec_mut().extend(value);
2134 self
2135 }
2136 pub fn push_interval_probe_time_ms(mut self, value: u64) -> Self {
2137 push_header(self.as_rec_mut(), 19u16, 8 as u16);
2138 self.as_rec_mut().extend(value.to_ne_bytes());
2139 self
2140 }
2141}
2142impl<Prev: Rec> Drop for PushNdtpaAttrs<Prev> {
2143 fn drop(&mut self) {
2144 if let Some(prev) = &mut self.prev {
2145 if let Some(header_offset) = &self.header_offset {
2146 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2147 }
2148 }
2149 }
2150}
2151#[derive(Clone)]
2152pub struct PushNdmsg {
2153 pub(crate) buf: [u8; 12usize],
2154}
2155#[doc = "Create zero-initialized struct"]
2156impl Default for PushNdmsg {
2157 fn default() -> Self {
2158 Self {
2159 buf: [0u8; 12usize],
2160 }
2161 }
2162}
2163impl PushNdmsg {
2164 #[doc = "Create zero-initialized struct"]
2165 pub fn new() -> Self {
2166 Default::default()
2167 }
2168 #[doc = "Copy from contents from other slice"]
2169 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2170 if other.len() != Self::len() {
2171 return None;
2172 }
2173 let mut buf = [0u8; Self::len()];
2174 buf.clone_from_slice(other);
2175 Some(Self { buf })
2176 }
2177 pub fn as_slice(&self) -> &[u8] {
2178 &self.buf
2179 }
2180 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2181 &mut self.buf
2182 }
2183 pub const fn len() -> usize {
2184 12usize
2185 }
2186 pub fn ndm_family(&self) -> u8 {
2187 parse_u8(&self.buf[0usize..1usize]).unwrap()
2188 }
2189 pub fn set_ndm_family(&mut self, value: u8) {
2190 self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
2191 }
2192 pub fn ndm_ifindex(&self) -> i32 {
2193 parse_i32(&self.buf[4usize..8usize]).unwrap()
2194 }
2195 pub fn set_ndm_ifindex(&mut self, value: i32) {
2196 self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2197 }
2198 #[doc = "Associated type: \"NudState\" (enum)"]
2199 pub fn ndm_state(&self) -> u16 {
2200 parse_u16(&self.buf[8usize..10usize]).unwrap()
2201 }
2202 #[doc = "Associated type: \"NudState\" (enum)"]
2203 pub fn set_ndm_state(&mut self, value: u16) {
2204 self.buf[8usize..10usize].copy_from_slice(&value.to_ne_bytes())
2205 }
2206 #[doc = "Associated type: \"NtfFlags\" (enum)"]
2207 pub fn ndm_flags(&self) -> u8 {
2208 parse_u8(&self.buf[10usize..11usize]).unwrap()
2209 }
2210 #[doc = "Associated type: \"NtfFlags\" (enum)"]
2211 pub fn set_ndm_flags(&mut self, value: u8) {
2212 self.buf[10usize..11usize].copy_from_slice(&value.to_ne_bytes())
2213 }
2214 #[doc = "Associated type: \"RtmType\" (enum)"]
2215 pub fn ndm_type(&self) -> u8 {
2216 parse_u8(&self.buf[11usize..12usize]).unwrap()
2217 }
2218 #[doc = "Associated type: \"RtmType\" (enum)"]
2219 pub fn set_ndm_type(&mut self, value: u8) {
2220 self.buf[11usize..12usize].copy_from_slice(&value.to_ne_bytes())
2221 }
2222}
2223impl std::fmt::Debug for PushNdmsg {
2224 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2225 fmt.debug_struct("Ndmsg")
2226 .field("ndm_family", &self.ndm_family())
2227 .field("ndm_ifindex", &self.ndm_ifindex())
2228 .field("ndm_state", &self.ndm_state())
2229 .field("ndm_flags", &self.ndm_flags())
2230 .field("ndm_type", &self.ndm_type())
2231 .finish()
2232 }
2233}
2234#[derive(Clone)]
2235pub struct PushNdtmsg {
2236 pub(crate) buf: [u8; 4usize],
2237}
2238#[doc = "Create zero-initialized struct"]
2239impl Default for PushNdtmsg {
2240 fn default() -> Self {
2241 Self { buf: [0u8; 4usize] }
2242 }
2243}
2244impl PushNdtmsg {
2245 #[doc = "Create zero-initialized struct"]
2246 pub fn new() -> Self {
2247 Default::default()
2248 }
2249 #[doc = "Copy from contents from other slice"]
2250 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2251 if other.len() != Self::len() {
2252 return None;
2253 }
2254 let mut buf = [0u8; Self::len()];
2255 buf.clone_from_slice(other);
2256 Some(Self { buf })
2257 }
2258 pub fn as_slice(&self) -> &[u8] {
2259 &self.buf
2260 }
2261 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2262 &mut self.buf
2263 }
2264 pub const fn len() -> usize {
2265 4usize
2266 }
2267 pub fn family(&self) -> u8 {
2268 parse_u8(&self.buf[0usize..1usize]).unwrap()
2269 }
2270 pub fn set_family(&mut self, value: u8) {
2271 self.buf[0usize..1usize].copy_from_slice(&value.to_ne_bytes())
2272 }
2273}
2274impl std::fmt::Debug for PushNdtmsg {
2275 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2276 fmt.debug_struct("Ndtmsg")
2277 .field("family", &self.family())
2278 .finish()
2279 }
2280}
2281#[derive(Clone)]
2282pub struct PushNdaCacheinfo {
2283 pub(crate) buf: [u8; 16usize],
2284}
2285#[doc = "Create zero-initialized struct"]
2286impl Default for PushNdaCacheinfo {
2287 fn default() -> Self {
2288 Self {
2289 buf: [0u8; 16usize],
2290 }
2291 }
2292}
2293impl PushNdaCacheinfo {
2294 #[doc = "Create zero-initialized struct"]
2295 pub fn new() -> Self {
2296 Default::default()
2297 }
2298 #[doc = "Copy from contents from other slice"]
2299 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2300 if other.len() != Self::len() {
2301 return None;
2302 }
2303 let mut buf = [0u8; Self::len()];
2304 buf.clone_from_slice(other);
2305 Some(Self { buf })
2306 }
2307 pub fn as_slice(&self) -> &[u8] {
2308 &self.buf
2309 }
2310 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2311 &mut self.buf
2312 }
2313 pub const fn len() -> usize {
2314 16usize
2315 }
2316 pub fn confirmed(&self) -> u32 {
2317 parse_u32(&self.buf[0usize..4usize]).unwrap()
2318 }
2319 pub fn set_confirmed(&mut self, value: u32) {
2320 self.buf[0usize..4usize].copy_from_slice(&value.to_ne_bytes())
2321 }
2322 pub fn used(&self) -> u32 {
2323 parse_u32(&self.buf[4usize..8usize]).unwrap()
2324 }
2325 pub fn set_used(&mut self, value: u32) {
2326 self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2327 }
2328 pub fn updated(&self) -> u32 {
2329 parse_u32(&self.buf[8usize..12usize]).unwrap()
2330 }
2331 pub fn set_updated(&mut self, value: u32) {
2332 self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
2333 }
2334 pub fn refcnt(&self) -> u32 {
2335 parse_u32(&self.buf[12usize..16usize]).unwrap()
2336 }
2337 pub fn set_refcnt(&mut self, value: u32) {
2338 self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
2339 }
2340}
2341impl std::fmt::Debug for PushNdaCacheinfo {
2342 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2343 fmt.debug_struct("NdaCacheinfo")
2344 .field("confirmed", &self.confirmed())
2345 .field("used", &self.used())
2346 .field("updated", &self.updated())
2347 .field("refcnt", &self.refcnt())
2348 .finish()
2349 }
2350}
2351#[derive(Clone)]
2352pub struct PushNdtConfig {
2353 pub(crate) buf: [u8; 32usize],
2354}
2355#[doc = "Create zero-initialized struct"]
2356impl Default for PushNdtConfig {
2357 fn default() -> Self {
2358 Self {
2359 buf: [0u8; 32usize],
2360 }
2361 }
2362}
2363impl PushNdtConfig {
2364 #[doc = "Create zero-initialized struct"]
2365 pub fn new() -> Self {
2366 Default::default()
2367 }
2368 #[doc = "Copy from contents from other slice"]
2369 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2370 if other.len() != Self::len() {
2371 return None;
2372 }
2373 let mut buf = [0u8; Self::len()];
2374 buf.clone_from_slice(other);
2375 Some(Self { buf })
2376 }
2377 pub fn as_slice(&self) -> &[u8] {
2378 &self.buf
2379 }
2380 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2381 &mut self.buf
2382 }
2383 pub const fn len() -> usize {
2384 32usize
2385 }
2386 pub fn key_len(&self) -> u16 {
2387 parse_u16(&self.buf[0usize..2usize]).unwrap()
2388 }
2389 pub fn set_key_len(&mut self, value: u16) {
2390 self.buf[0usize..2usize].copy_from_slice(&value.to_ne_bytes())
2391 }
2392 pub fn entry_size(&self) -> u16 {
2393 parse_u16(&self.buf[2usize..4usize]).unwrap()
2394 }
2395 pub fn set_entry_size(&mut self, value: u16) {
2396 self.buf[2usize..4usize].copy_from_slice(&value.to_ne_bytes())
2397 }
2398 pub fn entries(&self) -> u32 {
2399 parse_u32(&self.buf[4usize..8usize]).unwrap()
2400 }
2401 pub fn set_entries(&mut self, value: u32) {
2402 self.buf[4usize..8usize].copy_from_slice(&value.to_ne_bytes())
2403 }
2404 pub fn last_flush(&self) -> u32 {
2405 parse_u32(&self.buf[8usize..12usize]).unwrap()
2406 }
2407 pub fn set_last_flush(&mut self, value: u32) {
2408 self.buf[8usize..12usize].copy_from_slice(&value.to_ne_bytes())
2409 }
2410 pub fn last_rand(&self) -> u32 {
2411 parse_u32(&self.buf[12usize..16usize]).unwrap()
2412 }
2413 pub fn set_last_rand(&mut self, value: u32) {
2414 self.buf[12usize..16usize].copy_from_slice(&value.to_ne_bytes())
2415 }
2416 pub fn hash_rnd(&self) -> u32 {
2417 parse_u32(&self.buf[16usize..20usize]).unwrap()
2418 }
2419 pub fn set_hash_rnd(&mut self, value: u32) {
2420 self.buf[16usize..20usize].copy_from_slice(&value.to_ne_bytes())
2421 }
2422 pub fn hash_mask(&self) -> u32 {
2423 parse_u32(&self.buf[20usize..24usize]).unwrap()
2424 }
2425 pub fn set_hash_mask(&mut self, value: u32) {
2426 self.buf[20usize..24usize].copy_from_slice(&value.to_ne_bytes())
2427 }
2428 pub fn hash_chain_gc(&self) -> u32 {
2429 parse_u32(&self.buf[24usize..28usize]).unwrap()
2430 }
2431 pub fn set_hash_chain_gc(&mut self, value: u32) {
2432 self.buf[24usize..28usize].copy_from_slice(&value.to_ne_bytes())
2433 }
2434 pub fn proxy_qlen(&self) -> u32 {
2435 parse_u32(&self.buf[28usize..32usize]).unwrap()
2436 }
2437 pub fn set_proxy_qlen(&mut self, value: u32) {
2438 self.buf[28usize..32usize].copy_from_slice(&value.to_ne_bytes())
2439 }
2440}
2441impl std::fmt::Debug for PushNdtConfig {
2442 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2443 fmt.debug_struct("NdtConfig")
2444 .field("key_len", &self.key_len())
2445 .field("entry_size", &self.entry_size())
2446 .field("entries", &self.entries())
2447 .field("last_flush", &self.last_flush())
2448 .field("last_rand", &self.last_rand())
2449 .field("hash_rnd", &self.hash_rnd())
2450 .field("hash_mask", &self.hash_mask())
2451 .field("hash_chain_gc", &self.hash_chain_gc())
2452 .field("proxy_qlen", &self.proxy_qlen())
2453 .finish()
2454 }
2455}
2456#[derive(Clone)]
2457pub struct PushNdtStats {
2458 pub(crate) buf: [u8; 88usize],
2459}
2460#[doc = "Create zero-initialized struct"]
2461impl Default for PushNdtStats {
2462 fn default() -> Self {
2463 Self {
2464 buf: [0u8; 88usize],
2465 }
2466 }
2467}
2468impl PushNdtStats {
2469 #[doc = "Create zero-initialized struct"]
2470 pub fn new() -> Self {
2471 Default::default()
2472 }
2473 #[doc = "Copy from contents from other slice"]
2474 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
2475 if other.len() != Self::len() {
2476 return None;
2477 }
2478 let mut buf = [0u8; Self::len()];
2479 buf.clone_from_slice(other);
2480 Some(Self { buf })
2481 }
2482 pub fn as_slice(&self) -> &[u8] {
2483 &self.buf
2484 }
2485 pub fn as_mut_slice(&mut self) -> &mut [u8] {
2486 &mut self.buf
2487 }
2488 pub const fn len() -> usize {
2489 88usize
2490 }
2491 pub fn allocs(&self) -> u64 {
2492 parse_u64(&self.buf[0usize..8usize]).unwrap()
2493 }
2494 pub fn set_allocs(&mut self, value: u64) {
2495 self.buf[0usize..8usize].copy_from_slice(&value.to_ne_bytes())
2496 }
2497 pub fn destroys(&self) -> u64 {
2498 parse_u64(&self.buf[8usize..16usize]).unwrap()
2499 }
2500 pub fn set_destroys(&mut self, value: u64) {
2501 self.buf[8usize..16usize].copy_from_slice(&value.to_ne_bytes())
2502 }
2503 pub fn hash_grows(&self) -> u64 {
2504 parse_u64(&self.buf[16usize..24usize]).unwrap()
2505 }
2506 pub fn set_hash_grows(&mut self, value: u64) {
2507 self.buf[16usize..24usize].copy_from_slice(&value.to_ne_bytes())
2508 }
2509 pub fn res_failed(&self) -> u64 {
2510 parse_u64(&self.buf[24usize..32usize]).unwrap()
2511 }
2512 pub fn set_res_failed(&mut self, value: u64) {
2513 self.buf[24usize..32usize].copy_from_slice(&value.to_ne_bytes())
2514 }
2515 pub fn lookups(&self) -> u64 {
2516 parse_u64(&self.buf[32usize..40usize]).unwrap()
2517 }
2518 pub fn set_lookups(&mut self, value: u64) {
2519 self.buf[32usize..40usize].copy_from_slice(&value.to_ne_bytes())
2520 }
2521 pub fn hits(&self) -> u64 {
2522 parse_u64(&self.buf[40usize..48usize]).unwrap()
2523 }
2524 pub fn set_hits(&mut self, value: u64) {
2525 self.buf[40usize..48usize].copy_from_slice(&value.to_ne_bytes())
2526 }
2527 pub fn rcv_probes_mcast(&self) -> u64 {
2528 parse_u64(&self.buf[48usize..56usize]).unwrap()
2529 }
2530 pub fn set_rcv_probes_mcast(&mut self, value: u64) {
2531 self.buf[48usize..56usize].copy_from_slice(&value.to_ne_bytes())
2532 }
2533 pub fn rcv_probes_ucast(&self) -> u64 {
2534 parse_u64(&self.buf[56usize..64usize]).unwrap()
2535 }
2536 pub fn set_rcv_probes_ucast(&mut self, value: u64) {
2537 self.buf[56usize..64usize].copy_from_slice(&value.to_ne_bytes())
2538 }
2539 pub fn periodic_gc_runs(&self) -> u64 {
2540 parse_u64(&self.buf[64usize..72usize]).unwrap()
2541 }
2542 pub fn set_periodic_gc_runs(&mut self, value: u64) {
2543 self.buf[64usize..72usize].copy_from_slice(&value.to_ne_bytes())
2544 }
2545 pub fn forced_gc_runs(&self) -> u64 {
2546 parse_u64(&self.buf[72usize..80usize]).unwrap()
2547 }
2548 pub fn set_forced_gc_runs(&mut self, value: u64) {
2549 self.buf[72usize..80usize].copy_from_slice(&value.to_ne_bytes())
2550 }
2551 pub fn table_fulls(&self) -> u64 {
2552 parse_u64(&self.buf[80usize..88usize]).unwrap()
2553 }
2554 pub fn set_table_fulls(&mut self, value: u64) {
2555 self.buf[80usize..88usize].copy_from_slice(&value.to_ne_bytes())
2556 }
2557}
2558impl std::fmt::Debug for PushNdtStats {
2559 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2560 fmt.debug_struct("NdtStats")
2561 .field("allocs", &self.allocs())
2562 .field("destroys", &self.destroys())
2563 .field("hash_grows", &self.hash_grows())
2564 .field("res_failed", &self.res_failed())
2565 .field("lookups", &self.lookups())
2566 .field("hits", &self.hits())
2567 .field("rcv_probes_mcast", &self.rcv_probes_mcast())
2568 .field("rcv_probes_ucast", &self.rcv_probes_ucast())
2569 .field("periodic_gc_runs", &self.periodic_gc_runs())
2570 .field("forced_gc_runs", &self.forced_gc_runs())
2571 .field("table_fulls", &self.table_fulls())
2572 .finish()
2573 }
2574}
2575#[doc = "Add new neighbour entry"]
2576pub struct PushOpNewneighDoRequest<Prev: Rec> {
2577 pub(crate) prev: Option<Prev>,
2578 pub(crate) header_offset: Option<usize>,
2579}
2580impl<Prev: Rec> Rec for PushOpNewneighDoRequest<Prev> {
2581 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
2582 self.prev.as_mut().unwrap().as_rec_mut()
2583 }
2584}
2585impl<Prev: Rec> PushOpNewneighDoRequest<Prev> {
2586 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
2587 Self::write_header(&mut prev, header);
2588 Self::new_without_header(prev)
2589 }
2590 fn new_without_header(prev: Prev) -> Self {
2591 Self {
2592 prev: Some(prev),
2593 header_offset: None,
2594 }
2595 }
2596 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
2597 prev.as_rec_mut().extend(header.as_slice());
2598 }
2599 pub fn end_nested(mut self) -> Prev {
2600 let mut prev = self.prev.take().unwrap();
2601 if let Some(header_offset) = &self.header_offset {
2602 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2603 }
2604 prev
2605 }
2606 pub fn push_dst(mut self, value: &[u8]) -> Self {
2607 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
2608 self.as_rec_mut().extend(value);
2609 self
2610 }
2611 pub fn push_lladdr(mut self, value: &[u8]) -> Self {
2612 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
2613 self.as_rec_mut().extend(value);
2614 self
2615 }
2616 pub fn push_probes(mut self, value: u32) -> Self {
2617 push_header(self.as_rec_mut(), 4u16, 4 as u16);
2618 self.as_rec_mut().extend(value.to_ne_bytes());
2619 self
2620 }
2621 pub fn push_vlan(mut self, value: u16) -> Self {
2622 push_header(self.as_rec_mut(), 5u16, 2 as u16);
2623 self.as_rec_mut().extend(value.to_ne_bytes());
2624 self
2625 }
2626 pub fn push_port(mut self, value: u16) -> Self {
2627 push_header(self.as_rec_mut(), 6u16, 2 as u16);
2628 self.as_rec_mut().extend(value.to_ne_bytes());
2629 self
2630 }
2631 pub fn push_vni(mut self, value: u32) -> Self {
2632 push_header(self.as_rec_mut(), 7u16, 4 as u16);
2633 self.as_rec_mut().extend(value.to_ne_bytes());
2634 self
2635 }
2636 pub fn push_ifindex(mut self, value: u32) -> Self {
2637 push_header(self.as_rec_mut(), 8u16, 4 as u16);
2638 self.as_rec_mut().extend(value.to_ne_bytes());
2639 self
2640 }
2641 pub fn push_master(mut self, value: u32) -> Self {
2642 push_header(self.as_rec_mut(), 9u16, 4 as u16);
2643 self.as_rec_mut().extend(value.to_ne_bytes());
2644 self
2645 }
2646 pub fn push_protocol(mut self, value: u8) -> Self {
2647 push_header(self.as_rec_mut(), 12u16, 1 as u16);
2648 self.as_rec_mut().extend(value.to_ne_bytes());
2649 self
2650 }
2651 pub fn push_nh_id(mut self, value: u32) -> Self {
2652 push_header(self.as_rec_mut(), 13u16, 4 as u16);
2653 self.as_rec_mut().extend(value.to_ne_bytes());
2654 self
2655 }
2656 pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
2657 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
2658 self.as_rec_mut().extend(value);
2659 self
2660 }
2661 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
2662 pub fn push_flags_ext(mut self, value: u32) -> Self {
2663 push_header(self.as_rec_mut(), 15u16, 4 as u16);
2664 self.as_rec_mut().extend(value.to_ne_bytes());
2665 self
2666 }
2667}
2668impl<Prev: Rec> Drop for PushOpNewneighDoRequest<Prev> {
2669 fn drop(&mut self) {
2670 if let Some(prev) = &mut self.prev {
2671 if let Some(header_offset) = &self.header_offset {
2672 finalize_nested_header(prev.as_rec_mut(), *header_offset);
2673 }
2674 }
2675 }
2676}
2677#[doc = "Add new neighbour entry"]
2678#[derive(Clone)]
2679pub enum OpNewneighDoRequest<'a> {
2680 Dst(&'a [u8]),
2681 Lladdr(&'a [u8]),
2682 Probes(u32),
2683 Vlan(u16),
2684 Port(u16),
2685 Vni(u32),
2686 Ifindex(u32),
2687 Master(u32),
2688 Protocol(u8),
2689 NhId(u32),
2690 FdbExtAttrs(&'a [u8]),
2691 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
2692 FlagsExt(u32),
2693}
2694impl<'a> IterableOpNewneighDoRequest<'a> {
2695 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
2696 let mut iter = self.clone();
2697 iter.pos = 0;
2698 for attr in iter {
2699 if let OpNewneighDoRequest::Dst(val) = attr? {
2700 return Ok(val);
2701 }
2702 }
2703 Err(ErrorContext::new_missing(
2704 "OpNewneighDoRequest",
2705 "Dst",
2706 self.orig_loc,
2707 self.buf.as_ptr() as usize,
2708 ))
2709 }
2710 pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
2711 let mut iter = self.clone();
2712 iter.pos = 0;
2713 for attr in iter {
2714 if let OpNewneighDoRequest::Lladdr(val) = attr? {
2715 return Ok(val);
2716 }
2717 }
2718 Err(ErrorContext::new_missing(
2719 "OpNewneighDoRequest",
2720 "Lladdr",
2721 self.orig_loc,
2722 self.buf.as_ptr() as usize,
2723 ))
2724 }
2725 pub fn get_probes(&self) -> Result<u32, ErrorContext> {
2726 let mut iter = self.clone();
2727 iter.pos = 0;
2728 for attr in iter {
2729 if let OpNewneighDoRequest::Probes(val) = attr? {
2730 return Ok(val);
2731 }
2732 }
2733 Err(ErrorContext::new_missing(
2734 "OpNewneighDoRequest",
2735 "Probes",
2736 self.orig_loc,
2737 self.buf.as_ptr() as usize,
2738 ))
2739 }
2740 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
2741 let mut iter = self.clone();
2742 iter.pos = 0;
2743 for attr in iter {
2744 if let OpNewneighDoRequest::Vlan(val) = attr? {
2745 return Ok(val);
2746 }
2747 }
2748 Err(ErrorContext::new_missing(
2749 "OpNewneighDoRequest",
2750 "Vlan",
2751 self.orig_loc,
2752 self.buf.as_ptr() as usize,
2753 ))
2754 }
2755 pub fn get_port(&self) -> Result<u16, ErrorContext> {
2756 let mut iter = self.clone();
2757 iter.pos = 0;
2758 for attr in iter {
2759 if let OpNewneighDoRequest::Port(val) = attr? {
2760 return Ok(val);
2761 }
2762 }
2763 Err(ErrorContext::new_missing(
2764 "OpNewneighDoRequest",
2765 "Port",
2766 self.orig_loc,
2767 self.buf.as_ptr() as usize,
2768 ))
2769 }
2770 pub fn get_vni(&self) -> Result<u32, ErrorContext> {
2771 let mut iter = self.clone();
2772 iter.pos = 0;
2773 for attr in iter {
2774 if let OpNewneighDoRequest::Vni(val) = attr? {
2775 return Ok(val);
2776 }
2777 }
2778 Err(ErrorContext::new_missing(
2779 "OpNewneighDoRequest",
2780 "Vni",
2781 self.orig_loc,
2782 self.buf.as_ptr() as usize,
2783 ))
2784 }
2785 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
2786 let mut iter = self.clone();
2787 iter.pos = 0;
2788 for attr in iter {
2789 if let OpNewneighDoRequest::Ifindex(val) = attr? {
2790 return Ok(val);
2791 }
2792 }
2793 Err(ErrorContext::new_missing(
2794 "OpNewneighDoRequest",
2795 "Ifindex",
2796 self.orig_loc,
2797 self.buf.as_ptr() as usize,
2798 ))
2799 }
2800 pub fn get_master(&self) -> Result<u32, ErrorContext> {
2801 let mut iter = self.clone();
2802 iter.pos = 0;
2803 for attr in iter {
2804 if let OpNewneighDoRequest::Master(val) = attr? {
2805 return Ok(val);
2806 }
2807 }
2808 Err(ErrorContext::new_missing(
2809 "OpNewneighDoRequest",
2810 "Master",
2811 self.orig_loc,
2812 self.buf.as_ptr() as usize,
2813 ))
2814 }
2815 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
2816 let mut iter = self.clone();
2817 iter.pos = 0;
2818 for attr in iter {
2819 if let OpNewneighDoRequest::Protocol(val) = attr? {
2820 return Ok(val);
2821 }
2822 }
2823 Err(ErrorContext::new_missing(
2824 "OpNewneighDoRequest",
2825 "Protocol",
2826 self.orig_loc,
2827 self.buf.as_ptr() as usize,
2828 ))
2829 }
2830 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
2831 let mut iter = self.clone();
2832 iter.pos = 0;
2833 for attr in iter {
2834 if let OpNewneighDoRequest::NhId(val) = attr? {
2835 return Ok(val);
2836 }
2837 }
2838 Err(ErrorContext::new_missing(
2839 "OpNewneighDoRequest",
2840 "NhId",
2841 self.orig_loc,
2842 self.buf.as_ptr() as usize,
2843 ))
2844 }
2845 pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
2846 let mut iter = self.clone();
2847 iter.pos = 0;
2848 for attr in iter {
2849 if let OpNewneighDoRequest::FdbExtAttrs(val) = attr? {
2850 return Ok(val);
2851 }
2852 }
2853 Err(ErrorContext::new_missing(
2854 "OpNewneighDoRequest",
2855 "FdbExtAttrs",
2856 self.orig_loc,
2857 self.buf.as_ptr() as usize,
2858 ))
2859 }
2860 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
2861 pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
2862 let mut iter = self.clone();
2863 iter.pos = 0;
2864 for attr in iter {
2865 if let OpNewneighDoRequest::FlagsExt(val) = attr? {
2866 return Ok(val);
2867 }
2868 }
2869 Err(ErrorContext::new_missing(
2870 "OpNewneighDoRequest",
2871 "FlagsExt",
2872 self.orig_loc,
2873 self.buf.as_ptr() as usize,
2874 ))
2875 }
2876}
2877impl<'a> OpNewneighDoRequest<'a> {
2878 pub fn new(buf: &'a [u8]) -> (PushNdmsg, IterableOpNewneighDoRequest<'a>) {
2879 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
2880 (
2881 PushNdmsg::new_from_slice(header).unwrap_or_default(),
2882 IterableOpNewneighDoRequest::with_loc(attrs, buf.as_ptr() as usize),
2883 )
2884 }
2885 fn attr_from_type(r#type: u16) -> Option<&'static str> {
2886 NeighbourAttrs::attr_from_type(r#type)
2887 }
2888}
2889#[derive(Clone, Copy, Default)]
2890pub struct IterableOpNewneighDoRequest<'a> {
2891 buf: &'a [u8],
2892 pos: usize,
2893 orig_loc: usize,
2894}
2895impl<'a> IterableOpNewneighDoRequest<'a> {
2896 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
2897 Self {
2898 buf,
2899 pos: 0,
2900 orig_loc,
2901 }
2902 }
2903 pub fn get_buf(&self) -> &'a [u8] {
2904 self.buf
2905 }
2906}
2907impl<'a> Iterator for IterableOpNewneighDoRequest<'a> {
2908 type Item = Result<OpNewneighDoRequest<'a>, ErrorContext>;
2909 fn next(&mut self) -> Option<Self::Item> {
2910 if self.buf.len() == self.pos {
2911 return None;
2912 }
2913 let pos = self.pos;
2914 let mut r#type = None;
2915 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
2916 r#type = Some(header.r#type);
2917 let res = match header.r#type {
2918 1u16 => OpNewneighDoRequest::Dst({
2919 let res = Some(next);
2920 let Some(val) = res else { break };
2921 val
2922 }),
2923 2u16 => OpNewneighDoRequest::Lladdr({
2924 let res = Some(next);
2925 let Some(val) = res else { break };
2926 val
2927 }),
2928 4u16 => OpNewneighDoRequest::Probes({
2929 let res = parse_u32(next);
2930 let Some(val) = res else { break };
2931 val
2932 }),
2933 5u16 => OpNewneighDoRequest::Vlan({
2934 let res = parse_u16(next);
2935 let Some(val) = res else { break };
2936 val
2937 }),
2938 6u16 => OpNewneighDoRequest::Port({
2939 let res = parse_u16(next);
2940 let Some(val) = res else { break };
2941 val
2942 }),
2943 7u16 => OpNewneighDoRequest::Vni({
2944 let res = parse_u32(next);
2945 let Some(val) = res else { break };
2946 val
2947 }),
2948 8u16 => OpNewneighDoRequest::Ifindex({
2949 let res = parse_u32(next);
2950 let Some(val) = res else { break };
2951 val
2952 }),
2953 9u16 => OpNewneighDoRequest::Master({
2954 let res = parse_u32(next);
2955 let Some(val) = res else { break };
2956 val
2957 }),
2958 12u16 => OpNewneighDoRequest::Protocol({
2959 let res = parse_u8(next);
2960 let Some(val) = res else { break };
2961 val
2962 }),
2963 13u16 => OpNewneighDoRequest::NhId({
2964 let res = parse_u32(next);
2965 let Some(val) = res else { break };
2966 val
2967 }),
2968 14u16 => OpNewneighDoRequest::FdbExtAttrs({
2969 let res = Some(next);
2970 let Some(val) = res else { break };
2971 val
2972 }),
2973 15u16 => OpNewneighDoRequest::FlagsExt({
2974 let res = parse_u32(next);
2975 let Some(val) = res else { break };
2976 val
2977 }),
2978 n => {
2979 if cfg!(any(test, feature = "deny-unknown-attrs")) {
2980 break;
2981 } else {
2982 continue;
2983 }
2984 }
2985 };
2986 return Some(Ok(res));
2987 }
2988 Some(Err(ErrorContext::new(
2989 "OpNewneighDoRequest",
2990 r#type.and_then(|t| OpNewneighDoRequest::attr_from_type(t)),
2991 self.orig_loc,
2992 self.buf.as_ptr().wrapping_add(pos) as usize,
2993 )))
2994 }
2995}
2996impl<'a> std::fmt::Debug for IterableOpNewneighDoRequest<'_> {
2997 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2998 let mut fmt = f.debug_struct("OpNewneighDoRequest");
2999 for attr in self.clone() {
3000 let attr = match attr {
3001 Ok(a) => a,
3002 Err(err) => {
3003 fmt.finish()?;
3004 f.write_str("Err(")?;
3005 err.fmt(f)?;
3006 return f.write_str(")");
3007 }
3008 };
3009 match attr {
3010 OpNewneighDoRequest::Dst(val) => fmt.field("Dst", &val),
3011 OpNewneighDoRequest::Lladdr(val) => fmt.field("Lladdr", &val),
3012 OpNewneighDoRequest::Probes(val) => fmt.field("Probes", &val),
3013 OpNewneighDoRequest::Vlan(val) => fmt.field("Vlan", &val),
3014 OpNewneighDoRequest::Port(val) => fmt.field("Port", &val),
3015 OpNewneighDoRequest::Vni(val) => fmt.field("Vni", &val),
3016 OpNewneighDoRequest::Ifindex(val) => fmt.field("Ifindex", &val),
3017 OpNewneighDoRequest::Master(val) => fmt.field("Master", &val),
3018 OpNewneighDoRequest::Protocol(val) => fmt.field("Protocol", &val),
3019 OpNewneighDoRequest::NhId(val) => fmt.field("NhId", &val),
3020 OpNewneighDoRequest::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
3021 OpNewneighDoRequest::FlagsExt(val) => fmt.field(
3022 "FlagsExt",
3023 &FormatFlags(val.into(), NtfExtFlags::from_value),
3024 ),
3025 };
3026 }
3027 fmt.finish()
3028 }
3029}
3030impl IterableOpNewneighDoRequest<'_> {
3031 pub fn lookup_attr(
3032 &self,
3033 offset: usize,
3034 missing_type: Option<u16>,
3035 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3036 let mut stack = Vec::new();
3037 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3038 if cur == offset + PushNdmsg::len() {
3039 stack.push(("OpNewneighDoRequest", offset));
3040 return (
3041 stack,
3042 missing_type.and_then(|t| OpNewneighDoRequest::attr_from_type(t)),
3043 );
3044 }
3045 if cur > offset || cur + self.buf.len() < offset {
3046 return (stack, None);
3047 }
3048 let mut attrs = self.clone();
3049 let mut last_off = cur + attrs.pos;
3050 while let Some(attr) = attrs.next() {
3051 let Ok(attr) = attr else { break };
3052 match attr {
3053 OpNewneighDoRequest::Dst(val) => {
3054 if last_off == offset {
3055 stack.push(("Dst", last_off));
3056 break;
3057 }
3058 }
3059 OpNewneighDoRequest::Lladdr(val) => {
3060 if last_off == offset {
3061 stack.push(("Lladdr", last_off));
3062 break;
3063 }
3064 }
3065 OpNewneighDoRequest::Probes(val) => {
3066 if last_off == offset {
3067 stack.push(("Probes", last_off));
3068 break;
3069 }
3070 }
3071 OpNewneighDoRequest::Vlan(val) => {
3072 if last_off == offset {
3073 stack.push(("Vlan", last_off));
3074 break;
3075 }
3076 }
3077 OpNewneighDoRequest::Port(val) => {
3078 if last_off == offset {
3079 stack.push(("Port", last_off));
3080 break;
3081 }
3082 }
3083 OpNewneighDoRequest::Vni(val) => {
3084 if last_off == offset {
3085 stack.push(("Vni", last_off));
3086 break;
3087 }
3088 }
3089 OpNewneighDoRequest::Ifindex(val) => {
3090 if last_off == offset {
3091 stack.push(("Ifindex", last_off));
3092 break;
3093 }
3094 }
3095 OpNewneighDoRequest::Master(val) => {
3096 if last_off == offset {
3097 stack.push(("Master", last_off));
3098 break;
3099 }
3100 }
3101 OpNewneighDoRequest::Protocol(val) => {
3102 if last_off == offset {
3103 stack.push(("Protocol", last_off));
3104 break;
3105 }
3106 }
3107 OpNewneighDoRequest::NhId(val) => {
3108 if last_off == offset {
3109 stack.push(("NhId", last_off));
3110 break;
3111 }
3112 }
3113 OpNewneighDoRequest::FdbExtAttrs(val) => {
3114 if last_off == offset {
3115 stack.push(("FdbExtAttrs", last_off));
3116 break;
3117 }
3118 }
3119 OpNewneighDoRequest::FlagsExt(val) => {
3120 if last_off == offset {
3121 stack.push(("FlagsExt", last_off));
3122 break;
3123 }
3124 }
3125 _ => {}
3126 };
3127 last_off = cur + attrs.pos;
3128 }
3129 if !stack.is_empty() {
3130 stack.push(("OpNewneighDoRequest", cur));
3131 }
3132 (stack, None)
3133 }
3134}
3135#[doc = "Add new neighbour entry"]
3136pub struct PushOpNewneighDoReply<Prev: Rec> {
3137 pub(crate) prev: Option<Prev>,
3138 pub(crate) header_offset: Option<usize>,
3139}
3140impl<Prev: Rec> Rec for PushOpNewneighDoReply<Prev> {
3141 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3142 self.prev.as_mut().unwrap().as_rec_mut()
3143 }
3144}
3145impl<Prev: Rec> PushOpNewneighDoReply<Prev> {
3146 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3147 Self::write_header(&mut prev, header);
3148 Self::new_without_header(prev)
3149 }
3150 fn new_without_header(prev: Prev) -> Self {
3151 Self {
3152 prev: Some(prev),
3153 header_offset: None,
3154 }
3155 }
3156 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3157 prev.as_rec_mut().extend(header.as_slice());
3158 }
3159 pub fn end_nested(mut self) -> Prev {
3160 let mut prev = self.prev.take().unwrap();
3161 if let Some(header_offset) = &self.header_offset {
3162 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3163 }
3164 prev
3165 }
3166}
3167impl<Prev: Rec> Drop for PushOpNewneighDoReply<Prev> {
3168 fn drop(&mut self) {
3169 if let Some(prev) = &mut self.prev {
3170 if let Some(header_offset) = &self.header_offset {
3171 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3172 }
3173 }
3174 }
3175}
3176#[doc = "Add new neighbour entry"]
3177#[derive(Clone)]
3178pub enum OpNewneighDoReply {}
3179impl<'a> IterableOpNewneighDoReply<'a> {}
3180impl OpNewneighDoReply {
3181 pub fn new(buf: &'_ [u8]) -> (PushNdmsg, IterableOpNewneighDoReply<'_>) {
3182 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3183 (
3184 PushNdmsg::new_from_slice(header).unwrap_or_default(),
3185 IterableOpNewneighDoReply::with_loc(attrs, buf.as_ptr() as usize),
3186 )
3187 }
3188 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3189 NeighbourAttrs::attr_from_type(r#type)
3190 }
3191}
3192#[derive(Clone, Copy, Default)]
3193pub struct IterableOpNewneighDoReply<'a> {
3194 buf: &'a [u8],
3195 pos: usize,
3196 orig_loc: usize,
3197}
3198impl<'a> IterableOpNewneighDoReply<'a> {
3199 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3200 Self {
3201 buf,
3202 pos: 0,
3203 orig_loc,
3204 }
3205 }
3206 pub fn get_buf(&self) -> &'a [u8] {
3207 self.buf
3208 }
3209}
3210impl<'a> Iterator for IterableOpNewneighDoReply<'a> {
3211 type Item = Result<OpNewneighDoReply, ErrorContext>;
3212 fn next(&mut self) -> Option<Self::Item> {
3213 if self.buf.len() == self.pos {
3214 return None;
3215 }
3216 let pos = self.pos;
3217 let mut r#type = None;
3218 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
3219 r#type = Some(header.r#type);
3220 let res = match header.r#type {
3221 n => {
3222 if cfg!(any(test, feature = "deny-unknown-attrs")) {
3223 break;
3224 } else {
3225 continue;
3226 }
3227 }
3228 };
3229 return Some(Ok(res));
3230 }
3231 Some(Err(ErrorContext::new(
3232 "OpNewneighDoReply",
3233 r#type.and_then(|t| OpNewneighDoReply::attr_from_type(t)),
3234 self.orig_loc,
3235 self.buf.as_ptr().wrapping_add(pos) as usize,
3236 )))
3237 }
3238}
3239impl std::fmt::Debug for IterableOpNewneighDoReply<'_> {
3240 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3241 let mut fmt = f.debug_struct("OpNewneighDoReply");
3242 for attr in self.clone() {
3243 let attr = match attr {
3244 Ok(a) => a,
3245 Err(err) => {
3246 fmt.finish()?;
3247 f.write_str("Err(")?;
3248 err.fmt(f)?;
3249 return f.write_str(")");
3250 }
3251 };
3252 match attr {};
3253 }
3254 fmt.finish()
3255 }
3256}
3257impl IterableOpNewneighDoReply<'_> {
3258 pub fn lookup_attr(
3259 &self,
3260 offset: usize,
3261 missing_type: Option<u16>,
3262 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3263 let mut stack = Vec::new();
3264 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3265 if cur == offset + PushNdmsg::len() {
3266 stack.push(("OpNewneighDoReply", offset));
3267 return (
3268 stack,
3269 missing_type.and_then(|t| OpNewneighDoReply::attr_from_type(t)),
3270 );
3271 }
3272 (stack, None)
3273 }
3274}
3275#[derive(Debug)]
3276pub struct RequestOpNewneighDoRequest<'r> {
3277 request: Request<'r>,
3278}
3279impl<'r> RequestOpNewneighDoRequest<'r> {
3280 pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
3281 PushOpNewneighDoRequest::write_header(&mut request.buf_mut(), header);
3282 Self { request: request }
3283 }
3284 pub fn encode(&mut self) -> PushOpNewneighDoRequest<&mut Vec<u8>> {
3285 PushOpNewneighDoRequest::new_without_header(self.request.buf_mut())
3286 }
3287 pub fn into_encoder(self) -> PushOpNewneighDoRequest<RequestBuf<'r>> {
3288 PushOpNewneighDoRequest::new_without_header(self.request.buf)
3289 }
3290}
3291impl NetlinkRequest for RequestOpNewneighDoRequest<'_> {
3292 type ReplyType<'buf> = (PushNdmsg, IterableOpNewneighDoReply<'buf>);
3293 fn protocol(&self) -> Protocol {
3294 Protocol::Raw {
3295 protonum: 0u16,
3296 request_type: 28u16,
3297 }
3298 }
3299 fn flags(&self) -> u16 {
3300 self.request.flags
3301 }
3302 fn payload(&self) -> &[u8] {
3303 self.request.buf()
3304 }
3305 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3306 OpNewneighDoReply::new(buf)
3307 }
3308 fn lookup(
3309 buf: &[u8],
3310 offset: usize,
3311 missing_type: Option<u16>,
3312 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3313 OpNewneighDoRequest::new(buf)
3314 .1
3315 .lookup_attr(offset, missing_type)
3316 }
3317}
3318#[doc = "Remove an existing neighbour entry"]
3319pub struct PushOpDelneighDoRequest<Prev: Rec> {
3320 pub(crate) prev: Option<Prev>,
3321 pub(crate) header_offset: Option<usize>,
3322}
3323impl<Prev: Rec> Rec for PushOpDelneighDoRequest<Prev> {
3324 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3325 self.prev.as_mut().unwrap().as_rec_mut()
3326 }
3327}
3328impl<Prev: Rec> PushOpDelneighDoRequest<Prev> {
3329 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3330 Self::write_header(&mut prev, header);
3331 Self::new_without_header(prev)
3332 }
3333 fn new_without_header(prev: Prev) -> Self {
3334 Self {
3335 prev: Some(prev),
3336 header_offset: None,
3337 }
3338 }
3339 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3340 prev.as_rec_mut().extend(header.as_slice());
3341 }
3342 pub fn end_nested(mut self) -> Prev {
3343 let mut prev = self.prev.take().unwrap();
3344 if let Some(header_offset) = &self.header_offset {
3345 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3346 }
3347 prev
3348 }
3349 pub fn push_dst(mut self, value: &[u8]) -> Self {
3350 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
3351 self.as_rec_mut().extend(value);
3352 self
3353 }
3354 pub fn push_ifindex(mut self, value: u32) -> Self {
3355 push_header(self.as_rec_mut(), 8u16, 4 as u16);
3356 self.as_rec_mut().extend(value.to_ne_bytes());
3357 self
3358 }
3359}
3360impl<Prev: Rec> Drop for PushOpDelneighDoRequest<Prev> {
3361 fn drop(&mut self) {
3362 if let Some(prev) = &mut self.prev {
3363 if let Some(header_offset) = &self.header_offset {
3364 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3365 }
3366 }
3367 }
3368}
3369#[doc = "Remove an existing neighbour entry"]
3370#[derive(Clone)]
3371pub enum OpDelneighDoRequest<'a> {
3372 Dst(&'a [u8]),
3373 Ifindex(u32),
3374}
3375impl<'a> IterableOpDelneighDoRequest<'a> {
3376 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
3377 let mut iter = self.clone();
3378 iter.pos = 0;
3379 for attr in iter {
3380 if let OpDelneighDoRequest::Dst(val) = attr? {
3381 return Ok(val);
3382 }
3383 }
3384 Err(ErrorContext::new_missing(
3385 "OpDelneighDoRequest",
3386 "Dst",
3387 self.orig_loc,
3388 self.buf.as_ptr() as usize,
3389 ))
3390 }
3391 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
3392 let mut iter = self.clone();
3393 iter.pos = 0;
3394 for attr in iter {
3395 if let OpDelneighDoRequest::Ifindex(val) = attr? {
3396 return Ok(val);
3397 }
3398 }
3399 Err(ErrorContext::new_missing(
3400 "OpDelneighDoRequest",
3401 "Ifindex",
3402 self.orig_loc,
3403 self.buf.as_ptr() as usize,
3404 ))
3405 }
3406}
3407impl<'a> OpDelneighDoRequest<'a> {
3408 pub fn new(buf: &'a [u8]) -> (PushNdmsg, IterableOpDelneighDoRequest<'a>) {
3409 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3410 (
3411 PushNdmsg::new_from_slice(header).unwrap_or_default(),
3412 IterableOpDelneighDoRequest::with_loc(attrs, buf.as_ptr() as usize),
3413 )
3414 }
3415 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3416 NeighbourAttrs::attr_from_type(r#type)
3417 }
3418}
3419#[derive(Clone, Copy, Default)]
3420pub struct IterableOpDelneighDoRequest<'a> {
3421 buf: &'a [u8],
3422 pos: usize,
3423 orig_loc: usize,
3424}
3425impl<'a> IterableOpDelneighDoRequest<'a> {
3426 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3427 Self {
3428 buf,
3429 pos: 0,
3430 orig_loc,
3431 }
3432 }
3433 pub fn get_buf(&self) -> &'a [u8] {
3434 self.buf
3435 }
3436}
3437impl<'a> Iterator for IterableOpDelneighDoRequest<'a> {
3438 type Item = Result<OpDelneighDoRequest<'a>, ErrorContext>;
3439 fn next(&mut self) -> Option<Self::Item> {
3440 if self.buf.len() == self.pos {
3441 return None;
3442 }
3443 let pos = self.pos;
3444 let mut r#type = None;
3445 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
3446 r#type = Some(header.r#type);
3447 let res = match header.r#type {
3448 1u16 => OpDelneighDoRequest::Dst({
3449 let res = Some(next);
3450 let Some(val) = res else { break };
3451 val
3452 }),
3453 8u16 => OpDelneighDoRequest::Ifindex({
3454 let res = parse_u32(next);
3455 let Some(val) = res else { break };
3456 val
3457 }),
3458 n => {
3459 if cfg!(any(test, feature = "deny-unknown-attrs")) {
3460 break;
3461 } else {
3462 continue;
3463 }
3464 }
3465 };
3466 return Some(Ok(res));
3467 }
3468 Some(Err(ErrorContext::new(
3469 "OpDelneighDoRequest",
3470 r#type.and_then(|t| OpDelneighDoRequest::attr_from_type(t)),
3471 self.orig_loc,
3472 self.buf.as_ptr().wrapping_add(pos) as usize,
3473 )))
3474 }
3475}
3476impl<'a> std::fmt::Debug for IterableOpDelneighDoRequest<'_> {
3477 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3478 let mut fmt = f.debug_struct("OpDelneighDoRequest");
3479 for attr in self.clone() {
3480 let attr = match attr {
3481 Ok(a) => a,
3482 Err(err) => {
3483 fmt.finish()?;
3484 f.write_str("Err(")?;
3485 err.fmt(f)?;
3486 return f.write_str(")");
3487 }
3488 };
3489 match attr {
3490 OpDelneighDoRequest::Dst(val) => fmt.field("Dst", &val),
3491 OpDelneighDoRequest::Ifindex(val) => fmt.field("Ifindex", &val),
3492 };
3493 }
3494 fmt.finish()
3495 }
3496}
3497impl IterableOpDelneighDoRequest<'_> {
3498 pub fn lookup_attr(
3499 &self,
3500 offset: usize,
3501 missing_type: Option<u16>,
3502 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3503 let mut stack = Vec::new();
3504 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3505 if cur == offset + PushNdmsg::len() {
3506 stack.push(("OpDelneighDoRequest", offset));
3507 return (
3508 stack,
3509 missing_type.and_then(|t| OpDelneighDoRequest::attr_from_type(t)),
3510 );
3511 }
3512 if cur > offset || cur + self.buf.len() < offset {
3513 return (stack, None);
3514 }
3515 let mut attrs = self.clone();
3516 let mut last_off = cur + attrs.pos;
3517 while let Some(attr) = attrs.next() {
3518 let Ok(attr) = attr else { break };
3519 match attr {
3520 OpDelneighDoRequest::Dst(val) => {
3521 if last_off == offset {
3522 stack.push(("Dst", last_off));
3523 break;
3524 }
3525 }
3526 OpDelneighDoRequest::Ifindex(val) => {
3527 if last_off == offset {
3528 stack.push(("Ifindex", last_off));
3529 break;
3530 }
3531 }
3532 _ => {}
3533 };
3534 last_off = cur + attrs.pos;
3535 }
3536 if !stack.is_empty() {
3537 stack.push(("OpDelneighDoRequest", cur));
3538 }
3539 (stack, None)
3540 }
3541}
3542#[doc = "Remove an existing neighbour entry"]
3543pub struct PushOpDelneighDoReply<Prev: Rec> {
3544 pub(crate) prev: Option<Prev>,
3545 pub(crate) header_offset: Option<usize>,
3546}
3547impl<Prev: Rec> Rec for PushOpDelneighDoReply<Prev> {
3548 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3549 self.prev.as_mut().unwrap().as_rec_mut()
3550 }
3551}
3552impl<Prev: Rec> PushOpDelneighDoReply<Prev> {
3553 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3554 Self::write_header(&mut prev, header);
3555 Self::new_without_header(prev)
3556 }
3557 fn new_without_header(prev: Prev) -> Self {
3558 Self {
3559 prev: Some(prev),
3560 header_offset: None,
3561 }
3562 }
3563 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3564 prev.as_rec_mut().extend(header.as_slice());
3565 }
3566 pub fn end_nested(mut self) -> Prev {
3567 let mut prev = self.prev.take().unwrap();
3568 if let Some(header_offset) = &self.header_offset {
3569 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3570 }
3571 prev
3572 }
3573}
3574impl<Prev: Rec> Drop for PushOpDelneighDoReply<Prev> {
3575 fn drop(&mut self) {
3576 if let Some(prev) = &mut self.prev {
3577 if let Some(header_offset) = &self.header_offset {
3578 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3579 }
3580 }
3581 }
3582}
3583#[doc = "Remove an existing neighbour entry"]
3584#[derive(Clone)]
3585pub enum OpDelneighDoReply {}
3586impl<'a> IterableOpDelneighDoReply<'a> {}
3587impl OpDelneighDoReply {
3588 pub fn new(buf: &'_ [u8]) -> (PushNdmsg, IterableOpDelneighDoReply<'_>) {
3589 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3590 (
3591 PushNdmsg::new_from_slice(header).unwrap_or_default(),
3592 IterableOpDelneighDoReply::with_loc(attrs, buf.as_ptr() as usize),
3593 )
3594 }
3595 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3596 NeighbourAttrs::attr_from_type(r#type)
3597 }
3598}
3599#[derive(Clone, Copy, Default)]
3600pub struct IterableOpDelneighDoReply<'a> {
3601 buf: &'a [u8],
3602 pos: usize,
3603 orig_loc: usize,
3604}
3605impl<'a> IterableOpDelneighDoReply<'a> {
3606 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3607 Self {
3608 buf,
3609 pos: 0,
3610 orig_loc,
3611 }
3612 }
3613 pub fn get_buf(&self) -> &'a [u8] {
3614 self.buf
3615 }
3616}
3617impl<'a> Iterator for IterableOpDelneighDoReply<'a> {
3618 type Item = Result<OpDelneighDoReply, ErrorContext>;
3619 fn next(&mut self) -> Option<Self::Item> {
3620 if self.buf.len() == self.pos {
3621 return None;
3622 }
3623 let pos = self.pos;
3624 let mut r#type = None;
3625 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
3626 r#type = Some(header.r#type);
3627 let res = match header.r#type {
3628 n => {
3629 if cfg!(any(test, feature = "deny-unknown-attrs")) {
3630 break;
3631 } else {
3632 continue;
3633 }
3634 }
3635 };
3636 return Some(Ok(res));
3637 }
3638 Some(Err(ErrorContext::new(
3639 "OpDelneighDoReply",
3640 r#type.and_then(|t| OpDelneighDoReply::attr_from_type(t)),
3641 self.orig_loc,
3642 self.buf.as_ptr().wrapping_add(pos) as usize,
3643 )))
3644 }
3645}
3646impl std::fmt::Debug for IterableOpDelneighDoReply<'_> {
3647 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3648 let mut fmt = f.debug_struct("OpDelneighDoReply");
3649 for attr in self.clone() {
3650 let attr = match attr {
3651 Ok(a) => a,
3652 Err(err) => {
3653 fmt.finish()?;
3654 f.write_str("Err(")?;
3655 err.fmt(f)?;
3656 return f.write_str(")");
3657 }
3658 };
3659 match attr {};
3660 }
3661 fmt.finish()
3662 }
3663}
3664impl IterableOpDelneighDoReply<'_> {
3665 pub fn lookup_attr(
3666 &self,
3667 offset: usize,
3668 missing_type: Option<u16>,
3669 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3670 let mut stack = Vec::new();
3671 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3672 if cur == offset + PushNdmsg::len() {
3673 stack.push(("OpDelneighDoReply", offset));
3674 return (
3675 stack,
3676 missing_type.and_then(|t| OpDelneighDoReply::attr_from_type(t)),
3677 );
3678 }
3679 (stack, None)
3680 }
3681}
3682#[derive(Debug)]
3683pub struct RequestOpDelneighDoRequest<'r> {
3684 request: Request<'r>,
3685}
3686impl<'r> RequestOpDelneighDoRequest<'r> {
3687 pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
3688 PushOpDelneighDoRequest::write_header(&mut request.buf_mut(), header);
3689 Self { request: request }
3690 }
3691 pub fn encode(&mut self) -> PushOpDelneighDoRequest<&mut Vec<u8>> {
3692 PushOpDelneighDoRequest::new_without_header(self.request.buf_mut())
3693 }
3694 pub fn into_encoder(self) -> PushOpDelneighDoRequest<RequestBuf<'r>> {
3695 PushOpDelneighDoRequest::new_without_header(self.request.buf)
3696 }
3697}
3698impl NetlinkRequest for RequestOpDelneighDoRequest<'_> {
3699 type ReplyType<'buf> = (PushNdmsg, IterableOpDelneighDoReply<'buf>);
3700 fn protocol(&self) -> Protocol {
3701 Protocol::Raw {
3702 protonum: 0u16,
3703 request_type: 29u16,
3704 }
3705 }
3706 fn flags(&self) -> u16 {
3707 self.request.flags
3708 }
3709 fn payload(&self) -> &[u8] {
3710 self.request.buf()
3711 }
3712 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
3713 OpDelneighDoReply::new(buf)
3714 }
3715 fn lookup(
3716 buf: &[u8],
3717 offset: usize,
3718 missing_type: Option<u16>,
3719 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3720 OpDelneighDoRequest::new(buf)
3721 .1
3722 .lookup_attr(offset, missing_type)
3723 }
3724}
3725#[doc = "Get or dump neighbour entries"]
3726pub struct PushOpGetneighDumpRequest<Prev: Rec> {
3727 pub(crate) prev: Option<Prev>,
3728 pub(crate) header_offset: Option<usize>,
3729}
3730impl<Prev: Rec> Rec for PushOpGetneighDumpRequest<Prev> {
3731 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3732 self.prev.as_mut().unwrap().as_rec_mut()
3733 }
3734}
3735impl<Prev: Rec> PushOpGetneighDumpRequest<Prev> {
3736 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3737 Self::write_header(&mut prev, header);
3738 Self::new_without_header(prev)
3739 }
3740 fn new_without_header(prev: Prev) -> Self {
3741 Self {
3742 prev: Some(prev),
3743 header_offset: None,
3744 }
3745 }
3746 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3747 prev.as_rec_mut().extend(header.as_slice());
3748 }
3749 pub fn end_nested(mut self) -> Prev {
3750 let mut prev = self.prev.take().unwrap();
3751 if let Some(header_offset) = &self.header_offset {
3752 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3753 }
3754 prev
3755 }
3756 pub fn push_ifindex(mut self, value: u32) -> Self {
3757 push_header(self.as_rec_mut(), 8u16, 4 as u16);
3758 self.as_rec_mut().extend(value.to_ne_bytes());
3759 self
3760 }
3761 pub fn push_master(mut self, value: u32) -> Self {
3762 push_header(self.as_rec_mut(), 9u16, 4 as u16);
3763 self.as_rec_mut().extend(value.to_ne_bytes());
3764 self
3765 }
3766}
3767impl<Prev: Rec> Drop for PushOpGetneighDumpRequest<Prev> {
3768 fn drop(&mut self) {
3769 if let Some(prev) = &mut self.prev {
3770 if let Some(header_offset) = &self.header_offset {
3771 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3772 }
3773 }
3774 }
3775}
3776#[doc = "Get or dump neighbour entries"]
3777#[derive(Clone)]
3778pub enum OpGetneighDumpRequest {
3779 Ifindex(u32),
3780 Master(u32),
3781}
3782impl<'a> IterableOpGetneighDumpRequest<'a> {
3783 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
3784 let mut iter = self.clone();
3785 iter.pos = 0;
3786 for attr in iter {
3787 if let OpGetneighDumpRequest::Ifindex(val) = attr? {
3788 return Ok(val);
3789 }
3790 }
3791 Err(ErrorContext::new_missing(
3792 "OpGetneighDumpRequest",
3793 "Ifindex",
3794 self.orig_loc,
3795 self.buf.as_ptr() as usize,
3796 ))
3797 }
3798 pub fn get_master(&self) -> Result<u32, ErrorContext> {
3799 let mut iter = self.clone();
3800 iter.pos = 0;
3801 for attr in iter {
3802 if let OpGetneighDumpRequest::Master(val) = attr? {
3803 return Ok(val);
3804 }
3805 }
3806 Err(ErrorContext::new_missing(
3807 "OpGetneighDumpRequest",
3808 "Master",
3809 self.orig_loc,
3810 self.buf.as_ptr() as usize,
3811 ))
3812 }
3813}
3814impl OpGetneighDumpRequest {
3815 pub fn new(buf: &'_ [u8]) -> (PushNdmsg, IterableOpGetneighDumpRequest<'_>) {
3816 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
3817 (
3818 PushNdmsg::new_from_slice(header).unwrap_or_default(),
3819 IterableOpGetneighDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
3820 )
3821 }
3822 fn attr_from_type(r#type: u16) -> Option<&'static str> {
3823 NeighbourAttrs::attr_from_type(r#type)
3824 }
3825}
3826#[derive(Clone, Copy, Default)]
3827pub struct IterableOpGetneighDumpRequest<'a> {
3828 buf: &'a [u8],
3829 pos: usize,
3830 orig_loc: usize,
3831}
3832impl<'a> IterableOpGetneighDumpRequest<'a> {
3833 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
3834 Self {
3835 buf,
3836 pos: 0,
3837 orig_loc,
3838 }
3839 }
3840 pub fn get_buf(&self) -> &'a [u8] {
3841 self.buf
3842 }
3843}
3844impl<'a> Iterator for IterableOpGetneighDumpRequest<'a> {
3845 type Item = Result<OpGetneighDumpRequest, ErrorContext>;
3846 fn next(&mut self) -> Option<Self::Item> {
3847 if self.buf.len() == self.pos {
3848 return None;
3849 }
3850 let pos = self.pos;
3851 let mut r#type = None;
3852 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
3853 r#type = Some(header.r#type);
3854 let res = match header.r#type {
3855 8u16 => OpGetneighDumpRequest::Ifindex({
3856 let res = parse_u32(next);
3857 let Some(val) = res else { break };
3858 val
3859 }),
3860 9u16 => OpGetneighDumpRequest::Master({
3861 let res = parse_u32(next);
3862 let Some(val) = res else { break };
3863 val
3864 }),
3865 n => {
3866 if cfg!(any(test, feature = "deny-unknown-attrs")) {
3867 break;
3868 } else {
3869 continue;
3870 }
3871 }
3872 };
3873 return Some(Ok(res));
3874 }
3875 Some(Err(ErrorContext::new(
3876 "OpGetneighDumpRequest",
3877 r#type.and_then(|t| OpGetneighDumpRequest::attr_from_type(t)),
3878 self.orig_loc,
3879 self.buf.as_ptr().wrapping_add(pos) as usize,
3880 )))
3881 }
3882}
3883impl std::fmt::Debug for IterableOpGetneighDumpRequest<'_> {
3884 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3885 let mut fmt = f.debug_struct("OpGetneighDumpRequest");
3886 for attr in self.clone() {
3887 let attr = match attr {
3888 Ok(a) => a,
3889 Err(err) => {
3890 fmt.finish()?;
3891 f.write_str("Err(")?;
3892 err.fmt(f)?;
3893 return f.write_str(")");
3894 }
3895 };
3896 match attr {
3897 OpGetneighDumpRequest::Ifindex(val) => fmt.field("Ifindex", &val),
3898 OpGetneighDumpRequest::Master(val) => fmt.field("Master", &val),
3899 };
3900 }
3901 fmt.finish()
3902 }
3903}
3904impl IterableOpGetneighDumpRequest<'_> {
3905 pub fn lookup_attr(
3906 &self,
3907 offset: usize,
3908 missing_type: Option<u16>,
3909 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
3910 let mut stack = Vec::new();
3911 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
3912 if cur == offset + PushNdmsg::len() {
3913 stack.push(("OpGetneighDumpRequest", offset));
3914 return (
3915 stack,
3916 missing_type.and_then(|t| OpGetneighDumpRequest::attr_from_type(t)),
3917 );
3918 }
3919 if cur > offset || cur + self.buf.len() < offset {
3920 return (stack, None);
3921 }
3922 let mut attrs = self.clone();
3923 let mut last_off = cur + attrs.pos;
3924 while let Some(attr) = attrs.next() {
3925 let Ok(attr) = attr else { break };
3926 match attr {
3927 OpGetneighDumpRequest::Ifindex(val) => {
3928 if last_off == offset {
3929 stack.push(("Ifindex", last_off));
3930 break;
3931 }
3932 }
3933 OpGetneighDumpRequest::Master(val) => {
3934 if last_off == offset {
3935 stack.push(("Master", last_off));
3936 break;
3937 }
3938 }
3939 _ => {}
3940 };
3941 last_off = cur + attrs.pos;
3942 }
3943 if !stack.is_empty() {
3944 stack.push(("OpGetneighDumpRequest", cur));
3945 }
3946 (stack, None)
3947 }
3948}
3949#[doc = "Get or dump neighbour entries"]
3950pub struct PushOpGetneighDumpReply<Prev: Rec> {
3951 pub(crate) prev: Option<Prev>,
3952 pub(crate) header_offset: Option<usize>,
3953}
3954impl<Prev: Rec> Rec for PushOpGetneighDumpReply<Prev> {
3955 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
3956 self.prev.as_mut().unwrap().as_rec_mut()
3957 }
3958}
3959impl<Prev: Rec> PushOpGetneighDumpReply<Prev> {
3960 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
3961 Self::write_header(&mut prev, header);
3962 Self::new_without_header(prev)
3963 }
3964 fn new_without_header(prev: Prev) -> Self {
3965 Self {
3966 prev: Some(prev),
3967 header_offset: None,
3968 }
3969 }
3970 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
3971 prev.as_rec_mut().extend(header.as_slice());
3972 }
3973 pub fn end_nested(mut self) -> Prev {
3974 let mut prev = self.prev.take().unwrap();
3975 if let Some(header_offset) = &self.header_offset {
3976 finalize_nested_header(prev.as_rec_mut(), *header_offset);
3977 }
3978 prev
3979 }
3980 pub fn push_dst(mut self, value: &[u8]) -> Self {
3981 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
3982 self.as_rec_mut().extend(value);
3983 self
3984 }
3985 pub fn push_lladdr(mut self, value: &[u8]) -> Self {
3986 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
3987 self.as_rec_mut().extend(value);
3988 self
3989 }
3990 pub fn push_probes(mut self, value: u32) -> Self {
3991 push_header(self.as_rec_mut(), 4u16, 4 as u16);
3992 self.as_rec_mut().extend(value.to_ne_bytes());
3993 self
3994 }
3995 pub fn push_vlan(mut self, value: u16) -> Self {
3996 push_header(self.as_rec_mut(), 5u16, 2 as u16);
3997 self.as_rec_mut().extend(value.to_ne_bytes());
3998 self
3999 }
4000 pub fn push_port(mut self, value: u16) -> Self {
4001 push_header(self.as_rec_mut(), 6u16, 2 as u16);
4002 self.as_rec_mut().extend(value.to_ne_bytes());
4003 self
4004 }
4005 pub fn push_vni(mut self, value: u32) -> Self {
4006 push_header(self.as_rec_mut(), 7u16, 4 as u16);
4007 self.as_rec_mut().extend(value.to_ne_bytes());
4008 self
4009 }
4010 pub fn push_ifindex(mut self, value: u32) -> Self {
4011 push_header(self.as_rec_mut(), 8u16, 4 as u16);
4012 self.as_rec_mut().extend(value.to_ne_bytes());
4013 self
4014 }
4015 pub fn push_master(mut self, value: u32) -> Self {
4016 push_header(self.as_rec_mut(), 9u16, 4 as u16);
4017 self.as_rec_mut().extend(value.to_ne_bytes());
4018 self
4019 }
4020 pub fn push_protocol(mut self, value: u8) -> Self {
4021 push_header(self.as_rec_mut(), 12u16, 1 as u16);
4022 self.as_rec_mut().extend(value.to_ne_bytes());
4023 self
4024 }
4025 pub fn push_nh_id(mut self, value: u32) -> Self {
4026 push_header(self.as_rec_mut(), 13u16, 4 as u16);
4027 self.as_rec_mut().extend(value.to_ne_bytes());
4028 self
4029 }
4030 pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
4031 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
4032 self.as_rec_mut().extend(value);
4033 self
4034 }
4035 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4036 pub fn push_flags_ext(mut self, value: u32) -> Self {
4037 push_header(self.as_rec_mut(), 15u16, 4 as u16);
4038 self.as_rec_mut().extend(value.to_ne_bytes());
4039 self
4040 }
4041}
4042impl<Prev: Rec> Drop for PushOpGetneighDumpReply<Prev> {
4043 fn drop(&mut self) {
4044 if let Some(prev) = &mut self.prev {
4045 if let Some(header_offset) = &self.header_offset {
4046 finalize_nested_header(prev.as_rec_mut(), *header_offset);
4047 }
4048 }
4049 }
4050}
4051#[doc = "Get or dump neighbour entries"]
4052#[derive(Clone)]
4053pub enum OpGetneighDumpReply<'a> {
4054 Dst(&'a [u8]),
4055 Lladdr(&'a [u8]),
4056 Probes(u32),
4057 Vlan(u16),
4058 Port(u16),
4059 Vni(u32),
4060 Ifindex(u32),
4061 Master(u32),
4062 Protocol(u8),
4063 NhId(u32),
4064 FdbExtAttrs(&'a [u8]),
4065 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4066 FlagsExt(u32),
4067}
4068impl<'a> IterableOpGetneighDumpReply<'a> {
4069 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4070 let mut iter = self.clone();
4071 iter.pos = 0;
4072 for attr in iter {
4073 if let OpGetneighDumpReply::Dst(val) = attr? {
4074 return Ok(val);
4075 }
4076 }
4077 Err(ErrorContext::new_missing(
4078 "OpGetneighDumpReply",
4079 "Dst",
4080 self.orig_loc,
4081 self.buf.as_ptr() as usize,
4082 ))
4083 }
4084 pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
4085 let mut iter = self.clone();
4086 iter.pos = 0;
4087 for attr in iter {
4088 if let OpGetneighDumpReply::Lladdr(val) = attr? {
4089 return Ok(val);
4090 }
4091 }
4092 Err(ErrorContext::new_missing(
4093 "OpGetneighDumpReply",
4094 "Lladdr",
4095 self.orig_loc,
4096 self.buf.as_ptr() as usize,
4097 ))
4098 }
4099 pub fn get_probes(&self) -> Result<u32, ErrorContext> {
4100 let mut iter = self.clone();
4101 iter.pos = 0;
4102 for attr in iter {
4103 if let OpGetneighDumpReply::Probes(val) = attr? {
4104 return Ok(val);
4105 }
4106 }
4107 Err(ErrorContext::new_missing(
4108 "OpGetneighDumpReply",
4109 "Probes",
4110 self.orig_loc,
4111 self.buf.as_ptr() as usize,
4112 ))
4113 }
4114 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
4115 let mut iter = self.clone();
4116 iter.pos = 0;
4117 for attr in iter {
4118 if let OpGetneighDumpReply::Vlan(val) = attr? {
4119 return Ok(val);
4120 }
4121 }
4122 Err(ErrorContext::new_missing(
4123 "OpGetneighDumpReply",
4124 "Vlan",
4125 self.orig_loc,
4126 self.buf.as_ptr() as usize,
4127 ))
4128 }
4129 pub fn get_port(&self) -> Result<u16, ErrorContext> {
4130 let mut iter = self.clone();
4131 iter.pos = 0;
4132 for attr in iter {
4133 if let OpGetneighDumpReply::Port(val) = attr? {
4134 return Ok(val);
4135 }
4136 }
4137 Err(ErrorContext::new_missing(
4138 "OpGetneighDumpReply",
4139 "Port",
4140 self.orig_loc,
4141 self.buf.as_ptr() as usize,
4142 ))
4143 }
4144 pub fn get_vni(&self) -> Result<u32, ErrorContext> {
4145 let mut iter = self.clone();
4146 iter.pos = 0;
4147 for attr in iter {
4148 if let OpGetneighDumpReply::Vni(val) = attr? {
4149 return Ok(val);
4150 }
4151 }
4152 Err(ErrorContext::new_missing(
4153 "OpGetneighDumpReply",
4154 "Vni",
4155 self.orig_loc,
4156 self.buf.as_ptr() as usize,
4157 ))
4158 }
4159 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
4160 let mut iter = self.clone();
4161 iter.pos = 0;
4162 for attr in iter {
4163 if let OpGetneighDumpReply::Ifindex(val) = attr? {
4164 return Ok(val);
4165 }
4166 }
4167 Err(ErrorContext::new_missing(
4168 "OpGetneighDumpReply",
4169 "Ifindex",
4170 self.orig_loc,
4171 self.buf.as_ptr() as usize,
4172 ))
4173 }
4174 pub fn get_master(&self) -> Result<u32, ErrorContext> {
4175 let mut iter = self.clone();
4176 iter.pos = 0;
4177 for attr in iter {
4178 if let OpGetneighDumpReply::Master(val) = attr? {
4179 return Ok(val);
4180 }
4181 }
4182 Err(ErrorContext::new_missing(
4183 "OpGetneighDumpReply",
4184 "Master",
4185 self.orig_loc,
4186 self.buf.as_ptr() as usize,
4187 ))
4188 }
4189 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
4190 let mut iter = self.clone();
4191 iter.pos = 0;
4192 for attr in iter {
4193 if let OpGetneighDumpReply::Protocol(val) = attr? {
4194 return Ok(val);
4195 }
4196 }
4197 Err(ErrorContext::new_missing(
4198 "OpGetneighDumpReply",
4199 "Protocol",
4200 self.orig_loc,
4201 self.buf.as_ptr() as usize,
4202 ))
4203 }
4204 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
4205 let mut iter = self.clone();
4206 iter.pos = 0;
4207 for attr in iter {
4208 if let OpGetneighDumpReply::NhId(val) = attr? {
4209 return Ok(val);
4210 }
4211 }
4212 Err(ErrorContext::new_missing(
4213 "OpGetneighDumpReply",
4214 "NhId",
4215 self.orig_loc,
4216 self.buf.as_ptr() as usize,
4217 ))
4218 }
4219 pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
4220 let mut iter = self.clone();
4221 iter.pos = 0;
4222 for attr in iter {
4223 if let OpGetneighDumpReply::FdbExtAttrs(val) = attr? {
4224 return Ok(val);
4225 }
4226 }
4227 Err(ErrorContext::new_missing(
4228 "OpGetneighDumpReply",
4229 "FdbExtAttrs",
4230 self.orig_loc,
4231 self.buf.as_ptr() as usize,
4232 ))
4233 }
4234 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4235 pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
4236 let mut iter = self.clone();
4237 iter.pos = 0;
4238 for attr in iter {
4239 if let OpGetneighDumpReply::FlagsExt(val) = attr? {
4240 return Ok(val);
4241 }
4242 }
4243 Err(ErrorContext::new_missing(
4244 "OpGetneighDumpReply",
4245 "FlagsExt",
4246 self.orig_loc,
4247 self.buf.as_ptr() as usize,
4248 ))
4249 }
4250}
4251impl<'a> OpGetneighDumpReply<'a> {
4252 pub fn new(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDumpReply<'a>) {
4253 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
4254 (
4255 PushNdmsg::new_from_slice(header).unwrap_or_default(),
4256 IterableOpGetneighDumpReply::with_loc(attrs, buf.as_ptr() as usize),
4257 )
4258 }
4259 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4260 NeighbourAttrs::attr_from_type(r#type)
4261 }
4262}
4263#[derive(Clone, Copy, Default)]
4264pub struct IterableOpGetneighDumpReply<'a> {
4265 buf: &'a [u8],
4266 pos: usize,
4267 orig_loc: usize,
4268}
4269impl<'a> IterableOpGetneighDumpReply<'a> {
4270 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4271 Self {
4272 buf,
4273 pos: 0,
4274 orig_loc,
4275 }
4276 }
4277 pub fn get_buf(&self) -> &'a [u8] {
4278 self.buf
4279 }
4280}
4281impl<'a> Iterator for IterableOpGetneighDumpReply<'a> {
4282 type Item = Result<OpGetneighDumpReply<'a>, ErrorContext>;
4283 fn next(&mut self) -> Option<Self::Item> {
4284 if self.buf.len() == self.pos {
4285 return None;
4286 }
4287 let pos = self.pos;
4288 let mut r#type = None;
4289 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
4290 r#type = Some(header.r#type);
4291 let res = match header.r#type {
4292 1u16 => OpGetneighDumpReply::Dst({
4293 let res = Some(next);
4294 let Some(val) = res else { break };
4295 val
4296 }),
4297 2u16 => OpGetneighDumpReply::Lladdr({
4298 let res = Some(next);
4299 let Some(val) = res else { break };
4300 val
4301 }),
4302 4u16 => OpGetneighDumpReply::Probes({
4303 let res = parse_u32(next);
4304 let Some(val) = res else { break };
4305 val
4306 }),
4307 5u16 => OpGetneighDumpReply::Vlan({
4308 let res = parse_u16(next);
4309 let Some(val) = res else { break };
4310 val
4311 }),
4312 6u16 => OpGetneighDumpReply::Port({
4313 let res = parse_u16(next);
4314 let Some(val) = res else { break };
4315 val
4316 }),
4317 7u16 => OpGetneighDumpReply::Vni({
4318 let res = parse_u32(next);
4319 let Some(val) = res else { break };
4320 val
4321 }),
4322 8u16 => OpGetneighDumpReply::Ifindex({
4323 let res = parse_u32(next);
4324 let Some(val) = res else { break };
4325 val
4326 }),
4327 9u16 => OpGetneighDumpReply::Master({
4328 let res = parse_u32(next);
4329 let Some(val) = res else { break };
4330 val
4331 }),
4332 12u16 => OpGetneighDumpReply::Protocol({
4333 let res = parse_u8(next);
4334 let Some(val) = res else { break };
4335 val
4336 }),
4337 13u16 => OpGetneighDumpReply::NhId({
4338 let res = parse_u32(next);
4339 let Some(val) = res else { break };
4340 val
4341 }),
4342 14u16 => OpGetneighDumpReply::FdbExtAttrs({
4343 let res = Some(next);
4344 let Some(val) = res else { break };
4345 val
4346 }),
4347 15u16 => OpGetneighDumpReply::FlagsExt({
4348 let res = parse_u32(next);
4349 let Some(val) = res else { break };
4350 val
4351 }),
4352 n => {
4353 if cfg!(any(test, feature = "deny-unknown-attrs")) {
4354 break;
4355 } else {
4356 continue;
4357 }
4358 }
4359 };
4360 return Some(Ok(res));
4361 }
4362 Some(Err(ErrorContext::new(
4363 "OpGetneighDumpReply",
4364 r#type.and_then(|t| OpGetneighDumpReply::attr_from_type(t)),
4365 self.orig_loc,
4366 self.buf.as_ptr().wrapping_add(pos) as usize,
4367 )))
4368 }
4369}
4370impl<'a> std::fmt::Debug for IterableOpGetneighDumpReply<'_> {
4371 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4372 let mut fmt = f.debug_struct("OpGetneighDumpReply");
4373 for attr in self.clone() {
4374 let attr = match attr {
4375 Ok(a) => a,
4376 Err(err) => {
4377 fmt.finish()?;
4378 f.write_str("Err(")?;
4379 err.fmt(f)?;
4380 return f.write_str(")");
4381 }
4382 };
4383 match attr {
4384 OpGetneighDumpReply::Dst(val) => fmt.field("Dst", &val),
4385 OpGetneighDumpReply::Lladdr(val) => fmt.field("Lladdr", &val),
4386 OpGetneighDumpReply::Probes(val) => fmt.field("Probes", &val),
4387 OpGetneighDumpReply::Vlan(val) => fmt.field("Vlan", &val),
4388 OpGetneighDumpReply::Port(val) => fmt.field("Port", &val),
4389 OpGetneighDumpReply::Vni(val) => fmt.field("Vni", &val),
4390 OpGetneighDumpReply::Ifindex(val) => fmt.field("Ifindex", &val),
4391 OpGetneighDumpReply::Master(val) => fmt.field("Master", &val),
4392 OpGetneighDumpReply::Protocol(val) => fmt.field("Protocol", &val),
4393 OpGetneighDumpReply::NhId(val) => fmt.field("NhId", &val),
4394 OpGetneighDumpReply::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
4395 OpGetneighDumpReply::FlagsExt(val) => fmt.field(
4396 "FlagsExt",
4397 &FormatFlags(val.into(), NtfExtFlags::from_value),
4398 ),
4399 };
4400 }
4401 fmt.finish()
4402 }
4403}
4404impl IterableOpGetneighDumpReply<'_> {
4405 pub fn lookup_attr(
4406 &self,
4407 offset: usize,
4408 missing_type: Option<u16>,
4409 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4410 let mut stack = Vec::new();
4411 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4412 if cur == offset + PushNdmsg::len() {
4413 stack.push(("OpGetneighDumpReply", offset));
4414 return (
4415 stack,
4416 missing_type.and_then(|t| OpGetneighDumpReply::attr_from_type(t)),
4417 );
4418 }
4419 if cur > offset || cur + self.buf.len() < offset {
4420 return (stack, None);
4421 }
4422 let mut attrs = self.clone();
4423 let mut last_off = cur + attrs.pos;
4424 while let Some(attr) = attrs.next() {
4425 let Ok(attr) = attr else { break };
4426 match attr {
4427 OpGetneighDumpReply::Dst(val) => {
4428 if last_off == offset {
4429 stack.push(("Dst", last_off));
4430 break;
4431 }
4432 }
4433 OpGetneighDumpReply::Lladdr(val) => {
4434 if last_off == offset {
4435 stack.push(("Lladdr", last_off));
4436 break;
4437 }
4438 }
4439 OpGetneighDumpReply::Probes(val) => {
4440 if last_off == offset {
4441 stack.push(("Probes", last_off));
4442 break;
4443 }
4444 }
4445 OpGetneighDumpReply::Vlan(val) => {
4446 if last_off == offset {
4447 stack.push(("Vlan", last_off));
4448 break;
4449 }
4450 }
4451 OpGetneighDumpReply::Port(val) => {
4452 if last_off == offset {
4453 stack.push(("Port", last_off));
4454 break;
4455 }
4456 }
4457 OpGetneighDumpReply::Vni(val) => {
4458 if last_off == offset {
4459 stack.push(("Vni", last_off));
4460 break;
4461 }
4462 }
4463 OpGetneighDumpReply::Ifindex(val) => {
4464 if last_off == offset {
4465 stack.push(("Ifindex", last_off));
4466 break;
4467 }
4468 }
4469 OpGetneighDumpReply::Master(val) => {
4470 if last_off == offset {
4471 stack.push(("Master", last_off));
4472 break;
4473 }
4474 }
4475 OpGetneighDumpReply::Protocol(val) => {
4476 if last_off == offset {
4477 stack.push(("Protocol", last_off));
4478 break;
4479 }
4480 }
4481 OpGetneighDumpReply::NhId(val) => {
4482 if last_off == offset {
4483 stack.push(("NhId", last_off));
4484 break;
4485 }
4486 }
4487 OpGetneighDumpReply::FdbExtAttrs(val) => {
4488 if last_off == offset {
4489 stack.push(("FdbExtAttrs", last_off));
4490 break;
4491 }
4492 }
4493 OpGetneighDumpReply::FlagsExt(val) => {
4494 if last_off == offset {
4495 stack.push(("FlagsExt", last_off));
4496 break;
4497 }
4498 }
4499 _ => {}
4500 };
4501 last_off = cur + attrs.pos;
4502 }
4503 if !stack.is_empty() {
4504 stack.push(("OpGetneighDumpReply", cur));
4505 }
4506 (stack, None)
4507 }
4508}
4509#[derive(Debug)]
4510pub struct RequestOpGetneighDumpRequest<'r> {
4511 request: Request<'r>,
4512}
4513impl<'r> RequestOpGetneighDumpRequest<'r> {
4514 pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
4515 PushOpGetneighDumpRequest::write_header(&mut request.buf_mut(), header);
4516 Self {
4517 request: request.set_dump(),
4518 }
4519 }
4520 pub fn encode(&mut self) -> PushOpGetneighDumpRequest<&mut Vec<u8>> {
4521 PushOpGetneighDumpRequest::new_without_header(self.request.buf_mut())
4522 }
4523 pub fn into_encoder(self) -> PushOpGetneighDumpRequest<RequestBuf<'r>> {
4524 PushOpGetneighDumpRequest::new_without_header(self.request.buf)
4525 }
4526}
4527impl NetlinkRequest for RequestOpGetneighDumpRequest<'_> {
4528 type ReplyType<'buf> = (PushNdmsg, IterableOpGetneighDumpReply<'buf>);
4529 fn protocol(&self) -> Protocol {
4530 Protocol::Raw {
4531 protonum: 0u16,
4532 request_type: 30u16,
4533 }
4534 }
4535 fn flags(&self) -> u16 {
4536 self.request.flags
4537 }
4538 fn payload(&self) -> &[u8] {
4539 self.request.buf()
4540 }
4541 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
4542 OpGetneighDumpReply::new(buf)
4543 }
4544 fn lookup(
4545 buf: &[u8],
4546 offset: usize,
4547 missing_type: Option<u16>,
4548 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4549 OpGetneighDumpRequest::new(buf)
4550 .1
4551 .lookup_attr(offset, missing_type)
4552 }
4553}
4554#[doc = "Get or dump neighbour entries"]
4555pub struct PushOpGetneighDoRequest<Prev: Rec> {
4556 pub(crate) prev: Option<Prev>,
4557 pub(crate) header_offset: Option<usize>,
4558}
4559impl<Prev: Rec> Rec for PushOpGetneighDoRequest<Prev> {
4560 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
4561 self.prev.as_mut().unwrap().as_rec_mut()
4562 }
4563}
4564impl<Prev: Rec> PushOpGetneighDoRequest<Prev> {
4565 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
4566 Self::write_header(&mut prev, header);
4567 Self::new_without_header(prev)
4568 }
4569 fn new_without_header(prev: Prev) -> Self {
4570 Self {
4571 prev: Some(prev),
4572 header_offset: None,
4573 }
4574 }
4575 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
4576 prev.as_rec_mut().extend(header.as_slice());
4577 }
4578 pub fn end_nested(mut self) -> Prev {
4579 let mut prev = self.prev.take().unwrap();
4580 if let Some(header_offset) = &self.header_offset {
4581 finalize_nested_header(prev.as_rec_mut(), *header_offset);
4582 }
4583 prev
4584 }
4585 pub fn push_dst(mut self, value: &[u8]) -> Self {
4586 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
4587 self.as_rec_mut().extend(value);
4588 self
4589 }
4590}
4591impl<Prev: Rec> Drop for PushOpGetneighDoRequest<Prev> {
4592 fn drop(&mut self) {
4593 if let Some(prev) = &mut self.prev {
4594 if let Some(header_offset) = &self.header_offset {
4595 finalize_nested_header(prev.as_rec_mut(), *header_offset);
4596 }
4597 }
4598 }
4599}
4600#[doc = "Get or dump neighbour entries"]
4601#[derive(Clone)]
4602pub enum OpGetneighDoRequest<'a> {
4603 Dst(&'a [u8]),
4604}
4605impl<'a> IterableOpGetneighDoRequest<'a> {
4606 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4607 let mut iter = self.clone();
4608 iter.pos = 0;
4609 for attr in iter {
4610 if let OpGetneighDoRequest::Dst(val) = attr? {
4611 return Ok(val);
4612 }
4613 }
4614 Err(ErrorContext::new_missing(
4615 "OpGetneighDoRequest",
4616 "Dst",
4617 self.orig_loc,
4618 self.buf.as_ptr() as usize,
4619 ))
4620 }
4621}
4622impl<'a> OpGetneighDoRequest<'a> {
4623 pub fn new(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDoRequest<'a>) {
4624 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
4625 (
4626 PushNdmsg::new_from_slice(header).unwrap_or_default(),
4627 IterableOpGetneighDoRequest::with_loc(attrs, buf.as_ptr() as usize),
4628 )
4629 }
4630 fn attr_from_type(r#type: u16) -> Option<&'static str> {
4631 NeighbourAttrs::attr_from_type(r#type)
4632 }
4633}
4634#[derive(Clone, Copy, Default)]
4635pub struct IterableOpGetneighDoRequest<'a> {
4636 buf: &'a [u8],
4637 pos: usize,
4638 orig_loc: usize,
4639}
4640impl<'a> IterableOpGetneighDoRequest<'a> {
4641 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
4642 Self {
4643 buf,
4644 pos: 0,
4645 orig_loc,
4646 }
4647 }
4648 pub fn get_buf(&self) -> &'a [u8] {
4649 self.buf
4650 }
4651}
4652impl<'a> Iterator for IterableOpGetneighDoRequest<'a> {
4653 type Item = Result<OpGetneighDoRequest<'a>, ErrorContext>;
4654 fn next(&mut self) -> Option<Self::Item> {
4655 if self.buf.len() == self.pos {
4656 return None;
4657 }
4658 let pos = self.pos;
4659 let mut r#type = None;
4660 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
4661 r#type = Some(header.r#type);
4662 let res = match header.r#type {
4663 1u16 => OpGetneighDoRequest::Dst({
4664 let res = Some(next);
4665 let Some(val) = res else { break };
4666 val
4667 }),
4668 n => {
4669 if cfg!(any(test, feature = "deny-unknown-attrs")) {
4670 break;
4671 } else {
4672 continue;
4673 }
4674 }
4675 };
4676 return Some(Ok(res));
4677 }
4678 Some(Err(ErrorContext::new(
4679 "OpGetneighDoRequest",
4680 r#type.and_then(|t| OpGetneighDoRequest::attr_from_type(t)),
4681 self.orig_loc,
4682 self.buf.as_ptr().wrapping_add(pos) as usize,
4683 )))
4684 }
4685}
4686impl<'a> std::fmt::Debug for IterableOpGetneighDoRequest<'_> {
4687 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4688 let mut fmt = f.debug_struct("OpGetneighDoRequest");
4689 for attr in self.clone() {
4690 let attr = match attr {
4691 Ok(a) => a,
4692 Err(err) => {
4693 fmt.finish()?;
4694 f.write_str("Err(")?;
4695 err.fmt(f)?;
4696 return f.write_str(")");
4697 }
4698 };
4699 match attr {
4700 OpGetneighDoRequest::Dst(val) => fmt.field("Dst", &val),
4701 };
4702 }
4703 fmt.finish()
4704 }
4705}
4706impl IterableOpGetneighDoRequest<'_> {
4707 pub fn lookup_attr(
4708 &self,
4709 offset: usize,
4710 missing_type: Option<u16>,
4711 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
4712 let mut stack = Vec::new();
4713 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
4714 if cur == offset + PushNdmsg::len() {
4715 stack.push(("OpGetneighDoRequest", offset));
4716 return (
4717 stack,
4718 missing_type.and_then(|t| OpGetneighDoRequest::attr_from_type(t)),
4719 );
4720 }
4721 if cur > offset || cur + self.buf.len() < offset {
4722 return (stack, None);
4723 }
4724 let mut attrs = self.clone();
4725 let mut last_off = cur + attrs.pos;
4726 while let Some(attr) = attrs.next() {
4727 let Ok(attr) = attr else { break };
4728 match attr {
4729 OpGetneighDoRequest::Dst(val) => {
4730 if last_off == offset {
4731 stack.push(("Dst", last_off));
4732 break;
4733 }
4734 }
4735 _ => {}
4736 };
4737 last_off = cur + attrs.pos;
4738 }
4739 if !stack.is_empty() {
4740 stack.push(("OpGetneighDoRequest", cur));
4741 }
4742 (stack, None)
4743 }
4744}
4745#[doc = "Get or dump neighbour entries"]
4746pub struct PushOpGetneighDoReply<Prev: Rec> {
4747 pub(crate) prev: Option<Prev>,
4748 pub(crate) header_offset: Option<usize>,
4749}
4750impl<Prev: Rec> Rec for PushOpGetneighDoReply<Prev> {
4751 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
4752 self.prev.as_mut().unwrap().as_rec_mut()
4753 }
4754}
4755impl<Prev: Rec> PushOpGetneighDoReply<Prev> {
4756 pub fn new(mut prev: Prev, header: &PushNdmsg) -> Self {
4757 Self::write_header(&mut prev, header);
4758 Self::new_without_header(prev)
4759 }
4760 fn new_without_header(prev: Prev) -> Self {
4761 Self {
4762 prev: Some(prev),
4763 header_offset: None,
4764 }
4765 }
4766 fn write_header(prev: &mut Prev, header: &PushNdmsg) {
4767 prev.as_rec_mut().extend(header.as_slice());
4768 }
4769 pub fn end_nested(mut self) -> Prev {
4770 let mut prev = self.prev.take().unwrap();
4771 if let Some(header_offset) = &self.header_offset {
4772 finalize_nested_header(prev.as_rec_mut(), *header_offset);
4773 }
4774 prev
4775 }
4776 pub fn push_dst(mut self, value: &[u8]) -> Self {
4777 push_header(self.as_rec_mut(), 1u16, value.len() as u16);
4778 self.as_rec_mut().extend(value);
4779 self
4780 }
4781 pub fn push_lladdr(mut self, value: &[u8]) -> Self {
4782 push_header(self.as_rec_mut(), 2u16, value.len() as u16);
4783 self.as_rec_mut().extend(value);
4784 self
4785 }
4786 pub fn push_probes(mut self, value: u32) -> Self {
4787 push_header(self.as_rec_mut(), 4u16, 4 as u16);
4788 self.as_rec_mut().extend(value.to_ne_bytes());
4789 self
4790 }
4791 pub fn push_vlan(mut self, value: u16) -> Self {
4792 push_header(self.as_rec_mut(), 5u16, 2 as u16);
4793 self.as_rec_mut().extend(value.to_ne_bytes());
4794 self
4795 }
4796 pub fn push_port(mut self, value: u16) -> Self {
4797 push_header(self.as_rec_mut(), 6u16, 2 as u16);
4798 self.as_rec_mut().extend(value.to_ne_bytes());
4799 self
4800 }
4801 pub fn push_vni(mut self, value: u32) -> Self {
4802 push_header(self.as_rec_mut(), 7u16, 4 as u16);
4803 self.as_rec_mut().extend(value.to_ne_bytes());
4804 self
4805 }
4806 pub fn push_ifindex(mut self, value: u32) -> Self {
4807 push_header(self.as_rec_mut(), 8u16, 4 as u16);
4808 self.as_rec_mut().extend(value.to_ne_bytes());
4809 self
4810 }
4811 pub fn push_master(mut self, value: u32) -> Self {
4812 push_header(self.as_rec_mut(), 9u16, 4 as u16);
4813 self.as_rec_mut().extend(value.to_ne_bytes());
4814 self
4815 }
4816 pub fn push_protocol(mut self, value: u8) -> Self {
4817 push_header(self.as_rec_mut(), 12u16, 1 as u16);
4818 self.as_rec_mut().extend(value.to_ne_bytes());
4819 self
4820 }
4821 pub fn push_nh_id(mut self, value: u32) -> Self {
4822 push_header(self.as_rec_mut(), 13u16, 4 as u16);
4823 self.as_rec_mut().extend(value.to_ne_bytes());
4824 self
4825 }
4826 pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
4827 push_header(self.as_rec_mut(), 14u16, value.len() as u16);
4828 self.as_rec_mut().extend(value);
4829 self
4830 }
4831 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4832 pub fn push_flags_ext(mut self, value: u32) -> Self {
4833 push_header(self.as_rec_mut(), 15u16, 4 as u16);
4834 self.as_rec_mut().extend(value.to_ne_bytes());
4835 self
4836 }
4837}
4838impl<Prev: Rec> Drop for PushOpGetneighDoReply<Prev> {
4839 fn drop(&mut self) {
4840 if let Some(prev) = &mut self.prev {
4841 if let Some(header_offset) = &self.header_offset {
4842 finalize_nested_header(prev.as_rec_mut(), *header_offset);
4843 }
4844 }
4845 }
4846}
4847#[doc = "Get or dump neighbour entries"]
4848#[derive(Clone)]
4849pub enum OpGetneighDoReply<'a> {
4850 Dst(&'a [u8]),
4851 Lladdr(&'a [u8]),
4852 Probes(u32),
4853 Vlan(u16),
4854 Port(u16),
4855 Vni(u32),
4856 Ifindex(u32),
4857 Master(u32),
4858 Protocol(u8),
4859 NhId(u32),
4860 FdbExtAttrs(&'a [u8]),
4861 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
4862 FlagsExt(u32),
4863}
4864impl<'a> IterableOpGetneighDoReply<'a> {
4865 pub fn get_dst(&self) -> Result<&'a [u8], ErrorContext> {
4866 let mut iter = self.clone();
4867 iter.pos = 0;
4868 for attr in iter {
4869 if let OpGetneighDoReply::Dst(val) = attr? {
4870 return Ok(val);
4871 }
4872 }
4873 Err(ErrorContext::new_missing(
4874 "OpGetneighDoReply",
4875 "Dst",
4876 self.orig_loc,
4877 self.buf.as_ptr() as usize,
4878 ))
4879 }
4880 pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
4881 let mut iter = self.clone();
4882 iter.pos = 0;
4883 for attr in iter {
4884 if let OpGetneighDoReply::Lladdr(val) = attr? {
4885 return Ok(val);
4886 }
4887 }
4888 Err(ErrorContext::new_missing(
4889 "OpGetneighDoReply",
4890 "Lladdr",
4891 self.orig_loc,
4892 self.buf.as_ptr() as usize,
4893 ))
4894 }
4895 pub fn get_probes(&self) -> Result<u32, ErrorContext> {
4896 let mut iter = self.clone();
4897 iter.pos = 0;
4898 for attr in iter {
4899 if let OpGetneighDoReply::Probes(val) = attr? {
4900 return Ok(val);
4901 }
4902 }
4903 Err(ErrorContext::new_missing(
4904 "OpGetneighDoReply",
4905 "Probes",
4906 self.orig_loc,
4907 self.buf.as_ptr() as usize,
4908 ))
4909 }
4910 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
4911 let mut iter = self.clone();
4912 iter.pos = 0;
4913 for attr in iter {
4914 if let OpGetneighDoReply::Vlan(val) = attr? {
4915 return Ok(val);
4916 }
4917 }
4918 Err(ErrorContext::new_missing(
4919 "OpGetneighDoReply",
4920 "Vlan",
4921 self.orig_loc,
4922 self.buf.as_ptr() as usize,
4923 ))
4924 }
4925 pub fn get_port(&self) -> Result<u16, ErrorContext> {
4926 let mut iter = self.clone();
4927 iter.pos = 0;
4928 for attr in iter {
4929 if let OpGetneighDoReply::Port(val) = attr? {
4930 return Ok(val);
4931 }
4932 }
4933 Err(ErrorContext::new_missing(
4934 "OpGetneighDoReply",
4935 "Port",
4936 self.orig_loc,
4937 self.buf.as_ptr() as usize,
4938 ))
4939 }
4940 pub fn get_vni(&self) -> Result<u32, ErrorContext> {
4941 let mut iter = self.clone();
4942 iter.pos = 0;
4943 for attr in iter {
4944 if let OpGetneighDoReply::Vni(val) = attr? {
4945 return Ok(val);
4946 }
4947 }
4948 Err(ErrorContext::new_missing(
4949 "OpGetneighDoReply",
4950 "Vni",
4951 self.orig_loc,
4952 self.buf.as_ptr() as usize,
4953 ))
4954 }
4955 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
4956 let mut iter = self.clone();
4957 iter.pos = 0;
4958 for attr in iter {
4959 if let OpGetneighDoReply::Ifindex(val) = attr? {
4960 return Ok(val);
4961 }
4962 }
4963 Err(ErrorContext::new_missing(
4964 "OpGetneighDoReply",
4965 "Ifindex",
4966 self.orig_loc,
4967 self.buf.as_ptr() as usize,
4968 ))
4969 }
4970 pub fn get_master(&self) -> Result<u32, ErrorContext> {
4971 let mut iter = self.clone();
4972 iter.pos = 0;
4973 for attr in iter {
4974 if let OpGetneighDoReply::Master(val) = attr? {
4975 return Ok(val);
4976 }
4977 }
4978 Err(ErrorContext::new_missing(
4979 "OpGetneighDoReply",
4980 "Master",
4981 self.orig_loc,
4982 self.buf.as_ptr() as usize,
4983 ))
4984 }
4985 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
4986 let mut iter = self.clone();
4987 iter.pos = 0;
4988 for attr in iter {
4989 if let OpGetneighDoReply::Protocol(val) = attr? {
4990 return Ok(val);
4991 }
4992 }
4993 Err(ErrorContext::new_missing(
4994 "OpGetneighDoReply",
4995 "Protocol",
4996 self.orig_loc,
4997 self.buf.as_ptr() as usize,
4998 ))
4999 }
5000 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
5001 let mut iter = self.clone();
5002 iter.pos = 0;
5003 for attr in iter {
5004 if let OpGetneighDoReply::NhId(val) = attr? {
5005 return Ok(val);
5006 }
5007 }
5008 Err(ErrorContext::new_missing(
5009 "OpGetneighDoReply",
5010 "NhId",
5011 self.orig_loc,
5012 self.buf.as_ptr() as usize,
5013 ))
5014 }
5015 pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
5016 let mut iter = self.clone();
5017 iter.pos = 0;
5018 for attr in iter {
5019 if let OpGetneighDoReply::FdbExtAttrs(val) = attr? {
5020 return Ok(val);
5021 }
5022 }
5023 Err(ErrorContext::new_missing(
5024 "OpGetneighDoReply",
5025 "FdbExtAttrs",
5026 self.orig_loc,
5027 self.buf.as_ptr() as usize,
5028 ))
5029 }
5030 #[doc = "Associated type: \"NtfExtFlags\" (enum)"]
5031 pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
5032 let mut iter = self.clone();
5033 iter.pos = 0;
5034 for attr in iter {
5035 if let OpGetneighDoReply::FlagsExt(val) = attr? {
5036 return Ok(val);
5037 }
5038 }
5039 Err(ErrorContext::new_missing(
5040 "OpGetneighDoReply",
5041 "FlagsExt",
5042 self.orig_loc,
5043 self.buf.as_ptr() as usize,
5044 ))
5045 }
5046}
5047impl<'a> OpGetneighDoReply<'a> {
5048 pub fn new(buf: &'a [u8]) -> (PushNdmsg, IterableOpGetneighDoReply<'a>) {
5049 let (header, attrs) = buf.split_at(buf.len().min(PushNdmsg::len()));
5050 (
5051 PushNdmsg::new_from_slice(header).unwrap_or_default(),
5052 IterableOpGetneighDoReply::with_loc(attrs, buf.as_ptr() as usize),
5053 )
5054 }
5055 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5056 NeighbourAttrs::attr_from_type(r#type)
5057 }
5058}
5059#[derive(Clone, Copy, Default)]
5060pub struct IterableOpGetneighDoReply<'a> {
5061 buf: &'a [u8],
5062 pos: usize,
5063 orig_loc: usize,
5064}
5065impl<'a> IterableOpGetneighDoReply<'a> {
5066 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5067 Self {
5068 buf,
5069 pos: 0,
5070 orig_loc,
5071 }
5072 }
5073 pub fn get_buf(&self) -> &'a [u8] {
5074 self.buf
5075 }
5076}
5077impl<'a> Iterator for IterableOpGetneighDoReply<'a> {
5078 type Item = Result<OpGetneighDoReply<'a>, ErrorContext>;
5079 fn next(&mut self) -> Option<Self::Item> {
5080 if self.buf.len() == self.pos {
5081 return None;
5082 }
5083 let pos = self.pos;
5084 let mut r#type = None;
5085 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
5086 r#type = Some(header.r#type);
5087 let res = match header.r#type {
5088 1u16 => OpGetneighDoReply::Dst({
5089 let res = Some(next);
5090 let Some(val) = res else { break };
5091 val
5092 }),
5093 2u16 => OpGetneighDoReply::Lladdr({
5094 let res = Some(next);
5095 let Some(val) = res else { break };
5096 val
5097 }),
5098 4u16 => OpGetneighDoReply::Probes({
5099 let res = parse_u32(next);
5100 let Some(val) = res else { break };
5101 val
5102 }),
5103 5u16 => OpGetneighDoReply::Vlan({
5104 let res = parse_u16(next);
5105 let Some(val) = res else { break };
5106 val
5107 }),
5108 6u16 => OpGetneighDoReply::Port({
5109 let res = parse_u16(next);
5110 let Some(val) = res else { break };
5111 val
5112 }),
5113 7u16 => OpGetneighDoReply::Vni({
5114 let res = parse_u32(next);
5115 let Some(val) = res else { break };
5116 val
5117 }),
5118 8u16 => OpGetneighDoReply::Ifindex({
5119 let res = parse_u32(next);
5120 let Some(val) = res else { break };
5121 val
5122 }),
5123 9u16 => OpGetneighDoReply::Master({
5124 let res = parse_u32(next);
5125 let Some(val) = res else { break };
5126 val
5127 }),
5128 12u16 => OpGetneighDoReply::Protocol({
5129 let res = parse_u8(next);
5130 let Some(val) = res else { break };
5131 val
5132 }),
5133 13u16 => OpGetneighDoReply::NhId({
5134 let res = parse_u32(next);
5135 let Some(val) = res else { break };
5136 val
5137 }),
5138 14u16 => OpGetneighDoReply::FdbExtAttrs({
5139 let res = Some(next);
5140 let Some(val) = res else { break };
5141 val
5142 }),
5143 15u16 => OpGetneighDoReply::FlagsExt({
5144 let res = parse_u32(next);
5145 let Some(val) = res else { break };
5146 val
5147 }),
5148 n => {
5149 if cfg!(any(test, feature = "deny-unknown-attrs")) {
5150 break;
5151 } else {
5152 continue;
5153 }
5154 }
5155 };
5156 return Some(Ok(res));
5157 }
5158 Some(Err(ErrorContext::new(
5159 "OpGetneighDoReply",
5160 r#type.and_then(|t| OpGetneighDoReply::attr_from_type(t)),
5161 self.orig_loc,
5162 self.buf.as_ptr().wrapping_add(pos) as usize,
5163 )))
5164 }
5165}
5166impl<'a> std::fmt::Debug for IterableOpGetneighDoReply<'_> {
5167 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5168 let mut fmt = f.debug_struct("OpGetneighDoReply");
5169 for attr in self.clone() {
5170 let attr = match attr {
5171 Ok(a) => a,
5172 Err(err) => {
5173 fmt.finish()?;
5174 f.write_str("Err(")?;
5175 err.fmt(f)?;
5176 return f.write_str(")");
5177 }
5178 };
5179 match attr {
5180 OpGetneighDoReply::Dst(val) => fmt.field("Dst", &val),
5181 OpGetneighDoReply::Lladdr(val) => fmt.field("Lladdr", &val),
5182 OpGetneighDoReply::Probes(val) => fmt.field("Probes", &val),
5183 OpGetneighDoReply::Vlan(val) => fmt.field("Vlan", &val),
5184 OpGetneighDoReply::Port(val) => fmt.field("Port", &val),
5185 OpGetneighDoReply::Vni(val) => fmt.field("Vni", &val),
5186 OpGetneighDoReply::Ifindex(val) => fmt.field("Ifindex", &val),
5187 OpGetneighDoReply::Master(val) => fmt.field("Master", &val),
5188 OpGetneighDoReply::Protocol(val) => fmt.field("Protocol", &val),
5189 OpGetneighDoReply::NhId(val) => fmt.field("NhId", &val),
5190 OpGetneighDoReply::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
5191 OpGetneighDoReply::FlagsExt(val) => fmt.field(
5192 "FlagsExt",
5193 &FormatFlags(val.into(), NtfExtFlags::from_value),
5194 ),
5195 };
5196 }
5197 fmt.finish()
5198 }
5199}
5200impl IterableOpGetneighDoReply<'_> {
5201 pub fn lookup_attr(
5202 &self,
5203 offset: usize,
5204 missing_type: Option<u16>,
5205 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5206 let mut stack = Vec::new();
5207 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5208 if cur == offset + PushNdmsg::len() {
5209 stack.push(("OpGetneighDoReply", offset));
5210 return (
5211 stack,
5212 missing_type.and_then(|t| OpGetneighDoReply::attr_from_type(t)),
5213 );
5214 }
5215 if cur > offset || cur + self.buf.len() < offset {
5216 return (stack, None);
5217 }
5218 let mut attrs = self.clone();
5219 let mut last_off = cur + attrs.pos;
5220 while let Some(attr) = attrs.next() {
5221 let Ok(attr) = attr else { break };
5222 match attr {
5223 OpGetneighDoReply::Dst(val) => {
5224 if last_off == offset {
5225 stack.push(("Dst", last_off));
5226 break;
5227 }
5228 }
5229 OpGetneighDoReply::Lladdr(val) => {
5230 if last_off == offset {
5231 stack.push(("Lladdr", last_off));
5232 break;
5233 }
5234 }
5235 OpGetneighDoReply::Probes(val) => {
5236 if last_off == offset {
5237 stack.push(("Probes", last_off));
5238 break;
5239 }
5240 }
5241 OpGetneighDoReply::Vlan(val) => {
5242 if last_off == offset {
5243 stack.push(("Vlan", last_off));
5244 break;
5245 }
5246 }
5247 OpGetneighDoReply::Port(val) => {
5248 if last_off == offset {
5249 stack.push(("Port", last_off));
5250 break;
5251 }
5252 }
5253 OpGetneighDoReply::Vni(val) => {
5254 if last_off == offset {
5255 stack.push(("Vni", last_off));
5256 break;
5257 }
5258 }
5259 OpGetneighDoReply::Ifindex(val) => {
5260 if last_off == offset {
5261 stack.push(("Ifindex", last_off));
5262 break;
5263 }
5264 }
5265 OpGetneighDoReply::Master(val) => {
5266 if last_off == offset {
5267 stack.push(("Master", last_off));
5268 break;
5269 }
5270 }
5271 OpGetneighDoReply::Protocol(val) => {
5272 if last_off == offset {
5273 stack.push(("Protocol", last_off));
5274 break;
5275 }
5276 }
5277 OpGetneighDoReply::NhId(val) => {
5278 if last_off == offset {
5279 stack.push(("NhId", last_off));
5280 break;
5281 }
5282 }
5283 OpGetneighDoReply::FdbExtAttrs(val) => {
5284 if last_off == offset {
5285 stack.push(("FdbExtAttrs", last_off));
5286 break;
5287 }
5288 }
5289 OpGetneighDoReply::FlagsExt(val) => {
5290 if last_off == offset {
5291 stack.push(("FlagsExt", last_off));
5292 break;
5293 }
5294 }
5295 _ => {}
5296 };
5297 last_off = cur + attrs.pos;
5298 }
5299 if !stack.is_empty() {
5300 stack.push(("OpGetneighDoReply", cur));
5301 }
5302 (stack, None)
5303 }
5304}
5305#[derive(Debug)]
5306pub struct RequestOpGetneighDoRequest<'r> {
5307 request: Request<'r>,
5308}
5309impl<'r> RequestOpGetneighDoRequest<'r> {
5310 pub fn new(mut request: Request<'r>, header: &PushNdmsg) -> Self {
5311 PushOpGetneighDoRequest::write_header(&mut request.buf_mut(), header);
5312 Self { request: request }
5313 }
5314 pub fn encode(&mut self) -> PushOpGetneighDoRequest<&mut Vec<u8>> {
5315 PushOpGetneighDoRequest::new_without_header(self.request.buf_mut())
5316 }
5317 pub fn into_encoder(self) -> PushOpGetneighDoRequest<RequestBuf<'r>> {
5318 PushOpGetneighDoRequest::new_without_header(self.request.buf)
5319 }
5320}
5321impl NetlinkRequest for RequestOpGetneighDoRequest<'_> {
5322 type ReplyType<'buf> = (PushNdmsg, IterableOpGetneighDoReply<'buf>);
5323 fn protocol(&self) -> Protocol {
5324 Protocol::Raw {
5325 protonum: 0u16,
5326 request_type: 30u16,
5327 }
5328 }
5329 fn flags(&self) -> u16 {
5330 self.request.flags
5331 }
5332 fn payload(&self) -> &[u8] {
5333 self.request.buf()
5334 }
5335 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5336 OpGetneighDoReply::new(buf)
5337 }
5338 fn lookup(
5339 buf: &[u8],
5340 offset: usize,
5341 missing_type: Option<u16>,
5342 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5343 OpGetneighDoRequest::new(buf)
5344 .1
5345 .lookup_attr(offset, missing_type)
5346 }
5347}
5348#[doc = "Get or dump neighbour tables"]
5349pub struct PushOpGetneightblDumpRequest<Prev: Rec> {
5350 pub(crate) prev: Option<Prev>,
5351 pub(crate) header_offset: Option<usize>,
5352}
5353impl<Prev: Rec> Rec for PushOpGetneightblDumpRequest<Prev> {
5354 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
5355 self.prev.as_mut().unwrap().as_rec_mut()
5356 }
5357}
5358impl<Prev: Rec> PushOpGetneightblDumpRequest<Prev> {
5359 pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
5360 Self::write_header(&mut prev, header);
5361 Self::new_without_header(prev)
5362 }
5363 fn new_without_header(prev: Prev) -> Self {
5364 Self {
5365 prev: Some(prev),
5366 header_offset: None,
5367 }
5368 }
5369 fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
5370 prev.as_rec_mut().extend(header.as_slice());
5371 }
5372 pub fn end_nested(mut self) -> Prev {
5373 let mut prev = self.prev.take().unwrap();
5374 if let Some(header_offset) = &self.header_offset {
5375 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5376 }
5377 prev
5378 }
5379}
5380impl<Prev: Rec> Drop for PushOpGetneightblDumpRequest<Prev> {
5381 fn drop(&mut self) {
5382 if let Some(prev) = &mut self.prev {
5383 if let Some(header_offset) = &self.header_offset {
5384 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5385 }
5386 }
5387 }
5388}
5389#[doc = "Get or dump neighbour tables"]
5390#[derive(Clone)]
5391pub enum OpGetneightblDumpRequest {}
5392impl<'a> IterableOpGetneightblDumpRequest<'a> {}
5393impl OpGetneightblDumpRequest {
5394 pub fn new(buf: &'_ [u8]) -> (PushNdtmsg, IterableOpGetneightblDumpRequest<'_>) {
5395 let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
5396 (
5397 PushNdtmsg::new_from_slice(header).unwrap_or_default(),
5398 IterableOpGetneightblDumpRequest::with_loc(attrs, buf.as_ptr() as usize),
5399 )
5400 }
5401 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5402 NdtAttrs::attr_from_type(r#type)
5403 }
5404}
5405#[derive(Clone, Copy, Default)]
5406pub struct IterableOpGetneightblDumpRequest<'a> {
5407 buf: &'a [u8],
5408 pos: usize,
5409 orig_loc: usize,
5410}
5411impl<'a> IterableOpGetneightblDumpRequest<'a> {
5412 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5413 Self {
5414 buf,
5415 pos: 0,
5416 orig_loc,
5417 }
5418 }
5419 pub fn get_buf(&self) -> &'a [u8] {
5420 self.buf
5421 }
5422}
5423impl<'a> Iterator for IterableOpGetneightblDumpRequest<'a> {
5424 type Item = Result<OpGetneightblDumpRequest, ErrorContext>;
5425 fn next(&mut self) -> Option<Self::Item> {
5426 if self.buf.len() == self.pos {
5427 return None;
5428 }
5429 let pos = self.pos;
5430 let mut r#type = None;
5431 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
5432 r#type = Some(header.r#type);
5433 let res = match header.r#type {
5434 n => {
5435 if cfg!(any(test, feature = "deny-unknown-attrs")) {
5436 break;
5437 } else {
5438 continue;
5439 }
5440 }
5441 };
5442 return Some(Ok(res));
5443 }
5444 Some(Err(ErrorContext::new(
5445 "OpGetneightblDumpRequest",
5446 r#type.and_then(|t| OpGetneightblDumpRequest::attr_from_type(t)),
5447 self.orig_loc,
5448 self.buf.as_ptr().wrapping_add(pos) as usize,
5449 )))
5450 }
5451}
5452impl std::fmt::Debug for IterableOpGetneightblDumpRequest<'_> {
5453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5454 let mut fmt = f.debug_struct("OpGetneightblDumpRequest");
5455 for attr in self.clone() {
5456 let attr = match attr {
5457 Ok(a) => a,
5458 Err(err) => {
5459 fmt.finish()?;
5460 f.write_str("Err(")?;
5461 err.fmt(f)?;
5462 return f.write_str(")");
5463 }
5464 };
5465 match attr {};
5466 }
5467 fmt.finish()
5468 }
5469}
5470impl IterableOpGetneightblDumpRequest<'_> {
5471 pub fn lookup_attr(
5472 &self,
5473 offset: usize,
5474 missing_type: Option<u16>,
5475 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5476 let mut stack = Vec::new();
5477 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5478 if cur == offset + PushNdtmsg::len() {
5479 stack.push(("OpGetneightblDumpRequest", offset));
5480 return (
5481 stack,
5482 missing_type.and_then(|t| OpGetneightblDumpRequest::attr_from_type(t)),
5483 );
5484 }
5485 (stack, None)
5486 }
5487}
5488#[doc = "Get or dump neighbour tables"]
5489pub struct PushOpGetneightblDumpReply<Prev: Rec> {
5490 pub(crate) prev: Option<Prev>,
5491 pub(crate) header_offset: Option<usize>,
5492}
5493impl<Prev: Rec> Rec for PushOpGetneightblDumpReply<Prev> {
5494 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
5495 self.prev.as_mut().unwrap().as_rec_mut()
5496 }
5497}
5498impl<Prev: Rec> PushOpGetneightblDumpReply<Prev> {
5499 pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
5500 Self::write_header(&mut prev, header);
5501 Self::new_without_header(prev)
5502 }
5503 fn new_without_header(prev: Prev) -> Self {
5504 Self {
5505 prev: Some(prev),
5506 header_offset: None,
5507 }
5508 }
5509 fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
5510 prev.as_rec_mut().extend(header.as_slice());
5511 }
5512 pub fn end_nested(mut self) -> Prev {
5513 let mut prev = self.prev.take().unwrap();
5514 if let Some(header_offset) = &self.header_offset {
5515 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5516 }
5517 prev
5518 }
5519 pub fn push_name(mut self, value: &CStr) -> Self {
5520 push_header(
5521 self.as_rec_mut(),
5522 1u16,
5523 value.to_bytes_with_nul().len() as u16,
5524 );
5525 self.as_rec_mut().extend(value.to_bytes_with_nul());
5526 self
5527 }
5528 pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
5529 push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
5530 self.as_rec_mut().extend(value);
5531 self.as_rec_mut().push(0);
5532 self
5533 }
5534 pub fn push_thresh1(mut self, value: u32) -> Self {
5535 push_header(self.as_rec_mut(), 2u16, 4 as u16);
5536 self.as_rec_mut().extend(value.to_ne_bytes());
5537 self
5538 }
5539 pub fn push_thresh2(mut self, value: u32) -> Self {
5540 push_header(self.as_rec_mut(), 3u16, 4 as u16);
5541 self.as_rec_mut().extend(value.to_ne_bytes());
5542 self
5543 }
5544 pub fn push_thresh3(mut self, value: u32) -> Self {
5545 push_header(self.as_rec_mut(), 4u16, 4 as u16);
5546 self.as_rec_mut().extend(value.to_ne_bytes());
5547 self
5548 }
5549 pub fn push_config(mut self, value: PushNdtConfig) -> Self {
5550 push_header(self.as_rec_mut(), 5u16, value.as_slice().len() as u16);
5551 self.as_rec_mut().extend(value.as_slice());
5552 self
5553 }
5554 pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
5555 let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
5556 PushNdtpaAttrs {
5557 prev: Some(self),
5558 header_offset: Some(header_offset),
5559 }
5560 }
5561 pub fn push_stats(mut self, value: PushNdtStats) -> Self {
5562 push_header(self.as_rec_mut(), 7u16, value.as_slice().len() as u16);
5563 self.as_rec_mut().extend(value.as_slice());
5564 self
5565 }
5566 pub fn push_gc_interval(mut self, value: u64) -> Self {
5567 push_header(self.as_rec_mut(), 8u16, 8 as u16);
5568 self.as_rec_mut().extend(value.to_ne_bytes());
5569 self
5570 }
5571}
5572impl<Prev: Rec> Drop for PushOpGetneightblDumpReply<Prev> {
5573 fn drop(&mut self) {
5574 if let Some(prev) = &mut self.prev {
5575 if let Some(header_offset) = &self.header_offset {
5576 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5577 }
5578 }
5579 }
5580}
5581#[doc = "Get or dump neighbour tables"]
5582#[derive(Clone)]
5583pub enum OpGetneightblDumpReply<'a> {
5584 Name(&'a CStr),
5585 Thresh1(u32),
5586 Thresh2(u32),
5587 Thresh3(u32),
5588 Config(PushNdtConfig),
5589 Parms(IterableNdtpaAttrs<'a>),
5590 Stats(PushNdtStats),
5591 GcInterval(u64),
5592}
5593impl<'a> IterableOpGetneightblDumpReply<'a> {
5594 pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
5595 let mut iter = self.clone();
5596 iter.pos = 0;
5597 for attr in iter {
5598 if let OpGetneightblDumpReply::Name(val) = attr? {
5599 return Ok(val);
5600 }
5601 }
5602 Err(ErrorContext::new_missing(
5603 "OpGetneightblDumpReply",
5604 "Name",
5605 self.orig_loc,
5606 self.buf.as_ptr() as usize,
5607 ))
5608 }
5609 pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
5610 let mut iter = self.clone();
5611 iter.pos = 0;
5612 for attr in iter {
5613 if let OpGetneightblDumpReply::Thresh1(val) = attr? {
5614 return Ok(val);
5615 }
5616 }
5617 Err(ErrorContext::new_missing(
5618 "OpGetneightblDumpReply",
5619 "Thresh1",
5620 self.orig_loc,
5621 self.buf.as_ptr() as usize,
5622 ))
5623 }
5624 pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
5625 let mut iter = self.clone();
5626 iter.pos = 0;
5627 for attr in iter {
5628 if let OpGetneightblDumpReply::Thresh2(val) = attr? {
5629 return Ok(val);
5630 }
5631 }
5632 Err(ErrorContext::new_missing(
5633 "OpGetneightblDumpReply",
5634 "Thresh2",
5635 self.orig_loc,
5636 self.buf.as_ptr() as usize,
5637 ))
5638 }
5639 pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
5640 let mut iter = self.clone();
5641 iter.pos = 0;
5642 for attr in iter {
5643 if let OpGetneightblDumpReply::Thresh3(val) = attr? {
5644 return Ok(val);
5645 }
5646 }
5647 Err(ErrorContext::new_missing(
5648 "OpGetneightblDumpReply",
5649 "Thresh3",
5650 self.orig_loc,
5651 self.buf.as_ptr() as usize,
5652 ))
5653 }
5654 pub fn get_config(&self) -> Result<PushNdtConfig, ErrorContext> {
5655 let mut iter = self.clone();
5656 iter.pos = 0;
5657 for attr in iter {
5658 if let OpGetneightblDumpReply::Config(val) = attr? {
5659 return Ok(val);
5660 }
5661 }
5662 Err(ErrorContext::new_missing(
5663 "OpGetneightblDumpReply",
5664 "Config",
5665 self.orig_loc,
5666 self.buf.as_ptr() as usize,
5667 ))
5668 }
5669 pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
5670 let mut iter = self.clone();
5671 iter.pos = 0;
5672 for attr in iter {
5673 if let OpGetneightblDumpReply::Parms(val) = attr? {
5674 return Ok(val);
5675 }
5676 }
5677 Err(ErrorContext::new_missing(
5678 "OpGetneightblDumpReply",
5679 "Parms",
5680 self.orig_loc,
5681 self.buf.as_ptr() as usize,
5682 ))
5683 }
5684 pub fn get_stats(&self) -> Result<PushNdtStats, ErrorContext> {
5685 let mut iter = self.clone();
5686 iter.pos = 0;
5687 for attr in iter {
5688 if let OpGetneightblDumpReply::Stats(val) = attr? {
5689 return Ok(val);
5690 }
5691 }
5692 Err(ErrorContext::new_missing(
5693 "OpGetneightblDumpReply",
5694 "Stats",
5695 self.orig_loc,
5696 self.buf.as_ptr() as usize,
5697 ))
5698 }
5699 pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
5700 let mut iter = self.clone();
5701 iter.pos = 0;
5702 for attr in iter {
5703 if let OpGetneightblDumpReply::GcInterval(val) = attr? {
5704 return Ok(val);
5705 }
5706 }
5707 Err(ErrorContext::new_missing(
5708 "OpGetneightblDumpReply",
5709 "GcInterval",
5710 self.orig_loc,
5711 self.buf.as_ptr() as usize,
5712 ))
5713 }
5714}
5715impl<'a> OpGetneightblDumpReply<'a> {
5716 pub fn new(buf: &'a [u8]) -> (PushNdtmsg, IterableOpGetneightblDumpReply<'a>) {
5717 let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
5718 (
5719 PushNdtmsg::new_from_slice(header).unwrap_or_default(),
5720 IterableOpGetneightblDumpReply::with_loc(attrs, buf.as_ptr() as usize),
5721 )
5722 }
5723 fn attr_from_type(r#type: u16) -> Option<&'static str> {
5724 NdtAttrs::attr_from_type(r#type)
5725 }
5726}
5727#[derive(Clone, Copy, Default)]
5728pub struct IterableOpGetneightblDumpReply<'a> {
5729 buf: &'a [u8],
5730 pos: usize,
5731 orig_loc: usize,
5732}
5733impl<'a> IterableOpGetneightblDumpReply<'a> {
5734 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
5735 Self {
5736 buf,
5737 pos: 0,
5738 orig_loc,
5739 }
5740 }
5741 pub fn get_buf(&self) -> &'a [u8] {
5742 self.buf
5743 }
5744}
5745impl<'a> Iterator for IterableOpGetneightblDumpReply<'a> {
5746 type Item = Result<OpGetneightblDumpReply<'a>, ErrorContext>;
5747 fn next(&mut self) -> Option<Self::Item> {
5748 if self.buf.len() == self.pos {
5749 return None;
5750 }
5751 let pos = self.pos;
5752 let mut r#type = None;
5753 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
5754 r#type = Some(header.r#type);
5755 let res = match header.r#type {
5756 1u16 => OpGetneightblDumpReply::Name({
5757 let res = CStr::from_bytes_with_nul(next).ok();
5758 let Some(val) = res else { break };
5759 val
5760 }),
5761 2u16 => OpGetneightblDumpReply::Thresh1({
5762 let res = parse_u32(next);
5763 let Some(val) = res else { break };
5764 val
5765 }),
5766 3u16 => OpGetneightblDumpReply::Thresh2({
5767 let res = parse_u32(next);
5768 let Some(val) = res else { break };
5769 val
5770 }),
5771 4u16 => OpGetneightblDumpReply::Thresh3({
5772 let res = parse_u32(next);
5773 let Some(val) = res else { break };
5774 val
5775 }),
5776 5u16 => OpGetneightblDumpReply::Config({
5777 let res = PushNdtConfig::new_from_slice(next);
5778 let Some(val) = res else { break };
5779 val
5780 }),
5781 6u16 => OpGetneightblDumpReply::Parms({
5782 let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
5783 let Some(val) = res else { break };
5784 val
5785 }),
5786 7u16 => OpGetneightblDumpReply::Stats({
5787 let res = PushNdtStats::new_from_slice(next);
5788 let Some(val) = res else { break };
5789 val
5790 }),
5791 8u16 => OpGetneightblDumpReply::GcInterval({
5792 let res = parse_u64(next);
5793 let Some(val) = res else { break };
5794 val
5795 }),
5796 n => {
5797 if cfg!(any(test, feature = "deny-unknown-attrs")) {
5798 break;
5799 } else {
5800 continue;
5801 }
5802 }
5803 };
5804 return Some(Ok(res));
5805 }
5806 Some(Err(ErrorContext::new(
5807 "OpGetneightblDumpReply",
5808 r#type.and_then(|t| OpGetneightblDumpReply::attr_from_type(t)),
5809 self.orig_loc,
5810 self.buf.as_ptr().wrapping_add(pos) as usize,
5811 )))
5812 }
5813}
5814impl<'a> std::fmt::Debug for IterableOpGetneightblDumpReply<'_> {
5815 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5816 let mut fmt = f.debug_struct("OpGetneightblDumpReply");
5817 for attr in self.clone() {
5818 let attr = match attr {
5819 Ok(a) => a,
5820 Err(err) => {
5821 fmt.finish()?;
5822 f.write_str("Err(")?;
5823 err.fmt(f)?;
5824 return f.write_str(")");
5825 }
5826 };
5827 match attr {
5828 OpGetneightblDumpReply::Name(val) => fmt.field("Name", &val),
5829 OpGetneightblDumpReply::Thresh1(val) => fmt.field("Thresh1", &val),
5830 OpGetneightblDumpReply::Thresh2(val) => fmt.field("Thresh2", &val),
5831 OpGetneightblDumpReply::Thresh3(val) => fmt.field("Thresh3", &val),
5832 OpGetneightblDumpReply::Config(val) => fmt.field("Config", &val),
5833 OpGetneightblDumpReply::Parms(val) => fmt.field("Parms", &val),
5834 OpGetneightblDumpReply::Stats(val) => fmt.field("Stats", &val),
5835 OpGetneightblDumpReply::GcInterval(val) => fmt.field("GcInterval", &val),
5836 };
5837 }
5838 fmt.finish()
5839 }
5840}
5841impl IterableOpGetneightblDumpReply<'_> {
5842 pub fn lookup_attr(
5843 &self,
5844 offset: usize,
5845 missing_type: Option<u16>,
5846 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5847 let mut stack = Vec::new();
5848 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
5849 if cur == offset + PushNdtmsg::len() {
5850 stack.push(("OpGetneightblDumpReply", offset));
5851 return (
5852 stack,
5853 missing_type.and_then(|t| OpGetneightblDumpReply::attr_from_type(t)),
5854 );
5855 }
5856 if cur > offset || cur + self.buf.len() < offset {
5857 return (stack, None);
5858 }
5859 let mut attrs = self.clone();
5860 let mut last_off = cur + attrs.pos;
5861 let mut missing = None;
5862 while let Some(attr) = attrs.next() {
5863 let Ok(attr) = attr else { break };
5864 match attr {
5865 OpGetneightblDumpReply::Name(val) => {
5866 if last_off == offset {
5867 stack.push(("Name", last_off));
5868 break;
5869 }
5870 }
5871 OpGetneightblDumpReply::Thresh1(val) => {
5872 if last_off == offset {
5873 stack.push(("Thresh1", last_off));
5874 break;
5875 }
5876 }
5877 OpGetneightblDumpReply::Thresh2(val) => {
5878 if last_off == offset {
5879 stack.push(("Thresh2", last_off));
5880 break;
5881 }
5882 }
5883 OpGetneightblDumpReply::Thresh3(val) => {
5884 if last_off == offset {
5885 stack.push(("Thresh3", last_off));
5886 break;
5887 }
5888 }
5889 OpGetneightblDumpReply::Config(val) => {
5890 if last_off == offset {
5891 stack.push(("Config", last_off));
5892 break;
5893 }
5894 }
5895 OpGetneightblDumpReply::Parms(val) => {
5896 (stack, missing) = val.lookup_attr(offset, missing_type);
5897 if !stack.is_empty() {
5898 break;
5899 }
5900 }
5901 OpGetneightblDumpReply::Stats(val) => {
5902 if last_off == offset {
5903 stack.push(("Stats", last_off));
5904 break;
5905 }
5906 }
5907 OpGetneightblDumpReply::GcInterval(val) => {
5908 if last_off == offset {
5909 stack.push(("GcInterval", last_off));
5910 break;
5911 }
5912 }
5913 _ => {}
5914 };
5915 last_off = cur + attrs.pos;
5916 }
5917 if !stack.is_empty() {
5918 stack.push(("OpGetneightblDumpReply", cur));
5919 }
5920 (stack, missing)
5921 }
5922}
5923#[derive(Debug)]
5924pub struct RequestOpGetneightblDumpRequest<'r> {
5925 request: Request<'r>,
5926}
5927impl<'r> RequestOpGetneightblDumpRequest<'r> {
5928 pub fn new(mut request: Request<'r>, header: &PushNdtmsg) -> Self {
5929 PushOpGetneightblDumpRequest::write_header(&mut request.buf_mut(), header);
5930 Self {
5931 request: request.set_dump(),
5932 }
5933 }
5934 pub fn encode(&mut self) -> PushOpGetneightblDumpRequest<&mut Vec<u8>> {
5935 PushOpGetneightblDumpRequest::new_without_header(self.request.buf_mut())
5936 }
5937 pub fn into_encoder(self) -> PushOpGetneightblDumpRequest<RequestBuf<'r>> {
5938 PushOpGetneightblDumpRequest::new_without_header(self.request.buf)
5939 }
5940}
5941impl NetlinkRequest for RequestOpGetneightblDumpRequest<'_> {
5942 type ReplyType<'buf> = (PushNdtmsg, IterableOpGetneightblDumpReply<'buf>);
5943 fn protocol(&self) -> Protocol {
5944 Protocol::Raw {
5945 protonum: 0u16,
5946 request_type: 66u16,
5947 }
5948 }
5949 fn flags(&self) -> u16 {
5950 self.request.flags
5951 }
5952 fn payload(&self) -> &[u8] {
5953 self.request.buf()
5954 }
5955 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
5956 OpGetneightblDumpReply::new(buf)
5957 }
5958 fn lookup(
5959 buf: &[u8],
5960 offset: usize,
5961 missing_type: Option<u16>,
5962 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
5963 OpGetneightblDumpRequest::new(buf)
5964 .1
5965 .lookup_attr(offset, missing_type)
5966 }
5967}
5968#[doc = "Set neighbour tables"]
5969pub struct PushOpSetneightblDoRequest<Prev: Rec> {
5970 pub(crate) prev: Option<Prev>,
5971 pub(crate) header_offset: Option<usize>,
5972}
5973impl<Prev: Rec> Rec for PushOpSetneightblDoRequest<Prev> {
5974 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
5975 self.prev.as_mut().unwrap().as_rec_mut()
5976 }
5977}
5978impl<Prev: Rec> PushOpSetneightblDoRequest<Prev> {
5979 pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
5980 Self::write_header(&mut prev, header);
5981 Self::new_without_header(prev)
5982 }
5983 fn new_without_header(prev: Prev) -> Self {
5984 Self {
5985 prev: Some(prev),
5986 header_offset: None,
5987 }
5988 }
5989 fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
5990 prev.as_rec_mut().extend(header.as_slice());
5991 }
5992 pub fn end_nested(mut self) -> Prev {
5993 let mut prev = self.prev.take().unwrap();
5994 if let Some(header_offset) = &self.header_offset {
5995 finalize_nested_header(prev.as_rec_mut(), *header_offset);
5996 }
5997 prev
5998 }
5999 pub fn push_name(mut self, value: &CStr) -> Self {
6000 push_header(
6001 self.as_rec_mut(),
6002 1u16,
6003 value.to_bytes_with_nul().len() as u16,
6004 );
6005 self.as_rec_mut().extend(value.to_bytes_with_nul());
6006 self
6007 }
6008 pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
6009 push_header(self.as_rec_mut(), 1u16, (value.len() + 1) as u16);
6010 self.as_rec_mut().extend(value);
6011 self.as_rec_mut().push(0);
6012 self
6013 }
6014 pub fn push_thresh1(mut self, value: u32) -> Self {
6015 push_header(self.as_rec_mut(), 2u16, 4 as u16);
6016 self.as_rec_mut().extend(value.to_ne_bytes());
6017 self
6018 }
6019 pub fn push_thresh2(mut self, value: u32) -> Self {
6020 push_header(self.as_rec_mut(), 3u16, 4 as u16);
6021 self.as_rec_mut().extend(value.to_ne_bytes());
6022 self
6023 }
6024 pub fn push_thresh3(mut self, value: u32) -> Self {
6025 push_header(self.as_rec_mut(), 4u16, 4 as u16);
6026 self.as_rec_mut().extend(value.to_ne_bytes());
6027 self
6028 }
6029 pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
6030 let header_offset = push_nested_header(self.as_rec_mut(), 6u16);
6031 PushNdtpaAttrs {
6032 prev: Some(self),
6033 header_offset: Some(header_offset),
6034 }
6035 }
6036 pub fn push_gc_interval(mut self, value: u64) -> Self {
6037 push_header(self.as_rec_mut(), 8u16, 8 as u16);
6038 self.as_rec_mut().extend(value.to_ne_bytes());
6039 self
6040 }
6041}
6042impl<Prev: Rec> Drop for PushOpSetneightblDoRequest<Prev> {
6043 fn drop(&mut self) {
6044 if let Some(prev) = &mut self.prev {
6045 if let Some(header_offset) = &self.header_offset {
6046 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6047 }
6048 }
6049 }
6050}
6051#[doc = "Set neighbour tables"]
6052#[derive(Clone)]
6053pub enum OpSetneightblDoRequest<'a> {
6054 Name(&'a CStr),
6055 Thresh1(u32),
6056 Thresh2(u32),
6057 Thresh3(u32),
6058 Parms(IterableNdtpaAttrs<'a>),
6059 GcInterval(u64),
6060}
6061impl<'a> IterableOpSetneightblDoRequest<'a> {
6062 pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
6063 let mut iter = self.clone();
6064 iter.pos = 0;
6065 for attr in iter {
6066 if let OpSetneightblDoRequest::Name(val) = attr? {
6067 return Ok(val);
6068 }
6069 }
6070 Err(ErrorContext::new_missing(
6071 "OpSetneightblDoRequest",
6072 "Name",
6073 self.orig_loc,
6074 self.buf.as_ptr() as usize,
6075 ))
6076 }
6077 pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
6078 let mut iter = self.clone();
6079 iter.pos = 0;
6080 for attr in iter {
6081 if let OpSetneightblDoRequest::Thresh1(val) = attr? {
6082 return Ok(val);
6083 }
6084 }
6085 Err(ErrorContext::new_missing(
6086 "OpSetneightblDoRequest",
6087 "Thresh1",
6088 self.orig_loc,
6089 self.buf.as_ptr() as usize,
6090 ))
6091 }
6092 pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
6093 let mut iter = self.clone();
6094 iter.pos = 0;
6095 for attr in iter {
6096 if let OpSetneightblDoRequest::Thresh2(val) = attr? {
6097 return Ok(val);
6098 }
6099 }
6100 Err(ErrorContext::new_missing(
6101 "OpSetneightblDoRequest",
6102 "Thresh2",
6103 self.orig_loc,
6104 self.buf.as_ptr() as usize,
6105 ))
6106 }
6107 pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
6108 let mut iter = self.clone();
6109 iter.pos = 0;
6110 for attr in iter {
6111 if let OpSetneightblDoRequest::Thresh3(val) = attr? {
6112 return Ok(val);
6113 }
6114 }
6115 Err(ErrorContext::new_missing(
6116 "OpSetneightblDoRequest",
6117 "Thresh3",
6118 self.orig_loc,
6119 self.buf.as_ptr() as usize,
6120 ))
6121 }
6122 pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
6123 let mut iter = self.clone();
6124 iter.pos = 0;
6125 for attr in iter {
6126 if let OpSetneightblDoRequest::Parms(val) = attr? {
6127 return Ok(val);
6128 }
6129 }
6130 Err(ErrorContext::new_missing(
6131 "OpSetneightblDoRequest",
6132 "Parms",
6133 self.orig_loc,
6134 self.buf.as_ptr() as usize,
6135 ))
6136 }
6137 pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
6138 let mut iter = self.clone();
6139 iter.pos = 0;
6140 for attr in iter {
6141 if let OpSetneightblDoRequest::GcInterval(val) = attr? {
6142 return Ok(val);
6143 }
6144 }
6145 Err(ErrorContext::new_missing(
6146 "OpSetneightblDoRequest",
6147 "GcInterval",
6148 self.orig_loc,
6149 self.buf.as_ptr() as usize,
6150 ))
6151 }
6152}
6153impl<'a> OpSetneightblDoRequest<'a> {
6154 pub fn new(buf: &'a [u8]) -> (PushNdtmsg, IterableOpSetneightblDoRequest<'a>) {
6155 let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
6156 (
6157 PushNdtmsg::new_from_slice(header).unwrap_or_default(),
6158 IterableOpSetneightblDoRequest::with_loc(attrs, buf.as_ptr() as usize),
6159 )
6160 }
6161 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6162 NdtAttrs::attr_from_type(r#type)
6163 }
6164}
6165#[derive(Clone, Copy, Default)]
6166pub struct IterableOpSetneightblDoRequest<'a> {
6167 buf: &'a [u8],
6168 pos: usize,
6169 orig_loc: usize,
6170}
6171impl<'a> IterableOpSetneightblDoRequest<'a> {
6172 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6173 Self {
6174 buf,
6175 pos: 0,
6176 orig_loc,
6177 }
6178 }
6179 pub fn get_buf(&self) -> &'a [u8] {
6180 self.buf
6181 }
6182}
6183impl<'a> Iterator for IterableOpSetneightblDoRequest<'a> {
6184 type Item = Result<OpSetneightblDoRequest<'a>, ErrorContext>;
6185 fn next(&mut self) -> Option<Self::Item> {
6186 if self.buf.len() == self.pos {
6187 return None;
6188 }
6189 let pos = self.pos;
6190 let mut r#type = None;
6191 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
6192 r#type = Some(header.r#type);
6193 let res = match header.r#type {
6194 1u16 => OpSetneightblDoRequest::Name({
6195 let res = CStr::from_bytes_with_nul(next).ok();
6196 let Some(val) = res else { break };
6197 val
6198 }),
6199 2u16 => OpSetneightblDoRequest::Thresh1({
6200 let res = parse_u32(next);
6201 let Some(val) = res else { break };
6202 val
6203 }),
6204 3u16 => OpSetneightblDoRequest::Thresh2({
6205 let res = parse_u32(next);
6206 let Some(val) = res else { break };
6207 val
6208 }),
6209 4u16 => OpSetneightblDoRequest::Thresh3({
6210 let res = parse_u32(next);
6211 let Some(val) = res else { break };
6212 val
6213 }),
6214 6u16 => OpSetneightblDoRequest::Parms({
6215 let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
6216 let Some(val) = res else { break };
6217 val
6218 }),
6219 8u16 => OpSetneightblDoRequest::GcInterval({
6220 let res = parse_u64(next);
6221 let Some(val) = res else { break };
6222 val
6223 }),
6224 n => {
6225 if cfg!(any(test, feature = "deny-unknown-attrs")) {
6226 break;
6227 } else {
6228 continue;
6229 }
6230 }
6231 };
6232 return Some(Ok(res));
6233 }
6234 Some(Err(ErrorContext::new(
6235 "OpSetneightblDoRequest",
6236 r#type.and_then(|t| OpSetneightblDoRequest::attr_from_type(t)),
6237 self.orig_loc,
6238 self.buf.as_ptr().wrapping_add(pos) as usize,
6239 )))
6240 }
6241}
6242impl<'a> std::fmt::Debug for IterableOpSetneightblDoRequest<'_> {
6243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6244 let mut fmt = f.debug_struct("OpSetneightblDoRequest");
6245 for attr in self.clone() {
6246 let attr = match attr {
6247 Ok(a) => a,
6248 Err(err) => {
6249 fmt.finish()?;
6250 f.write_str("Err(")?;
6251 err.fmt(f)?;
6252 return f.write_str(")");
6253 }
6254 };
6255 match attr {
6256 OpSetneightblDoRequest::Name(val) => fmt.field("Name", &val),
6257 OpSetneightblDoRequest::Thresh1(val) => fmt.field("Thresh1", &val),
6258 OpSetneightblDoRequest::Thresh2(val) => fmt.field("Thresh2", &val),
6259 OpSetneightblDoRequest::Thresh3(val) => fmt.field("Thresh3", &val),
6260 OpSetneightblDoRequest::Parms(val) => fmt.field("Parms", &val),
6261 OpSetneightblDoRequest::GcInterval(val) => fmt.field("GcInterval", &val),
6262 };
6263 }
6264 fmt.finish()
6265 }
6266}
6267impl IterableOpSetneightblDoRequest<'_> {
6268 pub fn lookup_attr(
6269 &self,
6270 offset: usize,
6271 missing_type: Option<u16>,
6272 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6273 let mut stack = Vec::new();
6274 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6275 if cur == offset + PushNdtmsg::len() {
6276 stack.push(("OpSetneightblDoRequest", offset));
6277 return (
6278 stack,
6279 missing_type.and_then(|t| OpSetneightblDoRequest::attr_from_type(t)),
6280 );
6281 }
6282 if cur > offset || cur + self.buf.len() < offset {
6283 return (stack, None);
6284 }
6285 let mut attrs = self.clone();
6286 let mut last_off = cur + attrs.pos;
6287 let mut missing = None;
6288 while let Some(attr) = attrs.next() {
6289 let Ok(attr) = attr else { break };
6290 match attr {
6291 OpSetneightblDoRequest::Name(val) => {
6292 if last_off == offset {
6293 stack.push(("Name", last_off));
6294 break;
6295 }
6296 }
6297 OpSetneightblDoRequest::Thresh1(val) => {
6298 if last_off == offset {
6299 stack.push(("Thresh1", last_off));
6300 break;
6301 }
6302 }
6303 OpSetneightblDoRequest::Thresh2(val) => {
6304 if last_off == offset {
6305 stack.push(("Thresh2", last_off));
6306 break;
6307 }
6308 }
6309 OpSetneightblDoRequest::Thresh3(val) => {
6310 if last_off == offset {
6311 stack.push(("Thresh3", last_off));
6312 break;
6313 }
6314 }
6315 OpSetneightblDoRequest::Parms(val) => {
6316 (stack, missing) = val.lookup_attr(offset, missing_type);
6317 if !stack.is_empty() {
6318 break;
6319 }
6320 }
6321 OpSetneightblDoRequest::GcInterval(val) => {
6322 if last_off == offset {
6323 stack.push(("GcInterval", last_off));
6324 break;
6325 }
6326 }
6327 _ => {}
6328 };
6329 last_off = cur + attrs.pos;
6330 }
6331 if !stack.is_empty() {
6332 stack.push(("OpSetneightblDoRequest", cur));
6333 }
6334 (stack, missing)
6335 }
6336}
6337#[doc = "Set neighbour tables"]
6338pub struct PushOpSetneightblDoReply<Prev: Rec> {
6339 pub(crate) prev: Option<Prev>,
6340 pub(crate) header_offset: Option<usize>,
6341}
6342impl<Prev: Rec> Rec for PushOpSetneightblDoReply<Prev> {
6343 fn as_rec_mut(&mut self) -> &mut Vec<u8> {
6344 self.prev.as_mut().unwrap().as_rec_mut()
6345 }
6346}
6347impl<Prev: Rec> PushOpSetneightblDoReply<Prev> {
6348 pub fn new(mut prev: Prev, header: &PushNdtmsg) -> Self {
6349 Self::write_header(&mut prev, header);
6350 Self::new_without_header(prev)
6351 }
6352 fn new_without_header(prev: Prev) -> Self {
6353 Self {
6354 prev: Some(prev),
6355 header_offset: None,
6356 }
6357 }
6358 fn write_header(prev: &mut Prev, header: &PushNdtmsg) {
6359 prev.as_rec_mut().extend(header.as_slice());
6360 }
6361 pub fn end_nested(mut self) -> Prev {
6362 let mut prev = self.prev.take().unwrap();
6363 if let Some(header_offset) = &self.header_offset {
6364 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6365 }
6366 prev
6367 }
6368}
6369impl<Prev: Rec> Drop for PushOpSetneightblDoReply<Prev> {
6370 fn drop(&mut self) {
6371 if let Some(prev) = &mut self.prev {
6372 if let Some(header_offset) = &self.header_offset {
6373 finalize_nested_header(prev.as_rec_mut(), *header_offset);
6374 }
6375 }
6376 }
6377}
6378#[doc = "Set neighbour tables"]
6379#[derive(Clone)]
6380pub enum OpSetneightblDoReply {}
6381impl<'a> IterableOpSetneightblDoReply<'a> {}
6382impl OpSetneightblDoReply {
6383 pub fn new(buf: &'_ [u8]) -> (PushNdtmsg, IterableOpSetneightblDoReply<'_>) {
6384 let (header, attrs) = buf.split_at(buf.len().min(PushNdtmsg::len()));
6385 (
6386 PushNdtmsg::new_from_slice(header).unwrap_or_default(),
6387 IterableOpSetneightblDoReply::with_loc(attrs, buf.as_ptr() as usize),
6388 )
6389 }
6390 fn attr_from_type(r#type: u16) -> Option<&'static str> {
6391 NdtAttrs::attr_from_type(r#type)
6392 }
6393}
6394#[derive(Clone, Copy, Default)]
6395pub struct IterableOpSetneightblDoReply<'a> {
6396 buf: &'a [u8],
6397 pos: usize,
6398 orig_loc: usize,
6399}
6400impl<'a> IterableOpSetneightblDoReply<'a> {
6401 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
6402 Self {
6403 buf,
6404 pos: 0,
6405 orig_loc,
6406 }
6407 }
6408 pub fn get_buf(&self) -> &'a [u8] {
6409 self.buf
6410 }
6411}
6412impl<'a> Iterator for IterableOpSetneightblDoReply<'a> {
6413 type Item = Result<OpSetneightblDoReply, ErrorContext>;
6414 fn next(&mut self) -> Option<Self::Item> {
6415 if self.buf.len() == self.pos {
6416 return None;
6417 }
6418 let pos = self.pos;
6419 let mut r#type = None;
6420 while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
6421 r#type = Some(header.r#type);
6422 let res = match header.r#type {
6423 n => {
6424 if cfg!(any(test, feature = "deny-unknown-attrs")) {
6425 break;
6426 } else {
6427 continue;
6428 }
6429 }
6430 };
6431 return Some(Ok(res));
6432 }
6433 Some(Err(ErrorContext::new(
6434 "OpSetneightblDoReply",
6435 r#type.and_then(|t| OpSetneightblDoReply::attr_from_type(t)),
6436 self.orig_loc,
6437 self.buf.as_ptr().wrapping_add(pos) as usize,
6438 )))
6439 }
6440}
6441impl std::fmt::Debug for IterableOpSetneightblDoReply<'_> {
6442 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
6443 let mut fmt = f.debug_struct("OpSetneightblDoReply");
6444 for attr in self.clone() {
6445 let attr = match attr {
6446 Ok(a) => a,
6447 Err(err) => {
6448 fmt.finish()?;
6449 f.write_str("Err(")?;
6450 err.fmt(f)?;
6451 return f.write_str(")");
6452 }
6453 };
6454 match attr {};
6455 }
6456 fmt.finish()
6457 }
6458}
6459impl IterableOpSetneightblDoReply<'_> {
6460 pub fn lookup_attr(
6461 &self,
6462 offset: usize,
6463 missing_type: Option<u16>,
6464 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6465 let mut stack = Vec::new();
6466 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
6467 if cur == offset + PushNdtmsg::len() {
6468 stack.push(("OpSetneightblDoReply", offset));
6469 return (
6470 stack,
6471 missing_type.and_then(|t| OpSetneightblDoReply::attr_from_type(t)),
6472 );
6473 }
6474 (stack, None)
6475 }
6476}
6477#[derive(Debug)]
6478pub struct RequestOpSetneightblDoRequest<'r> {
6479 request: Request<'r>,
6480}
6481impl<'r> RequestOpSetneightblDoRequest<'r> {
6482 pub fn new(mut request: Request<'r>, header: &PushNdtmsg) -> Self {
6483 PushOpSetneightblDoRequest::write_header(&mut request.buf_mut(), header);
6484 Self { request: request }
6485 }
6486 pub fn encode(&mut self) -> PushOpSetneightblDoRequest<&mut Vec<u8>> {
6487 PushOpSetneightblDoRequest::new_without_header(self.request.buf_mut())
6488 }
6489 pub fn into_encoder(self) -> PushOpSetneightblDoRequest<RequestBuf<'r>> {
6490 PushOpSetneightblDoRequest::new_without_header(self.request.buf)
6491 }
6492}
6493impl NetlinkRequest for RequestOpSetneightblDoRequest<'_> {
6494 type ReplyType<'buf> = (PushNdtmsg, IterableOpSetneightblDoReply<'buf>);
6495 fn protocol(&self) -> Protocol {
6496 Protocol::Raw {
6497 protonum: 0u16,
6498 request_type: 67u16,
6499 }
6500 }
6501 fn flags(&self) -> u16 {
6502 self.request.flags
6503 }
6504 fn payload(&self) -> &[u8] {
6505 self.request.buf()
6506 }
6507 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
6508 OpSetneightblDoReply::new(buf)
6509 }
6510 fn lookup(
6511 buf: &[u8],
6512 offset: usize,
6513 missing_type: Option<u16>,
6514 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
6515 OpSetneightblDoRequest::new(buf)
6516 .1
6517 .lookup_attr(offset, missing_type)
6518 }
6519}
6520#[derive(Debug)]
6521pub struct ChainedFinal<'a> {
6522 inner: Chained<'a>,
6523}
6524#[derive(Debug)]
6525pub struct Chained<'a> {
6526 buf: RequestBuf<'a>,
6527 first_seq: u32,
6528 lookups: Vec<(&'static str, LookupFn)>,
6529 last_header_offset: usize,
6530 last_kind: Option<RequestInfo>,
6531}
6532impl<'a> ChainedFinal<'a> {
6533 pub fn into_chained(self) -> Chained<'a> {
6534 self.inner
6535 }
6536 pub fn buf(&self) -> &Vec<u8> {
6537 self.inner.buf()
6538 }
6539 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6540 self.inner.buf_mut()
6541 }
6542 fn get_index(&self, seq: u32) -> Option<u32> {
6543 let min = self.inner.first_seq;
6544 let max = min.wrapping_add(self.inner.lookups.len() as u32);
6545 return if min <= max {
6546 (min..max).contains(&seq).then(|| seq - min)
6547 } else if min <= seq {
6548 Some(seq - min)
6549 } else if seq < max {
6550 Some(u32::MAX - min + seq)
6551 } else {
6552 None
6553 };
6554 }
6555}
6556impl crate::traits::NetlinkChained for ChainedFinal<'_> {
6557 fn protonum(&self) -> u16 {
6558 PROTONUM
6559 }
6560 fn payload(&self) -> &[u8] {
6561 self.buf()
6562 }
6563 fn chain_len(&self) -> usize {
6564 self.inner.lookups.len()
6565 }
6566 fn get_index(&self, seq: u32) -> Option<usize> {
6567 self.get_index(seq).map(|n| n as usize)
6568 }
6569 fn name(&self, index: usize) -> &'static str {
6570 self.inner.lookups[index].0
6571 }
6572 fn lookup(&self, index: usize) -> LookupFn {
6573 self.inner.lookups[index].1
6574 }
6575}
6576impl Chained<'static> {
6577 pub fn new(first_seq: u32) -> Self {
6578 Self::new_from_buf(Vec::new(), first_seq)
6579 }
6580 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
6581 Self {
6582 buf: RequestBuf::Own(buf),
6583 first_seq,
6584 lookups: Vec::new(),
6585 last_header_offset: 0,
6586 last_kind: None,
6587 }
6588 }
6589 pub fn into_buf(self) -> Vec<u8> {
6590 match self.buf {
6591 RequestBuf::Own(buf) => buf,
6592 _ => unreachable!(),
6593 }
6594 }
6595}
6596impl<'a> Chained<'a> {
6597 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
6598 Self {
6599 buf: RequestBuf::Ref(buf),
6600 first_seq,
6601 lookups: Vec::new(),
6602 last_header_offset: 0,
6603 last_kind: None,
6604 }
6605 }
6606 pub fn finalize(mut self) -> ChainedFinal<'a> {
6607 self.update_header();
6608 ChainedFinal { inner: self }
6609 }
6610 pub fn request(&mut self) -> Request<'_> {
6611 self.update_header();
6612 self.last_header_offset = self.buf().len();
6613 self.buf_mut()
6614 .extend_from_slice(PushNlmsghdr::new().as_slice());
6615 let mut request = Request::new_extend(self.buf.buf_mut());
6616 self.last_kind = None;
6617 request.writeback = Some(&mut self.last_kind);
6618 request
6619 }
6620 pub fn buf(&self) -> &Vec<u8> {
6621 self.buf.buf()
6622 }
6623 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6624 self.buf.buf_mut()
6625 }
6626 fn update_header(&mut self) {
6627 let Some(RequestInfo {
6628 protocol,
6629 flags,
6630 name,
6631 lookup,
6632 }) = self.last_kind
6633 else {
6634 if !self.buf().is_empty() {
6635 assert_eq!(
6636 self.last_header_offset + PushNlmsghdr::len(),
6637 self.buf().len()
6638 );
6639 self.buf.buf_mut().truncate(self.last_header_offset);
6640 }
6641 return;
6642 };
6643 let header_offset = self.last_header_offset;
6644 let request_type = match protocol {
6645 Protocol::Raw { request_type, .. } => request_type,
6646 Protocol::Generic(_) => unreachable!(),
6647 };
6648 let index = self.lookups.len();
6649 let seq = self.first_seq.wrapping_add(index as u32);
6650 self.lookups.push((name, lookup));
6651 let buf = self.buf_mut();
6652 align(buf);
6653 let mut header = PushNlmsghdr::new();
6654 header.set_len((buf.len() - header_offset) as u32);
6655 header.set_type(request_type);
6656 header.set_flags(flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16);
6657 header.set_seq(seq);
6658 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
6659 }
6660}
6661use crate::traits::LookupFn;
6662use crate::utils::RequestBuf;
6663#[derive(Debug)]
6664pub struct Request<'buf> {
6665 buf: RequestBuf<'buf>,
6666 flags: u16,
6667 writeback: Option<&'buf mut Option<RequestInfo>>,
6668}
6669#[allow(unused)]
6670#[derive(Debug, Clone)]
6671pub struct RequestInfo {
6672 protocol: Protocol,
6673 flags: u16,
6674 name: &'static str,
6675 lookup: LookupFn,
6676}
6677impl Request<'static> {
6678 pub fn new() -> Self {
6679 Self::new_from_buf(Vec::new())
6680 }
6681 pub fn new_from_buf(buf: Vec<u8>) -> Self {
6682 Self {
6683 flags: 0,
6684 buf: RequestBuf::Own(buf),
6685 writeback: None,
6686 }
6687 }
6688 pub fn into_buf(self) -> Vec<u8> {
6689 match self.buf {
6690 RequestBuf::Own(buf) => buf,
6691 _ => unreachable!(),
6692 }
6693 }
6694}
6695impl<'buf> Request<'buf> {
6696 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
6697 buf.clear();
6698 Self::new_extend(buf)
6699 }
6700 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
6701 Self {
6702 flags: 0,
6703 buf: RequestBuf::Ref(buf),
6704 writeback: None,
6705 }
6706 }
6707 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
6708 let Some(writeback) = &mut self.writeback else {
6709 return;
6710 };
6711 **writeback = Some(RequestInfo {
6712 protocol,
6713 flags: self.flags,
6714 name,
6715 lookup,
6716 })
6717 }
6718 pub fn buf(&self) -> &Vec<u8> {
6719 self.buf.buf()
6720 }
6721 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
6722 self.buf.buf_mut()
6723 }
6724 #[doc = "Set `NLM_F_CREATE` flag"]
6725 pub fn set_create(mut self) -> Self {
6726 self.flags |= consts::NLM_F_CREATE as u16;
6727 self
6728 }
6729 #[doc = "Set `NLM_F_EXCL` flag"]
6730 pub fn set_excl(mut self) -> Self {
6731 self.flags |= consts::NLM_F_EXCL as u16;
6732 self
6733 }
6734 #[doc = "Set `NLM_F_REPLACE` flag"]
6735 pub fn set_replace(mut self) -> Self {
6736 self.flags |= consts::NLM_F_REPLACE as u16;
6737 self
6738 }
6739 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
6740 pub fn set_change(self) -> Self {
6741 self.set_create().set_replace()
6742 }
6743 #[doc = "Set `NLM_F_APPEND` flag"]
6744 pub fn set_append(mut self) -> Self {
6745 self.flags |= consts::NLM_F_APPEND as u16;
6746 self
6747 }
6748 #[doc = "Set `NLM_F_DUMP` flag"]
6749 fn set_dump(mut self) -> Self {
6750 self.flags |= consts::NLM_F_DUMP as u16;
6751 self
6752 }
6753 pub fn op_newneigh_do_request(self, header: &PushNdmsg) -> RequestOpNewneighDoRequest<'buf> {
6754 let mut res = RequestOpNewneighDoRequest::new(self, header);
6755 res.request.do_writeback(
6756 res.protocol(),
6757 "op-newneigh-do-request",
6758 RequestOpNewneighDoRequest::lookup,
6759 );
6760 res
6761 }
6762 pub fn op_delneigh_do_request(self, header: &PushNdmsg) -> RequestOpDelneighDoRequest<'buf> {
6763 let mut res = RequestOpDelneighDoRequest::new(self, header);
6764 res.request.do_writeback(
6765 res.protocol(),
6766 "op-delneigh-do-request",
6767 RequestOpDelneighDoRequest::lookup,
6768 );
6769 res
6770 }
6771 pub fn op_getneigh_dump_request(
6772 self,
6773 header: &PushNdmsg,
6774 ) -> RequestOpGetneighDumpRequest<'buf> {
6775 let mut res = RequestOpGetneighDumpRequest::new(self, header);
6776 res.request.do_writeback(
6777 res.protocol(),
6778 "op-getneigh-dump-request",
6779 RequestOpGetneighDumpRequest::lookup,
6780 );
6781 res
6782 }
6783 pub fn op_getneigh_do_request(self, header: &PushNdmsg) -> RequestOpGetneighDoRequest<'buf> {
6784 let mut res = RequestOpGetneighDoRequest::new(self, header);
6785 res.request.do_writeback(
6786 res.protocol(),
6787 "op-getneigh-do-request",
6788 RequestOpGetneighDoRequest::lookup,
6789 );
6790 res
6791 }
6792 pub fn op_getneightbl_dump_request(
6793 self,
6794 header: &PushNdtmsg,
6795 ) -> RequestOpGetneightblDumpRequest<'buf> {
6796 let mut res = RequestOpGetneightblDumpRequest::new(self, header);
6797 res.request.do_writeback(
6798 res.protocol(),
6799 "op-getneightbl-dump-request",
6800 RequestOpGetneightblDumpRequest::lookup,
6801 );
6802 res
6803 }
6804 pub fn op_setneightbl_do_request(
6805 self,
6806 header: &PushNdtmsg,
6807 ) -> RequestOpSetneightblDoRequest<'buf> {
6808 let mut res = RequestOpSetneightblDoRequest::new(self, header);
6809 res.request.do_writeback(
6810 res.protocol(),
6811 "op-setneightbl-do-request",
6812 RequestOpSetneightblDoRequest::lookup,
6813 );
6814 res
6815 }
6816}