netlink_packet_route/rtnl/route/nlas/
metrics.rs

1// SPDX-License-Identifier: MIT
2
3use anyhow::Context;
4use byteorder::{ByteOrder, NativeEndian};
5use std::mem::size_of;
6
7use crate::{
8    constants::*,
9    nlas::{DefaultNla, Nla, NlaBuffer},
10    parsers::parse_u32,
11    traits::Parseable,
12    DecodeError,
13};
14
15#[derive(Debug, PartialEq, Eq, Clone)]
16pub enum Metrics {
17    Unspec(Vec<u8>),
18    Lock(u32),
19    Mtu(u32),
20    Window(u32),
21    Rtt(u32),
22    RttVar(u32),
23    SsThresh(u32),
24    Cwnd(u32),
25    Advmss(u32),
26    Reordering(u32),
27    Hoplimit(u32),
28    InitCwnd(u32),
29    Features(u32),
30    RtoMin(u32),
31    InitRwnd(u32),
32    QuickAck(u32),
33    CcAlgo(u32),
34    FastopenNoCookie(u32),
35    Other(DefaultNla),
36}
37
38impl Nla for Metrics {
39    #[rustfmt::skip]
40    fn value_len(&self) -> usize {
41        use self::Metrics::*;
42        match *self {
43            Unspec(ref bytes) => bytes.len(),
44            Lock(_)
45                | Mtu(_)
46                | Window(_)
47                | Rtt(_)
48                | RttVar(_)
49                | SsThresh(_)
50                | Cwnd(_)
51                | Advmss(_)
52                | Reordering(_)
53                | Hoplimit(_)
54                | InitCwnd(_)
55                | Features(_)
56                | RtoMin(_)
57                | InitRwnd(_)
58                | QuickAck(_)
59                | CcAlgo(_)
60                | FastopenNoCookie(_)
61                => size_of::<u32>(),
62            Other(ref attr) => attr.value_len(),
63        }
64    }
65
66    #[rustfmt::skip]
67    fn emit_value(&self, buffer: &mut [u8]) {
68        use self::Metrics::*;
69        match *self {
70            Unspec(ref bytes) => buffer.copy_from_slice(bytes.as_slice()),
71
72            Lock(value)
73                | Mtu(value)
74                | Window(value)
75                | Rtt(value)
76                | RttVar(value)
77                | SsThresh(value)
78                | Cwnd(value)
79                | Advmss(value)
80                | Reordering(value)
81                | Hoplimit(value)
82                | InitCwnd(value)
83                | Features(value)
84                | RtoMin(value)
85                | InitRwnd(value)
86                | QuickAck(value)
87                | CcAlgo(value)
88                | FastopenNoCookie(value)
89                => NativeEndian::write_u32(buffer, value),
90
91            Other(ref attr) => attr.emit_value(buffer),
92        }
93    }
94
95    fn kind(&self) -> u16 {
96        use self::Metrics::*;
97        match *self {
98            Unspec(_) => RTAX_UNSPEC,
99            Lock(_) => RTAX_LOCK,
100            Mtu(_) => RTAX_MTU,
101            Window(_) => RTAX_WINDOW,
102            Rtt(_) => RTAX_RTT,
103            RttVar(_) => RTAX_RTTVAR,
104            SsThresh(_) => RTAX_SSTHRESH,
105            Cwnd(_) => RTAX_CWND,
106            Advmss(_) => RTAX_ADVMSS,
107            Reordering(_) => RTAX_REORDERING,
108            Hoplimit(_) => RTAX_HOPLIMIT,
109            InitCwnd(_) => RTAX_INITCWND,
110            Features(_) => RTAX_FEATURES,
111            RtoMin(_) => RTAX_RTO_MIN,
112            InitRwnd(_) => RTAX_INITRWND,
113            QuickAck(_) => RTAX_QUICKACK,
114            CcAlgo(_) => RTAX_CC_ALGO,
115            FastopenNoCookie(_) => RTAX_FASTOPEN_NO_COOKIE,
116            Other(ref attr) => attr.kind(),
117        }
118    }
119}
120
121impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Metrics {
122    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
123        use self::Metrics::*;
124        let payload = buf.value();
125        Ok(match buf.kind() {
126            RTAX_UNSPEC => Unspec(payload.to_vec()),
127            RTAX_LOCK => Lock(parse_u32(payload).context("invalid RTAX_LOCK value")?),
128            RTAX_MTU => Mtu(parse_u32(payload).context("invalid RTAX_MTU value")?),
129            RTAX_WINDOW => Window(parse_u32(payload).context("invalid RTAX_WINDOW value")?),
130            RTAX_RTT => Rtt(parse_u32(payload).context("invalid RTAX_RTT value")?),
131            RTAX_RTTVAR => RttVar(parse_u32(payload).context("invalid RTAX_RTTVAR value")?),
132            RTAX_SSTHRESH => SsThresh(parse_u32(payload).context("invalid RTAX_SSTHRESH value")?),
133            RTAX_CWND => Cwnd(parse_u32(payload).context("invalid RTAX_CWND value")?),
134            RTAX_ADVMSS => Advmss(parse_u32(payload).context("invalid RTAX_ADVMSS value")?),
135            RTAX_REORDERING => {
136                Reordering(parse_u32(payload).context("invalid RTAX_REORDERING value")?)
137            }
138            RTAX_HOPLIMIT => Hoplimit(parse_u32(payload).context("invalid RTAX_HOPLIMIT value")?),
139            RTAX_INITCWND => InitCwnd(parse_u32(payload).context("invalid RTAX_INITCWND value")?),
140            RTAX_FEATURES => Features(parse_u32(payload).context("invalid RTAX_FEATURES value")?),
141            RTAX_RTO_MIN => RtoMin(parse_u32(payload).context("invalid RTAX_RTO_MIN value")?),
142            RTAX_INITRWND => InitRwnd(parse_u32(payload).context("invalid RTAX_INITRWND value")?),
143            RTAX_QUICKACK => QuickAck(parse_u32(payload).context("invalid RTAX_QUICKACK value")?),
144            RTAX_CC_ALGO => CcAlgo(parse_u32(payload).context("invalid RTAX_CC_ALGO value")?),
145            RTAX_FASTOPEN_NO_COOKIE => FastopenNoCookie(
146                parse_u32(payload).context("invalid RTAX_FASTOPEN_NO_COOKIE value")?,
147            ),
148            _ => Other(DefaultNla::parse(buf).context("invalid NLA value (unknown type) value")?),
149        })
150    }
151}