netlink_packet_generic/ctrl/nlas/
oppolicy.rs1use crate::constants::*;
4use netlink_packet_core::{
5 emit_u32, parse_u32, DecodeError, Emitable, ErrorContext, Nla, NlaBuffer,
6 NlasIterator, Parseable,
7};
8use std::mem::size_of_val;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct OppolicyAttr {
12 pub cmd: u8,
13 pub policy_idx: Vec<OppolicyIndexAttr>,
14}
15
16impl Nla for OppolicyAttr {
17 fn value_len(&self) -> usize {
18 self.policy_idx.as_slice().buffer_len()
19 }
20
21 fn kind(&self) -> u16 {
22 self.cmd as u16
23 }
24
25 fn emit_value(&self, buffer: &mut [u8]) {
26 self.policy_idx.as_slice().emit(buffer);
27 }
28
29 fn is_nested(&self) -> bool {
30 true
31 }
32}
33
34impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for OppolicyAttr {
35 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
36 let payload = buf.value();
37 let policy_idx = NlasIterator::new(payload)
38 .map(|nla| nla.and_then(|nla| OppolicyIndexAttr::parse(&nla)))
39 .collect::<Result<Vec<_>, _>>()
40 .context("failed to parse OppolicyAttr")?;
41
42 Ok(Self {
43 cmd: buf.kind() as u8,
44 policy_idx,
45 })
46 }
47}
48
49#[derive(Clone, Debug, PartialEq, Eq)]
50pub enum OppolicyIndexAttr {
51 Do(u32),
52 Dump(u32),
53}
54
55impl Nla for OppolicyIndexAttr {
56 fn value_len(&self) -> usize {
57 use OppolicyIndexAttr::*;
58 match self {
59 Do(v) => size_of_val(v),
60 Dump(v) => size_of_val(v),
61 }
62 }
63
64 fn kind(&self) -> u16 {
65 use OppolicyIndexAttr::*;
66 match self {
67 Do(_) => CTRL_ATTR_POLICY_DO,
68 Dump(_) => CTRL_ATTR_POLICY_DUMP,
69 }
70 }
71
72 fn emit_value(&self, buffer: &mut [u8]) {
73 use OppolicyIndexAttr::*;
74 match self {
75 Do(v) => emit_u32(buffer, *v).unwrap(),
76 Dump(v) => emit_u32(buffer, *v).unwrap(),
77 }
78 }
79}
80
81impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
82 for OppolicyIndexAttr
83{
84 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
85 let payload = buf.value();
86 Ok(match buf.kind() {
87 CTRL_ATTR_POLICY_DO => Self::Do(
88 parse_u32(payload)
89 .context("invalid CTRL_ATTR_POLICY_DO value")?,
90 ),
91 CTRL_ATTR_POLICY_DUMP => Self::Dump(
92 parse_u32(payload)
93 .context("invalid CTRL_ATTR_POLICY_DUMP value")?,
94 ),
95 kind => {
96 return Err(DecodeError::from(format!(
97 "Unknown NLA type: {kind}"
98 )))
99 }
100 })
101 }
102}