Forráskód Böngészése

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 <mrjana@docker.com>

Jana Radhakrishnan 10 éve
szülő
commit
68cae04fe9

+ 5 - 1
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 {

+ 19 - 19
libnetwork/drivers/bridge/bridge_test.go

@@ -14,11 +14,18 @@ import (
 	"github.com/vishvananda/netlink"
 )
 
-func TestCreate(t *testing.T) {
+func TestCreateFullOptions(t *testing.T) {
 	defer netutils.SetupTestNetNS(t)()
 	_, d := New()
 
-	config := &Configuration{BridgeName: DefaultBridgeName}
+	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
 
@@ -26,16 +33,17 @@ func TestCreate(t *testing.T) {
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 
-	if err := d.CreateNetwork("dummy", nil); err != nil {
+	err := d.CreateNetwork("dummy", nil)
+	if err != nil {
 		t.Fatalf("Failed to create bridge: %v", err)
 	}
 }
 
-func TestCreateFail(t *testing.T) {
+func TestCreate(t *testing.T) {
 	defer netutils.SetupTestNetNS(t)()
 	_, d := New()
 
-	config := &Configuration{BridgeName: "dummy0"}
+	config := &Configuration{BridgeName: DefaultBridgeName}
 	genericOption := make(map[string]interface{})
 	genericOption[options.GenericData] = config
 
@@ -43,23 +51,16 @@ func TestCreateFail(t *testing.T) {
 		t.Fatalf("Failed to setup driver config: %v", err)
 	}
 
-	if err := d.CreateNetwork("dummy", nil); err == nil {
-		t.Fatal("Bridge creation was expected to fail")
+	if err := d.CreateNetwork("dummy", nil); err != nil {
+		t.Fatalf("Failed to create bridge: %v", err)
 	}
 }
 
-func TestCreateFullOptions(t *testing.T) {
+func TestCreateFail(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")
+	config := &Configuration{BridgeName: "dummy0"}
 	genericOption := make(map[string]interface{})
 	genericOption[options.GenericData] = config
 
@@ -67,9 +68,8 @@ func TestCreateFullOptions(t *testing.T) {
 		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)
+	if err := d.CreateNetwork("dummy", nil); err == nil {
+		t.Fatal("Bridge creation was expected to fail")
 	}
 }
 

+ 24 - 0
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 {