github.com/rumpl/bof@v23.0.0-rc.2+incompatible/libnetwork/drivers/bridge/bridge.go (about)

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