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:
@@ -53,6 +53,10 @@ func (e *Extension) Name() string {
|
|||||||
|
|
||||||
// Init implements the [ipnext.Extension.Init] interface method.
|
// Init implements the [ipnext.Extension.Init] interface method.
|
||||||
func (e *Extension) Init(h ipnext.Host) error {
|
func (e *Extension) Init(h ipnext.Host) error {
|
||||||
|
if routecheck.DebugForceClientSideReachabilityRoutecheck().EqualBool(false) {
|
||||||
|
return ipnext.SkipExtension
|
||||||
|
}
|
||||||
|
|
||||||
e.nb = nodeBackender{h}
|
e.nb = nodeBackender{h}
|
||||||
|
|
||||||
nm, ok := e.backend.(routecheck.NetMapper)
|
nm, ok := e.backend.(routecheck.NetMapper)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tailscale.com/envknob"
|
||||||
"tailscale.com/ipn/ipnstate"
|
"tailscale.com/ipn/ipnstate"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
@@ -23,6 +24,26 @@ var (
|
|||||||
metricRefresh = clientmetric.NewCounter("routecheck_refresh")
|
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
|
// Client generates Reports describing the result of both passive and active
|
||||||
// reachability probing.
|
// reachability probing.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
|
|||||||
+11
-1
@@ -2756,7 +2756,17 @@ const (
|
|||||||
// reachability itself when choosing connectors. When absent, the
|
// reachability itself when choosing connectors. When absent, the
|
||||||
// default behavior is to trust the control plane when it claims that a
|
// default behavior is to trust the control plane when it claims that a
|
||||||
// node is no longer online, but that is not a reliable signal.
|
// node is no longer online, but that is not a reliable signal.
|
||||||
NodeAttrClientSideReachability = "client-side-reachability"
|
//
|
||||||
|
// It is temporary and will be ignored once its behaviour becomes the default.
|
||||||
|
NodeAttrClientSideReachability NodeCapability = "client-side-reachability"
|
||||||
|
|
||||||
|
// NodeAttrClientSideReachabilityRouteCheck configures the node to use
|
||||||
|
// the routecheck subsystem to determine reachability when choosing
|
||||||
|
// connectors. This relies on [NodeAttrClientSideReachability] being set.
|
||||||
|
// See tailscale/tailscale#17367.
|
||||||
|
//
|
||||||
|
// It is temporary and will be ignored once its behaviour becomes the default.
|
||||||
|
NodeAttrClientSideReachabilityRouteCheck NodeCapability = "client-side-reachability-routecheck"
|
||||||
|
|
||||||
// NodeAttrDefaultAutoUpdate advertises the default node auto-update setting
|
// NodeAttrDefaultAutoUpdate advertises the default node auto-update setting
|
||||||
// for this tailnet. The node is free to opt-in or out locally regardless of
|
// for this tailnet. The node is free to opt-in or out locally regardless of
|
||||||
|
|||||||
Reference in New Issue
Block a user