2023-04-17 11:15:37 +02:00
|
|
|
//go:build !android
|
|
|
|
|
2022-09-05 09:06:35 +02:00
|
|
|
package routemanager
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"net/netip"
|
2023-04-17 11:15:37 +02:00
|
|
|
|
|
|
|
"github.com/libp2p/go-netroute"
|
|
|
|
log "github.com/sirupsen/logrus"
|
2022-09-05 09:06:35 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var errRouteNotFound = fmt.Errorf("route not found")
|
|
|
|
|
|
|
|
func addToRouteTableIfNoExists(prefix netip.Prefix, addr string) error {
|
2023-06-09 12:35:57 +02:00
|
|
|
defaultGateway, err := getExistingRIBRouteGateway(netip.MustParsePrefix("0.0.0.0/0"))
|
2022-09-05 09:06:35 +02:00
|
|
|
if err != nil && err != errRouteNotFound {
|
|
|
|
return err
|
|
|
|
}
|
2023-06-09 12:35:57 +02:00
|
|
|
|
|
|
|
gatewayIP := netip.MustParseAddr(defaultGateway.String())
|
|
|
|
if prefix.Contains(gatewayIP) {
|
|
|
|
log.Warnf("skipping adding a new route for network %s because it overlaps with the default gateway: %s", prefix, gatewayIP)
|
|
|
|
return nil
|
2022-09-05 09:06:35 +02:00
|
|
|
}
|
|
|
|
|
2023-06-09 17:59:06 +02:00
|
|
|
ok, err := existsInRouteTable(prefix)
|
2023-06-09 12:35:57 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if ok {
|
|
|
|
log.Warnf("skipping adding a new route for network %s because it already exists", prefix)
|
2022-09-05 09:06:35 +02:00
|
|
|
return nil
|
|
|
|
}
|
2023-06-09 12:35:57 +02:00
|
|
|
|
2022-09-05 09:06:35 +02:00
|
|
|
return addToRouteTable(prefix, addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func removeFromRouteTableIfNonSystem(prefix netip.Prefix, addr string) error {
|
|
|
|
addrIP := net.ParseIP(addr)
|
|
|
|
prefixGateway, err := getExistingRIBRouteGateway(prefix)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if prefixGateway != nil && !prefixGateway.Equal(addrIP) {
|
|
|
|
log.Warnf("route for network %s is pointing to a different gateway: %s, should be pointing to: %s, not removing", prefix, prefixGateway, addrIP)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return removeFromRouteTable(prefix)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getExistingRIBRouteGateway(prefix netip.Prefix) (net.IP, error) {
|
|
|
|
r, err := netroute.New()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-06-09 17:59:06 +02:00
|
|
|
_, gateway, _, err := r.Route(prefix.Addr().AsSlice())
|
2022-09-05 09:06:35 +02:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("getting routes returned an error: %v", err)
|
|
|
|
return nil, errRouteNotFound
|
|
|
|
}
|
|
|
|
|
2022-10-31 11:54:34 +01:00
|
|
|
return gateway, nil
|
2022-09-05 09:06:35 +02:00
|
|
|
}
|