netlink_packet_route/link/
message.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
5use netlink_packet_utils::DecodeError;
6
7use crate::link::{LinkAttribute, LinkHeader, LinkMessageBuffer};
8use crate::AddressFamily;
9
10#[derive(Debug, PartialEq, Eq, Clone, Default)]
11#[non_exhaustive]
12pub struct LinkMessage {
13    pub header: LinkHeader,
14    pub attributes: Vec<LinkAttribute>,
15}
16
17impl Emitable for LinkMessage {
18    fn buffer_len(&self) -> usize {
19        self.header.buffer_len() + self.attributes.as_slice().buffer_len()
20    }
21
22    fn emit(&self, buffer: &mut [u8]) {
23        self.header.emit(buffer);
24        self.attributes.as_slice().emit(&mut buffer[self.header.buffer_len()..]);
25    }
26}
27
28impl<'a, T: AsRef<[u8]> + 'a> Parseable<LinkMessageBuffer<&'a T>> for LinkMessage {
29    type Error = DecodeError;
30    fn parse(buf: &LinkMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
31        let header = LinkHeader::parse(buf).context("failed to parse link message header")?;
32        let interface_family = header.interface_family;
33        let attributes = Vec::<LinkAttribute>::parse_with_param(buf, interface_family)
34            .context("failed to parse link message NLAs")?;
35        Ok(LinkMessage { header, attributes })
36    }
37}
38
39impl<'a, T: AsRef<[u8]> + 'a> ParseableParametrized<LinkMessageBuffer<&'a T>, AddressFamily>
40    for Vec<LinkAttribute>
41{
42    type Error = DecodeError;
43    fn parse_with_param(
44        buf: &LinkMessageBuffer<&'a T>,
45        family: AddressFamily,
46    ) -> Result<Self, DecodeError> {
47        let mut attributes = vec![];
48        for nla_buf in buf.attributes() {
49            attributes.push(LinkAttribute::parse_with_param(&nla_buf?, family)?);
50        }
51        Ok(attributes)
52    }
53}