netlink_packet_route/rtnl/link/header.rs
1// SPDX-License-Identifier: MIT
2
3use crate::{
4 traits::{Emitable, Parseable},
5 DecodeError,
6 LinkMessageBuffer,
7 LINK_HEADER_LEN,
8};
9
10/// High level representation of `RTM_GETLINK`, `RTM_SETLINK`, `RTM_NEWLINK` and `RTM_DELLINK`
11/// messages headers.
12///
13/// These headers have the following structure:
14///
15/// ```no_rust
16/// 0 8 16 24 32
17/// +----------------+----------------+----------------+----------------+
18/// |interface family| reserved | link layer type |
19/// +----------------+----------------+----------------+----------------+
20/// | link index |
21/// +----------------+----------------+----------------+----------------+
22/// | flags |
23/// +----------------+----------------+----------------+----------------+
24/// | change mask |
25/// +----------------+----------------+----------------+----------------+
26/// ```
27///
28/// `LinkHeader` exposes all these fields except for the "reserved" one.
29#[derive(Debug, PartialEq, Eq, Clone, Default)]
30pub struct LinkHeader {
31 /// Address family: one of the `AF_*` constants.
32 pub interface_family: u8,
33 /// Link index.
34 pub index: u32,
35 /// Link type. It should be set to one of the `ARPHRD_*`
36 /// constants. The most common value is `ARPHRD_ETHER` for
37 /// Ethernet.
38 pub link_layer_type: u16,
39 /// State of the link, described by a combinations of `IFF_*`
40 /// constants, for instance `IFF_UP | IFF_LOWER_UP`.
41 pub flags: u32,
42 /// Change mask for the `flags` field. Reserved, it should be set
43 /// to `0xffff_ffff`.
44 pub change_mask: u32,
45}
46
47impl Emitable for LinkHeader {
48 fn buffer_len(&self) -> usize {
49 LINK_HEADER_LEN
50 }
51
52 fn emit(&self, buffer: &mut [u8]) {
53 let mut packet = LinkMessageBuffer::new(buffer);
54 packet.set_interface_family(self.interface_family);
55 packet.set_link_index(self.index);
56 packet.set_change_mask(self.change_mask);
57 packet.set_link_layer_type(self.link_layer_type);
58 packet.set_flags(self.flags);
59 }
60}
61
62impl<T: AsRef<[u8]>> Parseable<LinkMessageBuffer<T>> for LinkHeader {
63 fn parse(buf: &LinkMessageBuffer<T>) -> Result<Self, DecodeError> {
64 Ok(Self {
65 interface_family: buf.interface_family(),
66 link_layer_type: buf.link_layer_type(),
67 index: buf.link_index(),
68 change_mask: buf.change_mask(),
69 flags: buf.flags(),
70 })
71 }
72}