use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::netlink::error::{Error, Result};
#[repr(C)]
#[derive(Debug, Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
pub struct IfInfoMsg {
pub ifi_family: u8,
pub __ifi_pad: u8,
pub ifi_type: u16,
pub ifi_index: i32,
pub ifi_flags: u32,
pub ifi_change: u32,
}
impl IfInfoMsg {
pub const SIZE: usize = std::mem::size_of::<Self>();
pub fn new() -> Self {
Self::default()
}
pub fn with_index(mut self, index: i32) -> Self {
self.ifi_index = index;
self
}
pub fn with_family(mut self, family: u8) -> Self {
self.ifi_family = family;
self
}
pub fn as_bytes(&self) -> &[u8] {
<Self as IntoBytes>::as_bytes(self)
}
pub fn from_bytes(data: &[u8]) -> Result<&Self> {
Self::ref_from_prefix(data)
.map(|(r, _)| r)
.map_err(|_| Error::Truncated {
expected: Self::SIZE,
actual: data.len(),
})
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
#[non_exhaustive]
pub enum IflaAttr {
Unspec = 0,
Address = 1,
Broadcast = 2,
Ifname = 3,
Mtu = 4,
Link = 5,
Qdisc = 6,
Stats = 7,
Cost = 8,
Priority = 9,
Master = 10,
Wireless = 11,
Protinfo = 12,
TxqLen = 13,
Map = 14,
Weight = 15,
Operstate = 16,
Linkmode = 17,
Linkinfo = 18,
NetNsPid = 19,
Ifalias = 20,
NumVf = 21,
VfinfoList = 22,
Stats64 = 23,
VfPorts = 24,
PortSelf = 25,
AfSpec = 26,
Group = 27,
NetNsFd = 28,
ExtMask = 29,
Promiscuity = 30,
NumTxQueues = 31,
NumRxQueues = 32,
Carrier = 33,
PhysPortId = 34,
CarrierChanges = 35,
PhysSwitchId = 36,
LinkNetnsid = 37,
PhysPortName = 38,
ProtoDown = 39,
GsoMaxSegs = 40,
GsoMaxSize = 41,
Pad = 42,
Xdp = 43,
Event = 44,
NewNetnsid = 45,
IfNetnsid = 46,
CarrierUpCount = 47,
CarrierDownCount = 48,
NewIfindex = 49,
MinMtu = 50,
MaxMtu = 51,
PropList = 52,
AltIfname = 53,
PermAddress = 54,
ProtoDownReason = 55,
ParentDevName = 56,
ParentDevBusName = 57,
GroMaxSize = 58,
TsoMaxSize = 59,
TsoMaxSegs = 60,
Allmulti = 61,
}
impl From<u16> for IflaAttr {
fn from(val: u16) -> Self {
match val {
0 => Self::Unspec,
1 => Self::Address,
2 => Self::Broadcast,
3 => Self::Ifname,
4 => Self::Mtu,
5 => Self::Link,
6 => Self::Qdisc,
7 => Self::Stats,
8 => Self::Cost,
9 => Self::Priority,
10 => Self::Master,
11 => Self::Wireless,
12 => Self::Protinfo,
13 => Self::TxqLen,
14 => Self::Map,
15 => Self::Weight,
16 => Self::Operstate,
17 => Self::Linkmode,
18 => Self::Linkinfo,
19 => Self::NetNsPid,
20 => Self::Ifalias,
21 => Self::NumVf,
22 => Self::VfinfoList,
23 => Self::Stats64,
24 => Self::VfPorts,
25 => Self::PortSelf,
26 => Self::AfSpec,
27 => Self::Group,
28 => Self::NetNsFd,
29 => Self::ExtMask,
30 => Self::Promiscuity,
31 => Self::NumTxQueues,
32 => Self::NumRxQueues,
33 => Self::Carrier,
34 => Self::PhysPortId,
35 => Self::CarrierChanges,
36 => Self::PhysSwitchId,
37 => Self::LinkNetnsid,
38 => Self::PhysPortName,
39 => Self::ProtoDown,
40 => Self::GsoMaxSegs,
41 => Self::GsoMaxSize,
42 => Self::Pad,
43 => Self::Xdp,
44 => Self::Event,
45 => Self::NewNetnsid,
46 => Self::IfNetnsid,
47 => Self::CarrierUpCount,
48 => Self::CarrierDownCount,
49 => Self::NewIfindex,
50 => Self::MinMtu,
51 => Self::MaxMtu,
52 => Self::PropList,
53 => Self::AltIfname,
54 => Self::PermAddress,
55 => Self::ProtoDownReason,
56 => Self::ParentDevName,
57 => Self::ParentDevBusName,
58 => Self::GroMaxSize,
59 => Self::TsoMaxSize,
60 => Self::TsoMaxSegs,
61 => Self::Allmulti,
_ => Self::Unspec,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u16)]
#[non_exhaustive]
pub enum IflaInfo {
Unspec = 0,
Kind = 1,
Data = 2,
Xstats = 3,
SlaveKind = 4,
SlaveData = 5,
}
impl From<u16> for IflaInfo {
fn from(val: u16) -> Self {
match val {
1 => Self::Kind,
2 => Self::Data,
3 => Self::Xstats,
4 => Self::SlaveKind,
5 => Self::SlaveData,
_ => Self::Unspec,
}
}
}
pub mod iff {
pub const UP: u32 = 1 << 0;
pub const BROADCAST: u32 = 1 << 1;
pub const DEBUG: u32 = 1 << 2;
pub const LOOPBACK: u32 = 1 << 3;
pub const POINTOPOINT: u32 = 1 << 4;
pub const NOTRAILERS: u32 = 1 << 5;
pub const RUNNING: u32 = 1 << 6;
pub const NOARP: u32 = 1 << 7;
pub const PROMISC: u32 = 1 << 8;
pub const ALLMULTI: u32 = 1 << 9;
pub const MASTER: u32 = 1 << 10;
pub const SLAVE: u32 = 1 << 11;
pub const MULTICAST: u32 = 1 << 12;
pub const PORTSEL: u32 = 1 << 13;
pub const AUTOMEDIA: u32 = 1 << 14;
pub const DYNAMIC: u32 = 1 << 15;
pub const LOWER_UP: u32 = 1 << 16;
pub const DORMANT: u32 = 1 << 17;
pub const ECHO: u32 = 1 << 18;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
#[repr(u8)]
pub enum OperState {
Unknown = 0,
NotPresent = 1,
Down = 2,
LowerLayerDown = 3,
Testing = 4,
Dormant = 5,
Up = 6,
}
impl From<u8> for OperState {
fn from(val: u8) -> Self {
match val {
0 => Self::Unknown,
1 => Self::NotPresent,
2 => Self::Down,
3 => Self::LowerLayerDown,
4 => Self::Testing,
5 => Self::Dormant,
6 => Self::Up,
_ => Self::Unknown,
}
}
}
impl OperState {
pub fn name(&self) -> &'static str {
match self {
Self::Unknown => "UNKNOWN",
Self::NotPresent => "NOT_PRESENT",
Self::Down => "DOWN",
Self::LowerLayerDown => "LOWERLAYERDOWN",
Self::Testing => "TESTING",
Self::Dormant => "DORMANT",
Self::Up => "UP",
}
}
pub fn display_name(&self) -> &'static str {
match self {
Self::Unknown => "unknown",
Self::NotPresent => "not_present",
Self::Down => "down",
Self::LowerLayerDown => "lower_layer_down",
Self::Testing => "testing",
Self::Dormant => "dormant",
Self::Up => "up",
}
}
}
impl std::fmt::Display for OperState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.display_name())
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Default, FromBytes, Immutable, KnownLayout)]
pub struct LinkStats64 {
pub rx_packets: u64,
pub tx_packets: u64,
pub rx_bytes: u64,
pub tx_bytes: u64,
pub rx_errors: u64,
pub tx_errors: u64,
pub rx_dropped: u64,
pub tx_dropped: u64,
pub multicast: u64,
pub collisions: u64,
pub rx_length_errors: u64,
pub rx_over_errors: u64,
pub rx_crc_errors: u64,
pub rx_frame_errors: u64,
pub rx_fifo_errors: u64,
pub rx_missed_errors: u64,
pub tx_aborted_errors: u64,
pub tx_carrier_errors: u64,
pub tx_fifo_errors: u64,
pub tx_heartbeat_errors: u64,
pub tx_window_errors: u64,
pub rx_compressed: u64,
pub tx_compressed: u64,
pub rx_nohandler: u64,
}
impl LinkStats64 {
pub fn from_bytes(data: &[u8]) -> Option<Self> {
Self::read_from_prefix(data).map(|(r, _)| r).ok()
}
}
pub mod bridge_af {
pub const IFLA_BRIDGE_FLAGS: u16 = 0;
pub const IFLA_BRIDGE_MODE: u16 = 1;
pub const IFLA_BRIDGE_VLAN_INFO: u16 = 2;
pub const IFLA_BRIDGE_VLAN_TUNNEL_INFO: u16 = 3;
pub const IFLA_BRIDGE_MRP: u16 = 4;
pub const IFLA_BRIDGE_CFM: u16 = 5;
pub const IFLA_BRIDGE_MST: u16 = 6;
}
pub mod bridge_vlan_tunnel {
pub const IFLA_BRIDGE_VLAN_TUNNEL_ID: u16 = 1;
pub const IFLA_BRIDGE_VLAN_TUNNEL_VID: u16 = 2;
pub const IFLA_BRIDGE_VLAN_TUNNEL_FLAGS: u16 = 3;
}
pub mod bridge_vlan_flags {
pub const MASTER: u16 = 1 << 0;
pub const PVID: u16 = 1 << 1;
pub const UNTAGGED: u16 = 1 << 2;
pub const RANGE_BEGIN: u16 = 1 << 3;
pub const RANGE_END: u16 = 1 << 4;
pub const BRENTRY: u16 = 1 << 5;
pub const ONLY_OPTS: u16 = 1 << 6;
}
#[repr(C)]
#[derive(Debug, Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
pub struct BridgeVlanInfo {
pub flags: u16,
pub vid: u16,
}
impl BridgeVlanInfo {
pub const SIZE: usize = std::mem::size_of::<Self>();
pub fn new(vid: u16) -> Self {
Self { flags: 0, vid }
}
pub fn with_flags(mut self, flags: u16) -> Self {
self.flags = flags;
self
}
pub fn is_pvid(&self) -> bool {
self.flags & bridge_vlan_flags::PVID != 0
}
pub fn is_untagged(&self) -> bool {
self.flags & bridge_vlan_flags::UNTAGGED != 0
}
pub fn is_range_begin(&self) -> bool {
self.flags & bridge_vlan_flags::RANGE_BEGIN != 0
}
pub fn is_range_end(&self) -> bool {
self.flags & bridge_vlan_flags::RANGE_END != 0
}
pub fn as_bytes(&self) -> &[u8] {
<Self as IntoBytes>::as_bytes(self)
}
pub fn from_bytes(data: &[u8]) -> Option<&Self> {
Self::ref_from_prefix(data).map(|(r, _)| r).ok()
}
}
pub mod rtext_filter {
pub const VF: u32 = 1 << 0;
pub const BRVLAN: u32 = 1 << 1;
pub const BRVLAN_COMPRESSED: u32 = 1 << 2;
pub const SKIP_STATS: u32 = 1 << 3;
pub const MRP: u32 = 1 << 4;
pub const CFM_CONFIG: u32 = 1 << 5;
pub const CFM_STATUS: u32 = 1 << 6;
pub const MST: u32 = 1 << 7;
}