diff --git a/netstack/src/router/mod.rs b/netstack/src/router/mod.rs index 5e9dbc0b76..56c8a2a8a9 100644 --- a/netstack/src/router/mod.rs +++ b/netstack/src/router/mod.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::rc::Rc; use smoltcp::phy::{Device, DeviceCapabilities, Medium}; @@ -21,6 +21,7 @@ pub struct Router { tx_buffer: PacketBuffer, devices: Rc>, route_table: Rc>, + pub ip_forward: Rc>, } impl Router { @@ -38,6 +39,7 @@ impl Router { tx_buffer, devices, route_table, + ip_forward: Rc::new(Cell::new(true)), } } @@ -93,6 +95,9 @@ impl Router { } pub fn forward_packets(&mut self, filter_table: &Rc>, now: Instant) { + if !self.ip_forward.get() { + return; + } let mut forwarded: Vec> = Vec::new(); let mut local: Vec> = Vec::new(); diff --git a/netstack/src/scheme/mod.rs b/netstack/src/scheme/mod.rs index 9dff56271e..d2f641b9e1 100644 --- a/netstack/src/scheme/mod.rs +++ b/netstack/src/scheme/mod.rs @@ -116,6 +116,8 @@ impl Smolnetd { |_timestamp, printer| trace!("{}", printer), ); + let ip_forward = network_device.get_mut().ip_forward.clone(); + let config = Config::new(HardwareAddress::Ip); let mut iface = SmoltcpInterface::new(config, &mut network_device, Instant::now()); iface.update_ip_addrs(|ip_addrs| ip_addrs.extend(protocol_addrs)); @@ -190,6 +192,7 @@ impl Smolnetd { Rc::clone(&route_table), Rc::clone(&devices), Rc::clone(&socket_set), + ip_forward, )?, netfilter_scheme: NetFilterScheme::new( netfilter_file, diff --git a/netstack/src/scheme/netcfg/mod.rs b/netstack/src/scheme/netcfg/mod.rs index 038da7e625..0e8da29785 100644 --- a/netstack/src/scheme/netcfg/mod.rs +++ b/netstack/src/scheme/netcfg/mod.rs @@ -8,7 +8,7 @@ use redox_scheme::{ }; use scheme_utils::HandleMap; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address, Ipv6Address}; -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::collections::BTreeMap; use std::mem; use std::rc::Rc; @@ -101,6 +101,7 @@ fn mk_root_node( route_table: Rc>, devices: Rc>, socket_set: Rc>, + ip_forward: Rc>, ) -> CfgNodeRef { cfg_node! { "sockets" => { @@ -221,6 +222,33 @@ fn mk_root_node( } }, }, + "sysctl" => { + "net" => { + "ipv4" => { + "ip_forward" => { + rw [ip_forward] (Option, None) + || { + let val: u8 = if ip_forward.get() { 1 } else { 0 }; + format!("{}\n", val) + } + |cur_value, line| { + let val = line.trim().parse::() + .map_err(|_| SyscallError::new(syscall::EINVAL))?; + match val { + 0 => { ip_forward.set(false); } + 1 => { ip_forward.set(true); } + _ => return Err(SyscallError::new(syscall::EINVAL)), + } + *cur_value = Some(val == 1); + Ok(()) + } + |_cur_value| { + Ok(()) + } + } + } + } + }, "ifaces" => { "eth0" => { "mac" => { @@ -484,6 +512,7 @@ impl NetCfgScheme { route_table: Rc>, devices: Rc>, socket_set: Rc>, + ip_forward: Rc>, ) -> Result { let notifier = Notifier::new_ref(); let dns_config = Rc::new(RefCell::new(DNSConfig { @@ -500,6 +529,7 @@ impl NetCfgScheme { route_table, devices, socket_set, + ip_forward, ), notifier, };