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