ipn/ipnlocal, net/netns: add node cap to disable netns interface binding on netext Apple clients (#17691)

updates tailscale/corp#31571

It appears that on the latest macOS, iOS and tVOS versions, the work
that netns is doing to bind outgoing connections to the default interface (and all
of the trimmings and workarounds in netmon et al that make that work) are
not needed. The kernel is extension-aware and doing nothing, is the right
thing.  This is, however, not the case for tailscaled (which is not a
special process).

To allow us to test this assertion (and where it might break things), we add a
new node cap that turns this behaviour off only for network-extension equipped clients,
making it possible to turn this off tailnet-wide, without breaking any tailscaled
macos nodes.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit is contained in:
Jonathan Nobels
2025-11-12 10:25:27 -05:00
committed by GitHub
parent 16e90dcb27
commit e8d2f96449
4 changed files with 30 additions and 11 deletions

View File

@@ -21,6 +21,7 @@ import (
"tailscale.com/net/netmon"
"tailscale.com/net/tsaddr"
"tailscale.com/types/logger"
"tailscale.com/version"
)
func control(logf logger.Logf, netMon *netmon.Monitor) func(network, address string, c syscall.RawConn) error {
@@ -36,13 +37,11 @@ var errInterfaceStateInvalid = errors.New("interface state invalid")
// controlLogf binds c to a particular interface as necessary to dial the
// provided (network, address).
func controlLogf(logf logger.Logf, netMon *netmon.Monitor, network, address string, c syscall.RawConn) error {
if isLocalhost(address) {
// Don't bind to an interface for localhost connections.
if disableBindConnToInterface.Load() || (version.IsMacGUIVariant() && disableBindConnToInterfaceAppleExt.Load()) {
return nil
}
if disableBindConnToInterface.Load() {
logf("netns_darwin: binding connection to interfaces disabled")
if isLocalhost(address) {
return nil
}