net: report link state to userspace
This commit is contained in:
parent
8db05f304e
commit
b8078561bf
@ -27,37 +27,6 @@ pub struct L2Packet {
|
|||||||
pub data: Arc<DmaBuffer<[u8]>>,
|
pub data: Arc<DmaBuffer<[u8]>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines an Ethernet link speed
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum EthernetSpeed {
|
|
||||||
/// 1Gbps link
|
|
||||||
Speed1000,
|
|
||||||
/// 100Mbps link
|
|
||||||
Speed100,
|
|
||||||
/// 10Mbps link
|
|
||||||
Speed10,
|
|
||||||
/// Link speed not available/unknown
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines whether an Ethernet link is capable of transmiting data both ways simultaneously
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum Duplex {
|
|
||||||
/// Half-duplex link with multiplexed Tx and Rx
|
|
||||||
Half,
|
|
||||||
/// Full-duplex link capable of simultaneous Tx and Rx
|
|
||||||
Full,
|
|
||||||
/// Duplex mode not available/unknown
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents the state of an Ethernet link
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub enum EthernetLinkState {
|
|
||||||
Up(EthernetSpeed, Duplex),
|
|
||||||
Down,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl L2Packet {
|
impl L2Packet {
|
||||||
pub fn ethernet_frame(&self) -> &EthernetFrame {
|
pub fn ethernet_frame(&self) -> &EthernetFrame {
|
||||||
bytemuck::from_bytes(
|
bytemuck::from_bytes(
|
||||||
@ -109,39 +78,3 @@ pub fn handle(packet: L2Packet) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for EthernetSpeed {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let text = match self {
|
|
||||||
Self::Speed10 => "10Mbps",
|
|
||||||
Self::Speed100 => "100Mbps",
|
|
||||||
Self::Speed1000 => "1Gbps",
|
|
||||||
Self::Unknown => "N/A",
|
|
||||||
};
|
|
||||||
f.write_str(text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Duplex {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
let text = match self {
|
|
||||||
Self::Half => "half-duplex",
|
|
||||||
Self::Full => "full-duplex",
|
|
||||||
Self::Unknown => "N/A duplex mode",
|
|
||||||
};
|
|
||||||
f.write_str(text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for EthernetLinkState {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::Up(speed, duplex) => {
|
|
||||||
write!(f, "up, speed {speed}, {duplex}")
|
|
||||||
}
|
|
||||||
Self::Down => {
|
|
||||||
write!(f, "down")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,7 +13,7 @@ use libk_util::{
|
|||||||
};
|
};
|
||||||
use yggdrasil_abi::{
|
use yggdrasil_abi::{
|
||||||
error::Error,
|
error::Error,
|
||||||
net::{protocols::EthernetFrame, MacAddress},
|
net::{link::LinkState, protocols::EthernetFrame, MacAddress},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::l3::{arp::ArpTable, Route};
|
use crate::l3::{arp::ArpTable, Route};
|
||||||
@ -25,6 +25,9 @@ pub trait NetworkDevice: Sync + Send {
|
|||||||
fn packet_prefix_size(&self) -> usize;
|
fn packet_prefix_size(&self) -> usize;
|
||||||
|
|
||||||
fn read_hardware_address(&self) -> MacAddress;
|
fn read_hardware_address(&self) -> MacAddress;
|
||||||
|
fn link_state(&self) -> LinkState {
|
||||||
|
LinkState::Other { up: true }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NetworkInterface {
|
pub struct NetworkInterface {
|
||||||
@ -101,6 +104,10 @@ impl NetworkInterface {
|
|||||||
ArpTable::insert_address(self.id, self.mac, address, true);
|
ArpTable::insert_address(self.id, self.mac, address, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn link_state(&self) -> LinkState {
|
||||||
|
self.device.link_state()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn send_l2(&self, l2_frame: &EthernetFrame, l2_data: &[u8]) -> Result<(), Error> {
|
pub fn send_l2(&self, l2_frame: &EthernetFrame, l2_data: &[u8]) -> Result<(), Error> {
|
||||||
let l2_offset = self.device.packet_prefix_size();
|
let l2_offset = self.device.packet_prefix_size();
|
||||||
let l2_data_offset = l2_offset + size_of::<EthernetFrame>();
|
let l2_data_offset = l2_offset + size_of::<EthernetFrame>();
|
||||||
|
@ -250,6 +250,7 @@ fn describe_interface(interface: &NetworkInterface) -> InterfaceInfo {
|
|||||||
interface_name: interface.name.clone(),
|
interface_name: interface.name.clone(),
|
||||||
address: interface.address.read().map(Into::into),
|
address: interface.address.read().map(Into::into),
|
||||||
mac: interface.mac,
|
mac: interface.mac,
|
||||||
|
link: interface.link_state(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ use ygg_driver_pci::{
|
|||||||
macros::pci_driver,
|
macros::pci_driver,
|
||||||
PciBaseAddress, PciCommandRegister, PciConfigurationSpace,
|
PciBaseAddress, PciCommandRegister, PciConfigurationSpace,
|
||||||
};
|
};
|
||||||
use yggdrasil_abi::net::MacAddress;
|
use yggdrasil_abi::net::{link::LinkState, MacAddress};
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
@ -369,6 +369,10 @@ impl NetworkDevice for Igbe {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn link_state(&self) -> LinkState {
|
||||||
|
LinkState::Ethernet(self.regs.lock().read_link())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_driver! {
|
pci_driver! {
|
||||||
|
@ -4,9 +4,11 @@ use core::{cell::UnsafeCell, marker::PhantomData, time};
|
|||||||
use libk::error::Error;
|
use libk::error::Error;
|
||||||
use libk_mm::{address::PhysicalAddress, device::RawDeviceMemoryMapping};
|
use libk_mm::{address::PhysicalAddress, device::RawDeviceMemoryMapping};
|
||||||
use tock_registers::{fields::FieldValue, register_bitfields, LocalRegisterCopy, RegisterLongName};
|
use tock_registers::{fields::FieldValue, register_bitfields, LocalRegisterCopy, RegisterLongName};
|
||||||
use ygg_driver_net_core::ethernet::{Duplex, EthernetLinkState, EthernetSpeed};
|
|
||||||
use ygg_driver_pci::PciBaseAddress;
|
use ygg_driver_pci::PciBaseAddress;
|
||||||
use yggdrasil_abi::net::MacAddress;
|
use yggdrasil_abi::net::{
|
||||||
|
link::{Duplex, EthernetLinkState, EthernetSpeed},
|
||||||
|
MacAddress,
|
||||||
|
};
|
||||||
use TXDCTL::LWTHRESH;
|
use TXDCTL::LWTHRESH;
|
||||||
|
|
||||||
use crate::{RxRing, TxRing};
|
use crate::{RxRing, TxRing};
|
||||||
|
@ -21,12 +21,17 @@ use tock_registers::{
|
|||||||
registers::{ReadOnly, ReadWrite, WriteOnly},
|
registers::{ReadOnly, ReadWrite, WriteOnly},
|
||||||
};
|
};
|
||||||
use ygg_driver_net_core::{
|
use ygg_driver_net_core::{
|
||||||
ethernet::{Duplex, EthernetLinkState, EthernetSpeed},
|
|
||||||
interface::{NetworkDevice, NetworkInterfaceType},
|
interface::{NetworkDevice, NetworkInterfaceType},
|
||||||
Packet,
|
Packet,
|
||||||
};
|
};
|
||||||
use ygg_driver_pci::device::{PciDeviceInfo, PreferredInterruptMode};
|
use ygg_driver_pci::device::{PciDeviceInfo, PreferredInterruptMode};
|
||||||
use yggdrasil_abi::{bitflags, net::MacAddress};
|
use yggdrasil_abi::{
|
||||||
|
bitflags,
|
||||||
|
net::{
|
||||||
|
link::{Duplex, EthernetLinkState, EthernetSpeed, LinkState},
|
||||||
|
MacAddress,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
register_bitfields! {
|
register_bitfields! {
|
||||||
u8,
|
u8,
|
||||||
@ -715,6 +720,10 @@ impl NetworkDevice for Rtl8168 {
|
|||||||
fn read_hardware_address(&self) -> MacAddress {
|
fn read_hardware_address(&self) -> MacAddress {
|
||||||
self.mac
|
self.mac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn link_state(&self) -> LinkState {
|
||||||
|
LinkState::Ethernet(self.regs.lock().get_link_state())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Revision {
|
impl Revision {
|
||||||
|
@ -70,11 +70,11 @@ impl Serialize for SocketAddrV6 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::impl_enum_serde!(IpAddr: [
|
crate::impl_enum1_serde!(IpAddr: [
|
||||||
V4 => 4,
|
V4 => 4,
|
||||||
V6 => 6
|
V6 => 6
|
||||||
]);
|
]);
|
||||||
crate::impl_enum_serde!(SocketAddr: [
|
crate::impl_enum1_serde!(SocketAddr: [
|
||||||
V4 => 4,
|
V4 => 4,
|
||||||
V6 => 6
|
V6 => 6
|
||||||
]);
|
]);
|
||||||
|
@ -20,7 +20,7 @@ pub use des::Deserialize;
|
|||||||
pub use ser::Serialize;
|
pub use ser::Serialize;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_enum_serde {
|
macro_rules! impl_enum1_serde {
|
||||||
(
|
(
|
||||||
$name:ident $(<$lifetime:lifetime>)? : [
|
$name:ident $(<$lifetime:lifetime>)? : [
|
||||||
$(
|
$(
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
/// Helper macro to define primitive enums with integer reprs, as well as their conversion methods
|
/// Helper macro to define primitive enums with integer reprs, as well as their conversion methods
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! primitive_enum {
|
macro_rules! primitive_enum {
|
||||||
($(#[$struct_meta:meta])* $vis:vis enum $name:ident: $repr:ty {
|
(
|
||||||
$( $(#[$variant_meta:meta])* $variant:ident = $discriminant:literal ),+ $(,)?
|
$(#[$struct_meta:meta])*
|
||||||
}) => {
|
$vis:vis enum $name:ident: $repr:ty {
|
||||||
|
$( $(#[$variant_meta:meta])* $variant:ident = $discriminant:literal ),+ $(,)?
|
||||||
|
}
|
||||||
|
$([ $enum_extra:tt ]),* $(,)?
|
||||||
|
) => {
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
#[repr($repr)]
|
#[repr($repr)]
|
||||||
$(#[$struct_meta])*
|
$(#[$struct_meta])*
|
||||||
@ -32,9 +36,36 @@ macro_rules! primitive_enum {
|
|||||||
v as $repr
|
v as $repr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
$crate::primitive_enum_extra!($enum_extra,
|
||||||
|
impl abi_serde::Serialize for $name {
|
||||||
|
fn serialize<S: abi_serde::ser::Serializer>(&self, serializer: &mut S) -> Result<(), <S as abi_serde::ser::Serializer>::Error> {
|
||||||
|
let repr = *self as $repr;
|
||||||
|
repr.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> abi_serde::Deserialize<'de> for $name {
|
||||||
|
fn deserialize<D: abi_serde::des::Deserializer<'de>>(deserializer: &mut D) -> Result<Self, <D as abi_serde::des::Deserializer<'de>>::Error> {
|
||||||
|
let repr = <$repr>::deserialize(deserializer)?;
|
||||||
|
Self::try_from(repr).map_err(|_| <<D as abi_serde::des::Deserializer<'de>>::Error as abi_serde::des::DeserializeError>::INVALID_ENUM_VARIANT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
)*
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! primitive_enum_extra {
|
||||||
|
(with_serde, $($inner:item)+) => {
|
||||||
|
$($inner)+
|
||||||
|
};
|
||||||
|
($any_other:ident, $($inner:item)+) => {};
|
||||||
|
}
|
||||||
|
|
||||||
/// Common implementations for bitflag definitions
|
/// Common implementations for bitflag definitions
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! bitflags_impl_common {
|
macro_rules! bitflags_impl_common {
|
||||||
|
161
lib/abi/src/net/link.rs
Normal file
161
lib/abi/src/net/link.rs
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
//! Types for handling network interface link state information
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
|
||||||
|
use abi_serde::{
|
||||||
|
des::{DeserializeError, Deserializer},
|
||||||
|
ser::Serializer,
|
||||||
|
Deserialize, Serialize,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::primitive_enum;
|
||||||
|
|
||||||
|
primitive_enum! {
|
||||||
|
/// Defines an Ethernet link speed
|
||||||
|
pub enum EthernetSpeed: u8 {
|
||||||
|
/// 1Gbps link
|
||||||
|
Speed1000 = 3,
|
||||||
|
/// 100Mbps link
|
||||||
|
Speed100 = 2,
|
||||||
|
/// 10Mbps link
|
||||||
|
Speed10 = 1,
|
||||||
|
/// Link speed not available/unknown
|
||||||
|
Unknown = 0,
|
||||||
|
}
|
||||||
|
[with_serde]
|
||||||
|
}
|
||||||
|
|
||||||
|
primitive_enum! {
|
||||||
|
/// Defines whether an Ethernet link is capable of transmiting data both ways simultaneously
|
||||||
|
pub enum Duplex: u32 {
|
||||||
|
/// Half-duplex mode
|
||||||
|
Half = 1,
|
||||||
|
/// Full-duplex mode
|
||||||
|
Full = 2,
|
||||||
|
/// Duplex mode information not available/unknown
|
||||||
|
Unknown = 0,
|
||||||
|
}
|
||||||
|
[with_serde]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the state of an Ethernet link
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
pub enum EthernetLinkState {
|
||||||
|
/// Link is up, fields indicate the link configuration
|
||||||
|
Up(EthernetSpeed, Duplex),
|
||||||
|
/// Link is down
|
||||||
|
Down,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the state of network interface's link
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum LinkState {
|
||||||
|
/// Ethernet link state
|
||||||
|
Ethernet(EthernetLinkState),
|
||||||
|
/// Any other device, just indicates whether the link is up or down
|
||||||
|
Other {
|
||||||
|
/// If `true`, the link is up
|
||||||
|
up: bool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for EthernetLinkState {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
|
||||||
|
match self {
|
||||||
|
Self::Up(speed, duplex) => {
|
||||||
|
serializer.write_u8(0x01)?;
|
||||||
|
speed.serialize(serializer)?;
|
||||||
|
duplex.serialize(serializer)
|
||||||
|
}
|
||||||
|
Self::Down => serializer.write_u8(0x00),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for LinkState {
|
||||||
|
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
|
||||||
|
match self {
|
||||||
|
Self::Ethernet(state) => {
|
||||||
|
serializer.write_u8(0xEE)?;
|
||||||
|
state.serialize(serializer)
|
||||||
|
}
|
||||||
|
Self::Other { up } => {
|
||||||
|
serializer.write_u8(0xFF)?;
|
||||||
|
up.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for EthernetLinkState {
|
||||||
|
fn deserialize<D: Deserializer<'de>>(deserializer: &mut D) -> Result<Self, D::Error> {
|
||||||
|
match deserializer.read_u8()? {
|
||||||
|
0x01 => {
|
||||||
|
let speed = EthernetSpeed::deserialize(deserializer)?;
|
||||||
|
let duplex = Duplex::deserialize(deserializer)?;
|
||||||
|
Ok(Self::Up(speed, duplex))
|
||||||
|
}
|
||||||
|
0x00 => Ok(Self::Down),
|
||||||
|
_ => Err(D::Error::INVALID_ENUM_VARIANT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for LinkState {
|
||||||
|
fn deserialize<D: Deserializer<'de>>(deserializer: &mut D) -> Result<Self, D::Error> {
|
||||||
|
match deserializer.read_u8()? {
|
||||||
|
0xEE => EthernetLinkState::deserialize(deserializer).map(Self::Ethernet),
|
||||||
|
0xFF => {
|
||||||
|
let up = bool::deserialize(deserializer)?;
|
||||||
|
Ok(Self::Other { up })
|
||||||
|
}
|
||||||
|
_ => Err(D::Error::INVALID_ENUM_VARIANT),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for EthernetSpeed {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let text = match self {
|
||||||
|
Self::Speed10 => "10Mbps",
|
||||||
|
Self::Speed100 => "100Mbps",
|
||||||
|
Self::Speed1000 => "1Gbps",
|
||||||
|
Self::Unknown => "N/A",
|
||||||
|
};
|
||||||
|
f.write_str(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Duplex {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
let text = match self {
|
||||||
|
Self::Half => "half-duplex",
|
||||||
|
Self::Full => "full-duplex",
|
||||||
|
Self::Unknown => "N/A duplex mode",
|
||||||
|
};
|
||||||
|
f.write_str(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for EthernetLinkState {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Up(speed, duplex) => {
|
||||||
|
write!(f, "up, speed {speed}, {duplex}")
|
||||||
|
}
|
||||||
|
Self::Down => {
|
||||||
|
write!(f, "down")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for LinkState {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Other { up: true } => write!(f, "up"),
|
||||||
|
Self::Other { up: false } => write!(f, "down"),
|
||||||
|
Self::Ethernet(ethernet) => fmt::Display::fmt(ethernet, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ pub mod dns;
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
pub mod netconfig;
|
pub mod netconfig;
|
||||||
|
|
||||||
|
pub mod link;
|
||||||
pub mod options;
|
pub mod options;
|
||||||
pub mod protocols;
|
pub mod protocols;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
@ -54,7 +55,7 @@ abi_serde::impl_struct_serde!(MessageHeader<'de>: [
|
|||||||
payload,
|
payload,
|
||||||
ancillary
|
ancillary
|
||||||
]);
|
]);
|
||||||
abi_serde::impl_enum_serde!(AncillaryMessage: [
|
abi_serde::impl_enum1_serde!(AncillaryMessage: [
|
||||||
File => 1
|
File => 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -80,7 +81,7 @@ impl From<u32> for SocketInterfaceQuery<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abi_serde::impl_enum_serde!(SocketInterfaceQuery<'de>: [
|
abi_serde::impl_enum1_serde!(SocketInterfaceQuery<'de>: [
|
||||||
ById => 1,
|
ById => 1,
|
||||||
ByName => 2
|
ByName => 2
|
||||||
]);
|
]);
|
||||||
|
@ -9,7 +9,7 @@ use abi_serde::{
|
|||||||
};
|
};
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
|
||||||
use super::{MacAddress, SocketInterfaceQuery, SubnetAddr};
|
use super::{link::LinkState, MacAddress, SocketInterfaceQuery, SubnetAddr};
|
||||||
|
|
||||||
/// Describes the binding between interfaces and their IDs
|
/// Describes the binding between interfaces and their IDs
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
@ -80,12 +80,15 @@ pub struct InterfaceInfo {
|
|||||||
pub address: Option<IpAddr>,
|
pub address: Option<IpAddr>,
|
||||||
/// Interface hardware address
|
/// Interface hardware address
|
||||||
pub mac: MacAddress,
|
pub mac: MacAddress,
|
||||||
|
/// Interface link status
|
||||||
|
pub link: LinkState,
|
||||||
}
|
}
|
||||||
abi_serde::impl_struct_serde!(InterfaceInfo: [
|
abi_serde::impl_struct_serde!(InterfaceInfo: [
|
||||||
interface_name,
|
interface_name,
|
||||||
interface_id,
|
interface_id,
|
||||||
address,
|
address,
|
||||||
mac
|
mac,
|
||||||
|
link
|
||||||
]);
|
]);
|
||||||
|
|
||||||
/// Describes a request to add a route to an interface
|
/// Describes a request to add a route to an interface
|
||||||
@ -155,7 +158,7 @@ pub enum NetConfigRequest<'a> {
|
|||||||
/// Query the MAC address of the specified IP
|
/// Query the MAC address of the specified IP
|
||||||
ArpQuery(ArpQueryRequest<'a>),
|
ArpQuery(ArpQueryRequest<'a>),
|
||||||
}
|
}
|
||||||
abi_serde::impl_enum_serde!(NetConfigRequest<'de>: [
|
abi_serde::impl_enum1_serde!(NetConfigRequest<'de>: [
|
||||||
ListRoutes => 1,
|
ListRoutes => 1,
|
||||||
ListInterfaces => 2,
|
ListInterfaces => 2,
|
||||||
DescribeRoutes => 3,
|
DescribeRoutes => 3,
|
||||||
|
@ -63,7 +63,7 @@ pub enum LocalSocketAddress<'a> {
|
|||||||
/// Describes an anonymous socket
|
/// Describes an anonymous socket
|
||||||
Anonymous(u64),
|
Anonymous(u64),
|
||||||
}
|
}
|
||||||
abi_serde::impl_enum_serde!(LocalSocketAddress<'de>: [
|
abi_serde::impl_enum1_serde!(LocalSocketAddress<'de>: [
|
||||||
Path => 1,
|
Path => 1,
|
||||||
Anonymous => 2,
|
Anonymous => 2,
|
||||||
]);
|
]);
|
||||||
|
@ -29,7 +29,7 @@ pub enum SubnetAddr {
|
|||||||
/// IPv4 subnetwork
|
/// IPv4 subnetwork
|
||||||
V4(SubnetV4Addr),
|
V4(SubnetV4Addr),
|
||||||
}
|
}
|
||||||
abi_serde::impl_enum_serde!(SubnetAddr: [
|
abi_serde::impl_enum1_serde!(SubnetAddr: [
|
||||||
V4 => 4
|
V4 => 4
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -227,6 +227,7 @@ pub fn run_action(section: Section) -> Result<(), Error> {
|
|||||||
fn print_interface_info(info: &InterfaceInfo) {
|
fn print_interface_info(info: &InterfaceInfo) {
|
||||||
println!("{}:", info.interface_name);
|
println!("{}:", info.interface_name);
|
||||||
println!(" Id: #{}", info.interface_id);
|
println!(" Id: #{}", info.interface_id);
|
||||||
|
println!(" Link: {}", info.link);
|
||||||
if let Some(address) = info.address {
|
if let Some(address) = info.address {
|
||||||
println!(" Address: {}", address);
|
println!(" Address: {}", address);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user