From cfef5c4105a099d6d16a27fb160823db4d965086 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 23 Jan 2026 21:05:00 +0000 Subject: [PATCH] policy: use CIDR format for autogroup:self destinations Updates #3036 --- CHANGELOG.md | 1 + hscontrol/policy/v2/filter.go | 3 +- hscontrol/policy/v2/filter_test.go | 7 +- hscontrol/policy/v2/tailscale_compat_test.go | 111 +++++++++---------- 4 files changed, 61 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f648c1c3..1059b772 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ overall our implementation was very close. - **ACL Policy**: Add ICMP and IPv6-ICMP protocols to default filter rules when no protocol is specified [#3036](https://github.com/juanfont/headscale/pull/3036) - **ACL Policy**: Fix autogroup:self handling for tagged nodes - tagged nodes no longer incorrectly receive autogroup:self filter rules [#3036](https://github.com/juanfont/headscale/pull/3036) +- **ACL Policy**: Use CIDR format for autogroup:self destination IPs matching Tailscale behavior [#3036](https://github.com/juanfont/headscale/pull/3036) ## 0.28.0 (2026-02-04) diff --git a/hscontrol/policy/v2/filter.go b/hscontrol/policy/v2/filter.go index 3ba14feb..bdcbb1f2 100644 --- a/hscontrol/policy/v2/filter.go +++ b/hscontrol/policy/v2/filter.go @@ -3,6 +3,7 @@ package v2 import ( "errors" "fmt" + "net/netip" "slices" "time" @@ -197,7 +198,7 @@ func (pol *Policy) compileACLWithAutogroupSelf( for _, port := range dest.Ports { for _, ip := range n.IPs() { destPorts = append(destPorts, tailcfg.NetPortRange{ - IP: ip.String(), + IP: netip.PrefixFrom(ip, ip.BitLen()).String(), Ports: port, }) } diff --git a/hscontrol/policy/v2/filter_test.go b/hscontrol/policy/v2/filter_test.go index 0bb3b8be..eb3afb39 100644 --- a/hscontrol/policy/v2/filter_test.go +++ b/hscontrol/policy/v2/filter_test.go @@ -941,7 +941,7 @@ func TestCompileFilterRulesForNodeWithAutogroupSelf(t *testing.T) { } } - expectedDestIPs := []string{"100.64.0.1", "100.64.0.2"} + expectedDestIPs := []string{"100.64.0.1/32", "100.64.0.2/32"} actualDestIPs := make([]string, 0, len(rule.DstPorts)) for _, dst := range rule.DstPorts { @@ -957,7 +957,7 @@ func TestCompileFilterRulesForNodeWithAutogroupSelf(t *testing.T) { } // Verify that other users' devices and tagged devices are not in destinations - excludedDestIPs := []string{"100.64.0.3", "100.64.0.4", "100.64.0.5", "100.64.0.6"} + excludedDestIPs := []string{"100.64.0.3/32", "100.64.0.4/32", "100.64.0.5/32", "100.64.0.6/32"} for _, excludedIP := range excludedDestIPs { for _, actualIP := range actualDestIPs { if actualIP == excludedIP { @@ -1294,7 +1294,8 @@ func TestAutogroupSelfWithSpecificUserSource(t *testing.T) { actualDestIPs = append(actualDestIPs, dst.IP) } - assert.ElementsMatch(t, expectedSourceIPs, actualDestIPs) + expectedDestIPs := []string{"100.64.0.1/32", "100.64.0.2/32"} + assert.ElementsMatch(t, expectedDestIPs, actualDestIPs) node2 := nodes[2].View() rules2, err := policy.compileFilterRulesForNode(users, node2, nodes.ViewSlice()) diff --git a/hscontrol/policy/v2/tailscale_compat_test.go b/hscontrol/policy/v2/tailscale_compat_test.go index 3d5071af..c7116130 100644 --- a/hscontrol/policy/v2/tailscale_compat_test.go +++ b/hscontrol/policy/v2/tailscale_compat_test.go @@ -1318,11 +1318,10 @@ func TestTailscaleCompatAutogroups(t *testing.T) { "100.90.199.68/32", "fd7a:115c:a1e0::2d01:c747/128", }, - // NOTE: Headscale uses raw IP addresses without CIDR suffix for autogroup:self destinations. // Tailscale uses CIDR format: "100.90.199.68/32" and "fd7a:115c:a1e0::2d01:c747/128" DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRangeAny}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRangeAny}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRangeAny}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRangeAny}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -1395,11 +1394,9 @@ func TestTailscaleCompatAutogroups(t *testing.T) { "100.90.199.68/32", "fd7a:115c:a1e0::2d01:c747/128", }, - // NOTE: Headscale uses raw IP addresses without CIDR suffix for autogroup:self destinations. - // TODO: Tailscale uses CIDR format DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRangeAny}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRangeAny}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRangeAny}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRangeAny}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3584,8 +3581,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, // Dsts = user1's own IPs with all ports (no CIDR notation for autogroup:self) DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3612,8 +3609,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 22, Last: 22}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3639,8 +3636,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3666,8 +3663,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3693,8 +3690,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3722,8 +3719,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, // autogroup:self destinations use plain IPs (no CIDR notation) DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -3996,12 +3993,12 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, // 6 Dsts: 3 ports × 2 IPs (autogroup:self uses plain IPs) DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 80, Last: 80}}, - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 443, Last: 443}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 80, Last: 80}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 443, Last: 443}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 80, Last: 80}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 443, Last: 443}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 80, Last: 80}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 443, Last: 443}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -4028,8 +4025,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, // Port range preserved (autogroup:self uses plain IPs) DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 80, Last: 443}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 80, Last: 443}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 80, Last: 443}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 80, Last: 443}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -4061,8 +4058,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 22, Last: 22}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -4072,8 +4069,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 80, Last: 80}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 80, Last: 80}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 80, Last: 80}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 80, Last: 80}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -4221,8 +4218,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -5308,8 +5305,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 22, Last: 22}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -5350,8 +5347,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 22, Last: 22}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -5361,8 +5358,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 80, Last: 80}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 80, Last: 80}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 80, Last: 80}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 80, Last: 80}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -6858,8 +6855,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -6884,8 +6881,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 22, Last: 22}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 22, Last: 22}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 22, Last: 22}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -6909,8 +6906,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -6934,8 +6931,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -6959,8 +6956,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { "fd7a:115c:a1e0::2d01:c747/128", }, DstPorts: []tailcfg.NetPortRange{ - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -8028,8 +8025,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, DstPorts: []tailcfg.NetPortRange{ // Note: autogroup:self destinations use raw IP format (no /32 suffix) - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -8268,8 +8265,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, DstPorts: []tailcfg.NetPortRange{ // Note: autogroup:self destinations use raw IP format (no /32 suffix) - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 80, Last: 443}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 80, Last: 443}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 80, Last: 443}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 80, Last: 443}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -8293,8 +8290,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, DstPorts: []tailcfg.NetPortRange{ // Note: autogroup:self destinations use raw IP format (no /32 suffix) - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, }, @@ -8335,8 +8332,8 @@ func TestTailscaleCompatComplexScenarios(t *testing.T) { }, DstPorts: []tailcfg.NetPortRange{ // Note: autogroup:self destinations use raw IP format (no /32 suffix) - {IP: "100.90.199.68", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, - {IP: "fd7a:115c:a1e0::2d01:c747", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "100.90.199.68/32", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, + {IP: "fd7a:115c:a1e0::2d01:c747/128", Ports: tailcfg.PortRange{First: 0, Last: 65535}}, }, IPProto: []int{ProtocolTCP, ProtocolUDP, ProtocolICMP, ProtocolIPv6ICMP}, },