diff --git a/pkg/util/util.go b/pkg/util/util.go index 07a8762d0b8..1af10e01ed8 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -321,7 +321,7 @@ func isInterfaceUp(intf *net.Interface) bool { } //getFinalIP method receives all the IP addrs of a Interface -//and returns a nil if the address is Loopback , Ipv6 or nil. +//and returns a nil if the address is Loopback, Ipv6, link-local or nil. //It returns a valid IPv4 if an Ipv4 address is found in the array. func getFinalIP(addrs []net.Addr) (net.IP, error) { if len(addrs) > 0 { @@ -334,11 +334,11 @@ func getFinalIP(addrs []net.Addr) (net.IP, error) { //Only IPv4 //TODO : add IPv6 support if ip.To4() != nil { - if !ip.IsLoopback() { + if !ip.IsLoopback() && !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() { glog.V(4).Infof("IP found %v", ip) return ip, nil } else { - glog.V(4).Infof("Loopback found %v", ip) + glog.V(4).Infof("Loopback/link-local found %v", ip) } } else { glog.V(4).Infof("%v is not a valid IPv4 address", ip) @@ -399,7 +399,9 @@ func chooseHostInterfaceNativeGo() (net.IP, error) { if addrIP, _, err := net.ParseCIDR(addr.String()); err == nil { if addrIP.To4() != nil { ip = addrIP.To4() - break + if !ip.IsLinkLocalMulticast() && !ip.IsLinkLocalUnicast() { + break + } } } } diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index ba3a0da0b72..99711691916 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -379,6 +379,12 @@ docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0 virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0 ` +// Based on DigitalOcean COREOS +const gatewayfirstLinkLocal = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT +eth0 00000000 0120372D 0001 0 0 0 00000000 0 0 0 +eth0 00000000 00000000 0001 0 0 2048 00000000 0 0 0 +` + func TestGetRoutes(t *testing.T) { testCases := []struct { tcase string @@ -499,6 +505,19 @@ func (_ validNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) { return ifat, nil } +type validNetworkInterfaceWithLinkLocal struct { +} + +func (_ validNetworkInterfaceWithLinkLocal) InterfaceByName(intfName string) (*net.Interface, error) { + c := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: net.FlagUp} + return &c, nil +} +func (_ validNetworkInterfaceWithLinkLocal) Addrs(intf *net.Interface) ([]net.Addr, error) { + var ifat []net.Addr + ifat = []net.Addr{addrStruct{val: "169.254.162.166/16"}, addrStruct{val: "45.55.47.146/19"}} + return ifat, nil +} + type validNetworkInterfacewithIpv6Only struct { } @@ -577,6 +596,7 @@ func TestChooseHostInterfaceFromRoute(t *testing.T) { {"valid_routemiddle", strings.NewReader(gatewaymiddle), validNetworkInterface{}, net.ParseIP("10.254.71.145")}, {"valid_routemiddle_ipv6", strings.NewReader(gatewaymiddle), validNetworkInterfacewithIpv6Only{}, nil}, {"no internet connection", strings.NewReader(noInternetConnection), validNetworkInterface{}, nil}, + {"no non-link-local ip", strings.NewReader(gatewayfirstLinkLocal), validNetworkInterfaceWithLinkLocal{}, net.ParseIP("45.55.47.146")}, {"no route", strings.NewReader(nothing), validNetworkInterface{}, nil}, {"no route file", nil, validNetworkInterface{}, nil}, {"no interfaces", nil, noNetworkInterface{}, nil},