control/controlknobs,net/{batching,tstun},wgengine: add nodecaps to disable UDP & TUN GRO/GSO

Add four control-plane node attributes that let us disable UDP GSO/GRO
on the magicsock UDP socket and UDP/TCP GRO on the Tailscale TUN
device.

These complement the pre-existing TS_DEBUG_DISABLE_UDP_{GRO,GSO} and
TS_TUN_DISABLE_{UDP,TCP}_GRO envknobs. They exist so we can mitigate
upstream Linux kernel regressions on a deployed fleet without
requiring a client release, after two incidents (#13041, #19777) where
buggy kernel patches landed upstream and the fix took an excessively
long time to reach downstream distros.

Knob changes are reacted to in setNetworkMapInternal / SetNetworkMap via
a comparison against a cached "last applied" value and only an actual
transition triggers work: magicsock Rebind()+ReSTUN for UDP,
ApplyGROKnobs for TUN. The TUN side is gated by buildfeatures.HasGRO and
is one-way (wireguard-go GRO disablement is sticky); re-enabling
requires a client restart.

Updates #13041
Updates #19777

Change-Id: I802993070afa659cc06809bb0bfbb7f8a0cdb273
Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2026-05-27 17:10:14 -07:00
committed by James Tucker
parent 94af1b00fb
commit 25b8ed8d9e
13 changed files with 212 additions and 30 deletions
+38 -1
View File
@@ -186,7 +186,8 @@ type CapabilityVersion int
// - 137: 2026-04-15: Client handles 429 responses to /machine/register.
// - 138: 2026-03-31: can handle C2N /debug/tka.
// - 139: 2026-05-22: Client understands [NodeAttrEmitRuntimeMetrics]
const CurrentCapabilityVersion CapabilityVersion = 139
// - 140: 2026-05-27: Client understands [NodeAttrDisableUDPGRO], [NodeAttrDisableUDPGSO], [NodeAttrDisableTUNUDPGRO], [NodeAttrDisableTUNTCPGRO]
const CurrentCapabilityVersion CapabilityVersion = 140
// ID is an integer ID for a user, node, or login allocated by the
// control plane.
@@ -2793,6 +2794,42 @@ const (
// NodeAttrEmitRuntimeMetrics enables emission of [runtime/metrics] as
// [tailscale.com/util/clientmetric]'s.
NodeAttrEmitRuntimeMetrics NodeCapability = "emit-runtime-metrics"
// NodeAttrDisableUDPGRO disables UDP GRO (UDP_GRO socket option on Linux)
// on the magicsock UDP socket. It exists so control can mitigate kernel
// regressions that cause throughput or correctness issues with UDP GRO on
// specific OS/kernel versions, without requiring a client release. See
// https://github.com/tailscale/tailscale/issues/19777 for example.
// Currently only consulted on Linux; may apply to other platforms as they
// gain UDP GRO support.
NodeAttrDisableUDPGRO NodeCapability = "disable-udp-gro"
// NodeAttrDisableUDPGSO disables UDP GSO (UDP_SEGMENT socket option on
// Linux) on the magicsock UDP socket. It exists so control can mitigate
// kernel regressions that cause throughput or correctness issues with UDP
// GSO on specific OS/kernel versions, without requiring a client release.
// See https://github.com/tailscale/tailscale/issues/19777 for example.
// Currently only consulted on Linux; may apply to other platforms as they
// gain UDP GSO support.
NodeAttrDisableUDPGSO NodeCapability = "disable-udp-gso"
// NodeAttrDisableTUNUDPGRO disables UDP GRO on the Tailscale TUN device.
// It exists so control can mitigate kernel regressions that cause
// throughput or correctness issues with TUN UDP GRO on specific OS/kernel
// versions, without requiring a client release. See
// https://github.com/tailscale/tailscale/issues/13041 for example.
// Currently only consulted on Linux; may apply to other platforms as they
// gain TUN UDP GRO support.
NodeAttrDisableTUNUDPGRO NodeCapability = "disable-tun-udp-gro"
// NodeAttrDisableTUNTCPGRO disables TCP GRO on the Tailscale TUN device.
// It exists so control can mitigate kernel regressions that cause
// throughput or correctness issues with TUN TCP GRO on specific OS/kernel
// versions, without requiring a client release. See
// https://github.com/tailscale/tailscale/issues/13041 for example.
// Currently only consulted on Linux; may apply to other platforms as they
// gain TUN TCP GRO support.
NodeAttrDisableTUNTCPGRO NodeCapability = "disable-tun-tcp-gro"
)
const (