netstack3_base/device/
link.rs
1use core::fmt::Debug;
11
12use net_types::ethernet::Mac;
13use net_types::UnicastAddress;
14use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
15
16use crate::Device;
17
18pub trait LinkAddress:
20 'static
21 + FromBytes
22 + IntoBytes
23 + KnownLayout
24 + Immutable
25 + Unaligned
26 + Copy
27 + Clone
28 + Debug
29 + Eq
30 + Send
31{
32 const BYTES_LENGTH: usize;
34
35 fn bytes(&self) -> &[u8];
37
38 fn from_bytes(bytes: &[u8]) -> Self;
45}
46
47impl LinkAddress for Mac {
48 const BYTES_LENGTH: usize = 6;
49
50 fn bytes(&self) -> &[u8] {
51 self.as_ref()
52 }
53
54 fn from_bytes(bytes: &[u8]) -> Self {
55 debug_assert_eq!(bytes.len(), Self::BYTES_LENGTH);
57 let mut b = [0; Self::BYTES_LENGTH];
58 b.copy_from_slice(bytes);
59 Self::new(b)
60 }
61}
62
63pub trait LinkUnicastAddress: LinkAddress + UnicastAddress {}
65impl<L: LinkAddress + UnicastAddress> LinkUnicastAddress for L {}
66
67pub trait LinkDevice: Device + Debug {
72 type Address: LinkUnicastAddress;
74}
75
76#[cfg(any(test, feature = "testutils"))]
78pub(crate) mod testutil {
79 use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
80
81 use super::*;
82 use crate::testutil::{FakeCoreCtx, FakeStrongDeviceId, FakeWeakDeviceId};
83 use crate::{DeviceIdContext, DeviceIdentifier, StrongDeviceIdentifier};
84
85 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
87 pub enum FakeLinkDevice {}
88
89 const FAKE_LINK_ADDRESS_LEN: usize = 1;
90
91 #[derive(
95 KnownLayout,
96 FromBytes,
97 IntoBytes,
98 Immutable,
99 Unaligned,
100 Copy,
101 Clone,
102 Debug,
103 Hash,
104 PartialEq,
105 Eq,
106 )]
107 #[repr(transparent)]
108 pub struct FakeLinkAddress(pub [u8; FAKE_LINK_ADDRESS_LEN]);
109
110 impl UnicastAddress for FakeLinkAddress {
111 fn is_unicast(&self) -> bool {
112 let Self(bytes) = self;
113 bytes != &[0xff]
114 }
115 }
116
117 impl LinkAddress for FakeLinkAddress {
118 const BYTES_LENGTH: usize = FAKE_LINK_ADDRESS_LEN;
119
120 fn bytes(&self) -> &[u8] {
121 &self.0[..]
122 }
123
124 fn from_bytes(bytes: &[u8]) -> FakeLinkAddress {
125 FakeLinkAddress(bytes.try_into().unwrap())
126 }
127 }
128
129 impl Device for FakeLinkDevice {}
130
131 impl LinkDevice for FakeLinkDevice {
132 type Address = FakeLinkAddress;
133 }
134
135 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
137 pub struct FakeLinkDeviceId;
138
139 impl StrongDeviceIdentifier for FakeLinkDeviceId {
140 type Weak = FakeWeakDeviceId<Self>;
141
142 fn downgrade(&self) -> Self::Weak {
143 FakeWeakDeviceId(*self)
144 }
145 }
146
147 impl DeviceIdentifier for FakeLinkDeviceId {
148 fn is_loopback(&self) -> bool {
149 false
150 }
151 }
152
153 impl<S, M> DeviceIdContext<FakeLinkDevice> for FakeCoreCtx<S, M, FakeLinkDeviceId> {
154 type DeviceId = FakeLinkDeviceId;
155 type WeakDeviceId = FakeWeakDeviceId<FakeLinkDeviceId>;
156 }
157
158 impl FakeStrongDeviceId for FakeLinkDeviceId {
159 fn is_alive(&self) -> bool {
160 true
161 }
162 }
163
164 impl PartialEq<FakeWeakDeviceId<FakeLinkDeviceId>> for FakeLinkDeviceId {
165 fn eq(&self, FakeWeakDeviceId(other): &FakeWeakDeviceId<FakeLinkDeviceId>) -> bool {
166 self == other
167 }
168 }
169}