Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -455,12 +455,25 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e |
| 455 | 455 |
ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4.String() |
| 456 | 456 |
} |
| 457 | 457 |
|
| 458 |
- var ipamV6Conf *libnetwork.IpamConf |
|
| 458 |
+ var ( |
|
| 459 |
+ ipamV6Conf *libnetwork.IpamConf |
|
| 460 |
+ deferIPv6Alloc bool |
|
| 461 |
+ ) |
|
| 459 | 462 |
if config.Bridge.FixedCIDRv6 != "" {
|
| 460 | 463 |
_, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6) |
| 461 | 464 |
if err != nil {
|
| 462 | 465 |
return err |
| 463 | 466 |
} |
| 467 |
+ |
|
| 468 |
+ // In case user has specified the daemon flag --fixed-cidr-v6 and the passed network has |
|
| 469 |
+ // at least 48 host bits, we need to guarantee the current behavior where the containers' |
|
| 470 |
+ // IPv6 addresses will be constructed based on the containers' interface MAC address. |
|
| 471 |
+ // We do so by telling libnetwork to defer the IPv6 address allocation for the endpoints |
|
| 472 |
+ // on this network until after the driver has created the endpoint and returned the |
|
| 473 |
+ // constructed address. Libnetwork will then reserve this address with the ipam driver. |
|
| 474 |
+ ones, _ := fCIDRv6.Mask.Size() |
|
| 475 |
+ deferIPv6Alloc = ones <= 80 |
|
| 476 |
+ |
|
| 464 | 477 |
if ipamV6Conf == nil {
|
| 465 | 478 |
ipamV6Conf = &libnetwork.IpamConf{}
|
| 466 | 479 |
} |
| ... | ... |
@@ -485,7 +498,8 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e |
| 485 | 485 |
netlabel.GenericData: netOption, |
| 486 | 486 |
netlabel.EnableIPv6: config.Bridge.EnableIPv6, |
| 487 | 487 |
}), |
| 488 |
- libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf))
|
|
| 488 |
+ libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf),
|
|
| 489 |
+ libnetwork.NetworkOptionDeferIPv6Alloc(deferIPv6Alloc)) |
|
| 489 | 490 |
if err != nil {
|
| 490 | 491 |
return fmt.Errorf("Error creating default \"bridge\" network: %v", err)
|
| 491 | 492 |
} |
| ... | ... |
@@ -377,6 +377,29 @@ func (s *DockerSuite) TestDaemonIPv6FixedCIDR(c *check.C) {
|
| 377 | 377 |
} |
| 378 | 378 |
} |
| 379 | 379 |
|
| 380 |
+// TestDaemonIPv6FixedCIDRAndMac checks that when the daemon is started with ipv6 fixed CIDR |
|
| 381 |
+// the running containers are given a an IPv6 address derived from the MAC address and the ipv6 fixed CIDR |
|
| 382 |
+func (s *DockerSuite) TestDaemonIPv6FixedCIDRAndMac(c *check.C) {
|
|
| 383 |
+ err := setupV6() |
|
| 384 |
+ c.Assert(err, checker.IsNil) |
|
| 385 |
+ |
|
| 386 |
+ d := NewDaemon(c) |
|
| 387 |
+ |
|
| 388 |
+ err = d.StartWithBusybox("--ipv6", "--fixed-cidr-v6='2001:db8:1::/64'")
|
|
| 389 |
+ c.Assert(err, checker.IsNil) |
|
| 390 |
+ defer d.Stop() |
|
| 391 |
+ |
|
| 392 |
+ out, err := d.Cmd("run", "-itd", "--name=ipv6test", "--mac-address", "AA:BB:CC:DD:EE:FF", "busybox")
|
|
| 393 |
+ c.Assert(err, checker.IsNil) |
|
| 394 |
+ |
|
| 395 |
+ out, err = d.Cmd("inspect", "--format", "'{{.NetworkSettings.Networks.bridge.GlobalIPv6Address}}'", "ipv6test")
|
|
| 396 |
+ c.Assert(err, checker.IsNil) |
|
| 397 |
+ c.Assert(strings.Trim(out, " \r\n'"), checker.Equals, "2001:db8:1::aabb:ccdd:eeff") |
|
| 398 |
+ |
|
| 399 |
+ err = teardownV6() |
|
| 400 |
+ c.Assert(err, checker.IsNil) |
|
| 401 |
+} |
|
| 402 |
+ |
|
| 380 | 403 |
func (s *DockerDaemonSuite) TestDaemonLogLevelWrong(c *check.C) {
|
| 381 | 404 |
c.Assert(s.d.Start("--log-level=bogus"), check.NotNil, check.Commentf("Daemon shouldn't start with wrong log level"))
|
| 382 | 405 |
} |