nixos/network-interfaces: don't write net.ipv4.conf.all.forwarding=0

This key is an alias for net.ipv4.ip_forward. The kernel default is
already 0, so emitting `=0` from sysctl.d is at best a no-op.

It is actively harmful when systemd-networkd manages forwarding via
`networkd.conf [Network] IPv4Forwarding=yes`: on a cold boot
systemd-sysctl runs before networkd and networkd's write wins, but on
a `nixos-rebuild switch` that restarts both services (any systemd
package change does, since kernel.poweroff_cmd in 60-nixos.conf
follows the systemd store path) the ordering is undefined and sysctl
can run last, silently flipping a router back to ip_forward=0.

Only emit the sysctl when at least one interface has proxyARP=true,
matching every other in-tree setter of this key (nat, docker,
tailscale, netbird, ...) which only ever write `true`. The previous
value was already mkDefault, so nothing could have been relying on it
to force forwarding off anyway.
This commit is contained in:
r-vdp
2026-04-13 20:05:44 +02:00
parent 4317660021
commit f7f9148111
+3 -1
View File
@@ -1780,7 +1780,9 @@ in
optionalString hasBonds "options bonding max_bonds=0";
boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
# Only set when proxyARP needs it; never write =0 (the kernel default),
# which would race with systemd-networkd's IPv4Forwarding= on switch.
"net.ipv4.conf.all.forwarding" = mkIf (any (i: i.proxyARP) interfaces) (mkDefault true);
"net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6);
"net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
# allow all users to do ICMP echo requests (ping)