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