-
-
Notifications
You must be signed in to change notification settings - Fork 555
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '0.28.0' into feature/dns-routes
- Loading branch information
Showing
3 changed files
with
121 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//go:build darwin || dragonfly || netbsd || openbsd | ||
|
||
package routemanager | ||
|
||
import "syscall" | ||
|
||
// filterRoutesByFlags - return true if need to ignore such route message because it consists specific flags. | ||
func filterRoutesByFlags(routeMessageFlags int) bool { | ||
if routeMessageFlags&syscall.RTF_UP == 0 { | ||
return true | ||
} | ||
|
||
if routeMessageFlags&(syscall.RTF_REJECT|syscall.RTF_BLACKHOLE|syscall.RTF_WASCLONED) != 0 { | ||
return true | ||
} | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//go:build: freebsd | ||
package routemanager | ||
|
||
import "syscall" | ||
|
||
// filterRoutesByFlags - return true if need to ignore such route message because it consists specific flags. | ||
func filterRoutesByFlags(routeMessageFlags int) bool { | ||
if routeMessageFlags&syscall.RTF_UP == 0 { | ||
return true | ||
} | ||
|
||
// NOTE: syscall.RTF_WASCLONED deprecated in FreeBSD 8.0 (https://www.freebsd.org/releases/8.0R/relnotes-detailed/) | ||
// a concept of cloned route (a route generated by an entry with RTF_CLONING flag) is deprecated. | ||
if routeMessageFlags&(syscall.RTF_REJECT|syscall.RTF_BLACKHOLE) != 0 { | ||
return true | ||
} | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//go:build (darwin && !ios) || dragonfly || freebsd || netbsd || openbsd | ||
|
||
package systemops | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"net/netip" | ||
"os/exec" | ||
"strings" | ||
"time" | ||
|
||
"github.com/cenkalti/backoff/v4" | ||
log "github.com/sirupsen/logrus" | ||
|
||
"github.com/netbirdio/netbird/client/internal/peer" | ||
"github.com/netbirdio/netbird/iface" | ||
) | ||
|
||
var refCounter *ExclusionCounter | ||
|
||
func SetupRouting(initAddresses []net.IP, wgIface *iface.WGIface) (peer.BeforeAddPeerHookFunc, peer.AfterRemovePeerHookFunc, error) { | ||
return setupRoutingWithRefCounter(&refCounter, initAddresses, wgIface) | ||
} | ||
|
||
func CleanupRouting() error { | ||
return cleanupRoutingWithRefCounter(refCounter) | ||
} | ||
|
||
func addToRouteTable(prefix netip.Prefix, nexthop Nexthop) error { | ||
return routeCmd("add", prefix, nexthop) | ||
} | ||
|
||
func removeFromRouteTable(prefix netip.Prefix, nexthop Nexthop) error { | ||
return routeCmd("delete", prefix, nexthop) | ||
} | ||
|
||
func routeCmd(action string, prefix netip.Prefix, nexthop Nexthop) error { | ||
inet := "-inet" | ||
network := prefix.String() | ||
if prefix.IsSingleIP() { | ||
network = prefix.Addr().String() | ||
} | ||
if prefix.Addr().Is6() { | ||
inet = "-inet6" | ||
} | ||
|
||
args := []string{"-n", action, inet, network} | ||
if nexthop.IP.IsValid() { | ||
args = append(args, nexthop.IP.Unmap().String()) | ||
} else if nexthop.Intf != nil { | ||
args = append(args, "-interface", nexthop.Intf.Name) | ||
} | ||
|
||
if err := retryRouteCmd(args); err != nil { | ||
return fmt.Errorf("failed to %s route for %s: %w", action, prefix, err) | ||
} | ||
return nil | ||
} | ||
|
||
func retryRouteCmd(args []string) error { | ||
operation := func() error { | ||
out, err := exec.Command("route", args...).CombinedOutput() | ||
log.Tracef("route %s: %s", strings.Join(args, " "), out) | ||
// https://github.com/golang/go/issues/45736 | ||
if err != nil && strings.Contains(string(out), "sysctl: cannot allocate memory") { | ||
return err | ||
} else if err != nil { | ||
return backoff.Permanent(err) | ||
} | ||
return nil | ||
} | ||
|
||
expBackOff := backoff.NewExponentialBackOff() | ||
expBackOff.InitialInterval = 50 * time.Millisecond | ||
expBackOff.MaxInterval = 500 * time.Millisecond | ||
expBackOff.MaxElapsedTime = 1 * time.Second | ||
|
||
err := backoff.Retry(operation, expBackOff) | ||
if err != nil { | ||
return fmt.Errorf("route cmd retry failed: %w", err) | ||
} | ||
return nil | ||
} |