From 562e3981e7da1449d8a29b67202b1dae6efaa353 Mon Sep 17 00:00:00 2001 From: Viktor Liu Date: Fri, 14 Jun 2024 18:46:05 +0900 Subject: [PATCH] Fix rebasing --- .../routemanager/systemops/systemops.go | 55 ---------------- .../systemops/systemops_darwin_test.go | 0 .../systemops/systemops_generic.go | 62 ++++++++++++++++++- .../routemanager/systemops/systemops_ios.go | 0 .../routemanager/systemops/systemops_linux.go | 7 +++ .../systemops/systemops_mobile.go | 12 ---- .../systemops/systemops_nonlinux.go | 8 --- .../systemops/systemops_windows.go | 4 +- util/net/net.go | 1 + 9 files changed, 68 insertions(+), 81 deletions(-) delete mode 100644 client/internal/routemanager/systemops/systemops_darwin_test.go delete mode 100644 client/internal/routemanager/systemops/systemops_ios.go diff --git a/client/internal/routemanager/systemops/systemops.go b/client/internal/routemanager/systemops/systemops.go index d465aa8fc03..9ee51538b5a 100644 --- a/client/internal/routemanager/systemops/systemops.go +++ b/client/internal/routemanager/systemops/systemops.go @@ -25,58 +25,3 @@ func NewSysOps(wgInterface *iface.WGIface) *SysOps { wgInterface: wgInterface, } } - -// IsAddrRouted checks if the candidate address would route to the vpn, in which case it returns true and the matched prefix. -func IsAddrRouted(addr netip.Addr, vpnRoutes []netip.Prefix) (bool, netip.Prefix) { - localRoutes, err := hasSeparateRouting() - if err != nil { - if !errors.Is(err, ErrRoutingIsSeparate) { - log.Errorf("Failed to get routes: %v", err) - } - return false, netip.Prefix{} - } - - return isVpnRoute(addr, vpnRoutes, localRoutes) -} - -func isVpnRoute(addr netip.Addr, vpnRoutes []netip.Prefix, localRoutes []netip.Prefix) (bool, netip.Prefix) { - vpnPrefixMap := map[netip.Prefix]struct{}{} - for _, prefix := range vpnRoutes { - vpnPrefixMap[prefix] = struct{}{} - } - - // remove vpnRoute duplicates - for _, prefix := range localRoutes { - delete(vpnPrefixMap, prefix) - } - - var longestPrefix netip.Prefix - var isVpn bool - - combinedRoutes := make([]netip.Prefix, len(vpnRoutes)+len(localRoutes)) - copy(combinedRoutes, vpnRoutes) - copy(combinedRoutes[len(vpnRoutes):], localRoutes) - - for _, prefix := range combinedRoutes { - // Ignore the default route, it has special handling - if prefix.Bits() == 0 { - continue - } - - if prefix.Contains(addr) { - // Longest prefix match - if !longestPrefix.IsValid() || prefix.Bits() > longestPrefix.Bits() { - longestPrefix = prefix - _, isVpn = vpnPrefixMap[prefix] - } - } - } - - if !longestPrefix.IsValid() { - // No route matched - return false, netip.Prefix{} - } - - // Return true if the longest matching prefix is from vpnRoutes - return isVpn, longestPrefix -} diff --git a/client/internal/routemanager/systemops/systemops_darwin_test.go b/client/internal/routemanager/systemops/systemops_darwin_test.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/client/internal/routemanager/systemops/systemops_generic.go b/client/internal/routemanager/systemops/systemops_generic.go index 01b9ebda6cf..53bab6edf40 100644 --- a/client/internal/routemanager/systemops/systemops_generic.go +++ b/client/internal/routemanager/systemops/systemops_generic.go @@ -16,7 +16,6 @@ import ( log "github.com/sirupsen/logrus" nberrors "github.com/netbirdio/netbird/client/errors" - "github.com/netbirdio/netbird/client/internal/peer" "github.com/netbirdio/netbird/client/internal/routemanager/refcounter" "github.com/netbirdio/netbird/client/internal/routemanager/util" "github.com/netbirdio/netbird/client/internal/routemanager/vars" @@ -29,7 +28,9 @@ var splitDefaultv4_2 = netip.PrefixFrom(netip.AddrFrom4([4]byte{128}), 1) var splitDefaultv6_1 = netip.PrefixFrom(netip.IPv6Unspecified(), 1) var splitDefaultv6_2 = netip.PrefixFrom(netip.AddrFrom16([16]byte{0x80}), 1) -func (r *SysOps) setupRefCounter(initAddresses []net.IP) (peer.BeforeAddPeerHookFunc, peer.AfterRemovePeerHookFunc, error) { +var ErrRoutingIsSeparate = errors.New("routing is separate") + +func (r *SysOps) setupRefCounter(initAddresses []net.IP) (nbnet.AddHookFunc, nbnet.RemoveHookFunc, error) { initialNextHopV4, err := GetNextHop(netip.IPv4Unspecified()) if err != nil && !errors.Is(err, vars.ErrRouteNotFound) { log.Errorf("Unable to get initial v4 default next hop: %v", err) @@ -273,7 +274,7 @@ func (r *SysOps) genericRemoveVPNRoute(prefix netip.Prefix, intf *net.Interface) return r.removeFromRouteTable(prefix, nextHop) } -func (r *SysOps) setupHooks(initAddresses []net.IP) (peer.BeforeAddPeerHookFunc, peer.AfterRemovePeerHookFunc, error) { +func (r *SysOps) setupHooks(initAddresses []net.IP) (nbnet.AddHookFunc, nbnet.RemoveHookFunc, error) { beforeHook := func(connID nbnet.ConnectionID, ip net.IP) error { prefix, err := util.GetPrefixFromIP(ip) if err != nil { @@ -414,3 +415,58 @@ func isSubRange(prefix netip.Prefix) (bool, error) { } return false, nil } + +// IsAddrRouted checks if the candidate address would route to the vpn, in which case it returns true and the matched prefix. +func IsAddrRouted(addr netip.Addr, vpnRoutes []netip.Prefix) (bool, netip.Prefix) { + localRoutes, err := hasSeparateRouting() + if err != nil { + if !errors.Is(err, ErrRoutingIsSeparate) { + log.Errorf("Failed to get routes: %v", err) + } + return false, netip.Prefix{} + } + + return isVpnRoute(addr, vpnRoutes, localRoutes) +} + +func isVpnRoute(addr netip.Addr, vpnRoutes []netip.Prefix, localRoutes []netip.Prefix) (bool, netip.Prefix) { + vpnPrefixMap := map[netip.Prefix]struct{}{} + for _, prefix := range vpnRoutes { + vpnPrefixMap[prefix] = struct{}{} + } + + // remove vpnRoute duplicates + for _, prefix := range localRoutes { + delete(vpnPrefixMap, prefix) + } + + var longestPrefix netip.Prefix + var isVpn bool + + combinedRoutes := make([]netip.Prefix, len(vpnRoutes)+len(localRoutes)) + copy(combinedRoutes, vpnRoutes) + copy(combinedRoutes[len(vpnRoutes):], localRoutes) + + for _, prefix := range combinedRoutes { + // Ignore the default route, it has special handling + if prefix.Bits() == 0 { + continue + } + + if prefix.Contains(addr) { + // Longest prefix match + if !longestPrefix.IsValid() || prefix.Bits() > longestPrefix.Bits() { + longestPrefix = prefix + _, isVpn = vpnPrefixMap[prefix] + } + } + } + + if !longestPrefix.IsValid() { + // No route matched + return false, netip.Prefix{} + } + + // Return true if the longest matching prefix is from vpnRoutes + return isVpn, longestPrefix +} diff --git a/client/internal/routemanager/systemops/systemops_ios.go b/client/internal/routemanager/systemops/systemops_ios.go deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/client/internal/routemanager/systemops/systemops_linux.go b/client/internal/routemanager/systemops/systemops_linux.go index bd13a561d71..c4f69fba5c0 100644 --- a/client/internal/routemanager/systemops/systemops_linux.go +++ b/client/internal/routemanager/systemops/systemops_linux.go @@ -501,3 +501,10 @@ func getAddressFamily(prefix netip.Prefix) int { } return netlink.FAMILY_V6 } + +func hasSeparateRouting() ([]netip.Prefix, error) { + if isLegacy() { + return getRoutesFromTable() + } + return nil, ErrRoutingIsSeparate +} diff --git a/client/internal/routemanager/systemops/systemops_mobile.go b/client/internal/routemanager/systemops/systemops_mobile.go index b1683ca9fd9..43815c65705 100644 --- a/client/internal/routemanager/systemops/systemops_mobile.go +++ b/client/internal/routemanager/systemops/systemops_mobile.go @@ -33,18 +33,6 @@ func EnableIPForwarding() error { return nil } -func hasSeparateRouting() ([]netip.Prefix, error) { - return nil, ErrRoutingIsSeparate -} - -func AddVPNRoute(netip.Prefix, *net.Interface) error { - return nil -} - -func RemoveVPNRoute(netip.Prefix, *net.Interface) error { - return nil -} - func IsAddrRouted(netip.Addr, []netip.Prefix) (bool, netip.Prefix) { return false, netip.Prefix{} } diff --git a/client/internal/routemanager/systemops/systemops_nonlinux.go b/client/internal/routemanager/systemops/systemops_nonlinux.go index 6793bfacc11..0adeb09927c 100644 --- a/client/internal/routemanager/systemops/systemops_nonlinux.go +++ b/client/internal/routemanager/systemops/systemops_nonlinux.go @@ -23,14 +23,6 @@ func EnableIPForwarding() error { return nil } -func AddVPNRoute(prefix netip.Prefix, intf *net.Interface) error { - return genericAddVPNRoute(prefix, intf) -} - -func RemoveVPNRoute(prefix netip.Prefix, intf *net.Interface) error { - return genericRemoveVPNRoute(prefix, intf) -} - func hasSeparateRouting() ([]netip.Prefix, error) { return getRoutesFromTable() } diff --git a/client/internal/routemanager/systemops/systemops_windows.go b/client/internal/routemanager/systemops/systemops_windows.go index 1888dc44590..a0b5fb1e516 100644 --- a/client/internal/routemanager/systemops/systemops_windows.go +++ b/client/internal/routemanager/systemops/systemops_windows.go @@ -17,8 +17,6 @@ import ( "github.com/yusufpapurcu/wmi" "github.com/netbirdio/netbird/client/firewall/uspfilter" - "github.com/netbirdio/netbird/client/internal/peer" - "github.com/netbirdio/netbird/iface" nbnet "github.com/netbirdio/netbird/util/net" ) @@ -58,7 +56,7 @@ var prefixList []netip.Prefix var lastUpdate time.Time var mux = sync.Mutex{} -func (r *SysOps) SetupRouting(initAddresses []net.IP) (peer.BeforeAddPeerHookFunc, peer.AfterRemovePeerHookFunc, error) { +func (r *SysOps) SetupRouting(initAddresses []net.IP) (nbnet.AddHookFunc, nbnet.RemoveHookFunc, error) { return r.setupRefCounter(initAddresses) } diff --git a/util/net/net.go b/util/net/net.go index 24006e8ccb0..8d1fcebd0af 100644 --- a/util/net/net.go +++ b/util/net/net.go @@ -1,6 +1,7 @@ package net import ( + "net" "os" "github.com/netbirdio/netbird/iface/netstack"