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