@ -54,13 +54,23 @@ type Impl struct {
// port other than accepting it and closing it.
ForwardTCPIn func ( c net . Conn , port uint16 )
// ProcessLocalIPs is whether netstack should handle incoming
// traffic directed at the Node.Addresses (local IPs).
// It can only be set before calling Start.
ProcessLocalIPs bool
// ProcessSubnets is whether netstack should handle incoming
// traffic destined to non-local IPs (i.e. whether it should
// be a subnet router).
// It can only be set before calling Start.
ProcessSubnets bool
ipstack * stack . Stack
linkEP * channel . Endpoint
tundev * tstun . Wrapper
e wgengine . Engine
mc * magicsock . Conn
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
@ -81,7 +91,7 @@ const nicID = 1
const mtu = 1500
// Create creates and populates a new Impl.
func Create ( logf logger . Logf , tundev * tstun . Wrapper , e wgengine . Engine , mc * magicsock . Conn , onlySubnets bool ) ( * Impl , error ) {
func Create ( logf logger . Logf , tundev * tstun . Wrapper , e wgengine . Engine , mc * magicsock . Conn ) ( * Impl , error ) {
if mc == nil {
return nil , errors . New ( "nil magicsock.Conn" )
}
@ -130,7 +140,6 @@ func Create(logf logger.Logf, tundev *tstun.Wrapper, e wgengine.Engine, mc *magi
e : e ,
mc : mc ,
connsOpenBySubnetIP : make ( map [ netaddr . IP ] int ) ,
onlySubnets : onlySubnets ,
}
ns . atomicIsLocalIPFunc . Store ( tsaddr . NewContainsIPFunc ( nil ) )
return ns , nil
@ -275,11 +284,11 @@ func (ns *Impl) updateIPs(nm *netmap.NetworkMap) {
isAddr [ ipp ] = true
}
for _ , ipp := range nm . SelfNode . AllowedIPs {
if ns . onlySubnets && isAddr [ ipp ] {
continue
}
local := isAddr [ ipp ]
if local && ns . ProcessLocalIPs || ! local && ns . ProcessSubnets {
newIPs [ ipPrefixToAddressWithPrefix ( ipp ) ] = true
}
}
ipsToBeAdded := make ( map [ tcpip . AddressWithPrefix ] bool )
for ipp := range newIPs {
@ -446,11 +455,27 @@ func (ns *Impl) isLocalIP(ip netaddr.IP) bool {
return ns . atomicIsLocalIPFunc . Load ( ) . ( func ( netaddr . IP ) bool ) ( ip )
}
// shouldProcessInbound reports whether an inbound packet should be
// handled by netstack.
func ( ns * Impl ) shouldProcessInbound ( p * packet . Parsed , t * tstun . Wrapper ) bool {
if ! ns . ProcessLocalIPs && ! ns . ProcessSubnets {
// Fast path for common case (e.g. Linux server in TUN mode) where
// netstack isn't used at all; don't even do an isLocalIP lookup.
return false
}
isLocal := ns . isLocalIP ( p . Dst . IP ( ) )
if ns . ProcessLocalIPs && isLocal {
return true
}
if ns . ProcessSubnets && ! isLocal {
return true
}
return false
}
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.
if ! ns . shouldProcessInbound ( p , t ) {
// Let the host network stack (if any) deal with it.
return filter . Accept
}
var pn tcpip . NetworkProtocolNumber