tailcfg,net/routecheck: add NodeAttrClientSideReachabilityRouteCheck (#20169)

This patch adds a new `client-side-reachability-routecheck` node
attribute to allow admins to selectively enable background routecheck
probing on trial nodes. The current implementation is still
experimental.

It adds the routecheck.IsEnabled helper to check for the new
`client-side-reachability-routecheck` node attribute alongside the
existing `client-side-reachability` node attribute in this node’s self
capabilities. This allows administrators to turn on and off this
feature by editing the policy file.

It adds the `TS_DEBUG_FORCE_CLIENT_SIDE_REACHABILITY_ROUTECHECK`
environment variable which can be set to override the policy file.
When set to `true`, it forcibly enables this feature. And when set to
`false`, it forcibly disables it.

Updates #17366
Updates tailscale/corp#33033

Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit is contained in:
Simon Law
2026-06-25 18:22:15 -07:00
committed by GitHub
parent 9169b206be
commit 2fbd30824b
3 changed files with 36 additions and 1 deletions
+21
View File
@@ -12,6 +12,7 @@ import (
"sync/atomic"
"time"
"tailscale.com/envknob"
"tailscale.com/ipn/ipnstate"
"tailscale.com/tailcfg"
"tailscale.com/types/logger"
@@ -23,6 +24,26 @@ var (
metricRefresh = clientmetric.NewCounter("routecheck_refresh")
)
// DebugForceClientSideReachabilityRoutecheck reports whether routecheck should be forced on or off.
// If the TS_DEBUG_FORCE_CLIENT_SIDE_REACHABILITY_ROUTECHECK environment variable is true,
// then routecheck is forced on. If it is false, then routecheck is forced off.
// If unset, then the client respects the client-side-reachability and
// client-side-reachability-routecheck node attributes.
var DebugForceClientSideReachabilityRoutecheck = envknob.RegisterOptBool("TS_DEBUG_FORCE_CLIENT_SIDE_REACHABILITY_ROUTECHECK")
// IsEnabled reports whether routecheck probing has been enabled for this client.
func IsEnabled(self tailcfg.NodeView) bool {
if v, ok := DebugForceClientSideReachabilityRoutecheck().Get(); ok {
return v // forced
}
if !self.Valid() {
return false
}
// TODO(sfllaw): We intend to eventually enable this behaviour by default.
return self.HasCap(tailcfg.NodeAttrClientSideReachability) &&
self.HasCap(tailcfg.NodeAttrClientSideReachabilityRouteCheck)
}
// Client generates Reports describing the result of both passive and active
// reachability probing.
type Client struct {