瀏覽代碼

Merge pull request #817 from aboch/pip

Add support for Endpoint's preferred IPv6 address
Madhu Venugopal 9 年之前
父節點
當前提交
c8dcb0340d
共有 1 個文件被更改,包括 23 次插入7 次删除
  1. 23 7
      libnetwork/endpoint.go

+ 23 - 7
libnetwork/endpoint.go

@@ -61,6 +61,7 @@ type endpoint struct {
 	generic       map[string]interface{}
 	joinLeaveDone chan struct{}
 	prefAddress   net.IP
+	prefAddressV6 net.IP
 	ipamOptions   map[string]string
 	dbIndex       uint64
 	dbExists      bool
@@ -688,9 +689,10 @@ func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
 }
 
 // CreateOptionIpam function returns an option setter for the ipam configuration for this endpoint
-func CreateOptionIpam(prefAddress net.IP, ipamOptions map[string]string) EndpointOption {
+func CreateOptionIpam(ipV4, ipV6 net.IP, ipamOptions map[string]string) EndpointOption {
 	return func(ep *endpoint) {
-		ep.prefAddress = prefAddress
+		ep.prefAddress = ipV4
+		ep.prefAddressV6 = ipV6
 		ep.ipamOptions = ipamOptions
 	}
 }
@@ -775,6 +777,8 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 	var (
 		poolID  *string
 		address **net.IPNet
+		prefAdd net.IP
+		progAdd net.IP
 	)
 
 	n := ep.getNetwork()
@@ -782,9 +786,11 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 	case 4:
 		poolID = &ep.iface.v4PoolID
 		address = &ep.iface.addr
+		prefAdd = ep.prefAddress
 	case 6:
 		poolID = &ep.iface.v6PoolID
 		address = &ep.iface.addrv6
+		prefAdd = ep.prefAddressV6
 	default:
 		return types.InternalErrorf("incorrect ip version number passed: %d", ipVer)
 	}
@@ -796,12 +802,19 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 		return nil
 	}
 
+	// The address to program may be chosen by the user or by the network driver in one specific
+	// case to support backward compatibility with `docker daemon --fixed-cidrv6` use case
+	if prefAdd != nil {
+		progAdd = prefAdd
+	} else if *address != nil {
+		progAdd = (*address).IP
+	}
+
 	for _, d := range ipInfo {
-		var prefIP net.IP
-		if *address != nil {
-			prefIP = (*address).IP
+		if progAdd != nil && !d.Pool.Contains(progAdd) {
+			continue
 		}
-		addr, _, err := ipam.RequestAddress(d.PoolID, prefIP, ep.ipamOptions)
+		addr, _, err := ipam.RequestAddress(d.PoolID, progAdd, ep.ipamOptions)
 		if err == nil {
 			ep.Lock()
 			*address = addr
@@ -809,10 +822,13 @@ func (ep *endpoint) assignAddressVersion(ipVer int, ipam ipamapi.Ipam) error {
 			ep.Unlock()
 			return nil
 		}
-		if err != ipamapi.ErrNoAvailableIPs {
+		if err != ipamapi.ErrNoAvailableIPs || progAdd != nil {
 			return err
 		}
 	}
+	if progAdd != nil {
+		return types.BadRequestErrorf("Invalid preferred address %s: It does not belong to any of this network's subnets")
+	}
 	return fmt.Errorf("no available IPv%d addresses on this network's address pools: %s (%s)", ipVer, n.Name(), n.ID())
 }