netlink_packet_route/rule/
header.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_utils::{
4    nla::{NlaBuffer, NlasIterator},
5    traits::{Emitable, Parseable},
6    DecodeError,
7};
8
9use super::{super::AddressFamily, flags::RuleFlags, RuleAction};
10
11const RULE_HEADER_LEN: usize = 12;
12
13buffer!(RuleMessageBuffer(RULE_HEADER_LEN) {
14    family: (u8, 0),
15    dst_len: (u8, 1),
16    src_len: (u8, 2),
17    tos: (u8, 3),
18    table: (u8, 4),
19    reserve_1: (u8, 5),
20    reserve_2: (u8, 6),
21    action: (u8, 7),
22    flags: (u32, 8..RULE_HEADER_LEN),
23    payload: (slice, RULE_HEADER_LEN..),
24});
25
26impl<'a, T: AsRef<[u8]> + ?Sized> RuleMessageBuffer<&'a T> {
27    pub fn attributes(
28        &self,
29    ) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>, DecodeError>> {
30        NlasIterator::new(self.payload())
31    }
32}
33
34// Linux kernel code `struct fib_rule_hdr`
35#[derive(Debug, PartialEq, Eq, Clone, Default)]
36pub struct RuleHeader {
37    pub family: AddressFamily,
38    pub dst_len: u8,
39    pub src_len: u8,
40    pub tos: u8,
41    pub table: u8,
42    pub action: RuleAction,
43    pub flags: RuleFlags,
44}
45
46impl Emitable for RuleHeader {
47    fn buffer_len(&self) -> usize {
48        RULE_HEADER_LEN
49    }
50
51    fn emit(&self, buffer: &mut [u8]) {
52        let mut packet = RuleMessageBuffer::new(buffer);
53        packet.set_family(self.family.into());
54        packet.set_dst_len(self.dst_len);
55        packet.set_src_len(self.src_len);
56        packet.set_table(self.table);
57        packet.set_tos(self.tos);
58        packet.set_action(self.action.into());
59        packet.set_flags(self.flags.bits());
60    }
61}
62
63impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<RuleMessageBuffer<&'a T>>
64    for RuleHeader
65{
66    fn parse(buf: &RuleMessageBuffer<&'a T>) -> Result<Self, DecodeError> {
67        Ok(RuleHeader {
68            family: buf.family().into(),
69            dst_len: buf.dst_len(),
70            src_len: buf.src_len(),
71            tos: buf.tos(),
72            table: buf.table(),
73            action: buf.action().into(),
74            flags: RuleFlags::from_bits_retain(buf.flags()),
75        })
76    }
77}