diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go index 4adb14894..7c430585a 100644 --- a/wgengine/netstack/netstack.go +++ b/wgengine/netstack/netstack.go @@ -559,8 +559,8 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool { return true } } - if p.IPVersion == 6 && viaRange.Contains(p.Dst.Addr()) { - return ns.lb != nil && ns.lb.ShouldHandleViaIP(p.Dst.Addr()) + if p.IPVersion == 6 && !isLocal && viaRange.Contains(dstIP) { + return ns.lb != nil && ns.lb.ShouldHandleViaIP(dstIP) } if !ns.ProcessLocalIPs && !ns.ProcessSubnets { // Fast path for common case (e.g. Linux server in TUN mode) where diff --git a/wgengine/netstack/netstack_test.go b/wgengine/netstack/netstack_test.go index 6b8f14beb..6135ad858 100644 --- a/wgengine/netstack/netstack_test.go +++ b/wgengine/netstack/netstack_test.go @@ -259,6 +259,13 @@ func TestShouldHandlePing(t *testing.T) { } } +// looksLikeATailscaleSelfAddress reports whether addr looks like +// a Tailscale self address, for tests. +func looksLikeATailscaleSelfAddress(addr netip.Addr) bool { + return addr.Is4() && tsaddr.IsTailscaleIP(addr) || + addr.Is6() && tsaddr.Tailscale4To6Range().Contains(addr) +} + func TestShouldProcessInbound(t *testing.T) { testCases := []struct { name string @@ -289,6 +296,7 @@ func TestShouldProcessInbound(t *testing.T) { StateKey: ipn.GlobalDaemonStateKey, UpdatePrefs: prefs, }) + i.atomicIsLocalIPFunc.Store(looksLikeATailscaleSelfAddress) // This should be handled even if we're // otherwise not processing local IPs or @@ -400,7 +408,7 @@ func TestShouldProcessInbound(t *testing.T) { // For testing purposes, assume all Tailscale // IPs are local; the Dst above is something // not in that range. - i.atomicIsLocalIPFunc.Store(tsaddr.IsTailscaleIP) + i.atomicIsLocalIPFunc.Store(looksLikeATailscaleSelfAddress) }, want: true, },