netlink_packet_generic/ctrl/nlas/
ops.rs1use crate::constants::*;
4use anyhow::Context;
5use byteorder::{ByteOrder, NativeEndian};
6use netlink_packet_utils::{
7 nla::{Nla, NlaBuffer},
8 parsers::*,
9 traits::*,
10 DecodeError,
11};
12use std::{mem::size_of_val, ops::Deref};
13
14pub struct OpList(Vec<Op>);
15
16impl Deref for OpList {
17 type Target = Vec<Op>;
18
19 fn deref(&self) -> &Self::Target {
20 &self.0
21 }
22}
23
24impl From<&Vec<Vec<OpAttrs>>> for OpList {
25 fn from(ops: &Vec<Vec<OpAttrs>>) -> Self {
26 Self(
27 ops.iter()
28 .cloned()
29 .enumerate()
30 .map(|(index, nlas)| Op {
31 index: index as u16,
32 nlas,
33 })
34 .collect(),
35 )
36 }
37}
38
39#[derive(Clone, Debug, PartialEq, Eq)]
40pub struct Op {
41 pub index: u16,
42 pub nlas: Vec<OpAttrs>,
43}
44
45impl Nla for Op {
46 fn value_len(&self) -> usize {
47 self.nlas.as_slice().buffer_len()
48 }
49
50 fn kind(&self) -> u16 {
51 self.index + 1
52 }
53
54 fn emit_value(&self, buffer: &mut [u8]) {
55 self.nlas.as_slice().emit(buffer);
56 }
57}
58
59#[derive(Clone, Debug, PartialEq, Eq)]
60pub enum OpAttrs {
61 Id(u32),
62 Flags(u32),
63}
64
65impl Nla for OpAttrs {
66 fn value_len(&self) -> usize {
67 use OpAttrs::*;
68 match self {
69 Id(v) => size_of_val(v),
70 Flags(v) => size_of_val(v),
71 }
72 }
73
74 fn kind(&self) -> u16 {
75 use OpAttrs::*;
76 match self {
77 Id(_) => CTRL_ATTR_OP_ID,
78 Flags(_) => CTRL_ATTR_OP_FLAGS,
79 }
80 }
81
82 fn emit_value(&self, buffer: &mut [u8]) {
83 use OpAttrs::*;
84 match self {
85 Id(v) => NativeEndian::write_u32(buffer, *v),
86 Flags(v) => NativeEndian::write_u32(buffer, *v),
87 }
88 }
89}
90
91impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for OpAttrs {
92 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
93 let payload = buf.value();
94 Ok(match buf.kind() {
95 CTRL_ATTR_OP_ID => Self::Id(
96 parse_u32(payload).context("invalid CTRL_ATTR_OP_ID value")?,
97 ),
98 CTRL_ATTR_OP_FLAGS => Self::Flags(
99 parse_u32(payload)
100 .context("invalid CTRL_ATTR_OP_FLAGS value")?,
101 ),
102 kind => {
103 return Err(DecodeError::from(format!(
104 "Unknown NLA type: {kind}"
105 )))
106 }
107 })
108 }
109}