types: lead AllowedIPs with the node's own addresses

As SaaS. tailscale whois prints AllowedIPs[2:] as routes, so sorted
entries showed an own address in place of a subnet route.
This commit is contained in:
Kristoffer Dalby committed 2026-11-03 17:05:00 +01:00
1 parent edad4ff324
commit 68b0274694
3 files changed
+13 -7

No files matched your search

+2 -4
View File
@@ -137,8 +137,8 @@ func TestTailNode(t *testing.T) {
),
Addresses: []netip.Prefix{netip.MustParsePrefix("100.64.0.1/32")},
AllowedIPs: []netip.Prefix{
tsaddr.AllIPv4(),
netip.MustParsePrefix("100.64.0.1/32"),
tsaddr.AllIPv4(),
netip.MustParsePrefix("192.168.0.0/24"),
tsaddr.AllIPv6(),
},
@@ -399,11 +399,9 @@ func TestTailNodeDisableIPv4(t *testing.T) {
name: "cap_keeps_advertised_subnet_route",
hasCap: true,
approved: []netip.Prefix{subnet},
// AllowedIPs is sorted by netip.Prefix.Compare so IPv4
// sorts before IPv6.
wantAllowed: []netip.Prefix{
subnet,
netip.MustParsePrefix("fd7a:115c:a1e0::1/128"),
subnet,
},
wantPrimary: []netip.Prefix{subnet},
wantAddrs: []netip.Prefix{netip.MustParsePrefix("fd7a:115c:a1e0::1/128")},
+7 -1
View File
@@ -601,9 +601,11 @@ func selfRoutes(nm *netmap.NetworkMap) string {
var allowed, primary []string
for _, pfx := range self.AllowedIPs().All() {
for i, pfx := range self.AllowedIPs().All() {
if !views.SliceContains(self.Addresses(), pfx) {
allowed = append(allowed, pfx.String())
} else if i >= self.Addresses().Len() {
allowed = append(allowed, "own address after a route: "+pfx.String())
}
}
@@ -828,6 +830,10 @@ func comparePeers(
prefix := peer.AllowedIPs().At(i)
if isTailscaleIP(prefix) {
tsIPs = append(tsIPs, prefix)
// As SaaS: own addresses lead, and whois reads routes by position.
assert.Lessf(check["peer-addresses"], i, peer.Addresses().Len(),
"peer %s: own address %s comes after a route", name, prefix)
} else {
routePrefixes = append(routePrefixes, prefix.String())
}
+4 -2
View File
@@ -1411,8 +1411,10 @@ func (nv NodeView) TailNode(
// routeFunc returns ALL routes (subnet + exit) for this node.
allRoutes := primaryRouteFunc(nv.ID())
allowedIPs := slices.Concat(addresses, allRoutes)
slices.SortFunc(allowedIPs, netip.Prefix.Compare)
// Own addresses lead, as on SaaS: `tailscale whois` prints AllowedIPs[2:]
// as the peer's routes.
allowedIPs := slices.Concat(addresses, slices.SortedFunc(slices.Values(allRoutes), netip.Prefix.Compare))
// PrimaryRoutes only includes non-exit subnet routes for HA tracking.
var primaryRoutes []netip.Prefix