netlink_packet_route/rtnl/rule/
message.rs

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