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