netstack3_base/device/
link.rsuse core::fmt::Debug;
use net_types::ethernet::Mac;
use net_types::UnicastAddress;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
use crate::Device;
pub trait LinkAddress:
'static
+ FromBytes
+ IntoBytes
+ KnownLayout
+ Immutable
+ Unaligned
+ Copy
+ Clone
+ Debug
+ Eq
+ Send
{
const BYTES_LENGTH: usize;
fn bytes(&self) -> &[u8];
fn from_bytes(bytes: &[u8]) -> Self;
}
impl LinkAddress for Mac {
const BYTES_LENGTH: usize = 6;
fn bytes(&self) -> &[u8] {
self.as_ref()
}
fn from_bytes(bytes: &[u8]) -> Self {
debug_assert_eq!(bytes.len(), Self::BYTES_LENGTH);
let mut b = [0; Self::BYTES_LENGTH];
b.copy_from_slice(bytes);
Self::new(b)
}
}
pub trait LinkUnicastAddress: LinkAddress + UnicastAddress {}
impl<L: LinkAddress + UnicastAddress> LinkUnicastAddress for L {}
pub trait LinkDevice: Device + Debug {
type Address: LinkUnicastAddress;
}
#[cfg(any(test, feature = "testutils"))]
pub(crate) mod testutil {
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
use super::*;
use crate::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
use crate::{DeviceIdContext, DeviceIdentifier, StrongDeviceIdentifier};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum FakeLinkDevice {}
const FAKE_LINK_ADDRESS_LEN: usize = 1;
#[derive(
KnownLayout,
FromBytes,
IntoBytes,
Immutable,
Unaligned,
Copy,
Clone,
Debug,
Hash,
PartialEq,
Eq,
)]
#[repr(transparent)]
pub struct FakeLinkAddress(pub [u8; FAKE_LINK_ADDRESS_LEN]);
impl UnicastAddress for FakeLinkAddress {
fn is_unicast(&self) -> bool {
let Self(bytes) = self;
bytes != &[0xff]
}
}
impl LinkAddress for FakeLinkAddress {
const BYTES_LENGTH: usize = FAKE_LINK_ADDRESS_LEN;
fn bytes(&self) -> &[u8] {
&self.0[..]
}
fn from_bytes(bytes: &[u8]) -> FakeLinkAddress {
FakeLinkAddress(bytes.try_into().unwrap())
}
}
impl Device for FakeLinkDevice {}
impl LinkDevice for FakeLinkDevice {
type Address = FakeLinkAddress;
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct FakeLinkDeviceId;
impl StrongDeviceIdentifier for FakeLinkDeviceId {
type Weak = FakeWeakDeviceId<Self>;
fn downgrade(&self) -> Self::Weak {
FakeWeakDeviceId(*self)
}
}
impl DeviceIdentifier for FakeLinkDeviceId {
fn is_loopback(&self) -> bool {
false
}
}
impl<S, M> DeviceIdContext<FakeLinkDevice> for FakeCoreCtx<S, M, FakeLinkDeviceId> {
type DeviceId = FakeLinkDeviceId;
type WeakDeviceId = FakeWeakDeviceId<FakeLinkDeviceId>;
}
impl FakeStrongDeviceId for FakeLinkDeviceId {
fn is_alive(&self) -> bool {
true
}
}
impl PartialEq<FakeWeakDeviceId<FakeLinkDeviceId>> for FakeLinkDeviceId {
fn eq(&self, FakeWeakDeviceId(other): &FakeWeakDeviceId<FakeLinkDeviceId>) -> bool {
self == other
}
}
}