netlink_packet_route/link/sriov/
stats.rs

1// SPDX-License-Identifier: MIT
2
3use netlink_packet_core::{
4    emit_u64, parse_u64, DecodeError, DefaultNla, ErrorContext, Nla, NlaBuffer,
5    Parseable,
6};
7
8const IFLA_VF_STATS_RX_PACKETS: u16 = 0;
9const IFLA_VF_STATS_TX_PACKETS: u16 = 1;
10const IFLA_VF_STATS_RX_BYTES: u16 = 2;
11const IFLA_VF_STATS_TX_BYTES: u16 = 3;
12const IFLA_VF_STATS_BROADCAST: u16 = 4;
13const IFLA_VF_STATS_MULTICAST: u16 = 5;
14// const IFLA_VF_STATS_PAD: u16 = 6;
15const IFLA_VF_STATS_RX_DROPPED: u16 = 7;
16const IFLA_VF_STATS_TX_DROPPED: u16 = 8;
17
18#[derive(Debug, Clone, Eq, PartialEq)]
19#[non_exhaustive]
20pub enum VfStats {
21    RxPackets(u64),
22    TxPackets(u64),
23    RxBytes(u64),
24    TxBytes(u64),
25    Broadcast(u64),
26    Multicast(u64),
27    RxDropped(u64),
28    TxDropped(u64),
29    Other(DefaultNla),
30}
31
32impl Nla for VfStats {
33    fn value_len(&self) -> usize {
34        match self {
35            Self::Other(v) => v.value_len(),
36            _ => 8,
37        }
38    }
39
40    fn emit_value(&self, buffer: &mut [u8]) {
41        match self {
42            Self::RxPackets(v)
43            | Self::TxPackets(v)
44            | Self::RxBytes(v)
45            | Self::TxBytes(v)
46            | Self::Broadcast(v)
47            | Self::Multicast(v)
48            | Self::RxDropped(v)
49            | Self::TxDropped(v) => emit_u64(buffer, *v).unwrap(),
50            Self::Other(attr) => attr.emit_value(buffer),
51        }
52    }
53
54    fn kind(&self) -> u16 {
55        match self {
56            Self::RxPackets(_) => IFLA_VF_STATS_RX_PACKETS,
57            Self::TxPackets(_) => IFLA_VF_STATS_TX_PACKETS,
58            Self::RxBytes(_) => IFLA_VF_STATS_RX_BYTES,
59            Self::TxBytes(_) => IFLA_VF_STATS_TX_BYTES,
60            Self::Broadcast(_) => IFLA_VF_STATS_BROADCAST,
61            Self::Multicast(_) => IFLA_VF_STATS_MULTICAST,
62            Self::RxDropped(_) => IFLA_VF_STATS_RX_DROPPED,
63            Self::TxDropped(_) => IFLA_VF_STATS_TX_DROPPED,
64            Self::Other(v) => v.kind(),
65        }
66    }
67}
68
69impl<'a, T: AsRef<[u8]> + ?Sized> Parseable<NlaBuffer<&'a T>> for VfStats {
70    fn parse(buf: &NlaBuffer<&'a T>) -> Result<Self, DecodeError> {
71        let payload = buf.value();
72        Ok(match buf.kind() {
73            IFLA_VF_STATS_RX_PACKETS => {
74                Self::RxPackets(parse_u64(payload).context(format!(
75                    "invalid IFLA_VF_STATS_RX_PACKETS value {payload:?}"
76                ))?)
77            }
78            IFLA_VF_STATS_TX_PACKETS => {
79                Self::TxPackets(parse_u64(payload).context(format!(
80                    "invalid IFLA_VF_STATS_TX_PACKETS value {payload:?}"
81                ))?)
82            }
83            IFLA_VF_STATS_RX_BYTES => {
84                Self::RxBytes(parse_u64(payload).context(format!(
85                    "invalid IFLA_VF_STATS_RX_BYTES value {payload:?}"
86                ))?)
87            }
88            IFLA_VF_STATS_TX_BYTES => {
89                Self::TxBytes(parse_u64(payload).context(format!(
90                    "invalid IFLA_VF_STATS_TX_BYTES value {payload:?}"
91                ))?)
92            }
93            IFLA_VF_STATS_BROADCAST => {
94                Self::Broadcast(parse_u64(payload).context(format!(
95                    "invalid IFLA_VF_STATS_BROADCAST value {payload:?}"
96                ))?)
97            }
98            IFLA_VF_STATS_MULTICAST => {
99                Self::Multicast(parse_u64(payload).context(format!(
100                    "invalid IFLA_VF_STATS_MULTICAST value {payload:?}"
101                ))?)
102            }
103            IFLA_VF_STATS_RX_DROPPED => {
104                Self::RxDropped(parse_u64(payload).context(format!(
105                    "invalid IFLA_VF_STATS_RX_DROPPED value {payload:?}"
106                ))?)
107            }
108            IFLA_VF_STATS_TX_DROPPED => {
109                Self::TxDropped(parse_u64(payload).context(format!(
110                    "invalid IFLA_VF_STATS_TX_DROPPED value {payload:?}"
111                ))?)
112            }
113            kind => Self::Other(DefaultNla::parse(buf).context(format!(
114                "failed to parse {kind} as DefaultNla: {payload:?}"
115            ))?),
116        })
117    }
118}