summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@tailscale.com>2021-05-05 12:32:46 -0700
committerBrad Fitzpatrick <brad@danga.com>2021-05-05 13:38:55 -0700
commiteb06ec172f1d984bb87c589da1dd2d3f15dc6d82 (patch)
tree1bc4f055e8354f10907313ab88d240a627737ff1
parent7629cd6120345dbdbbee3b5a48c6f7ac9576cdfe (diff)
downloadtailscale-eb06ec172f1d984bb87c589da1dd2d3f15dc6d82.tar.xz
tailscale-eb06ec172f1d984bb87c589da1dd2d3f15dc6d82.zip
wgengine/netstack: don't pass non-subnet traffic to netstack in hybrid mode
Fixes tailscale/corp#1725 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
-rw-r--r--types/netmap/netmap.go4
-rw-r--r--wgengine/netstack/netstack.go23
2 files changed, 24 insertions, 3 deletions
diff --git a/types/netmap/netmap.go b/types/netmap/netmap.go
index a97d87b73..b69779c69 100644
--- a/types/netmap/netmap.go
+++ b/types/netmap/netmap.go
@@ -31,8 +31,8 @@ type NetworkMap struct {
Expiry time.Time
// Name is the DNS name assigned to this node.
Name string
- Addresses []netaddr.IPPrefix
- LocalPort uint16 // used for debugging
+ Addresses []netaddr.IPPrefix // same as tailcfg.Node.Addresses (IP addresses of this Node directly)
+ LocalPort uint16 // used for debugging
MachineStatus tailcfg.MachineStatus
MachineKey tailcfg.MachineKey
Peers []*tailcfg.Node // sorted by Node.ID
diff --git a/wgengine/netstack/netstack.go b/wgengine/netstack/netstack.go
index 1c051f5d2..acc32bb56 100644
--- a/wgengine/netstack/netstack.go
+++ b/wgengine/netstack/netstack.go
@@ -15,6 +15,7 @@ import (
"strconv"
"strings"
"sync"
+ "sync/atomic"
"time"
"inet.af/netaddr"
@@ -55,6 +56,12 @@ type Impl struct {
logf logger.Logf
onlySubnets bool // whether we only want to handle subnet relaying
+ // atomicIsLocalIPFunc holds a func that reports whether an IP
+ // is a local (non-subnet) Tailscale IP address of this
+ // machine. It's always a non-nil func. It's changed on netmap
+ // updates.
+ atomicIsLocalIPFunc atomic.Value // of func(netaddr.IP) bool
+
mu sync.Mutex
dns DNSMap
// connsOpenBySubnetIP keeps track of number of connections open
@@ -119,6 +126,7 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
connsOpenBySubnetIP: make(map[netaddr.IP]int),
onlySubnets: onlySubnets,
}
+ ns.atomicIsLocalIPFunc.Store(tsaddr.NewContainsIPFunc(nil))
return ns, nil
}
@@ -145,7 +153,7 @@ func (ns *Impl) Start() error {
ns.logf("netstack: could not parse local address %s for incoming TCP connection", ip)
return false
}
- if !tsaddr.IsTailscaleIP(ip) {
+ if !ns.isLocalIP(ip) {
ns.addSubnetAddress(pn, ip)
}
return tcpFwd.HandlePacket(tei, pb)
@@ -219,6 +227,7 @@ func ipPrefixToAddressWithPrefix(ipp netaddr.IPPrefix) tcpip.AddressWithPrefix {
}
func (ns *Impl) updateIPs(nm *netmap.NetworkMap) {
+ ns.atomicIsLocalIPFunc.Store(tsaddr.NewContainsIPFunc(nm.Addresses))
ns.updateDNS(nm)
oldIPs := make(map[tcpip.AddressWithPrefix]bool)
@@ -373,7 +382,19 @@ func (ns *Impl) injectOutbound() {
}
}
+// isLocalIP reports whether ip is a Tailscale IP assigned to this
+// node directly (but not a subnet-routed IP).
+func (ns *Impl) isLocalIP(ip netaddr.IP) bool {
+ return ns.atomicIsLocalIPFunc.Load().(func(netaddr.IP) bool)(ip)
+}
+
func (ns *Impl) injectInbound(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
+ if ns.onlySubnets && ns.isLocalIP(p.Dst.IP) {
+ // In hybrid ("only subnets") mode, bail out early if
+ // the traffic is destined for an actual Tailscale
+ // address. The real host OS interface will handle it.
+ return filter.Accept
+ }
var pn tcpip.NetworkProtocolNumber
switch p.IPVersion {
case 4: