netlink_packet_route/link/
message.rs

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