netlink_packet_route/tc/stats/
stats2.rs

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