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