Add Interface struct wrapping smoltcp iface

This commit is contained in:
Vincent Ollivier 2022-05-04 19:02:21 +02:00
parent 03de98381d
commit ede7d5d0c9
7 changed files with 68 additions and 65 deletions

View File

@ -16,10 +16,12 @@ use spin::Mutex;
mod rtl8139;
mod pcnet;
pub type Interface = smoltcp::iface::Interface<'static, EthernetDevice>;
pub struct Interface {
pub iface: smoltcp::iface::Interface<'static, EthernetDevice>,
}
lazy_static! {
pub static ref IFACE: Mutex<Option<Interface>> = Mutex::new(None);
pub static ref INTERFACE: Mutex<Option<Interface>> = Mutex::new(None);
}
#[derive(Clone)]
@ -228,8 +230,9 @@ pub fn init() {
builder = builder.hardware_addr(mac.into()).neighbor_cache(neighbor_cache);
}
let iface = builder.finalize();
let interface = Interface { iface };
*IFACE.lock() = Some(iface);
*INTERFACE.lock() = Some(interface);
}
};

View File

@ -18,9 +18,9 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
}
}
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
let dhcp_socket = Dhcpv4Socket::new();
let dhcp_handle = iface.add_socket(dhcp_socket);
let dhcp_handle = interface.iface.add_socket(dhcp_socket);
if verbose {
debug!("DHCP Discover transmitted");
}
@ -29,21 +29,21 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
loop {
if syscall::realtime() - started > timeout {
error!("Timeout reached");
iface.remove_socket(dhcp_handle);
interface.iface.remove_socket(dhcp_handle);
return usr::shell::ExitCode::CommandError;
}
if sys::console::end_of_text() {
eprintln!();
iface.remove_socket(dhcp_handle);
interface.iface.remove_socket(dhcp_handle);
return usr::shell::ExitCode::CommandError;
}
let timestamp = Instant::from_micros((syscall::realtime() * 1000000.0) as i64);
if let Err(e) = iface.poll(timestamp) {
if let Err(e) = interface.iface.poll(timestamp) {
error!("Network Error: {}", e);
}
let event = iface.get_socket::<Dhcpv4Socket>(dhcp_handle).poll();
let event = interface.iface.get_socket::<Dhcpv4Socket>(dhcp_handle).poll();
match event {
None => {}
Some(Dhcpv4Event::Configured(config)) => {
@ -51,14 +51,14 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
if verbose {
debug!("DHCP Offer received");
}
iface.remove_socket(dhcp_handle);
interface.iface.remove_socket(dhcp_handle);
break;
}
Some(Dhcpv4Event::Deconfigured) => {
}
}
if let Some(wait_duration) = iface.poll_delay(timestamp) {
if let Some(wait_duration) = interface.iface.poll_delay(timestamp) {
syscall::sleep((wait_duration.total_micros() as f64) / 1000000.0);
}
}
@ -72,10 +72,10 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
usr::net::main(&["net", "config", "ip"]);
if let Some(router) = config.router {
//iface.routes_mut().add_default_ipv4_route(router).unwrap();
//interface.iface.routes_mut().add_default_ipv4_route(router).unwrap();
usr::net::main(&["net", "config", "gw", &router.to_string()]);
} else {
//iface.routes_mut().remove_default_ipv4_route();
//interface.iface.routes_mut().remove_default_ipv4_route();
usr::net::main(&["net", "config", "gw", ""]);
}
usr::net::main(&["net", "config", "gw"]);

View File

@ -153,8 +153,8 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
#[derive(Debug)]
enum State { Bind, Query, Response }
let mut state = State::Bind;
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
match iface.ipv4_addr() {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
match interface.iface.ipv4_addr() {
None => {
return Err(ResponseCode::NetworkError);
}
@ -164,21 +164,21 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
_ => {}
}
let udp_handle = iface.add_socket(udp_socket);
let udp_handle = interface.iface.add_socket(udp_socket);
let timeout = 5.0;
let started = syscall::realtime();
loop {
if syscall::realtime() - started > timeout {
iface.remove_socket(udp_handle);
interface.iface.remove_socket(udp_handle);
return Err(ResponseCode::NetworkError);
}
let timestamp = Instant::from_micros((syscall::realtime() * 1000000.0) as i64);
if let Err(e) = iface.poll(timestamp) {
if let Err(e) = interface.iface.poll(timestamp) {
error!("Network Error: {}", e);
}
let socket = iface.get_socket::<UdpSocket>(udp_handle);
let socket = interface.iface.get_socket::<UdpSocket>(udp_handle);
state = match state {
State::Bind if !socket.is_open() => {
@ -193,7 +193,7 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
let (data, _) = socket.recv().expect("cannot receive");
let message = Message::from(data);
if message.id() == query.id() && message.is_response() {
iface.remove_socket(udp_handle);
interface.iface.remove_socket(udp_handle);
return match message.rcode() {
ResponseCode::NoError => {
// TODO: Parse the datagram instead of
@ -214,7 +214,7 @@ pub fn resolve(name: &str) -> Result<IpAddress, ResponseCode> {
_ => state
};
if let Some(wait_duration) = iface.poll_delay(timestamp) {
if let Some(wait_duration) = interface.iface.poll_delay(timestamp) {
syscall::sleep((wait_duration.total_micros() as f64) / 1000000.0);
}

View File

@ -108,8 +108,8 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
enum State { Connect, Request, Response }
let mut state = State::Connect;
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
let tcp_handle = iface.add_socket(tcp_socket);
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
let tcp_handle = interface.iface.add_socket(tcp_socket);
let mut is_header = true;
let timeout = 5.0;
@ -117,20 +117,20 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
loop {
if syscall::realtime() - started > timeout {
error!("Timeout reached");
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
return usr::shell::ExitCode::CommandError;
}
if sys::console::end_of_text() {
eprintln!(); // FIXME
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
return usr::shell::ExitCode::CommandError;
}
let timestamp = Instant::from_micros((syscall::realtime() * 1000000.0) as i64);
if let Err(e) = iface.poll(timestamp) {
if let Err(e) = interface.iface.poll(timestamp) {
error!("Network Error: {}", e);
}
let (socket, cx) = iface.get_socket_and_context::<TcpSocket>(tcp_handle);
let (socket, cx) = interface.iface.get_socket_and_context::<TcpSocket>(tcp_handle);
state = match state {
State::Connect if !socket.is_active() => {
@ -142,7 +142,7 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
}
if socket.connect(cx, (address, url.port), local_port).is_err() {
error!("Could not connect to {}:{}", address, url.port);
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
return usr::shell::ExitCode::CommandError;
}
State::Request
@ -201,11 +201,11 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
_ => state
};
if let Some(wait_duration) = iface.poll_delay(timestamp) {
if let Some(wait_duration) = interface.iface.poll_delay(timestamp) {
syscall::sleep((wait_duration.total_micros() as f64) / 1000000.0);
}
}
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
println!();
usr::shell::ExitCode::CommandSuccessful
} else {

View File

@ -17,29 +17,29 @@ pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
let csi_reset = Style::reset();
let port = 80;
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
println!("{}HTTP Server listening on 0.0.0.0:{}{}", csi_color, port, csi_reset);
let mtu = iface.device().capabilities().max_transmission_unit;
let mtu = interface.iface.device().capabilities().max_transmission_unit;
let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; mtu]);
let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; mtu]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
let tcp_handle = iface.add_socket(tcp_socket);
let tcp_handle = interface.iface.add_socket(tcp_socket);
let mut send_queue: VecDeque<Vec<u8>> = VecDeque::new();
loop {
if sys::console::end_of_text() {
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
println!();
return usr::shell::ExitCode::CommandSuccessful;
}
let timestamp = Instant::from_micros((syscall::realtime() * 1000000.0) as i64);
if let Err(e) = iface.poll(timestamp) {
if let Err(e) = interface.iface.poll(timestamp) {
error!("Network Error: {}", e);
}
let socket = iface.get_socket::<TcpSocket>(tcp_handle);
let socket = interface.iface.get_socket::<TcpSocket>(tcp_handle);
if !socket.is_open() {
socket.listen(port).unwrap();
@ -175,7 +175,7 @@ pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
socket.close();
send_queue.clear();
}
if let Some(wait_duration) = iface.poll_delay(timestamp) {
if let Some(wait_duration) = interface.iface.poll_delay(timestamp) {
syscall::sleep((wait_duration.total_micros() as f64) / 1000000.0);
}
}

View File

@ -40,8 +40,8 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
}
/*
"stat" => {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
let stats = iface.device().stats.clone();
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
let stats = interface.iface.device().stats.clone();
let csi_color = Style::color("LightCyan");
let csi_reset = Style::reset();
println!("{}rx:{} {} packets ({} bytes)", csi_color, csi_reset, stats.rx_packets_count(), stats.rx_bytes_count());
@ -51,14 +51,14 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
}
}
"monitor" => {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
iface.device_mut().debug_mode = true;
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
interface.iface.device_mut().debug_mode = true;
let mtu = iface.device().capabilities().max_transmission_unit;
let mtu = interface.iface.device().capabilities().max_transmission_unit;
let tcp_rx_buffer = TcpSocketBuffer::new(vec![0; mtu]);
let tcp_tx_buffer = TcpSocketBuffer::new(vec![0; mtu]);
let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer);
let tcp_handle = iface.add_socket(tcp_socket);
let tcp_handle = interface.iface.add_socket(tcp_socket);
loop {
if sys::console::end_of_text() {
@ -68,11 +68,11 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
syscall::sleep(0.1);
let timestamp = Instant::from_micros((syscall::realtime() * 1000000.0) as i64);
if let Err(e) = iface.poll(timestamp) {
if let Err(e) = interface.iface.poll(timestamp) {
error!("Network Error: {}", e);
}
let socket = iface.get_socket::<TcpSocket>(tcp_handle);
let socket = interface.iface.get_socket::<TcpSocket>(tcp_handle);
if socket.may_recv() {
socket.recv(|buffer| {
let recvd_len = buffer.len();
@ -136,16 +136,16 @@ const DNS_FILE: &str = "/ini/dns";
pub fn get_config(attribute: &str) -> Option<String> {
match attribute {
"mac" => {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
return Some(iface.hardware_addr().to_string());
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
return Some(interface.iface.hardware_addr().to_string());
} else {
error!("Network error");
}
None
}
"ip" => {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
if let Some(ip_cidr) = iface.ip_addrs().iter().next() {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
if let Some(ip_cidr) = interface.iface.ip_addrs().iter().next() {
return Some(format!("{}/{}", ip_cidr.address(), ip_cidr.prefix_len()));
}
} else {
@ -155,8 +155,8 @@ pub fn get_config(attribute: &str) -> Option<String> {
}
"gw" => {
let mut res = None;
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
iface.routes_mut().update(|storage| {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
interface.iface.routes_mut().update(|storage| {
if let Some((_, route)) = storage.iter().next() {
res = Some(route.via_router.to_string());
}
@ -191,8 +191,8 @@ pub fn set_config(attribute: &str, value: &str) {
match attribute {
/*
"debug" => {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
iface.device_mut().debug_mode = match value {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
interface.iface.device_mut().debug_mode = match value {
"1" | "true" => true,
"0" | "false" => false,
_ => {
@ -207,8 +207,8 @@ pub fn set_config(attribute: &str, value: &str) {
*/
"ip" => {
if let Ok(ip) = IpCidr::from_str(value) {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
iface.update_ip_addrs(|addrs| {
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
interface.iface.update_ip_addrs(|addrs| {
if let Some(addr) = addrs.iter_mut().next() {
*addr = ip;
}
@ -222,8 +222,8 @@ pub fn set_config(attribute: &str, value: &str) {
}
"gw" => {
if let Ok(ip) = Ipv4Address::from_str(value) {
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
iface.routes_mut().add_default_ipv4_route(ip).unwrap();
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
interface.iface.routes_mut().add_default_ipv4_route(ip).unwrap();
} else {
error!("Network error");
}

View File

@ -54,28 +54,28 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
enum State { Connect, Request, Response }
let mut state = State::Connect;
if let Some(ref mut iface) = *sys::net::IFACE.lock() {
let tcp_handle = iface.add_socket(tcp_socket);
if let Some(ref mut interface) = *sys::net::INTERFACE.lock() {
let tcp_handle = interface.iface.add_socket(tcp_socket);
let timeout = 5.0;
let started = syscall::realtime();
loop {
if syscall::realtime() - started > timeout {
error!("Timeout reached");
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
return usr::shell::ExitCode::CommandError;
}
if sys::console::end_of_text() {
eprintln!();
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
return usr::shell::ExitCode::CommandError;
}
let timestamp = Instant::from_micros((syscall::realtime() * 1000000.0) as i64);
if let Err(e) = iface.poll(timestamp) {
if let Err(e) = interface.iface.poll(timestamp) {
error!("Network Error: {}", e);
}
let (socket, cx) = iface.get_socket_and_context::<TcpSocket>(tcp_handle);
let (socket, cx) = interface.iface.get_socket_and_context::<TcpSocket>(tcp_handle);
state = match state {
State::Connect if !socket.is_active() => {
@ -109,11 +109,11 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
_ => state
};
if let Some(wait_duration) = iface.poll_delay(timestamp) {
if let Some(wait_duration) = interface.iface.poll_delay(timestamp) {
syscall::sleep((wait_duration.total_micros() as f64) / 1000000.0);
}
}
iface.remove_socket(tcp_handle);
interface.iface.remove_socket(tcp_handle);
usr::shell::ExitCode::CommandSuccessful
} else {
usr::shell::ExitCode::CommandError