From ee5eb4fc4eaef7c54fe259709e703741c4ee6955 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Mon, 28 Aug 2023 09:43:56 +0000 Subject: [PATCH] cmd/cli: another fix for finding default route IP The current approach to get default route IP is finding the LAN interface with the same MAC address. However, there could be multiple interfaces like that, making ctrld confused. This commit fixes this issue, by listing all possible private IPs, then sorting them and use the smallest one for router self queries. --- cmd/cli/prog.go | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/cmd/cli/prog.go b/cmd/cli/prog.go index e1850bf..2a06dc3 100644 --- a/cmd/cli/prog.go +++ b/cmd/cli/prog.go @@ -10,6 +10,7 @@ import ( "net/url" "os" "runtime" + "sort" "strconv" "sync" "syscall" @@ -401,23 +402,41 @@ func defaultRouteIP() string { if err != nil { return "" } + mainLog.Load().Debug().Str("iface", drNetIface.Name).Msg("checking default route interface") if ip := ifaceFirstPrivateIP(drNetIface); ip != "" { + mainLog.Load().Debug().Str("ip", ip).Msg("found ip with default route interface") return ip } // If we reach here, it means the default route interface is connected directly to ISP. // We need to find the LAN interface with the same Mac address with drNetIface. - var drLanNetIface *net.Interface + // + // There could be multiple LAN interfaces with the same Mac address, so we find all private + // IPs then using the smallest one. + var addrs []netip.Addr interfaces.ForeachInterface(func(i interfaces.Interface, prefixes []netip.Prefix) { if i.Name == drNetIface.Name { return } if bytes.Equal(i.HardwareAddr, drNetIface.HardwareAddr) { - drLanNetIface = i.Interface + for _, pfx := range prefixes { + addr := pfx.Addr() + if addr.IsPrivate() { + addrs = append(addrs, addr) + } + } } }) - if ip := ifaceFirstPrivateIP(drLanNetIface); ip != "" { - return ip + + if len(addrs) == 0 { + mainLog.Load().Warn().Msg("no default route IP found") + return "" } - return "" + sort.Slice(addrs, func(i, j int) bool { + return addrs[i].Less(addrs[j]) + }) + + ip := addrs[0].String() + mainLog.Load().Debug().Str("ip", ip).Msg("found LAN interface IP") + return ip }