140 lines
3.2 KiB
Rust
Raw Normal View History

#![feature(map_try_insert)]
#![no_std]
extern crate alloc;
use core::{
fmt,
future::Future,
mem::size_of,
net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4},
pin::Pin,
str::FromStr,
sync::atomic::{AtomicU32, Ordering},
task::{Context, Poll},
};
use alloc::{collections::BTreeMap, format, string::String, vec::Vec};
use ethernet::{EtherType, EthernetFrame, L2Packet};
use interface::{NetworkDevice, NetworkInterface};
use kernel_fs::devfs;
use kernel_util::{
mem::PageBox,
runtime::{self, QueueWaker},
sync::{mutex::Mutex, spin_rwlock::IrqSafeRwLock, IrqSafeSpinlock},
util::ring::RingBuffer,
};
use l3::{ip::Protocol, L3Packet, Route};
use queue::Queue;
use socket::UdpSocket;
use types::{MacAddress, NetValue, SubnetAddress, Value};
use vfs::{impls::FnValueNode, PacketSocket};
use yggdrasil_abi::error::Error;
use crate::types::SubnetV4Address;
pub mod ethernet;
pub mod l3;
pub mod l4;
pub mod socket;
pub mod interface;
pub mod queue;
pub mod types;
pub use interface::register_interface;
pub struct Packet {
// TODO info about "received" interface
buffer: PageBox<[u8]>,
offset: usize,
iface: u32,
}
impl Packet {
#[inline]
pub fn new(buffer: PageBox<[u8]>, offset: usize, iface: u32) -> Self {
Self {
buffer,
offset,
iface,
}
}
}
static PACKET_QUEUE: Queue<Packet> = Queue::new();
static ACCEPT_QUEUE: Queue<L3Packet> = Queue::new();
#[inline]
pub fn receive_packet(packet: Packet) -> Result<(), Error> {
PACKET_QUEUE.receive_packet(packet)
}
pub fn start_network_tasks() -> Result<(), Error> {
devfs::add_network_config(
"routes",
FnValueNode::new(
|| {
let mut output = String::new();
l3::list_routes(|route| {
output.push_str(&format!("{}\n", route));
});
Ok(output)
},
|_value| Err(Error::NotImplemented),
),
);
runtime::spawn(l2_packet_handler_worker())?;
for _ in 0..1 {
runtime::spawn(l3_accept_worker())?;
}
Ok(())
}
async fn l2_packet_handler_worker() {
loop {
let packet = PACKET_QUEUE.wait().await;
let eth_frame: &EthernetFrame = bytemuck::from_bytes(
&packet.buffer[packet.offset..packet.offset + size_of::<EthernetFrame>()],
);
let l2_packet = L2Packet {
interface_id: packet.iface,
source_address: eth_frame.source_mac,
destination_address: eth_frame.destination_mac,
l2_offset: packet.offset,
l3_offset: packet.offset + size_of::<EthernetFrame>(),
data: packet.buffer,
};
ethernet::handle(l2_packet);
}
}
async fn l3_accept_worker() {
loop {
let l3_packet = ACCEPT_QUEUE.wait().await;
log::debug!(
"INPUT {:?} {}:{:?} -> {}:{:?}: ACCEPT",
l3_packet.protocol,
l3_packet.source_address,
l3_packet.source_port,
l3_packet.destination_address,
l3_packet.destination_port
);
if let Err(error) = l3::handle_accepted(l3_packet) {
log::error!("L3 handle error: {:?}", error);
}
}
}