@@ -827,7 +827,7 @@ func (s *State) SetPolicy(pol []byte) (bool, error) {
827827
828828// AutoApproveRoutes checks if a node's routes should be auto-approved.
829829// AutoApproveRoutes checks if any routes should be auto-approved for a node and updates them.
830- func (s * State ) AutoApproveRoutes (nv types.NodeView ) bool {
830+ func (s * State ) AutoApproveRoutes (nv types.NodeView ) (change. ChangeSet , error ) {
831831 approved , changed := policy .ApproveRoutesWithPolicy (s .polMan , nv , nv .ApprovedRoutes ().AsSlice (), nv .AnnouncedRoutes ())
832832 if changed {
833833 log .Debug ().
@@ -840,21 +840,23 @@ func (s *State) AutoApproveRoutes(nv types.NodeView) bool {
840840
841841 // Persist the auto-approved routes to database and NodeStore via SetApprovedRoutes
842842 // This ensures consistency between database and NodeStore
843- _ , _ , err := s .SetApprovedRoutes (nv .ID (), approved )
843+ _ , c , err := s .SetApprovedRoutes (nv .ID (), approved )
844844 if err != nil {
845845 log .Error ().
846846 Uint64 ("node.id" , nv .ID ().Uint64 ()).
847847 Str ("node.name" , nv .Hostname ()).
848848 Err (err ).
849849 Msg ("Failed to persist auto-approved routes" )
850850
851- return false
851+ return change . EmptySet , err
852852 }
853853
854854 log .Info ().Uint64 ("node.id" , nv .ID ().Uint64 ()).Str ("node.name" , nv .Hostname ()).Strs ("routes.approved" , util .PrefixesToString (approved )).Msg ("Routes approved" )
855+
856+ return c , nil
855857 }
856858
857- return changed
859+ return change . EmptySet , nil
858860}
859861
860862// GetPolicy retrieves the current policy from the database.
@@ -1637,6 +1639,7 @@ func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest
16371639 var routeChange bool
16381640 var hostinfoChanged bool
16391641 var needsRouteApproval bool
1642+ var autoApprovedRoutes []netip.Prefix
16401643 // We need to ensure we update the node as it is in the NodeStore at
16411644 // the time of the request.
16421645 updatedNode , ok := s .nodeStore .UpdateNode (id , func (currentNode * types.Node ) {
@@ -1661,7 +1664,6 @@ func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest
16611664 }
16621665
16631666 // Calculate route approval before NodeStore update to avoid calling View() inside callback
1664- var autoApprovedRoutes []netip.Prefix
16651667 var hasNewRoutes bool
16661668 if hi := req .Hostinfo ; hi != nil {
16671669 hasNewRoutes = len (hi .RoutableIPs ) > 0
@@ -1727,7 +1729,6 @@ func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest
17271729 Strs ("newApprovedRoutes" , util .PrefixesToString (autoApprovedRoutes )).
17281730 Bool ("routeChanged" , routeChange ).
17291731 Msg ("applying route approval results" )
1730- currentNode .ApprovedRoutes = autoApprovedRoutes
17311732 }
17321733 }
17331734 })
@@ -1736,6 +1737,24 @@ func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest
17361737 return change .EmptySet , fmt .Errorf ("node not found in NodeStore: %d" , id )
17371738 }
17381739
1740+ if routeChange {
1741+ log .Debug ().
1742+ Uint64 ("node.id" , id .Uint64 ()).
1743+ Strs ("autoApprovedRoutes" , util .PrefixesToString (autoApprovedRoutes )).
1744+ Msg ("Persisting auto-approved routes from MapRequest" )
1745+
1746+ // SetApprovedRoutes will update both database and PrimaryRoutes table
1747+ _ , c , err := s .SetApprovedRoutes (id , autoApprovedRoutes )
1748+ if err != nil {
1749+ return change .EmptySet , fmt .Errorf ("persisting auto-approved routes: %w" , err )
1750+ }
1751+
1752+ // If SetApprovedRoutes resulted in a policy change, return it
1753+ if ! c .Empty () {
1754+ return c , nil
1755+ }
1756+ } // Continue with the rest of the processing using the updated node
1757+
17391758 nodeRouteChange := change .EmptySet
17401759
17411760 // Handle route changes after NodeStore update
@@ -1750,13 +1769,8 @@ func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest
17501769 routesChangedButNotApproved = true
17511770 }
17521771 }
1753- if routeChange {
1754- needsRouteUpdate = true
1755- log .Debug ().
1756- Caller ().
1757- Uint64 ("node.id" , id .Uint64 ()).
1758- Msg ("updating routes because approved routes changed" )
1759- } else if routesChangedButNotApproved {
1772+
1773+ if routesChangedButNotApproved {
17601774 needsRouteUpdate = true
17611775 log .Debug ().
17621776 Caller ().
@@ -1793,25 +1807,26 @@ func (s *State) UpdateNodeFromMapRequest(id types.NodeID, req tailcfg.MapRequest
17931807 return change .NodeAdded (id ), nil
17941808}
17951809
1796- func hostinfoEqual (oldNode types.NodeView , new * tailcfg.Hostinfo ) bool {
1797- if ! oldNode .Valid () && new == nil {
1810+ func hostinfoEqual (oldNode types.NodeView , newHI * tailcfg.Hostinfo ) bool {
1811+ if ! oldNode .Valid () && newHI == nil {
17981812 return true
17991813 }
1800- if ! oldNode .Valid () || new == nil {
1814+
1815+ if ! oldNode .Valid () || newHI == nil {
18011816 return false
18021817 }
18031818 old := oldNode .AsStruct ().Hostinfo
18041819
1805- return old .Equal (new )
1820+ return old .Equal (newHI )
18061821}
18071822
1808- func routesChanged (oldNode types.NodeView , new * tailcfg.Hostinfo ) bool {
1823+ func routesChanged (oldNode types.NodeView , newHI * tailcfg.Hostinfo ) bool {
18091824 var oldRoutes []netip.Prefix
18101825 if oldNode .Valid () && oldNode .AsStruct ().Hostinfo != nil {
18111826 oldRoutes = oldNode .AsStruct ().Hostinfo .RoutableIPs
18121827 }
18131828
1814- newRoutes := new .RoutableIPs
1829+ newRoutes := newHI .RoutableIPs
18151830 if newRoutes == nil {
18161831 newRoutes = []netip.Prefix {}
18171832 }
0 commit comments