1#![doc = "PSP Security Protocol Generic Netlink family.\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 = "psp";
17pub const PROTONAME_CSTR: &CStr = c"psp";
18#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
19#[derive(Debug, Clone, Copy)]
20pub enum Version {
21 Hdr0AesGcm128 = 0,
22 Hdr0AesGcm256 = 1,
23 Hdr0AesGmac128 = 2,
24 Hdr0AesGmac256 = 3,
25}
26impl Version {
27 pub fn from_value(value: u64) -> Option<Self> {
28 Some(match value {
29 0 => Self::Hdr0AesGcm128,
30 1 => Self::Hdr0AesGcm256,
31 2 => Self::Hdr0AesGmac128,
32 3 => Self::Hdr0AesGmac256,
33 _ => return None,
34 })
35 }
36}
37#[derive(Clone)]
38pub enum AssocDevInfo {
39 #[doc = "ifindex of an associated network device.\n"]
40 Ifindex(u32),
41 #[doc = "Network namespace ID of the associated device.\n"]
42 Nsid(i32),
43}
44impl<'a> IterableAssocDevInfo<'a> {
45 #[doc = "ifindex of an associated network device.\n"]
46 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
47 let mut iter = self.clone();
48 iter.pos = 0;
49 for attr in iter {
50 if let Ok(AssocDevInfo::Ifindex(val)) = attr {
51 return Ok(val);
52 }
53 }
54 Err(ErrorContext::new_missing(
55 "AssocDevInfo",
56 "Ifindex",
57 self.orig_loc,
58 self.buf.as_ptr() as usize,
59 ))
60 }
61 #[doc = "Network namespace ID of the associated device.\n"]
62 pub fn get_nsid(&self) -> Result<i32, ErrorContext> {
63 let mut iter = self.clone();
64 iter.pos = 0;
65 for attr in iter {
66 if let Ok(AssocDevInfo::Nsid(val)) = attr {
67 return Ok(val);
68 }
69 }
70 Err(ErrorContext::new_missing(
71 "AssocDevInfo",
72 "Nsid",
73 self.orig_loc,
74 self.buf.as_ptr() as usize,
75 ))
76 }
77}
78impl AssocDevInfo {
79 pub fn new<'a>(buf: &'a [u8]) -> IterableAssocDevInfo<'a> {
80 IterableAssocDevInfo::with_loc(buf, buf.as_ptr() as usize)
81 }
82 fn attr_from_type(r#type: u16) -> Option<&'static str> {
83 let res = match r#type {
84 1u16 => "Ifindex",
85 2u16 => "Nsid",
86 _ => return None,
87 };
88 Some(res)
89 }
90}
91#[derive(Clone, Copy, Default)]
92pub struct IterableAssocDevInfo<'a> {
93 buf: &'a [u8],
94 pos: usize,
95 orig_loc: usize,
96}
97impl<'a> IterableAssocDevInfo<'a> {
98 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
99 Self {
100 buf,
101 pos: 0,
102 orig_loc,
103 }
104 }
105 pub fn get_buf(&self) -> &'a [u8] {
106 self.buf
107 }
108}
109impl<'a> Iterator for IterableAssocDevInfo<'a> {
110 type Item = Result<AssocDevInfo, ErrorContext>;
111 fn next(&mut self) -> Option<Self::Item> {
112 let mut pos;
113 let mut r#type;
114 loop {
115 pos = self.pos;
116 r#type = None;
117 if self.buf.len() == self.pos {
118 return None;
119 }
120 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
121 self.pos = self.buf.len();
122 break;
123 };
124 r#type = Some(header.r#type);
125 let res = match header.r#type {
126 1u16 => AssocDevInfo::Ifindex({
127 let res = parse_u32(next);
128 let Some(val) = res else { break };
129 val
130 }),
131 2u16 => AssocDevInfo::Nsid({
132 let res = parse_i32(next);
133 let Some(val) = res else { break };
134 val
135 }),
136 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
137 n => continue,
138 };
139 return Some(Ok(res));
140 }
141 Some(Err(ErrorContext::new(
142 "AssocDevInfo",
143 r#type.and_then(|t| AssocDevInfo::attr_from_type(t)),
144 self.orig_loc,
145 self.buf.as_ptr().wrapping_add(pos) as usize,
146 )))
147 }
148}
149impl std::fmt::Debug for IterableAssocDevInfo<'_> {
150 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 let mut fmt = f.debug_struct("AssocDevInfo");
152 for attr in self.clone() {
153 let attr = match attr {
154 Ok(a) => a,
155 Err(err) => {
156 fmt.finish()?;
157 f.write_str("Err(")?;
158 err.fmt(f)?;
159 return f.write_str(")");
160 }
161 };
162 match attr {
163 AssocDevInfo::Ifindex(val) => fmt.field("Ifindex", &val),
164 AssocDevInfo::Nsid(val) => fmt.field("Nsid", &val),
165 };
166 }
167 fmt.finish()
168 }
169}
170impl IterableAssocDevInfo<'_> {
171 pub fn lookup_attr(
172 &self,
173 offset: usize,
174 missing_type: Option<u16>,
175 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
176 let mut stack = Vec::new();
177 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
178 if missing_type.is_some() && cur == offset {
179 stack.push(("AssocDevInfo", offset));
180 return (
181 stack,
182 missing_type.and_then(|t| AssocDevInfo::attr_from_type(t)),
183 );
184 }
185 if cur > offset || cur + self.buf.len() < offset {
186 return (stack, None);
187 }
188 let mut attrs = self.clone();
189 let mut last_off = cur + attrs.pos;
190 while let Some(attr) = attrs.next() {
191 let Ok(attr) = attr else { break };
192 match attr {
193 AssocDevInfo::Ifindex(val) => {
194 if last_off == offset {
195 stack.push(("Ifindex", last_off));
196 break;
197 }
198 }
199 AssocDevInfo::Nsid(val) => {
200 if last_off == offset {
201 stack.push(("Nsid", last_off));
202 break;
203 }
204 }
205 _ => {}
206 };
207 last_off = cur + attrs.pos;
208 }
209 if !stack.is_empty() {
210 stack.push(("AssocDevInfo", cur));
211 }
212 (stack, None)
213 }
214}
215#[derive(Clone)]
216pub enum Dev<'a> {
217 #[doc = "PSP device ID.\n"]
218 Id(u32),
219 #[doc = "ifindex of the main netdevice linked to the PSP device, or the ifindex\nto associate with the PSP device.\n"]
220 Ifindex(u32),
221 #[doc = "Bitmask of PSP versions supported by the device.\n\nAssociated type: [`Version`] (1 bit per enumeration)"]
222 PspVersionsCap(u32),
223 #[doc = "Bitmask of currently enabled (accepted on Rx) PSP versions.\n\nAssociated type: [`Version`] (1 bit per enumeration)"]
224 PspVersionsEna(u32),
225 #[doc = "List of associated virtual devices.\n\nAttribute may repeat multiple times (treat it as array)"]
226 AssocList(IterableAssocDevInfo<'a>),
227 #[doc = "Network namespace ID for the device to associate/disassociate. Optional\nfor dev-assoc and dev-disassoc; if not present, the device is looked up\nin the caller\\'s network namespace.\n"]
228 Nsid(i32),
229 #[doc = "Flag indicating the PSP device is an associated device from a different\nnetwork namespace. Present when in associated namespace, absent when in\nprimary/host namespace.\n"]
230 ByAssociation(()),
231}
232impl<'a> IterableDev<'a> {
233 #[doc = "PSP device ID.\n"]
234 pub fn get_id(&self) -> Result<u32, ErrorContext> {
235 let mut iter = self.clone();
236 iter.pos = 0;
237 for attr in iter {
238 if let Ok(Dev::Id(val)) = attr {
239 return Ok(val);
240 }
241 }
242 Err(ErrorContext::new_missing(
243 "Dev",
244 "Id",
245 self.orig_loc,
246 self.buf.as_ptr() as usize,
247 ))
248 }
249 #[doc = "ifindex of the main netdevice linked to the PSP device, or the ifindex\nto associate with the PSP device.\n"]
250 pub fn get_ifindex(&self) -> Result<u32, ErrorContext> {
251 let mut iter = self.clone();
252 iter.pos = 0;
253 for attr in iter {
254 if let Ok(Dev::Ifindex(val)) = attr {
255 return Ok(val);
256 }
257 }
258 Err(ErrorContext::new_missing(
259 "Dev",
260 "Ifindex",
261 self.orig_loc,
262 self.buf.as_ptr() as usize,
263 ))
264 }
265 #[doc = "Bitmask of PSP versions supported by the device.\n\nAssociated type: [`Version`] (1 bit per enumeration)"]
266 pub fn get_psp_versions_cap(&self) -> Result<u32, ErrorContext> {
267 let mut iter = self.clone();
268 iter.pos = 0;
269 for attr in iter {
270 if let Ok(Dev::PspVersionsCap(val)) = attr {
271 return Ok(val);
272 }
273 }
274 Err(ErrorContext::new_missing(
275 "Dev",
276 "PspVersionsCap",
277 self.orig_loc,
278 self.buf.as_ptr() as usize,
279 ))
280 }
281 #[doc = "Bitmask of currently enabled (accepted on Rx) PSP versions.\n\nAssociated type: [`Version`] (1 bit per enumeration)"]
282 pub fn get_psp_versions_ena(&self) -> Result<u32, ErrorContext> {
283 let mut iter = self.clone();
284 iter.pos = 0;
285 for attr in iter {
286 if let Ok(Dev::PspVersionsEna(val)) = attr {
287 return Ok(val);
288 }
289 }
290 Err(ErrorContext::new_missing(
291 "Dev",
292 "PspVersionsEna",
293 self.orig_loc,
294 self.buf.as_ptr() as usize,
295 ))
296 }
297 #[doc = "List of associated virtual devices.\n\nAttribute may repeat multiple times (treat it as array)"]
298 pub fn get_assoc_list(&self) -> MultiAttrIterable<Self, Dev<'a>, IterableAssocDevInfo<'a>> {
299 MultiAttrIterable::new(self.clone(), |variant| {
300 if let Dev::AssocList(val) = variant {
301 Some(val)
302 } else {
303 None
304 }
305 })
306 }
307 #[doc = "Network namespace ID for the device to associate/disassociate. Optional\nfor dev-assoc and dev-disassoc; if not present, the device is looked up\nin the caller\\'s network namespace.\n"]
308 pub fn get_nsid(&self) -> Result<i32, ErrorContext> {
309 let mut iter = self.clone();
310 iter.pos = 0;
311 for attr in iter {
312 if let Ok(Dev::Nsid(val)) = attr {
313 return Ok(val);
314 }
315 }
316 Err(ErrorContext::new_missing(
317 "Dev",
318 "Nsid",
319 self.orig_loc,
320 self.buf.as_ptr() as usize,
321 ))
322 }
323 #[doc = "Flag indicating the PSP device is an associated device from a different\nnetwork namespace. Present when in associated namespace, absent when in\nprimary/host namespace.\n"]
324 pub fn get_by_association(&self) -> Result<(), ErrorContext> {
325 let mut iter = self.clone();
326 iter.pos = 0;
327 for attr in iter {
328 if let Ok(Dev::ByAssociation(val)) = attr {
329 return Ok(val);
330 }
331 }
332 Err(ErrorContext::new_missing(
333 "Dev",
334 "ByAssociation",
335 self.orig_loc,
336 self.buf.as_ptr() as usize,
337 ))
338 }
339}
340impl Dev<'_> {
341 pub fn new<'a>(buf: &'a [u8]) -> IterableDev<'a> {
342 IterableDev::with_loc(buf, buf.as_ptr() as usize)
343 }
344 fn attr_from_type(r#type: u16) -> Option<&'static str> {
345 let res = match r#type {
346 1u16 => "Id",
347 2u16 => "Ifindex",
348 3u16 => "PspVersionsCap",
349 4u16 => "PspVersionsEna",
350 5u16 => "AssocList",
351 6u16 => "Nsid",
352 7u16 => "ByAssociation",
353 _ => return None,
354 };
355 Some(res)
356 }
357}
358#[derive(Clone, Copy, Default)]
359pub struct IterableDev<'a> {
360 buf: &'a [u8],
361 pos: usize,
362 orig_loc: usize,
363}
364impl<'a> IterableDev<'a> {
365 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
366 Self {
367 buf,
368 pos: 0,
369 orig_loc,
370 }
371 }
372 pub fn get_buf(&self) -> &'a [u8] {
373 self.buf
374 }
375}
376impl<'a> Iterator for IterableDev<'a> {
377 type Item = Result<Dev<'a>, ErrorContext>;
378 fn next(&mut self) -> Option<Self::Item> {
379 let mut pos;
380 let mut r#type;
381 loop {
382 pos = self.pos;
383 r#type = None;
384 if self.buf.len() == self.pos {
385 return None;
386 }
387 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
388 self.pos = self.buf.len();
389 break;
390 };
391 r#type = Some(header.r#type);
392 let res = match header.r#type {
393 1u16 => Dev::Id({
394 let res = parse_u32(next);
395 let Some(val) = res else { break };
396 val
397 }),
398 2u16 => Dev::Ifindex({
399 let res = parse_u32(next);
400 let Some(val) = res else { break };
401 val
402 }),
403 3u16 => Dev::PspVersionsCap({
404 let res = parse_u32(next);
405 let Some(val) = res else { break };
406 val
407 }),
408 4u16 => Dev::PspVersionsEna({
409 let res = parse_u32(next);
410 let Some(val) = res else { break };
411 val
412 }),
413 5u16 => Dev::AssocList({
414 let res = Some(IterableAssocDevInfo::with_loc(next, self.orig_loc));
415 let Some(val) = res else { break };
416 val
417 }),
418 6u16 => Dev::Nsid({
419 let res = parse_i32(next);
420 let Some(val) = res else { break };
421 val
422 }),
423 7u16 => Dev::ByAssociation(()),
424 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
425 n => continue,
426 };
427 return Some(Ok(res));
428 }
429 Some(Err(ErrorContext::new(
430 "Dev",
431 r#type.and_then(|t| Dev::attr_from_type(t)),
432 self.orig_loc,
433 self.buf.as_ptr().wrapping_add(pos) as usize,
434 )))
435 }
436}
437impl<'a> std::fmt::Debug for IterableDev<'_> {
438 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
439 let mut fmt = f.debug_struct("Dev");
440 for attr in self.clone() {
441 let attr = match attr {
442 Ok(a) => a,
443 Err(err) => {
444 fmt.finish()?;
445 f.write_str("Err(")?;
446 err.fmt(f)?;
447 return f.write_str(")");
448 }
449 };
450 match attr {
451 Dev::Id(val) => fmt.field("Id", &val),
452 Dev::Ifindex(val) => fmt.field("Ifindex", &val),
453 Dev::PspVersionsCap(val) => fmt.field(
454 "PspVersionsCap",
455 &FormatFlags(val.into(), |val| {
456 Version::from_value(val.trailing_zeros().into())
457 }),
458 ),
459 Dev::PspVersionsEna(val) => fmt.field(
460 "PspVersionsEna",
461 &FormatFlags(val.into(), |val| {
462 Version::from_value(val.trailing_zeros().into())
463 }),
464 ),
465 Dev::AssocList(val) => fmt.field("AssocList", &val),
466 Dev::Nsid(val) => fmt.field("Nsid", &val),
467 Dev::ByAssociation(val) => fmt.field("ByAssociation", &val),
468 };
469 }
470 fmt.finish()
471 }
472}
473impl IterableDev<'_> {
474 pub fn lookup_attr(
475 &self,
476 offset: usize,
477 missing_type: Option<u16>,
478 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
479 let mut stack = Vec::new();
480 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
481 if missing_type.is_some() && cur == offset {
482 stack.push(("Dev", offset));
483 return (stack, missing_type.and_then(|t| Dev::attr_from_type(t)));
484 }
485 if cur > offset || cur + self.buf.len() < offset {
486 return (stack, None);
487 }
488 let mut attrs = self.clone();
489 let mut last_off = cur + attrs.pos;
490 let mut missing = None;
491 while let Some(attr) = attrs.next() {
492 let Ok(attr) = attr else { break };
493 match attr {
494 Dev::Id(val) => {
495 if last_off == offset {
496 stack.push(("Id", last_off));
497 break;
498 }
499 }
500 Dev::Ifindex(val) => {
501 if last_off == offset {
502 stack.push(("Ifindex", last_off));
503 break;
504 }
505 }
506 Dev::PspVersionsCap(val) => {
507 if last_off == offset {
508 stack.push(("PspVersionsCap", last_off));
509 break;
510 }
511 }
512 Dev::PspVersionsEna(val) => {
513 if last_off == offset {
514 stack.push(("PspVersionsEna", last_off));
515 break;
516 }
517 }
518 Dev::AssocList(val) => {
519 (stack, missing) = val.lookup_attr(offset, missing_type);
520 if !stack.is_empty() {
521 break;
522 }
523 }
524 Dev::Nsid(val) => {
525 if last_off == offset {
526 stack.push(("Nsid", last_off));
527 break;
528 }
529 }
530 Dev::ByAssociation(val) => {
531 if last_off == offset {
532 stack.push(("ByAssociation", last_off));
533 break;
534 }
535 }
536 _ => {}
537 };
538 last_off = cur + attrs.pos;
539 }
540 if !stack.is_empty() {
541 stack.push(("Dev", cur));
542 }
543 (stack, missing)
544 }
545}
546#[derive(Clone)]
547pub enum Assoc<'a> {
548 #[doc = "PSP device ID.\n"]
549 DevId(u32),
550 #[doc = "PSP versions (AEAD and protocol version) used by this association,\ndictates the size of the key.\n\nAssociated type: [`Version`] (enum)"]
551 Version(u32),
552 RxKey(IterableKeys<'a>),
553 TxKey(IterableKeys<'a>),
554 #[doc = "Sockets which should be bound to the association immediately.\n"]
555 SockFd(u32),
556}
557impl<'a> IterableAssoc<'a> {
558 #[doc = "PSP device ID.\n"]
559 pub fn get_dev_id(&self) -> Result<u32, ErrorContext> {
560 let mut iter = self.clone();
561 iter.pos = 0;
562 for attr in iter {
563 if let Ok(Assoc::DevId(val)) = attr {
564 return Ok(val);
565 }
566 }
567 Err(ErrorContext::new_missing(
568 "Assoc",
569 "DevId",
570 self.orig_loc,
571 self.buf.as_ptr() as usize,
572 ))
573 }
574 #[doc = "PSP versions (AEAD and protocol version) used by this association,\ndictates the size of the key.\n\nAssociated type: [`Version`] (enum)"]
575 pub fn get_version(&self) -> Result<u32, ErrorContext> {
576 let mut iter = self.clone();
577 iter.pos = 0;
578 for attr in iter {
579 if let Ok(Assoc::Version(val)) = attr {
580 return Ok(val);
581 }
582 }
583 Err(ErrorContext::new_missing(
584 "Assoc",
585 "Version",
586 self.orig_loc,
587 self.buf.as_ptr() as usize,
588 ))
589 }
590 pub fn get_rx_key(&self) -> Result<IterableKeys<'a>, ErrorContext> {
591 let mut iter = self.clone();
592 iter.pos = 0;
593 for attr in iter {
594 if let Ok(Assoc::RxKey(val)) = attr {
595 return Ok(val);
596 }
597 }
598 Err(ErrorContext::new_missing(
599 "Assoc",
600 "RxKey",
601 self.orig_loc,
602 self.buf.as_ptr() as usize,
603 ))
604 }
605 pub fn get_tx_key(&self) -> Result<IterableKeys<'a>, ErrorContext> {
606 let mut iter = self.clone();
607 iter.pos = 0;
608 for attr in iter {
609 if let Ok(Assoc::TxKey(val)) = attr {
610 return Ok(val);
611 }
612 }
613 Err(ErrorContext::new_missing(
614 "Assoc",
615 "TxKey",
616 self.orig_loc,
617 self.buf.as_ptr() as usize,
618 ))
619 }
620 #[doc = "Sockets which should be bound to the association immediately.\n"]
621 pub fn get_sock_fd(&self) -> Result<u32, ErrorContext> {
622 let mut iter = self.clone();
623 iter.pos = 0;
624 for attr in iter {
625 if let Ok(Assoc::SockFd(val)) = attr {
626 return Ok(val);
627 }
628 }
629 Err(ErrorContext::new_missing(
630 "Assoc",
631 "SockFd",
632 self.orig_loc,
633 self.buf.as_ptr() as usize,
634 ))
635 }
636}
637impl Assoc<'_> {
638 pub fn new<'a>(buf: &'a [u8]) -> IterableAssoc<'a> {
639 IterableAssoc::with_loc(buf, buf.as_ptr() as usize)
640 }
641 fn attr_from_type(r#type: u16) -> Option<&'static str> {
642 let res = match r#type {
643 1u16 => "DevId",
644 2u16 => "Version",
645 3u16 => "RxKey",
646 4u16 => "TxKey",
647 5u16 => "SockFd",
648 _ => return None,
649 };
650 Some(res)
651 }
652}
653#[derive(Clone, Copy, Default)]
654pub struct IterableAssoc<'a> {
655 buf: &'a [u8],
656 pos: usize,
657 orig_loc: usize,
658}
659impl<'a> IterableAssoc<'a> {
660 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
661 Self {
662 buf,
663 pos: 0,
664 orig_loc,
665 }
666 }
667 pub fn get_buf(&self) -> &'a [u8] {
668 self.buf
669 }
670}
671impl<'a> Iterator for IterableAssoc<'a> {
672 type Item = Result<Assoc<'a>, ErrorContext>;
673 fn next(&mut self) -> Option<Self::Item> {
674 let mut pos;
675 let mut r#type;
676 loop {
677 pos = self.pos;
678 r#type = None;
679 if self.buf.len() == self.pos {
680 return None;
681 }
682 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
683 self.pos = self.buf.len();
684 break;
685 };
686 r#type = Some(header.r#type);
687 let res = match header.r#type {
688 1u16 => Assoc::DevId({
689 let res = parse_u32(next);
690 let Some(val) = res else { break };
691 val
692 }),
693 2u16 => Assoc::Version({
694 let res = parse_u32(next);
695 let Some(val) = res else { break };
696 val
697 }),
698 3u16 => Assoc::RxKey({
699 let res = Some(IterableKeys::with_loc(next, self.orig_loc));
700 let Some(val) = res else { break };
701 val
702 }),
703 4u16 => Assoc::TxKey({
704 let res = Some(IterableKeys::with_loc(next, self.orig_loc));
705 let Some(val) = res else { break };
706 val
707 }),
708 5u16 => Assoc::SockFd({
709 let res = parse_u32(next);
710 let Some(val) = res else { break };
711 val
712 }),
713 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
714 n => continue,
715 };
716 return Some(Ok(res));
717 }
718 Some(Err(ErrorContext::new(
719 "Assoc",
720 r#type.and_then(|t| Assoc::attr_from_type(t)),
721 self.orig_loc,
722 self.buf.as_ptr().wrapping_add(pos) as usize,
723 )))
724 }
725}
726impl<'a> std::fmt::Debug for IterableAssoc<'_> {
727 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
728 let mut fmt = f.debug_struct("Assoc");
729 for attr in self.clone() {
730 let attr = match attr {
731 Ok(a) => a,
732 Err(err) => {
733 fmt.finish()?;
734 f.write_str("Err(")?;
735 err.fmt(f)?;
736 return f.write_str(")");
737 }
738 };
739 match attr {
740 Assoc::DevId(val) => fmt.field("DevId", &val),
741 Assoc::Version(val) => {
742 fmt.field("Version", &FormatEnum(val.into(), Version::from_value))
743 }
744 Assoc::RxKey(val) => fmt.field("RxKey", &val),
745 Assoc::TxKey(val) => fmt.field("TxKey", &val),
746 Assoc::SockFd(val) => fmt.field("SockFd", &val),
747 };
748 }
749 fmt.finish()
750 }
751}
752impl IterableAssoc<'_> {
753 pub fn lookup_attr(
754 &self,
755 offset: usize,
756 missing_type: Option<u16>,
757 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
758 let mut stack = Vec::new();
759 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
760 if missing_type.is_some() && cur == offset {
761 stack.push(("Assoc", offset));
762 return (stack, missing_type.and_then(|t| Assoc::attr_from_type(t)));
763 }
764 if cur > offset || cur + self.buf.len() < offset {
765 return (stack, None);
766 }
767 let mut attrs = self.clone();
768 let mut last_off = cur + attrs.pos;
769 let mut missing = None;
770 while let Some(attr) = attrs.next() {
771 let Ok(attr) = attr else { break };
772 match attr {
773 Assoc::DevId(val) => {
774 if last_off == offset {
775 stack.push(("DevId", last_off));
776 break;
777 }
778 }
779 Assoc::Version(val) => {
780 if last_off == offset {
781 stack.push(("Version", last_off));
782 break;
783 }
784 }
785 Assoc::RxKey(val) => {
786 (stack, missing) = val.lookup_attr(offset, missing_type);
787 if !stack.is_empty() {
788 break;
789 }
790 }
791 Assoc::TxKey(val) => {
792 (stack, missing) = val.lookup_attr(offset, missing_type);
793 if !stack.is_empty() {
794 break;
795 }
796 }
797 Assoc::SockFd(val) => {
798 if last_off == offset {
799 stack.push(("SockFd", last_off));
800 break;
801 }
802 }
803 _ => {}
804 };
805 last_off = cur + attrs.pos;
806 }
807 if !stack.is_empty() {
808 stack.push(("Assoc", cur));
809 }
810 (stack, missing)
811 }
812}
813#[derive(Clone)]
814pub enum Keys<'a> {
815 Key(&'a [u8]),
816 #[doc = "Security Parameters Index (SPI) of the association.\n"]
817 Spi(u32),
818}
819impl<'a> IterableKeys<'a> {
820 pub fn get_key(&self) -> Result<&'a [u8], ErrorContext> {
821 let mut iter = self.clone();
822 iter.pos = 0;
823 for attr in iter {
824 if let Ok(Keys::Key(val)) = attr {
825 return Ok(val);
826 }
827 }
828 Err(ErrorContext::new_missing(
829 "Keys",
830 "Key",
831 self.orig_loc,
832 self.buf.as_ptr() as usize,
833 ))
834 }
835 #[doc = "Security Parameters Index (SPI) of the association.\n"]
836 pub fn get_spi(&self) -> Result<u32, ErrorContext> {
837 let mut iter = self.clone();
838 iter.pos = 0;
839 for attr in iter {
840 if let Ok(Keys::Spi(val)) = attr {
841 return Ok(val);
842 }
843 }
844 Err(ErrorContext::new_missing(
845 "Keys",
846 "Spi",
847 self.orig_loc,
848 self.buf.as_ptr() as usize,
849 ))
850 }
851}
852impl Keys<'_> {
853 pub fn new<'a>(buf: &'a [u8]) -> IterableKeys<'a> {
854 IterableKeys::with_loc(buf, buf.as_ptr() as usize)
855 }
856 fn attr_from_type(r#type: u16) -> Option<&'static str> {
857 let res = match r#type {
858 1u16 => "Key",
859 2u16 => "Spi",
860 _ => return None,
861 };
862 Some(res)
863 }
864}
865#[derive(Clone, Copy, Default)]
866pub struct IterableKeys<'a> {
867 buf: &'a [u8],
868 pos: usize,
869 orig_loc: usize,
870}
871impl<'a> IterableKeys<'a> {
872 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
873 Self {
874 buf,
875 pos: 0,
876 orig_loc,
877 }
878 }
879 pub fn get_buf(&self) -> &'a [u8] {
880 self.buf
881 }
882}
883impl<'a> Iterator for IterableKeys<'a> {
884 type Item = Result<Keys<'a>, ErrorContext>;
885 fn next(&mut self) -> Option<Self::Item> {
886 let mut pos;
887 let mut r#type;
888 loop {
889 pos = self.pos;
890 r#type = None;
891 if self.buf.len() == self.pos {
892 return None;
893 }
894 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
895 self.pos = self.buf.len();
896 break;
897 };
898 r#type = Some(header.r#type);
899 let res = match header.r#type {
900 1u16 => Keys::Key({
901 let res = Some(next);
902 let Some(val) = res else { break };
903 val
904 }),
905 2u16 => Keys::Spi({
906 let res = parse_u32(next);
907 let Some(val) = res else { break };
908 val
909 }),
910 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
911 n => continue,
912 };
913 return Some(Ok(res));
914 }
915 Some(Err(ErrorContext::new(
916 "Keys",
917 r#type.and_then(|t| Keys::attr_from_type(t)),
918 self.orig_loc,
919 self.buf.as_ptr().wrapping_add(pos) as usize,
920 )))
921 }
922}
923impl<'a> std::fmt::Debug for IterableKeys<'_> {
924 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
925 let mut fmt = f.debug_struct("Keys");
926 for attr in self.clone() {
927 let attr = match attr {
928 Ok(a) => a,
929 Err(err) => {
930 fmt.finish()?;
931 f.write_str("Err(")?;
932 err.fmt(f)?;
933 return f.write_str(")");
934 }
935 };
936 match attr {
937 Keys::Key(val) => fmt.field("Key", &val),
938 Keys::Spi(val) => fmt.field("Spi", &val),
939 };
940 }
941 fmt.finish()
942 }
943}
944impl IterableKeys<'_> {
945 pub fn lookup_attr(
946 &self,
947 offset: usize,
948 missing_type: Option<u16>,
949 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
950 let mut stack = Vec::new();
951 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
952 if missing_type.is_some() && cur == offset {
953 stack.push(("Keys", offset));
954 return (stack, missing_type.and_then(|t| Keys::attr_from_type(t)));
955 }
956 if cur > offset || cur + self.buf.len() < offset {
957 return (stack, None);
958 }
959 let mut attrs = self.clone();
960 let mut last_off = cur + attrs.pos;
961 while let Some(attr) = attrs.next() {
962 let Ok(attr) = attr else { break };
963 match attr {
964 Keys::Key(val) => {
965 if last_off == offset {
966 stack.push(("Key", last_off));
967 break;
968 }
969 }
970 Keys::Spi(val) => {
971 if last_off == offset {
972 stack.push(("Spi", last_off));
973 break;
974 }
975 }
976 _ => {}
977 };
978 last_off = cur + attrs.pos;
979 }
980 if !stack.is_empty() {
981 stack.push(("Keys", cur));
982 }
983 (stack, None)
984 }
985}
986#[derive(Clone)]
987pub enum Stats {
988 #[doc = "PSP device ID.\n"]
989 DevId(u32),
990 #[doc = "Number of key rotations during the lifetime of the device. Kernel\nstatistic.\n"]
991 KeyRotations(u32),
992 #[doc = "Number of times a socket\\'s Rx got shut down due to using a key which\nwent stale (fully rotated out). Kernel statistic.\n"]
993 StaleEvents(u32),
994 #[doc = "Number of successfully processed and authenticated PSP packets. Device\nstatistic (from the PSP spec).\n"]
995 RxPackets(u32),
996 #[doc = "Number of successfully authenticated PSP bytes received, counting from\nthe first byte after the IV through the last byte of payload. The fixed\ninitial portion of the PSP header (16 bytes) and the PSP trailer/ICV (16\nbytes) are not included in this count. Device statistic (from the PSP\nspec).\n"]
997 RxBytes(u32),
998 #[doc = "Number of received PSP packets with unsuccessful authentication. Device\nstatistic (from the PSP spec).\n"]
999 RxAuthFail(u32),
1000 #[doc = "Number of received PSP packets with length/framing errors. Device\nstatistic (from the PSP spec).\n"]
1001 RxError(u32),
1002 #[doc = "Number of received PSP packets with miscellaneous errors (invalid master\nkey indicated by SPI, unsupported version, etc.) Device statistic (from\nthe PSP spec).\n"]
1003 RxBad(u32),
1004 #[doc = "Number of successfully processed PSP packets for transmission. Device\nstatistic (from the PSP spec).\n"]
1005 TxPackets(u32),
1006 #[doc = "Number of successfully processed PSP bytes for transmit, counting from\nthe first byte after the IV through the last byte of payload. The fixed\ninitial portion of the PSP header (16 bytes) and the PSP trailer/ICV (16\nbytes) are not included in this count. Device statistic (from the PSP\nspec).\n"]
1007 TxBytes(u32),
1008 #[doc = "Number of PSP packets for transmission with errors. Device statistic\n(from the PSP spec).\n"]
1009 TxError(u32),
1010}
1011impl<'a> IterableStats<'a> {
1012 #[doc = "PSP device ID.\n"]
1013 pub fn get_dev_id(&self) -> Result<u32, ErrorContext> {
1014 let mut iter = self.clone();
1015 iter.pos = 0;
1016 for attr in iter {
1017 if let Ok(Stats::DevId(val)) = attr {
1018 return Ok(val);
1019 }
1020 }
1021 Err(ErrorContext::new_missing(
1022 "Stats",
1023 "DevId",
1024 self.orig_loc,
1025 self.buf.as_ptr() as usize,
1026 ))
1027 }
1028 #[doc = "Number of key rotations during the lifetime of the device. Kernel\nstatistic.\n"]
1029 pub fn get_key_rotations(&self) -> Result<u32, ErrorContext> {
1030 let mut iter = self.clone();
1031 iter.pos = 0;
1032 for attr in iter {
1033 if let Ok(Stats::KeyRotations(val)) = attr {
1034 return Ok(val);
1035 }
1036 }
1037 Err(ErrorContext::new_missing(
1038 "Stats",
1039 "KeyRotations",
1040 self.orig_loc,
1041 self.buf.as_ptr() as usize,
1042 ))
1043 }
1044 #[doc = "Number of times a socket\\'s Rx got shut down due to using a key which\nwent stale (fully rotated out). Kernel statistic.\n"]
1045 pub fn get_stale_events(&self) -> Result<u32, ErrorContext> {
1046 let mut iter = self.clone();
1047 iter.pos = 0;
1048 for attr in iter {
1049 if let Ok(Stats::StaleEvents(val)) = attr {
1050 return Ok(val);
1051 }
1052 }
1053 Err(ErrorContext::new_missing(
1054 "Stats",
1055 "StaleEvents",
1056 self.orig_loc,
1057 self.buf.as_ptr() as usize,
1058 ))
1059 }
1060 #[doc = "Number of successfully processed and authenticated PSP packets. Device\nstatistic (from the PSP spec).\n"]
1061 pub fn get_rx_packets(&self) -> Result<u32, ErrorContext> {
1062 let mut iter = self.clone();
1063 iter.pos = 0;
1064 for attr in iter {
1065 if let Ok(Stats::RxPackets(val)) = attr {
1066 return Ok(val);
1067 }
1068 }
1069 Err(ErrorContext::new_missing(
1070 "Stats",
1071 "RxPackets",
1072 self.orig_loc,
1073 self.buf.as_ptr() as usize,
1074 ))
1075 }
1076 #[doc = "Number of successfully authenticated PSP bytes received, counting from\nthe first byte after the IV through the last byte of payload. The fixed\ninitial portion of the PSP header (16 bytes) and the PSP trailer/ICV (16\nbytes) are not included in this count. Device statistic (from the PSP\nspec).\n"]
1077 pub fn get_rx_bytes(&self) -> Result<u32, ErrorContext> {
1078 let mut iter = self.clone();
1079 iter.pos = 0;
1080 for attr in iter {
1081 if let Ok(Stats::RxBytes(val)) = attr {
1082 return Ok(val);
1083 }
1084 }
1085 Err(ErrorContext::new_missing(
1086 "Stats",
1087 "RxBytes",
1088 self.orig_loc,
1089 self.buf.as_ptr() as usize,
1090 ))
1091 }
1092 #[doc = "Number of received PSP packets with unsuccessful authentication. Device\nstatistic (from the PSP spec).\n"]
1093 pub fn get_rx_auth_fail(&self) -> Result<u32, ErrorContext> {
1094 let mut iter = self.clone();
1095 iter.pos = 0;
1096 for attr in iter {
1097 if let Ok(Stats::RxAuthFail(val)) = attr {
1098 return Ok(val);
1099 }
1100 }
1101 Err(ErrorContext::new_missing(
1102 "Stats",
1103 "RxAuthFail",
1104 self.orig_loc,
1105 self.buf.as_ptr() as usize,
1106 ))
1107 }
1108 #[doc = "Number of received PSP packets with length/framing errors. Device\nstatistic (from the PSP spec).\n"]
1109 pub fn get_rx_error(&self) -> Result<u32, ErrorContext> {
1110 let mut iter = self.clone();
1111 iter.pos = 0;
1112 for attr in iter {
1113 if let Ok(Stats::RxError(val)) = attr {
1114 return Ok(val);
1115 }
1116 }
1117 Err(ErrorContext::new_missing(
1118 "Stats",
1119 "RxError",
1120 self.orig_loc,
1121 self.buf.as_ptr() as usize,
1122 ))
1123 }
1124 #[doc = "Number of received PSP packets with miscellaneous errors (invalid master\nkey indicated by SPI, unsupported version, etc.) Device statistic (from\nthe PSP spec).\n"]
1125 pub fn get_rx_bad(&self) -> Result<u32, ErrorContext> {
1126 let mut iter = self.clone();
1127 iter.pos = 0;
1128 for attr in iter {
1129 if let Ok(Stats::RxBad(val)) = attr {
1130 return Ok(val);
1131 }
1132 }
1133 Err(ErrorContext::new_missing(
1134 "Stats",
1135 "RxBad",
1136 self.orig_loc,
1137 self.buf.as_ptr() as usize,
1138 ))
1139 }
1140 #[doc = "Number of successfully processed PSP packets for transmission. Device\nstatistic (from the PSP spec).\n"]
1141 pub fn get_tx_packets(&self) -> Result<u32, ErrorContext> {
1142 let mut iter = self.clone();
1143 iter.pos = 0;
1144 for attr in iter {
1145 if let Ok(Stats::TxPackets(val)) = attr {
1146 return Ok(val);
1147 }
1148 }
1149 Err(ErrorContext::new_missing(
1150 "Stats",
1151 "TxPackets",
1152 self.orig_loc,
1153 self.buf.as_ptr() as usize,
1154 ))
1155 }
1156 #[doc = "Number of successfully processed PSP bytes for transmit, counting from\nthe first byte after the IV through the last byte of payload. The fixed\ninitial portion of the PSP header (16 bytes) and the PSP trailer/ICV (16\nbytes) are not included in this count. Device statistic (from the PSP\nspec).\n"]
1157 pub fn get_tx_bytes(&self) -> Result<u32, ErrorContext> {
1158 let mut iter = self.clone();
1159 iter.pos = 0;
1160 for attr in iter {
1161 if let Ok(Stats::TxBytes(val)) = attr {
1162 return Ok(val);
1163 }
1164 }
1165 Err(ErrorContext::new_missing(
1166 "Stats",
1167 "TxBytes",
1168 self.orig_loc,
1169 self.buf.as_ptr() as usize,
1170 ))
1171 }
1172 #[doc = "Number of PSP packets for transmission with errors. Device statistic\n(from the PSP spec).\n"]
1173 pub fn get_tx_error(&self) -> Result<u32, ErrorContext> {
1174 let mut iter = self.clone();
1175 iter.pos = 0;
1176 for attr in iter {
1177 if let Ok(Stats::TxError(val)) = attr {
1178 return Ok(val);
1179 }
1180 }
1181 Err(ErrorContext::new_missing(
1182 "Stats",
1183 "TxError",
1184 self.orig_loc,
1185 self.buf.as_ptr() as usize,
1186 ))
1187 }
1188}
1189impl Stats {
1190 pub fn new<'a>(buf: &'a [u8]) -> IterableStats<'a> {
1191 IterableStats::with_loc(buf, buf.as_ptr() as usize)
1192 }
1193 fn attr_from_type(r#type: u16) -> Option<&'static str> {
1194 let res = match r#type {
1195 1u16 => "DevId",
1196 2u16 => "KeyRotations",
1197 3u16 => "StaleEvents",
1198 4u16 => "RxPackets",
1199 5u16 => "RxBytes",
1200 6u16 => "RxAuthFail",
1201 7u16 => "RxError",
1202 8u16 => "RxBad",
1203 9u16 => "TxPackets",
1204 10u16 => "TxBytes",
1205 11u16 => "TxError",
1206 _ => return None,
1207 };
1208 Some(res)
1209 }
1210}
1211#[derive(Clone, Copy, Default)]
1212pub struct IterableStats<'a> {
1213 buf: &'a [u8],
1214 pos: usize,
1215 orig_loc: usize,
1216}
1217impl<'a> IterableStats<'a> {
1218 fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
1219 Self {
1220 buf,
1221 pos: 0,
1222 orig_loc,
1223 }
1224 }
1225 pub fn get_buf(&self) -> &'a [u8] {
1226 self.buf
1227 }
1228}
1229impl<'a> Iterator for IterableStats<'a> {
1230 type Item = Result<Stats, ErrorContext>;
1231 fn next(&mut self) -> Option<Self::Item> {
1232 let mut pos;
1233 let mut r#type;
1234 loop {
1235 pos = self.pos;
1236 r#type = None;
1237 if self.buf.len() == self.pos {
1238 return None;
1239 }
1240 let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
1241 self.pos = self.buf.len();
1242 break;
1243 };
1244 r#type = Some(header.r#type);
1245 let res = match header.r#type {
1246 1u16 => Stats::DevId({
1247 let res = parse_u32(next);
1248 let Some(val) = res else { break };
1249 val
1250 }),
1251 2u16 => Stats::KeyRotations({
1252 let res = parse_u32(next);
1253 let Some(val) = res else { break };
1254 val
1255 }),
1256 3u16 => Stats::StaleEvents({
1257 let res = parse_u32(next);
1258 let Some(val) = res else { break };
1259 val
1260 }),
1261 4u16 => Stats::RxPackets({
1262 let res = parse_u32(next);
1263 let Some(val) = res else { break };
1264 val
1265 }),
1266 5u16 => Stats::RxBytes({
1267 let res = parse_u32(next);
1268 let Some(val) = res else { break };
1269 val
1270 }),
1271 6u16 => Stats::RxAuthFail({
1272 let res = parse_u32(next);
1273 let Some(val) = res else { break };
1274 val
1275 }),
1276 7u16 => Stats::RxError({
1277 let res = parse_u32(next);
1278 let Some(val) = res else { break };
1279 val
1280 }),
1281 8u16 => Stats::RxBad({
1282 let res = parse_u32(next);
1283 let Some(val) = res else { break };
1284 val
1285 }),
1286 9u16 => Stats::TxPackets({
1287 let res = parse_u32(next);
1288 let Some(val) = res else { break };
1289 val
1290 }),
1291 10u16 => Stats::TxBytes({
1292 let res = parse_u32(next);
1293 let Some(val) = res else { break };
1294 val
1295 }),
1296 11u16 => Stats::TxError({
1297 let res = parse_u32(next);
1298 let Some(val) = res else { break };
1299 val
1300 }),
1301 n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
1302 n => continue,
1303 };
1304 return Some(Ok(res));
1305 }
1306 Some(Err(ErrorContext::new(
1307 "Stats",
1308 r#type.and_then(|t| Stats::attr_from_type(t)),
1309 self.orig_loc,
1310 self.buf.as_ptr().wrapping_add(pos) as usize,
1311 )))
1312 }
1313}
1314impl std::fmt::Debug for IterableStats<'_> {
1315 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1316 let mut fmt = f.debug_struct("Stats");
1317 for attr in self.clone() {
1318 let attr = match attr {
1319 Ok(a) => a,
1320 Err(err) => {
1321 fmt.finish()?;
1322 f.write_str("Err(")?;
1323 err.fmt(f)?;
1324 return f.write_str(")");
1325 }
1326 };
1327 match attr {
1328 Stats::DevId(val) => fmt.field("DevId", &val),
1329 Stats::KeyRotations(val) => fmt.field("KeyRotations", &val),
1330 Stats::StaleEvents(val) => fmt.field("StaleEvents", &val),
1331 Stats::RxPackets(val) => fmt.field("RxPackets", &val),
1332 Stats::RxBytes(val) => fmt.field("RxBytes", &val),
1333 Stats::RxAuthFail(val) => fmt.field("RxAuthFail", &val),
1334 Stats::RxError(val) => fmt.field("RxError", &val),
1335 Stats::RxBad(val) => fmt.field("RxBad", &val),
1336 Stats::TxPackets(val) => fmt.field("TxPackets", &val),
1337 Stats::TxBytes(val) => fmt.field("TxBytes", &val),
1338 Stats::TxError(val) => fmt.field("TxError", &val),
1339 };
1340 }
1341 fmt.finish()
1342 }
1343}
1344impl IterableStats<'_> {
1345 pub fn lookup_attr(
1346 &self,
1347 offset: usize,
1348 missing_type: Option<u16>,
1349 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1350 let mut stack = Vec::new();
1351 let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
1352 if missing_type.is_some() && cur == offset {
1353 stack.push(("Stats", offset));
1354 return (stack, missing_type.and_then(|t| Stats::attr_from_type(t)));
1355 }
1356 if cur > offset || cur + self.buf.len() < offset {
1357 return (stack, None);
1358 }
1359 let mut attrs = self.clone();
1360 let mut last_off = cur + attrs.pos;
1361 while let Some(attr) = attrs.next() {
1362 let Ok(attr) = attr else { break };
1363 match attr {
1364 Stats::DevId(val) => {
1365 if last_off == offset {
1366 stack.push(("DevId", last_off));
1367 break;
1368 }
1369 }
1370 Stats::KeyRotations(val) => {
1371 if last_off == offset {
1372 stack.push(("KeyRotations", last_off));
1373 break;
1374 }
1375 }
1376 Stats::StaleEvents(val) => {
1377 if last_off == offset {
1378 stack.push(("StaleEvents", last_off));
1379 break;
1380 }
1381 }
1382 Stats::RxPackets(val) => {
1383 if last_off == offset {
1384 stack.push(("RxPackets", last_off));
1385 break;
1386 }
1387 }
1388 Stats::RxBytes(val) => {
1389 if last_off == offset {
1390 stack.push(("RxBytes", last_off));
1391 break;
1392 }
1393 }
1394 Stats::RxAuthFail(val) => {
1395 if last_off == offset {
1396 stack.push(("RxAuthFail", last_off));
1397 break;
1398 }
1399 }
1400 Stats::RxError(val) => {
1401 if last_off == offset {
1402 stack.push(("RxError", last_off));
1403 break;
1404 }
1405 }
1406 Stats::RxBad(val) => {
1407 if last_off == offset {
1408 stack.push(("RxBad", last_off));
1409 break;
1410 }
1411 }
1412 Stats::TxPackets(val) => {
1413 if last_off == offset {
1414 stack.push(("TxPackets", last_off));
1415 break;
1416 }
1417 }
1418 Stats::TxBytes(val) => {
1419 if last_off == offset {
1420 stack.push(("TxBytes", last_off));
1421 break;
1422 }
1423 }
1424 Stats::TxError(val) => {
1425 if last_off == offset {
1426 stack.push(("TxError", last_off));
1427 break;
1428 }
1429 }
1430 _ => {}
1431 };
1432 last_off = cur + attrs.pos;
1433 }
1434 if !stack.is_empty() {
1435 stack.push(("Stats", cur));
1436 }
1437 (stack, None)
1438 }
1439}
1440pub struct PushAssocDevInfo<Prev: Pusher> {
1441 pub(crate) prev: Option<Prev>,
1442 pub(crate) header_offset: Option<usize>,
1443}
1444impl<Prev: Pusher> Pusher for PushAssocDevInfo<Prev> {
1445 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1446 self.prev.as_mut().unwrap().as_vec_mut()
1447 }
1448 fn as_vec(&self) -> &Vec<u8> {
1449 self.prev.as_ref().unwrap().as_vec()
1450 }
1451}
1452impl<Prev: Pusher> PushAssocDevInfo<Prev> {
1453 pub fn new(prev: Prev) -> Self {
1454 Self {
1455 prev: Some(prev),
1456 header_offset: None,
1457 }
1458 }
1459 pub fn end_nested(mut self) -> Prev {
1460 let mut prev = self.prev.take().unwrap();
1461 if let Some(header_offset) = &self.header_offset {
1462 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1463 }
1464 prev
1465 }
1466 #[doc = "ifindex of an associated network device.\n"]
1467 pub fn push_ifindex(mut self, value: u32) -> Self {
1468 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1469 self.as_vec_mut().extend(value.to_ne_bytes());
1470 self
1471 }
1472 #[doc = "Network namespace ID of the associated device.\n"]
1473 pub fn push_nsid(mut self, value: i32) -> Self {
1474 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1475 self.as_vec_mut().extend(value.to_ne_bytes());
1476 self
1477 }
1478}
1479impl<Prev: Pusher> Drop for PushAssocDevInfo<Prev> {
1480 fn drop(&mut self) {
1481 if let Some(prev) = &mut self.prev {
1482 if let Some(header_offset) = &self.header_offset {
1483 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1484 }
1485 }
1486 }
1487}
1488pub struct PushDev<Prev: Pusher> {
1489 pub(crate) prev: Option<Prev>,
1490 pub(crate) header_offset: Option<usize>,
1491}
1492impl<Prev: Pusher> Pusher for PushDev<Prev> {
1493 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1494 self.prev.as_mut().unwrap().as_vec_mut()
1495 }
1496 fn as_vec(&self) -> &Vec<u8> {
1497 self.prev.as_ref().unwrap().as_vec()
1498 }
1499}
1500impl<Prev: Pusher> PushDev<Prev> {
1501 pub fn new(prev: Prev) -> Self {
1502 Self {
1503 prev: Some(prev),
1504 header_offset: None,
1505 }
1506 }
1507 pub fn end_nested(mut self) -> Prev {
1508 let mut prev = self.prev.take().unwrap();
1509 if let Some(header_offset) = &self.header_offset {
1510 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1511 }
1512 prev
1513 }
1514 #[doc = "PSP device ID.\n"]
1515 pub fn push_id(mut self, value: u32) -> Self {
1516 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1517 self.as_vec_mut().extend(value.to_ne_bytes());
1518 self
1519 }
1520 #[doc = "ifindex of the main netdevice linked to the PSP device, or the ifindex\nto associate with the PSP device.\n"]
1521 pub fn push_ifindex(mut self, value: u32) -> Self {
1522 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1523 self.as_vec_mut().extend(value.to_ne_bytes());
1524 self
1525 }
1526 #[doc = "Bitmask of PSP versions supported by the device.\n\nAssociated type: [`Version`] (1 bit per enumeration)"]
1527 pub fn push_psp_versions_cap(mut self, value: u32) -> Self {
1528 push_header(self.as_vec_mut(), 3u16, 4 as u16);
1529 self.as_vec_mut().extend(value.to_ne_bytes());
1530 self
1531 }
1532 #[doc = "Bitmask of currently enabled (accepted on Rx) PSP versions.\n\nAssociated type: [`Version`] (1 bit per enumeration)"]
1533 pub fn push_psp_versions_ena(mut self, value: u32) -> Self {
1534 push_header(self.as_vec_mut(), 4u16, 4 as u16);
1535 self.as_vec_mut().extend(value.to_ne_bytes());
1536 self
1537 }
1538 #[doc = "List of associated virtual devices.\n\nAttribute may repeat multiple times (treat it as array)"]
1539 pub fn nested_assoc_list(mut self) -> PushAssocDevInfo<Self> {
1540 let header_offset = push_nested_header(self.as_vec_mut(), 5u16);
1541 PushAssocDevInfo {
1542 prev: Some(self),
1543 header_offset: Some(header_offset),
1544 }
1545 }
1546 #[doc = "Network namespace ID for the device to associate/disassociate. Optional\nfor dev-assoc and dev-disassoc; if not present, the device is looked up\nin the caller\\'s network namespace.\n"]
1547 pub fn push_nsid(mut self, value: i32) -> Self {
1548 push_header(self.as_vec_mut(), 6u16, 4 as u16);
1549 self.as_vec_mut().extend(value.to_ne_bytes());
1550 self
1551 }
1552 #[doc = "Flag indicating the PSP device is an associated device from a different\nnetwork namespace. Present when in associated namespace, absent when in\nprimary/host namespace.\n"]
1553 pub fn push_by_association(mut self, value: ()) -> Self {
1554 push_header(self.as_vec_mut(), 7u16, 0 as u16);
1555 self
1556 }
1557}
1558impl<Prev: Pusher> Drop for PushDev<Prev> {
1559 fn drop(&mut self) {
1560 if let Some(prev) = &mut self.prev {
1561 if let Some(header_offset) = &self.header_offset {
1562 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1563 }
1564 }
1565 }
1566}
1567pub struct PushAssoc<Prev: Pusher> {
1568 pub(crate) prev: Option<Prev>,
1569 pub(crate) header_offset: Option<usize>,
1570}
1571impl<Prev: Pusher> Pusher for PushAssoc<Prev> {
1572 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1573 self.prev.as_mut().unwrap().as_vec_mut()
1574 }
1575 fn as_vec(&self) -> &Vec<u8> {
1576 self.prev.as_ref().unwrap().as_vec()
1577 }
1578}
1579impl<Prev: Pusher> PushAssoc<Prev> {
1580 pub fn new(prev: Prev) -> Self {
1581 Self {
1582 prev: Some(prev),
1583 header_offset: None,
1584 }
1585 }
1586 pub fn end_nested(mut self) -> Prev {
1587 let mut prev = self.prev.take().unwrap();
1588 if let Some(header_offset) = &self.header_offset {
1589 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1590 }
1591 prev
1592 }
1593 #[doc = "PSP device ID.\n"]
1594 pub fn push_dev_id(mut self, value: u32) -> Self {
1595 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1596 self.as_vec_mut().extend(value.to_ne_bytes());
1597 self
1598 }
1599 #[doc = "PSP versions (AEAD and protocol version) used by this association,\ndictates the size of the key.\n\nAssociated type: [`Version`] (enum)"]
1600 pub fn push_version(mut self, value: u32) -> Self {
1601 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1602 self.as_vec_mut().extend(value.to_ne_bytes());
1603 self
1604 }
1605 pub fn nested_rx_key(mut self) -> PushKeys<Self> {
1606 let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
1607 PushKeys {
1608 prev: Some(self),
1609 header_offset: Some(header_offset),
1610 }
1611 }
1612 pub fn nested_tx_key(mut self) -> PushKeys<Self> {
1613 let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
1614 PushKeys {
1615 prev: Some(self),
1616 header_offset: Some(header_offset),
1617 }
1618 }
1619 #[doc = "Sockets which should be bound to the association immediately.\n"]
1620 pub fn push_sock_fd(mut self, value: u32) -> Self {
1621 push_header(self.as_vec_mut(), 5u16, 4 as u16);
1622 self.as_vec_mut().extend(value.to_ne_bytes());
1623 self
1624 }
1625}
1626impl<Prev: Pusher> Drop for PushAssoc<Prev> {
1627 fn drop(&mut self) {
1628 if let Some(prev) = &mut self.prev {
1629 if let Some(header_offset) = &self.header_offset {
1630 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1631 }
1632 }
1633 }
1634}
1635pub struct PushKeys<Prev: Pusher> {
1636 pub(crate) prev: Option<Prev>,
1637 pub(crate) header_offset: Option<usize>,
1638}
1639impl<Prev: Pusher> Pusher for PushKeys<Prev> {
1640 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1641 self.prev.as_mut().unwrap().as_vec_mut()
1642 }
1643 fn as_vec(&self) -> &Vec<u8> {
1644 self.prev.as_ref().unwrap().as_vec()
1645 }
1646}
1647impl<Prev: Pusher> PushKeys<Prev> {
1648 pub fn new(prev: Prev) -> Self {
1649 Self {
1650 prev: Some(prev),
1651 header_offset: None,
1652 }
1653 }
1654 pub fn end_nested(mut self) -> Prev {
1655 let mut prev = self.prev.take().unwrap();
1656 if let Some(header_offset) = &self.header_offset {
1657 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1658 }
1659 prev
1660 }
1661 pub fn push_key(mut self, value: &[u8]) -> Self {
1662 push_header(self.as_vec_mut(), 1u16, value.len() as u16);
1663 self.as_vec_mut().extend(value);
1664 self
1665 }
1666 #[doc = "Security Parameters Index (SPI) of the association.\n"]
1667 pub fn push_spi(mut self, value: u32) -> Self {
1668 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1669 self.as_vec_mut().extend(value.to_ne_bytes());
1670 self
1671 }
1672}
1673impl<Prev: Pusher> Drop for PushKeys<Prev> {
1674 fn drop(&mut self) {
1675 if let Some(prev) = &mut self.prev {
1676 if let Some(header_offset) = &self.header_offset {
1677 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1678 }
1679 }
1680 }
1681}
1682pub struct PushStats<Prev: Pusher> {
1683 pub(crate) prev: Option<Prev>,
1684 pub(crate) header_offset: Option<usize>,
1685}
1686impl<Prev: Pusher> Pusher for PushStats<Prev> {
1687 fn as_vec_mut(&mut self) -> &mut Vec<u8> {
1688 self.prev.as_mut().unwrap().as_vec_mut()
1689 }
1690 fn as_vec(&self) -> &Vec<u8> {
1691 self.prev.as_ref().unwrap().as_vec()
1692 }
1693}
1694impl<Prev: Pusher> PushStats<Prev> {
1695 pub fn new(prev: Prev) -> Self {
1696 Self {
1697 prev: Some(prev),
1698 header_offset: None,
1699 }
1700 }
1701 pub fn end_nested(mut self) -> Prev {
1702 let mut prev = self.prev.take().unwrap();
1703 if let Some(header_offset) = &self.header_offset {
1704 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1705 }
1706 prev
1707 }
1708 #[doc = "PSP device ID.\n"]
1709 pub fn push_dev_id(mut self, value: u32) -> Self {
1710 push_header(self.as_vec_mut(), 1u16, 4 as u16);
1711 self.as_vec_mut().extend(value.to_ne_bytes());
1712 self
1713 }
1714 #[doc = "Number of key rotations during the lifetime of the device. Kernel\nstatistic.\n"]
1715 pub fn push_key_rotations(mut self, value: u32) -> Self {
1716 push_header(self.as_vec_mut(), 2u16, 4 as u16);
1717 self.as_vec_mut().extend(value.to_ne_bytes());
1718 self
1719 }
1720 #[doc = "Number of times a socket\\'s Rx got shut down due to using a key which\nwent stale (fully rotated out). Kernel statistic.\n"]
1721 pub fn push_stale_events(mut self, value: u32) -> Self {
1722 push_header(self.as_vec_mut(), 3u16, 4 as u16);
1723 self.as_vec_mut().extend(value.to_ne_bytes());
1724 self
1725 }
1726 #[doc = "Number of successfully processed and authenticated PSP packets. Device\nstatistic (from the PSP spec).\n"]
1727 pub fn push_rx_packets(mut self, value: u32) -> Self {
1728 push_header(self.as_vec_mut(), 4u16, 4 as u16);
1729 self.as_vec_mut().extend(value.to_ne_bytes());
1730 self
1731 }
1732 #[doc = "Number of successfully authenticated PSP bytes received, counting from\nthe first byte after the IV through the last byte of payload. The fixed\ninitial portion of the PSP header (16 bytes) and the PSP trailer/ICV (16\nbytes) are not included in this count. Device statistic (from the PSP\nspec).\n"]
1733 pub fn push_rx_bytes(mut self, value: u32) -> Self {
1734 push_header(self.as_vec_mut(), 5u16, 4 as u16);
1735 self.as_vec_mut().extend(value.to_ne_bytes());
1736 self
1737 }
1738 #[doc = "Number of received PSP packets with unsuccessful authentication. Device\nstatistic (from the PSP spec).\n"]
1739 pub fn push_rx_auth_fail(mut self, value: u32) -> Self {
1740 push_header(self.as_vec_mut(), 6u16, 4 as u16);
1741 self.as_vec_mut().extend(value.to_ne_bytes());
1742 self
1743 }
1744 #[doc = "Number of received PSP packets with length/framing errors. Device\nstatistic (from the PSP spec).\n"]
1745 pub fn push_rx_error(mut self, value: u32) -> Self {
1746 push_header(self.as_vec_mut(), 7u16, 4 as u16);
1747 self.as_vec_mut().extend(value.to_ne_bytes());
1748 self
1749 }
1750 #[doc = "Number of received PSP packets with miscellaneous errors (invalid master\nkey indicated by SPI, unsupported version, etc.) Device statistic (from\nthe PSP spec).\n"]
1751 pub fn push_rx_bad(mut self, value: u32) -> Self {
1752 push_header(self.as_vec_mut(), 8u16, 4 as u16);
1753 self.as_vec_mut().extend(value.to_ne_bytes());
1754 self
1755 }
1756 #[doc = "Number of successfully processed PSP packets for transmission. Device\nstatistic (from the PSP spec).\n"]
1757 pub fn push_tx_packets(mut self, value: u32) -> Self {
1758 push_header(self.as_vec_mut(), 9u16, 4 as u16);
1759 self.as_vec_mut().extend(value.to_ne_bytes());
1760 self
1761 }
1762 #[doc = "Number of successfully processed PSP bytes for transmit, counting from\nthe first byte after the IV through the last byte of payload. The fixed\ninitial portion of the PSP header (16 bytes) and the PSP trailer/ICV (16\nbytes) are not included in this count. Device statistic (from the PSP\nspec).\n"]
1763 pub fn push_tx_bytes(mut self, value: u32) -> Self {
1764 push_header(self.as_vec_mut(), 10u16, 4 as u16);
1765 self.as_vec_mut().extend(value.to_ne_bytes());
1766 self
1767 }
1768 #[doc = "Number of PSP packets for transmission with errors. Device statistic\n(from the PSP spec).\n"]
1769 pub fn push_tx_error(mut self, value: u32) -> Self {
1770 push_header(self.as_vec_mut(), 11u16, 4 as u16);
1771 self.as_vec_mut().extend(value.to_ne_bytes());
1772 self
1773 }
1774}
1775impl<Prev: Pusher> Drop for PushStats<Prev> {
1776 fn drop(&mut self) {
1777 if let Some(prev) = &mut self.prev {
1778 if let Some(header_offset) = &self.header_offset {
1779 finalize_nested_header(prev.as_vec_mut(), *header_offset);
1780 }
1781 }
1782 }
1783}
1784#[doc = "Notify attributes:\n- [`.get_id()`](IterableDev::get_id)\n- [`.get_ifindex()`](IterableDev::get_ifindex)\n- [`.get_psp_versions_cap()`](IterableDev::get_psp_versions_cap)\n- [`.get_psp_versions_ena()`](IterableDev::get_psp_versions_ena)\n- [`.get_assoc_list()`](IterableDev::get_assoc_list)\n- [`.get_by_association()`](IterableDev::get_by_association)\n"]
1785#[derive(Debug)]
1786pub struct OpDevAddNotif;
1787impl OpDevAddNotif {
1788 pub const CMD: u8 = 2u8;
1789 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1790 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1791 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1792 }
1793}
1794#[doc = "Notify attributes:\n- [`.get_id()`](IterableDev::get_id)\n- [`.get_ifindex()`](IterableDev::get_ifindex)\n- [`.get_psp_versions_cap()`](IterableDev::get_psp_versions_cap)\n- [`.get_psp_versions_ena()`](IterableDev::get_psp_versions_ena)\n- [`.get_assoc_list()`](IterableDev::get_assoc_list)\n- [`.get_by_association()`](IterableDev::get_by_association)\n"]
1795#[derive(Debug)]
1796pub struct OpDevDelNotif;
1797impl OpDevDelNotif {
1798 pub const CMD: u8 = 3u8;
1799 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1800 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1801 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1802 }
1803}
1804#[doc = "Notify attributes:\n- [`.get_id()`](IterableDev::get_id)\n- [`.get_ifindex()`](IterableDev::get_ifindex)\n- [`.get_psp_versions_cap()`](IterableDev::get_psp_versions_cap)\n- [`.get_psp_versions_ena()`](IterableDev::get_psp_versions_ena)\n- [`.get_assoc_list()`](IterableDev::get_assoc_list)\n- [`.get_by_association()`](IterableDev::get_by_association)\n"]
1805#[derive(Debug)]
1806pub struct OpDevChangeNotif;
1807impl OpDevChangeNotif {
1808 pub const CMD: u8 = 5u8;
1809 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1810 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1811 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1812 }
1813}
1814#[doc = "Notify attributes:\n- [`.get_id()`](IterableDev::get_id)\n"]
1815#[derive(Debug)]
1816pub struct OpKeyRotateNotif;
1817impl OpKeyRotateNotif {
1818 pub const CMD: u8 = 7u8;
1819 pub fn decode_notif<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1820 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1821 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1822 }
1823}
1824pub struct NotifGroup;
1825impl NotifGroup {
1826 #[doc = "Notifications:\n- [`OpDevAddNotif`]\n- [`OpDevDelNotif`]\n- [`OpDevChangeNotif`]\n"]
1827 pub const MGMT: &str = "mgmt";
1828 #[doc = "Notifications:\n- [`OpDevAddNotif`]\n- [`OpDevDelNotif`]\n- [`OpDevChangeNotif`]\n"]
1829 pub const MGMT_CSTR: &CStr = c"mgmt";
1830 #[doc = "Notifications:\n- [`OpKeyRotateNotif`]\n"]
1831 pub const USE: &str = "use";
1832 #[doc = "Notifications:\n- [`OpKeyRotateNotif`]\n"]
1833 pub const USE_CSTR: &CStr = c"use";
1834}
1835#[doc = "Get / dump information about PSP capable devices on the system.\n\nReply attributes:\n- [.get_id()](IterableDev::get_id)\n- [.get_ifindex()](IterableDev::get_ifindex)\n- [.get_psp_versions_cap()](IterableDev::get_psp_versions_cap)\n- [.get_psp_versions_ena()](IterableDev::get_psp_versions_ena)\n- [.get_assoc_list()](IterableDev::get_assoc_list)\n- [.get_by_association()](IterableDev::get_by_association)\n\n"]
1836#[derive(Debug)]
1837pub struct OpDevGetDump<'r> {
1838 request: Request<'r>,
1839}
1840impl<'r> OpDevGetDump<'r> {
1841 pub fn new(mut request: Request<'r>) -> Self {
1842 Self::write_header(request.buf_mut());
1843 Self {
1844 request: request.set_dump(),
1845 }
1846 }
1847 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDev<&'buf mut Vec<u8>> {
1848 Self::write_header(buf);
1849 PushDev::new(buf)
1850 }
1851 pub fn encode(&mut self) -> PushDev<&mut Vec<u8>> {
1852 PushDev::new(self.request.buf_mut())
1853 }
1854 pub fn into_encoder(self) -> PushDev<RequestBuf<'r>> {
1855 PushDev::new(self.request.buf)
1856 }
1857 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1858 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1859 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1860 }
1861 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1862 let mut header = BuiltinNfgenmsg::new();
1863 header.cmd = 1u8;
1864 header.version = 1u8;
1865 prev.as_vec_mut().extend(header.as_slice());
1866 }
1867}
1868impl NetlinkRequest for OpDevGetDump<'_> {
1869 fn protocol(&self) -> Protocol {
1870 Protocol::Generic("psp".as_bytes())
1871 }
1872 fn flags(&self) -> u16 {
1873 self.request.flags
1874 }
1875 fn payload(&self) -> &[u8] {
1876 self.request.buf()
1877 }
1878 type ReplyType<'buf> = IterableDev<'buf>;
1879 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1880 Self::decode_request(buf)
1881 }
1882 fn lookup(
1883 buf: &[u8],
1884 offset: usize,
1885 missing_type: Option<u16>,
1886 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1887 Self::decode_request(buf).lookup_attr(offset, missing_type)
1888 }
1889}
1890#[doc = "Get / dump information about PSP capable devices on the system.\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n\nReply attributes:\n- [.get_id()](IterableDev::get_id)\n- [.get_ifindex()](IterableDev::get_ifindex)\n- [.get_psp_versions_cap()](IterableDev::get_psp_versions_cap)\n- [.get_psp_versions_ena()](IterableDev::get_psp_versions_ena)\n- [.get_assoc_list()](IterableDev::get_assoc_list)\n- [.get_by_association()](IterableDev::get_by_association)\n\n"]
1891#[derive(Debug)]
1892pub struct OpDevGetDo<'r> {
1893 request: Request<'r>,
1894}
1895impl<'r> OpDevGetDo<'r> {
1896 pub fn new(mut request: Request<'r>) -> Self {
1897 Self::write_header(request.buf_mut());
1898 Self { request: request }
1899 }
1900 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDev<&'buf mut Vec<u8>> {
1901 Self::write_header(buf);
1902 PushDev::new(buf)
1903 }
1904 pub fn encode(&mut self) -> PushDev<&mut Vec<u8>> {
1905 PushDev::new(self.request.buf_mut())
1906 }
1907 pub fn into_encoder(self) -> PushDev<RequestBuf<'r>> {
1908 PushDev::new(self.request.buf)
1909 }
1910 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1911 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1912 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1913 }
1914 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1915 let mut header = BuiltinNfgenmsg::new();
1916 header.cmd = 1u8;
1917 header.version = 1u8;
1918 prev.as_vec_mut().extend(header.as_slice());
1919 }
1920}
1921impl NetlinkRequest for OpDevGetDo<'_> {
1922 fn protocol(&self) -> Protocol {
1923 Protocol::Generic("psp".as_bytes())
1924 }
1925 fn flags(&self) -> u16 {
1926 self.request.flags
1927 }
1928 fn payload(&self) -> &[u8] {
1929 self.request.buf()
1930 }
1931 type ReplyType<'buf> = IterableDev<'buf>;
1932 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1933 Self::decode_request(buf)
1934 }
1935 fn lookup(
1936 buf: &[u8],
1937 offset: usize,
1938 missing_type: Option<u16>,
1939 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1940 Self::decode_request(buf).lookup_attr(offset, missing_type)
1941 }
1942}
1943#[doc = "Set the configuration of a PSP device.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n- [.push_psp_versions_ena()](PushDev::push_psp_versions_ena)\n\n"]
1944#[derive(Debug)]
1945pub struct OpDevSetDo<'r> {
1946 request: Request<'r>,
1947}
1948impl<'r> OpDevSetDo<'r> {
1949 pub fn new(mut request: Request<'r>) -> Self {
1950 Self::write_header(request.buf_mut());
1951 Self { request: request }
1952 }
1953 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDev<&'buf mut Vec<u8>> {
1954 Self::write_header(buf);
1955 PushDev::new(buf)
1956 }
1957 pub fn encode(&mut self) -> PushDev<&mut Vec<u8>> {
1958 PushDev::new(self.request.buf_mut())
1959 }
1960 pub fn into_encoder(self) -> PushDev<RequestBuf<'r>> {
1961 PushDev::new(self.request.buf)
1962 }
1963 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDev<'a> {
1964 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
1965 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
1966 }
1967 fn write_header<Prev: Pusher>(prev: &mut Prev) {
1968 let mut header = BuiltinNfgenmsg::new();
1969 header.cmd = 4u8;
1970 header.version = 1u8;
1971 prev.as_vec_mut().extend(header.as_slice());
1972 }
1973}
1974impl NetlinkRequest for OpDevSetDo<'_> {
1975 fn protocol(&self) -> Protocol {
1976 Protocol::Generic("psp".as_bytes())
1977 }
1978 fn flags(&self) -> u16 {
1979 self.request.flags
1980 }
1981 fn payload(&self) -> &[u8] {
1982 self.request.buf()
1983 }
1984 type ReplyType<'buf> = IterableDev<'buf>;
1985 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
1986 Self::decode_request(buf)
1987 }
1988 fn lookup(
1989 buf: &[u8],
1990 offset: usize,
1991 missing_type: Option<u16>,
1992 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
1993 Self::decode_request(buf).lookup_attr(offset, missing_type)
1994 }
1995}
1996#[doc = "Rotate the device key.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n\nReply attributes:\n- [.get_id()](IterableDev::get_id)\n\n"]
1997#[derive(Debug)]
1998pub struct OpKeyRotateDo<'r> {
1999 request: Request<'r>,
2000}
2001impl<'r> OpKeyRotateDo<'r> {
2002 pub fn new(mut request: Request<'r>) -> Self {
2003 Self::write_header(request.buf_mut());
2004 Self { request: request }
2005 }
2006 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDev<&'buf mut Vec<u8>> {
2007 Self::write_header(buf);
2008 PushDev::new(buf)
2009 }
2010 pub fn encode(&mut self) -> PushDev<&mut Vec<u8>> {
2011 PushDev::new(self.request.buf_mut())
2012 }
2013 pub fn into_encoder(self) -> PushDev<RequestBuf<'r>> {
2014 PushDev::new(self.request.buf)
2015 }
2016 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDev<'a> {
2017 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2018 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
2019 }
2020 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2021 let mut header = BuiltinNfgenmsg::new();
2022 header.cmd = 6u8;
2023 header.version = 1u8;
2024 prev.as_vec_mut().extend(header.as_slice());
2025 }
2026}
2027impl NetlinkRequest for OpKeyRotateDo<'_> {
2028 fn protocol(&self) -> Protocol {
2029 Protocol::Generic("psp".as_bytes())
2030 }
2031 fn flags(&self) -> u16 {
2032 self.request.flags
2033 }
2034 fn payload(&self) -> &[u8] {
2035 self.request.buf()
2036 }
2037 type ReplyType<'buf> = IterableDev<'buf>;
2038 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2039 Self::decode_request(buf)
2040 }
2041 fn lookup(
2042 buf: &[u8],
2043 offset: usize,
2044 missing_type: Option<u16>,
2045 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2046 Self::decode_request(buf).lookup_attr(offset, missing_type)
2047 }
2048}
2049#[doc = "Allocate a new Rx key + SPI pair, associate it with a socket.\n\nRequest attributes:\n- [.push_dev_id()](PushAssoc::push_dev_id)\n- [.push_version()](PushAssoc::push_version)\n- [.push_sock_fd()](PushAssoc::push_sock_fd)\n\nReply attributes:\n- [.get_dev_id()](IterableAssoc::get_dev_id)\n- [.get_rx_key()](IterableAssoc::get_rx_key)\n\n"]
2050#[derive(Debug)]
2051pub struct OpRxAssocDo<'r> {
2052 request: Request<'r>,
2053}
2054impl<'r> OpRxAssocDo<'r> {
2055 pub fn new(mut request: Request<'r>) -> Self {
2056 Self::write_header(request.buf_mut());
2057 Self { request: request }
2058 }
2059 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushAssoc<&'buf mut Vec<u8>> {
2060 Self::write_header(buf);
2061 PushAssoc::new(buf)
2062 }
2063 pub fn encode(&mut self) -> PushAssoc<&mut Vec<u8>> {
2064 PushAssoc::new(self.request.buf_mut())
2065 }
2066 pub fn into_encoder(self) -> PushAssoc<RequestBuf<'r>> {
2067 PushAssoc::new(self.request.buf)
2068 }
2069 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableAssoc<'a> {
2070 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2071 IterableAssoc::with_loc(attrs, buf.as_ptr() as usize)
2072 }
2073 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2074 let mut header = BuiltinNfgenmsg::new();
2075 header.cmd = 8u8;
2076 header.version = 1u8;
2077 prev.as_vec_mut().extend(header.as_slice());
2078 }
2079}
2080impl NetlinkRequest for OpRxAssocDo<'_> {
2081 fn protocol(&self) -> Protocol {
2082 Protocol::Generic("psp".as_bytes())
2083 }
2084 fn flags(&self) -> u16 {
2085 self.request.flags
2086 }
2087 fn payload(&self) -> &[u8] {
2088 self.request.buf()
2089 }
2090 type ReplyType<'buf> = IterableAssoc<'buf>;
2091 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2092 Self::decode_request(buf)
2093 }
2094 fn lookup(
2095 buf: &[u8],
2096 offset: usize,
2097 missing_type: Option<u16>,
2098 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2099 Self::decode_request(buf).lookup_attr(offset, missing_type)
2100 }
2101}
2102#[doc = "Add a PSP Tx association.\n\nRequest attributes:\n- [.push_dev_id()](PushAssoc::push_dev_id)\n- [.push_version()](PushAssoc::push_version)\n- [.nested_tx_key()](PushAssoc::nested_tx_key)\n- [.push_sock_fd()](PushAssoc::push_sock_fd)\n\n"]
2103#[derive(Debug)]
2104pub struct OpTxAssocDo<'r> {
2105 request: Request<'r>,
2106}
2107impl<'r> OpTxAssocDo<'r> {
2108 pub fn new(mut request: Request<'r>) -> Self {
2109 Self::write_header(request.buf_mut());
2110 Self { request: request }
2111 }
2112 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushAssoc<&'buf mut Vec<u8>> {
2113 Self::write_header(buf);
2114 PushAssoc::new(buf)
2115 }
2116 pub fn encode(&mut self) -> PushAssoc<&mut Vec<u8>> {
2117 PushAssoc::new(self.request.buf_mut())
2118 }
2119 pub fn into_encoder(self) -> PushAssoc<RequestBuf<'r>> {
2120 PushAssoc::new(self.request.buf)
2121 }
2122 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableAssoc<'a> {
2123 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2124 IterableAssoc::with_loc(attrs, buf.as_ptr() as usize)
2125 }
2126 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2127 let mut header = BuiltinNfgenmsg::new();
2128 header.cmd = 9u8;
2129 header.version = 1u8;
2130 prev.as_vec_mut().extend(header.as_slice());
2131 }
2132}
2133impl NetlinkRequest for OpTxAssocDo<'_> {
2134 fn protocol(&self) -> Protocol {
2135 Protocol::Generic("psp".as_bytes())
2136 }
2137 fn flags(&self) -> u16 {
2138 self.request.flags
2139 }
2140 fn payload(&self) -> &[u8] {
2141 self.request.buf()
2142 }
2143 type ReplyType<'buf> = IterableAssoc<'buf>;
2144 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2145 Self::decode_request(buf)
2146 }
2147 fn lookup(
2148 buf: &[u8],
2149 offset: usize,
2150 missing_type: Option<u16>,
2151 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2152 Self::decode_request(buf).lookup_attr(offset, missing_type)
2153 }
2154}
2155#[doc = "Get device statistics.\n\nReply attributes:\n- [.get_dev_id()](IterableStats::get_dev_id)\n- [.get_key_rotations()](IterableStats::get_key_rotations)\n- [.get_stale_events()](IterableStats::get_stale_events)\n- [.get_rx_packets()](IterableStats::get_rx_packets)\n- [.get_rx_bytes()](IterableStats::get_rx_bytes)\n- [.get_rx_auth_fail()](IterableStats::get_rx_auth_fail)\n- [.get_rx_error()](IterableStats::get_rx_error)\n- [.get_rx_bad()](IterableStats::get_rx_bad)\n- [.get_tx_packets()](IterableStats::get_tx_packets)\n- [.get_tx_bytes()](IterableStats::get_tx_bytes)\n- [.get_tx_error()](IterableStats::get_tx_error)\n\n"]
2156#[derive(Debug)]
2157pub struct OpGetStatsDump<'r> {
2158 request: Request<'r>,
2159}
2160impl<'r> OpGetStatsDump<'r> {
2161 pub fn new(mut request: Request<'r>) -> Self {
2162 Self::write_header(request.buf_mut());
2163 Self {
2164 request: request.set_dump(),
2165 }
2166 }
2167 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushStats<&'buf mut Vec<u8>> {
2168 Self::write_header(buf);
2169 PushStats::new(buf)
2170 }
2171 pub fn encode(&mut self) -> PushStats<&mut Vec<u8>> {
2172 PushStats::new(self.request.buf_mut())
2173 }
2174 pub fn into_encoder(self) -> PushStats<RequestBuf<'r>> {
2175 PushStats::new(self.request.buf)
2176 }
2177 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableStats<'a> {
2178 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2179 IterableStats::with_loc(attrs, buf.as_ptr() as usize)
2180 }
2181 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2182 let mut header = BuiltinNfgenmsg::new();
2183 header.cmd = 10u8;
2184 header.version = 1u8;
2185 prev.as_vec_mut().extend(header.as_slice());
2186 }
2187}
2188impl NetlinkRequest for OpGetStatsDump<'_> {
2189 fn protocol(&self) -> Protocol {
2190 Protocol::Generic("psp".as_bytes())
2191 }
2192 fn flags(&self) -> u16 {
2193 self.request.flags
2194 }
2195 fn payload(&self) -> &[u8] {
2196 self.request.buf()
2197 }
2198 type ReplyType<'buf> = IterableStats<'buf>;
2199 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2200 Self::decode_request(buf)
2201 }
2202 fn lookup(
2203 buf: &[u8],
2204 offset: usize,
2205 missing_type: Option<u16>,
2206 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2207 Self::decode_request(buf).lookup_attr(offset, missing_type)
2208 }
2209}
2210#[doc = "Get device statistics.\n\nRequest attributes:\n- [.push_dev_id()](PushStats::push_dev_id)\n\nReply attributes:\n- [.get_dev_id()](IterableStats::get_dev_id)\n- [.get_key_rotations()](IterableStats::get_key_rotations)\n- [.get_stale_events()](IterableStats::get_stale_events)\n- [.get_rx_packets()](IterableStats::get_rx_packets)\n- [.get_rx_bytes()](IterableStats::get_rx_bytes)\n- [.get_rx_auth_fail()](IterableStats::get_rx_auth_fail)\n- [.get_rx_error()](IterableStats::get_rx_error)\n- [.get_rx_bad()](IterableStats::get_rx_bad)\n- [.get_tx_packets()](IterableStats::get_tx_packets)\n- [.get_tx_bytes()](IterableStats::get_tx_bytes)\n- [.get_tx_error()](IterableStats::get_tx_error)\n\n"]
2211#[derive(Debug)]
2212pub struct OpGetStatsDo<'r> {
2213 request: Request<'r>,
2214}
2215impl<'r> OpGetStatsDo<'r> {
2216 pub fn new(mut request: Request<'r>) -> Self {
2217 Self::write_header(request.buf_mut());
2218 Self { request: request }
2219 }
2220 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushStats<&'buf mut Vec<u8>> {
2221 Self::write_header(buf);
2222 PushStats::new(buf)
2223 }
2224 pub fn encode(&mut self) -> PushStats<&mut Vec<u8>> {
2225 PushStats::new(self.request.buf_mut())
2226 }
2227 pub fn into_encoder(self) -> PushStats<RequestBuf<'r>> {
2228 PushStats::new(self.request.buf)
2229 }
2230 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableStats<'a> {
2231 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2232 IterableStats::with_loc(attrs, buf.as_ptr() as usize)
2233 }
2234 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2235 let mut header = BuiltinNfgenmsg::new();
2236 header.cmd = 10u8;
2237 header.version = 1u8;
2238 prev.as_vec_mut().extend(header.as_slice());
2239 }
2240}
2241impl NetlinkRequest for OpGetStatsDo<'_> {
2242 fn protocol(&self) -> Protocol {
2243 Protocol::Generic("psp".as_bytes())
2244 }
2245 fn flags(&self) -> u16 {
2246 self.request.flags
2247 }
2248 fn payload(&self) -> &[u8] {
2249 self.request.buf()
2250 }
2251 type ReplyType<'buf> = IterableStats<'buf>;
2252 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2253 Self::decode_request(buf)
2254 }
2255 fn lookup(
2256 buf: &[u8],
2257 offset: usize,
2258 missing_type: Option<u16>,
2259 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2260 Self::decode_request(buf).lookup_attr(offset, missing_type)
2261 }
2262}
2263#[doc = "Associate a network device with a PSP device.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n- [.push_ifindex()](PushDev::push_ifindex)\n- [.push_nsid()](PushDev::push_nsid)\n\n"]
2264#[derive(Debug)]
2265pub struct OpDevAssocDo<'r> {
2266 request: Request<'r>,
2267}
2268impl<'r> OpDevAssocDo<'r> {
2269 pub fn new(mut request: Request<'r>) -> Self {
2270 Self::write_header(request.buf_mut());
2271 Self { request: request }
2272 }
2273 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDev<&'buf mut Vec<u8>> {
2274 Self::write_header(buf);
2275 PushDev::new(buf)
2276 }
2277 pub fn encode(&mut self) -> PushDev<&mut Vec<u8>> {
2278 PushDev::new(self.request.buf_mut())
2279 }
2280 pub fn into_encoder(self) -> PushDev<RequestBuf<'r>> {
2281 PushDev::new(self.request.buf)
2282 }
2283 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDev<'a> {
2284 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2285 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
2286 }
2287 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2288 let mut header = BuiltinNfgenmsg::new();
2289 header.cmd = 11u8;
2290 header.version = 1u8;
2291 prev.as_vec_mut().extend(header.as_slice());
2292 }
2293}
2294impl NetlinkRequest for OpDevAssocDo<'_> {
2295 fn protocol(&self) -> Protocol {
2296 Protocol::Generic("psp".as_bytes())
2297 }
2298 fn flags(&self) -> u16 {
2299 self.request.flags
2300 }
2301 fn payload(&self) -> &[u8] {
2302 self.request.buf()
2303 }
2304 type ReplyType<'buf> = IterableDev<'buf>;
2305 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2306 Self::decode_request(buf)
2307 }
2308 fn lookup(
2309 buf: &[u8],
2310 offset: usize,
2311 missing_type: Option<u16>,
2312 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2313 Self::decode_request(buf).lookup_attr(offset, missing_type)
2314 }
2315}
2316#[doc = "Disassociate a network device from a PSP device.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n- [.push_ifindex()](PushDev::push_ifindex)\n- [.push_nsid()](PushDev::push_nsid)\n\n"]
2317#[derive(Debug)]
2318pub struct OpDevDisassocDo<'r> {
2319 request: Request<'r>,
2320}
2321impl<'r> OpDevDisassocDo<'r> {
2322 pub fn new(mut request: Request<'r>) -> Self {
2323 Self::write_header(request.buf_mut());
2324 Self { request: request }
2325 }
2326 pub fn encode_request<'buf>(buf: &'buf mut Vec<u8>) -> PushDev<&'buf mut Vec<u8>> {
2327 Self::write_header(buf);
2328 PushDev::new(buf)
2329 }
2330 pub fn encode(&mut self) -> PushDev<&mut Vec<u8>> {
2331 PushDev::new(self.request.buf_mut())
2332 }
2333 pub fn into_encoder(self) -> PushDev<RequestBuf<'r>> {
2334 PushDev::new(self.request.buf)
2335 }
2336 pub fn decode_request<'a>(buf: &'a [u8]) -> IterableDev<'a> {
2337 let (_header, attrs) = buf.split_at(buf.len().min(BuiltinNfgenmsg::len()));
2338 IterableDev::with_loc(attrs, buf.as_ptr() as usize)
2339 }
2340 fn write_header<Prev: Pusher>(prev: &mut Prev) {
2341 let mut header = BuiltinNfgenmsg::new();
2342 header.cmd = 12u8;
2343 header.version = 1u8;
2344 prev.as_vec_mut().extend(header.as_slice());
2345 }
2346}
2347impl NetlinkRequest for OpDevDisassocDo<'_> {
2348 fn protocol(&self) -> Protocol {
2349 Protocol::Generic("psp".as_bytes())
2350 }
2351 fn flags(&self) -> u16 {
2352 self.request.flags
2353 }
2354 fn payload(&self) -> &[u8] {
2355 self.request.buf()
2356 }
2357 type ReplyType<'buf> = IterableDev<'buf>;
2358 fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
2359 Self::decode_request(buf)
2360 }
2361 fn lookup(
2362 buf: &[u8],
2363 offset: usize,
2364 missing_type: Option<u16>,
2365 ) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
2366 Self::decode_request(buf).lookup_attr(offset, missing_type)
2367 }
2368}
2369use crate::traits::LookupFn;
2370use crate::utils::RequestBuf;
2371#[derive(Debug)]
2372pub struct Request<'buf> {
2373 buf: RequestBuf<'buf>,
2374 flags: u16,
2375 writeback: Option<&'buf mut Option<RequestInfo>>,
2376}
2377#[allow(unused)]
2378#[derive(Debug, Clone)]
2379pub struct RequestInfo {
2380 protocol: Protocol,
2381 flags: u16,
2382 name: &'static str,
2383 lookup: LookupFn,
2384}
2385impl Request<'static> {
2386 pub fn new() -> Self {
2387 Self::new_from_buf(Vec::new())
2388 }
2389 pub fn new_from_buf(buf: Vec<u8>) -> Self {
2390 Self {
2391 flags: 0,
2392 buf: RequestBuf::Own(buf),
2393 writeback: None,
2394 }
2395 }
2396 pub fn into_buf(self) -> Vec<u8> {
2397 match self.buf {
2398 RequestBuf::Own(buf) => buf,
2399 _ => unreachable!(),
2400 }
2401 }
2402}
2403impl<'buf> Request<'buf> {
2404 pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
2405 buf.clear();
2406 Self::new_extend(buf)
2407 }
2408 pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
2409 Self {
2410 flags: 0,
2411 buf: RequestBuf::Ref(buf),
2412 writeback: None,
2413 }
2414 }
2415 fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
2416 let Some(writeback) = &mut self.writeback else {
2417 return;
2418 };
2419 **writeback = Some(RequestInfo {
2420 protocol,
2421 flags: self.flags,
2422 name,
2423 lookup,
2424 })
2425 }
2426 pub fn buf(&self) -> &Vec<u8> {
2427 self.buf.buf()
2428 }
2429 pub fn buf_mut(&mut self) -> &mut Vec<u8> {
2430 self.buf.buf_mut()
2431 }
2432 #[doc = "Set `NLM_F_CREATE` flag"]
2433 pub fn set_create(mut self) -> Self {
2434 self.flags |= consts::NLM_F_CREATE as u16;
2435 self
2436 }
2437 #[doc = "Set `NLM_F_EXCL` flag"]
2438 pub fn set_excl(mut self) -> Self {
2439 self.flags |= consts::NLM_F_EXCL as u16;
2440 self
2441 }
2442 #[doc = "Set `NLM_F_REPLACE` flag"]
2443 pub fn set_replace(mut self) -> Self {
2444 self.flags |= consts::NLM_F_REPLACE as u16;
2445 self
2446 }
2447 #[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
2448 pub fn set_change(self) -> Self {
2449 self.set_create().set_replace()
2450 }
2451 #[doc = "Set `NLM_F_APPEND` flag"]
2452 pub fn set_append(mut self) -> Self {
2453 self.flags |= consts::NLM_F_APPEND as u16;
2454 self
2455 }
2456 #[doc = "Set `self.flags |= flags`"]
2457 pub fn set_flags(mut self, flags: u16) -> Self {
2458 self.flags |= flags;
2459 self
2460 }
2461 #[doc = "Set `self.flags ^= self.flags & flags`"]
2462 pub fn unset_flags(mut self, flags: u16) -> Self {
2463 self.flags ^= self.flags & flags;
2464 self
2465 }
2466 #[doc = "Set `NLM_F_DUMP` flag"]
2467 fn set_dump(mut self) -> Self {
2468 self.flags |= consts::NLM_F_DUMP as u16;
2469 self
2470 }
2471 #[doc = "Get / dump information about PSP capable devices on the system.\n\nReply attributes:\n- [.get_id()](IterableDev::get_id)\n- [.get_ifindex()](IterableDev::get_ifindex)\n- [.get_psp_versions_cap()](IterableDev::get_psp_versions_cap)\n- [.get_psp_versions_ena()](IterableDev::get_psp_versions_ena)\n- [.get_assoc_list()](IterableDev::get_assoc_list)\n- [.get_by_association()](IterableDev::get_by_association)\n\n"]
2472 pub fn op_dev_get_dump(self) -> OpDevGetDump<'buf> {
2473 let mut res = OpDevGetDump::new(self);
2474 res.request
2475 .do_writeback(res.protocol(), "op-dev-get-dump", OpDevGetDump::lookup);
2476 res
2477 }
2478 #[doc = "Get / dump information about PSP capable devices on the system.\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n\nReply attributes:\n- [.get_id()](IterableDev::get_id)\n- [.get_ifindex()](IterableDev::get_ifindex)\n- [.get_psp_versions_cap()](IterableDev::get_psp_versions_cap)\n- [.get_psp_versions_ena()](IterableDev::get_psp_versions_ena)\n- [.get_assoc_list()](IterableDev::get_assoc_list)\n- [.get_by_association()](IterableDev::get_by_association)\n\n"]
2479 pub fn op_dev_get_do(self) -> OpDevGetDo<'buf> {
2480 let mut res = OpDevGetDo::new(self);
2481 res.request
2482 .do_writeback(res.protocol(), "op-dev-get-do", OpDevGetDo::lookup);
2483 res
2484 }
2485 #[doc = "Set the configuration of a PSP device.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n- [.push_psp_versions_ena()](PushDev::push_psp_versions_ena)\n\n"]
2486 pub fn op_dev_set_do(self) -> OpDevSetDo<'buf> {
2487 let mut res = OpDevSetDo::new(self);
2488 res.request
2489 .do_writeback(res.protocol(), "op-dev-set-do", OpDevSetDo::lookup);
2490 res
2491 }
2492 #[doc = "Rotate the device key.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n\nReply attributes:\n- [.get_id()](IterableDev::get_id)\n\n"]
2493 pub fn op_key_rotate_do(self) -> OpKeyRotateDo<'buf> {
2494 let mut res = OpKeyRotateDo::new(self);
2495 res.request
2496 .do_writeback(res.protocol(), "op-key-rotate-do", OpKeyRotateDo::lookup);
2497 res
2498 }
2499 #[doc = "Allocate a new Rx key + SPI pair, associate it with a socket.\n\nRequest attributes:\n- [.push_dev_id()](PushAssoc::push_dev_id)\n- [.push_version()](PushAssoc::push_version)\n- [.push_sock_fd()](PushAssoc::push_sock_fd)\n\nReply attributes:\n- [.get_dev_id()](IterableAssoc::get_dev_id)\n- [.get_rx_key()](IterableAssoc::get_rx_key)\n\n"]
2500 pub fn op_rx_assoc_do(self) -> OpRxAssocDo<'buf> {
2501 let mut res = OpRxAssocDo::new(self);
2502 res.request
2503 .do_writeback(res.protocol(), "op-rx-assoc-do", OpRxAssocDo::lookup);
2504 res
2505 }
2506 #[doc = "Add a PSP Tx association.\n\nRequest attributes:\n- [.push_dev_id()](PushAssoc::push_dev_id)\n- [.push_version()](PushAssoc::push_version)\n- [.nested_tx_key()](PushAssoc::nested_tx_key)\n- [.push_sock_fd()](PushAssoc::push_sock_fd)\n\n"]
2507 pub fn op_tx_assoc_do(self) -> OpTxAssocDo<'buf> {
2508 let mut res = OpTxAssocDo::new(self);
2509 res.request
2510 .do_writeback(res.protocol(), "op-tx-assoc-do", OpTxAssocDo::lookup);
2511 res
2512 }
2513 #[doc = "Get device statistics.\n\nReply attributes:\n- [.get_dev_id()](IterableStats::get_dev_id)\n- [.get_key_rotations()](IterableStats::get_key_rotations)\n- [.get_stale_events()](IterableStats::get_stale_events)\n- [.get_rx_packets()](IterableStats::get_rx_packets)\n- [.get_rx_bytes()](IterableStats::get_rx_bytes)\n- [.get_rx_auth_fail()](IterableStats::get_rx_auth_fail)\n- [.get_rx_error()](IterableStats::get_rx_error)\n- [.get_rx_bad()](IterableStats::get_rx_bad)\n- [.get_tx_packets()](IterableStats::get_tx_packets)\n- [.get_tx_bytes()](IterableStats::get_tx_bytes)\n- [.get_tx_error()](IterableStats::get_tx_error)\n\n"]
2514 pub fn op_get_stats_dump(self) -> OpGetStatsDump<'buf> {
2515 let mut res = OpGetStatsDump::new(self);
2516 res.request
2517 .do_writeback(res.protocol(), "op-get-stats-dump", OpGetStatsDump::lookup);
2518 res
2519 }
2520 #[doc = "Get device statistics.\n\nRequest attributes:\n- [.push_dev_id()](PushStats::push_dev_id)\n\nReply attributes:\n- [.get_dev_id()](IterableStats::get_dev_id)\n- [.get_key_rotations()](IterableStats::get_key_rotations)\n- [.get_stale_events()](IterableStats::get_stale_events)\n- [.get_rx_packets()](IterableStats::get_rx_packets)\n- [.get_rx_bytes()](IterableStats::get_rx_bytes)\n- [.get_rx_auth_fail()](IterableStats::get_rx_auth_fail)\n- [.get_rx_error()](IterableStats::get_rx_error)\n- [.get_rx_bad()](IterableStats::get_rx_bad)\n- [.get_tx_packets()](IterableStats::get_tx_packets)\n- [.get_tx_bytes()](IterableStats::get_tx_bytes)\n- [.get_tx_error()](IterableStats::get_tx_error)\n\n"]
2521 pub fn op_get_stats_do(self) -> OpGetStatsDo<'buf> {
2522 let mut res = OpGetStatsDo::new(self);
2523 res.request
2524 .do_writeback(res.protocol(), "op-get-stats-do", OpGetStatsDo::lookup);
2525 res
2526 }
2527 #[doc = "Associate a network device with a PSP device.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n- [.push_ifindex()](PushDev::push_ifindex)\n- [.push_nsid()](PushDev::push_nsid)\n\n"]
2528 pub fn op_dev_assoc_do(self) -> OpDevAssocDo<'buf> {
2529 let mut res = OpDevAssocDo::new(self);
2530 res.request
2531 .do_writeback(res.protocol(), "op-dev-assoc-do", OpDevAssocDo::lookup);
2532 res
2533 }
2534 #[doc = "Disassociate a network device from a PSP device.\n\nFlags: admin-perm\n\nRequest attributes:\n- [.push_id()](PushDev::push_id)\n- [.push_ifindex()](PushDev::push_ifindex)\n- [.push_nsid()](PushDev::push_nsid)\n\n"]
2535 pub fn op_dev_disassoc_do(self) -> OpDevDisassocDo<'buf> {
2536 let mut res = OpDevDisassocDo::new(self);
2537 res.request.do_writeback(
2538 res.protocol(),
2539 "op-dev-disassoc-do",
2540 OpDevDisassocDo::lookup,
2541 );
2542 res
2543 }
2544}
2545#[cfg(test)]
2546mod generated_tests {
2547 use super::*;
2548 #[test]
2549 fn tests() {
2550 let _ = IterableAssoc::get_dev_id;
2551 let _ = IterableAssoc::get_rx_key;
2552 let _ = IterableDev::get_assoc_list;
2553 let _ = IterableDev::get_by_association;
2554 let _ = IterableDev::get_id;
2555 let _ = IterableDev::get_ifindex;
2556 let _ = IterableDev::get_psp_versions_cap;
2557 let _ = IterableDev::get_psp_versions_ena;
2558 let _ = IterableStats::get_dev_id;
2559 let _ = IterableStats::get_key_rotations;
2560 let _ = IterableStats::get_rx_auth_fail;
2561 let _ = IterableStats::get_rx_bad;
2562 let _ = IterableStats::get_rx_bytes;
2563 let _ = IterableStats::get_rx_error;
2564 let _ = IterableStats::get_rx_packets;
2565 let _ = IterableStats::get_stale_events;
2566 let _ = IterableStats::get_tx_bytes;
2567 let _ = IterableStats::get_tx_error;
2568 let _ = IterableStats::get_tx_packets;
2569 let _ = OpDevAddNotif;
2570 let _ = OpDevChangeNotif;
2571 let _ = OpDevDelNotif;
2572 let _ = OpKeyRotateNotif;
2573 let _ = PushAssoc::<&mut Vec<u8>>::nested_tx_key;
2574 let _ = PushAssoc::<&mut Vec<u8>>::push_dev_id;
2575 let _ = PushAssoc::<&mut Vec<u8>>::push_sock_fd;
2576 let _ = PushAssoc::<&mut Vec<u8>>::push_version;
2577 let _ = PushDev::<&mut Vec<u8>>::push_id;
2578 let _ = PushDev::<&mut Vec<u8>>::push_ifindex;
2579 let _ = PushDev::<&mut Vec<u8>>::push_nsid;
2580 let _ = PushDev::<&mut Vec<u8>>::push_psp_versions_ena;
2581 let _ = PushStats::<&mut Vec<u8>>::push_dev_id;
2582 }
2583}