|
|
@@ -32,10 +32,12 @@ import (
|
|
|
"tailscale.com/ipn"
|
|
|
"tailscale.com/ipn/ipnstate"
|
|
|
"tailscale.com/net/netutil"
|
|
|
+ "tailscale.com/net/tsaddr"
|
|
|
"tailscale.com/safesocket"
|
|
|
"tailscale.com/tailcfg"
|
|
|
"tailscale.com/types/logger"
|
|
|
"tailscale.com/types/preftype"
|
|
|
+ "tailscale.com/types/views"
|
|
|
"tailscale.com/util/dnsname"
|
|
|
"tailscale.com/version"
|
|
|
"tailscale.com/version/distro"
|
|
|
@@ -1015,7 +1017,7 @@ func prefsToFlags(env upCheckEnv, prefs *ipn.Prefs) (flagVal map[string]any) {
|
|
|
set(prefs.OperatorUser)
|
|
|
case "advertise-routes":
|
|
|
var sb strings.Builder
|
|
|
- for i, r := range withoutExitNodes(prefs.AdvertiseRoutes) {
|
|
|
+ for i, r := range tsaddr.WithoutExitRoutes(views.SliceOf(prefs.AdvertiseRoutes)).All() {
|
|
|
if i > 0 {
|
|
|
sb.WriteByte(',')
|
|
|
}
|
|
|
@@ -1023,7 +1025,7 @@ func prefsToFlags(env upCheckEnv, prefs *ipn.Prefs) (flagVal map[string]any) {
|
|
|
}
|
|
|
set(sb.String())
|
|
|
case "advertise-exit-node":
|
|
|
- set(hasExitNodeRoutes(prefs.AdvertiseRoutes))
|
|
|
+ set(tsaddr.ContainsExitRoutes(views.SliceOf(prefs.AdvertiseRoutes)))
|
|
|
case "advertise-connector":
|
|
|
set(prefs.AppConnector.Advertise)
|
|
|
case "snat-subnet-routes":
|
|
|
@@ -1057,36 +1059,6 @@ func fmtFlagValueArg(flagName string, val any) string {
|
|
|
return fmt.Sprintf("--%s=%v", flagName, shellquote.Join(fmt.Sprint(val)))
|
|
|
}
|
|
|
|
|
|
-func hasExitNodeRoutes(rr []netip.Prefix) bool {
|
|
|
- var v4, v6 bool
|
|
|
- for _, r := range rr {
|
|
|
- if r.Bits() == 0 {
|
|
|
- if r.Addr().Is4() {
|
|
|
- v4 = true
|
|
|
- } else if r.Addr().Is6() {
|
|
|
- v6 = true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return v4 && v6
|
|
|
-}
|
|
|
-
|
|
|
-// withoutExitNodes returns rr unchanged if it has only 1 or 0 /0
|
|
|
-// routes. If it has both IPv4 and IPv6 /0 routes, then it returns
|
|
|
-// a copy with all /0 routes removed.
|
|
|
-func withoutExitNodes(rr []netip.Prefix) []netip.Prefix {
|
|
|
- if !hasExitNodeRoutes(rr) {
|
|
|
- return rr
|
|
|
- }
|
|
|
- var out []netip.Prefix
|
|
|
- for _, r := range rr {
|
|
|
- if r.Bits() > 0 {
|
|
|
- out = append(out, r)
|
|
|
- }
|
|
|
- }
|
|
|
- return out
|
|
|
-}
|
|
|
-
|
|
|
// exitNodeIP returns the exit node IP from p, using st to map
|
|
|
// it from its ID form to an IP address if needed.
|
|
|
func exitNodeIP(p *ipn.Prefs, st *ipnstate.Status) (ip netip.Addr) {
|