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