From fbd3049e89dd9ad8edf24e737854ffd1767c66a7 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Fri, 2 May 2025 16:30:21 +0200 Subject: [PATCH] policy: add tests to validate fix for 2181 Fixes #2181 Signed-off-by: Kristoffer Dalby --- hscontrol/policy/policy_test.go | 106 +++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/hscontrol/policy/policy_test.go b/hscontrol/policy/policy_test.go index cebda65f..671ed829 100644 --- a/hscontrol/policy/policy_test.go +++ b/hscontrol/policy/policy_test.go @@ -2,10 +2,11 @@ package policy import ( "fmt" - "github.com/juanfont/headscale/hscontrol/policy/matcher" "net/netip" "testing" + "github.com/juanfont/headscale/hscontrol/policy/matcher" + "github.com/google/go-cmp/cmp" "github.com/juanfont/headscale/hscontrol/types" "github.com/juanfont/headscale/hscontrol/util" @@ -1370,7 +1371,6 @@ func TestFilterNodesByACL(t *testing.T) { }, }, }, - { name: "subnet-router-with-only-route", args: args{ @@ -1422,6 +1422,108 @@ func TestFilterNodesByACL(t *testing.T) { }, }, }, + { + name: "subnet-router-with-only-route-smaller-mask-2181", + args: args{ + nodes: []*types.Node{ + { + ID: 1, + IPv4: ap("100.64.0.1"), + Hostname: "router", + User: types.User{Name: "router"}, + Hostinfo: &tailcfg.Hostinfo{ + RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + ApprovedRoutes: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + { + ID: 2, + IPv4: ap("100.64.0.2"), + Hostname: "node", + User: types.User{Name: "node"}, + }, + }, + rules: []tailcfg.FilterRule{ + { + SrcIPs: []string{ + "100.64.0.2/32", + }, + DstPorts: []tailcfg.NetPortRange{ + {IP: "10.99.0.2/32", Ports: tailcfg.PortRangeAny}, + }, + }, + }, + node: &types.Node{ + ID: 1, + IPv4: ap("100.64.0.1"), + Hostname: "router", + User: types.User{Name: "router"}, + Hostinfo: &tailcfg.Hostinfo{ + RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + ApprovedRoutes: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + }, + want: []*types.Node{ + { + ID: 2, + IPv4: ap("100.64.0.2"), + Hostname: "node", + User: types.User{Name: "node"}, + }, + }, + }, + { + name: "node-to-subnet-router-with-only-route-smaller-mask-2181", + args: args{ + nodes: []*types.Node{ + { + ID: 1, + IPv4: ap("100.64.0.1"), + Hostname: "router", + User: types.User{Name: "router"}, + Hostinfo: &tailcfg.Hostinfo{ + RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + ApprovedRoutes: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + { + ID: 2, + IPv4: ap("100.64.0.2"), + Hostname: "node", + User: types.User{Name: "node"}, + }, + }, + rules: []tailcfg.FilterRule{ + { + SrcIPs: []string{ + "100.64.0.2/32", + }, + DstPorts: []tailcfg.NetPortRange{ + {IP: "10.99.0.2/32", Ports: tailcfg.PortRangeAny}, + }, + }, + }, + node: &types.Node{ + ID: 2, + IPv4: ap("100.64.0.2"), + Hostname: "node", + User: types.User{Name: "node"}, + }, + }, + want: []*types.Node{ + { + ID: 1, + IPv4: ap("100.64.0.1"), + Hostname: "router", + User: types.User{Name: "router"}, + Hostinfo: &tailcfg.Hostinfo{ + RoutableIPs: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + ApprovedRoutes: []netip.Prefix{netip.MustParsePrefix("10.99.0.0/16")}, + }, + }, + }, } for _, tt := range tests {