diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index 14cc8f1503..594c48a0e1 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -204,12 +204,12 @@ func buildEndpointResource(e libnetwork.Endpoint) types.EndpointResource { if mac := iface.MacAddress(); mac != nil { er.MacAddress = mac.String() } - if ip := iface.Address(); len(ip.IP) > 0 { - er.IPv4Address = (&ip).String() + if ip := iface.Address(); ip != nil && len(ip.IP) > 0 { + er.IPv4Address = ip.String() } - if ipv6 := iface.AddressIPv6(); len(ipv6.IP) > 0 { - er.IPv6Address = (&ipv6).String() + if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 { + er.IPv6Address = ipv6.String() } } return er diff --git a/daemon/container_unix.go b/daemon/container_unix.go index 26462b43c5..6497453ecc 100644 --- a/daemon/container_unix.go +++ b/daemon/container_unix.go @@ -30,6 +30,7 @@ import ( "github.com/docker/docker/volume" "github.com/docker/docker/volume/store" "github.com/docker/libnetwork" + "github.com/docker/libnetwork/drivers/bridge" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/options" "github.com/docker/libnetwork/types" @@ -651,11 +652,13 @@ func (container *Container) buildEndpointInfo(ep libnetwork.Endpoint, networkSet return networkSettings, nil } - ones, _ := iface.Address().Mask.Size() - networkSettings.IPAddress = iface.Address().IP.String() - networkSettings.IPPrefixLen = ones + if iface.Address() != nil { + ones, _ := iface.Address().Mask.Size() + networkSettings.IPAddress = iface.Address().IP.String() + networkSettings.IPPrefixLen = ones + } - if iface.AddressIPv6().IP.To16() != nil { + if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil { onesv6, _ := iface.AddressIPv6().Mask.Size() networkSettings.GlobalIPv6Address = iface.AddressIPv6().IP.String() networkSettings.GlobalIPv6PrefixLen = onesv6 @@ -861,9 +864,8 @@ func createNetwork(controller libnetwork.NetworkController, dnet string, driver // Bridge driver is special due to legacy reasons if runconfig.NetworkMode(driver).IsBridge() { - genericOption[netlabel.GenericData] = map[string]interface{}{ - "BridgeName": dnet, - "AllowNonDefaultBridge": "true", + genericOption[netlabel.GenericData] = map[string]string{ + bridge.BridgeName: dnet, } networkOption := libnetwork.NetworkOptionGeneric(genericOption) createOptions = append(createOptions, networkOption) @@ -1163,7 +1165,7 @@ func (container *Container) disconnectFromNetwork(n libnetwork.Network, updateSe n.WalkEndpoints(s) if ep == nil { - return fmt.Errorf("could not locate network endpoint for container %s", container.ID) + return fmt.Errorf("container %s is not connected to the network", container.ID) } if err := ep.Leave(sbox); err != nil { diff --git a/daemon/daemon_unix.go b/daemon/daemon_unix.go index d251d070c7..3e6c7a6a43 100644 --- a/daemon/daemon_unix.go +++ b/daemon/daemon_unix.go @@ -7,6 +7,7 @@ import ( "net" "os" "path/filepath" + "strconv" "strings" "syscall" @@ -23,8 +24,11 @@ import ( "github.com/docker/docker/utils" "github.com/docker/libnetwork" nwconfig "github.com/docker/libnetwork/config" + "github.com/docker/libnetwork/drivers/bridge" + "github.com/docker/libnetwork/ipamutils" "github.com/docker/libnetwork/netlabel" "github.com/docker/libnetwork/options" + "github.com/docker/libnetwork/types" "github.com/opencontainers/runc/libcontainer/label" "github.com/vishvananda/netlink" ) @@ -312,6 +316,9 @@ func (daemon *Daemon) networkOptions(dconfig *Config) ([]nwconfig.Option, error) if dconfig == nil { return options, nil } + + options = append(options, nwconfig.OptionDataDir(dconfig.Root)) + if strings.TrimSpace(dconfig.DefaultNetwork) != "" { dn := strings.Split(dconfig.DefaultNetwork, ":") if len(dn) < 2 { @@ -392,22 +399,48 @@ func driverOptions(config *Config) []nwconfig.Option { } func initBridgeDriver(controller libnetwork.NetworkController, config *Config) error { - netOption := options.Generic{ - "BridgeName": config.Bridge.Iface, - "DefaultBridge": true, - "Mtu": config.Mtu, - "EnableIPMasquerade": config.Bridge.EnableIPMasq, - "EnableICC": config.Bridge.InterContainerCommunication, + if n, err := controller.NetworkByName("bridge"); err == nil { + if err = n.Delete(); err != nil { + return fmt.Errorf("could not delete the default bridge network: %v", err) + } + } + + bridgeName := bridge.DefaultBridgeName + if config.Bridge.Iface != "" { + bridgeName = config.Bridge.Iface + } + netOption := map[string]string{ + bridge.BridgeName: bridgeName, + bridge.DefaultBridge: strconv.FormatBool(true), + netlabel.DriverMTU: strconv.Itoa(config.Mtu), + bridge.EnableIPMasquerade: strconv.FormatBool(config.Bridge.EnableIPMasq), + bridge.EnableICC: strconv.FormatBool(config.Bridge.InterContainerCommunication), + } + + // --ip processing + if config.Bridge.DefaultIP != nil { + netOption[bridge.DefaultBindingIP] = config.Bridge.DefaultIP.String() + } + + ipamV4Conf := libnetwork.IpamConf{} + + ipamV4Conf.AuxAddresses = make(map[string]string) + + if nw, _, err := ipamutils.ElectInterfaceAddresses(bridgeName); err == nil { + ipamV4Conf.PreferredPool = nw.String() + hip, _ := types.GetHostPartIP(nw.IP, nw.Mask) + if hip.IsGlobalUnicast() { + ipamV4Conf.Gateway = nw.IP.String() + } } if config.Bridge.IP != "" { - ip, bipNet, err := net.ParseCIDR(config.Bridge.IP) + ipamV4Conf.PreferredPool = config.Bridge.IP + ip, _, err := net.ParseCIDR(config.Bridge.IP) if err != nil { return err } - - bipNet.IP = ip - netOption["AddressIPv4"] = bipNet + ipamV4Conf.Gateway = ip.String() } if config.Bridge.FixedCIDR != "" { @@ -416,38 +449,44 @@ func initBridgeDriver(controller libnetwork.NetworkController, config *Config) e return err } - netOption["FixedCIDR"] = fCIDR + ipamV4Conf.SubPool = fCIDR.String() } + if config.Bridge.DefaultGatewayIPv4 != nil { + ipamV4Conf.AuxAddresses["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4.String() + } + + var ipamV6Conf *libnetwork.IpamConf if config.Bridge.FixedCIDRv6 != "" { _, fCIDRv6, err := net.ParseCIDR(config.Bridge.FixedCIDRv6) if err != nil { return err } - - netOption["FixedCIDRv6"] = fCIDRv6 - } - - if config.Bridge.DefaultGatewayIPv4 != nil { - netOption["DefaultGatewayIPv4"] = config.Bridge.DefaultGatewayIPv4 + if ipamV6Conf == nil { + ipamV6Conf = &libnetwork.IpamConf{} + } + ipamV6Conf.PreferredPool = fCIDRv6.String() } if config.Bridge.DefaultGatewayIPv6 != nil { - netOption["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6 + if ipamV6Conf == nil { + ipamV6Conf = &libnetwork.IpamConf{} + } + ipamV6Conf.AuxAddresses["DefaultGatewayIPv6"] = config.Bridge.DefaultGatewayIPv6.String() } - // --ip processing - if config.Bridge.DefaultIP != nil { - netOption["DefaultBindingIP"] = config.Bridge.DefaultIP + v4Conf := []*libnetwork.IpamConf{&ipamV4Conf} + v6Conf := []*libnetwork.IpamConf{} + if ipamV6Conf != nil { + v6Conf = append(v6Conf, ipamV6Conf) } - // Initialize default network on "bridge" with the same name _, err := controller.NewNetwork("bridge", "bridge", libnetwork.NetworkOptionGeneric(options.Generic{ netlabel.GenericData: netOption, netlabel.EnableIPv6: config.Bridge.EnableIPv6, }), - libnetwork.NetworkOptionPersist(false)) + libnetwork.NetworkOptionIpam("default", "", v4Conf, v6Conf)) if err != nil { return fmt.Errorf("Error creating default \"bridge\" network: %v", err) } diff --git a/daemon/network.go b/daemon/network.go index 546828a4c3..6bebb6812a 100644 --- a/daemon/network.go +++ b/daemon/network.go @@ -6,6 +6,7 @@ import ( "github.com/docker/libnetwork" "github.com/docker/libnetwork/netlabel" + "github.com/docker/libnetwork/options" ) const ( @@ -78,29 +79,14 @@ func (daemon *Daemon) GetNetworksByID(partialID string) []libnetwork.Network { } // CreateNetwork creates a network with the given name, driver and other optional parameters -func (daemon *Daemon) CreateNetwork(name, driver string, options map[string]interface{}) (libnetwork.Network, error) { +func (daemon *Daemon) CreateNetwork(name, driver string, labels map[string]interface{}) (libnetwork.Network, error) { c := daemon.netController if driver == "" { driver = c.Config().Daemon.DefaultDriver } + option := libnetwork.NetworkOptionGeneric(options.Generic{ + netlabel.GenericData: map[string]string{}, + }) - if options == nil { - options = make(map[string]interface{}) - } - _, ok := options[netlabel.GenericData] - if !ok { - options[netlabel.GenericData] = make(map[string]interface{}) - } - - return c.NewNetwork(driver, name, parseOptions(options)...) -} - -func parseOptions(options map[string]interface{}) []libnetwork.NetworkOption { - var setFctList []libnetwork.NetworkOption - - if options != nil { - setFctList = append(setFctList, libnetwork.NetworkOptionGeneric(options)) - } - - return setFctList + return c.NewNetwork(driver, name, option) } diff --git a/daemon/stats.go b/daemon/stats.go index 74d5bfc1d0..ae3a2d918b 100644 --- a/daemon/stats.go +++ b/daemon/stats.go @@ -8,7 +8,7 @@ import ( "github.com/docker/docker/api/types/versions/v1p20" "github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/pkg/version" - "github.com/docker/libnetwork/osl" + lntypes "github.com/docker/libnetwork/types" "github.com/opencontainers/runc/libcontainer" ) @@ -166,7 +166,7 @@ func (daemon *Daemon) getNetworkStats(c *Container) ([]*libcontainer.NetworkInte return list, nil } -func convertLnNetworkStats(name string, stats *osl.InterfaceStatistics) *libcontainer.NetworkInterface { +func convertLnNetworkStats(name string, stats *lntypes.InterfaceStatistics) *libcontainer.NetworkInterface { n := &libcontainer.NetworkInterface{Name: name} n.RxBytes = stats.RxBytes n.RxPackets = stats.RxPackets diff --git a/integration-cli/docker_cli_daemon_test.go b/integration-cli/docker_cli_daemon_test.go index b28c8404ab..d650f1871b 100644 --- a/integration-cli/docker_cli_daemon_test.go +++ b/integration-cli/docker_cli_daemon_test.go @@ -787,7 +787,7 @@ func (s *DockerDaemonSuite) TestDaemonBridgeFixedCidr(c *check.C) { cName := "Container" + strconv.Itoa(i) out, err := d.Cmd("run", "-d", "--name", cName, "busybox", "top") if err != nil { - c.Assert(strings.Contains(out, "no available ip addresses"), check.Equals, true, + c.Assert(strings.Contains(out, "no available IPv4 addresses"), check.Equals, true, check.Commentf("Could not run a Container : %s %s", err.Error(), out)) } }