bridge.go 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  1. package bridge
  2. import (
  3. "errors"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "os"
  8. "os/exec"
  9. "path/filepath"
  10. "strconv"
  11. "strings"
  12. "sync"
  13. "syscall"
  14. "github.com/Sirupsen/logrus"
  15. "github.com/docker/libnetwork/driverapi"
  16. "github.com/docker/libnetwork/ipallocator"
  17. "github.com/docker/libnetwork/iptables"
  18. "github.com/docker/libnetwork/netlabel"
  19. "github.com/docker/libnetwork/netutils"
  20. "github.com/docker/libnetwork/options"
  21. "github.com/docker/libnetwork/portmapper"
  22. "github.com/docker/libnetwork/types"
  23. "github.com/vishvananda/netlink"
  24. )
  25. const (
  26. networkType = "bridge"
  27. vethPrefix = "veth"
  28. vethLen = 7
  29. containerVethPrefix = "eth"
  30. maxAllocatePortAttempts = 10
  31. ifaceID = 1
  32. )
  33. var (
  34. ipAllocator *ipallocator.IPAllocator
  35. )
  36. // configuration info for the "bridge" driver.
  37. type configuration struct {
  38. EnableIPForwarding bool
  39. EnableIPTables bool
  40. EnableUserlandProxy bool
  41. }
  42. // networkConfiguration for network specific configuration
  43. type networkConfiguration struct {
  44. BridgeName string
  45. AddressIPv4 *net.IPNet
  46. FixedCIDR *net.IPNet
  47. FixedCIDRv6 *net.IPNet
  48. EnableIPv6 bool
  49. EnableIPMasquerade bool
  50. EnableICC bool
  51. Mtu int
  52. DefaultGatewayIPv4 net.IP
  53. DefaultGatewayIPv6 net.IP
  54. DefaultBindingIP net.IP
  55. AllowNonDefaultBridge bool
  56. }
  57. // endpointConfiguration represents the user specified configuration for the sandbox endpoint
  58. type endpointConfiguration struct {
  59. MacAddress net.HardwareAddr
  60. PortBindings []types.PortBinding
  61. ExposedPorts []types.TransportPort
  62. }
  63. // containerConfiguration represents the user specified configuration for a container
  64. type containerConfiguration struct {
  65. ParentEndpoints []string
  66. ChildEndpoints []string
  67. }
  68. type bridgeEndpoint struct {
  69. id types.UUID
  70. srcName string
  71. addr *net.IPNet
  72. addrv6 *net.IPNet
  73. macAddress net.HardwareAddr
  74. config *endpointConfiguration // User specified parameters
  75. containerConfig *containerConfiguration
  76. portMapping []types.PortBinding // Operation port bindings
  77. }
  78. type bridgeNetwork struct {
  79. id types.UUID
  80. bridge *bridgeInterface // The bridge's L3 interface
  81. config *networkConfiguration
  82. endpoints map[types.UUID]*bridgeEndpoint // key: endpoint id
  83. portMapper *portmapper.PortMapper
  84. driver *driver // The network's driver
  85. sync.Mutex
  86. }
  87. type driver struct {
  88. config *configuration
  89. network *bridgeNetwork
  90. natChain *iptables.ChainInfo
  91. filterChain *iptables.ChainInfo
  92. networks map[types.UUID]*bridgeNetwork
  93. sync.Mutex
  94. }
  95. func init() {
  96. ipAllocator = ipallocator.New()
  97. }
  98. // New constructs a new bridge driver
  99. func newDriver() driverapi.Driver {
  100. return &driver{networks: map[types.UUID]*bridgeNetwork{}}
  101. }
  102. // Init registers a new instance of bridge driver
  103. func Init(dc driverapi.DriverCallback) error {
  104. if _, err := os.Stat("/proc/sys/net/bridge"); err != nil {
  105. if out, err := exec.Command("modprobe", "-va", "bridge", "br_netfilter").CombinedOutput(); err != nil {
  106. logrus.Warnf("Running modprobe bridge br_netfilter failed with message: %s, error: %v", out, err)
  107. }
  108. }
  109. if out, err := exec.Command("modprobe", "-va", "nf_nat").CombinedOutput(); err != nil {
  110. logrus.Warnf("Running modprobe nf_nat failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err)
  111. }
  112. if err := iptables.FirewalldInit(); err != nil {
  113. logrus.Debugf("Fail to initialize firewalld: %v, using raw iptables instead", err)
  114. }
  115. if err := iptables.RemoveExistingChain(DockerChain, iptables.Nat); err != nil {
  116. logrus.Warnf("Failed to remove existing iptables entries in %s : %v", DockerChain, err)
  117. }
  118. c := driverapi.Capability{
  119. Scope: driverapi.LocalScope,
  120. }
  121. return dc.RegisterDriver(networkType, newDriver(), c)
  122. }
  123. // Validate performs a static validation on the network configuration parameters.
  124. // Whatever can be assessed a priori before attempting any programming.
  125. func (c *networkConfiguration) Validate() error {
  126. if c.Mtu < 0 {
  127. return ErrInvalidMtu(c.Mtu)
  128. }
  129. // If bridge v4 subnet is specified
  130. if c.AddressIPv4 != nil {
  131. // If Container restricted subnet is specified, it must be a subset of bridge subnet
  132. if c.FixedCIDR != nil {
  133. // Check Network address
  134. if !c.AddressIPv4.Contains(c.FixedCIDR.IP) {
  135. return &ErrInvalidContainerSubnet{}
  136. }
  137. // Check it is effectively a subset
  138. brNetLen, _ := c.AddressIPv4.Mask.Size()
  139. cnNetLen, _ := c.FixedCIDR.Mask.Size()
  140. if brNetLen > cnNetLen {
  141. return &ErrInvalidContainerSubnet{}
  142. }
  143. }
  144. // If default gw is specified, it must be part of bridge subnet
  145. if c.DefaultGatewayIPv4 != nil {
  146. if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) {
  147. return &ErrInvalidGateway{}
  148. }
  149. }
  150. }
  151. // If default v6 gw is specified, FixedCIDRv6 must be specified and gw must belong to FixedCIDRv6 subnet
  152. if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
  153. if c.FixedCIDRv6 == nil || !c.FixedCIDRv6.Contains(c.DefaultGatewayIPv6) {
  154. return &ErrInvalidGateway{}
  155. }
  156. }
  157. return nil
  158. }
  159. // Conflicts check if two NetworkConfiguration objects overlap
  160. func (c *networkConfiguration) Conflicts(o *networkConfiguration) bool {
  161. if o == nil {
  162. return false
  163. }
  164. // Also empty, becasue only one network with empty name is allowed
  165. if c.BridgeName == o.BridgeName {
  166. return true
  167. }
  168. // They must be in different subnets
  169. if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) &&
  170. (c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) {
  171. return true
  172. }
  173. return false
  174. }
  175. // fromMap retrieve the configuration data from the map form.
  176. func (c *networkConfiguration) fromMap(data map[string]interface{}) error {
  177. var err error
  178. if i, ok := data["BridgeName"]; ok && i != nil {
  179. if c.BridgeName, ok = i.(string); !ok {
  180. return types.BadRequestErrorf("invalid type for BridgeName value")
  181. }
  182. }
  183. if i, ok := data["Mtu"]; ok && i != nil {
  184. if s, ok := i.(string); ok {
  185. if c.Mtu, err = strconv.Atoi(s); err != nil {
  186. return types.BadRequestErrorf("failed to parse Mtu value: %s", err.Error())
  187. }
  188. } else {
  189. return types.BadRequestErrorf("invalid type for Mtu value")
  190. }
  191. }
  192. if i, ok := data["EnableIPv6"]; ok && i != nil {
  193. if s, ok := i.(string); ok {
  194. if c.EnableIPv6, err = strconv.ParseBool(s); err != nil {
  195. return types.BadRequestErrorf("failed to parse EnableIPv6 value: %s", err.Error())
  196. }
  197. } else {
  198. return types.BadRequestErrorf("invalid type for EnableIPv6 value")
  199. }
  200. }
  201. if i, ok := data["EnableIPMasquerade"]; ok && i != nil {
  202. if s, ok := i.(string); ok {
  203. if c.EnableIPMasquerade, err = strconv.ParseBool(s); err != nil {
  204. return types.BadRequestErrorf("failed to parse EnableIPMasquerade value: %s", err.Error())
  205. }
  206. } else {
  207. return types.BadRequestErrorf("invalid type for EnableIPMasquerade value")
  208. }
  209. }
  210. if i, ok := data["EnableICC"]; ok && i != nil {
  211. if s, ok := i.(string); ok {
  212. if c.EnableICC, err = strconv.ParseBool(s); err != nil {
  213. return types.BadRequestErrorf("failed to parse EnableICC value: %s", err.Error())
  214. }
  215. } else {
  216. return types.BadRequestErrorf("invalid type for EnableICC value")
  217. }
  218. }
  219. if i, ok := data["AllowNonDefaultBridge"]; ok && i != nil {
  220. if s, ok := i.(string); ok {
  221. if c.AllowNonDefaultBridge, err = strconv.ParseBool(s); err != nil {
  222. return types.BadRequestErrorf("failed to parse AllowNonDefaultBridge value: %s", err.Error())
  223. }
  224. } else {
  225. return types.BadRequestErrorf("invalid type for AllowNonDefaultBridge value")
  226. }
  227. }
  228. if i, ok := data["AddressIPv4"]; ok && i != nil {
  229. if s, ok := i.(string); ok {
  230. if ip, nw, e := net.ParseCIDR(s); e == nil {
  231. nw.IP = ip
  232. c.AddressIPv4 = nw
  233. } else {
  234. return types.BadRequestErrorf("failed to parse AddressIPv4 value")
  235. }
  236. } else {
  237. return types.BadRequestErrorf("invalid type for AddressIPv4 value")
  238. }
  239. }
  240. if i, ok := data["FixedCIDR"]; ok && i != nil {
  241. if s, ok := i.(string); ok {
  242. if ip, nw, e := net.ParseCIDR(s); e == nil {
  243. nw.IP = ip
  244. c.FixedCIDR = nw
  245. } else {
  246. return types.BadRequestErrorf("failed to parse FixedCIDR value")
  247. }
  248. } else {
  249. return types.BadRequestErrorf("invalid type for FixedCIDR value")
  250. }
  251. }
  252. if i, ok := data["FixedCIDRv6"]; ok && i != nil {
  253. if s, ok := i.(string); ok {
  254. if ip, nw, e := net.ParseCIDR(s); e == nil {
  255. nw.IP = ip
  256. c.FixedCIDRv6 = nw
  257. } else {
  258. return types.BadRequestErrorf("failed to parse FixedCIDRv6 value")
  259. }
  260. } else {
  261. return types.BadRequestErrorf("invalid type for FixedCIDRv6 value")
  262. }
  263. }
  264. if i, ok := data["DefaultGatewayIPv4"]; ok && i != nil {
  265. if s, ok := i.(string); ok {
  266. if c.DefaultGatewayIPv4 = net.ParseIP(s); c.DefaultGatewayIPv4 == nil {
  267. return types.BadRequestErrorf("failed to parse DefaultGatewayIPv4 value")
  268. }
  269. } else {
  270. return types.BadRequestErrorf("invalid type for DefaultGatewayIPv4 value")
  271. }
  272. }
  273. if i, ok := data["DefaultGatewayIPv6"]; ok && i != nil {
  274. if s, ok := i.(string); ok {
  275. if c.DefaultGatewayIPv6 = net.ParseIP(s); c.DefaultGatewayIPv6 == nil {
  276. return types.BadRequestErrorf("failed to parse DefaultGatewayIPv6 value")
  277. }
  278. } else {
  279. return types.BadRequestErrorf("invalid type for DefaultGatewayIPv6 value")
  280. }
  281. }
  282. if i, ok := data["DefaultBindingIP"]; ok && i != nil {
  283. if s, ok := i.(string); ok {
  284. if c.DefaultBindingIP = net.ParseIP(s); c.DefaultBindingIP == nil {
  285. return types.BadRequestErrorf("failed to parse DefaultBindingIP value")
  286. }
  287. } else {
  288. return types.BadRequestErrorf("invalid type for DefaultBindingIP value")
  289. }
  290. }
  291. return nil
  292. }
  293. func (n *bridgeNetwork) getDriverChains() (*iptables.ChainInfo, *iptables.ChainInfo, error) {
  294. n.Lock()
  295. defer n.Unlock()
  296. if n.driver == nil {
  297. return nil, nil, types.BadRequestErrorf("no driver found")
  298. }
  299. return n.driver.natChain, n.driver.filterChain, nil
  300. }
  301. func (n *bridgeNetwork) getNetworkBridgeName() string {
  302. n.Lock()
  303. config := n.config
  304. n.Unlock()
  305. return config.BridgeName
  306. }
  307. func (n *bridgeNetwork) getEndpoint(eid types.UUID) (*bridgeEndpoint, error) {
  308. n.Lock()
  309. defer n.Unlock()
  310. if eid == "" {
  311. return nil, InvalidEndpointIDError(eid)
  312. }
  313. if ep, ok := n.endpoints[eid]; ok {
  314. return ep, nil
  315. }
  316. return nil, nil
  317. }
  318. // Install/Removes the iptables rules needed to isolate this network
  319. // from each of the other networks
  320. func (n *bridgeNetwork) isolateNetwork(others []*bridgeNetwork, enable bool) error {
  321. n.Lock()
  322. thisV4 := n.bridge.bridgeIPv4
  323. thisV6 := getV6Network(n.config, n.bridge)
  324. n.Unlock()
  325. // Install the rules to isolate this networks against each of the other networks
  326. for _, o := range others {
  327. o.Lock()
  328. otherV4 := o.bridge.bridgeIPv4
  329. otherV6 := getV6Network(o.config, o.bridge)
  330. o.Unlock()
  331. if !types.CompareIPNet(thisV4, otherV4) {
  332. // It's ok to pass a.b.c.d/x, iptables will ignore the host subnet bits
  333. if err := setINC(thisV4.String(), otherV4.String(), enable); err != nil {
  334. return err
  335. }
  336. }
  337. if thisV6 != nil && otherV6 != nil && !types.CompareIPNet(thisV6, otherV6) {
  338. if err := setINC(thisV6.String(), otherV6.String(), enable); err != nil {
  339. return err
  340. }
  341. }
  342. }
  343. return nil
  344. }
  345. // Checks whether this network's configuration for the network with this id conflicts with any of the passed networks
  346. func (c *networkConfiguration) conflictsWithNetworks(id types.UUID, others []*bridgeNetwork) error {
  347. for _, nw := range others {
  348. nw.Lock()
  349. nwID := nw.id
  350. nwConfig := nw.config
  351. nwBridge := nw.bridge
  352. nw.Unlock()
  353. if nwID == id {
  354. continue
  355. }
  356. // Verify the name (which may have been set by newInterface()) does not conflict with
  357. // existing bridge interfaces. Ironically the system chosen name gets stored in the config...
  358. // Basically we are checking if the two original configs were both empty.
  359. if nwConfig.BridgeName == c.BridgeName {
  360. return types.ForbiddenErrorf("conflicts with network %s (%s) by bridge name", nwID, nwConfig.BridgeName)
  361. }
  362. // If this network config specifies the AddressIPv4, we need
  363. // to make sure it does not conflict with any previously allocated
  364. // bridges. This could not be completely caught by the config conflict
  365. // check, because networks which config does not specify the AddressIPv4
  366. // get their address and subnet selected by the driver (see electBridgeIPv4())
  367. if c.AddressIPv4 != nil {
  368. if nwBridge.bridgeIPv4.Contains(c.AddressIPv4.IP) ||
  369. c.AddressIPv4.Contains(nwBridge.bridgeIPv4.IP) {
  370. return types.ForbiddenErrorf("conflicts with network %s (%s) by ip network", nwID, nwConfig.BridgeName)
  371. }
  372. }
  373. }
  374. return nil
  375. }
  376. func (d *driver) Config(option map[string]interface{}) error {
  377. var config *configuration
  378. var err error
  379. d.Lock()
  380. defer d.Unlock()
  381. if d.config != nil {
  382. return &ErrConfigExists{}
  383. }
  384. genericData, ok := option[netlabel.GenericData]
  385. if ok && genericData != nil {
  386. switch opt := genericData.(type) {
  387. case options.Generic:
  388. opaqueConfig, err := options.GenerateFromModel(opt, &configuration{})
  389. if err != nil {
  390. return err
  391. }
  392. config = opaqueConfig.(*configuration)
  393. case *configuration:
  394. config = opt
  395. default:
  396. return &ErrInvalidDriverConfig{}
  397. }
  398. d.config = config
  399. } else {
  400. config = &configuration{}
  401. d.config = config
  402. }
  403. if config.EnableIPForwarding {
  404. err = setupIPForwarding()
  405. if err != nil {
  406. return err
  407. }
  408. }
  409. if config.EnableIPTables {
  410. d.natChain, d.filterChain, err = setupIPChains(config)
  411. return err
  412. }
  413. return nil
  414. }
  415. func (d *driver) getNetwork(id types.UUID) (*bridgeNetwork, error) {
  416. d.Lock()
  417. defer d.Unlock()
  418. if id == "" {
  419. return nil, types.BadRequestErrorf("invalid network id: %s", id)
  420. }
  421. if nw, ok := d.networks[id]; ok {
  422. return nw, nil
  423. }
  424. return nil, types.NotFoundErrorf("network not found: %s", id)
  425. }
  426. func parseNetworkGenericOptions(data interface{}) (*networkConfiguration, error) {
  427. var (
  428. err error
  429. config *networkConfiguration
  430. )
  431. switch opt := data.(type) {
  432. case *networkConfiguration:
  433. config = opt
  434. case map[string]interface{}:
  435. config = &networkConfiguration{
  436. EnableICC: true,
  437. EnableIPMasquerade: true,
  438. }
  439. err = config.fromMap(opt)
  440. case options.Generic:
  441. var opaqueConfig interface{}
  442. if opaqueConfig, err = options.GenerateFromModel(opt, config); err == nil {
  443. config = opaqueConfig.(*networkConfiguration)
  444. }
  445. default:
  446. err = types.BadRequestErrorf("do not recognize network configuration format: %T", opt)
  447. }
  448. return config, err
  449. }
  450. func parseNetworkOptions(option options.Generic) (*networkConfiguration, error) {
  451. var err error
  452. config := &networkConfiguration{}
  453. // Parse generic label first, config will be re-assigned
  454. if genData, ok := option[netlabel.GenericData]; ok && genData != nil {
  455. if config, err = parseNetworkGenericOptions(genData); err != nil {
  456. return nil, err
  457. }
  458. }
  459. // Process well-known labels next
  460. if _, ok := option[netlabel.EnableIPv6]; ok {
  461. config.EnableIPv6 = option[netlabel.EnableIPv6].(bool)
  462. }
  463. // Finally validate the configuration
  464. if err = config.Validate(); err != nil {
  465. return nil, err
  466. }
  467. return config, nil
  468. }
  469. // Returns the non link-local IPv6 subnet for the containers attached to this bridge if found, nil otherwise
  470. func getV6Network(config *networkConfiguration, i *bridgeInterface) *net.IPNet {
  471. if config.FixedCIDRv6 != nil {
  472. return config.FixedCIDRv6
  473. }
  474. if i.bridgeIPv6 != nil && i.bridgeIPv6.IP != nil && !i.bridgeIPv6.IP.IsLinkLocalUnicast() {
  475. return i.bridgeIPv6
  476. }
  477. return nil
  478. }
  479. // Return a slice of networks over which caller can iterate safely
  480. func (d *driver) getNetworks() []*bridgeNetwork {
  481. d.Lock()
  482. defer d.Unlock()
  483. ls := make([]*bridgeNetwork, 0, len(d.networks))
  484. for _, nw := range d.networks {
  485. ls = append(ls, nw)
  486. }
  487. return ls
  488. }
  489. // Create a new network using bridge plugin
  490. func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error {
  491. var err error
  492. // Sanity checks
  493. d.Lock()
  494. if _, ok := d.networks[id]; ok {
  495. d.Unlock()
  496. return types.ForbiddenErrorf("network %s exists", id)
  497. }
  498. d.Unlock()
  499. // Parse and validate the config. It should not conflict with existing networks' config
  500. config, err := parseNetworkOptions(option)
  501. if err != nil {
  502. return err
  503. }
  504. networkList := d.getNetworks()
  505. for _, nw := range networkList {
  506. nw.Lock()
  507. nwConfig := nw.config
  508. nw.Unlock()
  509. if nwConfig.Conflicts(config) {
  510. return types.ForbiddenErrorf("conflicts with network %s (%s)", nw.id, nw.config.BridgeName)
  511. }
  512. }
  513. // Create and set network handler in driver
  514. network := &bridgeNetwork{
  515. id: id,
  516. endpoints: make(map[types.UUID]*bridgeEndpoint),
  517. config: config,
  518. portMapper: portmapper.New(),
  519. driver: d,
  520. }
  521. d.Lock()
  522. d.networks[id] = network
  523. d.Unlock()
  524. // On failure make sure to reset driver network handler to nil
  525. defer func() {
  526. if err != nil {
  527. d.Lock()
  528. delete(d.networks, id)
  529. d.Unlock()
  530. }
  531. }()
  532. // Create or retrieve the bridge L3 interface
  533. bridgeIface := newInterface(config)
  534. network.bridge = bridgeIface
  535. // Verify the network configuration does not conflict with previously installed
  536. // networks. This step is needed now because driver might have now set the bridge
  537. // name on this config struct. And because we need to check for possible address
  538. // conflicts, so we need to check against operationa lnetworks.
  539. if err = config.conflictsWithNetworks(id, networkList); err != nil {
  540. return err
  541. }
  542. setupNetworkIsolationRules := func(config *networkConfiguration, i *bridgeInterface) error {
  543. if err := network.isolateNetwork(networkList, true); err != nil {
  544. if err := network.isolateNetwork(networkList, false); err != nil {
  545. logrus.Warnf("Failed on removing the inter-network iptables rules on cleanup: %v", err)
  546. }
  547. return err
  548. }
  549. return nil
  550. }
  551. // Prepare the bridge setup configuration
  552. bridgeSetup := newBridgeSetup(config, bridgeIface)
  553. // If the bridge interface doesn't exist, we need to start the setup steps
  554. // by creating a new device and assigning it an IPv4 address.
  555. bridgeAlreadyExists := bridgeIface.exists()
  556. if !bridgeAlreadyExists {
  557. bridgeSetup.queueStep(setupDevice)
  558. }
  559. // Even if a bridge exists try to setup IPv4.
  560. bridgeSetup.queueStep(setupBridgeIPv4)
  561. enableIPv6Forwarding := false
  562. if d.config != nil && d.config.EnableIPForwarding && config.FixedCIDRv6 != nil {
  563. enableIPv6Forwarding = true
  564. }
  565. // Conditionally queue setup steps depending on configuration values.
  566. for _, step := range []struct {
  567. Condition bool
  568. Fn setupStep
  569. }{
  570. // Enable IPv6 on the bridge if required. We do this even for a
  571. // previously existing bridge, as it may be here from a previous
  572. // installation where IPv6 wasn't supported yet and needs to be
  573. // assigned an IPv6 link-local address.
  574. {config.EnableIPv6, setupBridgeIPv6},
  575. // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in
  576. // the case of a previously existing device.
  577. {bridgeAlreadyExists, setupVerifyAndReconcile},
  578. // Setup the bridge to allocate containers IPv4 addresses in the
  579. // specified subnet.
  580. {config.FixedCIDR != nil, setupFixedCIDRv4},
  581. // Setup the bridge to allocate containers global IPv6 addresses in the
  582. // specified subnet.
  583. {config.FixedCIDRv6 != nil, setupFixedCIDRv6},
  584. // Enable IPv6 Forwarding
  585. {enableIPv6Forwarding, setupIPv6Forwarding},
  586. // Setup Loopback Adresses Routing
  587. {!d.config.EnableUserlandProxy, setupLoopbackAdressesRouting},
  588. // Setup IPTables.
  589. {d.config.EnableIPTables, network.setupIPTables},
  590. //We want to track firewalld configuration so that
  591. //if it is started/reloaded, the rules can be applied correctly
  592. {d.config.EnableIPTables, network.setupFirewalld},
  593. // Setup DefaultGatewayIPv4
  594. {config.DefaultGatewayIPv4 != nil, setupGatewayIPv4},
  595. // Setup DefaultGatewayIPv6
  596. {config.DefaultGatewayIPv6 != nil, setupGatewayIPv6},
  597. // Add inter-network communication rules.
  598. {d.config.EnableIPTables, setupNetworkIsolationRules},
  599. //Configure bridge networking filtering if ICC is off and IP tables are enabled
  600. {!config.EnableICC && d.config.EnableIPTables, setupBridgeNetFiltering},
  601. } {
  602. if step.Condition {
  603. bridgeSetup.queueStep(step.Fn)
  604. }
  605. }
  606. // Block bridge IP from being allocated.
  607. bridgeSetup.queueStep(allocateBridgeIP)
  608. // Apply the prepared list of steps, and abort at the first error.
  609. bridgeSetup.queueStep(setupDeviceUp)
  610. if err = bridgeSetup.apply(); err != nil {
  611. return err
  612. }
  613. return nil
  614. }
  615. func (d *driver) DeleteNetwork(nid types.UUID) error {
  616. var err error
  617. // Get network handler and remove it from driver
  618. d.Lock()
  619. n, ok := d.networks[nid]
  620. d.Unlock()
  621. if !ok {
  622. return types.InternalMaskableErrorf("network %s does not exist", nid)
  623. }
  624. n.Lock()
  625. config := n.config
  626. n.Unlock()
  627. if config.BridgeName == DefaultBridgeName {
  628. return types.ForbiddenErrorf("default network of type \"%s\" cannot be deleted", networkType)
  629. }
  630. d.Lock()
  631. delete(d.networks, nid)
  632. d.Unlock()
  633. // On failure set network handler back in driver, but
  634. // only if is not already taken over by some other thread
  635. defer func() {
  636. if err != nil {
  637. d.Lock()
  638. if _, ok := d.networks[nid]; !ok {
  639. d.networks[nid] = n
  640. }
  641. d.Unlock()
  642. }
  643. }()
  644. // Sanity check
  645. if n == nil {
  646. err = driverapi.ErrNoNetwork(nid)
  647. return err
  648. }
  649. // Cannot remove network if endpoints are still present
  650. if len(n.endpoints) != 0 {
  651. err = ActiveEndpointsError(n.id)
  652. return err
  653. }
  654. // In case of failures after this point, restore the network isolation rules
  655. nwList := d.getNetworks()
  656. defer func() {
  657. if err != nil {
  658. if err := n.isolateNetwork(nwList, true); err != nil {
  659. logrus.Warnf("Failed on restoring the inter-network iptables rules on cleanup: %v", err)
  660. }
  661. }
  662. }()
  663. // Remove inter-network communication rules.
  664. err = n.isolateNetwork(nwList, false)
  665. if err != nil {
  666. return err
  667. }
  668. // Programming
  669. err = netlink.LinkDel(n.bridge.Link)
  670. return err
  671. }
  672. func addToBridge(ifaceName, bridgeName string) error {
  673. link, err := netlink.LinkByName(ifaceName)
  674. if err != nil {
  675. return fmt.Errorf("could not find interface %s: %v", ifaceName, err)
  676. }
  677. if err = netlink.LinkSetMaster(link,
  678. &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil {
  679. logrus.Debugf("Failed to add %s to bridge via netlink.Trying ioctl: %v", ifaceName, err)
  680. iface, err := net.InterfaceByName(ifaceName)
  681. if err != nil {
  682. return fmt.Errorf("could not find network interface %s: %v", ifaceName, err)
  683. }
  684. master, err := net.InterfaceByName(bridgeName)
  685. if err != nil {
  686. return fmt.Errorf("could not find bridge %s: %v", bridgeName, err)
  687. }
  688. return ioctlAddToBridge(iface, master)
  689. }
  690. return nil
  691. }
  692. func setHairpinMode(link netlink.Link, enable bool) error {
  693. err := netlink.LinkSetHairpin(link, enable)
  694. if err != nil && err != syscall.EINVAL {
  695. // If error is not EINVAL something else went wrong, bail out right away
  696. return fmt.Errorf("unable to set hairpin mode on %s via netlink: %v",
  697. link.Attrs().Name, err)
  698. }
  699. // Hairpin mode successfully set up
  700. if err == nil {
  701. return nil
  702. }
  703. // The netlink method failed with EINVAL which is probably because of an older
  704. // kernel. Try one more time via the sysfs method.
  705. path := filepath.Join("/sys/class/net", link.Attrs().Name, "brport/hairpin_mode")
  706. var val []byte
  707. if enable {
  708. val = []byte{'1', '\n'}
  709. } else {
  710. val = []byte{'0', '\n'}
  711. }
  712. if err := ioutil.WriteFile(path, val, 0644); err != nil {
  713. return fmt.Errorf("unable to set hairpin mode on %s via sysfs: %v", link.Attrs().Name, err)
  714. }
  715. return nil
  716. }
  717. func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
  718. var (
  719. ipv6Addr *net.IPNet
  720. err error
  721. )
  722. if epInfo == nil {
  723. return errors.New("invalid endpoint info passed")
  724. }
  725. if len(epInfo.Interfaces()) != 0 {
  726. return errors.New("non empty interface list passed to bridge(local) driver")
  727. }
  728. // Get the network handler and make sure it exists
  729. d.Lock()
  730. n, ok := d.networks[nid]
  731. dconfig := d.config
  732. d.Unlock()
  733. if !ok {
  734. return types.NotFoundErrorf("network %s does not exist", nid)
  735. }
  736. if n == nil {
  737. return driverapi.ErrNoNetwork(nid)
  738. }
  739. // Sanity check
  740. n.Lock()
  741. if n.id != nid {
  742. n.Unlock()
  743. return InvalidNetworkIDError(nid)
  744. }
  745. n.Unlock()
  746. // Check if endpoint id is good and retrieve correspondent endpoint
  747. ep, err := n.getEndpoint(eid)
  748. if err != nil {
  749. return err
  750. }
  751. // Endpoint with that id exists either on desired or other sandbox
  752. if ep != nil {
  753. return driverapi.ErrEndpointExists(eid)
  754. }
  755. // Try to convert the options to endpoint configuration
  756. epConfig, err := parseEndpointOptions(epOptions)
  757. if err != nil {
  758. return err
  759. }
  760. // Create and add the endpoint
  761. n.Lock()
  762. endpoint := &bridgeEndpoint{id: eid, config: epConfig}
  763. n.endpoints[eid] = endpoint
  764. n.Unlock()
  765. // On failure make sure to remove the endpoint
  766. defer func() {
  767. if err != nil {
  768. n.Lock()
  769. delete(n.endpoints, eid)
  770. n.Unlock()
  771. }
  772. }()
  773. // Generate a name for what will be the host side pipe interface
  774. hostIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
  775. if err != nil {
  776. return err
  777. }
  778. // Generate a name for what will be the sandbox side pipe interface
  779. containerIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
  780. if err != nil {
  781. return err
  782. }
  783. // Generate and add the interface pipe host <-> sandbox
  784. veth := &netlink.Veth{
  785. LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
  786. PeerName: containerIfName}
  787. if err = netlink.LinkAdd(veth); err != nil {
  788. return err
  789. }
  790. // Get the host side pipe interface handler
  791. host, err := netlink.LinkByName(hostIfName)
  792. if err != nil {
  793. return err
  794. }
  795. defer func() {
  796. if err != nil {
  797. netlink.LinkDel(host)
  798. }
  799. }()
  800. // Get the sandbox side pipe interface handler
  801. sbox, err := netlink.LinkByName(containerIfName)
  802. if err != nil {
  803. return err
  804. }
  805. defer func() {
  806. if err != nil {
  807. netlink.LinkDel(sbox)
  808. }
  809. }()
  810. n.Lock()
  811. config := n.config
  812. n.Unlock()
  813. // Add bridge inherited attributes to pipe interfaces
  814. if config.Mtu != 0 {
  815. err = netlink.LinkSetMTU(host, config.Mtu)
  816. if err != nil {
  817. return err
  818. }
  819. err = netlink.LinkSetMTU(sbox, config.Mtu)
  820. if err != nil {
  821. return err
  822. }
  823. }
  824. // Attach host side pipe interface into the bridge
  825. if err = addToBridge(hostIfName, config.BridgeName); err != nil {
  826. return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, config.BridgeName, err)
  827. }
  828. if !dconfig.EnableUserlandProxy {
  829. err = setHairpinMode(host, true)
  830. if err != nil {
  831. return err
  832. }
  833. }
  834. // v4 address for the sandbox side pipe interface
  835. ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
  836. if err != nil {
  837. return err
  838. }
  839. ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}
  840. // Down the interface before configuring mac address.
  841. if err = netlink.LinkSetDown(sbox); err != nil {
  842. return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err)
  843. }
  844. // Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
  845. mac := electMacAddress(epConfig, ip4)
  846. err = netlink.LinkSetHardwareAddr(sbox, mac)
  847. if err != nil {
  848. return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
  849. }
  850. endpoint.macAddress = mac
  851. // Up the host interface after finishing all netlink configuration
  852. if err = netlink.LinkSetUp(host); err != nil {
  853. return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
  854. }
  855. // v6 address for the sandbox side pipe interface
  856. ipv6Addr = &net.IPNet{}
  857. if config.EnableIPv6 {
  858. var ip6 net.IP
  859. network := n.bridge.bridgeIPv6
  860. if config.FixedCIDRv6 != nil {
  861. network = config.FixedCIDRv6
  862. }
  863. ones, _ := network.Mask.Size()
  864. if ones <= 80 {
  865. ip6 = make(net.IP, len(network.IP))
  866. copy(ip6, network.IP)
  867. for i, h := range mac {
  868. ip6[i+10] = h
  869. }
  870. }
  871. ip6, err := ipAllocator.RequestIP(network, ip6)
  872. if err != nil {
  873. return err
  874. }
  875. ipv6Addr = &net.IPNet{IP: ip6, Mask: network.Mask}
  876. }
  877. // Create the sandbox side pipe interface
  878. endpoint.srcName = containerIfName
  879. endpoint.addr = ipv4Addr
  880. if config.EnableIPv6 {
  881. endpoint.addrv6 = ipv6Addr
  882. }
  883. err = epInfo.AddInterface(ifaceID, endpoint.macAddress, *ipv4Addr, *ipv6Addr)
  884. if err != nil {
  885. return err
  886. }
  887. // Program any required port mapping and store them in the endpoint
  888. endpoint.portMapping, err = n.allocatePorts(epConfig, endpoint, config.DefaultBindingIP, d.config.EnableUserlandProxy)
  889. if err != nil {
  890. return err
  891. }
  892. return nil
  893. }
  894. func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
  895. var err error
  896. // Get the network handler and make sure it exists
  897. d.Lock()
  898. n, ok := d.networks[nid]
  899. d.Unlock()
  900. if !ok {
  901. return types.NotFoundErrorf("network %s does not exist", nid)
  902. }
  903. if n == nil {
  904. return driverapi.ErrNoNetwork(nid)
  905. }
  906. // Sanity Check
  907. n.Lock()
  908. if n.id != nid {
  909. n.Unlock()
  910. return InvalidNetworkIDError(nid)
  911. }
  912. n.Unlock()
  913. // Check endpoint id and if an endpoint is actually there
  914. ep, err := n.getEndpoint(eid)
  915. if err != nil {
  916. return err
  917. }
  918. if ep == nil {
  919. return EndpointNotFoundError(eid)
  920. }
  921. // Remove it
  922. n.Lock()
  923. delete(n.endpoints, eid)
  924. n.Unlock()
  925. // On failure make sure to set back ep in n.endpoints, but only
  926. // if it hasn't been taken over already by some other thread.
  927. defer func() {
  928. if err != nil {
  929. n.Lock()
  930. if _, ok := n.endpoints[eid]; !ok {
  931. n.endpoints[eid] = ep
  932. }
  933. n.Unlock()
  934. }
  935. }()
  936. // Remove port mappings. Do not stop endpoint delete on unmap failure
  937. n.releasePorts(ep)
  938. // Release the v4 address allocated to this endpoint's sandbox interface
  939. err = ipAllocator.ReleaseIP(n.bridge.bridgeIPv4, ep.addr.IP)
  940. if err != nil {
  941. return err
  942. }
  943. n.Lock()
  944. config := n.config
  945. n.Unlock()
  946. // Release the v6 address allocated to this endpoint's sandbox interface
  947. if config.EnableIPv6 {
  948. network := n.bridge.bridgeIPv6
  949. if config.FixedCIDRv6 != nil {
  950. network = config.FixedCIDRv6
  951. }
  952. err := ipAllocator.ReleaseIP(network, ep.addrv6.IP)
  953. if err != nil {
  954. return err
  955. }
  956. }
  957. // Try removal of link. Discard error: link pair might have
  958. // already been deleted by sandbox delete. Make sure defer
  959. // does not see this error either.
  960. if link, err := netlink.LinkByName(ep.srcName); err == nil {
  961. netlink.LinkDel(link)
  962. }
  963. return nil
  964. }
  965. func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{}, error) {
  966. // Get the network handler and make sure it exists
  967. d.Lock()
  968. n, ok := d.networks[nid]
  969. d.Unlock()
  970. if !ok {
  971. return nil, types.NotFoundErrorf("network %s does not exist", nid)
  972. }
  973. if n == nil {
  974. return nil, driverapi.ErrNoNetwork(nid)
  975. }
  976. // Sanity check
  977. n.Lock()
  978. if n.id != nid {
  979. n.Unlock()
  980. return nil, InvalidNetworkIDError(nid)
  981. }
  982. n.Unlock()
  983. // Check if endpoint id is good and retrieve correspondent endpoint
  984. ep, err := n.getEndpoint(eid)
  985. if err != nil {
  986. return nil, err
  987. }
  988. if ep == nil {
  989. return nil, driverapi.ErrNoEndpoint(eid)
  990. }
  991. m := make(map[string]interface{})
  992. if ep.config.ExposedPorts != nil {
  993. // Return a copy of the config data
  994. epc := make([]types.TransportPort, 0, len(ep.config.ExposedPorts))
  995. for _, tp := range ep.config.ExposedPorts {
  996. epc = append(epc, tp.GetCopy())
  997. }
  998. m[netlabel.ExposedPorts] = epc
  999. }
  1000. if ep.portMapping != nil {
  1001. // Return a copy of the operational data
  1002. pmc := make([]types.PortBinding, 0, len(ep.portMapping))
  1003. for _, pm := range ep.portMapping {
  1004. pmc = append(pmc, pm.GetCopy())
  1005. }
  1006. m[netlabel.PortMap] = pmc
  1007. }
  1008. if len(ep.macAddress) != 0 {
  1009. m[netlabel.MacAddress] = ep.macAddress
  1010. }
  1011. return m, nil
  1012. }
  1013. // Join method is invoked when a Sandbox is attached to an endpoint.
  1014. func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
  1015. network, err := d.getNetwork(nid)
  1016. if err != nil {
  1017. return err
  1018. }
  1019. endpoint, err := network.getEndpoint(eid)
  1020. if err != nil {
  1021. return err
  1022. }
  1023. if endpoint == nil {
  1024. return EndpointNotFoundError(eid)
  1025. }
  1026. for _, iNames := range jinfo.InterfaceNames() {
  1027. // Make sure to set names on the correct interface ID.
  1028. if iNames.ID() == ifaceID {
  1029. err = iNames.SetNames(endpoint.srcName, containerVethPrefix)
  1030. if err != nil {
  1031. return err
  1032. }
  1033. }
  1034. }
  1035. err = jinfo.SetGateway(network.bridge.gatewayIPv4)
  1036. if err != nil {
  1037. return err
  1038. }
  1039. err = jinfo.SetGatewayIPv6(network.bridge.gatewayIPv6)
  1040. if err != nil {
  1041. return err
  1042. }
  1043. if !network.config.EnableICC {
  1044. return d.link(network, endpoint, options, true)
  1045. }
  1046. return nil
  1047. }
  1048. // Leave method is invoked when a Sandbox detaches from an endpoint.
  1049. func (d *driver) Leave(nid, eid types.UUID) error {
  1050. network, err := d.getNetwork(nid)
  1051. if err != nil {
  1052. return err
  1053. }
  1054. endpoint, err := network.getEndpoint(eid)
  1055. if err != nil {
  1056. return err
  1057. }
  1058. if endpoint == nil {
  1059. return EndpointNotFoundError(eid)
  1060. }
  1061. if !network.config.EnableICC {
  1062. return d.link(network, endpoint, nil, false)
  1063. }
  1064. return nil
  1065. }
  1066. func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, options map[string]interface{}, enable bool) error {
  1067. var (
  1068. cc *containerConfiguration
  1069. err error
  1070. )
  1071. if enable {
  1072. cc, err = parseContainerOptions(options)
  1073. if err != nil {
  1074. return err
  1075. }
  1076. } else {
  1077. cc = endpoint.containerConfig
  1078. }
  1079. if cc == nil {
  1080. return nil
  1081. }
  1082. if endpoint.config != nil && endpoint.config.ExposedPorts != nil {
  1083. for _, p := range cc.ParentEndpoints {
  1084. var parentEndpoint *bridgeEndpoint
  1085. parentEndpoint, err = network.getEndpoint(types.UUID(p))
  1086. if err != nil {
  1087. return err
  1088. }
  1089. if parentEndpoint == nil {
  1090. err = InvalidEndpointIDError(p)
  1091. return err
  1092. }
  1093. l := newLink(parentEndpoint.addr.IP.String(),
  1094. endpoint.addr.IP.String(),
  1095. endpoint.config.ExposedPorts, network.config.BridgeName)
  1096. if enable {
  1097. err = l.Enable()
  1098. if err != nil {
  1099. return err
  1100. }
  1101. defer func() {
  1102. if err != nil {
  1103. l.Disable()
  1104. }
  1105. }()
  1106. } else {
  1107. l.Disable()
  1108. }
  1109. }
  1110. }
  1111. for _, c := range cc.ChildEndpoints {
  1112. var childEndpoint *bridgeEndpoint
  1113. childEndpoint, err = network.getEndpoint(types.UUID(c))
  1114. if err != nil {
  1115. return err
  1116. }
  1117. if childEndpoint == nil {
  1118. err = InvalidEndpointIDError(c)
  1119. return err
  1120. }
  1121. if childEndpoint.config == nil || childEndpoint.config.ExposedPorts == nil {
  1122. continue
  1123. }
  1124. l := newLink(endpoint.addr.IP.String(),
  1125. childEndpoint.addr.IP.String(),
  1126. childEndpoint.config.ExposedPorts, network.config.BridgeName)
  1127. if enable {
  1128. err = l.Enable()
  1129. if err != nil {
  1130. return err
  1131. }
  1132. defer func() {
  1133. if err != nil {
  1134. l.Disable()
  1135. }
  1136. }()
  1137. } else {
  1138. l.Disable()
  1139. }
  1140. }
  1141. if enable {
  1142. endpoint.containerConfig = cc
  1143. }
  1144. return nil
  1145. }
  1146. func (d *driver) Type() string {
  1147. return networkType
  1148. }
  1149. func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfiguration, error) {
  1150. if epOptions == nil {
  1151. return nil, nil
  1152. }
  1153. ec := &endpointConfiguration{}
  1154. if opt, ok := epOptions[netlabel.MacAddress]; ok {
  1155. if mac, ok := opt.(net.HardwareAddr); ok {
  1156. ec.MacAddress = mac
  1157. } else {
  1158. return nil, &ErrInvalidEndpointConfig{}
  1159. }
  1160. }
  1161. if opt, ok := epOptions[netlabel.PortMap]; ok {
  1162. if bs, ok := opt.([]types.PortBinding); ok {
  1163. ec.PortBindings = bs
  1164. } else {
  1165. return nil, &ErrInvalidEndpointConfig{}
  1166. }
  1167. }
  1168. if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
  1169. if ports, ok := opt.([]types.TransportPort); ok {
  1170. ec.ExposedPorts = ports
  1171. } else {
  1172. return nil, &ErrInvalidEndpointConfig{}
  1173. }
  1174. }
  1175. return ec, nil
  1176. }
  1177. func parseContainerOptions(cOptions map[string]interface{}) (*containerConfiguration, error) {
  1178. if cOptions == nil {
  1179. return nil, nil
  1180. }
  1181. genericData := cOptions[netlabel.GenericData]
  1182. if genericData == nil {
  1183. return nil, nil
  1184. }
  1185. switch opt := genericData.(type) {
  1186. case options.Generic:
  1187. opaqueConfig, err := options.GenerateFromModel(opt, &containerConfiguration{})
  1188. if err != nil {
  1189. return nil, err
  1190. }
  1191. return opaqueConfig.(*containerConfiguration), nil
  1192. case *containerConfiguration:
  1193. return opt, nil
  1194. default:
  1195. return nil, nil
  1196. }
  1197. }
  1198. func electMacAddress(epConfig *endpointConfiguration, ip net.IP) net.HardwareAddr {
  1199. if epConfig != nil && epConfig.MacAddress != nil {
  1200. return epConfig.MacAddress
  1201. }
  1202. return netutils.GenerateMACFromIP(ip)
  1203. }