forked from arceos-org/arceos
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathloopback.rs
More file actions
90 lines (78 loc) · 2.09 KB
/
loopback.rs
File metadata and controls
90 lines (78 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use alloc::vec;
use core::{net::Ipv4Addr, task::Waker};
use axpoll::PollSet;
use smoltcp::{
storage::{PacketBuffer, PacketMetadata},
time::Instant,
wire::IpAddress,
};
use crate::{
consts::{SOCKET_BUFFER_SIZE, STANDARD_MTU},
device::{Device, DeviceFlags, DeviceType},
};
pub struct LoopbackDevice {
index: u32,
buffer: PacketBuffer<'static, ()>,
poll: PollSet,
}
impl LoopbackDevice {
pub fn new(index: u32) -> Self {
let buffer = PacketBuffer::new(
vec![PacketMetadata::EMPTY; SOCKET_BUFFER_SIZE],
vec![0u8; STANDARD_MTU * SOCKET_BUFFER_SIZE],
);
Self {
index,
buffer,
poll: PollSet::new(),
}
}
}
impl Device for LoopbackDevice {
fn name(&self) -> &str {
"lo"
}
fn get_type(&self) -> DeviceType {
DeviceType::LOOPBACK
}
fn get_flags(&self) -> DeviceFlags {
DeviceFlags::UP | DeviceFlags::LOOPBACK | DeviceFlags::RUNNING
}
fn get_index(&self) -> u32 {
self.index
}
fn ipv4_addr(&self) -> Option<Ipv4Addr> {
Some(Ipv4Addr::new(127, 0, 0, 1))
}
fn prefix_len(&self) -> Option<u8> {
Some(8)
}
fn recv(&mut self, buffer: &mut PacketBuffer<()>, _timestamp: Instant) -> bool {
self.buffer.dequeue().ok().is_some_and(|(_, rx_buf)| {
buffer
.enqueue(rx_buf.len(), ())
.unwrap()
.copy_from_slice(rx_buf);
true
})
}
fn send(&mut self, next_hop: IpAddress, packet: &[u8], _timestamp: Instant) -> bool {
match self.buffer.enqueue(packet.len(), ()) {
Ok(tx_buf) => {
tx_buf.copy_from_slice(packet);
self.poll.wake();
true
}
Err(_) => {
warn!(
"Loopback device buffer is full, dropping packet to {}",
next_hop
);
false
}
}
}
fn register_waker(&self, waker: &Waker) {
self.poll.register(waker);
}
}