network.go 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  1. package daemon // import "github.com/docker/docker/daemon"
  2. import (
  3. "context"
  4. "fmt"
  5. "net"
  6. "sort"
  7. "strconv"
  8. "strings"
  9. "sync"
  10. "github.com/docker/docker/api/types"
  11. containertypes "github.com/docker/docker/api/types/container"
  12. "github.com/docker/docker/api/types/filters"
  13. "github.com/docker/docker/api/types/network"
  14. "github.com/docker/docker/container"
  15. clustertypes "github.com/docker/docker/daemon/cluster/provider"
  16. internalnetwork "github.com/docker/docker/daemon/network"
  17. "github.com/docker/docker/errdefs"
  18. "github.com/docker/docker/libnetwork"
  19. lncluster "github.com/docker/docker/libnetwork/cluster"
  20. "github.com/docker/docker/libnetwork/driverapi"
  21. "github.com/docker/docker/libnetwork/ipamapi"
  22. "github.com/docker/docker/libnetwork/netlabel"
  23. "github.com/docker/docker/libnetwork/networkdb"
  24. "github.com/docker/docker/libnetwork/options"
  25. networktypes "github.com/docker/docker/libnetwork/types"
  26. "github.com/docker/docker/opts"
  27. "github.com/docker/docker/pkg/plugingetter"
  28. "github.com/docker/docker/runconfig"
  29. "github.com/docker/go-connections/nat"
  30. "github.com/pkg/errors"
  31. "github.com/sirupsen/logrus"
  32. )
  33. // PredefinedNetworkError is returned when user tries to create predefined network that already exists.
  34. type PredefinedNetworkError string
  35. func (pnr PredefinedNetworkError) Error() string {
  36. return fmt.Sprintf("operation is not permitted on predefined %s network ", string(pnr))
  37. }
  38. // Forbidden denotes the type of this error
  39. func (pnr PredefinedNetworkError) Forbidden() {}
  40. // NetworkControllerEnabled checks if the networking stack is enabled.
  41. // This feature depends on OS primitives and it's disabled in systems like Windows.
  42. func (daemon *Daemon) NetworkControllerEnabled() bool {
  43. return daemon.netController != nil
  44. }
  45. // NetworkController returns the network controller created by the daemon.
  46. func (daemon *Daemon) NetworkController() *libnetwork.Controller {
  47. return daemon.netController
  48. }
  49. // FindNetwork returns a network based on:
  50. // 1. Full ID
  51. // 2. Full Name
  52. // 3. Partial ID
  53. // as long as there is no ambiguity
  54. func (daemon *Daemon) FindNetwork(term string) (libnetwork.Network, error) {
  55. listByFullName := []libnetwork.Network{}
  56. listByPartialID := []libnetwork.Network{}
  57. for _, nw := range daemon.getAllNetworks() {
  58. if nw.ID() == term {
  59. return nw, nil
  60. }
  61. if nw.Name() == term {
  62. listByFullName = append(listByFullName, nw)
  63. }
  64. if strings.HasPrefix(nw.ID(), term) {
  65. listByPartialID = append(listByPartialID, nw)
  66. }
  67. }
  68. switch {
  69. case len(listByFullName) == 1:
  70. return listByFullName[0], nil
  71. case len(listByFullName) > 1:
  72. return nil, errdefs.InvalidParameter(errors.Errorf("network %s is ambiguous (%d matches found on name)", term, len(listByFullName)))
  73. case len(listByPartialID) == 1:
  74. return listByPartialID[0], nil
  75. case len(listByPartialID) > 1:
  76. return nil, errdefs.InvalidParameter(errors.Errorf("network %s is ambiguous (%d matches found based on ID prefix)", term, len(listByPartialID)))
  77. }
  78. // Be very careful to change the error type here, the
  79. // libnetwork.ErrNoSuchNetwork error is used by the controller
  80. // to retry the creation of the network as managed through the swarm manager
  81. return nil, errdefs.NotFound(libnetwork.ErrNoSuchNetwork(term))
  82. }
  83. // GetNetworkByID function returns a network whose ID matches the given ID.
  84. // It fails with an error if no matching network is found.
  85. func (daemon *Daemon) GetNetworkByID(id string) (libnetwork.Network, error) {
  86. c := daemon.netController
  87. if c == nil {
  88. return nil, errors.Wrap(libnetwork.ErrNoSuchNetwork(id), "netcontroller is nil")
  89. }
  90. return c.NetworkByID(id)
  91. }
  92. // GetNetworkByName function returns a network for a given network name.
  93. // If no network name is given, the default network is returned.
  94. func (daemon *Daemon) GetNetworkByName(name string) (libnetwork.Network, error) {
  95. c := daemon.netController
  96. if c == nil {
  97. return nil, libnetwork.ErrNoSuchNetwork(name)
  98. }
  99. if name == "" {
  100. name = c.Config().DefaultNetwork
  101. }
  102. return c.NetworkByName(name)
  103. }
  104. // GetNetworksByIDPrefix returns a list of networks whose ID partially matches zero or more networks
  105. func (daemon *Daemon) GetNetworksByIDPrefix(partialID string) []libnetwork.Network {
  106. c := daemon.netController
  107. if c == nil {
  108. return nil
  109. }
  110. list := []libnetwork.Network{}
  111. l := func(nw libnetwork.Network) bool {
  112. if strings.HasPrefix(nw.ID(), partialID) {
  113. list = append(list, nw)
  114. }
  115. return false
  116. }
  117. c.WalkNetworks(l)
  118. return list
  119. }
  120. // getAllNetworks returns a list containing all networks
  121. func (daemon *Daemon) getAllNetworks() []libnetwork.Network {
  122. c := daemon.netController
  123. if c == nil {
  124. return nil
  125. }
  126. return c.Networks()
  127. }
  128. type ingressJob struct {
  129. create *clustertypes.NetworkCreateRequest
  130. ip net.IP
  131. jobDone chan struct{}
  132. }
  133. var (
  134. ingressWorkerOnce sync.Once
  135. ingressJobsChannel chan *ingressJob
  136. ingressID string
  137. )
  138. func (daemon *Daemon) startIngressWorker() {
  139. ingressJobsChannel = make(chan *ingressJob, 100)
  140. go func() {
  141. //nolint: gosimple
  142. for {
  143. select {
  144. case r := <-ingressJobsChannel:
  145. if r.create != nil {
  146. daemon.setupIngress(r.create, r.ip, ingressID)
  147. ingressID = r.create.ID
  148. } else {
  149. daemon.releaseIngress(ingressID)
  150. ingressID = ""
  151. }
  152. close(r.jobDone)
  153. }
  154. }
  155. }()
  156. }
  157. // enqueueIngressJob adds a ingress add/rm request to the worker queue.
  158. // It guarantees the worker is started.
  159. func (daemon *Daemon) enqueueIngressJob(job *ingressJob) {
  160. ingressWorkerOnce.Do(daemon.startIngressWorker)
  161. ingressJobsChannel <- job
  162. }
  163. // SetupIngress setups ingress networking.
  164. // The function returns a channel which will signal the caller when the programming is completed.
  165. func (daemon *Daemon) SetupIngress(create clustertypes.NetworkCreateRequest, nodeIP string) (<-chan struct{}, error) {
  166. ip, _, err := net.ParseCIDR(nodeIP)
  167. if err != nil {
  168. return nil, err
  169. }
  170. done := make(chan struct{})
  171. daemon.enqueueIngressJob(&ingressJob{&create, ip, done})
  172. return done, nil
  173. }
  174. // ReleaseIngress releases the ingress networking.
  175. // The function returns a channel which will signal the caller when the programming is completed.
  176. func (daemon *Daemon) ReleaseIngress() (<-chan struct{}, error) {
  177. done := make(chan struct{})
  178. daemon.enqueueIngressJob(&ingressJob{nil, nil, done})
  179. return done, nil
  180. }
  181. func (daemon *Daemon) setupIngress(create *clustertypes.NetworkCreateRequest, ip net.IP, staleID string) {
  182. controller := daemon.netController
  183. controller.AgentInitWait()
  184. if staleID != "" && staleID != create.ID {
  185. daemon.releaseIngress(staleID)
  186. }
  187. if _, err := daemon.createNetwork(create.NetworkCreateRequest, create.ID, true); err != nil {
  188. // If it is any other error other than already
  189. // exists error log error and return.
  190. if _, ok := err.(libnetwork.NetworkNameError); !ok {
  191. logrus.Errorf("Failed creating ingress network: %v", err)
  192. return
  193. }
  194. // Otherwise continue down the call to create or recreate sandbox.
  195. }
  196. _, err := daemon.GetNetworkByID(create.ID)
  197. if err != nil {
  198. logrus.Errorf("Failed getting ingress network by id after creating: %v", err)
  199. }
  200. }
  201. func (daemon *Daemon) releaseIngress(id string) {
  202. controller := daemon.netController
  203. if id == "" {
  204. return
  205. }
  206. n, err := controller.NetworkByID(id)
  207. if err != nil {
  208. logrus.Errorf("failed to retrieve ingress network %s: %v", id, err)
  209. return
  210. }
  211. if err := n.Delete(libnetwork.NetworkDeleteOptionRemoveLB); err != nil {
  212. logrus.Errorf("Failed to delete ingress network %s: %v", n.ID(), err)
  213. return
  214. }
  215. }
  216. // SetNetworkBootstrapKeys sets the bootstrap keys.
  217. func (daemon *Daemon) SetNetworkBootstrapKeys(keys []*networktypes.EncryptionKey) error {
  218. err := daemon.netController.SetKeys(keys)
  219. if err == nil {
  220. // Upon successful key setting dispatch the keys available event
  221. daemon.cluster.SendClusterEvent(lncluster.EventNetworkKeysAvailable)
  222. }
  223. return err
  224. }
  225. // UpdateAttachment notifies the attacher about the attachment config.
  226. func (daemon *Daemon) UpdateAttachment(networkName, networkID, containerID string, config *network.NetworkingConfig) error {
  227. if daemon.clusterProvider == nil {
  228. return fmt.Errorf("cluster provider is not initialized")
  229. }
  230. if err := daemon.clusterProvider.UpdateAttachment(networkName, containerID, config); err != nil {
  231. return daemon.clusterProvider.UpdateAttachment(networkID, containerID, config)
  232. }
  233. return nil
  234. }
  235. // WaitForDetachment makes the cluster manager wait for detachment of
  236. // the container from the network.
  237. func (daemon *Daemon) WaitForDetachment(ctx context.Context, networkName, networkID, taskID, containerID string) error {
  238. if daemon.clusterProvider == nil {
  239. return fmt.Errorf("cluster provider is not initialized")
  240. }
  241. return daemon.clusterProvider.WaitForDetachment(ctx, networkName, networkID, taskID, containerID)
  242. }
  243. // CreateManagedNetwork creates an agent network.
  244. func (daemon *Daemon) CreateManagedNetwork(create clustertypes.NetworkCreateRequest) error {
  245. _, err := daemon.createNetwork(create.NetworkCreateRequest, create.ID, true)
  246. return err
  247. }
  248. // CreateNetwork creates a network with the given name, driver and other optional parameters
  249. func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.NetworkCreateResponse, error) {
  250. return daemon.createNetwork(create, "", false)
  251. }
  252. func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string, agent bool) (*types.NetworkCreateResponse, error) {
  253. if runconfig.IsPreDefinedNetwork(create.Name) {
  254. return nil, PredefinedNetworkError(create.Name)
  255. }
  256. var warning string
  257. nw, err := daemon.GetNetworkByName(create.Name)
  258. if err != nil {
  259. if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
  260. return nil, err
  261. }
  262. }
  263. if nw != nil {
  264. // check if user defined CheckDuplicate, if set true, return err
  265. // otherwise prepare a warning message
  266. if create.CheckDuplicate {
  267. if !agent || nw.Info().Dynamic() {
  268. return nil, libnetwork.NetworkNameError(create.Name)
  269. }
  270. }
  271. warning = fmt.Sprintf("Network with name %s (id : %s) already exists", nw.Name(), nw.ID())
  272. }
  273. c := daemon.netController
  274. driver := create.Driver
  275. if driver == "" {
  276. driver = c.Config().DefaultDriver
  277. }
  278. nwOptions := []libnetwork.NetworkOption{
  279. libnetwork.NetworkOptionEnableIPv6(create.EnableIPv6),
  280. libnetwork.NetworkOptionDriverOpts(create.Options),
  281. libnetwork.NetworkOptionLabels(create.Labels),
  282. libnetwork.NetworkOptionAttachable(create.Attachable),
  283. libnetwork.NetworkOptionIngress(create.Ingress),
  284. libnetwork.NetworkOptionScope(create.Scope),
  285. }
  286. if create.ConfigOnly {
  287. nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigOnly())
  288. }
  289. if create.IPAM != nil {
  290. ipam := create.IPAM
  291. v4Conf, v6Conf, err := getIpamConfig(ipam.Config)
  292. if err != nil {
  293. return nil, err
  294. }
  295. nwOptions = append(nwOptions, libnetwork.NetworkOptionIpam(ipam.Driver, "", v4Conf, v6Conf, ipam.Options))
  296. }
  297. if create.Internal {
  298. nwOptions = append(nwOptions, libnetwork.NetworkOptionInternalNetwork())
  299. }
  300. if agent {
  301. nwOptions = append(nwOptions, libnetwork.NetworkOptionDynamic())
  302. nwOptions = append(nwOptions, libnetwork.NetworkOptionPersist(false))
  303. }
  304. if create.ConfigFrom != nil {
  305. nwOptions = append(nwOptions, libnetwork.NetworkOptionConfigFrom(create.ConfigFrom.Network))
  306. }
  307. if agent && driver == "overlay" {
  308. nodeIP, exists := daemon.GetAttachmentStore().GetIPForNetwork(id)
  309. if !exists {
  310. return nil, fmt.Errorf("failed to find a load balancer IP to use for network: %v", id)
  311. }
  312. nwOptions = append(nwOptions, libnetwork.NetworkOptionLBEndpoint(nodeIP))
  313. }
  314. n, err := c.NewNetwork(driver, create.Name, id, nwOptions...)
  315. if err != nil {
  316. if errors.Is(err, libnetwork.ErrDataStoreNotInitialized) {
  317. //nolint: revive
  318. return nil, errors.New("This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
  319. }
  320. return nil, err
  321. }
  322. daemon.pluginRefCount(driver, driverapi.NetworkPluginEndpointType, plugingetter.Acquire)
  323. if create.IPAM != nil {
  324. daemon.pluginRefCount(create.IPAM.Driver, ipamapi.PluginEndpointType, plugingetter.Acquire)
  325. }
  326. daemon.LogNetworkEvent(n, "create")
  327. return &types.NetworkCreateResponse{
  328. ID: n.ID(),
  329. Warning: warning,
  330. }, nil
  331. }
  332. func (daemon *Daemon) pluginRefCount(driver, capability string, mode int) {
  333. var builtinDrivers []string
  334. if capability == driverapi.NetworkPluginEndpointType {
  335. builtinDrivers = daemon.netController.BuiltinDrivers()
  336. } else if capability == ipamapi.PluginEndpointType {
  337. builtinDrivers = daemon.netController.BuiltinIPAMDrivers()
  338. }
  339. for _, d := range builtinDrivers {
  340. if d == driver {
  341. return
  342. }
  343. }
  344. if daemon.PluginStore != nil {
  345. _, err := daemon.PluginStore.Get(driver, capability, mode)
  346. if err != nil {
  347. logrus.WithError(err).WithFields(logrus.Fields{"mode": mode, "driver": driver}).Error("Error handling plugin refcount operation")
  348. }
  349. }
  350. }
  351. func getIpamConfig(data []network.IPAMConfig) ([]*libnetwork.IpamConf, []*libnetwork.IpamConf, error) {
  352. ipamV4Cfg := []*libnetwork.IpamConf{}
  353. ipamV6Cfg := []*libnetwork.IpamConf{}
  354. for _, d := range data {
  355. iCfg := libnetwork.IpamConf{}
  356. iCfg.PreferredPool = d.Subnet
  357. iCfg.SubPool = d.IPRange
  358. iCfg.Gateway = d.Gateway
  359. iCfg.AuxAddresses = d.AuxAddress
  360. ip, _, err := net.ParseCIDR(d.Subnet)
  361. if err != nil {
  362. return nil, nil, fmt.Errorf("Invalid subnet %s : %v", d.Subnet, err)
  363. }
  364. if ip.To4() != nil {
  365. ipamV4Cfg = append(ipamV4Cfg, &iCfg)
  366. } else {
  367. ipamV6Cfg = append(ipamV6Cfg, &iCfg)
  368. }
  369. }
  370. return ipamV4Cfg, ipamV6Cfg, nil
  371. }
  372. // UpdateContainerServiceConfig updates a service configuration.
  373. func (daemon *Daemon) UpdateContainerServiceConfig(containerName string, serviceConfig *clustertypes.ServiceConfig) error {
  374. ctr, err := daemon.GetContainer(containerName)
  375. if err != nil {
  376. return err
  377. }
  378. ctr.NetworkSettings.Service = serviceConfig
  379. return nil
  380. }
  381. // ConnectContainerToNetwork connects the given container to the given
  382. // network. If either cannot be found, an err is returned. If the
  383. // network cannot be set up, an err is returned.
  384. func (daemon *Daemon) ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error {
  385. ctr, err := daemon.GetContainer(containerName)
  386. if err != nil {
  387. return err
  388. }
  389. return daemon.ConnectToNetwork(ctr, networkName, endpointConfig)
  390. }
  391. // DisconnectContainerFromNetwork disconnects the given container from
  392. // the given network. If either cannot be found, an err is returned.
  393. func (daemon *Daemon) DisconnectContainerFromNetwork(containerName string, networkName string, force bool) error {
  394. ctr, err := daemon.GetContainer(containerName)
  395. if err != nil {
  396. if force {
  397. return daemon.ForceEndpointDelete(containerName, networkName)
  398. }
  399. return err
  400. }
  401. return daemon.DisconnectFromNetwork(ctr, networkName, force)
  402. }
  403. // GetNetworkDriverList returns the list of plugins drivers
  404. // registered for network.
  405. func (daemon *Daemon) GetNetworkDriverList() []string {
  406. if !daemon.NetworkControllerEnabled() {
  407. return nil
  408. }
  409. pluginList := daemon.netController.BuiltinDrivers()
  410. managedPlugins := daemon.PluginStore.GetAllManagedPluginsByCap(driverapi.NetworkPluginEndpointType)
  411. for _, plugin := range managedPlugins {
  412. pluginList = append(pluginList, plugin.Name())
  413. }
  414. pluginMap := make(map[string]bool)
  415. for _, plugin := range pluginList {
  416. pluginMap[plugin] = true
  417. }
  418. networks := daemon.netController.Networks()
  419. for _, nw := range networks {
  420. if !pluginMap[nw.Type()] {
  421. pluginList = append(pluginList, nw.Type())
  422. pluginMap[nw.Type()] = true
  423. }
  424. }
  425. sort.Strings(pluginList)
  426. return pluginList
  427. }
  428. // DeleteManagedNetwork deletes an agent network.
  429. // The requirement of networkID is enforced.
  430. func (daemon *Daemon) DeleteManagedNetwork(networkID string) error {
  431. n, err := daemon.GetNetworkByID(networkID)
  432. if err != nil {
  433. return err
  434. }
  435. return daemon.deleteNetwork(n, true)
  436. }
  437. // DeleteNetwork destroys a network unless it's one of docker's predefined networks.
  438. func (daemon *Daemon) DeleteNetwork(networkID string) error {
  439. n, err := daemon.GetNetworkByID(networkID)
  440. if err != nil {
  441. return errors.Wrap(err, "could not find network by ID")
  442. }
  443. return daemon.deleteNetwork(n, false)
  444. }
  445. func (daemon *Daemon) deleteNetwork(nw libnetwork.Network, dynamic bool) error {
  446. if runconfig.IsPreDefinedNetwork(nw.Name()) && !dynamic {
  447. err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
  448. return errdefs.Forbidden(err)
  449. }
  450. if dynamic && !nw.Info().Dynamic() {
  451. if runconfig.IsPreDefinedNetwork(nw.Name()) {
  452. // Predefined networks now support swarm services. Make this
  453. // a no-op when cluster requests to remove the predefined network.
  454. return nil
  455. }
  456. err := fmt.Errorf("%s is not a dynamic network", nw.Name())
  457. return errdefs.Forbidden(err)
  458. }
  459. if err := nw.Delete(); err != nil {
  460. return errors.Wrap(err, "error while removing network")
  461. }
  462. // If this is not a configuration only network, we need to
  463. // update the corresponding remote drivers' reference counts
  464. if !nw.Info().ConfigOnly() {
  465. daemon.pluginRefCount(nw.Type(), driverapi.NetworkPluginEndpointType, plugingetter.Release)
  466. ipamType, _, _, _ := nw.Info().IpamConfig()
  467. daemon.pluginRefCount(ipamType, ipamapi.PluginEndpointType, plugingetter.Release)
  468. daemon.LogNetworkEvent(nw, "destroy")
  469. }
  470. return nil
  471. }
  472. // GetNetworks returns a list of all networks
  473. func (daemon *Daemon) GetNetworks(filter filters.Args, config types.NetworkListConfig) ([]types.NetworkResource, error) {
  474. networks := daemon.getAllNetworks()
  475. list := make([]types.NetworkResource, 0, len(networks))
  476. var idx map[string]libnetwork.Network
  477. if config.Detailed {
  478. idx = make(map[string]libnetwork.Network)
  479. }
  480. for _, n := range networks {
  481. nr := buildNetworkResource(n)
  482. list = append(list, nr)
  483. if config.Detailed {
  484. idx[nr.ID] = n
  485. }
  486. }
  487. var err error
  488. list, err = internalnetwork.FilterNetworks(list, filter)
  489. if err != nil {
  490. return nil, err
  491. }
  492. if config.Detailed {
  493. for i := range list {
  494. np := &list[i]
  495. buildDetailedNetworkResources(np, idx[np.ID], config.Verbose)
  496. list[i] = *np
  497. }
  498. }
  499. return list, nil
  500. }
  501. func buildNetworkResource(nw libnetwork.Network) types.NetworkResource {
  502. r := types.NetworkResource{}
  503. if nw == nil {
  504. return r
  505. }
  506. info := nw.Info()
  507. r.Name = nw.Name()
  508. r.ID = nw.ID()
  509. r.Created = info.Created()
  510. r.Scope = info.Scope()
  511. r.Driver = nw.Type()
  512. r.EnableIPv6 = info.IPv6Enabled()
  513. r.Internal = info.Internal()
  514. r.Attachable = info.Attachable()
  515. r.Ingress = info.Ingress()
  516. r.Options = info.DriverOptions()
  517. r.Containers = make(map[string]types.EndpointResource)
  518. buildIpamResources(&r, info)
  519. r.Labels = info.Labels()
  520. r.ConfigOnly = info.ConfigOnly()
  521. if cn := info.ConfigFrom(); cn != "" {
  522. r.ConfigFrom = network.ConfigReference{Network: cn}
  523. }
  524. peers := info.Peers()
  525. if len(peers) != 0 {
  526. r.Peers = buildPeerInfoResources(peers)
  527. }
  528. return r
  529. }
  530. func buildDetailedNetworkResources(r *types.NetworkResource, nw libnetwork.Network, verbose bool) {
  531. if nw == nil {
  532. return
  533. }
  534. epl := nw.Endpoints()
  535. for _, e := range epl {
  536. ei := e.Info()
  537. if ei == nil {
  538. continue
  539. }
  540. sb := ei.Sandbox()
  541. tmpID := e.ID()
  542. key := "ep-" + tmpID
  543. if sb != nil {
  544. key = sb.ContainerID()
  545. }
  546. r.Containers[key] = buildEndpointResource(tmpID, e.Name(), ei)
  547. }
  548. if !verbose {
  549. return
  550. }
  551. services := nw.Info().Services()
  552. r.Services = make(map[string]network.ServiceInfo)
  553. for name, service := range services {
  554. tasks := []network.Task{}
  555. for _, t := range service.Tasks {
  556. tasks = append(tasks, network.Task{
  557. Name: t.Name,
  558. EndpointID: t.EndpointID,
  559. EndpointIP: t.EndpointIP,
  560. Info: t.Info,
  561. })
  562. }
  563. r.Services[name] = network.ServiceInfo{
  564. VIP: service.VIP,
  565. Ports: service.Ports,
  566. Tasks: tasks,
  567. LocalLBIndex: service.LocalLBIndex,
  568. }
  569. }
  570. }
  571. func buildPeerInfoResources(peers []networkdb.PeerInfo) []network.PeerInfo {
  572. peerInfo := make([]network.PeerInfo, 0, len(peers))
  573. for _, peer := range peers {
  574. peerInfo = append(peerInfo, network.PeerInfo{
  575. Name: peer.Name,
  576. IP: peer.IP,
  577. })
  578. }
  579. return peerInfo
  580. }
  581. func buildIpamResources(r *types.NetworkResource, nwInfo libnetwork.NetworkInfo) {
  582. id, opts, ipv4conf, ipv6conf := nwInfo.IpamConfig()
  583. ipv4Info, ipv6Info := nwInfo.IpamInfo()
  584. r.IPAM.Driver = id
  585. r.IPAM.Options = opts
  586. r.IPAM.Config = []network.IPAMConfig{}
  587. for _, ip4 := range ipv4conf {
  588. if ip4.PreferredPool == "" {
  589. continue
  590. }
  591. iData := network.IPAMConfig{}
  592. iData.Subnet = ip4.PreferredPool
  593. iData.IPRange = ip4.SubPool
  594. iData.Gateway = ip4.Gateway
  595. iData.AuxAddress = ip4.AuxAddresses
  596. r.IPAM.Config = append(r.IPAM.Config, iData)
  597. }
  598. if len(r.IPAM.Config) == 0 {
  599. for _, ip4Info := range ipv4Info {
  600. iData := network.IPAMConfig{}
  601. iData.Subnet = ip4Info.IPAMData.Pool.String()
  602. if ip4Info.IPAMData.Gateway != nil {
  603. iData.Gateway = ip4Info.IPAMData.Gateway.IP.String()
  604. }
  605. r.IPAM.Config = append(r.IPAM.Config, iData)
  606. }
  607. }
  608. hasIpv6Conf := false
  609. for _, ip6 := range ipv6conf {
  610. if ip6.PreferredPool == "" {
  611. continue
  612. }
  613. hasIpv6Conf = true
  614. iData := network.IPAMConfig{}
  615. iData.Subnet = ip6.PreferredPool
  616. iData.IPRange = ip6.SubPool
  617. iData.Gateway = ip6.Gateway
  618. iData.AuxAddress = ip6.AuxAddresses
  619. r.IPAM.Config = append(r.IPAM.Config, iData)
  620. }
  621. if !hasIpv6Conf {
  622. for _, ip6Info := range ipv6Info {
  623. if ip6Info.IPAMData.Pool == nil {
  624. continue
  625. }
  626. iData := network.IPAMConfig{}
  627. iData.Subnet = ip6Info.IPAMData.Pool.String()
  628. iData.Gateway = ip6Info.IPAMData.Gateway.String()
  629. r.IPAM.Config = append(r.IPAM.Config, iData)
  630. }
  631. }
  632. }
  633. func buildEndpointResource(id string, name string, info libnetwork.EndpointInfo) types.EndpointResource {
  634. er := types.EndpointResource{}
  635. er.EndpointID = id
  636. er.Name = name
  637. ei := info
  638. if ei == nil {
  639. return er
  640. }
  641. if iface := ei.Iface(); iface != nil {
  642. if mac := iface.MacAddress(); mac != nil {
  643. er.MacAddress = mac.String()
  644. }
  645. if ip := iface.Address(); ip != nil && len(ip.IP) > 0 {
  646. er.IPv4Address = ip.String()
  647. }
  648. if ipv6 := iface.AddressIPv6(); ipv6 != nil && len(ipv6.IP) > 0 {
  649. er.IPv6Address = ipv6.String()
  650. }
  651. }
  652. return er
  653. }
  654. // clearAttachableNetworks removes the attachable networks
  655. // after disconnecting any connected container
  656. func (daemon *Daemon) clearAttachableNetworks() {
  657. for _, n := range daemon.getAllNetworks() {
  658. if !n.Info().Attachable() {
  659. continue
  660. }
  661. for _, ep := range n.Endpoints() {
  662. epInfo := ep.Info()
  663. if epInfo == nil {
  664. continue
  665. }
  666. sb := epInfo.Sandbox()
  667. if sb == nil {
  668. continue
  669. }
  670. containerID := sb.ContainerID()
  671. if err := daemon.DisconnectContainerFromNetwork(containerID, n.ID(), true); err != nil {
  672. logrus.Warnf("Failed to disconnect container %s from swarm network %s on cluster leave: %v",
  673. containerID, n.Name(), err)
  674. }
  675. }
  676. if err := daemon.DeleteManagedNetwork(n.ID()); err != nil {
  677. logrus.Warnf("Failed to remove swarm network %s on cluster leave: %v", n.Name(), err)
  678. }
  679. }
  680. }
  681. // buildCreateEndpointOptions builds endpoint options from a given network.
  682. func buildCreateEndpointOptions(c *container.Container, n libnetwork.Network, epConfig *network.EndpointSettings, sb *libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error) {
  683. var (
  684. bindings = make(nat.PortMap)
  685. pbList []networktypes.PortBinding
  686. exposeList []networktypes.TransportPort
  687. createOptions []libnetwork.EndpointOption
  688. )
  689. defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName()
  690. if (!serviceDiscoveryOnDefaultNetwork() && n.Name() == defaultNetName) ||
  691. c.NetworkSettings.IsAnonymousEndpoint {
  692. createOptions = append(createOptions, libnetwork.CreateOptionAnonymous())
  693. }
  694. if epConfig != nil {
  695. ipam := epConfig.IPAMConfig
  696. if ipam != nil {
  697. var (
  698. ipList []net.IP
  699. ip, ip6, linkip net.IP
  700. )
  701. for _, ips := range ipam.LinkLocalIPs {
  702. if linkip = net.ParseIP(ips); linkip == nil && ips != "" {
  703. return nil, errors.Errorf("Invalid link-local IP address: %s", ipam.LinkLocalIPs)
  704. }
  705. ipList = append(ipList, linkip)
  706. }
  707. if ip = net.ParseIP(ipam.IPv4Address); ip == nil && ipam.IPv4Address != "" {
  708. return nil, errors.Errorf("Invalid IPv4 address: %s)", ipam.IPv4Address)
  709. }
  710. if ip6 = net.ParseIP(ipam.IPv6Address); ip6 == nil && ipam.IPv6Address != "" {
  711. return nil, errors.Errorf("Invalid IPv6 address: %s)", ipam.IPv6Address)
  712. }
  713. createOptions = append(createOptions,
  714. libnetwork.CreateOptionIpam(ip, ip6, ipList, nil))
  715. }
  716. for _, alias := range epConfig.Aliases {
  717. createOptions = append(createOptions, libnetwork.CreateOptionMyAlias(alias))
  718. }
  719. for k, v := range epConfig.DriverOpts {
  720. createOptions = append(createOptions, libnetwork.EndpointOptionGeneric(options.Generic{k: v}))
  721. }
  722. }
  723. if c.NetworkSettings.Service != nil {
  724. svcCfg := c.NetworkSettings.Service
  725. var vip string
  726. if svcCfg.VirtualAddresses[n.ID()] != nil {
  727. vip = svcCfg.VirtualAddresses[n.ID()].IPv4
  728. }
  729. var portConfigs []*libnetwork.PortConfig
  730. for _, portConfig := range svcCfg.ExposedPorts {
  731. portConfigs = append(portConfigs, &libnetwork.PortConfig{
  732. Name: portConfig.Name,
  733. Protocol: libnetwork.PortConfig_Protocol(portConfig.Protocol),
  734. TargetPort: portConfig.TargetPort,
  735. PublishedPort: portConfig.PublishedPort,
  736. })
  737. }
  738. createOptions = append(createOptions, libnetwork.CreateOptionService(svcCfg.Name, svcCfg.ID, net.ParseIP(vip), portConfigs, svcCfg.Aliases[n.ID()]))
  739. }
  740. if !containertypes.NetworkMode(n.Name()).IsUserDefined() {
  741. createOptions = append(createOptions, libnetwork.CreateOptionDisableResolution())
  742. }
  743. // configs that are applicable only for the endpoint in the network
  744. // to which container was connected to on docker run.
  745. // Ideally all these network-specific endpoint configurations must be moved under
  746. // container.NetworkSettings.Networks[n.Name()]
  747. if n.Name() == c.HostConfig.NetworkMode.NetworkName() ||
  748. (n.Name() == defaultNetName && c.HostConfig.NetworkMode.IsDefault()) {
  749. if c.Config.MacAddress != "" {
  750. mac, err := net.ParseMAC(c.Config.MacAddress)
  751. if err != nil {
  752. return nil, err
  753. }
  754. genericOption := options.Generic{
  755. netlabel.MacAddress: mac,
  756. }
  757. createOptions = append(createOptions, libnetwork.EndpointOptionGeneric(genericOption))
  758. }
  759. }
  760. // Port-mapping rules belong to the container & applicable only to non-internal networks
  761. portmaps := getPortMapInfo(sb)
  762. if n.Info().Internal() || len(portmaps) > 0 {
  763. return createOptions, nil
  764. }
  765. if c.HostConfig.PortBindings != nil {
  766. for p, b := range c.HostConfig.PortBindings {
  767. bindings[p] = []nat.PortBinding{}
  768. for _, bb := range b {
  769. bindings[p] = append(bindings[p], nat.PortBinding{
  770. HostIP: bb.HostIP,
  771. HostPort: bb.HostPort,
  772. })
  773. }
  774. }
  775. }
  776. portSpecs := c.Config.ExposedPorts
  777. ports := make([]nat.Port, len(portSpecs))
  778. var i int
  779. for p := range portSpecs {
  780. ports[i] = p
  781. i++
  782. }
  783. nat.SortPortMap(ports, bindings)
  784. for _, port := range ports {
  785. expose := networktypes.TransportPort{}
  786. expose.Proto = networktypes.ParseProtocol(port.Proto())
  787. expose.Port = uint16(port.Int())
  788. exposeList = append(exposeList, expose)
  789. pb := networktypes.PortBinding{Port: expose.Port, Proto: expose.Proto}
  790. binding := bindings[port]
  791. for i := 0; i < len(binding); i++ {
  792. pbCopy := pb.GetCopy()
  793. newP, err := nat.NewPort(nat.SplitProtoPort(binding[i].HostPort))
  794. var portStart, portEnd int
  795. if err == nil {
  796. portStart, portEnd, err = newP.Range()
  797. }
  798. if err != nil {
  799. return nil, errors.Wrapf(err, "Error parsing HostPort value (%s)", binding[i].HostPort)
  800. }
  801. pbCopy.HostPort = uint16(portStart)
  802. pbCopy.HostPortEnd = uint16(portEnd)
  803. pbCopy.HostIP = net.ParseIP(binding[i].HostIP)
  804. pbList = append(pbList, pbCopy)
  805. }
  806. if c.HostConfig.PublishAllPorts && len(binding) == 0 {
  807. pbList = append(pbList, pb)
  808. }
  809. }
  810. var dns []string
  811. if len(c.HostConfig.DNS) > 0 {
  812. dns = c.HostConfig.DNS
  813. } else if len(daemonDNS) > 0 {
  814. dns = daemonDNS
  815. }
  816. if len(dns) > 0 {
  817. createOptions = append(createOptions,
  818. libnetwork.CreateOptionDNS(dns))
  819. }
  820. createOptions = append(createOptions,
  821. libnetwork.CreateOptionPortMapping(pbList),
  822. libnetwork.CreateOptionExposedPorts(exposeList))
  823. return createOptions, nil
  824. }
  825. // getPortMapInfo retrieves the current port-mapping programmed for the given sandbox
  826. func getPortMapInfo(sb *libnetwork.Sandbox) nat.PortMap {
  827. pm := nat.PortMap{}
  828. if sb == nil {
  829. return pm
  830. }
  831. for _, ep := range sb.Endpoints() {
  832. pm, _ = getEndpointPortMapInfo(ep)
  833. if len(pm) > 0 {
  834. break
  835. }
  836. }
  837. return pm
  838. }
  839. func getEndpointPortMapInfo(ep *libnetwork.Endpoint) (nat.PortMap, error) {
  840. pm := nat.PortMap{}
  841. driverInfo, err := ep.DriverInfo()
  842. if err != nil {
  843. return pm, err
  844. }
  845. if driverInfo == nil {
  846. // It is not an error for epInfo to be nil
  847. return pm, nil
  848. }
  849. if expData, ok := driverInfo[netlabel.ExposedPorts]; ok {
  850. if exposedPorts, ok := expData.([]networktypes.TransportPort); ok {
  851. for _, tp := range exposedPorts {
  852. natPort, err := nat.NewPort(tp.Proto.String(), strconv.Itoa(int(tp.Port)))
  853. if err != nil {
  854. return pm, fmt.Errorf("Error parsing Port value(%v):%v", tp.Port, err)
  855. }
  856. pm[natPort] = nil
  857. }
  858. }
  859. }
  860. mapData, ok := driverInfo[netlabel.PortMap]
  861. if !ok {
  862. return pm, nil
  863. }
  864. if portMapping, ok := mapData.([]networktypes.PortBinding); ok {
  865. for _, pp := range portMapping {
  866. natPort, err := nat.NewPort(pp.Proto.String(), strconv.Itoa(int(pp.Port)))
  867. if err != nil {
  868. return pm, err
  869. }
  870. natBndg := nat.PortBinding{HostIP: pp.HostIP.String(), HostPort: strconv.Itoa(int(pp.HostPort))}
  871. pm[natPort] = append(pm[natPort], natBndg)
  872. }
  873. }
  874. return pm, nil
  875. }
  876. // buildEndpointInfo sets endpoint-related fields on container.NetworkSettings based on the provided network and endpoint.
  877. func buildEndpointInfo(networkSettings *internalnetwork.Settings, n libnetwork.Network, ep *libnetwork.Endpoint) error {
  878. if ep == nil {
  879. return errors.New("endpoint cannot be nil")
  880. }
  881. if networkSettings == nil {
  882. return errors.New("network cannot be nil")
  883. }
  884. epInfo := ep.Info()
  885. if epInfo == nil {
  886. // It is not an error to get an empty endpoint info
  887. return nil
  888. }
  889. if _, ok := networkSettings.Networks[n.Name()]; !ok {
  890. networkSettings.Networks[n.Name()] = &internalnetwork.EndpointSettings{
  891. EndpointSettings: &network.EndpointSettings{},
  892. }
  893. }
  894. networkSettings.Networks[n.Name()].NetworkID = n.ID()
  895. networkSettings.Networks[n.Name()].EndpointID = ep.ID()
  896. iface := epInfo.Iface()
  897. if iface == nil {
  898. return nil
  899. }
  900. if iface.MacAddress() != nil {
  901. networkSettings.Networks[n.Name()].MacAddress = iface.MacAddress().String()
  902. }
  903. if iface.Address() != nil {
  904. ones, _ := iface.Address().Mask.Size()
  905. networkSettings.Networks[n.Name()].IPAddress = iface.Address().IP.String()
  906. networkSettings.Networks[n.Name()].IPPrefixLen = ones
  907. }
  908. if iface.AddressIPv6() != nil && iface.AddressIPv6().IP.To16() != nil {
  909. onesv6, _ := iface.AddressIPv6().Mask.Size()
  910. networkSettings.Networks[n.Name()].GlobalIPv6Address = iface.AddressIPv6().IP.String()
  911. networkSettings.Networks[n.Name()].GlobalIPv6PrefixLen = onesv6
  912. }
  913. return nil
  914. }
  915. // buildJoinOptions builds endpoint Join options from a given network.
  916. func buildJoinOptions(networkSettings *internalnetwork.Settings, n interface {
  917. Name() string
  918. }) ([]libnetwork.EndpointOption, error) {
  919. var joinOptions []libnetwork.EndpointOption
  920. if epConfig, ok := networkSettings.Networks[n.Name()]; ok {
  921. for _, str := range epConfig.Links {
  922. name, alias, err := opts.ParseLink(str)
  923. if err != nil {
  924. return nil, err
  925. }
  926. joinOptions = append(joinOptions, libnetwork.CreateOptionAlias(name, alias))
  927. }
  928. for k, v := range epConfig.DriverOpts {
  929. joinOptions = append(joinOptions, libnetwork.EndpointOptionGeneric(options.Generic{k: v}))
  930. }
  931. }
  932. return joinOptions, nil
  933. }