netlink_packet_route/neighbour/
header.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::{
4    DecodeError, Emitable, NlaBuffer, NlasIterator, Parseable,
5};
6
7use super::{flags::NeighbourFlags, NeighbourState};
8use crate::{route::RouteType, AddressFamily};
9
10const NEIGHBOUR_HEADER_LEN: usize = 12;
11
12buffer!(NeighbourMessageBuffer(NEIGHBOUR_HEADER_LEN) {
13    family: (u8, 0),
14    ifindex: (u32, 4..8),
15    state: (u16, 8..10),
16    flags: (u8, 10),
17    kind: (u8, 11),
18    payload:(slice, NEIGHBOUR_HEADER_LEN..),
19});
20
21impl<'a, T: AsRef<[u8]> + ?Sized> NeighbourMessageBuffer<&'a T> {
22    pub fn attributes(
23        &self,
24    ) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>, DecodeError>> {
25        NlasIterator::new(self.payload())
26    }
27}
28
29/// Neighbour headers have the following structure:
30///
31/// ```no_rust
32/// 0                8                16              24               32
33/// +----------------+----------------+----------------+----------------+
34/// |     family     |                     padding                      |
35/// +----------------+----------------+----------------+----------------+
36/// |                             link index                            |
37/// +----------------+----------------+----------------+----------------+
38/// |              state              |     flags      |     ntype      |
39/// +----------------+----------------+----------------+----------------+
40/// ```
41///
42/// `NeighbourHeader` exposes all these fields.
43// Linux kernel struct `struct ndmsg`
44#[derive(Debug, PartialEq, Eq, Clone, Default)]
45pub struct NeighbourHeader {
46    pub family: AddressFamily,
47    pub ifindex: u32,
48    /// Neighbour cache entry state.
49    pub state: NeighbourState,
50    /// Neighbour cache entry flags. It should be set to a combination
51    /// of the `NTF_*` constants
52    pub flags: NeighbourFlags,
53    /// Neighbour cache entry type. It should be set to one of the
54    /// `NDA_*` constants.
55    pub kind: RouteType,
56}
57
58impl<T: AsRef<[u8]>> Parseable<NeighbourMessageBuffer<T>> for NeighbourHeader {
59    fn parse(buf: &NeighbourMessageBuffer<T>) -> Result<Self, DecodeError> {
60        Ok(Self {
61            family: buf.family().into(),
62            ifindex: buf.ifindex(),
63            state: buf.state().into(),
64            flags: NeighbourFlags::from_bits_retain(buf.flags()),
65            kind: buf.kind().into(),
66        })
67    }
68}
69
70impl Emitable for NeighbourHeader {
71    fn buffer_len(&self) -> usize {
72        NEIGHBOUR_HEADER_LEN
73    }
74
75    fn emit(&self, buffer: &mut [u8]) {
76        let mut packet = NeighbourMessageBuffer::new(buffer);
77        packet.set_family(self.family.into());
78        packet.set_ifindex(self.ifindex);
79        packet.set_state(self.state.into());
80        packet.set_flags(self.flags.bits());
81        packet.set_kind(self.kind.into());
82    }
83}