@@ -36,8 +36,8 @@ import (
36
36
"github.com/netbirdio/netbird/client/internal/routemanager/vars"
37
37
"github.com/netbirdio/netbird/client/internal/routeselector"
38
38
"github.com/netbirdio/netbird/client/internal/statemanager"
39
- relayClient "github.com/netbirdio/netbird/shared/relay/client"
40
39
"github.com/netbirdio/netbird/route"
40
+ relayClient "github.com/netbirdio/netbird/shared/relay/client"
41
41
nbnet "github.com/netbirdio/netbird/util/net"
42
42
"github.com/netbirdio/netbird/version"
43
43
)
@@ -368,7 +368,11 @@ func (m *DefaultManager) UpdateRoutes(
368
368
369
369
var merr * multierror.Error
370
370
if ! m .disableClientRoutes {
371
- filteredClientRoutes := m .routeSelector .FilterSelected (clientRoutes )
371
+
372
+ // Update route selector based on management server's isSelected status
373
+ m .updateRouteSelectorFromManagement (clientRoutes )
374
+
375
+ filteredClientRoutes := m .routeSelector .FilterSelectedExitNodes (clientRoutes )
372
376
373
377
if err := m .updateSystemRoutes (filteredClientRoutes ); err != nil {
374
378
merr = multierror .Append (merr , fmt .Errorf ("update system routes: %w" , err ))
@@ -430,7 +434,7 @@ func (m *DefaultManager) TriggerSelection(networks route.HAMap) {
430
434
m .mux .Lock ()
431
435
defer m .mux .Unlock ()
432
436
433
- networks = m .routeSelector .FilterSelected (networks )
437
+ networks = m .routeSelector .FilterSelectedExitNodes (networks )
434
438
435
439
m .notifier .OnNewRoutes (networks )
436
440
@@ -583,3 +587,106 @@ func resolveURLsToIPs(urls []string) []net.IP {
583
587
}
584
588
return ips
585
589
}
590
+
591
+ // updateRouteSelectorFromManagement updates the route selector based on the isSelected status from the management server
592
+ func (m * DefaultManager ) updateRouteSelectorFromManagement (clientRoutes route.HAMap ) {
593
+ exitNodeInfo := m .collectExitNodeInfo (clientRoutes )
594
+ if len (exitNodeInfo .allIDs ) == 0 {
595
+ return
596
+ }
597
+
598
+ m .updateExitNodeSelections (exitNodeInfo )
599
+ m .logExitNodeUpdate (exitNodeInfo )
600
+ }
601
+
602
+ type exitNodeInfo struct {
603
+ allIDs []route.NetID
604
+ selectedByManagement []route.NetID
605
+ userSelected []route.NetID
606
+ userDeselected []route.NetID
607
+ }
608
+
609
+ func (m * DefaultManager ) collectExitNodeInfo (clientRoutes route.HAMap ) exitNodeInfo {
610
+ var info exitNodeInfo
611
+
612
+ for haID , routes := range clientRoutes {
613
+ if ! m .isExitNodeRoute (routes ) {
614
+ continue
615
+ }
616
+
617
+ netID := haID .NetID ()
618
+ info .allIDs = append (info .allIDs , netID )
619
+
620
+ if m .routeSelector .HasUserSelectionForRoute (netID ) {
621
+ m .categorizeUserSelection (netID , & info )
622
+ } else {
623
+ m .checkManagementSelection (routes , netID , & info )
624
+ }
625
+ }
626
+
627
+ return info
628
+ }
629
+
630
+ func (m * DefaultManager ) isExitNodeRoute (routes []* route.Route ) bool {
631
+ return len (routes ) > 0 && routes [0 ].Network .String () == vars .ExitNodeCIDR
632
+ }
633
+
634
+ func (m * DefaultManager ) categorizeUserSelection (netID route.NetID , info * exitNodeInfo ) {
635
+ if m .routeSelector .IsSelected (netID ) {
636
+ info .userSelected = append (info .userSelected , netID )
637
+ } else {
638
+ info .userDeselected = append (info .userDeselected , netID )
639
+ }
640
+ }
641
+
642
+ func (m * DefaultManager ) checkManagementSelection (routes []* route.Route , netID route.NetID , info * exitNodeInfo ) {
643
+ for _ , route := range routes {
644
+ if ! route .SkipAutoApply {
645
+ info .selectedByManagement = append (info .selectedByManagement , netID )
646
+ break
647
+ }
648
+ }
649
+ }
650
+
651
+ func (m * DefaultManager ) updateExitNodeSelections (info exitNodeInfo ) {
652
+ routesToDeselect := m .getRoutesToDeselect (info .allIDs )
653
+ m .deselectExitNodes (routesToDeselect )
654
+ m .selectExitNodesByManagement (info .selectedByManagement , info .allIDs )
655
+ }
656
+
657
+ func (m * DefaultManager ) getRoutesToDeselect (allIDs []route.NetID ) []route.NetID {
658
+ var routesToDeselect []route.NetID
659
+ for _ , netID := range allIDs {
660
+ if ! m .routeSelector .HasUserSelectionForRoute (netID ) {
661
+ routesToDeselect = append (routesToDeselect , netID )
662
+ }
663
+ }
664
+ return routesToDeselect
665
+ }
666
+
667
+ func (m * DefaultManager ) deselectExitNodes (routesToDeselect []route.NetID ) {
668
+ if len (routesToDeselect ) == 0 {
669
+ return
670
+ }
671
+
672
+ err := m .routeSelector .DeselectRoutes (routesToDeselect , routesToDeselect )
673
+ if err != nil {
674
+ log .Warnf ("Failed to deselect exit nodes: %v" , err )
675
+ }
676
+ }
677
+
678
+ func (m * DefaultManager ) selectExitNodesByManagement (selectedByManagement []route.NetID , allIDs []route.NetID ) {
679
+ if len (selectedByManagement ) == 0 {
680
+ return
681
+ }
682
+
683
+ err := m .routeSelector .SelectRoutes (selectedByManagement , true , allIDs )
684
+ if err != nil {
685
+ log .Warnf ("Failed to select exit nodes: %v" , err )
686
+ }
687
+ }
688
+
689
+ func (m * DefaultManager ) logExitNodeUpdate (info exitNodeInfo ) {
690
+ log .Debugf ("Updated route selector: %d exit nodes available, %d selected by management, %d user-selected, %d user-deselected" ,
691
+ len (info .allIDs ), len (info .selectedByManagement ), len (info .userSelected ), len (info .userDeselected ))
692
+ }
0 commit comments