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