netlink_packet_route/neighbour_table/
param.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::{
4    emit_u32, emit_u64, parse_u32, parse_u64, DecodeError, DefaultNla,
5    ErrorContext, Nla, NlaBuffer, NlasIterator, Parseable,
6};
7
8const NDTPA_IFINDEX: u16 = 1;
9const NDTPA_REFCNT: u16 = 2;
10const NDTPA_REACHABLE_TIME: u16 = 3;
11const NDTPA_BASE_REACHABLE_TIME: u16 = 4;
12const NDTPA_RETRANS_TIME: u16 = 5;
13const NDTPA_GC_STALETIME: u16 = 6;
14const NDTPA_DELAY_PROBE_TIME: u16 = 7;
15const NDTPA_QUEUE_LEN: u16 = 8;
16const NDTPA_APP_PROBES: u16 = 9;
17const NDTPA_UCAST_PROBES: u16 = 10;
18const NDTPA_MCAST_PROBES: u16 = 11;
19const NDTPA_ANYCAST_DELAY: u16 = 12;
20const NDTPA_PROXY_DELAY: u16 = 13;
21const NDTPA_PROXY_QLEN: u16 = 14;
22const NDTPA_LOCKTIME: u16 = 15;
23const NDTPA_QUEUE_LENBYTES: u16 = 16;
24const NDTPA_MCAST_REPROBES: u16 = 17;
25// const NDTPA_PAD: u16 = 18;
26const NDTPA_INTERVAL_PROBE_TIME_MS: u16 = 19;
27
28#[derive(Debug, PartialEq, Eq, Clone)]
29#[non_exhaustive]
30pub enum NeighbourTableParameter {
31    Ifindex(u32),
32    ReferenceCount(u32),
33    ReachableTime(u64),
34    BaseReachableTime(u64),
35    RetransTime(u64),
36    GcStaletime(u64),
37    DelayProbeTime(u64),
38    QueueLen(u32),
39    AppProbes(u32),
40    UcastProbes(u32),
41    McastProbes(u32),
42    AnycastDelay(u64),
43    ProxyDelay(u64),
44    ProxyQlen(u32),
45    Locktime(u64),
46    QueueLenbytes(u32),
47    McastReprobes(u32),
48    IntervalProbeTimeMs(u64),
49    Other(DefaultNla),
50}
51
52impl Nla for NeighbourTableParameter {
53    fn value_len(&self) -> usize {
54        match self {
55            Self::Ifindex(_)
56            | Self::ReferenceCount(_)
57            | Self::QueueLen(_)
58            | Self::AppProbes(_)
59            | Self::UcastProbes(_)
60            | Self::McastProbes(_)
61            | Self::ProxyQlen(_)
62            | Self::QueueLenbytes(_)
63            | Self::McastReprobes(_) => 4,
64
65            Self::ReachableTime(_)
66            | Self::BaseReachableTime(_)
67            | Self::RetransTime(_)
68            | Self::GcStaletime(_)
69            | Self::DelayProbeTime(_)
70            | Self::AnycastDelay(_)
71            | Self::ProxyDelay(_)
72            | Self::Locktime(_)
73            | Self::IntervalProbeTimeMs(_) => 8,
74
75            Self::Other(nla) => nla.value_len(),
76        }
77    }
78
79    fn emit_value(&self, buffer: &mut [u8]) {
80        match self {
81            Self::Ifindex(v)
82            | Self::ReferenceCount(v)
83            | Self::QueueLen(v)
84            | Self::AppProbes(v)
85            | Self::UcastProbes(v)
86            | Self::McastProbes(v)
87            | Self::ProxyQlen(v)
88            | Self::QueueLenbytes(v)
89            | Self::McastReprobes(v) => emit_u32(buffer, *v).unwrap(),
90
91            Self::ReachableTime(v)
92            | Self::BaseReachableTime(v)
93            | Self::RetransTime(v)
94            | Self::GcStaletime(v)
95            | Self::DelayProbeTime(v)
96            | Self::AnycastDelay(v)
97            | Self::ProxyDelay(v)
98            | Self::Locktime(v)
99            | Self::IntervalProbeTimeMs(v) => emit_u64(buffer, *v).unwrap(),
100
101            Self::Other(nla) => nla.emit_value(buffer),
102        }
103    }
104
105    fn kind(&self) -> u16 {
106        match self {
107            Self::Ifindex(_) => NDTPA_IFINDEX,
108            Self::ReferenceCount(_) => NDTPA_REFCNT,
109            Self::ReachableTime(_) => NDTPA_REACHABLE_TIME,
110            Self::BaseReachableTime(_) => NDTPA_BASE_REACHABLE_TIME,
111            Self::RetransTime(_) => NDTPA_RETRANS_TIME,
112            Self::GcStaletime(_) => NDTPA_GC_STALETIME,
113            Self::DelayProbeTime(_) => NDTPA_DELAY_PROBE_TIME,
114            Self::QueueLen(_) => NDTPA_QUEUE_LEN,
115            Self::AppProbes(_) => NDTPA_APP_PROBES,
116            Self::UcastProbes(_) => NDTPA_UCAST_PROBES,
117            Self::McastProbes(_) => NDTPA_MCAST_PROBES,
118            Self::AnycastDelay(_) => NDTPA_ANYCAST_DELAY,
119            Self::ProxyDelay(_) => NDTPA_PROXY_DELAY,
120            Self::ProxyQlen(_) => NDTPA_PROXY_QLEN,
121            Self::Locktime(_) => NDTPA_LOCKTIME,
122            Self::QueueLenbytes(_) => NDTPA_QUEUE_LENBYTES,
123            Self::McastReprobes(_) => NDTPA_MCAST_REPROBES,
124            Self::IntervalProbeTimeMs(_) => NDTPA_INTERVAL_PROBE_TIME_MS,
125            Self::Other(nla) => nla.kind(),
126        }
127    }
128}
129
130impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
131    for NeighbourTableParameter
132{
133    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
134        let payload = buf.value();
135        Ok(match buf.kind() {
136            NDTPA_IFINDEX => {
137                Self::Ifindex(parse_u32(payload).context(format!(
138                    "invalid NDTPA_IFINDEX value {payload:?}"
139                ))?)
140            }
141            NDTPA_REFCNT => {
142                Self::ReferenceCount(parse_u32(payload).context(format!(
143                    "invalid NDTPA_REFCNT value {payload:?}"
144                ))?)
145            }
146            NDTPA_REACHABLE_TIME => {
147                Self::ReachableTime(parse_u64(payload).context(format!(
148                    "invalid NDTPA_REACHABLE_TIME value {payload:?}"
149                ))?)
150            }
151            NDTPA_BASE_REACHABLE_TIME => {
152                Self::BaseReachableTime(parse_u64(payload).context(format!(
153                    "invalid NDTPA_BASE_REACHABLE_TIME value {payload:?}"
154                ))?)
155            }
156            NDTPA_RETRANS_TIME => {
157                Self::RetransTime(parse_u64(payload).context(format!(
158                    "invalid NDTPA_RETRANS_TIME value {payload:?}"
159                ))?)
160            }
161            NDTPA_GC_STALETIME => {
162                Self::GcStaletime(parse_u64(payload).context(format!(
163                    "invalid NDTPA_GC_STALE_TIME value {payload:?}"
164                ))?)
165            }
166            NDTPA_DELAY_PROBE_TIME => {
167                Self::DelayProbeTime(parse_u64(payload).context(format!(
168                    "invalid NDTPA_DELAY_PROBE_TIME value {payload:?}"
169                ))?)
170            }
171            NDTPA_QUEUE_LEN => Self::QueueLen(parse_u32(payload).context(
172                format!("invalid NDTPA_QUEUE_LEN value {payload:?}"),
173            )?),
174            NDTPA_APP_PROBES => Self::AppProbes(parse_u32(payload).context(
175                format!("invalid NDTPA_APP_PROBES value {payload:?}"),
176            )?),
177            NDTPA_UCAST_PROBES => {
178                Self::UcastProbes(parse_u32(payload).context(format!(
179                    "invalid NDTPA_UCAST_PROBES value {payload:?}"
180                ))?)
181            }
182            NDTPA_MCAST_PROBES => {
183                Self::McastProbes(parse_u32(payload).context(format!(
184                    "invalid NDTPA_MCAST_PROBES value {payload:?}"
185                ))?)
186            }
187            NDTPA_ANYCAST_DELAY => {
188                Self::AnycastDelay(parse_u64(payload).context(format!(
189                    "invalid NDTPA_ANYCAST_DELAY value {payload:?}"
190                ))?)
191            }
192            NDTPA_PROXY_DELAY => Self::ProxyDelay(parse_u64(payload).context(
193                format!("invalid NDTPA_PROXY_DELAY value {payload:?}"),
194            )?),
195            NDTPA_PROXY_QLEN => Self::ProxyQlen(parse_u32(payload).context(
196                format!("invalid NDTPA_PROXY_QLEN value {payload:?}"),
197            )?),
198            NDTPA_LOCKTIME => Self::Locktime(parse_u64(payload).context(
199                format!("invalid NDTPA_LOCKTIME value {payload:?}"),
200            )?),
201            NDTPA_QUEUE_LENBYTES => {
202                Self::QueueLenbytes(parse_u32(payload).context(format!(
203                    "invalid NDTPA_QUEUE_LENBYTES value {payload:?}"
204                ))?)
205            }
206            NDTPA_MCAST_REPROBES => {
207                Self::McastReprobes(parse_u32(payload).context(format!(
208                    "invalid NDTPA_MCAST_PROBES value {payload:?}"
209                ))?)
210            }
211            NDTPA_INTERVAL_PROBE_TIME_MS => Self::IntervalProbeTimeMs(
212                parse_u64(payload).context(format!(
213                    "invalid NDTPA_INTERVAL_PROBE_TIME_MS value {payload:?}"
214                ))?,
215            ),
216            _ => Self::Other(DefaultNla::parse(buf).context(format!(
217                "invalid NDTA_PARMS attribute {payload:?}"
218            ))?),
219        })
220    }
221}
222
223#[derive(Debug, PartialEq, Eq, Clone)]
224pub(crate) struct VecNeighbourTableParameter(
225    pub(crate) Vec<NeighbourTableParameter>,
226);
227
228impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>>
229    for VecNeighbourTableParameter
230{
231    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
232        let mut nlas = vec![];
233        let err = "invalid NDTA_PARMS attribute";
234        for nla in NlasIterator::new(buf.into_inner()) {
235            let nla = nla.context(err)?;
236            nlas.push(NeighbourTableParameter::parse(&nla).context(err)?);
237        }
238        Ok(Self(nlas))
239    }
240}