github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/libnetwork/drivers/bridge/bridge.go (about) 1 //go:build linux 2 // +build linux 3 4 package bridge 5 6 import ( 7 "errors" 8 "fmt" 9 "net" 10 "os" 11 "os/exec" 12 "path/filepath" 13 "strconv" 14 "sync" 15 "syscall" 16 17 "github.com/docker/docker/libnetwork/datastore" 18 "github.com/docker/docker/libnetwork/discoverapi" 19 "github.com/docker/docker/libnetwork/driverapi" 20 "github.com/docker/docker/libnetwork/iptables" 21 "github.com/docker/docker/libnetwork/netlabel" 22 "github.com/docker/docker/libnetwork/netutils" 23 "github.com/docker/docker/libnetwork/ns" 24 "github.com/docker/docker/libnetwork/options" 25 "github.com/docker/docker/libnetwork/osl" 26 "github.com/docker/docker/libnetwork/portmapper" 27 "github.com/docker/docker/libnetwork/types" 28 "github.com/sirupsen/logrus" 29 "github.com/vishvananda/netlink" 30 ) 31 32 const ( 33 networkType = "bridge" 34 vethPrefix = "veth" 35 vethLen = 7 36 defaultContainerVethPrefix = "eth" 37 maxAllocatePortAttempts = 10 38 ) 39 40 const ( 41 // DefaultGatewayV4AuxKey represents the default-gateway configured by the user 42 DefaultGatewayV4AuxKey = "DefaultGatewayIPv4" 43 // DefaultGatewayV6AuxKey represents the ipv6 default-gateway configured by the user 44 DefaultGatewayV6AuxKey = "DefaultGatewayIPv6" 45 ) 46 47 type defaultBridgeNetworkConflict struct { 48 ID string 49 } 50 51 func (d defaultBridgeNetworkConflict) Error() string { 52 return fmt.Sprintf("Stale default bridge network %s", d.ID) 53 } 54 55 type iptableCleanFunc func() error 56 type iptablesCleanFuncs []iptableCleanFunc 57 58 // configuration info for the "bridge" driver. 59 type configuration struct { 60 EnableIPForwarding bool 61 EnableIPTables bool 62 EnableIP6Tables bool 63 EnableUserlandProxy bool 64 UserlandProxyPath string 65 } 66 67 // networkConfiguration for network specific configuration 68 type networkConfiguration struct { 69 ID string 70 BridgeName string 71 EnableIPv6 bool 72 EnableIPMasquerade bool 73 EnableICC bool 74 InhibitIPv4 bool 75 Mtu int 76 DefaultBindingIP net.IP 77 DefaultBridge bool 78 HostIP net.IP 79 ContainerIfacePrefix string 80 // Internal fields set after ipam data parsing 81 AddressIPv4 *net.IPNet 82 AddressIPv6 *net.IPNet 83 DefaultGatewayIPv4 net.IP 84 DefaultGatewayIPv6 net.IP 85 dbIndex uint64 86 dbExists bool 87 Internal bool 88 89 BridgeIfaceCreator ifaceCreator 90 } 91 92 // ifaceCreator represents how the bridge interface was created 93 type ifaceCreator int8 94 95 const ( 96 ifaceCreatorUnknown ifaceCreator = iota 97 ifaceCreatedByLibnetwork 98 ifaceCreatedByUser 99 ) 100 101 // endpointConfiguration represents the user specified configuration for the sandbox endpoint 102 type endpointConfiguration struct { 103 MacAddress net.HardwareAddr 104 } 105 106 // containerConfiguration represents the user specified configuration for a container 107 type containerConfiguration struct { 108 ParentEndpoints []string 109 ChildEndpoints []string 110 } 111 112 // connectivityConfiguration represents the user specified configuration regarding the external connectivity 113 type connectivityConfiguration struct { 114 PortBindings []types.PortBinding 115 ExposedPorts []types.TransportPort 116 } 117 118 type bridgeEndpoint struct { 119 id string 120 nid string 121 srcName string 122 addr *net.IPNet 123 addrv6 *net.IPNet 124 macAddress net.HardwareAddr 125 config *endpointConfiguration // User specified parameters 126 containerConfig *containerConfiguration 127 extConnConfig *connectivityConfiguration 128 portMapping []types.PortBinding // Operation port bindings 129 dbIndex uint64 130 dbExists bool 131 } 132 133 type bridgeNetwork struct { 134 id string 135 bridge *bridgeInterface // The bridge's L3 interface 136 config *networkConfiguration 137 endpoints map[string]*bridgeEndpoint // key: endpoint id 138 portMapper *portmapper.PortMapper 139 portMapperV6 *portmapper.PortMapper 140 driver *driver // The network's driver 141 iptCleanFuncs iptablesCleanFuncs 142 sync.Mutex 143 } 144 145 type driver struct { 146 config *configuration 147 natChain *iptables.ChainInfo 148 filterChain *iptables.ChainInfo 149 isolationChain1 *iptables.ChainInfo 150 isolationChain2 *iptables.ChainInfo 151 natChainV6 *iptables.ChainInfo 152 filterChainV6 *iptables.ChainInfo 153 isolationChain1V6 *iptables.ChainInfo 154 isolationChain2V6 *iptables.ChainInfo 155 networks map[string]*bridgeNetwork 156 store datastore.DataStore 157 nlh *netlink.Handle 158 configNetwork sync.Mutex 159 sync.Mutex 160 } 161 162 // New constructs a new bridge driver 163 func newDriver() *driver { 164 return &driver{networks: map[string]*bridgeNetwork{}, config: &configuration{}} 165 } 166 167 // Init registers a new instance of bridge driver 168 func Init(dc driverapi.DriverCallback, config map[string]interface{}) error { 169 d := newDriver() 170 if err := d.configure(config); err != nil { 171 return err 172 } 173 174 c := driverapi.Capability{ 175 DataScope: datastore.LocalScope, 176 ConnectivityScope: datastore.LocalScope, 177 } 178 return dc.RegisterDriver(networkType, d, c) 179 } 180 181 // Validate performs a static validation on the network configuration parameters. 182 // Whatever can be assessed a priori before attempting any programming. 183 func (c *networkConfiguration) Validate() error { 184 if c.Mtu < 0 { 185 return ErrInvalidMtu(c.Mtu) 186 } 187 188 // If bridge v4 subnet is specified 189 if c.AddressIPv4 != nil { 190 // If default gw is specified, it must be part of bridge subnet 191 if c.DefaultGatewayIPv4 != nil { 192 if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) { 193 return &ErrInvalidGateway{} 194 } 195 } 196 } 197 198 // If default v6 gw is specified, AddressIPv6 must be specified and gw must belong to AddressIPv6 subnet 199 if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil { 200 if c.AddressIPv6 == nil || !c.AddressIPv6.Contains(c.DefaultGatewayIPv6) { 201 return &ErrInvalidGateway{} 202 } 203 } 204 return nil 205 } 206 207 // Conflicts check if two NetworkConfiguration objects overlap 208 func (c *networkConfiguration) Conflicts(o *networkConfiguration) error { 209 if o == nil { 210 return errors.New("same configuration") 211 } 212 213 // Also empty, because only one network with empty name is allowed 214 if c.BridgeName == o.BridgeName { 215 return errors.New("networks have same bridge name") 216 } 217 218 // They must be in different subnets 219 if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) && 220 (c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) { 221 return errors.New("networks have overlapping IPv4") 222 } 223 224 // They must be in different v6 subnets 225 if (c.AddressIPv6 != nil && o.AddressIPv6 != nil) && 226 (c.AddressIPv6.Contains(o.AddressIPv6.IP) || o.AddressIPv6.Contains(c.AddressIPv6.IP)) { 227 return errors.New("networks have overlapping IPv6") 228 } 229 230 return nil 231 } 232 233 func (c *networkConfiguration) fromLabels(labels map[string]string) error { 234 var err error 235 for label, value := range labels { 236 switch label { 237 case BridgeName: 238 c.BridgeName = value 239 case netlabel.DriverMTU: 240 if c.Mtu, err = strconv.Atoi(value); err != nil { 241 return parseErr(label, value, err.Error()) 242 } 243 case netlabel.EnableIPv6: 244 if c.EnableIPv6, err = strconv.ParseBool(value); err != nil { 245 return parseErr(label, value, err.Error()) 246 } 247 case EnableIPMasquerade: 248 if c.EnableIPMasquerade, err = strconv.ParseBool(value); err != nil { 249 return parseErr(label, value, err.Error()) 250 } 251 case EnableICC: 252 if c.EnableICC, err = strconv.ParseBool(value); err != nil { 253 return parseErr(label, value, err.Error()) 254 } 255 case InhibitIPv4: 256 if c.InhibitIPv4, err = strconv.ParseBool(value); err != nil { 257 return parseErr(label, value, err.Error()) 258 } 259 case DefaultBridge: 260 if c.DefaultBridge, err = strconv.ParseBool(value); err != nil { 261 return parseErr(label, value, err.Error()) 262 } 263 case DefaultBindingIP: 264 if c.DefaultBindingIP = net.ParseIP(value); c.DefaultBindingIP == nil { 265 return parseErr(label, value, "nil ip") 266 } 267 case netlabel.ContainerIfacePrefix: 268 c.ContainerIfacePrefix = value 269 case netlabel.HostIP: 270 if c.HostIP = net.ParseIP(value); c.HostIP == nil { 271 return parseErr(label, value, "nil ip") 272 } 273 } 274 } 275 276 return nil 277 } 278 279 func parseErr(label, value, errString string) error { 280 return types.BadRequestErrorf("failed to parse %s value: %v (%s)", label, value, errString) 281 } 282 283 func (n *bridgeNetwork) registerIptCleanFunc(clean iptableCleanFunc) { 284 n.iptCleanFuncs = append(n.iptCleanFuncs, clean) 285 } 286 287 func (n *bridgeNetwork) getDriverChains(version iptables.IPVersion) (*iptables.ChainInfo, *iptables.ChainInfo, *iptables.ChainInfo, *iptables.ChainInfo, error) { 288 n.Lock() 289 defer n.Unlock() 290 291 if n.driver == nil { 292 return nil, nil, nil, nil, types.BadRequestErrorf("no driver found") 293 } 294 295 if version == iptables.IPv6 { 296 return n.driver.natChainV6, n.driver.filterChainV6, n.driver.isolationChain1V6, n.driver.isolationChain2V6, nil 297 } 298 299 return n.driver.natChain, n.driver.filterChain, n.driver.isolationChain1, n.driver.isolationChain2, nil 300 } 301 302 func (n *bridgeNetwork) getNetworkBridgeName() string { 303 n.Lock() 304 config := n.config 305 n.Unlock() 306 307 return config.BridgeName 308 } 309 310 func (n *bridgeNetwork) getEndpoint(eid string) (*bridgeEndpoint, error) { 311 n.Lock() 312 defer n.Unlock() 313 314 if eid == "" { 315 return nil, InvalidEndpointIDError(eid) 316 } 317 318 if ep, ok := n.endpoints[eid]; ok { 319 return ep, nil 320 } 321 322 return nil, nil 323 } 324 325 // Install/Removes the iptables rules needed to isolate this network 326 // from each of the other networks 327 func (n *bridgeNetwork) isolateNetwork(enable bool) error { 328 n.Lock() 329 thisConfig := n.config 330 n.Unlock() 331 332 if thisConfig.Internal { 333 return nil 334 } 335 336 // Install the rules to isolate this network against each of the other networks 337 if n.driver.config.EnableIP6Tables { 338 err := setINC(iptables.IPv6, thisConfig.BridgeName, enable) 339 if err != nil { 340 return err 341 } 342 } 343 344 if n.driver.config.EnableIPTables { 345 return setINC(iptables.IPv4, thisConfig.BridgeName, enable) 346 } 347 return nil 348 } 349 350 func (d *driver) configure(option map[string]interface{}) error { 351 var ( 352 config *configuration 353 err error 354 natChain *iptables.ChainInfo 355 filterChain *iptables.ChainInfo 356 isolationChain1 *iptables.ChainInfo 357 isolationChain2 *iptables.ChainInfo 358 natChainV6 *iptables.ChainInfo 359 filterChainV6 *iptables.ChainInfo 360 isolationChain1V6 *iptables.ChainInfo 361 isolationChain2V6 *iptables.ChainInfo 362 ) 363 364 genericData, ok := option[netlabel.GenericData] 365 if !ok || genericData == nil { 366 return nil 367 } 368 369 switch opt := genericData.(type) { 370 case options.Generic: 371 opaqueConfig, err := options.GenerateFromModel(opt, &configuration{}) 372 if err != nil { 373 return err 374 } 375 config = opaqueConfig.(*configuration) 376 case *configuration: 377 config = opt 378 default: 379 return &ErrInvalidDriverConfig{} 380 } 381 382 if config.EnableIPTables || config.EnableIP6Tables { 383 if _, err := os.Stat("/proc/sys/net/bridge"); err != nil { 384 if out, err := exec.Command("modprobe", "-va", "bridge", "br_netfilter").CombinedOutput(); err != nil { 385 logrus.Warnf("Running modprobe bridge br_netfilter failed with message: %s, error: %v", out, err) 386 } 387 } 388 } 389 390 if config.EnableIPTables { 391 removeIPChains(iptables.IPv4) 392 393 natChain, filterChain, isolationChain1, isolationChain2, err = setupIPChains(config, iptables.IPv4) 394 if err != nil { 395 return err 396 } 397 398 // Make sure on firewall reload, first thing being re-played is chains creation 399 iptables.OnReloaded(func() { 400 logrus.Debugf("Recreating iptables chains on firewall reload") 401 if _, _, _, _, err := setupIPChains(config, iptables.IPv4); err != nil { 402 logrus.WithError(err).Error("Error reloading iptables chains") 403 } 404 }) 405 } 406 407 if config.EnableIP6Tables { 408 removeIPChains(iptables.IPv6) 409 410 natChainV6, filterChainV6, isolationChain1V6, isolationChain2V6, err = setupIPChains(config, iptables.IPv6) 411 if err != nil { 412 return err 413 } 414 415 // Make sure on firewall reload, first thing being re-played is chains creation 416 iptables.OnReloaded(func() { 417 logrus.Debugf("Recreating ip6tables chains on firewall reload") 418 if _, _, _, _, err := setupIPChains(config, iptables.IPv6); err != nil { 419 logrus.WithError(err).Error("Error reloading ip6tables chains") 420 } 421 }) 422 } 423 424 if config.EnableIPForwarding { 425 err = setupIPForwarding(config.EnableIPTables, config.EnableIP6Tables) 426 if err != nil { 427 logrus.Warn(err) 428 return err 429 } 430 } 431 432 d.Lock() 433 d.natChain = natChain 434 d.filterChain = filterChain 435 d.isolationChain1 = isolationChain1 436 d.isolationChain2 = isolationChain2 437 d.natChainV6 = natChainV6 438 d.filterChainV6 = filterChainV6 439 d.isolationChain1V6 = isolationChain1V6 440 d.isolationChain2V6 = isolationChain2V6 441 d.config = config 442 d.Unlock() 443 444 err = d.initStore(option) 445 if err != nil { 446 return err 447 } 448 449 return nil 450 } 451 452 func (d *driver) getNetwork(id string) (*bridgeNetwork, error) { 453 d.Lock() 454 defer d.Unlock() 455 456 if id == "" { 457 return nil, types.BadRequestErrorf("invalid network id: %s", id) 458 } 459 460 if nw, ok := d.networks[id]; ok { 461 return nw, nil 462 } 463 464 return nil, types.NotFoundErrorf("network not found: %s", id) 465 } 466 467 func parseNetworkGenericOptions(data interface{}) (*networkConfiguration, error) { 468 var ( 469 err error 470 config *networkConfiguration 471 ) 472 473 switch opt := data.(type) { 474 case *networkConfiguration: 475 config = opt 476 case map[string]string: 477 config = &networkConfiguration{ 478 EnableICC: true, 479 EnableIPMasquerade: true, 480 } 481 err = config.fromLabels(opt) 482 case options.Generic: 483 var opaqueConfig interface{} 484 if opaqueConfig, err = options.GenerateFromModel(opt, config); err == nil { 485 config = opaqueConfig.(*networkConfiguration) 486 } 487 default: 488 err = types.BadRequestErrorf("do not recognize network configuration format: %T", opt) 489 } 490 491 return config, err 492 } 493 494 func (c *networkConfiguration) processIPAM(id string, ipamV4Data, ipamV6Data []driverapi.IPAMData) error { 495 if len(ipamV4Data) > 1 || len(ipamV6Data) > 1 { 496 return types.ForbiddenErrorf("bridge driver doesn't support multiple subnets") 497 } 498 499 if len(ipamV4Data) == 0 { 500 return types.BadRequestErrorf("bridge network %s requires ipv4 configuration", id) 501 } 502 503 if ipamV4Data[0].Gateway != nil { 504 c.AddressIPv4 = types.GetIPNetCopy(ipamV4Data[0].Gateway) 505 } 506 507 if gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey]; ok { 508 c.DefaultGatewayIPv4 = gw.IP 509 } 510 511 if len(ipamV6Data) > 0 { 512 c.AddressIPv6 = ipamV6Data[0].Pool 513 514 if ipamV6Data[0].Gateway != nil { 515 c.AddressIPv6 = types.GetIPNetCopy(ipamV6Data[0].Gateway) 516 } 517 518 if gw, ok := ipamV6Data[0].AuxAddresses[DefaultGatewayV6AuxKey]; ok { 519 c.DefaultGatewayIPv6 = gw.IP 520 } 521 } 522 523 return nil 524 } 525 526 func parseNetworkOptions(id string, option options.Generic) (*networkConfiguration, error) { 527 var ( 528 err error 529 config = &networkConfiguration{} 530 ) 531 532 // Parse generic label first, config will be re-assigned 533 if genData, ok := option[netlabel.GenericData]; ok && genData != nil { 534 if config, err = parseNetworkGenericOptions(genData); err != nil { 535 return nil, err 536 } 537 } 538 539 // Process well-known labels next 540 if val, ok := option[netlabel.EnableIPv6]; ok { 541 config.EnableIPv6 = val.(bool) 542 } 543 544 if val, ok := option[netlabel.Internal]; ok { 545 if internal, ok := val.(bool); ok && internal { 546 config.Internal = true 547 } 548 } 549 550 // Finally validate the configuration 551 if err = config.Validate(); err != nil { 552 return nil, err 553 } 554 555 if config.BridgeName == "" && !config.DefaultBridge { 556 config.BridgeName = "br-" + id[:12] 557 } 558 559 exists, err := bridgeInterfaceExists(config.BridgeName) 560 if err != nil { 561 return nil, err 562 } 563 564 if !exists { 565 config.BridgeIfaceCreator = ifaceCreatedByLibnetwork 566 } else { 567 config.BridgeIfaceCreator = ifaceCreatedByUser 568 } 569 570 config.ID = id 571 return config, nil 572 } 573 574 // Return a slice of networks over which caller can iterate safely 575 func (d *driver) getNetworks() []*bridgeNetwork { 576 d.Lock() 577 defer d.Unlock() 578 579 ls := make([]*bridgeNetwork, 0, len(d.networks)) 580 for _, nw := range d.networks { 581 ls = append(ls, nw) 582 } 583 return ls 584 } 585 586 func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) { 587 return nil, types.NotImplementedErrorf("not implemented") 588 } 589 590 func (d *driver) NetworkFree(id string) error { 591 return types.NotImplementedErrorf("not implemented") 592 } 593 594 func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) { 595 } 596 597 func (d *driver) DecodeTableEntry(tablename string, key string, value []byte) (string, map[string]string) { 598 return "", nil 599 } 600 601 // Create a new network using bridge plugin 602 func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error { 603 if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" { 604 return types.BadRequestErrorf("ipv4 pool is empty") 605 } 606 // Sanity checks 607 d.Lock() 608 if _, ok := d.networks[id]; ok { 609 d.Unlock() 610 return types.ForbiddenErrorf("network %s exists", id) 611 } 612 d.Unlock() 613 614 // Parse and validate the config. It should not be conflict with existing networks' config 615 config, err := parseNetworkOptions(id, option) 616 if err != nil { 617 return err 618 } 619 620 if err = config.processIPAM(id, ipV4Data, ipV6Data); err != nil { 621 return err 622 } 623 624 // start the critical section, from this point onward we are dealing with the list of networks 625 // so to be consistent we cannot allow that the list changes 626 d.configNetwork.Lock() 627 defer d.configNetwork.Unlock() 628 629 // check network conflicts 630 if err = d.checkConflict(config); err != nil { 631 nerr, ok := err.(defaultBridgeNetworkConflict) 632 if !ok { 633 return err 634 } 635 // Got a conflict with a stale default network, clean that up and continue 636 logrus.Warn(nerr) 637 if err := d.deleteNetwork(nerr.ID); err != nil { 638 logrus.WithError(err).Debug("Error while cleaning up network on conflict") 639 } 640 } 641 642 // there is no conflict, now create the network 643 if err = d.createNetwork(config); err != nil { 644 return err 645 } 646 647 return d.storeUpdate(config) 648 } 649 650 func (d *driver) checkConflict(config *networkConfiguration) error { 651 networkList := d.getNetworks() 652 for _, nw := range networkList { 653 nw.Lock() 654 nwConfig := nw.config 655 nw.Unlock() 656 if err := nwConfig.Conflicts(config); err != nil { 657 if nwConfig.DefaultBridge { 658 // We encountered and identified a stale default network 659 // We must delete it as libnetwork is the source of truth 660 // The default network being created must be the only one 661 // This can happen only from docker 1.12 on ward 662 logrus.Infof("Found stale default bridge network %s (%s)", nwConfig.ID, nwConfig.BridgeName) 663 return defaultBridgeNetworkConflict{nwConfig.ID} 664 } 665 666 return types.ForbiddenErrorf("cannot create network %s (%s): conflicts with network %s (%s): %s", 667 config.ID, config.BridgeName, nwConfig.ID, nwConfig.BridgeName, err.Error()) 668 } 669 } 670 return nil 671 } 672 673 func (d *driver) createNetwork(config *networkConfiguration) (err error) { 674 defer osl.InitOSContext()() 675 676 // Initialize handle when needed 677 d.Lock() 678 if d.nlh == nil { 679 d.nlh = ns.NlHandle() 680 } 681 d.Unlock() 682 683 // Create or retrieve the bridge L3 interface 684 bridgeIface, err := newInterface(d.nlh, config) 685 if err != nil { 686 return err 687 } 688 689 // Create and set network handler in driver 690 network := &bridgeNetwork{ 691 id: config.ID, 692 endpoints: make(map[string]*bridgeEndpoint), 693 config: config, 694 portMapper: portmapper.New(d.config.UserlandProxyPath), 695 portMapperV6: portmapper.New(d.config.UserlandProxyPath), 696 bridge: bridgeIface, 697 driver: d, 698 } 699 700 d.Lock() 701 d.networks[config.ID] = network 702 d.Unlock() 703 704 // On failure make sure to reset driver network handler to nil 705 defer func() { 706 if err != nil { 707 d.Lock() 708 delete(d.networks, config.ID) 709 d.Unlock() 710 } 711 }() 712 713 // Add inter-network communication rules. 714 setupNetworkIsolationRules := func(config *networkConfiguration, i *bridgeInterface) error { 715 if err := network.isolateNetwork(true); err != nil { 716 if err = network.isolateNetwork(false); err != nil { 717 logrus.Warnf("Failed on removing the inter-network iptables rules on cleanup: %v", err) 718 } 719 return err 720 } 721 // register the cleanup function 722 network.registerIptCleanFunc(func() error { 723 return network.isolateNetwork(false) 724 }) 725 return nil 726 } 727 728 // Prepare the bridge setup configuration 729 bridgeSetup := newBridgeSetup(config, bridgeIface) 730 731 // If the bridge interface doesn't exist, we need to start the setup steps 732 // by creating a new device and assigning it an IPv4 address. 733 bridgeAlreadyExists := bridgeIface.exists() 734 if !bridgeAlreadyExists { 735 bridgeSetup.queueStep(setupDevice) 736 bridgeSetup.queueStep(setupDefaultSysctl) 737 } 738 739 // For the default bridge, set expected sysctls 740 if config.DefaultBridge { 741 bridgeSetup.queueStep(setupDefaultSysctl) 742 } 743 744 // Even if a bridge exists try to setup IPv4. 745 bridgeSetup.queueStep(setupBridgeIPv4) 746 747 enableIPv6Forwarding := d.config.EnableIPForwarding && config.AddressIPv6 != nil 748 749 // Conditionally queue setup steps depending on configuration values. 750 for _, step := range []struct { 751 Condition bool 752 Fn setupStep 753 }{ 754 // Enable IPv6 on the bridge if required. We do this even for a 755 // previously existing bridge, as it may be here from a previous 756 // installation where IPv6 wasn't supported yet and needs to be 757 // assigned an IPv6 link-local address. 758 {config.EnableIPv6, setupBridgeIPv6}, 759 760 // We ensure that the bridge has the expectedIPv4 and IPv6 addresses in 761 // the case of a previously existing device. 762 {bridgeAlreadyExists && !config.InhibitIPv4, setupVerifyAndReconcile}, 763 764 // Enable IPv6 Forwarding 765 {enableIPv6Forwarding, setupIPv6Forwarding}, 766 767 // Setup Loopback Addresses Routing 768 {!d.config.EnableUserlandProxy, setupLoopbackAddressesRouting}, 769 770 // Setup IPTables. 771 {d.config.EnableIPTables, network.setupIP4Tables}, 772 773 // Setup IP6Tables. 774 {config.EnableIPv6 && d.config.EnableIP6Tables, network.setupIP6Tables}, 775 776 // We want to track firewalld configuration so that 777 // if it is started/reloaded, the rules can be applied correctly 778 {d.config.EnableIPTables, network.setupFirewalld}, 779 // same for IPv6 780 {config.EnableIPv6 && d.config.EnableIP6Tables, network.setupFirewalld6}, 781 782 // Setup DefaultGatewayIPv4 783 {config.DefaultGatewayIPv4 != nil, setupGatewayIPv4}, 784 785 // Setup DefaultGatewayIPv6 786 {config.DefaultGatewayIPv6 != nil, setupGatewayIPv6}, 787 788 // Add inter-network communication rules. 789 {d.config.EnableIPTables, setupNetworkIsolationRules}, 790 791 // Configure bridge networking filtering if ICC is off and IP tables are enabled 792 {!config.EnableICC && d.config.EnableIPTables, setupBridgeNetFiltering}, 793 } { 794 if step.Condition { 795 bridgeSetup.queueStep(step.Fn) 796 } 797 } 798 799 // Apply the prepared list of steps, and abort at the first error. 800 bridgeSetup.queueStep(setupDeviceUp) 801 return bridgeSetup.apply() 802 } 803 804 func (d *driver) DeleteNetwork(nid string) error { 805 806 d.configNetwork.Lock() 807 defer d.configNetwork.Unlock() 808 809 return d.deleteNetwork(nid) 810 } 811 812 func (d *driver) deleteNetwork(nid string) error { 813 var err error 814 815 defer osl.InitOSContext()() 816 // Get network handler and remove it from driver 817 d.Lock() 818 n, ok := d.networks[nid] 819 d.Unlock() 820 821 if !ok { 822 return types.InternalMaskableErrorf("network %s does not exist", nid) 823 } 824 825 n.Lock() 826 config := n.config 827 n.Unlock() 828 829 // delele endpoints belong to this network 830 for _, ep := range n.endpoints { 831 if err := n.releasePorts(ep); err != nil { 832 logrus.Warn(err) 833 } 834 if link, err := d.nlh.LinkByName(ep.srcName); err == nil { 835 if err := d.nlh.LinkDel(link); err != nil { 836 logrus.WithError(err).Errorf("Failed to delete interface (%s)'s link on endpoint (%s) delete", ep.srcName, ep.id) 837 } 838 } 839 840 if err := d.storeDelete(ep); err != nil { 841 logrus.Warnf("Failed to remove bridge endpoint %.7s from store: %v", ep.id, err) 842 } 843 } 844 845 d.Lock() 846 delete(d.networks, nid) 847 d.Unlock() 848 849 // On failure set network handler back in driver, but 850 // only if is not already taken over by some other thread 851 defer func() { 852 if err != nil { 853 d.Lock() 854 if _, ok := d.networks[nid]; !ok { 855 d.networks[nid] = n 856 } 857 d.Unlock() 858 } 859 }() 860 861 switch config.BridgeIfaceCreator { 862 case ifaceCreatedByLibnetwork, ifaceCreatorUnknown: 863 // We only delete the bridge if it was created by the bridge driver and 864 // it is not the default one (to keep the backward compatible behavior.) 865 if !config.DefaultBridge { 866 if err := d.nlh.LinkDel(n.bridge.Link); err != nil { 867 logrus.Warnf("Failed to remove bridge interface %s on network %s delete: %v", config.BridgeName, nid, err) 868 } 869 } 870 case ifaceCreatedByUser: 871 // Don't delete the bridge interface if it was not created by libnetwork. 872 } 873 874 // clean all relevant iptables rules 875 for _, cleanFunc := range n.iptCleanFuncs { 876 if errClean := cleanFunc(); errClean != nil { 877 logrus.Warnf("Failed to clean iptables rules for bridge network: %v", errClean) 878 } 879 } 880 return d.storeDelete(config) 881 } 882 883 func addToBridge(nlh *netlink.Handle, ifaceName, bridgeName string) error { 884 link, err := nlh.LinkByName(ifaceName) 885 if err != nil { 886 return fmt.Errorf("could not find interface %s: %v", ifaceName, err) 887 } 888 if err = nlh.LinkSetMaster(link, 889 &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}}); err != nil { 890 logrus.Debugf("Failed to add %s to bridge via netlink.Trying ioctl: %v", ifaceName, err) 891 iface, err := net.InterfaceByName(ifaceName) 892 if err != nil { 893 return fmt.Errorf("could not find network interface %s: %v", ifaceName, err) 894 } 895 896 master, err := net.InterfaceByName(bridgeName) 897 if err != nil { 898 return fmt.Errorf("could not find bridge %s: %v", bridgeName, err) 899 } 900 901 return ioctlAddToBridge(iface, master) 902 } 903 return nil 904 } 905 906 func setHairpinMode(nlh *netlink.Handle, link netlink.Link, enable bool) error { 907 err := nlh.LinkSetHairpin(link, enable) 908 if err != nil && err != syscall.EINVAL { 909 // If error is not EINVAL something else went wrong, bail out right away 910 return fmt.Errorf("unable to set hairpin mode on %s via netlink: %v", 911 link.Attrs().Name, err) 912 } 913 914 // Hairpin mode successfully set up 915 if err == nil { 916 return nil 917 } 918 919 // The netlink method failed with EINVAL which is probably because of an older 920 // kernel. Try one more time via the sysfs method. 921 path := filepath.Join("/sys/class/net", link.Attrs().Name, "brport/hairpin_mode") 922 923 var val []byte 924 if enable { 925 val = []byte{'1', '\n'} 926 } else { 927 val = []byte{'0', '\n'} 928 } 929 930 if err := os.WriteFile(path, val, 0644); err != nil { 931 return fmt.Errorf("unable to set hairpin mode on %s via sysfs: %v", link.Attrs().Name, err) 932 } 933 934 return nil 935 } 936 937 func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error { 938 defer osl.InitOSContext()() 939 940 if ifInfo == nil { 941 return errors.New("invalid interface info passed") 942 } 943 944 // Get the network handler and make sure it exists 945 d.Lock() 946 n, ok := d.networks[nid] 947 dconfig := d.config 948 d.Unlock() 949 950 if !ok { 951 return types.NotFoundErrorf("network %s does not exist", nid) 952 } 953 if n == nil { 954 return driverapi.ErrNoNetwork(nid) 955 } 956 957 // Sanity check 958 n.Lock() 959 if n.id != nid { 960 n.Unlock() 961 return InvalidNetworkIDError(nid) 962 } 963 n.Unlock() 964 965 // Check if endpoint id is good and retrieve correspondent endpoint 966 ep, err := n.getEndpoint(eid) 967 if err != nil { 968 return err 969 } 970 971 // Endpoint with that id exists either on desired or other sandbox 972 if ep != nil { 973 return driverapi.ErrEndpointExists(eid) 974 } 975 976 // Try to convert the options to endpoint configuration 977 epConfig, err := parseEndpointOptions(epOptions) 978 if err != nil { 979 return err 980 } 981 982 // Create and add the endpoint 983 n.Lock() 984 endpoint := &bridgeEndpoint{id: eid, nid: nid, config: epConfig} 985 n.endpoints[eid] = endpoint 986 n.Unlock() 987 988 // On failure make sure to remove the endpoint 989 defer func() { 990 if err != nil { 991 n.Lock() 992 delete(n.endpoints, eid) 993 n.Unlock() 994 } 995 }() 996 997 // Generate a name for what will be the host side pipe interface 998 hostIfName, err := netutils.GenerateIfaceName(d.nlh, vethPrefix, vethLen) 999 if err != nil { 1000 return err 1001 } 1002 1003 // Generate a name for what will be the sandbox side pipe interface 1004 containerIfName, err := netutils.GenerateIfaceName(d.nlh, vethPrefix, vethLen) 1005 if err != nil { 1006 return err 1007 } 1008 1009 // Generate and add the interface pipe host <-> sandbox 1010 veth := &netlink.Veth{ 1011 LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0}, 1012 PeerName: containerIfName} 1013 if err = d.nlh.LinkAdd(veth); err != nil { 1014 return types.InternalErrorf("failed to add the host (%s) <=> sandbox (%s) pair interfaces: %v", hostIfName, containerIfName, err) 1015 } 1016 1017 // Get the host side pipe interface handler 1018 host, err := d.nlh.LinkByName(hostIfName) 1019 if err != nil { 1020 return types.InternalErrorf("failed to find host side interface %s: %v", hostIfName, err) 1021 } 1022 defer func() { 1023 if err != nil { 1024 if err := d.nlh.LinkDel(host); err != nil { 1025 logrus.WithError(err).Warnf("Failed to delete host side interface (%s)'s link", hostIfName) 1026 } 1027 } 1028 }() 1029 1030 // Get the sandbox side pipe interface handler 1031 sbox, err := d.nlh.LinkByName(containerIfName) 1032 if err != nil { 1033 return types.InternalErrorf("failed to find sandbox side interface %s: %v", containerIfName, err) 1034 } 1035 defer func() { 1036 if err != nil { 1037 if err := d.nlh.LinkDel(sbox); err != nil { 1038 logrus.WithError(err).Warnf("Failed to delete sandbox side interface (%s)'s link", containerIfName) 1039 } 1040 } 1041 }() 1042 1043 n.Lock() 1044 config := n.config 1045 n.Unlock() 1046 1047 // Add bridge inherited attributes to pipe interfaces 1048 if config.Mtu != 0 { 1049 err = d.nlh.LinkSetMTU(host, config.Mtu) 1050 if err != nil { 1051 return types.InternalErrorf("failed to set MTU on host interface %s: %v", hostIfName, err) 1052 } 1053 err = d.nlh.LinkSetMTU(sbox, config.Mtu) 1054 if err != nil { 1055 return types.InternalErrorf("failed to set MTU on sandbox interface %s: %v", containerIfName, err) 1056 } 1057 } 1058 1059 // Attach host side pipe interface into the bridge 1060 if err = addToBridge(d.nlh, hostIfName, config.BridgeName); err != nil { 1061 return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, config.BridgeName, err) 1062 } 1063 1064 if !dconfig.EnableUserlandProxy { 1065 err = setHairpinMode(d.nlh, host, true) 1066 if err != nil { 1067 return err 1068 } 1069 } 1070 1071 // Store the sandbox side pipe interface parameters 1072 endpoint.srcName = containerIfName 1073 endpoint.macAddress = ifInfo.MacAddress() 1074 endpoint.addr = ifInfo.Address() 1075 endpoint.addrv6 = ifInfo.AddressIPv6() 1076 1077 // Set the sbox's MAC if not provided. If specified, use the one configured by user, otherwise generate one based on IP. 1078 if endpoint.macAddress == nil { 1079 endpoint.macAddress = electMacAddress(epConfig, endpoint.addr.IP) 1080 if err = ifInfo.SetMacAddress(endpoint.macAddress); err != nil { 1081 return err 1082 } 1083 } 1084 1085 // Up the host interface after finishing all netlink configuration 1086 if err = d.nlh.LinkSetUp(host); err != nil { 1087 return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err) 1088 } 1089 1090 if endpoint.addrv6 == nil && config.EnableIPv6 { 1091 var ip6 net.IP 1092 network := n.bridge.bridgeIPv6 1093 if config.AddressIPv6 != nil { 1094 network = config.AddressIPv6 1095 } 1096 1097 ones, _ := network.Mask.Size() 1098 if ones > 80 { 1099 err = types.ForbiddenErrorf("Cannot self generate an IPv6 address on network %v: At least 48 host bits are needed.", network) 1100 return err 1101 } 1102 1103 ip6 = make(net.IP, len(network.IP)) 1104 copy(ip6, network.IP) 1105 for i, h := range endpoint.macAddress { 1106 ip6[i+10] = h 1107 } 1108 1109 endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask} 1110 if err = ifInfo.SetIPAddress(endpoint.addrv6); err != nil { 1111 return err 1112 } 1113 } 1114 1115 if err = d.storeUpdate(endpoint); err != nil { 1116 return fmt.Errorf("failed to save bridge endpoint %.7s to store: %v", endpoint.id, err) 1117 } 1118 1119 return nil 1120 } 1121 1122 func (d *driver) DeleteEndpoint(nid, eid string) error { 1123 var err error 1124 1125 defer osl.InitOSContext()() 1126 1127 // Get the network handler and make sure it exists 1128 d.Lock() 1129 n, ok := d.networks[nid] 1130 d.Unlock() 1131 1132 if !ok { 1133 return types.InternalMaskableErrorf("network %s does not exist", nid) 1134 } 1135 if n == nil { 1136 return driverapi.ErrNoNetwork(nid) 1137 } 1138 1139 // Sanity Check 1140 n.Lock() 1141 if n.id != nid { 1142 n.Unlock() 1143 return InvalidNetworkIDError(nid) 1144 } 1145 n.Unlock() 1146 1147 // Check endpoint id and if an endpoint is actually there 1148 ep, err := n.getEndpoint(eid) 1149 if err != nil { 1150 return err 1151 } 1152 if ep == nil { 1153 return EndpointNotFoundError(eid) 1154 } 1155 1156 // Remove it 1157 n.Lock() 1158 delete(n.endpoints, eid) 1159 n.Unlock() 1160 1161 // On failure make sure to set back ep in n.endpoints, but only 1162 // if it hasn't been taken over already by some other thread. 1163 defer func() { 1164 if err != nil { 1165 n.Lock() 1166 if _, ok := n.endpoints[eid]; !ok { 1167 n.endpoints[eid] = ep 1168 } 1169 n.Unlock() 1170 } 1171 }() 1172 1173 // Try removal of link. Discard error: it is a best effort. 1174 // Also make sure defer does not see this error either. 1175 if link, err := d.nlh.LinkByName(ep.srcName); err == nil { 1176 if err := d.nlh.LinkDel(link); err != nil { 1177 logrus.WithError(err).Errorf("Failed to delete interface (%s)'s link on endpoint (%s) delete", ep.srcName, ep.id) 1178 } 1179 } 1180 1181 if err := d.storeDelete(ep); err != nil { 1182 logrus.Warnf("Failed to remove bridge endpoint %.7s from store: %v", ep.id, err) 1183 } 1184 1185 return nil 1186 } 1187 1188 func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) { 1189 // Get the network handler and make sure it exists 1190 d.Lock() 1191 n, ok := d.networks[nid] 1192 d.Unlock() 1193 if !ok { 1194 return nil, types.NotFoundErrorf("network %s does not exist", nid) 1195 } 1196 if n == nil { 1197 return nil, driverapi.ErrNoNetwork(nid) 1198 } 1199 1200 // Sanity check 1201 n.Lock() 1202 if n.id != nid { 1203 n.Unlock() 1204 return nil, InvalidNetworkIDError(nid) 1205 } 1206 n.Unlock() 1207 1208 // Check if endpoint id is good and retrieve correspondent endpoint 1209 ep, err := n.getEndpoint(eid) 1210 if err != nil { 1211 return nil, err 1212 } 1213 if ep == nil { 1214 return nil, driverapi.ErrNoEndpoint(eid) 1215 } 1216 1217 m := make(map[string]interface{}) 1218 1219 if ep.extConnConfig != nil && ep.extConnConfig.ExposedPorts != nil { 1220 // Return a copy of the config data 1221 epc := make([]types.TransportPort, 0, len(ep.extConnConfig.ExposedPorts)) 1222 for _, tp := range ep.extConnConfig.ExposedPorts { 1223 epc = append(epc, tp.GetCopy()) 1224 } 1225 m[netlabel.ExposedPorts] = epc 1226 } 1227 1228 if ep.portMapping != nil { 1229 // Return a copy of the operational data 1230 pmc := make([]types.PortBinding, 0, len(ep.portMapping)) 1231 for _, pm := range ep.portMapping { 1232 pmc = append(pmc, pm.GetCopy()) 1233 } 1234 m[netlabel.PortMap] = pmc 1235 } 1236 1237 if len(ep.macAddress) != 0 { 1238 m[netlabel.MacAddress] = ep.macAddress 1239 } 1240 1241 return m, nil 1242 } 1243 1244 // Join method is invoked when a Sandbox is attached to an endpoint. 1245 func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error { 1246 defer osl.InitOSContext()() 1247 1248 network, err := d.getNetwork(nid) 1249 if err != nil { 1250 return err 1251 } 1252 1253 endpoint, err := network.getEndpoint(eid) 1254 if err != nil { 1255 return err 1256 } 1257 1258 if endpoint == nil { 1259 return EndpointNotFoundError(eid) 1260 } 1261 1262 endpoint.containerConfig, err = parseContainerOptions(options) 1263 if err != nil { 1264 return err 1265 } 1266 1267 iNames := jinfo.InterfaceName() 1268 containerVethPrefix := defaultContainerVethPrefix 1269 if network.config.ContainerIfacePrefix != "" { 1270 containerVethPrefix = network.config.ContainerIfacePrefix 1271 } 1272 err = iNames.SetNames(endpoint.srcName, containerVethPrefix) 1273 if err != nil { 1274 return err 1275 } 1276 1277 err = jinfo.SetGateway(network.bridge.gatewayIPv4) 1278 if err != nil { 1279 return err 1280 } 1281 1282 err = jinfo.SetGatewayIPv6(network.bridge.gatewayIPv6) 1283 if err != nil { 1284 return err 1285 } 1286 1287 return nil 1288 } 1289 1290 // Leave method is invoked when a Sandbox detaches from an endpoint. 1291 func (d *driver) Leave(nid, eid string) error { 1292 defer osl.InitOSContext()() 1293 1294 network, err := d.getNetwork(nid) 1295 if err != nil { 1296 return types.InternalMaskableErrorf("%s", err) 1297 } 1298 1299 endpoint, err := network.getEndpoint(eid) 1300 if err != nil { 1301 return err 1302 } 1303 1304 if endpoint == nil { 1305 return EndpointNotFoundError(eid) 1306 } 1307 1308 if !network.config.EnableICC { 1309 if err = d.link(network, endpoint, false); err != nil { 1310 return err 1311 } 1312 } 1313 1314 return nil 1315 } 1316 1317 func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error { 1318 defer osl.InitOSContext()() 1319 1320 network, err := d.getNetwork(nid) 1321 if err != nil { 1322 return err 1323 } 1324 1325 endpoint, err := network.getEndpoint(eid) 1326 if err != nil { 1327 return err 1328 } 1329 1330 if endpoint == nil { 1331 return EndpointNotFoundError(eid) 1332 } 1333 1334 endpoint.extConnConfig, err = parseConnectivityOptions(options) 1335 if err != nil { 1336 return err 1337 } 1338 1339 // Program any required port mapping and store them in the endpoint 1340 endpoint.portMapping, err = network.allocatePorts(endpoint, network.config.DefaultBindingIP, d.config.EnableUserlandProxy) 1341 if err != nil { 1342 return err 1343 } 1344 1345 defer func() { 1346 if err != nil { 1347 if e := network.releasePorts(endpoint); e != nil { 1348 logrus.Errorf("Failed to release ports allocated for the bridge endpoint %s on failure %v because of %v", 1349 eid, err, e) 1350 } 1351 endpoint.portMapping = nil 1352 } 1353 }() 1354 1355 if err = d.storeUpdate(endpoint); err != nil { 1356 return fmt.Errorf("failed to update bridge endpoint %.7s to store: %v", endpoint.id, err) 1357 } 1358 1359 if !network.config.EnableICC { 1360 return d.link(network, endpoint, true) 1361 } 1362 1363 return nil 1364 } 1365 1366 func (d *driver) RevokeExternalConnectivity(nid, eid string) error { 1367 defer osl.InitOSContext()() 1368 1369 network, err := d.getNetwork(nid) 1370 if err != nil { 1371 return err 1372 } 1373 1374 endpoint, err := network.getEndpoint(eid) 1375 if err != nil { 1376 return err 1377 } 1378 1379 if endpoint == nil { 1380 return EndpointNotFoundError(eid) 1381 } 1382 1383 err = network.releasePorts(endpoint) 1384 if err != nil { 1385 logrus.Warn(err) 1386 } 1387 1388 endpoint.portMapping = nil 1389 1390 // Clean the connection tracker state of the host for the specific endpoint 1391 // The host kernel keeps track of the connections (TCP and UDP), so if a new endpoint gets the same IP of 1392 // this one (that is going down), is possible that some of the packets would not be routed correctly inside 1393 // the new endpoint 1394 // Deeper details: https://github.com/docker/docker/issues/8795 1395 clearEndpointConnections(d.nlh, endpoint) 1396 1397 if err = d.storeUpdate(endpoint); err != nil { 1398 return fmt.Errorf("failed to update bridge endpoint %.7s to store: %v", endpoint.id, err) 1399 } 1400 1401 return nil 1402 } 1403 1404 func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, enable bool) error { 1405 var err error 1406 1407 cc := endpoint.containerConfig 1408 if cc == nil { 1409 return nil 1410 } 1411 ec := endpoint.extConnConfig 1412 if ec == nil { 1413 return nil 1414 } 1415 1416 if ec.ExposedPorts != nil { 1417 for _, p := range cc.ParentEndpoints { 1418 var parentEndpoint *bridgeEndpoint 1419 parentEndpoint, err = network.getEndpoint(p) 1420 if err != nil { 1421 return err 1422 } 1423 if parentEndpoint == nil { 1424 err = InvalidEndpointIDError(p) 1425 return err 1426 } 1427 1428 l := newLink(parentEndpoint.addr.IP.String(), 1429 endpoint.addr.IP.String(), 1430 ec.ExposedPorts, network.config.BridgeName) 1431 if enable { 1432 err = l.Enable() 1433 if err != nil { 1434 return err 1435 } 1436 defer func() { 1437 if err != nil { 1438 l.Disable() 1439 } 1440 }() 1441 } else { 1442 l.Disable() 1443 } 1444 } 1445 } 1446 1447 for _, c := range cc.ChildEndpoints { 1448 var childEndpoint *bridgeEndpoint 1449 childEndpoint, err = network.getEndpoint(c) 1450 if err != nil { 1451 return err 1452 } 1453 if childEndpoint == nil { 1454 err = InvalidEndpointIDError(c) 1455 return err 1456 } 1457 if childEndpoint.extConnConfig == nil || childEndpoint.extConnConfig.ExposedPorts == nil { 1458 continue 1459 } 1460 1461 l := newLink(endpoint.addr.IP.String(), 1462 childEndpoint.addr.IP.String(), 1463 childEndpoint.extConnConfig.ExposedPorts, network.config.BridgeName) 1464 if enable { 1465 err = l.Enable() 1466 if err != nil { 1467 return err 1468 } 1469 defer func() { 1470 if err != nil { 1471 l.Disable() 1472 } 1473 }() 1474 } else { 1475 l.Disable() 1476 } 1477 } 1478 1479 return nil 1480 } 1481 1482 func (d *driver) Type() string { 1483 return networkType 1484 } 1485 1486 func (d *driver) IsBuiltIn() bool { 1487 return true 1488 } 1489 1490 // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster 1491 func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error { 1492 return nil 1493 } 1494 1495 // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster 1496 func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error { 1497 return nil 1498 } 1499 1500 func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfiguration, error) { 1501 if epOptions == nil { 1502 return nil, nil 1503 } 1504 1505 ec := &endpointConfiguration{} 1506 1507 if opt, ok := epOptions[netlabel.MacAddress]; ok { 1508 if mac, ok := opt.(net.HardwareAddr); ok { 1509 ec.MacAddress = mac 1510 } else { 1511 return nil, &ErrInvalidEndpointConfig{} 1512 } 1513 } 1514 1515 return ec, nil 1516 } 1517 1518 func parseContainerOptions(cOptions map[string]interface{}) (*containerConfiguration, error) { 1519 if cOptions == nil { 1520 return nil, nil 1521 } 1522 genericData := cOptions[netlabel.GenericData] 1523 if genericData == nil { 1524 return nil, nil 1525 } 1526 switch opt := genericData.(type) { 1527 case options.Generic: 1528 opaqueConfig, err := options.GenerateFromModel(opt, &containerConfiguration{}) 1529 if err != nil { 1530 return nil, err 1531 } 1532 return opaqueConfig.(*containerConfiguration), nil 1533 case *containerConfiguration: 1534 return opt, nil 1535 default: 1536 return nil, nil 1537 } 1538 } 1539 1540 func parseConnectivityOptions(cOptions map[string]interface{}) (*connectivityConfiguration, error) { 1541 if cOptions == nil { 1542 return nil, nil 1543 } 1544 1545 cc := &connectivityConfiguration{} 1546 1547 if opt, ok := cOptions[netlabel.PortMap]; ok { 1548 if pb, ok := opt.([]types.PortBinding); ok { 1549 cc.PortBindings = pb 1550 } else { 1551 return nil, types.BadRequestErrorf("Invalid port mapping data in connectivity configuration: %v", opt) 1552 } 1553 } 1554 1555 if opt, ok := cOptions[netlabel.ExposedPorts]; ok { 1556 if ports, ok := opt.([]types.TransportPort); ok { 1557 cc.ExposedPorts = ports 1558 } else { 1559 return nil, types.BadRequestErrorf("Invalid exposed ports data in connectivity configuration: %v", opt) 1560 } 1561 } 1562 1563 return cc, nil 1564 } 1565 1566 func electMacAddress(epConfig *endpointConfiguration, ip net.IP) net.HardwareAddr { 1567 if epConfig != nil && epConfig.MacAddress != nil { 1568 return epConfig.MacAddress 1569 } 1570 return netutils.GenerateMACFromIP(ip) 1571 }