1#![doc = "IP neighbour management over rtnetlink.\n"]
2#![allow(clippy::all)]
3#![allow(unused_imports)]
4#![allow(unused_assignments)]
5#![allow(non_snake_case)]
6#![allow(unused_variables)]
7#![allow(irrefutable_let_patterns)]
8#![allow(unreachable_code)]
9#![allow(unreachable_patterns)]
10use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
11use crate::{
12 consts,
13 traits::{NetlinkRequest, Protocol},
14 utils::*,
15};
16pub const PROTONAME: &str = "rt-neigh";
17pub const PROTONAME_CSTR: &CStr = c"rt-neigh";
18pub const PROTONUM: u16 = 0u16;
19#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
20#[derive(Debug, Clone, Copy)]
21pub enum NudState {
22 Incomplete = 1 << 0,
23 Reachable = 1 << 1,
24 Stale = 1 << 2,
25 Delay = 1 << 3,
26 Probe = 1 << 4,
27 Failed = 1 << 5,
28 Noarp = 1 << 6,
29 Permanent = 1 << 7,
30}
31impl NudState {
32 pub fn from_value(value: u64) -> Option<Self> {
33 Some(match value {
34 n if n == 1 << 0 => Self::Incomplete,
35 n if n == 1 << 1 => Self::Reachable,
36 n if n == 1 << 2 => Self::Stale,
37 n if n == 1 << 3 => Self::Delay,
38 n if n == 1 << 4 => Self::Probe,
39 n if n == 1 << 5 => Self::Failed,
40 n if n == 1 << 6 => Self::Noarp,
41 n if n == 1 << 7 => Self::Permanent,
42 _ => return None,
43 })
44 }
45}
46#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
47#[derive(Debug, Clone, Copy)]
48pub enum NtfFlags {
49 Use = 1 << 0,
50 _Self = 1 << 1,
51 Master = 1 << 2,
52 Proxy = 1 << 3,
53 ExtLearned = 1 << 4,
54 Offloaded = 1 << 5,
55 Sticky = 1 << 6,
56 Router = 1 << 7,
57}
58impl NtfFlags {
59 pub fn from_value(value: u64) -> Option<Self> {
60 Some(match value {
61 n if n == 1 << 0 => Self::Use,
62 n if n == 1 << 1 => Self::_Self,
63 n if n == 1 << 2 => Self::Master,
64 n if n == 1 << 3 => Self::Proxy,
65 n if n == 1 << 4 => Self::ExtLearned,
66 n if n == 1 << 5 => Self::Offloaded,
67 n if n == 1 << 6 => Self::Sticky,
68 n if n == 1 << 7 => Self::Router,
69 _ => return None,
70 })
71 }
72}
73#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
74#[derive(Debug, Clone, Copy)]
75pub enum NtfExtFlags {
76 Managed = 1 << 0,
77 Locked = 1 << 1,
78 ExtValidated = 1 << 2,
79}
80impl NtfExtFlags {
81 pub fn from_value(value: u64) -> Option<Self> {
82 Some(match value {
83 n if n == 1 << 0 => Self::Managed,
84 n if n == 1 << 1 => Self::Locked,
85 n if n == 1 << 2 => Self::ExtValidated,
86 _ => return None,
87 })
88 }
89}
90#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
91#[derive(Debug, Clone, Copy)]
92pub enum RtmType {
93 Unspec = 0,
94 Unicast = 1,
95 Local = 2,
96 Broadcast = 3,
97 Anycast = 4,
98 Multicast = 5,
99 Blackhole = 6,
100 Unreachable = 7,
101 Prohibit = 8,
102 Throw = 9,
103 Nat = 10,
104 Xresolve = 11,
105}
106impl RtmType {
107 pub fn from_value(value: u64) -> Option<Self> {
108 Some(match value {
109 0 => Self::Unspec,
110 1 => Self::Unicast,
111 2 => Self::Local,
112 3 => Self::Broadcast,
113 4 => Self::Anycast,
114 5 => Self::Multicast,
115 6 => Self::Blackhole,
116 7 => Self::Unreachable,
117 8 => Self::Prohibit,
118 9 => Self::Throw,
119 10 => Self::Nat,
120 11 => Self::Xresolve,
121 _ => return None,
122 })
123 }
124}
125#[repr(C, packed(4))]
126pub struct Ndmsg {
127 pub ndm_family: u8,
128 pub _ndm_pad: [u8; 3usize],
129 pub ndm_ifindex: i32,
130 #[doc = "Associated type: [`NudState`] (enum)"]
131 pub ndm_state: u16,
132 #[doc = "Associated type: [`NtfFlags`] (enum)"]
133 pub ndm_flags: u8,
134 #[doc = "Associated type: [`RtmType`] (enum)"]
135 pub ndm_type: u8,
136}
137impl Clone for Ndmsg {
138 fn clone(&self) -> Self {
139 Self::new_from_array(*self.as_array())
140 }
141}
142#[doc = "Create zero-initialized struct"]
143impl Default for Ndmsg {
144 fn default() -> Self {
145 Self::new()
146 }
147}
148impl Ndmsg {
149 #[doc = "Create zero-initialized struct"]
150 pub fn new() -> Self {
151 Self::new_from_array([0u8; Self::len()])
152 }
153 #[doc = "Copy from contents from slice"]
154 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
155 if other.len() != Self::len() {
156 return None;
157 }
158 let mut buf = [0u8; Self::len()];
159 buf.clone_from_slice(other);
160 Some(Self::new_from_array(buf))
161 }
162 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
163 pub fn new_from_zeroed(other: &[u8]) -> Self {
164 let mut buf = [0u8; Self::len()];
165 let len = buf.len().min(other.len());
166 buf[..len].clone_from_slice(&other[..len]);
167 Self::new_from_array(buf)
168 }
169 pub fn new_from_array(buf: [u8; 12usize]) -> Self {
170 unsafe { std::mem::transmute(buf) }
171 }
172 pub fn as_slice(&self) -> &[u8] {
173 unsafe {
174 let ptr: *const u8 = std::mem::transmute(self as *const Self);
175 std::slice::from_raw_parts(ptr, Self::len())
176 }
177 }
178 pub fn from_slice(buf: &[u8]) -> &Self {
179 assert!(buf.len() >= Self::len());
180 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
181 unsafe { std::mem::transmute(buf.as_ptr()) }
182 }
183 pub fn as_array(&self) -> &[u8; 12usize] {
184 unsafe { std::mem::transmute(self) }
185 }
186 pub fn from_array(buf: &[u8; 12usize]) -> &Self {
187 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
188 unsafe { std::mem::transmute(buf) }
189 }
190 pub fn into_array(self) -> [u8; 12usize] {
191 unsafe { std::mem::transmute(self) }
192 }
193 pub const fn len() -> usize {
194 const _: () = assert!(std::mem::size_of::<Ndmsg>() == 12usize);
195 12usize
196 }
197}
198impl std::fmt::Debug for Ndmsg {
199 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
200 fmt.debug_struct("Ndmsg")
201 .field("ndm_family", &self.ndm_family)
202 .field("ndm_ifindex", &self.ndm_ifindex)
203 .field(
204 "ndm_state",
205 &FormatFlags(self.ndm_state.into(), NudState::from_value),
206 )
207 .field(
208 "ndm_flags",
209 &FormatFlags(self.ndm_flags.into(), NtfFlags::from_value),
210 )
211 .field(
212 "ndm_type",
213 &FormatEnum(self.ndm_type.into(), RtmType::from_value),
214 )
215 .finish()
216 }
217}
218#[repr(C, packed(4))]
219pub struct Ndtmsg {
220 pub family: u8,
221 pub _pad: [u8; 3usize],
222}
223impl Clone for Ndtmsg {
224 fn clone(&self) -> Self {
225 Self::new_from_array(*self.as_array())
226 }
227}
228#[doc = "Create zero-initialized struct"]
229impl Default for Ndtmsg {
230 fn default() -> Self {
231 Self::new()
232 }
233}
234impl Ndtmsg {
235 #[doc = "Create zero-initialized struct"]
236 pub fn new() -> Self {
237 Self::new_from_array([0u8; Self::len()])
238 }
239 #[doc = "Copy from contents from slice"]
240 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
241 if other.len() != Self::len() {
242 return None;
243 }
244 let mut buf = [0u8; Self::len()];
245 buf.clone_from_slice(other);
246 Some(Self::new_from_array(buf))
247 }
248 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
249 pub fn new_from_zeroed(other: &[u8]) -> Self {
250 let mut buf = [0u8; Self::len()];
251 let len = buf.len().min(other.len());
252 buf[..len].clone_from_slice(&other[..len]);
253 Self::new_from_array(buf)
254 }
255 pub fn new_from_array(buf: [u8; 4usize]) -> Self {
256 unsafe { std::mem::transmute(buf) }
257 }
258 pub fn as_slice(&self) -> &[u8] {
259 unsafe {
260 let ptr: *const u8 = std::mem::transmute(self as *const Self);
261 std::slice::from_raw_parts(ptr, Self::len())
262 }
263 }
264 pub fn from_slice(buf: &[u8]) -> &Self {
265 assert!(buf.len() >= Self::len());
266 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
267 unsafe { std::mem::transmute(buf.as_ptr()) }
268 }
269 pub fn as_array(&self) -> &[u8; 4usize] {
270 unsafe { std::mem::transmute(self) }
271 }
272 pub fn from_array(buf: &[u8; 4usize]) -> &Self {
273 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
274 unsafe { std::mem::transmute(buf) }
275 }
276 pub fn into_array(self) -> [u8; 4usize] {
277 unsafe { std::mem::transmute(self) }
278 }
279 pub const fn len() -> usize {
280 const _: () = assert!(std::mem::size_of::<Ndtmsg>() == 4usize);
281 4usize
282 }
283}
284impl std::fmt::Debug for Ndtmsg {
285 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
286 fmt.debug_struct("Ndtmsg")
287 .field("family", &self.family)
288 .finish()
289 }
290}
291#[derive(Debug)]
292#[repr(C, packed(4))]
293pub struct NdaCacheinfo {
294 pub confirmed: u32,
295 pub used: u32,
296 pub updated: u32,
297 pub refcnt: u32,
298}
299impl Clone for NdaCacheinfo {
300 fn clone(&self) -> Self {
301 Self::new_from_array(*self.as_array())
302 }
303}
304#[doc = "Create zero-initialized struct"]
305impl Default for NdaCacheinfo {
306 fn default() -> Self {
307 Self::new()
308 }
309}
310impl NdaCacheinfo {
311 #[doc = "Create zero-initialized struct"]
312 pub fn new() -> Self {
313 Self::new_from_array([0u8; Self::len()])
314 }
315 #[doc = "Copy from contents from slice"]
316 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
317 if other.len() != Self::len() {
318 return None;
319 }
320 let mut buf = [0u8; Self::len()];
321 buf.clone_from_slice(other);
322 Some(Self::new_from_array(buf))
323 }
324 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
325 pub fn new_from_zeroed(other: &[u8]) -> Self {
326 let mut buf = [0u8; Self::len()];
327 let len = buf.len().min(other.len());
328 buf[..len].clone_from_slice(&other[..len]);
329 Self::new_from_array(buf)
330 }
331 pub fn new_from_array(buf: [u8; 16usize]) -> Self {
332 unsafe { std::mem::transmute(buf) }
333 }
334 pub fn as_slice(&self) -> &[u8] {
335 unsafe {
336 let ptr: *const u8 = std::mem::transmute(self as *const Self);
337 std::slice::from_raw_parts(ptr, Self::len())
338 }
339 }
340 pub fn from_slice(buf: &[u8]) -> &Self {
341 assert!(buf.len() >= Self::len());
342 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
343 unsafe { std::mem::transmute(buf.as_ptr()) }
344 }
345 pub fn as_array(&self) -> &[u8; 16usize] {
346 unsafe { std::mem::transmute(self) }
347 }
348 pub fn from_array(buf: &[u8; 16usize]) -> &Self {
349 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
350 unsafe { std::mem::transmute(buf) }
351 }
352 pub fn into_array(self) -> [u8; 16usize] {
353 unsafe { std::mem::transmute(self) }
354 }
355 pub const fn len() -> usize {
356 const _: () = assert!(std::mem::size_of::<NdaCacheinfo>() == 16usize);
357 16usize
358 }
359}
360#[derive(Debug)]
361#[repr(C, packed(4))]
362pub struct NdtConfig {
363 pub key_len: u16,
364 pub entry_size: u16,
365 pub entries: u32,
366 pub last_flush: u32,
367 pub last_rand: u32,
368 pub hash_rnd: u32,
369 pub hash_mask: u32,
370 pub hash_chain_gc: u32,
371 pub proxy_qlen: u32,
372}
373impl Clone for NdtConfig {
374 fn clone(&self) -> Self {
375 Self::new_from_array(*self.as_array())
376 }
377}
378#[doc = "Create zero-initialized struct"]
379impl Default for NdtConfig {
380 fn default() -> Self {
381 Self::new()
382 }
383}
384impl NdtConfig {
385 #[doc = "Create zero-initialized struct"]
386 pub fn new() -> Self {
387 Self::new_from_array([0u8; Self::len()])
388 }
389 #[doc = "Copy from contents from slice"]
390 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
391 if other.len() != Self::len() {
392 return None;
393 }
394 let mut buf = [0u8; Self::len()];
395 buf.clone_from_slice(other);
396 Some(Self::new_from_array(buf))
397 }
398 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
399 pub fn new_from_zeroed(other: &[u8]) -> Self {
400 let mut buf = [0u8; Self::len()];
401 let len = buf.len().min(other.len());
402 buf[..len].clone_from_slice(&other[..len]);
403 Self::new_from_array(buf)
404 }
405 pub fn new_from_array(buf: [u8; 32usize]) -> Self {
406 unsafe { std::mem::transmute(buf) }
407 }
408 pub fn as_slice(&self) -> &[u8] {
409 unsafe {
410 let ptr: *const u8 = std::mem::transmute(self as *const Self);
411 std::slice::from_raw_parts(ptr, Self::len())
412 }
413 }
414 pub fn from_slice(buf: &[u8]) -> &Self {
415 assert!(buf.len() >= Self::len());
416 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
417 unsafe { std::mem::transmute(buf.as_ptr()) }
418 }
419 pub fn as_array(&self) -> &[u8; 32usize] {
420 unsafe { std::mem::transmute(self) }
421 }
422 pub fn from_array(buf: &[u8; 32usize]) -> &Self {
423 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
424 unsafe { std::mem::transmute(buf) }
425 }
426 pub fn into_array(self) -> [u8; 32usize] {
427 unsafe { std::mem::transmute(self) }
428 }
429 pub const fn len() -> usize {
430 const _: () = assert!(std::mem::size_of::<NdtConfig>() == 32usize);
431 32usize
432 }
433}
434#[repr(C, packed(4))]
435pub struct NdtStats {
436 pub allocs: u64,
437 pub destroys: u64,
438 pub hash_grows: u64,
439 pub res_failed: u64,
440 pub lookups: u64,
441 pub hits: u64,
442 pub rcv_probes_mcast: u64,
443 pub rcv_probes_ucast: u64,
444 pub periodic_gc_runs: u64,
445 pub forced_gc_runs: u64,
446 pub table_fulls: u64,
447}
448impl Clone for NdtStats {
449 fn clone(&self) -> Self {
450 Self::new_from_array(*self.as_array())
451 }
452}
453#[doc = "Create zero-initialized struct"]
454impl Default for NdtStats {
455 fn default() -> Self {
456 Self::new()
457 }
458}
459impl NdtStats {
460 #[doc = "Create zero-initialized struct"]
461 pub fn new() -> Self {
462 Self::new_from_array([0u8; Self::len()])
463 }
464 #[doc = "Copy from contents from slice"]
465 pub fn new_from_slice(other: &[u8]) -> Option<Self> {
466 if other.len() != Self::len() {
467 return None;
468 }
469 let mut buf = [0u8; Self::len()];
470 buf.clone_from_slice(other);
471 Some(Self::new_from_array(buf))
472 }
473 #[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
474 pub fn new_from_zeroed(other: &[u8]) -> Self {
475 let mut buf = [0u8; Self::len()];
476 let len = buf.len().min(other.len());
477 buf[..len].clone_from_slice(&other[..len]);
478 Self::new_from_array(buf)
479 }
480 pub fn new_from_array(buf: [u8; 88usize]) -> Self {
481 unsafe { std::mem::transmute(buf) }
482 }
483 pub fn as_slice(&self) -> &[u8] {
484 unsafe {
485 let ptr: *const u8 = std::mem::transmute(self as *const Self);
486 std::slice::from_raw_parts(ptr, Self::len())
487 }
488 }
489 pub fn from_slice(buf: &[u8]) -> &Self {
490 assert!(buf.len() >= Self::len());
491 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
492 unsafe { std::mem::transmute(buf.as_ptr()) }
493 }
494 pub fn as_array(&self) -> &[u8; 88usize] {
495 unsafe { std::mem::transmute(self) }
496 }
497 pub fn from_array(buf: &[u8; 88usize]) -> &Self {
498 assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
499 unsafe { std::mem::transmute(buf) }
500 }
501 pub fn into_array(self) -> [u8; 88usize] {
502 unsafe { std::mem::transmute(self) }
503 }
504 pub const fn len() -> usize {
505 const _: () = assert!(std::mem::size_of::<NdtStats>() == 88usize);
506 88usize
507 }
508}
509impl std::fmt::Debug for NdtStats {
510 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
511 fmt.debug_struct("NdtStats")
512 .field("allocs", &{ self.allocs })
513 .field("destroys", &{ self.destroys })
514 .field("hash_grows", &{ self.hash_grows })
515 .field("res_failed", &{ self.res_failed })
516 .field("lookups", &{ self.lookups })
517 .field("hits", &{ self.hits })
518 .field("rcv_probes_mcast", &{ self.rcv_probes_mcast })
519 .field("rcv_probes_ucast", &{ self.rcv_probes_ucast })
520 .field("periodic_gc_runs", &{ self.periodic_gc_runs })
521 .field("forced_gc_runs", &{ self.forced_gc_runs })
522 .field("table_fulls", &{ self.table_fulls })
523 .finish()
524 }
525}
526#[derive(Clone)]
527pub enum NeighbourAttrs<'a> {
528 Unspec(&'a [u8]),
529 Dst(std::net::IpAddr),
530 Lladdr(&'a [u8]),
531 Cacheinfo(NdaCacheinfo),
532 Probes(u32),
533 Vlan(u16),
534 Port(u16),
535 Vni(u32),
536 Ifindex(u32),
537 Master(u32),
538 LinkNetnsid(i32),
539 SrcVni(u32),
540 Protocol(u8),
541 NhId(u32),
542 FdbExtAttrs(&'a [u8]),
543 #[doc = "Associated type: [`NtfExtFlags`] (enum)"]
544 FlagsExt(u32),
545 NdmStateMask(u16),
546 NdmFlagsMask(u8),
547}
548impl<'a> IterableNeighbourAttrs<'a> {
549 pub fn get_unspec(&self) -> Result<&'a [u8], ErrorContext> {
550 let mut iter = self.clone();
551 iter.pos = 0;
552 for attr in iter {
553 if let Ok(NeighbourAttrs::Unspec(val)) = attr {
554 return Ok(val);
555 }
556 }
557 Err(ErrorContext::new_missing(
558 "NeighbourAttrs",
559 "Unspec",
560 self.orig_loc,
561 self.buf.as_ptr() as usize,
562 ))
563 }
564 pub fn get_dst(&self) -> Result<std::net::IpAddr, ErrorContext> {
565 let mut iter = self.clone();
566 iter.pos = 0;
567 for attr in iter {
568 if let Ok(NeighbourAttrs::Dst(val)) = attr {
569 return Ok(val);
570 }
571 }
572 Err(ErrorContext::new_missing(
573 "NeighbourAttrs",
574 "Dst",
575 self.orig_loc,
576 self.buf.as_ptr() as usize,
577 ))
578 }
579 pub fn get_lladdr(&self) -> Result<&'a [u8], ErrorContext> {
580 let mut iter = self.clone();
581 iter.pos = 0;
582 for attr in iter {
583 if let Ok(NeighbourAttrs::Lladdr(val)) = attr {
584 return Ok(val);
585 }
586 }
587 Err(ErrorContext::new_missing(
588 "NeighbourAttrs",
589 "Lladdr",
590 self.orig_loc,
591 self.buf.as_ptr() as usize,
592 ))
593 }
594 pub fn get_cacheinfo(&self) -> Result<NdaCacheinfo, ErrorContext> {
595 let mut iter = self.clone();
596 iter.pos = 0;
597 for attr in iter {
598 if let Ok(NeighbourAttrs::Cacheinfo(val)) = attr {
599 return Ok(val);
600 }
601 }
602 Err(ErrorContext::new_missing(
603 "NeighbourAttrs",
604 "Cacheinfo",
605 self.orig_loc,
606 self.buf.as_ptr() as usize,
607 ))
608 }
609 pub fn get_probes(&self) -> Result<u32, ErrorContext> {
610 let mut iter = self.clone();
611 iter.pos = 0;
612 for attr in iter {
613 if let Ok(NeighbourAttrs::Probes(val)) = attr {
614 return Ok(val);
615 }
616 }
617 Err(ErrorContext::new_missing(
618 "NeighbourAttrs",
619 "Probes",
620 self.orig_loc,
621 self.buf.as_ptr() as usize,
622 ))
623 }
624 pub fn get_vlan(&self) -> Result<u16, ErrorContext> {
625 let mut iter = self.clone();
626 iter.pos = 0;
627 for attr in iter {
628 if let Ok(NeighbourAttrs::Vlan(val)) = attr {
629 return Ok(val);
630 }
631 }
632 Err(ErrorContext::new_missing(
633 "NeighbourAttrs",
634 "Vlan",
635 self.orig_loc,
636 self.buf.as_ptr() as usize,
637 ))
638 }
639 pub fn get_port(&self) -> Result<u16, ErrorContext> {
640 let mut iter = self.clone();
641 iter.pos = 0;
642 for attr in iter {
643 if let Ok(NeighbourAttrs::Port(val)) = attr {
644 return Ok(val);
645 }
646 }
647 Err(ErrorContext::new_missing(
648 "NeighbourAttrs",
649 "Port",
650 self.orig_loc,
651 self.buf.as_ptr() as usize,
652 ))
653 }
654 pub fn get_vni(&self) -> Result<u32, ErrorContext> {
655 let mut iter = self.clone();
656 iter.pos = 0;
657 for attr in iter {
658 if let Ok(NeighbourAttrs::Vni(val)) = attr {
659 return Ok(val);
660 }
661 }
662 Err(ErrorContext::new_missing(
663 "NeighbourAttrs",
664 "Vni",
665 self.orig_loc,
666 self.buf.as_ptr() as usize,
667 ))
668 }
669 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
670 let mut iter = self.clone();
671 iter.pos = 0;
672 for attr in iter {
673 if let Ok(NeighbourAttrs::Ifindex(val)) = attr {
674 return Ok(val);
675 }
676 }
677 Err(ErrorContext::new_missing(
678 "NeighbourAttrs",
679 "Ifindex",
680 self.orig_loc,
681 self.buf.as_ptr() as usize,
682 ))
683 }
684 pub fn get_master(&self) -> Result<u32, ErrorContext> {
685 let mut iter = self.clone();
686 iter.pos = 0;
687 for attr in iter {
688 if let Ok(NeighbourAttrs::Master(val)) = attr {
689 return Ok(val);
690 }
691 }
692 Err(ErrorContext::new_missing(
693 "NeighbourAttrs",
694 "Master",
695 self.orig_loc,
696 self.buf.as_ptr() as usize,
697 ))
698 }
699 pub fn get_link_netnsid(&self) -> Result<i32, ErrorContext> {
700 let mut iter = self.clone();
701 iter.pos = 0;
702 for attr in iter {
703 if let Ok(NeighbourAttrs::LinkNetnsid(val)) = attr {
704 return Ok(val);
705 }
706 }
707 Err(ErrorContext::new_missing(
708 "NeighbourAttrs",
709 "LinkNetnsid",
710 self.orig_loc,
711 self.buf.as_ptr() as usize,
712 ))
713 }
714 pub fn get_src_vni(&self) -> Result<u32, ErrorContext> {
715 let mut iter = self.clone();
716 iter.pos = 0;
717 for attr in iter {
718 if let Ok(NeighbourAttrs::SrcVni(val)) = attr {
719 return Ok(val);
720 }
721 }
722 Err(ErrorContext::new_missing(
723 "NeighbourAttrs",
724 "SrcVni",
725 self.orig_loc,
726 self.buf.as_ptr() as usize,
727 ))
728 }
729 pub fn get_protocol(&self) -> Result<u8, ErrorContext> {
730 let mut iter = self.clone();
731 iter.pos = 0;
732 for attr in iter {
733 if let Ok(NeighbourAttrs::Protocol(val)) = attr {
734 return Ok(val);
735 }
736 }
737 Err(ErrorContext::new_missing(
738 "NeighbourAttrs",
739 "Protocol",
740 self.orig_loc,
741 self.buf.as_ptr() as usize,
742 ))
743 }
744 pub fn get_nh_id(&self) -> Result<u32, ErrorContext> {
745 let mut iter = self.clone();
746 iter.pos = 0;
747 for attr in iter {
748 if let Ok(NeighbourAttrs::NhId(val)) = attr {
749 return Ok(val);
750 }
751 }
752 Err(ErrorContext::new_missing(
753 "NeighbourAttrs",
754 "NhId",
755 self.orig_loc,
756 self.buf.as_ptr() as usize,
757 ))
758 }
759 pub fn get_fdb_ext_attrs(&self) -> Result<&'a [u8], ErrorContext> {
760 let mut iter = self.clone();
761 iter.pos = 0;
762 for attr in iter {
763 if let Ok(NeighbourAttrs::FdbExtAttrs(val)) = attr {
764 return Ok(val);
765 }
766 }
767 Err(ErrorContext::new_missing(
768 "NeighbourAttrs",
769 "FdbExtAttrs",
770 self.orig_loc,
771 self.buf.as_ptr() as usize,
772 ))
773 }
774 #[doc = "Associated type: [`NtfExtFlags`] (enum)"]
775 pub fn get_flags_ext(&self) -> Result<u32, ErrorContext> {
776 let mut iter = self.clone();
777 iter.pos = 0;
778 for attr in iter {
779 if let Ok(NeighbourAttrs::FlagsExt(val)) = attr {
780 return Ok(val);
781 }
782 }
783 Err(ErrorContext::new_missing(
784 "NeighbourAttrs",
785 "FlagsExt",
786 self.orig_loc,
787 self.buf.as_ptr() as usize,
788 ))
789 }
790 pub fn get_ndm_state_mask(&self) -> Result<u16, ErrorContext> {
791 let mut iter = self.clone();
792 iter.pos = 0;
793 for attr in iter {
794 if let Ok(NeighbourAttrs::NdmStateMask(val)) = attr {
795 return Ok(val);
796 }
797 }
798 Err(ErrorContext::new_missing(
799 "NeighbourAttrs",
800 "NdmStateMask",
801 self.orig_loc,
802 self.buf.as_ptr() as usize,
803 ))
804 }
805 pub fn get_ndm_flags_mask(&self) -> Result<u8, ErrorContext> {
806 let mut iter = self.clone();
807 iter.pos = 0;
808 for attr in iter {
809 if let Ok(NeighbourAttrs::NdmFlagsMask(val)) = attr {
810 return Ok(val);
811 }
812 }
813 Err(ErrorContext::new_missing(
814 "NeighbourAttrs",
815 "NdmFlagsMask",
816 self.orig_loc,
817 self.buf.as_ptr() as usize,
818 ))
819 }
820}
821impl NeighbourAttrs<'_> {
822 pub fn new<'a>(buf: &'a [u8]) -> IterableNeighbourAttrs<'a> {
823 IterableNeighbourAttrs::with_loc(buf, buf.as_ptr() as usize)
824 }
825 fn attr_from_type(r#type: u16) -> Option<&'static str> {
826 let res = match r#type {
827 0u16 => "Unspec",
828 1u16 => "Dst",
829 2u16 => "Lladdr",
830 3u16 => "Cacheinfo",
831 4u16 => "Probes",
832 5u16 => "Vlan",
833 6u16 => "Port",
834 7u16 => "Vni",
835 8u16 => "Ifindex",
836 9u16 => "Master",
837 10u16 => "LinkNetnsid",
838 11u16 => "SrcVni",
839 12u16 => "Protocol",
840 13u16 => "NhId",
841 14u16 => "FdbExtAttrs",
842 15u16 => "FlagsExt",
843 16u16 => "NdmStateMask",
844 17u16 => "NdmFlagsMask",
845 _ => return None,
846 };
847 Some(res)
848 }
849}
850#[derive(Clone, Copy, Default)]
851pub struct IterableNeighbourAttrs<'a> {
852 buf: &'a [u8],
853 pos: usize,
854 orig_loc: usize,
855}
856impl<'a> IterableNeighbourAttrs<'a> {
857 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
858 Self {
859 buf,
860 pos: 0,
861 orig_loc,
862 }
863 }
864 pub fn get_buf(&self) -> &'a [u8] {
865 self.buf
866 }
867}
868impl<'a> Iterator for IterableNeighbourAttrs<'a> {
869 type Item = Result<NeighbourAttrs<'a>, ErrorContext>;
870 fn next(&mut self) -> Option<Self::Item> {
871 let mut pos;
872 let mut r#type;
873 loop {
874 pos = self.pos;
875 r#type = None;
876 if self.buf.len() == self.pos {
877 return None;
878 }
879 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
880 self.pos = self.buf.len();
881 break;
882 };
883 r#type = Some(header.r#type);
884 let res = match header.r#type {
885 0u16 => NeighbourAttrs::Unspec({
886 let res = Some(next);
887 let Some(val) = res else { break };
888 val
889 }),
890 1u16 => NeighbourAttrs::Dst({
891 let res = parse_ip(next);
892 let Some(val) = res else { break };
893 val
894 }),
895 2u16 => NeighbourAttrs::Lladdr({
896 let res = Some(next);
897 let Some(val) = res else { break };
898 val
899 }),
900 3u16 => NeighbourAttrs::Cacheinfo({
901 let res = Some(NdaCacheinfo::new_from_zeroed(next));
902 let Some(val) = res else { break };
903 val
904 }),
905 4u16 => NeighbourAttrs::Probes({
906 let res = parse_u32(next);
907 let Some(val) = res else { break };
908 val
909 }),
910 5u16 => NeighbourAttrs::Vlan({
911 let res = parse_u16(next);
912 let Some(val) = res else { break };
913 val
914 }),
915 6u16 => NeighbourAttrs::Port({
916 let res = parse_u16(next);
917 let Some(val) = res else { break };
918 val
919 }),
920 7u16 => NeighbourAttrs::Vni({
921 let res = parse_u32(next);
922 let Some(val) = res else { break };
923 val
924 }),
925 8u16 => NeighbourAttrs::Ifindex({
926 let res = parse_u32(next);
927 let Some(val) = res else { break };
928 val
929 }),
930 9u16 => NeighbourAttrs::Master({
931 let res = parse_u32(next);
932 let Some(val) = res else { break };
933 val
934 }),
935 10u16 => NeighbourAttrs::LinkNetnsid({
936 let res = parse_i32(next);
937 let Some(val) = res else { break };
938 val
939 }),
940 11u16 => NeighbourAttrs::SrcVni({
941 let res = parse_u32(next);
942 let Some(val) = res else { break };
943 val
944 }),
945 12u16 => NeighbourAttrs::Protocol({
946 let res = parse_u8(next);
947 let Some(val) = res else { break };
948 val
949 }),
950 13u16 => NeighbourAttrs::NhId({
951 let res = parse_u32(next);
952 let Some(val) = res else { break };
953 val
954 }),
955 14u16 => NeighbourAttrs::FdbExtAttrs({
956 let res = Some(next);
957 let Some(val) = res else { break };
958 val
959 }),
960 15u16 => NeighbourAttrs::FlagsExt({
961 let res = parse_u32(next);
962 let Some(val) = res else { break };
963 val
964 }),
965 16u16 => NeighbourAttrs::NdmStateMask({
966 let res = parse_u16(next);
967 let Some(val) = res else { break };
968 val
969 }),
970 17u16 => NeighbourAttrs::NdmFlagsMask({
971 let res = parse_u8(next);
972 let Some(val) = res else { break };
973 val
974 }),
975 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
976 n => continue,
977 };
978 return Some(Ok(res));
979 }
980 Some(Err(ErrorContext::new(
981 "NeighbourAttrs",
982 r#type.and_then(|t| NeighbourAttrs::attr_from_type(t)),
983 self.orig_loc,
984 self.buf.as_ptr().wrapping_add(pos) as usize,
985 )))
986 }
987}
988impl<'a> std::fmt::Debug for IterableNeighbourAttrs<'_> {
989 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
990 let mut fmt = f.debug_struct("NeighbourAttrs");
991 for attr in self.clone() {
992 let attr = match attr {
993 Ok(a) => a,
994 Err(err) => {
995 fmt.finish()?;
996 f.write_str("Err(")?;
997 err.fmt(f)?;
998 return f.write_str(")");
999 }
1000 };
1001 match attr {
1002 NeighbourAttrs::Unspec(val) => fmt.field("Unspec", &val),
1003 NeighbourAttrs::Dst(val) => fmt.field("Dst", &val),
1004 NeighbourAttrs::Lladdr(val) => fmt.field("Lladdr", &FormatMac(val)),
1005 NeighbourAttrs::Cacheinfo(val) => fmt.field("Cacheinfo", &val),
1006 NeighbourAttrs::Probes(val) => fmt.field("Probes", &val),
1007 NeighbourAttrs::Vlan(val) => fmt.field("Vlan", &val),
1008 NeighbourAttrs::Port(val) => fmt.field("Port", &val),
1009 NeighbourAttrs::Vni(val) => fmt.field("Vni", &val),
1010 NeighbourAttrs::Ifindex(val) => fmt.field("Ifindex", &val),
1011 NeighbourAttrs::Master(val) => fmt.field("Master", &val),
1012 NeighbourAttrs::LinkNetnsid(val) => fmt.field("LinkNetnsid", &val),
1013 NeighbourAttrs::SrcVni(val) => fmt.field("SrcVni", &val),
1014 NeighbourAttrs::Protocol(val) => fmt.field("Protocol", &val),
1015 NeighbourAttrs::NhId(val) => fmt.field("NhId", &val),
1016 NeighbourAttrs::FdbExtAttrs(val) => fmt.field("FdbExtAttrs", &val),
1017 NeighbourAttrs::FlagsExt(val) => fmt.field(
1018 "FlagsExt",
1019 &FormatFlags(val.into(), NtfExtFlags::from_value),
1020 ),
1021 NeighbourAttrs::NdmStateMask(val) => fmt.field("NdmStateMask", &val),
1022 NeighbourAttrs::NdmFlagsMask(val) => fmt.field("NdmFlagsMask", &val),
1023 };
1024 }
1025 fmt.finish()
1026 }
1027}
1028impl IterableNeighbourAttrs<'_> {
1029 pub fn lookup_attr(
1030 &self,
1031 offset: usize,
1032 missing_type: Option<u16>,
1033 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1034 let mut stack = Vec::new();
1035 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1036 if missing_type.is_some() && cur == offset {
1037 stack.push(("NeighbourAttrs", offset));
1038 return (
1039 stack,
1040 missing_type.and_then(|t| NeighbourAttrs::attr_from_type(t)),
1041 );
1042 }
1043 if cur > offset || cur + self.buf.len() < offset {
1044 return (stack, None);
1045 }
1046 let mut attrs = self.clone();
1047 let mut last_off = cur + attrs.pos;
1048 while let Some(attr) = attrs.next() {
1049 let Ok(attr) = attr else { break };
1050 match attr {
1051 NeighbourAttrs::Unspec(val) => {
1052 if last_off == offset {
1053 stack.push(("Unspec", last_off));
1054 break;
1055 }
1056 }
1057 NeighbourAttrs::Dst(val) => {
1058 if last_off == offset {
1059 stack.push(("Dst", last_off));
1060 break;
1061 }
1062 }
1063 NeighbourAttrs::Lladdr(val) => {
1064 if last_off == offset {
1065 stack.push(("Lladdr", last_off));
1066 break;
1067 }
1068 }
1069 NeighbourAttrs::Cacheinfo(val) => {
1070 if last_off == offset {
1071 stack.push(("Cacheinfo", last_off));
1072 break;
1073 }
1074 }
1075 NeighbourAttrs::Probes(val) => {
1076 if last_off == offset {
1077 stack.push(("Probes", last_off));
1078 break;
1079 }
1080 }
1081 NeighbourAttrs::Vlan(val) => {
1082 if last_off == offset {
1083 stack.push(("Vlan", last_off));
1084 break;
1085 }
1086 }
1087 NeighbourAttrs::Port(val) => {
1088 if last_off == offset {
1089 stack.push(("Port", last_off));
1090 break;
1091 }
1092 }
1093 NeighbourAttrs::Vni(val) => {
1094 if last_off == offset {
1095 stack.push(("Vni", last_off));
1096 break;
1097 }
1098 }
1099 NeighbourAttrs::Ifindex(val) => {
1100 if last_off == offset {
1101 stack.push(("Ifindex", last_off));
1102 break;
1103 }
1104 }
1105 NeighbourAttrs::Master(val) => {
1106 if last_off == offset {
1107 stack.push(("Master", last_off));
1108 break;
1109 }
1110 }
1111 NeighbourAttrs::LinkNetnsid(val) => {
1112 if last_off == offset {
1113 stack.push(("LinkNetnsid", last_off));
1114 break;
1115 }
1116 }
1117 NeighbourAttrs::SrcVni(val) => {
1118 if last_off == offset {
1119 stack.push(("SrcVni", last_off));
1120 break;
1121 }
1122 }
1123 NeighbourAttrs::Protocol(val) => {
1124 if last_off == offset {
1125 stack.push(("Protocol", last_off));
1126 break;
1127 }
1128 }
1129 NeighbourAttrs::NhId(val) => {
1130 if last_off == offset {
1131 stack.push(("NhId", last_off));
1132 break;
1133 }
1134 }
1135 NeighbourAttrs::FdbExtAttrs(val) => {
1136 if last_off == offset {
1137 stack.push(("FdbExtAttrs", last_off));
1138 break;
1139 }
1140 }
1141 NeighbourAttrs::FlagsExt(val) => {
1142 if last_off == offset {
1143 stack.push(("FlagsExt", last_off));
1144 break;
1145 }
1146 }
1147 NeighbourAttrs::NdmStateMask(val) => {
1148 if last_off == offset {
1149 stack.push(("NdmStateMask", last_off));
1150 break;
1151 }
1152 }
1153 NeighbourAttrs::NdmFlagsMask(val) => {
1154 if last_off == offset {
1155 stack.push(("NdmFlagsMask", last_off));
1156 break;
1157 }
1158 }
1159 _ => {}
1160 };
1161 last_off = cur + attrs.pos;
1162 }
1163 if !stack.is_empty() {
1164 stack.push(("NeighbourAttrs", cur));
1165 }
1166 (stack, None)
1167 }
1168}
1169#[derive(Clone)]
1170pub enum NdtAttrs<'a> {
1171 Name(&'a CStr),
1172 Thresh1(u32),
1173 Thresh2(u32),
1174 Thresh3(u32),
1175 Config(NdtConfig),
1176 Parms(IterableNdtpaAttrs<'a>),
1177 Stats(NdtStats),
1178 GcInterval(u64),
1179 Pad(&'a [u8]),
1180}
1181impl<'a> IterableNdtAttrs<'a> {
1182 pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
1183 let mut iter = self.clone();
1184 iter.pos = 0;
1185 for attr in iter {
1186 if let Ok(NdtAttrs::Name(val)) = attr {
1187 return Ok(val);
1188 }
1189 }
1190 Err(ErrorContext::new_missing(
1191 "NdtAttrs",
1192 "Name",
1193 self.orig_loc,
1194 self.buf.as_ptr() as usize,
1195 ))
1196 }
1197 pub fn get_thresh1(&self) -> Result<u32, ErrorContext> {
1198 let mut iter = self.clone();
1199 iter.pos = 0;
1200 for attr in iter {
1201 if let Ok(NdtAttrs::Thresh1(val)) = attr {
1202 return Ok(val);
1203 }
1204 }
1205 Err(ErrorContext::new_missing(
1206 "NdtAttrs",
1207 "Thresh1",
1208 self.orig_loc,
1209 self.buf.as_ptr() as usize,
1210 ))
1211 }
1212 pub fn get_thresh2(&self) -> Result<u32, ErrorContext> {
1213 let mut iter = self.clone();
1214 iter.pos = 0;
1215 for attr in iter {
1216 if let Ok(NdtAttrs::Thresh2(val)) = attr {
1217 return Ok(val);
1218 }
1219 }
1220 Err(ErrorContext::new_missing(
1221 "NdtAttrs",
1222 "Thresh2",
1223 self.orig_loc,
1224 self.buf.as_ptr() as usize,
1225 ))
1226 }
1227 pub fn get_thresh3(&self) -> Result<u32, ErrorContext> {
1228 let mut iter = self.clone();
1229 iter.pos = 0;
1230 for attr in iter {
1231 if let Ok(NdtAttrs::Thresh3(val)) = attr {
1232 return Ok(val);
1233 }
1234 }
1235 Err(ErrorContext::new_missing(
1236 "NdtAttrs",
1237 "Thresh3",
1238 self.orig_loc,
1239 self.buf.as_ptr() as usize,
1240 ))
1241 }
1242 pub fn get_config(&self) -> Result<NdtConfig, ErrorContext> {
1243 let mut iter = self.clone();
1244 iter.pos = 0;
1245 for attr in iter {
1246 if let Ok(NdtAttrs::Config(val)) = attr {
1247 return Ok(val);
1248 }
1249 }
1250 Err(ErrorContext::new_missing(
1251 "NdtAttrs",
1252 "Config",
1253 self.orig_loc,
1254 self.buf.as_ptr() as usize,
1255 ))
1256 }
1257 pub fn get_parms(&self) -> Result<IterableNdtpaAttrs<'a>, ErrorContext> {
1258 let mut iter = self.clone();
1259 iter.pos = 0;
1260 for attr in iter {
1261 if let Ok(NdtAttrs::Parms(val)) = attr {
1262 return Ok(val);
1263 }
1264 }
1265 Err(ErrorContext::new_missing(
1266 "NdtAttrs",
1267 "Parms",
1268 self.orig_loc,
1269 self.buf.as_ptr() as usize,
1270 ))
1271 }
1272 pub fn get_stats(&self) -> Result<NdtStats, ErrorContext> {
1273 let mut iter = self.clone();
1274 iter.pos = 0;
1275 for attr in iter {
1276 if let Ok(NdtAttrs::Stats(val)) = attr {
1277 return Ok(val);
1278 }
1279 }
1280 Err(ErrorContext::new_missing(
1281 "NdtAttrs",
1282 "Stats",
1283 self.orig_loc,
1284 self.buf.as_ptr() as usize,
1285 ))
1286 }
1287 pub fn get_gc_interval(&self) -> Result<u64, ErrorContext> {
1288 let mut iter = self.clone();
1289 iter.pos = 0;
1290 for attr in iter {
1291 if let Ok(NdtAttrs::GcInterval(val)) = attr {
1292 return Ok(val);
1293 }
1294 }
1295 Err(ErrorContext::new_missing(
1296 "NdtAttrs",
1297 "GcInterval",
1298 self.orig_loc,
1299 self.buf.as_ptr() as usize,
1300 ))
1301 }
1302 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
1303 let mut iter = self.clone();
1304 iter.pos = 0;
1305 for attr in iter {
1306 if let Ok(NdtAttrs::Pad(val)) = attr {
1307 return Ok(val);
1308 }
1309 }
1310 Err(ErrorContext::new_missing(
1311 "NdtAttrs",
1312 "Pad",
1313 self.orig_loc,
1314 self.buf.as_ptr() as usize,
1315 ))
1316 }
1317}
1318impl NdtAttrs<'_> {
1319 pub fn new<'a>(buf: &'a [u8]) -> IterableNdtAttrs<'a> {
1320 IterableNdtAttrs::with_loc(buf, buf.as_ptr() as usize)
1321 }
1322 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1323 let res = match r#type {
1324 1u16 => "Name",
1325 2u16 => "Thresh1",
1326 3u16 => "Thresh2",
1327 4u16 => "Thresh3",
1328 5u16 => "Config",
1329 6u16 => "Parms",
1330 7u16 => "Stats",
1331 8u16 => "GcInterval",
1332 9u16 => "Pad",
1333 _ => return None,
1334 };
1335 Some(res)
1336 }
1337}
1338#[derive(Clone, Copy, Default)]
1339pub struct IterableNdtAttrs<'a> {
1340 buf: &'a [u8],
1341 pos: usize,
1342 orig_loc: usize,
1343}
1344impl<'a> IterableNdtAttrs<'a> {
1345 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1346 Self {
1347 buf,
1348 pos: 0,
1349 orig_loc,
1350 }
1351 }
1352 pub fn get_buf(&self) -> &'a [u8] {
1353 self.buf
1354 }
1355}
1356impl<'a> Iterator for IterableNdtAttrs<'a> {
1357 type Item = Result<NdtAttrs<'a>, ErrorContext>;
1358 fn next(&mut self) -> Option<Self::Item> {
1359 let mut pos;
1360 let mut r#type;
1361 loop {
1362 pos = self.pos;
1363 r#type = None;
1364 if self.buf.len() == self.pos {
1365 return None;
1366 }
1367 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1368 self.pos = self.buf.len();
1369 break;
1370 };
1371 r#type = Some(header.r#type);
1372 let res = match header.r#type {
1373 1u16 => NdtAttrs::Name({
1374 let res = CStr::from_bytes_with_nul(next).ok();
1375 let Some(val) = res else { break };
1376 val
1377 }),
1378 2u16 => NdtAttrs::Thresh1({
1379 let res = parse_u32(next);
1380 let Some(val) = res else { break };
1381 val
1382 }),
1383 3u16 => NdtAttrs::Thresh2({
1384 let res = parse_u32(next);
1385 let Some(val) = res else { break };
1386 val
1387 }),
1388 4u16 => NdtAttrs::Thresh3({
1389 let res = parse_u32(next);
1390 let Some(val) = res else { break };
1391 val
1392 }),
1393 5u16 => NdtAttrs::Config({
1394 let res = Some(NdtConfig::new_from_zeroed(next));
1395 let Some(val) = res else { break };
1396 val
1397 }),
1398 6u16 => NdtAttrs::Parms({
1399 let res = Some(IterableNdtpaAttrs::with_loc(next, self.orig_loc));
1400 let Some(val) = res else { break };
1401 val
1402 }),
1403 7u16 => NdtAttrs::Stats({
1404 let res = Some(NdtStats::new_from_zeroed(next));
1405 let Some(val) = res else { break };
1406 val
1407 }),
1408 8u16 => NdtAttrs::GcInterval({
1409 let res = parse_u64(next);
1410 let Some(val) = res else { break };
1411 val
1412 }),
1413 9u16 => NdtAttrs::Pad({
1414 let res = Some(next);
1415 let Some(val) = res else { break };
1416 val
1417 }),
1418 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1419 n => continue,
1420 };
1421 return Some(Ok(res));
1422 }
1423 Some(Err(ErrorContext::new(
1424 "NdtAttrs",
1425 r#type.and_then(|t| NdtAttrs::attr_from_type(t)),
1426 self.orig_loc,
1427 self.buf.as_ptr().wrapping_add(pos) as usize,
1428 )))
1429 }
1430}
1431impl<'a> std::fmt::Debug for IterableNdtAttrs<'_> {
1432 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1433 let mut fmt = f.debug_struct("NdtAttrs");
1434 for attr in self.clone() {
1435 let attr = match attr {
1436 Ok(a) => a,
1437 Err(err) => {
1438 fmt.finish()?;
1439 f.write_str("Err(")?;
1440 err.fmt(f)?;
1441 return f.write_str(")");
1442 }
1443 };
1444 match attr {
1445 NdtAttrs::Name(val) => fmt.field("Name", &val),
1446 NdtAttrs::Thresh1(val) => fmt.field("Thresh1", &val),
1447 NdtAttrs::Thresh2(val) => fmt.field("Thresh2", &val),
1448 NdtAttrs::Thresh3(val) => fmt.field("Thresh3", &val),
1449 NdtAttrs::Config(val) => fmt.field("Config", &val),
1450 NdtAttrs::Parms(val) => fmt.field("Parms", &val),
1451 NdtAttrs::Stats(val) => fmt.field("Stats", &val),
1452 NdtAttrs::GcInterval(val) => fmt.field("GcInterval", &val),
1453 NdtAttrs::Pad(val) => fmt.field("Pad", &val),
1454 };
1455 }
1456 fmt.finish()
1457 }
1458}
1459impl IterableNdtAttrs<'_> {
1460 pub fn lookup_attr(
1461 &self,
1462 offset: usize,
1463 missing_type: Option<u16>,
1464 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1465 let mut stack = Vec::new();
1466 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1467 if missing_type.is_some() && cur == offset {
1468 stack.push(("NdtAttrs", offset));
1469 return (
1470 stack,
1471 missing_type.and_then(|t| NdtAttrs::attr_from_type(t)),
1472 );
1473 }
1474 if cur > offset || cur + self.buf.len() < offset {
1475 return (stack, None);
1476 }
1477 let mut attrs = self.clone();
1478 let mut last_off = cur + attrs.pos;
1479 let mut missing = None;
1480 while let Some(attr) = attrs.next() {
1481 let Ok(attr) = attr else { break };
1482 match attr {
1483 NdtAttrs::Name(val) => {
1484 if last_off == offset {
1485 stack.push(("Name", last_off));
1486 break;
1487 }
1488 }
1489 NdtAttrs::Thresh1(val) => {
1490 if last_off == offset {
1491 stack.push(("Thresh1", last_off));
1492 break;
1493 }
1494 }
1495 NdtAttrs::Thresh2(val) => {
1496 if last_off == offset {
1497 stack.push(("Thresh2", last_off));
1498 break;
1499 }
1500 }
1501 NdtAttrs::Thresh3(val) => {
1502 if last_off == offset {
1503 stack.push(("Thresh3", last_off));
1504 break;
1505 }
1506 }
1507 NdtAttrs::Config(val) => {
1508 if last_off == offset {
1509 stack.push(("Config", last_off));
1510 break;
1511 }
1512 }
1513 NdtAttrs::Parms(val) => {
1514 (stack, missing) = val.lookup_attr(offset, missing_type);
1515 if !stack.is_empty() {
1516 break;
1517 }
1518 }
1519 NdtAttrs::Stats(val) => {
1520 if last_off == offset {
1521 stack.push(("Stats", last_off));
1522 break;
1523 }
1524 }
1525 NdtAttrs::GcInterval(val) => {
1526 if last_off == offset {
1527 stack.push(("GcInterval", last_off));
1528 break;
1529 }
1530 }
1531 NdtAttrs::Pad(val) => {
1532 if last_off == offset {
1533 stack.push(("Pad", last_off));
1534 break;
1535 }
1536 }
1537 _ => {}
1538 };
1539 last_off = cur + attrs.pos;
1540 }
1541 if !stack.is_empty() {
1542 stack.push(("NdtAttrs", cur));
1543 }
1544 (stack, missing)
1545 }
1546}
1547#[derive(Clone)]
1548pub enum NdtpaAttrs<'a> {
1549 Ifindex(u32),
1550 Refcnt(u32),
1551 ReachableTime(u64),
1552 BaseReachableTime(u64),
1553 RetransTime(u64),
1554 GcStaletime(u64),
1555 DelayProbeTime(u64),
1556 QueueLen(u32),
1557 AppProbes(u32),
1558 UcastProbes(u32),
1559 McastProbes(u32),
1560 AnycastDelay(u64),
1561 ProxyDelay(u64),
1562 ProxyQlen(u32),
1563 Locktime(u64),
1564 QueueLenbytes(u32),
1565 McastReprobes(u32),
1566 Pad(&'a [u8]),
1567 IntervalProbeTimeMs(u64),
1568}
1569impl<'a> IterableNdtpaAttrs<'a> {
1570 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
1571 let mut iter = self.clone();
1572 iter.pos = 0;
1573 for attr in iter {
1574 if let Ok(NdtpaAttrs::Ifindex(val)) = attr {
1575 return Ok(val);
1576 }
1577 }
1578 Err(ErrorContext::new_missing(
1579 "NdtpaAttrs",
1580 "Ifindex",
1581 self.orig_loc,
1582 self.buf.as_ptr() as usize,
1583 ))
1584 }
1585 pub fn get_refcnt(&self) -> Result<u32, ErrorContext> {
1586 let mut iter = self.clone();
1587 iter.pos = 0;
1588 for attr in iter {
1589 if let Ok(NdtpaAttrs::Refcnt(val)) = attr {
1590 return Ok(val);
1591 }
1592 }
1593 Err(ErrorContext::new_missing(
1594 "NdtpaAttrs",
1595 "Refcnt",
1596 self.orig_loc,
1597 self.buf.as_ptr() as usize,
1598 ))
1599 }
1600 pub fn get_reachable_time(&self) -> Result<u64, ErrorContext> {
1601 let mut iter = self.clone();
1602 iter.pos = 0;
1603 for attr in iter {
1604 if let Ok(NdtpaAttrs::ReachableTime(val)) = attr {
1605 return Ok(val);
1606 }
1607 }
1608 Err(ErrorContext::new_missing(
1609 "NdtpaAttrs",
1610 "ReachableTime",
1611 self.orig_loc,
1612 self.buf.as_ptr() as usize,
1613 ))
1614 }
1615 pub fn get_base_reachable_time(&self) -> Result<u64, ErrorContext> {
1616 let mut iter = self.clone();
1617 iter.pos = 0;
1618 for attr in iter {
1619 if let Ok(NdtpaAttrs::BaseReachableTime(val)) = attr {
1620 return Ok(val);
1621 }
1622 }
1623 Err(ErrorContext::new_missing(
1624 "NdtpaAttrs",
1625 "BaseReachableTime",
1626 self.orig_loc,
1627 self.buf.as_ptr() as usize,
1628 ))
1629 }
1630 pub fn get_retrans_time(&self) -> Result<u64, ErrorContext> {
1631 let mut iter = self.clone();
1632 iter.pos = 0;
1633 for attr in iter {
1634 if let Ok(NdtpaAttrs::RetransTime(val)) = attr {
1635 return Ok(val);
1636 }
1637 }
1638 Err(ErrorContext::new_missing(
1639 "NdtpaAttrs",
1640 "RetransTime",
1641 self.orig_loc,
1642 self.buf.as_ptr() as usize,
1643 ))
1644 }
1645 pub fn get_gc_staletime(&self) -> Result<u64, ErrorContext> {
1646 let mut iter = self.clone();
1647 iter.pos = 0;
1648 for attr in iter {
1649 if let Ok(NdtpaAttrs::GcStaletime(val)) = attr {
1650 return Ok(val);
1651 }
1652 }
1653 Err(ErrorContext::new_missing(
1654 "NdtpaAttrs",
1655 "GcStaletime",
1656 self.orig_loc,
1657 self.buf.as_ptr() as usize,
1658 ))
1659 }
1660 pub fn get_delay_probe_time(&self) -> Result<u64, ErrorContext> {
1661 let mut iter = self.clone();
1662 iter.pos = 0;
1663 for attr in iter {
1664 if let Ok(NdtpaAttrs::DelayProbeTime(val)) = attr {
1665 return Ok(val);
1666 }
1667 }
1668 Err(ErrorContext::new_missing(
1669 "NdtpaAttrs",
1670 "DelayProbeTime",
1671 self.orig_loc,
1672 self.buf.as_ptr() as usize,
1673 ))
1674 }
1675 pub fn get_queue_len(&self) -> Result<u32, ErrorContext> {
1676 let mut iter = self.clone();
1677 iter.pos = 0;
1678 for attr in iter {
1679 if let Ok(NdtpaAttrs::QueueLen(val)) = attr {
1680 return Ok(val);
1681 }
1682 }
1683 Err(ErrorContext::new_missing(
1684 "NdtpaAttrs",
1685 "QueueLen",
1686 self.orig_loc,
1687 self.buf.as_ptr() as usize,
1688 ))
1689 }
1690 pub fn get_app_probes(&self) -> Result<u32, ErrorContext> {
1691 let mut iter = self.clone();
1692 iter.pos = 0;
1693 for attr in iter {
1694 if let Ok(NdtpaAttrs::AppProbes(val)) = attr {
1695 return Ok(val);
1696 }
1697 }
1698 Err(ErrorContext::new_missing(
1699 "NdtpaAttrs",
1700 "AppProbes",
1701 self.orig_loc,
1702 self.buf.as_ptr() as usize,
1703 ))
1704 }
1705 pub fn get_ucast_probes(&self) -> Result<u32, ErrorContext> {
1706 let mut iter = self.clone();
1707 iter.pos = 0;
1708 for attr in iter {
1709 if let Ok(NdtpaAttrs::UcastProbes(val)) = attr {
1710 return Ok(val);
1711 }
1712 }
1713 Err(ErrorContext::new_missing(
1714 "NdtpaAttrs",
1715 "UcastProbes",
1716 self.orig_loc,
1717 self.buf.as_ptr() as usize,
1718 ))
1719 }
1720 pub fn get_mcast_probes(&self) -> Result<u32, ErrorContext> {
1721 let mut iter = self.clone();
1722 iter.pos = 0;
1723 for attr in iter {
1724 if let Ok(NdtpaAttrs::McastProbes(val)) = attr {
1725 return Ok(val);
1726 }
1727 }
1728 Err(ErrorContext::new_missing(
1729 "NdtpaAttrs",
1730 "McastProbes",
1731 self.orig_loc,
1732 self.buf.as_ptr() as usize,
1733 ))
1734 }
1735 pub fn get_anycast_delay(&self) -> Result<u64, ErrorContext> {
1736 let mut iter = self.clone();
1737 iter.pos = 0;
1738 for attr in iter {
1739 if let Ok(NdtpaAttrs::AnycastDelay(val)) = attr {
1740 return Ok(val);
1741 }
1742 }
1743 Err(ErrorContext::new_missing(
1744 "NdtpaAttrs",
1745 "AnycastDelay",
1746 self.orig_loc,
1747 self.buf.as_ptr() as usize,
1748 ))
1749 }
1750 pub fn get_proxy_delay(&self) -> Result<u64, ErrorContext> {
1751 let mut iter = self.clone();
1752 iter.pos = 0;
1753 for attr in iter {
1754 if let Ok(NdtpaAttrs::ProxyDelay(val)) = attr {
1755 return Ok(val);
1756 }
1757 }
1758 Err(ErrorContext::new_missing(
1759 "NdtpaAttrs",
1760 "ProxyDelay",
1761 self.orig_loc,
1762 self.buf.as_ptr() as usize,
1763 ))
1764 }
1765 pub fn get_proxy_qlen(&self) -> Result<u32, ErrorContext> {
1766 let mut iter = self.clone();
1767 iter.pos = 0;
1768 for attr in iter {
1769 if let Ok(NdtpaAttrs::ProxyQlen(val)) = attr {
1770 return Ok(val);
1771 }
1772 }
1773 Err(ErrorContext::new_missing(
1774 "NdtpaAttrs",
1775 "ProxyQlen",
1776 self.orig_loc,
1777 self.buf.as_ptr() as usize,
1778 ))
1779 }
1780 pub fn get_locktime(&self) -> Result<u64, ErrorContext> {
1781 let mut iter = self.clone();
1782 iter.pos = 0;
1783 for attr in iter {
1784 if let Ok(NdtpaAttrs::Locktime(val)) = attr {
1785 return Ok(val);
1786 }
1787 }
1788 Err(ErrorContext::new_missing(
1789 "NdtpaAttrs",
1790 "Locktime",
1791 self.orig_loc,
1792 self.buf.as_ptr() as usize,
1793 ))
1794 }
1795 pub fn get_queue_lenbytes(&self) -> Result<u32, ErrorContext> {
1796 let mut iter = self.clone();
1797 iter.pos = 0;
1798 for attr in iter {
1799 if let Ok(NdtpaAttrs::QueueLenbytes(val)) = attr {
1800 return Ok(val);
1801 }
1802 }
1803 Err(ErrorContext::new_missing(
1804 "NdtpaAttrs",
1805 "QueueLenbytes",
1806 self.orig_loc,
1807 self.buf.as_ptr() as usize,
1808 ))
1809 }
1810 pub fn get_mcast_reprobes(&self) -> Result<u32, ErrorContext> {
1811 let mut iter = self.clone();
1812 iter.pos = 0;
1813 for attr in iter {
1814 if let Ok(NdtpaAttrs::McastReprobes(val)) = attr {
1815 return Ok(val);
1816 }
1817 }
1818 Err(ErrorContext::new_missing(
1819 "NdtpaAttrs",
1820 "McastReprobes",
1821 self.orig_loc,
1822 self.buf.as_ptr() as usize,
1823 ))
1824 }
1825 pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
1826 let mut iter = self.clone();
1827 iter.pos = 0;
1828 for attr in iter {
1829 if let Ok(NdtpaAttrs::Pad(val)) = attr {
1830 return Ok(val);
1831 }
1832 }
1833 Err(ErrorContext::new_missing(
1834 "NdtpaAttrs",
1835 "Pad",
1836 self.orig_loc,
1837 self.buf.as_ptr() as usize,
1838 ))
1839 }
1840 pub fn get_interval_probe_time_ms(&self) -> Result<u64, ErrorContext> {
1841 let mut iter = self.clone();
1842 iter.pos = 0;
1843 for attr in iter {
1844 if let Ok(NdtpaAttrs::IntervalProbeTimeMs(val)) = attr {
1845 return Ok(val);
1846 }
1847 }
1848 Err(ErrorContext::new_missing(
1849 "NdtpaAttrs",
1850 "IntervalProbeTimeMs",
1851 self.orig_loc,
1852 self.buf.as_ptr() as usize,
1853 ))
1854 }
1855}
1856impl NdtpaAttrs<'_> {
1857 pub fn new<'a>(buf: &'a [u8]) -> IterableNdtpaAttrs<'a> {
1858 IterableNdtpaAttrs::with_loc(buf, buf.as_ptr() as usize)
1859 }
1860 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1861 let res = match r#type {
1862 1u16 => "Ifindex",
1863 2u16 => "Refcnt",
1864 3u16 => "ReachableTime",
1865 4u16 => "BaseReachableTime",
1866 5u16 => "RetransTime",
1867 6u16 => "GcStaletime",
1868 7u16 => "DelayProbeTime",
1869 8u16 => "QueueLen",
1870 9u16 => "AppProbes",
1871 10u16 => "UcastProbes",
1872 11u16 => "McastProbes",
1873 12u16 => "AnycastDelay",
1874 13u16 => "ProxyDelay",
1875 14u16 => "ProxyQlen",
1876 15u16 => "Locktime",
1877 16u16 => "QueueLenbytes",
1878 17u16 => "McastReprobes",
1879 18u16 => "Pad",
1880 19u16 => "IntervalProbeTimeMs",
1881 _ => return None,
1882 };
1883 Some(res)
1884 }
1885}
1886#[derive(Clone, Copy, Default)]
1887pub struct IterableNdtpaAttrs<'a> {
1888 buf: &'a [u8],
1889 pos: usize,
1890 orig_loc: usize,
1891}
1892impl<'a> IterableNdtpaAttrs<'a> {
1893 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1894 Self {
1895 buf,
1896 pos: 0,
1897 orig_loc,
1898 }
1899 }
1900 pub fn get_buf(&self) -> &'a [u8] {
1901 self.buf
1902 }
1903}
1904impl<'a> Iterator for IterableNdtpaAttrs<'a> {
1905 type Item = Result<NdtpaAttrs<'a>, ErrorContext>;
1906 fn next(&mut self) -> Option<Self::Item> {
1907 let mut pos;
1908 let mut r#type;
1909 loop {
1910 pos = self.pos;
1911 r#type = None;
1912 if self.buf.len() == self.pos {
1913 return None;
1914 }
1915 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1916 self.pos = self.buf.len();
1917 break;
1918 };
1919 r#type = Some(header.r#type);
1920 let res = match header.r#type {
1921 1u16 => NdtpaAttrs::Ifindex({
1922 let res = parse_u32(next);
1923 let Some(val) = res else { break };
1924 val
1925 }),
1926 2u16 => NdtpaAttrs::Refcnt({
1927 let res = parse_u32(next);
1928 let Some(val) = res else { break };
1929 val
1930 }),
1931 3u16 => NdtpaAttrs::ReachableTime({
1932 let res = parse_u64(next);
1933 let Some(val) = res else { break };
1934 val
1935 }),
1936 4u16 => NdtpaAttrs::BaseReachableTime({
1937 let res = parse_u64(next);
1938 let Some(val) = res else { break };
1939 val
1940 }),
1941 5u16 => NdtpaAttrs::RetransTime({
1942 let res = parse_u64(next);
1943 let Some(val) = res else { break };
1944 val
1945 }),
1946 6u16 => NdtpaAttrs::GcStaletime({
1947 let res = parse_u64(next);
1948 let Some(val) = res else { break };
1949 val
1950 }),
1951 7u16 => NdtpaAttrs::DelayProbeTime({
1952 let res = parse_u64(next);
1953 let Some(val) = res else { break };
1954 val
1955 }),
1956 8u16 => NdtpaAttrs::QueueLen({
1957 let res = parse_u32(next);
1958 let Some(val) = res else { break };
1959 val
1960 }),
1961 9u16 => NdtpaAttrs::AppProbes({
1962 let res = parse_u32(next);
1963 let Some(val) = res else { break };
1964 val
1965 }),
1966 10u16 => NdtpaAttrs::UcastProbes({
1967 let res = parse_u32(next);
1968 let Some(val) = res else { break };
1969 val
1970 }),
1971 11u16 => NdtpaAttrs::McastProbes({
1972 let res = parse_u32(next);
1973 let Some(val) = res else { break };
1974 val
1975 }),
1976 12u16 => NdtpaAttrs::AnycastDelay({
1977 let res = parse_u64(next);
1978 let Some(val) = res else { break };
1979 val
1980 }),
1981 13u16 => NdtpaAttrs::ProxyDelay({
1982 let res = parse_u64(next);
1983 let Some(val) = res else { break };
1984 val
1985 }),
1986 14u16 => NdtpaAttrs::ProxyQlen({
1987 let res = parse_u32(next);
1988 let Some(val) = res else { break };
1989 val
1990 }),
1991 15u16 => NdtpaAttrs::Locktime({
1992 let res = parse_u64(next);
1993 let Some(val) = res else { break };
1994 val
1995 }),
1996 16u16 => NdtpaAttrs::QueueLenbytes({
1997 let res = parse_u32(next);
1998 let Some(val) = res else { break };
1999 val
2000 }),
2001 17u16 => NdtpaAttrs::McastReprobes({
2002 let res = parse_u32(next);
2003 let Some(val) = res else { break };
2004 val
2005 }),
2006 18u16 => NdtpaAttrs::Pad({
2007 let res = Some(next);
2008 let Some(val) = res else { break };
2009 val
2010 }),
2011 19u16 => NdtpaAttrs::IntervalProbeTimeMs({
2012 let res = parse_u64(next);
2013 let Some(val) = res else { break };
2014 val
2015 }),
2016 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
2017 n => continue,
2018 };
2019 return Some(Ok(res));
2020 }
2021 Some(Err(ErrorContext::new(
2022 "NdtpaAttrs",
2023 r#type.and_then(|t| NdtpaAttrs::attr_from_type(t)),
2024 self.orig_loc,
2025 self.buf.as_ptr().wrapping_add(pos) as usize,
2026 )))
2027 }
2028}
2029impl<'a> std::fmt::Debug for IterableNdtpaAttrs<'_> {
2030 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2031 let mut fmt = f.debug_struct("NdtpaAttrs");
2032 for attr in self.clone() {
2033 let attr = match attr {
2034 Ok(a) => a,
2035 Err(err) => {
2036 fmt.finish()?;
2037 f.write_str("Err(")?;
2038 err.fmt(f)?;
2039 return f.write_str(")");
2040 }
2041 };
2042 match attr {
2043 NdtpaAttrs::Ifindex(val) => fmt.field("Ifindex", &val),
2044 NdtpaAttrs::Refcnt(val) => fmt.field("Refcnt", &val),
2045 NdtpaAttrs::ReachableTime(val) => fmt.field("ReachableTime", &val),
2046 NdtpaAttrs::BaseReachableTime(val) => fmt.field("BaseReachableTime", &val),
2047 NdtpaAttrs::RetransTime(val) => fmt.field("RetransTime", &val),
2048 NdtpaAttrs::GcStaletime(val) => fmt.field("GcStaletime", &val),
2049 NdtpaAttrs::DelayProbeTime(val) => fmt.field("DelayProbeTime", &val),
2050 NdtpaAttrs::QueueLen(val) => fmt.field("QueueLen", &val),
2051 NdtpaAttrs::AppProbes(val) => fmt.field("AppProbes", &val),
2052 NdtpaAttrs::UcastProbes(val) => fmt.field("UcastProbes", &val),
2053 NdtpaAttrs::McastProbes(val) => fmt.field("McastProbes", &val),
2054 NdtpaAttrs::AnycastDelay(val) => fmt.field("AnycastDelay", &val),
2055 NdtpaAttrs::ProxyDelay(val) => fmt.field("ProxyDelay", &val),
2056 NdtpaAttrs::ProxyQlen(val) => fmt.field("ProxyQlen", &val),
2057 NdtpaAttrs::Locktime(val) => fmt.field("Locktime", &val),
2058 NdtpaAttrs::QueueLenbytes(val) => fmt.field("QueueLenbytes", &val),
2059 NdtpaAttrs::McastReprobes(val) => fmt.field("McastReprobes", &val),
2060 NdtpaAttrs::Pad(val) => fmt.field("Pad", &val),
2061 NdtpaAttrs::IntervalProbeTimeMs(val) => fmt.field("IntervalProbeTimeMs", &val),
2062 };
2063 }
2064 fmt.finish()
2065 }
2066}
2067impl IterableNdtpaAttrs<'_> {
2068 pub fn lookup_attr(
2069 &self,
2070 offset: usize,
2071 missing_type: Option<u16>,
2072 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2073 let mut stack = Vec::new();
2074 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
2075 if missing_type.is_some() && cur == offset {
2076 stack.push(("NdtpaAttrs", offset));
2077 return (
2078 stack,
2079 missing_type.and_then(|t| NdtpaAttrs::attr_from_type(t)),
2080 );
2081 }
2082 if cur > offset || cur + self.buf.len() < offset {
2083 return (stack, None);
2084 }
2085 let mut attrs = self.clone();
2086 let mut last_off = cur + attrs.pos;
2087 while let Some(attr) = attrs.next() {
2088 let Ok(attr) = attr else { break };
2089 match attr {
2090 NdtpaAttrs::Ifindex(val) => {
2091 if last_off == offset {
2092 stack.push(("Ifindex", last_off));
2093 break;
2094 }
2095 }
2096 NdtpaAttrs::Refcnt(val) => {
2097 if last_off == offset {
2098 stack.push(("Refcnt", last_off));
2099 break;
2100 }
2101 }
2102 NdtpaAttrs::ReachableTime(val) => {
2103 if last_off == offset {
2104 stack.push(("ReachableTime", last_off));
2105 break;
2106 }
2107 }
2108 NdtpaAttrs::BaseReachableTime(val) => {
2109 if last_off == offset {
2110 stack.push(("BaseReachableTime", last_off));
2111 break;
2112 }
2113 }
2114 NdtpaAttrs::RetransTime(val) => {
2115 if last_off == offset {
2116 stack.push(("RetransTime", last_off));
2117 break;
2118 }
2119 }
2120 NdtpaAttrs::GcStaletime(val) => {
2121 if last_off == offset {
2122 stack.push(("GcStaletime", last_off));
2123 break;
2124 }
2125 }
2126 NdtpaAttrs::DelayProbeTime(val) => {
2127 if last_off == offset {
2128 stack.push(("DelayProbeTime", last_off));
2129 break;
2130 }
2131 }
2132 NdtpaAttrs::QueueLen(val) => {
2133 if last_off == offset {
2134 stack.push(("QueueLen", last_off));
2135 break;
2136 }
2137 }
2138 NdtpaAttrs::AppProbes(val) => {
2139 if last_off == offset {
2140 stack.push(("AppProbes", last_off));
2141 break;
2142 }
2143 }
2144 NdtpaAttrs::UcastProbes(val) => {
2145 if last_off == offset {
2146 stack.push(("UcastProbes", last_off));
2147 break;
2148 }
2149 }
2150 NdtpaAttrs::McastProbes(val) => {
2151 if last_off == offset {
2152 stack.push(("McastProbes", last_off));
2153 break;
2154 }
2155 }
2156 NdtpaAttrs::AnycastDelay(val) => {
2157 if last_off == offset {
2158 stack.push(("AnycastDelay", last_off));
2159 break;
2160 }
2161 }
2162 NdtpaAttrs::ProxyDelay(val) => {
2163 if last_off == offset {
2164 stack.push(("ProxyDelay", last_off));
2165 break;
2166 }
2167 }
2168 NdtpaAttrs::ProxyQlen(val) => {
2169 if last_off == offset {
2170 stack.push(("ProxyQlen", last_off));
2171 break;
2172 }
2173 }
2174 NdtpaAttrs::Locktime(val) => {
2175 if last_off == offset {
2176 stack.push(("Locktime", last_off));
2177 break;
2178 }
2179 }
2180 NdtpaAttrs::QueueLenbytes(val) => {
2181 if last_off == offset {
2182 stack.push(("QueueLenbytes", last_off));
2183 break;
2184 }
2185 }
2186 NdtpaAttrs::McastReprobes(val) => {
2187 if last_off == offset {
2188 stack.push(("McastReprobes", last_off));
2189 break;
2190 }
2191 }
2192 NdtpaAttrs::Pad(val) => {
2193 if last_off == offset {
2194 stack.push(("Pad", last_off));
2195 break;
2196 }
2197 }
2198 NdtpaAttrs::IntervalProbeTimeMs(val) => {
2199 if last_off == offset {
2200 stack.push(("IntervalProbeTimeMs", last_off));
2201 break;
2202 }
2203 }
2204 _ => {}
2205 };
2206 last_off = cur + attrs.pos;
2207 }
2208 if !stack.is_empty() {
2209 stack.push(("NdtpaAttrs", cur));
2210 }
2211 (stack, None)
2212 }
2213}
2214pub struct PushNeighbourAttrs<Prev: Pusher> {
2215 pub(crate) prev: Option<Prev>,
2216 pub(crate) header_offset: Option<usize>,
2217}
2218impl<Prev: Pusher> Pusher for PushNeighbourAttrs<Prev> {
2219 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
2220 self.prev.as_mut().unwrap().as_vec_mut()
2221 }
2222 fn as_vec(&self) -> &Vec<u8> {
2223 self.prev.as_ref().unwrap().as_vec()
2224 }
2225}
2226impl<Prev: Pusher> PushNeighbourAttrs<Prev> {
2227 pub fn new(prev: Prev) -> Self {
2228 Self {
2229 prev: Some(prev),
2230 header_offset: None,
2231 }
2232 }
2233 pub fn end_nested(mut self) -> Prev {
2234 let mut prev = self.prev.take().unwrap();
2235 if let Some(header_offset) = &self.header_offset {
2236 finalize_nested_header(prev.as_vec_mut(), *header_offset);
2237 }
2238 prev
2239 }
2240 pub fn push_unspec(mut self, value: &[u8]) -> Self {
2241 push_header(self.as_vec_mut(), 0u16, value.len() as u16);
2242 self.as_vec_mut().extend(value);
2243 self
2244 }
2245 pub fn push_dst(mut self, value: std::net::IpAddr) -> Self {
2246 push_header(self.as_vec_mut(), 1u16, {
2247 match &value {
2248 IpAddr::V4(_) => 4,
2249 IpAddr::V6(_) => 16,
2250 }
2251 } as u16);
2252 encode_ip(self.as_vec_mut(), value);
2253 self
2254 }
2255 pub fn push_lladdr(mut self, value: &[u8]) -> Self {
2256 push_header(self.as_vec_mut(), 2u16, value.len() as u16);
2257 self.as_vec_mut().extend(value);
2258 self
2259 }
2260 pub fn push_cacheinfo(mut self, value: NdaCacheinfo) -> Self {
2261 push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
2262 self.as_vec_mut().extend(value.as_slice());
2263 self
2264 }
2265 pub fn push_probes(mut self, value: u32) -> Self {
2266 push_header(self.as_vec_mut(), 4u16, 4 as u16);
2267 self.as_vec_mut().extend(value.to_ne_bytes());
2268 self
2269 }
2270 pub fn push_vlan(mut self, value: u16) -> Self {
2271 push_header(self.as_vec_mut(), 5u16, 2 as u16);
2272 self.as_vec_mut().extend(value.to_ne_bytes());
2273 self
2274 }
2275 pub fn push_port(mut self, value: u16) -> Self {
2276 push_header(self.as_vec_mut(), 6u16, 2 as u16);
2277 self.as_vec_mut().extend(value.to_ne_bytes());
2278 self
2279 }
2280 pub fn push_vni(mut self, value: u32) -> Self {
2281 push_header(self.as_vec_mut(), 7u16, 4 as u16);
2282 self.as_vec_mut().extend(value.to_ne_bytes());
2283 self
2284 }
2285 pub fn push_ifindex(mut self, value: u32) -> Self {
2286 push_header(self.as_vec_mut(), 8u16, 4 as u16);
2287 self.as_vec_mut().extend(value.to_ne_bytes());
2288 self
2289 }
2290 pub fn push_master(mut self, value: u32) -> Self {
2291 push_header(self.as_vec_mut(), 9u16, 4 as u16);
2292 self.as_vec_mut().extend(value.to_ne_bytes());
2293 self
2294 }
2295 pub fn push_link_netnsid(mut self, value: i32) -> Self {
2296 push_header(self.as_vec_mut(), 10u16, 4 as u16);
2297 self.as_vec_mut().extend(value.to_ne_bytes());
2298 self
2299 }
2300 pub fn push_src_vni(mut self, value: u32) -> Self {
2301 push_header(self.as_vec_mut(), 11u16, 4 as u16);
2302 self.as_vec_mut().extend(value.to_ne_bytes());
2303 self
2304 }
2305 pub fn push_protocol(mut self, value: u8) -> Self {
2306 push_header(self.as_vec_mut(), 12u16, 1 as u16);
2307 self.as_vec_mut().extend(value.to_ne_bytes());
2308 self
2309 }
2310 pub fn push_nh_id(mut self, value: u32) -> Self {
2311 push_header(self.as_vec_mut(), 13u16, 4 as u16);
2312 self.as_vec_mut().extend(value.to_ne_bytes());
2313 self
2314 }
2315 pub fn push_fdb_ext_attrs(mut self, value: &[u8]) -> Self {
2316 push_header(self.as_vec_mut(), 14u16, value.len() as u16);
2317 self.as_vec_mut().extend(value);
2318 self
2319 }
2320 #[doc = "Associated type: [`NtfExtFlags`] (enum)"]
2321 pub fn push_flags_ext(mut self, value: u32) -> Self {
2322 push_header(self.as_vec_mut(), 15u16, 4 as u16);
2323 self.as_vec_mut().extend(value.to_ne_bytes());
2324 self
2325 }
2326 pub fn push_ndm_state_mask(mut self, value: u16) -> Self {
2327 push_header(self.as_vec_mut(), 16u16, 2 as u16);
2328 self.as_vec_mut().extend(value.to_ne_bytes());
2329 self
2330 }
2331 pub fn push_ndm_flags_mask(mut self, value: u8) -> Self {
2332 push_header(self.as_vec_mut(), 17u16, 1 as u16);
2333 self.as_vec_mut().extend(value.to_ne_bytes());
2334 self
2335 }
2336}
2337impl<Prev: Pusher> Drop for PushNeighbourAttrs<Prev> {
2338 fn drop(&mut self) {
2339 if let Some(prev) = &mut self.prev {
2340 if let Some(header_offset) = &self.header_offset {
2341 finalize_nested_header(prev.as_vec_mut(), *header_offset);
2342 }
2343 }
2344 }
2345}
2346pub struct PushNdtAttrs<Prev: Pusher> {
2347 pub(crate) prev: Option<Prev>,
2348 pub(crate) header_offset: Option<usize>,
2349}
2350impl<Prev: Pusher> Pusher for PushNdtAttrs<Prev> {
2351 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
2352 self.prev.as_mut().unwrap().as_vec_mut()
2353 }
2354 fn as_vec(&self) -> &Vec<u8> {
2355 self.prev.as_ref().unwrap().as_vec()
2356 }
2357}
2358impl<Prev: Pusher> PushNdtAttrs<Prev> {
2359 pub fn new(prev: Prev) -> Self {
2360 Self {
2361 prev: Some(prev),
2362 header_offset: None,
2363 }
2364 }
2365 pub fn end_nested(mut self) -> Prev {
2366 let mut prev = self.prev.take().unwrap();
2367 if let Some(header_offset) = &self.header_offset {
2368 finalize_nested_header(prev.as_vec_mut(), *header_offset);
2369 }
2370 prev
2371 }
2372 pub fn push_name(mut self, value: &CStr) -> Self {
2373 push_header(
2374 self.as_vec_mut(),
2375 1u16,
2376 value.to_bytes_with_nul().len() as u16,
2377 );
2378 self.as_vec_mut().extend(value.to_bytes_with_nul());
2379 self
2380 }
2381 pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
2382 push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
2383 self.as_vec_mut().extend(value);
2384 self.as_vec_mut().push(0);
2385 self
2386 }
2387 pub fn push_thresh1(mut self, value: u32) -> Self {
2388 push_header(self.as_vec_mut(), 2u16, 4 as u16);
2389 self.as_vec_mut().extend(value.to_ne_bytes());
2390 self
2391 }
2392 pub fn push_thresh2(mut self, value: u32) -> Self {
2393 push_header(self.as_vec_mut(), 3u16, 4 as u16);
2394 self.as_vec_mut().extend(value.to_ne_bytes());
2395 self
2396 }
2397 pub fn push_thresh3(mut self, value: u32) -> Self {
2398 push_header(self.as_vec_mut(), 4u16, 4 as u16);
2399 self.as_vec_mut().extend(value.to_ne_bytes());
2400 self
2401 }
2402 pub fn push_config(mut self, value: NdtConfig) -> Self {
2403 push_header(self.as_vec_mut(), 5u16, value.as_slice().len() as u16);
2404 self.as_vec_mut().extend(value.as_slice());
2405 self
2406 }
2407 pub fn nested_parms(mut self) -> PushNdtpaAttrs<Self> {
2408 let header_offset = push_nested_header(self.as_vec_mut(), 6u16);
2409 PushNdtpaAttrs {
2410 prev: Some(self),
2411 header_offset: Some(header_offset),
2412 }
2413 }
2414 pub fn push_stats(mut self, value: NdtStats) -> Self {
2415 push_header(self.as_vec_mut(), 7u16, value.as_slice().len() as u16);
2416 self.as_vec_mut().extend(value.as_slice());
2417 self
2418 }
2419 pub fn push_gc_interval(mut self, value: u64) -> Self {
2420 push_header(self.as_vec_mut(), 8u16, 8 as u16);
2421 self.as_vec_mut().extend(value.to_ne_bytes());
2422 self
2423 }
2424 pub fn push_pad(mut self, value: &[u8]) -> Self {
2425 push_header(self.as_vec_mut(), 9u16, value.len() as u16);
2426 self.as_vec_mut().extend(value);
2427 self
2428 }
2429}
2430impl<Prev: Pusher> Drop for PushNdtAttrs<Prev> {
2431 fn drop(&mut self) {
2432 if let Some(prev) = &mut self.prev {
2433 if let Some(header_offset) = &self.header_offset {
2434 finalize_nested_header(prev.as_vec_mut(), *header_offset);
2435 }
2436 }
2437 }
2438}
2439pub struct PushNdtpaAttrs<Prev: Pusher> {
2440 pub(crate) prev: Option<Prev>,
2441 pub(crate) header_offset: Option<usize>,
2442}
2443impl<Prev: Pusher> Pusher for PushNdtpaAttrs<Prev> {
2444 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
2445 self.prev.as_mut().unwrap().as_vec_mut()
2446 }
2447 fn as_vec(&self) -> &Vec<u8> {
2448 self.prev.as_ref().unwrap().as_vec()
2449 }
2450}
2451impl<Prev: Pusher> PushNdtpaAttrs<Prev> {
2452 pub fn new(prev: Prev) -> Self {
2453 Self {
2454 prev: Some(prev),
2455 header_offset: None,
2456 }
2457 }
2458 pub fn end_nested(mut self) -> Prev {
2459 let mut prev = self.prev.take().unwrap();
2460 if let Some(header_offset) = &self.header_offset {
2461 finalize_nested_header(prev.as_vec_mut(), *header_offset);
2462 }
2463 prev
2464 }
2465 pub fn push_ifindex(mut self, value: u32) -> Self {
2466 push_header(self.as_vec_mut(), 1u16, 4 as u16);
2467 self.as_vec_mut().extend(value.to_ne_bytes());
2468 self
2469 }
2470 pub fn push_refcnt(mut self, value: u32) -> Self {
2471 push_header(self.as_vec_mut(), 2u16, 4 as u16);
2472 self.as_vec_mut().extend(value.to_ne_bytes());
2473 self
2474 }
2475 pub fn push_reachable_time(mut self, value: u64) -> Self {
2476 push_header(self.as_vec_mut(), 3u16, 8 as u16);
2477 self.as_vec_mut().extend(value.to_ne_bytes());
2478 self
2479 }
2480 pub fn push_base_reachable_time(mut self, value: u64) -> Self {
2481 push_header(self.as_vec_mut(), 4u16, 8 as u16);
2482 self.as_vec_mut().extend(value.to_ne_bytes());
2483 self
2484 }
2485 pub fn push_retrans_time(mut self, value: u64) -> Self {
2486 push_header(self.as_vec_mut(), 5u16, 8 as u16);
2487 self.as_vec_mut().extend(value.to_ne_bytes());
2488 self
2489 }
2490 pub fn push_gc_staletime(mut self, value: u64) -> Self {
2491 push_header(self.as_vec_mut(), 6u16, 8 as u16);
2492 self.as_vec_mut().extend(value.to_ne_bytes());
2493 self
2494 }
2495 pub fn push_delay_probe_time(mut self, value: u64) -> Self {
2496 push_header(self.as_vec_mut(), 7u16, 8 as u16);
2497 self.as_vec_mut().extend(value.to_ne_bytes());
2498 self
2499 }
2500 pub fn push_queue_len(mut self, value: u32) -> Self {
2501 push_header(self.as_vec_mut(), 8u16, 4 as u16);
2502 self.as_vec_mut().extend(value.to_ne_bytes());
2503 self
2504 }
2505 pub fn push_app_probes(mut self, value: u32) -> Self {
2506 push_header(self.as_vec_mut(), 9u16, 4 as u16);
2507 self.as_vec_mut().extend(value.to_ne_bytes());
2508 self
2509 }
2510 pub fn push_ucast_probes(mut self, value: u32) -> Self {
2511 push_header(self.as_vec_mut(), 10u16, 4 as u16);
2512 self.as_vec_mut().extend(value.to_ne_bytes());
2513 self
2514 }
2515 pub fn push_mcast_probes(mut self, value: u32) -> Self {
2516 push_header(self.as_vec_mut(), 11u16, 4 as u16);
2517 self.as_vec_mut().extend(value.to_ne_bytes());
2518 self
2519 }
2520 pub fn push_anycast_delay(mut self, value: u64) -> Self {
2521 push_header(self.as_vec_mut(), 12u16, 8 as u16);
2522 self.as_vec_mut().extend(value.to_ne_bytes());
2523 self
2524 }
2525 pub fn push_proxy_delay(mut self, value: u64) -> Self {
2526 push_header(self.as_vec_mut(), 13u16, 8 as u16);
2527 self.as_vec_mut().extend(value.to_ne_bytes());
2528 self
2529 }
2530 pub fn push_proxy_qlen(mut self, value: u32) -> Self {
2531 push_header(self.as_vec_mut(), 14u16, 4 as u16);
2532 self.as_vec_mut().extend(value.to_ne_bytes());
2533 self
2534 }
2535 pub fn push_locktime(mut self, value: u64) -> Self {
2536 push_header(self.as_vec_mut(), 15u16, 8 as u16);
2537 self.as_vec_mut().extend(value.to_ne_bytes());
2538 self
2539 }
2540 pub fn push_queue_lenbytes(mut self, value: u32) -> Self {
2541 push_header(self.as_vec_mut(), 16u16, 4 as u16);
2542 self.as_vec_mut().extend(value.to_ne_bytes());
2543 self
2544 }
2545 pub fn push_mcast_reprobes(mut self, value: u32) -> Self {
2546 push_header(self.as_vec_mut(), 17u16, 4 as u16);
2547 self.as_vec_mut().extend(value.to_ne_bytes());
2548 self
2549 }
2550 pub fn push_pad(mut self, value: &[u8]) -> Self {
2551 push_header(self.as_vec_mut(), 18u16, value.len() as u16);
2552 self.as_vec_mut().extend(value);
2553 self
2554 }
2555 pub fn push_interval_probe_time_ms(mut self, value: u64) -> Self {
2556 push_header(self.as_vec_mut(), 19u16, 8 as u16);
2557 self.as_vec_mut().extend(value.to_ne_bytes());
2558 self
2559 }
2560}
2561impl<Prev: Pusher> Drop for PushNdtpaAttrs<Prev> {
2562 fn drop(&mut self) {
2563 if let Some(prev) = &mut self.prev {
2564 if let Some(header_offset) = &self.header_offset {
2565 finalize_nested_header(prev.as_vec_mut(), *header_offset);
2566 }
2567 }
2568 }
2569}
2570#[doc = "Add new neighbour entry\n\nRequest attributes:\n- [.push_dst()](PushNeighbourAttrs::push_dst)\n- [.push_lladdr()](PushNeighbourAttrs::push_lladdr)\n- [.push_probes()](PushNeighbourAttrs::push_probes)\n- [.push_vlan()](PushNeighbourAttrs::push_vlan)\n- [.push_port()](PushNeighbourAttrs::push_port)\n- [.push_vni()](PushNeighbourAttrs::push_vni)\n- [.push_ifindex()](PushNeighbourAttrs::push_ifindex)\n- [.push_master()](PushNeighbourAttrs::push_master)\n- [.push_protocol()](PushNeighbourAttrs::push_protocol)\n- [.push_nh_id()](PushNeighbourAttrs::push_nh_id)\n- [.push_fdb_ext_attrs()](PushNeighbourAttrs::push_fdb_ext_attrs)\n- [.push_flags_ext()](PushNeighbourAttrs::push_flags_ext)\n\n"]
2571#[derive(Debug)]
2572pub struct OpNewneighDo<'r> {
2573 request: Request<'r>,
2574}
2575impl<'r> OpNewneighDo<'r> {
2576 pub fn new(mut request: Request<'r>, header: &Ndmsg) -> Self {
2577 Self::write_header(request.buf_mut(), header);
2578 Self { request: request }
2579 }
2580 pub fn encode_request<'buf>(
2581 buf: &'buf mut Vec<u8>,
2582 header: &Ndmsg,
2583 ) -> PushNeighbourAttrs<&'buf mut Vec<u8>> {
2584 Self::write_header(buf, header);
2585 PushNeighbourAttrs::new(buf)
2586 }
2587 pub fn encode(&mut self) -> PushNeighbourAttrs<&mut Vec<u8>> {
2588 PushNeighbourAttrs::new(self.request.buf_mut())
2589 }
2590 pub fn into_encoder(self) -> PushNeighbourAttrs<RequestBuf<'r>> {
2591 PushNeighbourAttrs::new(self.request.buf)
2592 }
2593 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ndmsg, IterableNeighbourAttrs<'a>) {
2594 let (header, attrs) = buf.split_at(buf.len().min(Ndmsg::len()));
2595 (
2596 Ndmsg::new_from_slice(header).unwrap_or_default(),
2597 IterableNeighbourAttrs::with_loc(attrs, buf.as_ptr() as usize),
2598 )
2599 }
2600 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Ndmsg) {
2601 prev.as_vec_mut().extend(header.as_slice());
2602 }
2603}
2604impl NetlinkRequest for OpNewneighDo<'_> {
2605 fn protocol(&self) -> Protocol {
2606 Protocol::Raw {
2607 protonum: 0u16,
2608 request_type: 28u16,
2609 }
2610 }
2611 fn flags(&self) -> u16 {
2612 self.request.flags
2613 }
2614 fn payload(&self) -> &[u8] {
2615 self.request.buf()
2616 }
2617 type ReplyType<'buf> = (Ndmsg, IterableNeighbourAttrs<'buf>);
2618 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2619 Self::decode_request(buf)
2620 }
2621 fn lookup(
2622 buf: &[u8],
2623 offset: usize,
2624 missing_type: Option<u16>,
2625 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2626 Self::decode_request(buf)
2627 .1
2628 .lookup_attr(offset, missing_type)
2629 }
2630}
2631#[doc = "Remove an existing neighbour entry\n\nRequest attributes:\n- [.push_dst()](PushNeighbourAttrs::push_dst)\n- [.push_ifindex()](PushNeighbourAttrs::push_ifindex)\n\n"]
2632#[derive(Debug)]
2633pub struct OpDelneighDo<'r> {
2634 request: Request<'r>,
2635}
2636impl<'r> OpDelneighDo<'r> {
2637 pub fn new(mut request: Request<'r>, header: &Ndmsg) -> Self {
2638 Self::write_header(request.buf_mut(), header);
2639 Self { request: request }
2640 }
2641 pub fn encode_request<'buf>(
2642 buf: &'buf mut Vec<u8>,
2643 header: &Ndmsg,
2644 ) -> PushNeighbourAttrs<&'buf mut Vec<u8>> {
2645 Self::write_header(buf, header);
2646 PushNeighbourAttrs::new(buf)
2647 }
2648 pub fn encode(&mut self) -> PushNeighbourAttrs<&mut Vec<u8>> {
2649 PushNeighbourAttrs::new(self.request.buf_mut())
2650 }
2651 pub fn into_encoder(self) -> PushNeighbourAttrs<RequestBuf<'r>> {
2652 PushNeighbourAttrs::new(self.request.buf)
2653 }
2654 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ndmsg, IterableNeighbourAttrs<'a>) {
2655 let (header, attrs) = buf.split_at(buf.len().min(Ndmsg::len()));
2656 (
2657 Ndmsg::new_from_slice(header).unwrap_or_default(),
2658 IterableNeighbourAttrs::with_loc(attrs, buf.as_ptr() as usize),
2659 )
2660 }
2661 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Ndmsg) {
2662 prev.as_vec_mut().extend(header.as_slice());
2663 }
2664}
2665impl NetlinkRequest for OpDelneighDo<'_> {
2666 fn protocol(&self) -> Protocol {
2667 Protocol::Raw {
2668 protonum: 0u16,
2669 request_type: 29u16,
2670 }
2671 }
2672 fn flags(&self) -> u16 {
2673 self.request.flags
2674 }
2675 fn payload(&self) -> &[u8] {
2676 self.request.buf()
2677 }
2678 type ReplyType<'buf> = (Ndmsg, IterableNeighbourAttrs<'buf>);
2679 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2680 Self::decode_request(buf)
2681 }
2682 fn lookup(
2683 buf: &[u8],
2684 offset: usize,
2685 missing_type: Option<u16>,
2686 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2687 Self::decode_request(buf)
2688 .1
2689 .lookup_attr(offset, missing_type)
2690 }
2691}
2692#[doc = "Get or dump neighbour entries\n\nRequest attributes:\n- [.push_ifindex()](PushNeighbourAttrs::push_ifindex)\n- [.push_master()](PushNeighbourAttrs::push_master)\n\nReply attributes:\n- [.get_dst()](IterableNeighbourAttrs::get_dst)\n- [.get_lladdr()](IterableNeighbourAttrs::get_lladdr)\n- [.get_probes()](IterableNeighbourAttrs::get_probes)\n- [.get_vlan()](IterableNeighbourAttrs::get_vlan)\n- [.get_port()](IterableNeighbourAttrs::get_port)\n- [.get_vni()](IterableNeighbourAttrs::get_vni)\n- [.get_ifindex()](IterableNeighbourAttrs::get_ifindex)\n- [.get_master()](IterableNeighbourAttrs::get_master)\n- [.get_protocol()](IterableNeighbourAttrs::get_protocol)\n- [.get_nh_id()](IterableNeighbourAttrs::get_nh_id)\n- [.get_fdb_ext_attrs()](IterableNeighbourAttrs::get_fdb_ext_attrs)\n- [.get_flags_ext()](IterableNeighbourAttrs::get_flags_ext)\n\n"]
2693#[derive(Debug)]
2694pub struct OpGetneighDump<'r> {
2695 request: Request<'r>,
2696}
2697impl<'r> OpGetneighDump<'r> {
2698 pub fn new(mut request: Request<'r>, header: &Ndmsg) -> Self {
2699 Self::write_header(request.buf_mut(), header);
2700 Self {
2701 request: request.set_dump(),
2702 }
2703 }
2704 pub fn encode_request<'buf>(
2705 buf: &'buf mut Vec<u8>,
2706 header: &Ndmsg,
2707 ) -> PushNeighbourAttrs<&'buf mut Vec<u8>> {
2708 Self::write_header(buf, header);
2709 PushNeighbourAttrs::new(buf)
2710 }
2711 pub fn encode(&mut self) -> PushNeighbourAttrs<&mut Vec<u8>> {
2712 PushNeighbourAttrs::new(self.request.buf_mut())
2713 }
2714 pub fn into_encoder(self) -> PushNeighbourAttrs<RequestBuf<'r>> {
2715 PushNeighbourAttrs::new(self.request.buf)
2716 }
2717 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ndmsg, IterableNeighbourAttrs<'a>) {
2718 let (header, attrs) = buf.split_at(buf.len().min(Ndmsg::len()));
2719 (
2720 Ndmsg::new_from_slice(header).unwrap_or_default(),
2721 IterableNeighbourAttrs::with_loc(attrs, buf.as_ptr() as usize),
2722 )
2723 }
2724 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Ndmsg) {
2725 prev.as_vec_mut().extend(header.as_slice());
2726 }
2727}
2728impl NetlinkRequest for OpGetneighDump<'_> {
2729 fn protocol(&self) -> Protocol {
2730 Protocol::Raw {
2731 protonum: 0u16,
2732 request_type: 30u16,
2733 }
2734 }
2735 fn flags(&self) -> u16 {
2736 self.request.flags
2737 }
2738 fn payload(&self) -> &[u8] {
2739 self.request.buf()
2740 }
2741 type ReplyType<'buf> = (Ndmsg, IterableNeighbourAttrs<'buf>);
2742 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2743 Self::decode_request(buf)
2744 }
2745 fn lookup(
2746 buf: &[u8],
2747 offset: usize,
2748 missing_type: Option<u16>,
2749 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2750 Self::decode_request(buf)
2751 .1
2752 .lookup_attr(offset, missing_type)
2753 }
2754}
2755#[doc = "Get or dump neighbour entries\n\nRequest attributes:\n- [.push_dst()](PushNeighbourAttrs::push_dst)\n\nReply attributes:\n- [.get_dst()](IterableNeighbourAttrs::get_dst)\n- [.get_lladdr()](IterableNeighbourAttrs::get_lladdr)\n- [.get_probes()](IterableNeighbourAttrs::get_probes)\n- [.get_vlan()](IterableNeighbourAttrs::get_vlan)\n- [.get_port()](IterableNeighbourAttrs::get_port)\n- [.get_vni()](IterableNeighbourAttrs::get_vni)\n- [.get_ifindex()](IterableNeighbourAttrs::get_ifindex)\n- [.get_master()](IterableNeighbourAttrs::get_master)\n- [.get_protocol()](IterableNeighbourAttrs::get_protocol)\n- [.get_nh_id()](IterableNeighbourAttrs::get_nh_id)\n- [.get_fdb_ext_attrs()](IterableNeighbourAttrs::get_fdb_ext_attrs)\n- [.get_flags_ext()](IterableNeighbourAttrs::get_flags_ext)\n\n"]
2756#[derive(Debug)]
2757pub struct OpGetneighDo<'r> {
2758 request: Request<'r>,
2759}
2760impl<'r> OpGetneighDo<'r> {
2761 pub fn new(mut request: Request<'r>, header: &Ndmsg) -> Self {
2762 Self::write_header(request.buf_mut(), header);
2763 Self { request: request }
2764 }
2765 pub fn encode_request<'buf>(
2766 buf: &'buf mut Vec<u8>,
2767 header: &Ndmsg,
2768 ) -> PushNeighbourAttrs<&'buf mut Vec<u8>> {
2769 Self::write_header(buf, header);
2770 PushNeighbourAttrs::new(buf)
2771 }
2772 pub fn encode(&mut self) -> PushNeighbourAttrs<&mut Vec<u8>> {
2773 PushNeighbourAttrs::new(self.request.buf_mut())
2774 }
2775 pub fn into_encoder(self) -> PushNeighbourAttrs<RequestBuf<'r>> {
2776 PushNeighbourAttrs::new(self.request.buf)
2777 }
2778 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ndmsg, IterableNeighbourAttrs<'a>) {
2779 let (header, attrs) = buf.split_at(buf.len().min(Ndmsg::len()));
2780 (
2781 Ndmsg::new_from_slice(header).unwrap_or_default(),
2782 IterableNeighbourAttrs::with_loc(attrs, buf.as_ptr() as usize),
2783 )
2784 }
2785 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Ndmsg) {
2786 prev.as_vec_mut().extend(header.as_slice());
2787 }
2788}
2789impl NetlinkRequest for OpGetneighDo<'_> {
2790 fn protocol(&self) -> Protocol {
2791 Protocol::Raw {
2792 protonum: 0u16,
2793 request_type: 30u16,
2794 }
2795 }
2796 fn flags(&self) -> u16 {
2797 self.request.flags
2798 }
2799 fn payload(&self) -> &[u8] {
2800 self.request.buf()
2801 }
2802 type ReplyType<'buf> = (Ndmsg, IterableNeighbourAttrs<'buf>);
2803 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2804 Self::decode_request(buf)
2805 }
2806 fn lookup(
2807 buf: &[u8],
2808 offset: usize,
2809 missing_type: Option<u16>,
2810 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2811 Self::decode_request(buf)
2812 .1
2813 .lookup_attr(offset, missing_type)
2814 }
2815}
2816#[doc = "Get or dump neighbour tables\n\nReply attributes:\n- [.get_name()](IterableNdtAttrs::get_name)\n- [.get_thresh1()](IterableNdtAttrs::get_thresh1)\n- [.get_thresh2()](IterableNdtAttrs::get_thresh2)\n- [.get_thresh3()](IterableNdtAttrs::get_thresh3)\n- [.get_config()](IterableNdtAttrs::get_config)\n- [.get_parms()](IterableNdtAttrs::get_parms)\n- [.get_stats()](IterableNdtAttrs::get_stats)\n- [.get_gc_interval()](IterableNdtAttrs::get_gc_interval)\n\n"]
2817#[derive(Debug)]
2818pub struct OpGetneightblDump<'r> {
2819 request: Request<'r>,
2820}
2821impl<'r> OpGetneightblDump<'r> {
2822 pub fn new(mut request: Request<'r>, header: &Ndtmsg) -> Self {
2823 Self::write_header(request.buf_mut(), header);
2824 Self {
2825 request: request.set_dump(),
2826 }
2827 }
2828 pub fn encode_request<'buf>(
2829 buf: &'buf mut Vec<u8>,
2830 header: &Ndtmsg,
2831 ) -> PushNdtAttrs<&'buf mut Vec<u8>> {
2832 Self::write_header(buf, header);
2833 PushNdtAttrs::new(buf)
2834 }
2835 pub fn encode(&mut self) -> PushNdtAttrs<&mut Vec<u8>> {
2836 PushNdtAttrs::new(self.request.buf_mut())
2837 }
2838 pub fn into_encoder(self) -> PushNdtAttrs<RequestBuf<'r>> {
2839 PushNdtAttrs::new(self.request.buf)
2840 }
2841 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ndtmsg, IterableNdtAttrs<'a>) {
2842 let (header, attrs) = buf.split_at(buf.len().min(Ndtmsg::len()));
2843 (
2844 Ndtmsg::new_from_slice(header).unwrap_or_default(),
2845 IterableNdtAttrs::with_loc(attrs, buf.as_ptr() as usize),
2846 )
2847 }
2848 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Ndtmsg) {
2849 prev.as_vec_mut().extend(header.as_slice());
2850 }
2851}
2852impl NetlinkRequest for OpGetneightblDump<'_> {
2853 fn protocol(&self) -> Protocol {
2854 Protocol::Raw {
2855 protonum: 0u16,
2856 request_type: 66u16,
2857 }
2858 }
2859 fn flags(&self) -> u16 {
2860 self.request.flags
2861 }
2862 fn payload(&self) -> &[u8] {
2863 self.request.buf()
2864 }
2865 type ReplyType<'buf> = (Ndtmsg, IterableNdtAttrs<'buf>);
2866 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2867 Self::decode_request(buf)
2868 }
2869 fn lookup(
2870 buf: &[u8],
2871 offset: usize,
2872 missing_type: Option<u16>,
2873 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2874 Self::decode_request(buf)
2875 .1
2876 .lookup_attr(offset, missing_type)
2877 }
2878}
2879#[doc = "Set neighbour tables\n\nRequest attributes:\n- [.push_name()](PushNdtAttrs::push_name)\n- [.push_thresh1()](PushNdtAttrs::push_thresh1)\n- [.push_thresh2()](PushNdtAttrs::push_thresh2)\n- [.push_thresh3()](PushNdtAttrs::push_thresh3)\n- [.nested_parms()](PushNdtAttrs::nested_parms)\n- [.push_gc_interval()](PushNdtAttrs::push_gc_interval)\n\n"]
2880#[derive(Debug)]
2881pub struct OpSetneightblDo<'r> {
2882 request: Request<'r>,
2883}
2884impl<'r> OpSetneightblDo<'r> {
2885 pub fn new(mut request: Request<'r>, header: &Ndtmsg) -> Self {
2886 Self::write_header(request.buf_mut(), header);
2887 Self { request: request }
2888 }
2889 pub fn encode_request<'buf>(
2890 buf: &'buf mut Vec<u8>,
2891 header: &Ndtmsg,
2892 ) -> PushNdtAttrs<&'buf mut Vec<u8>> {
2893 Self::write_header(buf, header);
2894 PushNdtAttrs::new(buf)
2895 }
2896 pub fn encode(&mut self) -> PushNdtAttrs<&mut Vec<u8>> {
2897 PushNdtAttrs::new(self.request.buf_mut())
2898 }
2899 pub fn into_encoder(self) -> PushNdtAttrs<RequestBuf<'r>> {
2900 PushNdtAttrs::new(self.request.buf)
2901 }
2902 pub fn decode_request<'a>(buf: &'a [u8]) -> (Ndtmsg, IterableNdtAttrs<'a>) {
2903 let (header, attrs) = buf.split_at(buf.len().min(Ndtmsg::len()));
2904 (
2905 Ndtmsg::new_from_slice(header).unwrap_or_default(),
2906 IterableNdtAttrs::with_loc(attrs, buf.as_ptr() as usize),
2907 )
2908 }
2909 fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Ndtmsg) {
2910 prev.as_vec_mut().extend(header.as_slice());
2911 }
2912}
2913impl NetlinkRequest for OpSetneightblDo<'_> {
2914 fn protocol(&self) -> Protocol {
2915 Protocol::Raw {
2916 protonum: 0u16,
2917 request_type: 67u16,
2918 }
2919 }
2920 fn flags(&self) -> u16 {
2921 self.request.flags
2922 }
2923 fn payload(&self) -> &[u8] {
2924 self.request.buf()
2925 }
2926 type ReplyType<'buf> = (Ndtmsg, IterableNdtAttrs<'buf>);
2927 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2928 Self::decode_request(buf)
2929 }
2930 fn lookup(
2931 buf: &[u8],
2932 offset: usize,
2933 missing_type: Option<u16>,
2934 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2935 Self::decode_request(buf)
2936 .1
2937 .lookup_attr(offset, missing_type)
2938 }
2939}
2940#[derive(Debug)]
2941pub struct ChainedFinal<'a> {
2942 inner: Chained<'a>,
2943}
2944#[derive(Debug)]
2945pub struct Chained<'a> {
2946 buf: RequestBuf<'a>,
2947 first_seq: u32,
2948 lookups: Vec<(&'static str, LookupFn)>,
2949 last_header_offset: usize,
2950 last_kind: Option<RequestInfo>,
2951}
2952impl<'a> ChainedFinal<'a> {
2953 pub fn into_chained(self) -> Chained<'a> {
2954 self.inner
2955 }
2956 pub fn buf(&self) -> &Vec<u8> {
2957 self.inner.buf()
2958 }
2959 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
2960 self.inner.buf_mut()
2961 }
2962 fn get_index(&self, seq: u32) -> Option<u32> {
2963 let min = self.inner.first_seq;
2964 let max = min.wrapping_add(self.inner.lookups.len() as u32);
2965 return if min <= max {
2966 (min..max).contains(&seq).then(|| seq - min)
2967 } else if min <= seq {
2968 Some(seq - min)
2969 } else if seq < max {
2970 Some(u32::MAX - min + seq)
2971 } else {
2972 None
2973 };
2974 }
2975}
2976impl crate::traits::NetlinkChained for ChainedFinal<'_> {
2977 fn protonum(&self) -> u16 {
2978 PROTONUM
2979 }
2980 fn payload(&self) -> &[u8] {
2981 self.buf()
2982 }
2983 fn chain_len(&self) -> usize {
2984 self.inner.lookups.len()
2985 }
2986 fn get_index(&self, seq: u32) -> Option<usize> {
2987 self.get_index(seq).map(|n| n as usize)
2988 }
2989 fn name(&self, index: usize) -> &'static str {
2990 self.inner.lookups[index].0
2991 }
2992 fn lookup(&self, index: usize) -> LookupFn {
2993 self.inner.lookups[index].1
2994 }
2995}
2996impl Chained<'static> {
2997 pub fn new(first_seq: u32) -> Self {
2998 Self::new_from_buf(Vec::new(), first_seq)
2999 }
3000 pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
3001 Self {
3002 buf: RequestBuf::Own(buf),
3003 first_seq,
3004 lookups: Vec::new(),
3005 last_header_offset: 0,
3006 last_kind: None,
3007 }
3008 }
3009 pub fn into_buf(self) -> Vec<u8> {
3010 match self.buf {
3011 RequestBuf::Own(buf) => buf,
3012 _ => unreachable!(),
3013 }
3014 }
3015}
3016impl<'a> Chained<'a> {
3017 pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
3018 Self {
3019 buf: RequestBuf::Ref(buf),
3020 first_seq,
3021 lookups: Vec::new(),
3022 last_header_offset: 0,
3023 last_kind: None,
3024 }
3025 }
3026 pub fn finalize(mut self) -> ChainedFinal<'a> {
3027 self.update_header();
3028 ChainedFinal { inner: self }
3029 }
3030 pub fn request(&mut self) -> Request<'_> {
3031 self.update_header();
3032 self.last_header_offset = self.buf().len();
3033 self.buf_mut().extend_from_slice(Nlmsghdr::new().as_slice());
3034 let mut request = Request::new_extend(self.buf.buf_mut());
3035 self.last_kind = None;
3036 request.writeback = Some(&mut self.last_kind);
3037 request
3038 }
3039 pub fn buf(&self) -> &Vec<u8> {
3040 self.buf.buf()
3041 }
3042 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3043 self.buf.buf_mut()
3044 }
3045 fn update_header(&mut self) {
3046 let Some(RequestInfo {
3047 protocol,
3048 flags,
3049 name,
3050 lookup,
3051 }) = self.last_kind
3052 else {
3053 if !self.buf().is_empty() {
3054 assert_eq!(self.last_header_offset + Nlmsghdr::len(), self.buf().len());
3055 self.buf.buf_mut().truncate(self.last_header_offset);
3056 }
3057 return;
3058 };
3059 let header_offset = self.last_header_offset;
3060 let request_type = match protocol {
3061 Protocol::Raw { request_type, .. } => request_type,
3062 Protocol::Generic(_) => unreachable!(),
3063 };
3064 let index = self.lookups.len();
3065 let seq = self.first_seq.wrapping_add(index as u32);
3066 self.lookups.push((name, lookup));
3067 let buf = self.buf_mut();
3068 align(buf);
3069 let header = Nlmsghdr {
3070 len: (buf.len() - header_offset) as u32,
3071 r#type: request_type,
3072 flags: flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16,
3073 seq,
3074 pid: 0,
3075 };
3076 buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
3077 }
3078}
3079use crate::traits::LookupFn;
3080use crate::utils::RequestBuf;
3081#[derive(Debug)]
3082pub struct Request<'buf> {
3083 buf: RequestBuf<'buf>,
3084 flags: u16,
3085 writeback: Option<&'buf mut Option<RequestInfo>>,
3086}
3087#[allow(unused)]
3088#[derive(Debug, Clone)]
3089pub struct RequestInfo {
3090 protocol: Protocol,
3091 flags: u16,
3092 name: &'static str,
3093 lookup: LookupFn,
3094}
3095impl Request<'static> {
3096 pub fn new() -> Self {
3097 Self::new_from_buf(Vec::new())
3098 }
3099 pub fn new_from_buf(buf: Vec<u8>) -> Self {
3100 Self {
3101 flags: 0,
3102 buf: RequestBuf::Own(buf),
3103 writeback: None,
3104 }
3105 }
3106 pub fn into_buf(self) -> Vec<u8> {
3107 match self.buf {
3108 RequestBuf::Own(buf) => buf,
3109 _ => unreachable!(),
3110 }
3111 }
3112}
3113impl<'buf> Request<'buf> {
3114 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
3115 buf.clear();
3116 Self::new_extend(buf)
3117 }
3118 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
3119 Self {
3120 flags: 0,
3121 buf: RequestBuf::Ref(buf),
3122 writeback: None,
3123 }
3124 }
3125 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
3126 let Some(writeback) = &mut self.writeback else {
3127 return;
3128 };
3129 **writeback = Some(RequestInfo {
3130 protocol,
3131 flags: self.flags,
3132 name,
3133 lookup,
3134 })
3135 }
3136 pub fn buf(&self) -> &Vec<u8> {
3137 self.buf.buf()
3138 }
3139 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
3140 self.buf.buf_mut()
3141 }
3142 #[doc = "Set `NLM_F_CREATE` flag"]
3143 pub fn set_create(mut self) -> Self {
3144 self.flags |= consts::NLM_F_CREATE as u16;
3145 self
3146 }
3147 #[doc = "Set `NLM_F_EXCL` flag"]
3148 pub fn set_excl(mut self) -> Self {
3149 self.flags |= consts::NLM_F_EXCL as u16;
3150 self
3151 }
3152 #[doc = "Set `NLM_F_REPLACE` flag"]
3153 pub fn set_replace(mut self) -> Self {
3154 self.flags |= consts::NLM_F_REPLACE as u16;
3155 self
3156 }
3157 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
3158 pub fn set_change(self) -> Self {
3159 self.set_create().set_replace()
3160 }
3161 #[doc = "Set `NLM_F_APPEND` flag"]
3162 pub fn set_append(mut self) -> Self {
3163 self.flags |= consts::NLM_F_APPEND as u16;
3164 self
3165 }
3166 #[doc = "Set `self.flags |= flags`"]
3167 pub fn set_flags(mut self, flags: u16) -> Self {
3168 self.flags |= flags;
3169 self
3170 }
3171 #[doc = "Set `self.flags ^= self.flags & flags`"]
3172 pub fn unset_flags(mut self, flags: u16) -> Self {
3173 self.flags ^= self.flags & flags;
3174 self
3175 }
3176 #[doc = "Set `NLM_F_DUMP` flag"]
3177 fn set_dump(mut self) -> Self {
3178 self.flags |= consts::NLM_F_DUMP as u16;
3179 self
3180 }
3181 #[doc = "Add new neighbour entry\n\nRequest attributes:\n- [.push_dst()](PushNeighbourAttrs::push_dst)\n- [.push_lladdr()](PushNeighbourAttrs::push_lladdr)\n- [.push_probes()](PushNeighbourAttrs::push_probes)\n- [.push_vlan()](PushNeighbourAttrs::push_vlan)\n- [.push_port()](PushNeighbourAttrs::push_port)\n- [.push_vni()](PushNeighbourAttrs::push_vni)\n- [.push_ifindex()](PushNeighbourAttrs::push_ifindex)\n- [.push_master()](PushNeighbourAttrs::push_master)\n- [.push_protocol()](PushNeighbourAttrs::push_protocol)\n- [.push_nh_id()](PushNeighbourAttrs::push_nh_id)\n- [.push_fdb_ext_attrs()](PushNeighbourAttrs::push_fdb_ext_attrs)\n- [.push_flags_ext()](PushNeighbourAttrs::push_flags_ext)\n\n"]
3182 pub fn op_newneigh_do(self, header: &Ndmsg) -> OpNewneighDo<'buf> {
3183 let mut res = OpNewneighDo::new(self, header);
3184 res.request
3185 .do_writeback(res.protocol(), "op-newneigh-do", OpNewneighDo::lookup);
3186 res
3187 }
3188 #[doc = "Remove an existing neighbour entry\n\nRequest attributes:\n- [.push_dst()](PushNeighbourAttrs::push_dst)\n- [.push_ifindex()](PushNeighbourAttrs::push_ifindex)\n\n"]
3189 pub fn op_delneigh_do(self, header: &Ndmsg) -> OpDelneighDo<'buf> {
3190 let mut res = OpDelneighDo::new(self, header);
3191 res.request
3192 .do_writeback(res.protocol(), "op-delneigh-do", OpDelneighDo::lookup);
3193 res
3194 }
3195 #[doc = "Get or dump neighbour entries\n\nRequest attributes:\n- [.push_ifindex()](PushNeighbourAttrs::push_ifindex)\n- [.push_master()](PushNeighbourAttrs::push_master)\n\nReply attributes:\n- [.get_dst()](IterableNeighbourAttrs::get_dst)\n- [.get_lladdr()](IterableNeighbourAttrs::get_lladdr)\n- [.get_probes()](IterableNeighbourAttrs::get_probes)\n- [.get_vlan()](IterableNeighbourAttrs::get_vlan)\n- [.get_port()](IterableNeighbourAttrs::get_port)\n- [.get_vni()](IterableNeighbourAttrs::get_vni)\n- [.get_ifindex()](IterableNeighbourAttrs::get_ifindex)\n- [.get_master()](IterableNeighbourAttrs::get_master)\n- [.get_protocol()](IterableNeighbourAttrs::get_protocol)\n- [.get_nh_id()](IterableNeighbourAttrs::get_nh_id)\n- [.get_fdb_ext_attrs()](IterableNeighbourAttrs::get_fdb_ext_attrs)\n- [.get_flags_ext()](IterableNeighbourAttrs::get_flags_ext)\n\n"]
3196 pub fn op_getneigh_dump(self, header: &Ndmsg) -> OpGetneighDump<'buf> {
3197 let mut res = OpGetneighDump::new(self, header);
3198 res.request
3199 .do_writeback(res.protocol(), "op-getneigh-dump", OpGetneighDump::lookup);
3200 res
3201 }
3202 #[doc = "Get or dump neighbour entries\n\nRequest attributes:\n- [.push_dst()](PushNeighbourAttrs::push_dst)\n\nReply attributes:\n- [.get_dst()](IterableNeighbourAttrs::get_dst)\n- [.get_lladdr()](IterableNeighbourAttrs::get_lladdr)\n- [.get_probes()](IterableNeighbourAttrs::get_probes)\n- [.get_vlan()](IterableNeighbourAttrs::get_vlan)\n- [.get_port()](IterableNeighbourAttrs::get_port)\n- [.get_vni()](IterableNeighbourAttrs::get_vni)\n- [.get_ifindex()](IterableNeighbourAttrs::get_ifindex)\n- [.get_master()](IterableNeighbourAttrs::get_master)\n- [.get_protocol()](IterableNeighbourAttrs::get_protocol)\n- [.get_nh_id()](IterableNeighbourAttrs::get_nh_id)\n- [.get_fdb_ext_attrs()](IterableNeighbourAttrs::get_fdb_ext_attrs)\n- [.get_flags_ext()](IterableNeighbourAttrs::get_flags_ext)\n\n"]
3203 pub fn op_getneigh_do(self, header: &Ndmsg) -> OpGetneighDo<'buf> {
3204 let mut res = OpGetneighDo::new(self, header);
3205 res.request
3206 .do_writeback(res.protocol(), "op-getneigh-do", OpGetneighDo::lookup);
3207 res
3208 }
3209 #[doc = "Get or dump neighbour tables\n\nReply attributes:\n- [.get_name()](IterableNdtAttrs::get_name)\n- [.get_thresh1()](IterableNdtAttrs::get_thresh1)\n- [.get_thresh2()](IterableNdtAttrs::get_thresh2)\n- [.get_thresh3()](IterableNdtAttrs::get_thresh3)\n- [.get_config()](IterableNdtAttrs::get_config)\n- [.get_parms()](IterableNdtAttrs::get_parms)\n- [.get_stats()](IterableNdtAttrs::get_stats)\n- [.get_gc_interval()](IterableNdtAttrs::get_gc_interval)\n\n"]
3210 pub fn op_getneightbl_dump(self, header: &Ndtmsg) -> OpGetneightblDump<'buf> {
3211 let mut res = OpGetneightblDump::new(self, header);
3212 res.request.do_writeback(
3213 res.protocol(),
3214 "op-getneightbl-dump",
3215 OpGetneightblDump::lookup,
3216 );
3217 res
3218 }
3219 #[doc = "Set neighbour tables\n\nRequest attributes:\n- [.push_name()](PushNdtAttrs::push_name)\n- [.push_thresh1()](PushNdtAttrs::push_thresh1)\n- [.push_thresh2()](PushNdtAttrs::push_thresh2)\n- [.push_thresh3()](PushNdtAttrs::push_thresh3)\n- [.nested_parms()](PushNdtAttrs::nested_parms)\n- [.push_gc_interval()](PushNdtAttrs::push_gc_interval)\n\n"]
3220 pub fn op_setneightbl_do(self, header: &Ndtmsg) -> OpSetneightblDo<'buf> {
3221 let mut res = OpSetneightblDo::new(self, header);
3222 res.request
3223 .do_writeback(res.protocol(), "op-setneightbl-do", OpSetneightblDo::lookup);
3224 res
3225 }
3226}
3227#[cfg(test)]
3228mod generated_tests {
3229 use super::*;
3230 #[test]
3231 fn tests() {
3232 let _ = IterableNdtAttrs::get_config;
3233 let _ = IterableNdtAttrs::get_gc_interval;
3234 let _ = IterableNdtAttrs::get_name;
3235 let _ = IterableNdtAttrs::get_parms;
3236 let _ = IterableNdtAttrs::get_stats;
3237 let _ = IterableNdtAttrs::get_thresh1;
3238 let _ = IterableNdtAttrs::get_thresh2;
3239 let _ = IterableNdtAttrs::get_thresh3;
3240 let _ = IterableNeighbourAttrs::get_dst;
3241 let _ = IterableNeighbourAttrs::get_fdb_ext_attrs;
3242 let _ = IterableNeighbourAttrs::get_flags_ext;
3243 let _ = IterableNeighbourAttrs::get_ifindex;
3244 let _ = IterableNeighbourAttrs::get_lladdr;
3245 let _ = IterableNeighbourAttrs::get_master;
3246 let _ = IterableNeighbourAttrs::get_nh_id;
3247 let _ = IterableNeighbourAttrs::get_port;
3248 let _ = IterableNeighbourAttrs::get_probes;
3249 let _ = IterableNeighbourAttrs::get_protocol;
3250 let _ = IterableNeighbourAttrs::get_vlan;
3251 let _ = IterableNeighbourAttrs::get_vni;
3252 let _ = PushNdtAttrs::<&mut Vec<u8>>::nested_parms;
3253 let _ = PushNdtAttrs::<&mut Vec<u8>>::push_gc_interval;
3254 let _ = PushNdtAttrs::<&mut Vec<u8>>::push_name;
3255 let _ = PushNdtAttrs::<&mut Vec<u8>>::push_thresh1;
3256 let _ = PushNdtAttrs::<&mut Vec<u8>>::push_thresh2;
3257 let _ = PushNdtAttrs::<&mut Vec<u8>>::push_thresh3;
3258 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_dst;
3259 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_fdb_ext_attrs;
3260 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_flags_ext;
3261 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_ifindex;
3262 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_lladdr;
3263 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_master;
3264 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_nh_id;
3265 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_port;
3266 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_probes;
3267 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_protocol;
3268 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_vlan;
3269 let _ = PushNeighbourAttrs::<&mut Vec<u8>>::push_vni;
3270 }
3271}