bridge.go 19 KB

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