netlink_packet_route/route/
message.rs1use super::super::AddressFamily;
4use super::attribute::RTA_ENCAP_TYPE;
5use super::error::RouteError;
6use super::{RouteAttribute, RouteHeader, RouteLwEnCapType, RouteMessageBuffer, RouteType};
7use crate::RouteNetlinkMessageParseMode;
8use netlink_packet_utils::nla::{HasNlas, NlaParseMode};
9use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
10
11#[derive(Debug, PartialEq, Eq, Clone, Default)]
12#[non_exhaustive]
13pub struct RouteMessage {
14 pub header: RouteHeader,
15 pub attributes: Vec<RouteAttribute>,
16}
17
18impl Emitable for RouteMessage {
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<RouteMessageBuffer<&'a T>, RouteNetlinkMessageParseMode>
31 for RouteMessage
32{
33 type Error = RouteError;
34 fn parse_with_param(
35 buf: &RouteMessageBuffer<&'a T>,
36 mode: RouteNetlinkMessageParseMode,
37 ) -> Result<Self, RouteError> {
38 let header = RouteHeader::parse(buf).unwrap();
40 let address_family = header.address_family;
41 let route_type = header.kind;
42 Ok(RouteMessage {
43 header,
44 attributes: Vec::<RouteAttribute>::parse_with_param(
45 buf,
46 (mode.into(), address_family, route_type),
47 )?,
48 })
49 }
50}
51
52impl<'a, T: AsRef<[u8]> + 'a>
53 ParseableParametrized<RouteMessageBuffer<&'a T>, (NlaParseMode, AddressFamily, RouteType)>
54 for Vec<RouteAttribute>
55{
56 type Error = RouteError;
57 fn parse_with_param(
58 buf: &RouteMessageBuffer<&'a T>,
59 (mode, address_family, route_type): (NlaParseMode, AddressFamily, RouteType),
60 ) -> Result<Self, RouteError> {
61 let mut encap_type = RouteLwEnCapType::None;
62 for nla_buf in buf.attributes() {
65 let nla = match nla_buf {
66 Ok(n) => n,
67 Err(_) => continue,
68 };
69 if nla.kind() == RTA_ENCAP_TYPE {
70 if let Ok(RouteAttribute::EncapType(v)) =
71 RouteAttribute::parse_with_param(&nla, (address_family, route_type, encap_type))
72 {
73 encap_type = v;
74 break;
75 }
76 }
77 }
78 buf.parse_attributes(mode, |b| {
79 RouteAttribute::parse_with_param(b, (address_family, route_type, encap_type))
80 })
81 }
82}