mirror of
https://github.com/netbirdio/netbird.git
synced 2025-07-21 00:13:26 +02:00
87 lines
2.3 KiB
Go
87 lines
2.3 KiB
Go
package networkmonitor
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/routemanager/systemops"
|
|
)
|
|
|
|
func checkChange(ctx context.Context, nexthopv4, nexthopv6 systemops.Nexthop) error {
|
|
routeMonitor, err := systemops.NewRouteMonitor(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("create route monitor: %w", err)
|
|
}
|
|
defer func() {
|
|
if err := routeMonitor.Stop(); err != nil {
|
|
log.Errorf("Network monitor: failed to stop route monitor: %v", err)
|
|
}
|
|
}()
|
|
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return ctx.Err()
|
|
case route := <-routeMonitor.RouteUpdates():
|
|
if route.Destination.Bits() != 0 {
|
|
continue
|
|
}
|
|
|
|
if routeChanged(route, nexthopv4, nexthopv6) {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func routeChanged(route systemops.RouteUpdate, nexthopv4, nexthopv6 systemops.Nexthop) bool {
|
|
if intf := route.NextHop.Intf; intf != nil && isSoftInterface(intf.Name) {
|
|
log.Debugf("Network monitor: ignoring default route change for next hop with soft interface %s", route.NextHop)
|
|
return false
|
|
}
|
|
|
|
// TODO: for the empty nexthop ip (on-link), determine the family differently
|
|
nexthop := nexthopv4
|
|
if route.NextHop.IP.Is6() {
|
|
nexthop = nexthopv6
|
|
}
|
|
|
|
switch route.Type {
|
|
case systemops.RouteModified, systemops.RouteAdded:
|
|
return handleRouteAddedOrModified(route, nexthop)
|
|
case systemops.RouteDeleted:
|
|
return handleRouteDeleted(route, nexthop)
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func handleRouteAddedOrModified(route systemops.RouteUpdate, nexthop systemops.Nexthop) bool {
|
|
// For added/modified routes, we care about different next hops
|
|
if !nexthop.Equal(route.NextHop) {
|
|
action := "changed"
|
|
if route.Type == systemops.RouteAdded {
|
|
action = "added"
|
|
}
|
|
log.Infof("Network monitor: default route %s: via %s", action, route.NextHop)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func handleRouteDeleted(route systemops.RouteUpdate, nexthop systemops.Nexthop) bool {
|
|
// For deleted routes, we care about our tracked next hop being deleted
|
|
if nexthop.Equal(route.NextHop) {
|
|
log.Infof("Network monitor: default route removed: via %s", route.NextHop)
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func isSoftInterface(name string) bool {
|
|
return strings.Contains(strings.ToLower(name), "isatap") || strings.Contains(strings.ToLower(name), "teredo")
|
|
}
|