github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/bridge/bridge_linux.go (about)

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