github.com/moby/docker@v26.1.3+incompatible/libnetwork/drivers/bridge/bridge_linux.go (about)

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