net/tsaddr: IsUla() for IPv6 Unique Local Address
Signed-off-by: Denton Gentry <dgentry@tailscale.com>pull/1619/head
parent
36a85e1760
commit
ecf310be3c
|
@ -33,6 +33,7 @@ func CGNATRange() netaddr.IPPrefix {
|
||||||
var (
|
var (
|
||||||
cgnatRange oncePrefix
|
cgnatRange oncePrefix
|
||||||
ulaRange oncePrefix
|
ulaRange oncePrefix
|
||||||
|
tsUlaRange oncePrefix
|
||||||
ula4To6Range oncePrefix
|
ula4To6Range oncePrefix
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,8 +58,8 @@ func IsTailscaleIP(ip netaddr.IP) bool {
|
||||||
// TailscaleULARange returns the IPv6 Unique Local Address range that
|
// TailscaleULARange returns the IPv6 Unique Local Address range that
|
||||||
// is the superset range that Tailscale assigns out of.
|
// is the superset range that Tailscale assigns out of.
|
||||||
func TailscaleULARange() netaddr.IPPrefix {
|
func TailscaleULARange() netaddr.IPPrefix {
|
||||||
ulaRange.Do(func() { mustPrefix(&ulaRange.v, "fd7a:115c:a1e0::/48") })
|
tsUlaRange.Do(func() { mustPrefix(&tsUlaRange.v, "fd7a:115c:a1e0::/48") })
|
||||||
return ulaRange.v
|
return tsUlaRange.v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tailscale4To6Range returns the subset of TailscaleULARange used for
|
// Tailscale4To6Range returns the subset of TailscaleULARange used for
|
||||||
|
@ -95,6 +96,11 @@ func Tailscale4To6(ipv4 netaddr.IP) netaddr.IP {
|
||||||
return netaddr.IPFrom16(ret)
|
return netaddr.IPFrom16(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsULA(ip netaddr.IP) bool {
|
||||||
|
ulaRange.Do(func() { mustPrefix(&ulaRange.v, "fc00::/7") })
|
||||||
|
return ulaRange.v.Contains(ip)
|
||||||
|
}
|
||||||
|
|
||||||
func mustPrefix(v *netaddr.IPPrefix, prefix string) {
|
func mustPrefix(v *netaddr.IPPrefix, prefix string) {
|
||||||
var err error
|
var err error
|
||||||
*v, err = netaddr.ParseIPPrefix(prefix)
|
*v, err = netaddr.ParseIPPrefix(prefix)
|
||||||
|
|
|
@ -42,3 +42,25 @@ func TestCGNATRange(t *testing.T) {
|
||||||
t.Errorf("got %q; want %q", got, want)
|
t.Errorf("got %q; want %q", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsUla(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
ip string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"first ULA", "fc00::1", true},
|
||||||
|
{"not ULA", "fb00::1", false},
|
||||||
|
{"Tailscale", "fd7a:115c:a1e0::1", true},
|
||||||
|
{"Cloud Run", "fddf:3978:feb1:d745::1", true},
|
||||||
|
{"zeros", "0000:0000:0000:0000:0000:0000:0000:0000", false},
|
||||||
|
{"Link Local", "fe80::1", false},
|
||||||
|
{"Global", "2602::1", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
if got := IsULA(netaddr.MustParseIP(test.ip)); got != test.want {
|
||||||
|
t.Errorf("IsULA(%s) = %v, want %v", test.name, got, test.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue