netlink_packet_route/tc/
message.rs1use anyhow::Context;
4use netlink_packet_utils::{
5 traits::{Emitable, Parseable, ParseableParametrized},
6 DecodeError,
7};
8
9use super::{TcAttribute, TcHeader, TcMessageBuffer};
10
11#[derive(Debug, PartialEq, Eq, Clone, Default)]
12#[non_exhaustive]
13pub struct TcMessage {
14 pub header: TcHeader,
15 pub attributes: Vec<TcAttribute>,
16}
17
18impl TcMessage {
19 pub fn into_parts(self) -> (TcHeader, Vec<TcAttribute>) {
20 (self.header, self.attributes)
21 }
22
23 pub fn from_parts(header: TcHeader, attributes: Vec<TcAttribute>) -> Self {
24 TcMessage { header, attributes }
25 }
26
27 pub fn with_index(index: i32) -> Self {
29 Self {
30 header: TcHeader {
31 index,
32 ..Default::default()
33 },
34 attributes: Vec::new(),
35 }
36 }
37}
38
39impl<'a, T: AsRef<[u8]> + 'a> Parseable<TcMessageBuffer<&'a T>> for TcMessage {
40 fn parse(buf: &TcMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
41 Ok(Self {
42 header: TcHeader::parse(buf)
43 .context("failed to parse tc message header")?,
44 attributes: Vec::<TcAttribute>::parse(buf)
45 .context("failed to parse tc message NLAs")?,
46 })
47 }
48}
49
50impl<'a, T: AsRef<[u8]> + 'a> Parseable<TcMessageBuffer<&'a T>>
51 for Vec<TcAttribute>
52{
53 fn parse(buf: &TcMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
54 let mut attributes = vec![];
55 let mut kind = String::new();
56
57 for nla_buf in buf.attributes() {
58 let attribute =
59 TcAttribute::parse_with_param(&nla_buf?, kind.as_str())?;
60 if let TcAttribute::Kind(s) = &attribute {
61 kind = s.to_string();
62 }
63 attributes.push(attribute)
64 }
65 Ok(attributes)
66 }
67}
68
69impl Emitable for TcMessage {
70 fn buffer_len(&self) -> usize {
71 self.header.buffer_len() + self.attributes.as_slice().buffer_len()
72 }
73
74 fn emit(&self, buffer: &mut [u8]) {
75 self.header.emit(buffer);
76 self.attributes
77 .as_slice()
78 .emit(&mut buffer[self.header.buffer_len()..]);
79 }
80}