netlink_packet_route/neighbour/
attribute.rs
1use super::{NeighbourAddress, NeighbourCacheInfo, NeighbourCacheInfoBuffer, NeighbourError};
4use crate::route::RouteProtocol;
5use crate::AddressFamily;
6use byteorder::{BigEndian, ByteOrder, NativeEndian};
7use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer};
8use netlink_packet_utils::parsers::{parse_u16, parse_u16_be, parse_u32};
9use netlink_packet_utils::{Emitable, Parseable, ParseableParametrized};
10
11const NDA_DST: u16 = 1;
12const NDA_LLADDR: u16 = 2;
13const NDA_CACHEINFO: u16 = 3;
14const NDA_PROBES: u16 = 4;
15const NDA_VLAN: u16 = 5;
16const NDA_PORT: u16 = 6;
17const NDA_VNI: u16 = 7;
18const NDA_IFINDEX: u16 = 8;
19const NDA_CONTROLLER: u16 = 9;
21const NDA_LINK_NETNSID: u16 = 10;
22const NDA_SRC_VNI: u16 = 11;
23const NDA_PROTOCOL: u16 = 12;
24#[derive(Debug, PartialEq, Eq, Clone)]
28#[non_exhaustive]
29pub enum NeighbourAttribute {
30 Destination(NeighbourAddress),
31 LinkLocalAddress(Vec<u8>),
32 CacheInfo(NeighbourCacheInfo),
33 Probes(u32),
34 Vlan(u16),
35 Port(u16),
36 Vni(u32),
37 IfIndex(u32),
38 Controller(u32),
39 LinkNetNsId(u32),
40 SourceVni(u32),
41 Protocol(RouteProtocol),
42 Other(DefaultNla),
43}
44
45impl Nla for NeighbourAttribute {
46 fn value_len(&self) -> usize {
47 match self {
48 Self::LinkLocalAddress(bytes) => bytes.len(),
49 Self::Destination(v) => v.buffer_len(),
50 Self::CacheInfo(v) => v.buffer_len(),
51 Self::Vlan(_) | Self::Port(_) => 2,
52 Self::Protocol(v) => v.buffer_len(),
53 Self::Probes(_)
54 | Self::LinkNetNsId(_)
55 | Self::Controller(_)
56 | Self::Vni(_)
57 | Self::IfIndex(_)
58 | Self::SourceVni(_) => 4,
59 Self::Other(attr) => attr.value_len(),
60 }
61 }
62
63 fn emit_value(&self, buffer: &mut [u8]) {
64 match self {
65 Self::Destination(v) => v.emit(buffer),
66 Self::LinkLocalAddress(bytes) => buffer.copy_from_slice(bytes.as_slice()),
67 Self::CacheInfo(v) => v.emit(buffer),
68 Self::Vlan(value) => NativeEndian::write_u16(buffer, *value),
69 Self::Port(value) => BigEndian::write_u16(buffer, *value),
70 Self::Probes(value)
71 | Self::LinkNetNsId(value)
72 | Self::Controller(value)
73 | Self::Vni(value)
74 | Self::IfIndex(value)
75 | Self::SourceVni(value) => NativeEndian::write_u32(buffer, *value),
76 Self::Protocol(v) => v.emit(buffer),
77 Self::Other(attr) => attr.emit_value(buffer),
78 }
79 }
80
81 fn kind(&self) -> u16 {
82 match self {
83 Self::Destination(_) => NDA_DST,
84 Self::LinkLocalAddress(_) => NDA_LLADDR,
85 Self::CacheInfo(_) => NDA_CACHEINFO,
86 Self::Probes(_) => NDA_PROBES,
87 Self::Vlan(_) => NDA_VLAN,
88 Self::Port(_) => NDA_PORT,
89 Self::Vni(_) => NDA_VNI,
90 Self::IfIndex(_) => NDA_IFINDEX,
91 Self::Controller(_) => NDA_CONTROLLER,
92 Self::LinkNetNsId(_) => NDA_LINK_NETNSID,
93 Self::SourceVni(_) => NDA_SRC_VNI,
94 Self::Protocol(_) => NDA_PROTOCOL,
95 Self::Other(nla) => nla.kind(),
96 }
97 }
98}
99
100impl<'a, T: AsRef<[u8]> + ?Sized> ParseableParametrized<NlaBuffer<&'a T>, AddressFamily>
101 for NeighbourAttribute
102{
103 type Error = NeighbourError;
104 fn parse_with_param(
105 buf: &NlaBuffer<&'a T>,
106 address_family: AddressFamily,
107 ) -> Result<Self, Self::Error> {
108 let payload = buf.value();
109 Ok(match buf.kind() {
110 NDA_DST => Self::Destination(
111 NeighbourAddress::parse_with_param(address_family, payload)
112 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_DST", error })?,
113 ),
114 NDA_LLADDR => Self::LinkLocalAddress(payload.to_vec()),
115 NDA_CACHEINFO => Self::CacheInfo(
116 NeighbourCacheInfoBuffer::new_checked(payload)
117 .and_then(|buffer| NeighbourCacheInfo::parse(&buffer))
118 .map_err(|error| NeighbourError::InvalidValue {
119 kind: "NDA_CACHEINFO",
120 error,
121 })?,
122 ),
123 NDA_PROBES => Self::Probes(
124 parse_u32(payload)
125 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_PROBES", error })?,
126 ),
127 NDA_VLAN => Self::Vlan(
128 parse_u16(payload)
129 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_VLAN", error })?,
130 ),
131 NDA_PORT => Self::Port(
132 parse_u16_be(payload)
133 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_PORT", error })?,
134 ),
135 NDA_VNI => Self::Vni(
136 parse_u32(payload)
137 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_VNI", error })?,
138 ),
139 NDA_IFINDEX => Self::IfIndex(
140 parse_u32(payload)
141 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_IFINDEX", error })?,
142 ),
143 NDA_CONTROLLER => {
144 Self::Controller(parse_u32(payload).map_err(|error| {
145 NeighbourError::InvalidValue { kind: "NDA_CONTROLLER", error }
146 })?)
147 }
148 NDA_LINK_NETNSID => Self::LinkNetNsId(parse_u32(payload).map_err(|error| {
149 NeighbourError::InvalidValue { kind: "NDA_LINK_NETNSID", error }
150 })?),
151 NDA_SRC_VNI => Self::SourceVni(
152 parse_u32(payload)
153 .map_err(|error| NeighbourError::InvalidValue { kind: "NDA_SRC_VNI", error })?,
154 ),
155 NDA_PROTOCOL => Self::Protocol(RouteProtocol::parse(payload)?),
156 kind => Self::Other(
157 DefaultNla::parse(buf)
158 .map_err(|error| NeighbourError::UnknownNLA { kind, error })?,
159 ),
160 })
161 }
162}