netlink_packet_route/rtnl/route/nlas/
metrics.rs1use 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}