Skip to main content

netlink_packet_route/link/
message.rs

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