From 952e06aa46b66ec02274a2dc3c3b4d5f1ec988a9 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 15 Apr 2024 08:55:17 -0700 Subject: [PATCH] wgengine/router: don't attempt route cleanup on Synology Trying to run iptables/nftables on Synology pauses for minutes with lots of errors and ultimately does nothing as it's not used and we lack permissions. This fixes a regression from db760d0bacd351a77f4 (#11601) that landed between Synology testing on unstable 1.63.110 and 1.64.0 being cut. Fixes #11737 Change-Id: Iaf9563363b8e45319a9b6fe94c8d5ffaecc9ccef Signed-off-by: Brad Fitzpatrick --- wgengine/router/router_linux.go | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/wgengine/router/router_linux.go b/wgengine/router/router_linux.go index 36e95d297..8b25243a5 100644 --- a/wgengine/router/router_linux.go +++ b/wgengine/router/router_linux.go @@ -469,7 +469,7 @@ func (r *linuxRouter) UpdateMagicsockPort(port uint16, network string) error { // reflect the new mode, and r.snatSubnetRoutes is updated to reflect // the current state of subnet SNATing. func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error { - if distro.Get() == distro.Synology { + if !platformCanNetfilter() { mode = netfilterOff } @@ -1396,11 +1396,26 @@ func normalizeCIDR(cidr netip.Prefix) string { return cidr.Masked().String() } +// platformCanNetfilter reports whether the current distro/environment supports +// running iptables/nftables commands. +func platformCanNetfilter() bool { + switch distro.Get() { + case distro.Synology: + // Synology doesn't support iptables or nftables. Attempting to run it + // just blocks for a long time while it logs about failures. + // + // See https://github.com/tailscale/tailscale/issues/11737 for one such + // prior regression where we tried to run iptables on Synology. + return false + } + return true +} + // cleanUp removes all the rules and routes that were added by the linux router. // The function calls cleanUp for both iptables and nftables since which ever // netfilter runner is used, the cleanUp function for the other one doesn't do anything. func cleanUp(logf logger.Logf, interfaceName string) { - if interfaceName != "userspace-networking" { + if interfaceName != "userspace-networking" && platformCanNetfilter() { linuxfw.IPTablesCleanUp(logf) linuxfw.NfTablesCleanUp(logf) }