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