bridge.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. package bridge
  2. import (
  3. "errors"
  4. "net"
  5. "strings"
  6. "sync"
  7. "github.com/docker/libnetwork/driverapi"
  8. "github.com/docker/libnetwork/ipallocator"
  9. "github.com/docker/libnetwork/netlabel"
  10. "github.com/docker/libnetwork/netutils"
  11. "github.com/docker/libnetwork/options"
  12. "github.com/docker/libnetwork/portmapper"
  13. "github.com/docker/libnetwork/sandbox"
  14. "github.com/docker/libnetwork/types"
  15. "github.com/vishvananda/netlink"
  16. )
  17. const (
  18. networkType = "bridge"
  19. vethPrefix = "veth"
  20. vethLen = 7
  21. containerVeth = "eth0"
  22. maxAllocatePortAttempts = 10
  23. ifaceID = 1
  24. )
  25. var (
  26. ipAllocator *ipallocator.IPAllocator
  27. portMapper *portmapper.PortMapper
  28. )
  29. // Configuration info for the "bridge" driver.
  30. type Configuration struct {
  31. EnableIPForwarding bool
  32. }
  33. // NetworkConfiguration for network specific configuration
  34. type NetworkConfiguration struct {
  35. BridgeName string
  36. AddressIPv4 *net.IPNet
  37. FixedCIDR *net.IPNet
  38. FixedCIDRv6 *net.IPNet
  39. EnableIPv6 bool
  40. EnableIPTables bool
  41. EnableIPMasquerade bool
  42. EnableICC bool
  43. Mtu int
  44. DefaultGatewayIPv4 net.IP
  45. DefaultGatewayIPv6 net.IP
  46. DefaultBindingIP net.IP
  47. AllowNonDefaultBridge bool
  48. EnableUserlandProxy bool
  49. }
  50. // EndpointConfiguration represents the user specified configuration for the sandbox endpoint
  51. type EndpointConfiguration struct {
  52. MacAddress net.HardwareAddr
  53. PortBindings []types.PortBinding
  54. ExposedPorts []types.TransportPort
  55. }
  56. // ContainerConfiguration represents the user specified configuration for a container
  57. type ContainerConfiguration struct {
  58. ParentEndpoints []string
  59. ChildEndpoints []string
  60. }
  61. type bridgeEndpoint struct {
  62. id types.UUID
  63. intf *sandbox.Interface
  64. macAddress net.HardwareAddr
  65. config *EndpointConfiguration // User specified parameters
  66. containerConfig *ContainerConfiguration
  67. portMapping []types.PortBinding // Operation port bindings
  68. }
  69. type bridgeNetwork struct {
  70. id types.UUID
  71. bridge *bridgeInterface // The bridge's L3 interface
  72. config *NetworkConfiguration
  73. endpoints map[types.UUID]*bridgeEndpoint // key: endpoint id
  74. sync.Mutex
  75. }
  76. type driver struct {
  77. config *Configuration
  78. network *bridgeNetwork
  79. sync.Mutex
  80. }
  81. func init() {
  82. ipAllocator = ipallocator.New()
  83. portMapper = portmapper.New()
  84. }
  85. // New constructs a new bridge driver
  86. func newDriver() driverapi.Driver {
  87. return &driver{}
  88. }
  89. // Init registers a new instance of bridge driver
  90. func Init(dc driverapi.DriverCallback) error {
  91. return dc.RegisterDriver(networkType, newDriver())
  92. }
  93. // Validate performs a static validation on the network configuration parameters.
  94. // Whatever can be assessed a priori before attempting any programming.
  95. func (c *NetworkConfiguration) Validate() error {
  96. if c.Mtu < 0 {
  97. return ErrInvalidMtu(c.Mtu)
  98. }
  99. // If bridge v4 subnet is specified
  100. if c.AddressIPv4 != nil {
  101. // If Container restricted subnet is specified, it must be a subset of bridge subnet
  102. if c.FixedCIDR != nil {
  103. // Check Network address
  104. if !c.AddressIPv4.Contains(c.FixedCIDR.IP) {
  105. return &ErrInvalidContainerSubnet{}
  106. }
  107. // Check it is effectively a subset
  108. brNetLen, _ := c.AddressIPv4.Mask.Size()
  109. cnNetLen, _ := c.FixedCIDR.Mask.Size()
  110. if brNetLen > cnNetLen {
  111. return &ErrInvalidContainerSubnet{}
  112. }
  113. }
  114. // If default gw is specified, it must be part of bridge subnet
  115. if c.DefaultGatewayIPv4 != nil {
  116. if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) {
  117. return &ErrInvalidGateway{}
  118. }
  119. }
  120. }
  121. // If default v6 gw is specified, FixedCIDRv6 must be specified and gw must belong to FixedCIDRv6 subnet
  122. if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
  123. if c.FixedCIDRv6 == nil || !c.FixedCIDRv6.Contains(c.DefaultGatewayIPv6) {
  124. return &ErrInvalidGateway{}
  125. }
  126. }
  127. return nil
  128. }
  129. func (n *bridgeNetwork) getEndpoint(eid types.UUID) (*bridgeEndpoint, error) {
  130. n.Lock()
  131. defer n.Unlock()
  132. if eid == "" {
  133. return nil, InvalidEndpointIDError(eid)
  134. }
  135. if ep, ok := n.endpoints[eid]; ok {
  136. return ep, nil
  137. }
  138. return nil, nil
  139. }
  140. func (d *driver) Config(option map[string]interface{}) error {
  141. var config *Configuration
  142. d.Lock()
  143. defer d.Unlock()
  144. if d.config != nil {
  145. return &ErrConfigExists{}
  146. }
  147. genericData, ok := option[netlabel.GenericData]
  148. if ok && genericData != nil {
  149. switch opt := genericData.(type) {
  150. case options.Generic:
  151. opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
  152. if err != nil {
  153. return err
  154. }
  155. config = opaqueConfig.(*Configuration)
  156. case *Configuration:
  157. config = opt
  158. default:
  159. return &ErrInvalidDriverConfig{}
  160. }
  161. d.config = config
  162. } else {
  163. config = &Configuration{}
  164. }
  165. if config.EnableIPForwarding {
  166. return setupIPForwarding(config)
  167. }
  168. return nil
  169. }
  170. func (d *driver) getNetwork(id types.UUID) (*bridgeNetwork, error) {
  171. // Just a dummy function to return the only network managed by Bridge driver.
  172. // But this API makes the caller code unchanged when we move to support multiple networks.
  173. d.Lock()
  174. defer d.Unlock()
  175. return d.network, nil
  176. }
  177. func parseNetworkOptions(option options.Generic) (*NetworkConfiguration, error) {
  178. var config *NetworkConfiguration
  179. genericData, ok := option[netlabel.GenericData]
  180. if ok && genericData != nil {
  181. switch opt := genericData.(type) {
  182. case options.Generic:
  183. opaqueConfig, err := options.GenerateFromModel(opt, &NetworkConfiguration{})
  184. if err != nil {
  185. return nil, err
  186. }
  187. config = opaqueConfig.(*NetworkConfiguration)
  188. case *NetworkConfiguration:
  189. config = opt
  190. default:
  191. return nil, &ErrInvalidNetworkConfig{}
  192. }
  193. if err := config.Validate(); err != nil {
  194. return nil, err
  195. }
  196. } else {
  197. config = &NetworkConfiguration{}
  198. }
  199. if _, ok := option[netlabel.EnableIPv6]; ok {
  200. config.EnableIPv6 = option[netlabel.EnableIPv6].(bool)
  201. }
  202. return config, nil
  203. }
  204. // Create a new network using bridge plugin
  205. func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error {
  206. var err error
  207. // Driver must be configured
  208. d.Lock()
  209. // Sanity checks
  210. if d.network != nil {
  211. d.Unlock()
  212. return &ErrNetworkExists{}
  213. }
  214. // Create and set network handler in driver
  215. d.network = &bridgeNetwork{id: id, endpoints: make(map[types.UUID]*bridgeEndpoint)}
  216. network := d.network
  217. d.Unlock()
  218. // On failure make sure to reset driver network handler to nil
  219. defer func() {
  220. if err != nil {
  221. d.Lock()
  222. d.network = nil
  223. d.Unlock()
  224. }
  225. }()
  226. config, err := parseNetworkOptions(option)
  227. if err != nil {
  228. return err
  229. }
  230. network.config = config
  231. // Create or retrieve the bridge L3 interface
  232. bridgeIface := newInterface(config)
  233. network.bridge = bridgeIface
  234. // Prepare the bridge setup configuration
  235. bridgeSetup := newBridgeSetup(config, bridgeIface)
  236. // If the bridge interface doesn't exist, we need to start the setup steps
  237. // by creating a new device and assigning it an IPv4 address.
  238. bridgeAlreadyExists := bridgeIface.exists()
  239. if !bridgeAlreadyExists {
  240. bridgeSetup.queueStep(setupDevice)
  241. }
  242. // Even if a bridge exists try to setup IPv4.
  243. bridgeSetup.queueStep(setupBridgeIPv4)
  244. // Conditionally queue setup steps depending on configuration values.
  245. for _, step := range []struct {
  246. Condition bool
  247. Fn setupStep
  248. }{
  249. // Enable IPv6 on the bridge if required. We do this even for a
  250. // previously existing bridge, as it may be here from a previous
  251. // installation where IPv6 wasn't supported yet and needs to be
  252. // assigned an IPv6 link-local address.
  253. {config.EnableIPv6, setupBridgeIPv6},
  254. // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in
  255. // the case of a previously existing device.
  256. {bridgeAlreadyExists, setupVerifyAndReconcile},
  257. // Setup the bridge to allocate containers IPv4 addresses in the
  258. // specified subnet.
  259. {config.FixedCIDR != nil, setupFixedCIDRv4},
  260. // Setup the bridge to allocate containers global IPv6 addresses in the
  261. // specified subnet.
  262. {config.FixedCIDRv6 != nil, setupFixedCIDRv6},
  263. // Setup Loopback Adresses Routing
  264. {!config.EnableUserlandProxy, setupLoopbackAdressesRouting},
  265. // Setup IPTables.
  266. {config.EnableIPTables, setupIPTables},
  267. // Setup DefaultGatewayIPv4
  268. {config.DefaultGatewayIPv4 != nil, setupGatewayIPv4},
  269. // Setup DefaultGatewayIPv6
  270. {config.DefaultGatewayIPv6 != nil, setupGatewayIPv6},
  271. } {
  272. if step.Condition {
  273. bridgeSetup.queueStep(step.Fn)
  274. }
  275. }
  276. // Block bridge IP from being allocated.
  277. bridgeSetup.queueStep(allocateBridgeIP)
  278. // Apply the prepared list of steps, and abort at the first error.
  279. bridgeSetup.queueStep(setupDeviceUp)
  280. if err = bridgeSetup.apply(); err != nil {
  281. return err
  282. }
  283. return nil
  284. }
  285. func (d *driver) DeleteNetwork(nid types.UUID) error {
  286. var err error
  287. // Get network handler and remove it from driver
  288. d.Lock()
  289. n := d.network
  290. d.network = nil
  291. d.Unlock()
  292. // On failure set network handler back in driver, but
  293. // only if is not already taken over by some other thread
  294. defer func() {
  295. if err != nil {
  296. d.Lock()
  297. if d.network == nil {
  298. d.network = n
  299. }
  300. d.Unlock()
  301. }
  302. }()
  303. // Sanity check
  304. if n == nil {
  305. err = driverapi.ErrNoNetwork(nid)
  306. return err
  307. }
  308. // Cannot remove network if endpoints are still present
  309. if len(n.endpoints) != 0 {
  310. err = ActiveEndpointsError(n.id)
  311. return err
  312. }
  313. // Programming
  314. err = netlink.LinkDel(n.bridge.Link)
  315. return err
  316. }
  317. func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
  318. var (
  319. ipv6Addr *net.IPNet
  320. err error
  321. )
  322. if epInfo == nil {
  323. return errors.New("invalid endpoint info passed")
  324. }
  325. if len(epInfo.Interfaces()) != 0 {
  326. return errors.New("non empty interface list passed to bridge(local) driver")
  327. }
  328. // Get the network handler and make sure it exists
  329. d.Lock()
  330. n := d.network
  331. config := n.config
  332. d.Unlock()
  333. if n == nil {
  334. return driverapi.ErrNoNetwork(nid)
  335. }
  336. // Sanity check
  337. n.Lock()
  338. if n.id != nid {
  339. n.Unlock()
  340. return InvalidNetworkIDError(nid)
  341. }
  342. n.Unlock()
  343. // Check if endpoint id is good and retrieve correspondent endpoint
  344. ep, err := n.getEndpoint(eid)
  345. if err != nil {
  346. return err
  347. }
  348. // Endpoint with that id exists either on desired or other sandbox
  349. if ep != nil {
  350. return driverapi.ErrEndpointExists(eid)
  351. }
  352. // Try to convert the options to endpoint configuration
  353. epConfig, err := parseEndpointOptions(epOptions)
  354. if err != nil {
  355. return err
  356. }
  357. // Create and add the endpoint
  358. n.Lock()
  359. endpoint := &bridgeEndpoint{id: eid, config: epConfig}
  360. n.endpoints[eid] = endpoint
  361. n.Unlock()
  362. // On failure make sure to remove the endpoint
  363. defer func() {
  364. if err != nil {
  365. n.Lock()
  366. delete(n.endpoints, eid)
  367. n.Unlock()
  368. }
  369. }()
  370. // Generate a name for what will be the host side pipe interface
  371. name1, err := generateIfaceName()
  372. if err != nil {
  373. return err
  374. }
  375. // Generate a name for what will be the sandbox side pipe interface
  376. name2, err := generateIfaceName()
  377. if err != nil {
  378. return err
  379. }
  380. // Generate and add the interface pipe host <-> sandbox
  381. veth := &netlink.Veth{
  382. LinkAttrs: netlink.LinkAttrs{Name: name1, TxQLen: 0},
  383. PeerName: name2}
  384. if err = netlink.LinkAdd(veth); err != nil {
  385. return err
  386. }
  387. // Get the host side pipe interface handler
  388. host, err := netlink.LinkByName(name1)
  389. if err != nil {
  390. return err
  391. }
  392. defer func() {
  393. if err != nil {
  394. netlink.LinkDel(host)
  395. }
  396. }()
  397. // Get the sandbox side pipe interface handler
  398. sbox, err := netlink.LinkByName(name2)
  399. if err != nil {
  400. return err
  401. }
  402. defer func() {
  403. if err != nil {
  404. netlink.LinkDel(sbox)
  405. }
  406. }()
  407. // Set the sbox's MAC. If specified, use the one configured by user, otherwise use a random one
  408. mac := electMacAddress(epConfig)
  409. err = netlink.LinkSetHardwareAddr(sbox, mac)
  410. if err != nil {
  411. return err
  412. }
  413. endpoint.macAddress = mac
  414. // Add bridge inherited attributes to pipe interfaces
  415. if config.Mtu != 0 {
  416. err = netlink.LinkSetMTU(host, config.Mtu)
  417. if err != nil {
  418. return err
  419. }
  420. err = netlink.LinkSetMTU(sbox, config.Mtu)
  421. if err != nil {
  422. return err
  423. }
  424. }
  425. // Attach host side pipe interface into the bridge
  426. if err = netlink.LinkSetMaster(host,
  427. &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: config.BridgeName}}); err != nil {
  428. return err
  429. }
  430. // v4 address for the sandbox side pipe interface
  431. ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
  432. if err != nil {
  433. return err
  434. }
  435. ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
  436. // v6 address for the sandbox side pipe interface
  437. ipv6Addr = &net.IPNet{}
  438. if config.EnableIPv6 {
  439. var ip6 net.IP
  440. network := n.bridge.bridgeIPv6
  441. if config.FixedCIDRv6 != nil {
  442. network = config.FixedCIDRv6
  443. }
  444. ones, _ := network.Mask.Size()
  445. if ones <= 80 {
  446. ip6 = make(net.IP, len(network.IP))
  447. copy(ip6, network.IP)
  448. for i, h := range mac {
  449. ip6[i+10] = h
  450. }
  451. }
  452. ip6, err := ipAllocator.RequestIP(network, ip6)
  453. if err != nil {
  454. return err
  455. }
  456. ipv6Addr = &net.IPNet{IP: ip6, Mask: network.Mask}
  457. }
  458. // Create the sandbox side pipe interface
  459. intf := &sandbox.Interface{}
  460. intf.SrcName = name2
  461. intf.DstName = containerVeth
  462. intf.Address = ipv4Addr
  463. if config.EnableIPv6 {
  464. intf.AddressIPv6 = ipv6Addr
  465. }
  466. // Store the interface in endpoint, this is needed for cleanup on DeleteEndpoint()
  467. endpoint.intf = intf
  468. err = epInfo.AddInterface(ifaceID, endpoint.macAddress, *ipv4Addr, *ipv6Addr)
  469. if err != nil {
  470. return err
  471. }
  472. // Program any required port mapping and store them in the endpoint
  473. endpoint.portMapping, err = allocatePorts(epConfig, intf, config.DefaultBindingIP, config.EnableUserlandProxy)
  474. if err != nil {
  475. return err
  476. }
  477. return nil
  478. }
  479. func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
  480. var err error
  481. // Get the network handler and make sure it exists
  482. d.Lock()
  483. n := d.network
  484. config := n.config
  485. d.Unlock()
  486. if n == nil {
  487. return driverapi.ErrNoNetwork(nid)
  488. }
  489. // Sanity Check
  490. n.Lock()
  491. if n.id != nid {
  492. n.Unlock()
  493. return InvalidNetworkIDError(nid)
  494. }
  495. n.Unlock()
  496. // Check endpoint id and if an endpoint is actually there
  497. ep, err := n.getEndpoint(eid)
  498. if err != nil {
  499. return err
  500. }
  501. if ep == nil {
  502. return EndpointNotFoundError(eid)
  503. }
  504. // Remove it
  505. n.Lock()
  506. delete(n.endpoints, eid)
  507. n.Unlock()
  508. // On failure make sure to set back ep in n.endpoints, but only
  509. // if it hasn't been taken over already by some other thread.
  510. defer func() {
  511. if err != nil {
  512. n.Lock()
  513. if _, ok := n.endpoints[eid]; !ok {
  514. n.endpoints[eid] = ep
  515. }
  516. n.Unlock()
  517. }
  518. }()
  519. // Remove port mappings. Do not stop endpoint delete on unmap failure
  520. releasePorts(ep)
  521. // Release the v4 address allocated to this endpoint's sandbox interface
  522. err = ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, ep.intf.Address.IP)
  523. if err != nil {
  524. return err
  525. }
  526. // Release the v6 address allocated to this endpoint's sandbox interface
  527. if config.EnableIPv6 {
  528. err := ipAllocator.ReleaseIP(n.bridge.bridgeIPv6, ep.intf.AddressIPv6.IP)
  529. if err != nil {
  530. return err
  531. }
  532. }
  533. // Try removal of link. Discard error: link pair might have
  534. // already been deleted by sandbox delete.
  535. link, err := netlink.LinkByName(ep.intf.SrcName)
  536. if err == nil {
  537. netlink.LinkDel(link)
  538. }
  539. return nil
  540. }
  541. func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{}, error) {
  542. // Get the network handler and make sure it exists
  543. d.Lock()
  544. n := d.network
  545. d.Unlock()
  546. if n == nil {
  547. return nil, driverapi.ErrNoNetwork(nid)
  548. }
  549. // Sanity check
  550. n.Lock()
  551. if n.id != nid {
  552. n.Unlock()
  553. return nil, InvalidNetworkIDError(nid)
  554. }
  555. n.Unlock()
  556. // Check if endpoint id is good and retrieve correspondent endpoint
  557. ep, err := n.getEndpoint(eid)
  558. if err != nil {
  559. return nil, err
  560. }
  561. if ep == nil {
  562. return nil, driverapi.ErrNoEndpoint(eid)
  563. }
  564. m := make(map[string]interface{})
  565. if ep.portMapping != nil {
  566. // Return a copy of the operational data
  567. pmc := make([]types.PortBinding, 0, len(ep.portMapping))
  568. for _, pm := range ep.portMapping {
  569. pmc = append(pmc, pm.GetCopy())
  570. }
  571. m[netlabel.PortMap] = pmc
  572. }
  573. if len(ep.macAddress) != 0 {
  574. m[netlabel.MacAddress] = ep.macAddress
  575. }
  576. return m, nil
  577. }
  578. // Join method is invoked when a Sandbox is attached to an endpoint.
  579. func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
  580. network, err := d.getNetwork(nid)
  581. if err != nil {
  582. return err
  583. }
  584. endpoint, err := network.getEndpoint(eid)
  585. if err != nil {
  586. return err
  587. }
  588. if endpoint == nil {
  589. return EndpointNotFoundError(eid)
  590. }
  591. for _, iNames := range jinfo.InterfaceNames() {
  592. // Make sure to set names on the correct interface ID.
  593. if iNames.ID() == ifaceID {
  594. err = iNames.SetNames(endpoint.intf.SrcName, endpoint.intf.DstName)
  595. if err != nil {
  596. return err
  597. }
  598. }
  599. }
  600. err = jinfo.SetGateway(network.bridge.gatewayIPv4)
  601. if err != nil {
  602. return err
  603. }
  604. err = jinfo.SetGatewayIPv6(network.bridge.gatewayIPv6)
  605. if err != nil {
  606. return err
  607. }
  608. if !network.config.EnableICC {
  609. return d.link(network, endpoint, options, true)
  610. }
  611. return nil
  612. }
  613. // Leave method is invoked when a Sandbox detaches from an endpoint.
  614. func (d *driver) Leave(nid, eid types.UUID) error {
  615. network, err := d.getNetwork(nid)
  616. if err != nil {
  617. return err
  618. }
  619. endpoint, err := network.getEndpoint(eid)
  620. if err != nil {
  621. return err
  622. }
  623. if endpoint == nil {
  624. return EndpointNotFoundError(eid)
  625. }
  626. if !network.config.EnableICC {
  627. return d.link(network, endpoint, nil, false)
  628. }
  629. return nil
  630. }
  631. func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, options map[string]interface{}, enable bool) error {
  632. var (
  633. cc *ContainerConfiguration
  634. err error
  635. )
  636. if enable {
  637. cc, err = parseContainerOptions(options)
  638. if err != nil {
  639. return err
  640. }
  641. } else {
  642. cc = endpoint.containerConfig
  643. }
  644. if cc == nil {
  645. return nil
  646. }
  647. if endpoint.config != nil && endpoint.config.ExposedPorts != nil {
  648. for _, p := range cc.ParentEndpoints {
  649. var parentEndpoint *bridgeEndpoint
  650. parentEndpoint, err = network.getEndpoint(types.UUID(p))
  651. if err != nil {
  652. return err
  653. }
  654. if parentEndpoint == nil {
  655. err = InvalidEndpointIDError(p)
  656. return err
  657. }
  658. l := newLink(parentEndpoint.intf.Address.IP.String(),
  659. endpoint.intf.Address.IP.String(),
  660. endpoint.config.ExposedPorts, network.config.BridgeName)
  661. if enable {
  662. err = l.Enable()
  663. if err != nil {
  664. return err
  665. }
  666. defer func() {
  667. if err != nil {
  668. l.Disable()
  669. }
  670. }()
  671. } else {
  672. l.Disable()
  673. }
  674. }
  675. }
  676. for _, c := range cc.ChildEndpoints {
  677. var childEndpoint *bridgeEndpoint
  678. childEndpoint, err = network.getEndpoint(types.UUID(c))
  679. if err != nil {
  680. return err
  681. }
  682. if childEndpoint == nil {
  683. err = InvalidEndpointIDError(c)
  684. return err
  685. }
  686. if childEndpoint.config == nil || childEndpoint.config.ExposedPorts == nil {
  687. continue
  688. }
  689. l := newLink(endpoint.intf.Address.IP.String(),
  690. childEndpoint.intf.Address.IP.String(),
  691. childEndpoint.config.ExposedPorts, network.config.BridgeName)
  692. if enable {
  693. err = l.Enable()
  694. if err != nil {
  695. return err
  696. }
  697. defer func() {
  698. if err != nil {
  699. l.Disable()
  700. }
  701. }()
  702. } else {
  703. l.Disable()
  704. }
  705. }
  706. if enable {
  707. endpoint.containerConfig = cc
  708. }
  709. return nil
  710. }
  711. func (d *driver) Type() string {
  712. return networkType
  713. }
  714. func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfiguration, error) {
  715. if epOptions == nil {
  716. return nil, nil
  717. }
  718. ec := &EndpointConfiguration{}
  719. if opt, ok := epOptions[netlabel.MacAddress]; ok {
  720. if mac, ok := opt.(net.HardwareAddr); ok {
  721. ec.MacAddress = mac
  722. } else {
  723. return nil, &ErrInvalidEndpointConfig{}
  724. }
  725. }
  726. if opt, ok := epOptions[netlabel.PortMap]; ok {
  727. if bs, ok := opt.([]types.PortBinding); ok {
  728. ec.PortBindings = bs
  729. } else {
  730. return nil, &ErrInvalidEndpointConfig{}
  731. }
  732. }
  733. if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
  734. if ports, ok := opt.([]types.TransportPort); ok {
  735. ec.ExposedPorts = ports
  736. } else {
  737. return nil, &ErrInvalidEndpointConfig{}
  738. }
  739. }
  740. return ec, nil
  741. }
  742. func parseContainerOptions(cOptions map[string]interface{}) (*ContainerConfiguration, error) {
  743. if cOptions == nil {
  744. return nil, nil
  745. }
  746. genericData := cOptions[netlabel.GenericData]
  747. if genericData == nil {
  748. return nil, nil
  749. }
  750. switch opt := genericData.(type) {
  751. case options.Generic:
  752. opaqueConfig, err := options.GenerateFromModel(opt, &ContainerConfiguration{})
  753. if err != nil {
  754. return nil, err
  755. }
  756. return opaqueConfig.(*ContainerConfiguration), nil
  757. case *ContainerConfiguration:
  758. return opt, nil
  759. default:
  760. return nil, nil
  761. }
  762. }
  763. func electMacAddress(epConfig *EndpointConfiguration) net.HardwareAddr {
  764. if epConfig != nil && epConfig.MacAddress != nil {
  765. return epConfig.MacAddress
  766. }
  767. return netutils.GenerateRandomMAC()
  768. }
  769. // Generates a name to be used for a virtual ethernet
  770. // interface. The name is constructed by 'veth' appended
  771. // by a randomly generated hex value. (example: veth0f60e2c)
  772. func generateIfaceName() (string, error) {
  773. for i := 0; i < 3; i++ {
  774. name, err := netutils.GenerateRandomName(vethPrefix, vethLen)
  775. if err != nil {
  776. continue
  777. }
  778. if _, err := net.InterfaceByName(name); err != nil {
  779. if strings.Contains(err.Error(), "no such") {
  780. return name, nil
  781. }
  782. return "", err
  783. }
  784. }
  785. return "", &ErrIfaceName{}
  786. }