netlink_packet_route/tc/stats/
stats2.rs

1// SPDX-License-Identifier: MIT
2
3use super::{TcStatsBasic, TcStatsBasicBuffer, TcStatsQueue, TcStatsQueueBuffer, TcXstats};
4use crate::tc::TcError;
5use netlink_packet_utils::nla::{DefaultNla, Nla, NlaBuffer};
6use netlink_packet_utils::traits::{Emitable, Parseable, ParseableParametrized};
7
8const TCA_STATS_BASIC: u16 = 1;
9// const TCA_STATS_RATE_EST: u16 = 2; // TODO
10const TCA_STATS_QUEUE: u16 = 3;
11const TCA_STATS_APP: u16 = 4;
12// const TCA_STATS_RATE_EST64: u16 = 5; // TODO
13// const TCA_STATS_PAD: u16 = 6;
14const TCA_STATS_BASIC_HW: u16 = 7;
15
16#[derive(Debug, PartialEq, Eq, Clone)]
17#[non_exhaustive]
18pub enum TcStats2 {
19    App(TcXstats),
20    Basic(TcStatsBasic),
21    Queue(TcStatsQueue),
22    BasicHw(TcStatsBasic),
23    Other(DefaultNla),
24}
25
26impl Nla for TcStats2 {
27    fn value_len(&self) -> usize {
28        match self {
29            Self::App(v) => v.buffer_len(),
30            Self::Basic(v) => v.buffer_len(),
31            Self::Queue(v) => v.buffer_len(),
32            Self::BasicHw(v) => v.buffer_len(),
33            Self::Other(ref nla) => nla.value_len(),
34        }
35    }
36
37    fn emit_value(&self, buffer: &mut [u8]) {
38        match self {
39            Self::App(v) => v.emit(buffer),
40            Self::Basic(v) => v.emit(buffer),
41            Self::Queue(v) => v.emit(buffer),
42            Self::BasicHw(v) => v.emit(buffer),
43            Self::Other(ref nla) => nla.emit_value(buffer),
44        }
45    }
46
47    fn kind(&self) -> u16 {
48        match self {
49            Self::App(_) => TCA_STATS_APP,
50            Self::Basic(_) => TCA_STATS_BASIC,
51            Self::Queue(_) => TCA_STATS_QUEUE,
52            Self::BasicHw(_) => TCA_STATS_BASIC_HW,
53            Self::Other(ref nla) => nla.kind(),
54        }
55    }
56}
57
58impl<'a, T> ParseableParametrized<NlaBuffer<&'a T>, &str> for TcStats2
59where
60    T: AsRef<[u8]> + ?Sized,
61{
62    type Error = TcError;
63    fn parse_with_param(buf: &NlaBuffer<&'a T>, kind: &str) -> Result<Self, TcError> {
64        let payload = buf.value();
65        Ok(match buf.kind() {
66            TCA_STATS_APP => Self::App(TcXstats::parse_with_param(buf, kind)?),
67            TCA_STATS_BASIC => Self::Basic(
68                // unwrap: TCStatsBasic doesn't fail to parse.
69                TcStatsBasic::parse(&TcStatsBasicBuffer::new(payload)).unwrap(),
70            ),
71            TCA_STATS_QUEUE => Self::Queue(
72                // unwrap: TCStatsQueue doesn't fail to parse.
73                TcStatsQueue::parse(&TcStatsQueueBuffer::new(payload)).unwrap(),
74            ),
75            TCA_STATS_BASIC_HW => Self::BasicHw(
76                // unwrap: TCStatsBasic doesn't fail to parse.
77                TcStatsBasic::parse(&TcStatsBasicBuffer::new(payload)).unwrap(),
78            ),
79            kind => Self::Other(
80                DefaultNla::parse(buf).map_err(|error| TcError::UnknownNla { kind, error })?,
81            ),
82        })
83    }
84}