From 68cae04fe9c45ef2f7d76ef80793297383e1eed5 Mon Sep 17 00:00:00 2001 From: Jana Radhakrishnan Date: Sun, 3 May 2015 20:23:52 +0000 Subject: [PATCH] Fixed a bug in bridge driver when docker0 has no IP address it doesn't select and configure a proper IP address. Signed-off-by: Jana Radhakrishnan --- libnetwork/drivers/bridge/bridge.go | 6 ++- libnetwork/drivers/bridge/bridge_test.go | 50 ++++++++++++------------ libnetwork/drivers/bridge/setup_ipv4.go | 24 ++++++++++++ 3 files changed, 54 insertions(+), 26 deletions(-) diff --git a/libnetwork/drivers/bridge/bridge.go b/libnetwork/drivers/bridge/bridge.go index 664811cd8e..41820c99cb 100644 --- a/libnetwork/drivers/bridge/bridge.go +++ b/libnetwork/drivers/bridge/bridge.go @@ -226,9 +226,11 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err bridgeAlreadyExists := bridgeIface.exists() if !bridgeAlreadyExists { bridgeSetup.queueStep(setupDevice) - bridgeSetup.queueStep(setupBridgeIPv4) } + // Even if a bridge exists try to setup IPv4. + bridgeSetup.queueStep(setupBridgeIPv4) + // Conditionnally queue setup steps depending on configuration values. for _, step := range []struct { Condition bool @@ -269,6 +271,8 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err } } + // Block bridge IP from being allocated. + bridgeSetup.queueStep(allocateBridgeIP) // Apply the prepared list of steps, and abort at the first error. bridgeSetup.queueStep(setupDeviceUp) if err = bridgeSetup.apply(); err != nil { diff --git a/libnetwork/drivers/bridge/bridge_test.go b/libnetwork/drivers/bridge/bridge_test.go index e623d40c03..e27bfd6e08 100644 --- a/libnetwork/drivers/bridge/bridge_test.go +++ b/libnetwork/drivers/bridge/bridge_test.go @@ -14,6 +14,31 @@ import ( "github.com/vishvananda/netlink" ) +func TestCreateFullOptions(t *testing.T) { + defer netutils.SetupTestNetNS(t)() + _, d := New() + + config := &Configuration{ + BridgeName: DefaultBridgeName, + EnableIPv6: true, + FixedCIDR: bridgeNetworks[0], + EnableIPTables: true, + EnableIPForwarding: true, + } + _, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48") + genericOption := make(map[string]interface{}) + genericOption[options.GenericData] = config + + if err := d.Config(genericOption); err != nil { + t.Fatalf("Failed to setup driver config: %v", err) + } + + err := d.CreateNetwork("dummy", nil) + if err != nil { + t.Fatalf("Failed to create bridge: %v", err) + } +} + func TestCreate(t *testing.T) { defer netutils.SetupTestNetNS(t)() _, d := New() @@ -48,31 +73,6 @@ func TestCreateFail(t *testing.T) { } } -func TestCreateFullOptions(t *testing.T) { - defer netutils.SetupTestNetNS(t)() - _, d := New() - - config := &Configuration{ - BridgeName: DefaultBridgeName, - EnableIPv6: true, - FixedCIDR: bridgeNetworks[0], - EnableIPTables: true, - EnableIPForwarding: true, - } - _, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48") - genericOption := make(map[string]interface{}) - genericOption[options.GenericData] = config - - if err := d.Config(genericOption); err != nil { - t.Fatalf("Failed to setup driver config: %v", err) - } - - err := d.CreateNetwork("dummy", nil) - if err != nil { - t.Fatalf("Failed to create bridge: %v", err) - } -} - func TestQueryEndpointInfo(t *testing.T) { defer netutils.SetupTestNetNS(t)() diff --git a/libnetwork/drivers/bridge/setup_ipv4.go b/libnetwork/drivers/bridge/setup_ipv4.go index 01137fb256..b21fb82197 100644 --- a/libnetwork/drivers/bridge/setup_ipv4.go +++ b/libnetwork/drivers/bridge/setup_ipv4.go @@ -41,6 +41,25 @@ func init() { } func setupBridgeIPv4(config *Configuration, i *bridgeInterface) error { + addrv4, _, err := i.addresses() + if err != nil { + return err + } + + // Check if we have an IP address already on the bridge. + if addrv4.IPNet != nil { + // Make sure to store bridge network and default gateway before getting out. + i.bridgeIPv4 = addrv4.IPNet + i.gatewayIPv4 = addrv4.IPNet.IP + return nil + } + + // Do not try to configure IPv4 on a non-default bridge unless you are + // specifically asked to do so. + if config.BridgeName != DefaultBridgeName && !config.AllowNonDefaultBridge { + return NonDefaultBridgeExistError(config.BridgeName) + } + bridgeIPv4, err := electBridgeIPv4(config) if err != nil { return err @@ -58,6 +77,11 @@ func setupBridgeIPv4(config *Configuration, i *bridgeInterface) error { return nil } +func allocateBridgeIP(config *Configuration, i *bridgeInterface) error { + ipAllocator.RequestIP(i.bridgeIPv4, i.bridgeIPv4.IP) + return nil +} + func electBridgeIPv4(config *Configuration) (*net.IPNet, error) { // Use the requested IPv4 CIDR when available. if config.AddressIPv4 != nil {