Skip to main content

netlink_bindings/psp/
mod.rs

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}