github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/drivers/bridge/bridge.go (about)

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