From 17f887c1b902d26ac1c49178164925ffa8b607c8 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Sun, 1 Oct 2023 17:55:59 -0700 Subject: [PATCH] ensure disabled and failover routes are propagated Signed-off-by: Kristoffer Dalby --- hscontrol/db/routes.go | 47 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/hscontrol/db/routes.go b/hscontrol/db/routes.go index d73c3afe58d..e7bb38bc29d 100644 --- a/hscontrol/db/routes.go +++ b/hscontrol/db/routes.go @@ -2,6 +2,7 @@ package db import ( "errors" + "fmt" "net/netip" "github.com/juanfont/headscale/hscontrol/policy" @@ -122,6 +123,8 @@ func (hsdb *HSDatabase) DisableRoute(id uint64) error { return err } + node := route.Node + // Tailscale requires both IPv4 and IPv6 exit routes to // be enabled at the same time, as per // https://github.com/juanfont/headscale/issues/804#issuecomment-1399314002 @@ -133,6 +136,20 @@ func (hsdb *HSDatabase) DisableRoute(id uint64) error { return err } + // Ensure the node has the latest routes when notifying the other + // nodes + nRoutes, err := hsdb.getNodeRoutes(&node) + if err != nil { + return fmt.Errorf("failed to read back routes: %w", err) + } + + node.Routes = nRoutes + + hsdb.notifier.NotifyAll(types.StateUpdate{ + Type: types.StatePeerChanged, + Changed: types.Nodes{&node}, + }) + return hsdb.handlePrimarySubnetFailover() } @@ -152,6 +169,13 @@ func (hsdb *HSDatabase) DisableRoute(id uint64) error { } } + node.Routes = routes + + hsdb.notifier.NotifyAll(types.StateUpdate{ + Type: types.StatePeerChanged, + Changed: types.Nodes{&node}, + }) + return hsdb.handlePrimarySubnetFailover() } @@ -363,6 +387,15 @@ func (hsdb *HSDatabase) handlePrimarySubnetFailover() error { return err } + // Ensure the node has the latest routes when notifying the other + // nodes + nRoutes, err := hsdb.getNodeRoutes(node) + if err != nil { + return fmt.Errorf("failed to read back routes: %w", err) + } + + node.Routes = nRoutes + changedNodes = append(changedNodes, node) continue @@ -437,10 +470,24 @@ func (hsdb *HSDatabase) handlePrimarySubnetFailover() error { return err } + // Ensure the node has the latest routes when notifying the other + // nodes + nRoutes, err := hsdb.getNodeRoutes(node) + if err != nil { + return fmt.Errorf("failed to read back routes: %w", err) + } + + node.Routes = nRoutes + changedNodes = append(changedNodes, node) } } + log.Trace(). + Caller(). + Interface("changed_nodes", changedNodes). + Msg("notifying nodes after route change") + if len(changedNodes) > 0 { hsdb.notifier.NotifyAll(types.StateUpdate{ Type: types.StatePeerChanged,