From 746bcb1dd3ffb64371a892401f331fa643a6fe66 Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Thu, 11 Jun 2015 23:21:50 -0700 Subject: [PATCH] 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 --- drivers/bridge/bridge.go | 4 +++- drivers/bridge/bridge_test.go | 18 ++++++++++++++---- drivers/bridge/setup_ipv4.go | 7 ++++++- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/drivers/bridge/bridge.go b/drivers/bridge/bridge.go index 7fd2e5f..4804d12 100644 --- a/drivers/bridge/bridge.go +++ b/drivers/bridge/bridge.go @@ -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 } diff --git a/drivers/bridge/bridge_test.go b/drivers/bridge/bridge_test.go index d872e4a..760e3f6 100644 --- a/drivers/bridge/bridge_test.go +++ b/drivers/bridge/bridge_test.go @@ -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{}) diff --git a/drivers/bridge/setup_ipv4.go b/drivers/bridge/setup_ipv4.go index d05a47a..a89d81d 100644 --- a/drivers/bridge/setup_ipv4.go +++ b/drivers/bridge/setup_ipv4.go @@ -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 }