sysctl: add /scheme/netcfg/sysctl tree with ip_forward toggle

Router gains Rc<Cell<bool>> ip_forward flag (default: true).
When false, forward_packets() returns immediately — no packets forwarded
between interfaces. Security best practice for non-router hosts.

netcfg scheme gains sysctl subtree:
  /scheme/netcfg/sysctl/net/ipv4/ip_forward  (rw: 0 or 1)

Read:  echo /scheme/netcfg/sysctl/net/ipv4/ip_forward  →  1
Write: echo 0 > /scheme/netcfg/sysctl/net/ipv4/ip_forward  (disable)
Restore: echo 1 > /scheme/netcfg/sysctl/net/ipv4/ip_forward

Mirrors Linux /proc/sys/net/ipv4/ip_forward.
Shared via Rc<Cell<bool>> between Router and NetCfgScheme.
This commit is contained in:
Red Bear OS
2026-07-08 15:20:21 +03:00
parent 25d6decc85
commit ba5a7cd3fc
3 changed files with 40 additions and 2 deletions
+6 -1
View File
@@ -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<RefCell<DeviceList>>,
route_table: Rc<RefCell<RouteTable>>,
pub ip_forward: Rc<Cell<bool>>,
}
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<RefCell<FilterTable>>, now: Instant) {
if !self.ip_forward.get() {
return;
}
let mut forwarded: Vec<Vec<u8>> = Vec::new();
let mut local: Vec<Vec<u8>> = Vec::new();
+3
View File
@@ -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,
+31 -1
View File
@@ -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<RefCell<RouteTable>>,
devices: Rc<RefCell<DeviceList>>,
socket_set: Rc<RefCell<SocketSet>>,
ip_forward: Rc<Cell<bool>>,
) -> CfgNodeRef {
cfg_node! {
"sockets" => {
@@ -221,6 +222,33 @@ fn mk_root_node(
}
},
},
"sysctl" => {
"net" => {
"ipv4" => {
"ip_forward" => {
rw [ip_forward] (Option<bool>, None)
|| {
let val: u8 = if ip_forward.get() { 1 } else { 0 };
format!("{}\n", val)
}
|cur_value, line| {
let val = line.trim().parse::<u8>()
.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<RefCell<RouteTable>>,
devices: Rc<RefCell<DeviceList>>,
socket_set: Rc<RefCell<SocketSet>>,
ip_forward: Rc<Cell<bool>>,
) -> Result<NetCfgScheme> {
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,
};