network.go 32 KB

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