netlink_packet_route/rtnl/tc/nlas/
mod.rs1mod stats;
4pub use self::stats::*;
5
6mod stats_queue;
7pub use self::stats_queue::*;
8
9mod stats_basic;
10pub use self::stats_basic::*;
11
12mod options;
13pub use self::options::*;
14
15mod qdisc;
16pub use self::qdisc::*;
17
18mod filter;
19pub use self::filter::*;
20
21mod action;
22pub use self::action::*;
23
24#[cfg(test)]
25mod test;
26
27use crate::{
28 constants::*,
29 nlas::{self, DefaultNla, NlaBuffer},
30 traits::{Emitable, Parseable},
31 DecodeError,
32};
33
34#[derive(Debug, PartialEq, Eq, Clone)]
35pub enum Nla {
36 Unspec(Vec<u8>),
38 Kind(String),
40 Options(Vec<TcOpt>),
42 Stats(Stats),
44 XStats(Vec<u8>),
46 Rate(Vec<u8>),
48 Fcnt(Vec<u8>),
49 Stats2(Vec<Stats2>),
50 Stab(Vec<u8>),
51 Chain(Vec<u8>),
52 HwOffload(u8),
53 Other(DefaultNla),
54}
55
56impl nlas::Nla for Nla {
57 #[rustfmt::skip]
58 fn value_len(&self) -> usize {
59 use self::Nla::*;
60 match *self {
61 Unspec(ref bytes) | XStats(ref bytes) | Rate(ref bytes) | Fcnt(ref bytes)
63 | Stab(ref bytes) | Chain(ref bytes) => bytes.len(),
64 HwOffload(_) => 1,
65 Stats2(ref thing) => thing.as_slice().buffer_len(),
66 Stats(_) => STATS_LEN,
67 Kind(ref string) => string.as_bytes().len() + 1,
68 Options(ref opt) => opt.as_slice().buffer_len(),
69 Other(ref attr) => attr.value_len(),
71 }
72 }
73
74 #[cfg_attr(nightly, rustfmt::skip)]
75 fn emit_value(&self, buffer: &mut [u8]) {
76 use self::Nla::*;
77 match *self {
78 Unspec(ref bytes)
80 | XStats(ref bytes)
81 | Rate(ref bytes)
82 | Fcnt(ref bytes)
83 | Stab(ref bytes)
84 | Chain(ref bytes) => buffer.copy_from_slice(bytes.as_slice()),
85
86 HwOffload(ref val) => buffer[0] = *val,
87 Stats2(ref stats) => stats.as_slice().emit(buffer),
88 Stats(ref stats) => stats.emit(buffer),
89
90 Kind(ref string) => {
91 buffer[..string.as_bytes().len()].copy_from_slice(string.as_bytes());
92 buffer[string.as_bytes().len()] = 0;
93 }
94 Options(ref opt) => opt.as_slice().emit(buffer),
95
96 Other(ref attr) => attr.emit_value(buffer),
98 }
99 }
100
101 fn kind(&self) -> u16 {
102 use self::Nla::*;
103 match *self {
104 Unspec(_) => TCA_UNSPEC,
105 Kind(_) => TCA_KIND,
106 Options(_) => TCA_OPTIONS,
107 Stats(_) => TCA_STATS,
108 XStats(_) => TCA_XSTATS,
109 Rate(_) => TCA_RATE,
110 Fcnt(_) => TCA_FCNT,
111 Stats2(_) => TCA_STATS2,
112 Stab(_) => TCA_STAB,
113 Chain(_) => TCA_CHAIN,
114 HwOffload(_) => TCA_HW_OFFLOAD,
115 Other(ref nla) => nla.kind(),
116 }
117 }
118}
119
120#[derive(Debug, PartialEq, Eq, Clone)]
121pub enum Stats2 {
122 StatsApp(Vec<u8>),
123 StatsBasic(Vec<u8>),
124 StatsQueue(Vec<u8>),
125 Other(DefaultNla),
126}
127
128impl nlas::Nla for Stats2 {
129 fn value_len(&self) -> usize {
130 use self::Stats2::*;
131 match *self {
132 StatsBasic(ref bytes) | StatsQueue(ref bytes) | StatsApp(ref bytes) => bytes.len(),
133 Other(ref nla) => nla.value_len(),
134 }
135 }
136
137 fn emit_value(&self, buffer: &mut [u8]) {
138 use self::Stats2::*;
139 match *self {
140 StatsBasic(ref bytes) | StatsQueue(ref bytes) | StatsApp(ref bytes) => {
141 buffer.copy_from_slice(bytes.as_slice())
142 }
143 Other(ref nla) => nla.emit_value(buffer),
144 }
145 }
146
147 fn kind(&self) -> u16 {
148 use self::Stats2::*;
149 match *self {
150 StatsApp(_) => TCA_STATS_APP,
151 StatsBasic(_) => TCA_STATS_BASIC,
152 StatsQueue(_) => TCA_STATS_QUEUE,
153 Other(ref nla) => nla.kind(),
154 }
155 }
156}
157
158impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for Stats2 {
159 fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
160 let payload = buf.value();
161 Ok(match buf.kind() {
162 TCA_STATS_APP => Self::StatsApp(payload.to_vec()),
163 TCA_STATS_BASIC => Self::StatsBasic(payload.to_vec()),
164 TCA_STATS_QUEUE => Self::StatsQueue(payload.to_vec()),
165 _ => Self::Other(DefaultNla::parse(buf)?),
166 })
167 }
168}