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