netlink_packet_route/rule/
header.rs

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