Merge pull request #12807 from paralin/fix-link-local

Always select non link-local network interface, fixes #11961.
This commit is contained in:
Nikhil Jindal 2015-08-24 15:56:55 -07:00
commit 40ba1856bc
2 changed files with 26 additions and 4 deletions

View File

@ -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
}
}
}
}

View File

@ -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},