Pass a canonical subnet to ipallocator

- Currently both network and host bits in the subnet are passed
  when requesting an address from ipallocator.
  The way ip allocator determines the first available
  IP is tainted when caller passes the subnet host bits.

- Verified this patch applied to libnetwork vendored in docker
  fixes the issue when starting the daemon.

- Fixes #287

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch
2015-06-11 23:21:50 -07:00
parent 092460013c
commit 746bcb1dd3
3 changed files with 23 additions and 6 deletions
+3 -1
View File
@@ -877,7 +877,9 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
}
// v4 address for the sandbox side pipe interface
ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
sub := types.GetIPNetCopy(n.bridge.bridgeIPv4)
sub.IP = sub.IP.Mask(sub.Mask)
ip4, err := ipAllocator.RequestIP(sub, nil)
if err != nil {
return err
}
+14 -4
View File
@@ -23,11 +23,21 @@ func TestCreateFullOptions(t *testing.T) {
EnableIPForwarding: true,
}
// Test this scenario: Default gw address does not belong to
// container network and it's greater than bridge address
cip, cnw, _ := net.ParseCIDR("172.16.122.0/24")
cnw.IP = cip
ip, nw, _ := net.ParseCIDR("172.16.0.10/16")
nw.IP = ip
gw := net.ParseIP("172.16.0.1")
netConfig := &networkConfiguration{
BridgeName: DefaultBridgeName,
EnableIPv6: true,
FixedCIDR: bridgeNetworks[0],
EnableIPTables: true,
BridgeName: DefaultBridgeName,
AddressIPv4: nw,
FixedCIDR: cnw,
DefaultGatewayIPv4: gw,
EnableIPv6: true,
EnableIPTables: true,
}
_, netConfig.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
genericOption := make(map[string]interface{})
+6 -1
View File
@@ -8,6 +8,7 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
@@ -109,7 +110,11 @@ func setupGatewayIPv4(config *networkConfiguration, i *bridgeInterface) error {
if !i.bridgeIPv4.Contains(config.DefaultGatewayIPv4) {
return &ErrInvalidGateway{}
}
if _, err := ipAllocator.RequestIP(i.bridgeIPv4, config.DefaultGatewayIPv4); err != nil {
// Pass the real network subnet to ip allocator (no host bits set)
sub := types.GetIPNetCopy(i.bridgeIPv4)
sub.IP = sub.IP.Mask(sub.Mask)
if _, err := ipAllocator.RequestIP(sub, config.DefaultGatewayIPv4); err != nil {
return err
}