func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error) { start := time.Now() if container.HostConfig.NetworkMode.IsContainer() { return runconfig.ErrConflictSharedNetwork } if containertypes.NetworkMode(idOrName).IsBridge() && daemon.configStore.DisableBridge { container.Config.NetworkDisabled = true return nil } if endpointConfig == nil { endpointConfig = &networktypes.EndpointSettings{} } n, config, err := daemon.findAndAttachNetwork(container, idOrName, endpointConfig) if err != nil { return err } if n == nil { return nil } var operIPAM bool if config != nil { if epConfig, ok := config.EndpointsConfig[n.Name()]; ok { if endpointConfig.IPAMConfig == nil || (endpointConfig.IPAMConfig.IPv4Address == "" && endpointConfig.IPAMConfig.IPv6Address == "" && len(endpointConfig.IPAMConfig.LinkLocalIPs) == 0) { operIPAM = true } // copy IPAMConfig and NetworkID from epConfig via AttachNetwork endpointConfig.IPAMConfig = epConfig.IPAMConfig endpointConfig.NetworkID = epConfig.NetworkID } } err = daemon.updateNetworkConfig(container, n, endpointConfig, updateSettings) if err != nil { return err } controller := daemon.netController sb := daemon.getNetworkSandbox(container) createOptions, err := container.BuildCreateEndpointOptions(n, endpointConfig, sb, daemon.configStore.DNS) if err != nil { return err } endpointName := strings.TrimPrefix(container.Name, "/") ep, err := n.CreateEndpoint(endpointName, createOptions...) if err != nil { return err } defer func() { if err != nil { if e := ep.Delete(false); e != nil { logrus.Warnf("Could not rollback container connection to network %s", idOrName) } } }() container.NetworkSettings.Networks[n.Name()] = &network.EndpointSettings{ EndpointSettings: endpointConfig, IPAMOperational: operIPAM, } if _, ok := container.NetworkSettings.Networks[n.ID()]; ok { delete(container.NetworkSettings.Networks, n.ID()) } if err := daemon.updateEndpointNetworkSettings(container, n, ep); err != nil { return err } if sb == nil { options, err := daemon.buildSandboxOptions(container) if err != nil { return err } sb, err = controller.NewSandbox(container.ID, options...) if err != nil { return err } container.UpdateSandboxNetworkSettings(sb) } joinOptions, err := container.BuildJoinOptions(n) if err != nil { return err } if err := ep.Join(sb, joinOptions...); err != nil { return err } if err := container.UpdateJoinInfo(n, ep); err != nil { return fmt.Errorf("Updating join info failed: %v", err) } container.NetworkSettings.Ports = getPortMapInfo(sb) daemon.LogNetworkEventWithAttributes(n, "connect", map[string]string{"container": container.ID}) networkActions.WithValues("connect").UpdateSince(start) return nil }