netlink_packet_route/link/sriov/
stats.rs1use 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;
14const 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}