github.com/brahmaroutu/docker@v1.2.1-0.20160809185609-eb28dde01f16/daemon/cluster/listen_addr_linux.go (about)

     1  // +build linux
     2  
     3  package cluster
     4  
     5  import (
     6  	"net"
     7  
     8  	"github.com/vishvananda/netlink"
     9  )
    10  
    11  func (c *Cluster) resolveSystemAddr() (net.IP, error) {
    12  	// Use the system's only device IP address, or fail if there are
    13  	// multiple addresses to choose from.
    14  	interfaces, err := netlink.LinkList()
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  
    19  	var systemAddr net.IP
    20  	var systemInterface string
    21  
    22  	for _, intf := range interfaces {
    23  		// Skip non device or inactive interfaces
    24  		if intf.Type() != "device" || intf.Attrs().Flags&net.FlagUp == 0 {
    25  			continue
    26  		}
    27  
    28  		addrs, err := netlink.AddrList(intf, netlink.FAMILY_ALL)
    29  		if err != nil {
    30  			continue
    31  		}
    32  
    33  		var interfaceAddr4, interfaceAddr6 net.IP
    34  
    35  		for _, addr := range addrs {
    36  			ipAddr := addr.IPNet.IP
    37  
    38  			// Skip loopback and link-local addresses
    39  			if !ipAddr.IsGlobalUnicast() {
    40  				continue
    41  			}
    42  
    43  			if ipAddr.To4() != nil {
    44  				if interfaceAddr4 != nil {
    45  					return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr4, ipAddr)
    46  				}
    47  				interfaceAddr4 = ipAddr
    48  			} else {
    49  				if interfaceAddr6 != nil {
    50  					return nil, errMultipleIPs(intf.Attrs().Name, intf.Attrs().Name, interfaceAddr6, ipAddr)
    51  				}
    52  				interfaceAddr6 = ipAddr
    53  			}
    54  		}
    55  
    56  		// In the case that this interface has exactly one IPv4 address
    57  		// and exactly one IPv6 address, favor IPv4 over IPv6.
    58  		if interfaceAddr4 != nil {
    59  			if systemAddr != nil {
    60  				return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr4)
    61  			}
    62  			systemAddr = interfaceAddr4
    63  			systemInterface = intf.Attrs().Name
    64  		} else if interfaceAddr6 != nil {
    65  			if systemAddr != nil {
    66  				return nil, errMultipleIPs(systemInterface, intf.Attrs().Name, systemAddr, interfaceAddr6)
    67  			}
    68  			systemAddr = interfaceAddr6
    69  			systemInterface = intf.Attrs().Name
    70  		}
    71  	}
    72  
    73  	if systemAddr == nil {
    74  		return nil, errNoIP
    75  	}
    76  
    77  	return systemAddr, nil
    78  }