mod.rs 4.63 KB
Newer Older
1
2
3
4
5
6
7
// Copyright (c) 2019 Stefan Lankes, RWTH Aachen University
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

Stefan Lankes's avatar
Stefan Lankes committed
8
pub mod rtl8139;
9
pub mod uhyve;
10

11
12
use smoltcp::iface::EthernetInterface;
use smoltcp::phy::Device;
13
14
use smoltcp::socket::SocketSet;
use smoltcp::time::Instant;
Stefan Lankes's avatar
Stefan Lankes committed
15
16
17
//use smoltcp::wire::{IpCidr, Ipv4Address, Ipv4Cidr};
//use smoltcp::socket::{RawSocketBuffer, RawPacketMetadata};
//use smoltcp::dhcp::Dhcpv4Client;
18

19
use scheduler::task::TaskId;
20
use synch::semaphore::*;
21
22
23
24
25

static NET_SEM: Semaphore = Semaphore::new(0);
static mut NETWORK_TASK_ID: TaskId = TaskId::from(0);

pub fn get_network_task_id() -> TaskId {
26
	unsafe { NETWORK_TASK_ID }
27
28
}

Stefan Lankes's avatar
Stefan Lankes committed
29
30
31
/*pub fn networkd_with_dhcp<'b, 'c, 'e, DeviceT: for<'d> Device<'d>, F>(iface: &mut EthernetInterface<'b, 'c, 'e, DeviceT>, is_polling: F) -> !
	where F: Fn() -> bool {
	let dhcp_rx_buffer = RawSocketBuffer::new(
32
33
34
35
36
37
38
		[RawPacketMetadata::EMPTY; 1],
		vec![0; 900]
	);
	let dhcp_tx_buffer = RawSocketBuffer::new(
		[RawPacketMetadata::EMPTY; 1],
		vec![0; 600]
	);
39
40
41
	let mut sockets = SocketSet::new(vec![]);
	let boot_time = crate::arch::get_boot_time();
	let mut counter: usize = 0;
Stefan Lankes's avatar
Stefan Lankes committed
42
43
44
	let microseconds = ::arch::processor::get_timer_ticks() - boot_time;
	let timestamp = Instant::from_millis(microseconds as i64 / 1000i64);
	let mut dhcp = Dhcpv4Client::new(&mut sockets, dhcp_rx_buffer, dhcp_tx_buffer, timestamp);
45
	let mut prev_cidr = Ipv4Cidr::new(Ipv4Address::UNSPECIFIED, 0);
46
47
48
49

	loop {
		let microseconds = ::arch::processor::get_timer_ticks() - boot_time;
		let timestamp = Instant::from_millis(microseconds as i64 / 1000i64);
50
51
52
53
54
55
56
57
		iface.poll(&mut sockets, timestamp)
			.map(|_| {trace!("receive message {}", counter); counter = counter+1;})
			.unwrap_or_else(|e| info!("Poll: {:?}", e));
		let config = dhcp.poll(iface, &mut sockets, timestamp)
			.unwrap_or_else(|e| {
				debug!("DHCP: {:?}", e);
				None
			});
Stefan Lankes's avatar
Stefan Lankes committed
58
		config.map(|config| {
59
60
61
62
63
64
65
66
67
68
69
70
71
72
			info!("DHCP config: {:?}", config);
			match config.address {
				Some(cidr) => if cidr != prev_cidr {
					iface.update_ip_addrs(|addrs| {
						addrs.iter_mut().nth(0)
							.map(|addr| {
								*addr = IpCidr::Ipv4(cidr);
							});
					});
					prev_cidr = cidr;
					info!("Assigned a new IPv4 address: {}", cidr);
				}
				_ => {}
			}
73

74
75
76
77
78
79
80
81
82
83
84
			config.router.map(|router| iface.routes_mut()
							  .add_default_ipv4_route(router.into())
							  .unwrap()
			);
			iface.routes_mut()
				.update(|routes_map| {
					routes_map.get(&IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 0))
						.map(|default_route| {
							info!("Default gateway: {}", default_route.via_router);
						});
				});
Stefan Lankes's avatar
Stefan Lankes committed
85

86
87
88
89
90
91
92
			if config.dns_servers.iter().any(|s| s.is_some()) {
				info!("DNS servers:");
				for dns_server in config.dns_servers.iter().filter_map(|s| *s) {
					info!("- {}", dns_server);
				}
			}
		});
Stefan Lankes's avatar
Stefan Lankes committed
93
94
95
96

		if is_polling() == false {
			let mut timeout = dhcp.next_poll(timestamp);
			iface.poll_delay(&sockets, timestamp)
97
				.map(|sockets_timeout| timeout = sockets_timeout);
Stefan Lankes's avatar
Stefan Lankes committed
98
99
100
			debug!("networkd timeout {}", timeout.millis());

			// Calculate the absolute wakeup time in processor timer ticks out of the relative timeout in milliseconds.
101
102
103
104
105
			let wakeup_time = if timeout.millis() > 0  {
				Some(::arch::processor::get_timer_ticks() + (timeout.millis() as u64) * 1000)
			} else {
				Some(::arch::processor::get_timer_ticks() + 100)
			};
Stefan Lankes's avatar
Stefan Lankes committed
106
			NET_SEM.acquire(wakeup_time);
107
		}
Stefan Lankes's avatar
Stefan Lankes committed
108
109
	}
}*/
110

111
112
113
114
115
116
117
pub fn networkd<'b, 'c, 'e, DeviceT: for<'d> Device<'d>, F>(
	iface: &mut EthernetInterface<'b, 'c, 'e, DeviceT>,
	is_polling: F,
) -> !
where
	F: Fn() -> bool,
{
Stefan Lankes's avatar
Stefan Lankes committed
118
119
120
121
122
123
124
125
	let mut sockets = SocketSet::new(vec![]);
	let boot_time = crate::arch::get_boot_time();
	let mut counter: usize = 0;

	loop {
		let microseconds = ::arch::processor::get_timer_ticks() - boot_time;
		let timestamp = Instant::from_millis(microseconds as i64 / 1000i64);

126
127
128
129
		iface
			.poll(&mut sockets, timestamp)
			.map(|_| {
				trace!("receive message {}", counter);
130
				counter += 1;
131
132
133
			})
			.unwrap_or_else(|e| debug!("Poll: {:?}", e));

134
		if !is_polling() {
Stefan Lankes's avatar
Stefan Lankes committed
135
136
137
			let wakeup_time = match iface.poll_delay(&sockets, timestamp) {
				Some(duration) => {
					// Calculate the absolute wakeup time in processor timer ticks out of the relative timeout in milliseconds.
138
139
140
141
142
143
144
145
146
					if duration.millis() > 0 {
						Some(
							::arch::processor::get_timer_ticks()
								+ (duration.millis() as u64) * 1000,
						)
					} else {
						Some(::arch::processor::get_timer_ticks() + 100)
					}
				}
Stefan Lankes's avatar
Stefan Lankes committed
147
148
149
150
				None => None,
			};
			NET_SEM.acquire(wakeup_time);
		}
151
	}
152
}