net/netmon: trim IPv6 endpoints in already routable subnets

We have observed some clients with extremely large lists of IPv6
endpoints, in some cases from subnets where the machine also has the
zero address for a whole /48 with then arbitrary addresses additionally
assigned within that /48. It is in general unnecessary for reachability
to report all of these addresses, typically only one will be necessary
for reachability. We report two, to cover some other common cases such
as some styles of IPv6 private address rotations.

Updates tailscale/corp#25850

Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker 2025-01-10 14:17:16 -08:00 committed by James Tucker
parent 2ac189800c
commit 6364b5f1e0

View File

@ -19,8 +19,14 @@ import (
"tailscale.com/net/netaddr"
"tailscale.com/net/tsaddr"
"tailscale.com/net/tshttpproxy"
"tailscale.com/util/mak"
)
// forceAllIPv6Endpoints is a debug knob that when set forces the client to
// report all IPv6 endpoints rather than trim endpoints that are siblings on the
// same interface and subnet.
var forceAllIPv6Endpoints = envknob.RegisterBool("TS_DEBUG_FORCE_ALL_IPV6_ENDPOINTS")
// LoginEndpointForProxyDetermination is the URL used for testing
// which HTTP proxy the system should use.
var LoginEndpointForProxyDetermination = "https://controlplane.tailscale.com/"
@ -65,6 +71,7 @@ func LocalAddresses() (regular, loopback []netip.Addr, err error) {
if err != nil {
return nil, nil, err
}
var subnets map[netip.Addr]int
for _, a := range addrs {
switch v := a.(type) {
case *net.IPNet:
@ -102,7 +109,15 @@ func LocalAddresses() (regular, loopback []netip.Addr, err error) {
if ip.Is4() {
regular4 = append(regular4, ip)
} else {
regular6 = append(regular6, ip)
curMask, _ := netip.AddrFromSlice(v.IP.Mask(v.Mask))
// Limit the number of addresses reported per subnet for
// IPv6, as we have seen some nodes with extremely large
// numbers of assigned addresses being carved out of
// same-subnet allocations.
if forceAllIPv6Endpoints() || subnets[curMask] < 2 {
regular6 = append(regular6, ip)
}
mak.Set(&subnets, curMask, subnets[curMask]+1)
}
}
}