1#![allow(clippy::derivable_impls)]
8
9use alloc::{boxed::Box, string::String, vec::Vec};
10
11use spin::Mutex;
12
13use super::{MacAddress, Packet};
14use crate::error::KernelError;
15
16#[derive(Debug, Clone, Copy)]
18pub struct DeviceCapabilities {
19 pub max_transmission_unit: usize,
20 pub supports_vlan: bool,
21 pub supports_checksum_offload: bool,
22 pub supports_tso: bool, pub supports_lro: bool, }
25
26impl Default for DeviceCapabilities {
27 fn default() -> Self {
28 Self {
29 max_transmission_unit: 1500,
30 supports_vlan: false,
31 supports_checksum_offload: false,
32 supports_tso: false,
33 supports_lro: false,
34 }
35 }
36}
37
38#[derive(Debug, Clone, Copy)]
40pub struct DeviceStatistics {
41 pub rx_packets: u64,
42 pub tx_packets: u64,
43 pub rx_bytes: u64,
44 pub tx_bytes: u64,
45 pub rx_errors: u64,
46 pub tx_errors: u64,
47 pub rx_dropped: u64,
48 pub tx_dropped: u64,
49}
50
51impl Default for DeviceStatistics {
52 fn default() -> Self {
53 Self {
54 rx_packets: 0,
55 tx_packets: 0,
56 rx_bytes: 0,
57 tx_bytes: 0,
58 rx_errors: 0,
59 tx_errors: 0,
60 rx_dropped: 0,
61 tx_dropped: 0,
62 }
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub enum DeviceState {
69 Down,
70 Up,
71 Dormant,
72 Testing,
73}
74
75pub trait NetworkDevice: Send {
77 fn name(&self) -> &str;
79
80 fn mac_address(&self) -> MacAddress;
82
83 fn capabilities(&self) -> DeviceCapabilities;
85
86 fn state(&self) -> DeviceState;
88
89 fn set_state(&mut self, state: DeviceState) -> Result<(), KernelError>;
91
92 fn statistics(&self) -> DeviceStatistics;
94
95 fn transmit(&mut self, packet: &Packet) -> Result<(), KernelError>;
97
98 fn receive(&mut self) -> Result<Option<Packet>, KernelError>;
100
101 fn mtu(&self) -> usize {
103 self.capabilities().max_transmission_unit
104 }
105}
106
107pub struct LoopbackDevice {
109 name: String,
110 mac: MacAddress,
111 state: DeviceState,
112 stats: DeviceStatistics,
113 queue: Vec<Packet>,
114}
115
116impl LoopbackDevice {
117 pub fn new() -> Self {
118 Self {
119 name: String::from("lo0"),
120 mac: MacAddress([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]),
121 state: DeviceState::Down,
122 stats: DeviceStatistics::default(),
123 queue: Vec::new(),
124 }
125 }
126}
127
128impl Default for LoopbackDevice {
129 fn default() -> Self {
130 Self::new()
131 }
132}
133
134impl NetworkDevice for LoopbackDevice {
135 fn name(&self) -> &str {
136 &self.name
137 }
138
139 fn mac_address(&self) -> MacAddress {
140 self.mac
141 }
142
143 fn capabilities(&self) -> DeviceCapabilities {
144 DeviceCapabilities {
145 max_transmission_unit: 65536,
146 supports_vlan: false,
147 supports_checksum_offload: true,
148 supports_tso: false,
149 supports_lro: false,
150 }
151 }
152
153 fn state(&self) -> DeviceState {
154 self.state
155 }
156
157 fn set_state(&mut self, state: DeviceState) -> Result<(), KernelError> {
158 self.state = state;
159 Ok(())
160 }
161
162 fn statistics(&self) -> DeviceStatistics {
163 self.stats
164 }
165
166 fn transmit(&mut self, packet: &Packet) -> Result<(), KernelError> {
167 if self.state != DeviceState::Up {
168 self.stats.tx_dropped += 1;
169 return Err(KernelError::InvalidState {
170 expected: "up",
171 actual: "not_up",
172 });
173 }
174
175 self.queue.push(packet.clone());
177 self.stats.tx_packets += 1;
178 self.stats.tx_bytes += packet.len() as u64;
179
180 Ok(())
181 }
182
183 fn receive(&mut self) -> Result<Option<Packet>, KernelError> {
184 if self.state != DeviceState::Up {
185 return Ok(None);
186 }
187
188 if let Some(packet) = self.queue.pop() {
189 self.stats.rx_packets += 1;
190 self.stats.rx_bytes += packet.len() as u64;
191 Ok(Some(packet))
192 } else {
193 Ok(None)
194 }
195 }
196}
197
198pub struct EthernetDevice {
200 name: String,
201 mac: MacAddress,
202 state: DeviceState,
203 stats: DeviceStatistics,
204 capabilities: DeviceCapabilities,
205}
206
207impl EthernetDevice {
208 pub fn new(name: String, mac: MacAddress) -> Self {
209 Self {
210 name,
211 mac,
212 state: DeviceState::Down,
213 stats: DeviceStatistics::default(),
214 capabilities: DeviceCapabilities::default(),
215 }
216 }
217}
218
219impl NetworkDevice for EthernetDevice {
220 fn name(&self) -> &str {
221 &self.name
222 }
223
224 fn mac_address(&self) -> MacAddress {
225 self.mac
226 }
227
228 fn capabilities(&self) -> DeviceCapabilities {
229 self.capabilities
230 }
231
232 fn state(&self) -> DeviceState {
233 self.state
234 }
235
236 fn set_state(&mut self, state: DeviceState) -> Result<(), KernelError> {
237 self.state = state;
238 Ok(())
240 }
241
242 fn statistics(&self) -> DeviceStatistics {
243 self.stats
244 }
245
246 fn transmit(&mut self, packet: &Packet) -> Result<(), KernelError> {
247 if self.state != DeviceState::Up {
248 self.stats.tx_dropped += 1;
249 return Err(KernelError::InvalidState {
250 expected: "up",
251 actual: "not_up",
252 });
253 }
254
255 self.stats.tx_packets += 1;
257 self.stats.tx_bytes += packet.len() as u64;
258
259 Ok(())
260 }
261
262 fn receive(&mut self) -> Result<Option<Packet>, KernelError> {
263 if self.state != DeviceState::Up {
264 return Ok(None);
265 }
266
267 Ok(None)
269 }
270}
271
272static DEVICES: Mutex<Option<Vec<Box<dyn NetworkDevice>>>> = Mutex::new(None);
274
275pub fn init() -> Result<(), KernelError> {
277 println!("[NETDEV] Initializing network device subsystem...");
278
279 let mut devices_lock = DEVICES.lock();
280 let mut device_list = Vec::new();
281
282 let mut lo = LoopbackDevice::new();
284 lo.set_state(DeviceState::Up)?;
285 device_list.push(Box::new(lo) as Box<dyn NetworkDevice>);
286
287 *devices_lock = Some(device_list);
288
289 println!("[NETDEV] Network device subsystem initialized");
290 Ok(())
291}
292
293pub fn register_device(device: Box<dyn NetworkDevice>) -> Result<(), KernelError> {
295 let mut devices_lock = DEVICES.lock();
296 if let Some(ref mut devices) = *devices_lock {
297 println!("[NETDEV] Registering device: {}", device.name());
298 devices.push(device);
299 Ok(())
300 } else {
301 Err(KernelError::InvalidState {
302 expected: "initialized",
303 actual: "not_initialized",
304 })
305 }
306}
307
308pub fn with_device<R, F: FnOnce(&dyn NetworkDevice) -> R>(name: &str, f: F) -> Option<R> {
310 let devices_lock = DEVICES.lock();
311 if let Some(ref devices) = *devices_lock {
312 devices
313 .iter()
314 .find(|d| d.name() == name)
315 .map(|d| f(d.as_ref()))
316 } else {
317 None
318 }
319}
320
321pub fn with_device_mut<R, F: FnOnce(&mut dyn NetworkDevice) -> R>(name: &str, f: F) -> Option<R> {
323 let mut devices_lock = DEVICES.lock();
324 if let Some(ref mut devices) = *devices_lock {
325 devices
326 .iter_mut()
327 .find(|d| d.name() == name)
328 .map(|d| f(d.as_mut()))
329 } else {
330 None
331 }
332}
333
334pub fn list_devices() -> Vec<String> {
336 let devices_lock = DEVICES.lock();
337 if let Some(ref devices) = *devices_lock {
338 devices.iter().map(|d| String::from(d.name())).collect()
339 } else {
340 Vec::new()
341 }
342}
343
344#[cfg(test)]
345mod tests {
346 use super::*;
347
348 #[test]
349 fn test_loopback_device() {
350 let mut lo = LoopbackDevice::new();
351 assert_eq!(lo.state(), DeviceState::Down);
352
353 lo.set_state(DeviceState::Up).unwrap();
354 assert_eq!(lo.state(), DeviceState::Up);
355 }
356
357 #[test]
358 fn test_device_capabilities() {
359 let caps = DeviceCapabilities::default();
360 assert_eq!(caps.max_transmission_unit, 1500);
361 assert!(!caps.supports_vlan);
362 }
363}