From ba70cbb930aa0e0ce87a1a0ff074c07e2ac7d063 Mon Sep 17 00:00:00 2001 From: James Tucker Date: Wed, 31 Jan 2024 17:36:39 -0800 Subject: [PATCH] ipn/ipnlocal: fix app connector route advertisements on exit nodes If an app connector is also configured as an exit node, it should still advertise discovered routes that are not covered by advertised routes, excluding the exit node routes. Updates tailscale/corp#16928 Signed-off-by: James Tucker --- ipn/ipnlocal/local.go | 11 +++++++---- ipn/ipnlocal/local_test.go | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index bdaef23a2..706ca524b 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -5808,7 +5808,7 @@ func (b *LocalBackend) AdvertiseRoute(ipps ...netip.Prefix) error { } // If the new prefix is already contained by existing routes, skip it. - if coveredRouteRange(finalRoutes, ipp) { + if coveredRouteRangeNoDefault(finalRoutes, ipp) { continue } @@ -5829,10 +5829,13 @@ func (b *LocalBackend) AdvertiseRoute(ipps ...netip.Prefix) error { return err } -// coveredRouteRange checks if a route is already included in a slice of -// prefixes. -func coveredRouteRange(finalRoutes []netip.Prefix, ipp netip.Prefix) bool { +// coveredRouteRangeNoDefault checks if a route is already included in a slice of +// prefixes, ignoring default routes in the range. +func coveredRouteRangeNoDefault(finalRoutes []netip.Prefix, ipp netip.Prefix) bool { for _, r := range finalRoutes { + if r == tsaddr.AllIPv4() || r == tsaddr.AllIPv6() { + continue + } if ipp.IsSingleIP() { if r.Contains(ipp.Addr()) { return true diff --git a/ipn/ipnlocal/local_test.go b/ipn/ipnlocal/local_test.go index 9ff967b2e..8c8b68a87 100644 --- a/ipn/ipnlocal/local_test.go +++ b/ipn/ipnlocal/local_test.go @@ -1218,7 +1218,7 @@ func TestObserveDNSResponse(t *testing.T) { } } -func TestCoveredRouteRange(t *testing.T) { +func TestCoveredRouteRangeNoDefault(t *testing.T) { tests := []struct { existingRoute netip.Prefix newRoute netip.Prefix @@ -1244,10 +1244,20 @@ func TestCoveredRouteRange(t *testing.T) { newRoute: netip.MustParsePrefix("192.0.0.0/24"), want: true, }, + { + existingRoute: netip.MustParsePrefix("0.0.0.0/0"), + newRoute: netip.MustParsePrefix("192.0.0.0/24"), + want: false, + }, + { + existingRoute: netip.MustParsePrefix("::/0"), + newRoute: netip.MustParsePrefix("2001:db8::/32"), + want: false, + }, } for _, tt := range tests { - got := coveredRouteRange([]netip.Prefix{tt.existingRoute}, tt.newRoute) + got := coveredRouteRangeNoDefault([]netip.Prefix{tt.existingRoute}, tt.newRoute) if got != tt.want { t.Errorf("coveredRouteRange(%v, %v) = %v, want %v", tt.existingRoute, tt.newRoute, got, tt.want) }