netlink_packet_route/neighbour_table/
param.rs

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