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 3ed19169a3
commit 3d805de246
3 changed files with 23 additions and 6 deletions

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
}

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{})

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
}