appc,ipn/ipnlocal,types/appctype: implement control provided routes

Control can now send down a set of routes along with the domains, and
the routes will be advertised, with any newly overlapped routes being
removed to reduce the size of the routing table.

Fixes tailscale/corp#16833
Signed-off-by: James Tucker <james@tailscale.com>
This commit is contained in:
James Tucker
2024-01-17 11:35:55 -08:00
committed by James Tucker
parent 543e7ed596
commit 24df1ef1ee
5 changed files with 159 additions and 2 deletions

View File

@@ -3446,14 +3446,21 @@ func (b *LocalBackend) reconfigAppConnectorLocked(nm *netmap.NetworkMap, prefs i
})
}
var domains []string
var (
domains []string
routes []netip.Prefix
)
for _, attr := range attrs {
if slices.Contains(attr.Connectors, "*") || selfHasTag(attr.Connectors) {
domains = append(domains, attr.Domains...)
routes = append(routes, attr.Routes...)
}
}
slices.Sort(domains)
slices.SortFunc(routes, func(i, j netip.Prefix) int { return i.Addr().Compare(j.Addr()) })
domains = slices.Compact(domains)
routes = slices.Compact(routes)
b.appConnector.UpdateRoutes(routes)
b.appConnector.UpdateDomains(domains)
}
@@ -5805,6 +5812,30 @@ func (b *LocalBackend) AdvertiseRoute(ipp netip.Prefix) error {
return err
}
// UnadvertiseRoute implements the appc.RouteAdvertiser interface. It removes
// a route advertisement if one is present in the existing routes.
func (b *LocalBackend) UnadvertiseRoute(ipp netip.Prefix) error {
currentRoutes := b.Prefs().AdvertiseRoutes().AsSlice()
if !slices.Contains(currentRoutes, ipp) {
return nil
}
newRoutes := currentRoutes[:0]
for _, r := range currentRoutes {
if r != ipp {
newRoutes = append(newRoutes, r)
}
}
_, err := b.EditPrefs(&ipn.MaskedPrefs{
Prefs: ipn.Prefs{
AdvertiseRoutes: newRoutes,
},
AdvertiseRoutesSet: true,
})
return err
}
// seamlessRenewalEnabled reports whether seamless key renewals are enabled
// (i.e. we saw our self node with the SeamlessKeyRenewal attr in a netmap).
// This enables beta functionality of renewing node keys without breaking

View File

@@ -1169,6 +1169,13 @@ func TestRouteAdvertiser(t *testing.T) {
if routes.Len() != 1 || routes.At(0) != testPrefix {
t.Fatalf("got routes %v, want %v", routes, []netip.Prefix{testPrefix})
}
must.Do(ra.UnadvertiseRoute(testPrefix))
routes = b.Prefs().AdvertiseRoutes()
if routes.Len() != 0 {
t.Fatalf("got routes %v, want none", routes)
}
}
func TestRouterAdvertiserIgnoresContainedRoutes(t *testing.T) {
@@ -1352,6 +1359,17 @@ func (rc *routeCollector) AdvertiseRoute(pfx netip.Prefix) error {
return nil
}
func (rc *routeCollector) UnadvertiseRoute(pfx netip.Prefix) error {
routes := rc.routes
rc.routes = rc.routes[:0]
for _, r := range routes {
if r != pfx {
rc.routes = append(rc.routes, r)
}
}
return nil
}
type errorSyspolicyHandler struct {
t *testing.T
err error