github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/drivers/solaris/bridge/bridge.go (about)

     1  // +build solaris
     2  
     3  package bridge
     4  
     5  import (
     6  	"bufio"
     7  	"errors"
     8  	"fmt"
     9  	"net"
    10  	"os"
    11  	"os/exec"
    12  	"strconv"
    13  	"strings"
    14  	"sync"
    15  
    16  	"github.com/Sirupsen/logrus"
    17  	"github.com/docker/libnetwork/datastore"
    18  	"github.com/docker/libnetwork/discoverapi"
    19  	"github.com/docker/libnetwork/driverapi"
    20  	"github.com/docker/libnetwork/iptables"
    21  	"github.com/docker/libnetwork/netlabel"
    22  	"github.com/docker/libnetwork/netutils"
    23  	"github.com/docker/libnetwork/options"
    24  	"github.com/docker/libnetwork/portmapper"
    25  	"github.com/docker/libnetwork/types"
    26  )
    27  
    28  const (
    29  	networkType = "bridge"
    30  
    31  	// DefaultBridgeName is the default name for the bridge interface managed
    32  	// by the driver when unspecified by the caller.
    33  	DefaultBridgeName = "docker0"
    34  
    35  	// BridgeName label for bridge driver
    36  	BridgeName = "com.docker.network.bridge.name"
    37  
    38  	// EnableIPMasquerade label for bridge driver
    39  	EnableIPMasquerade = "com.docker.network.bridge.enable_ip_masquerade"
    40  
    41  	// EnableICC label
    42  	EnableICC = "com.docker.network.bridge.enable_icc"
    43  
    44  	// DefaultBindingIP label
    45  	DefaultBindingIP = "com.docker.network.bridge.host_binding_ipv4"
    46  
    47  	// DefaultBridge label
    48  	DefaultBridge = "com.docker.network.bridge.default_bridge"
    49  
    50  	// DefaultGatewayV4AuxKey represents the default-gateway configured by the user
    51  	DefaultGatewayV4AuxKey = "DefaultGatewayIPv4"
    52  
    53  	// DefaultGatewayV6AuxKey represents the ipv6 default-gateway configured by the user
    54  	DefaultGatewayV6AuxKey = "DefaultGatewayIPv6"
    55  )
    56  
    57  // configuration info for the "bridge" driver.
    58  type configuration struct {
    59  	EnableIPForwarding  bool
    60  	EnableIPTables      bool
    61  	EnableUserlandProxy bool
    62  }
    63  
    64  // networkConfiguration for network specific configuration
    65  type networkConfiguration struct {
    66  	ID                 string
    67  	BridgeName         string
    68  	BridgeNameInternal string
    69  	EnableIPv6         bool
    70  	EnableIPMasquerade bool
    71  	EnableICC          bool
    72  	Mtu                int
    73  	DefaultBindingIntf string
    74  	DefaultBindingIP   net.IP
    75  	DefaultBridge      bool
    76  	// Internal fields set after ipam data parsing
    77  	AddressIPv4        *net.IPNet
    78  	AddressIPv6        *net.IPNet
    79  	DefaultGatewayIPv4 net.IP
    80  	DefaultGatewayIPv6 net.IP
    81  	dbIndex            uint64
    82  	dbExists           bool
    83  	Internal           bool
    84  }
    85  
    86  // endpointConfiguration represents the user specified configuration for the sandbox endpoint
    87  type endpointConfiguration struct {
    88  	MacAddress   net.HardwareAddr
    89  	PortBindings []types.PortBinding
    90  	ExposedPorts []types.TransportPort
    91  }
    92  
    93  // containerConfiguration represents the user specified configuration for a container
    94  type containerConfiguration struct {
    95  	ParentEndpoints []string
    96  	ChildEndpoints  []string
    97  }
    98  
    99  // cnnectivityConfiguration represents the user specified configuration regarding the external connectivity
   100  type connectivityConfiguration struct {
   101  	PortBindings []types.PortBinding
   102  	ExposedPorts []types.TransportPort
   103  }
   104  
   105  type bridgeEndpoint struct {
   106  	id              string
   107  	nid             string
   108  	srcName         string
   109  	addr            *net.IPNet
   110  	addrv6          *net.IPNet
   111  	macAddress      net.HardwareAddr
   112  	config          *endpointConfiguration // User specified parameters
   113  	containerConfig *containerConfiguration
   114  	extConnConfig   *connectivityConfiguration
   115  	portMapping     []types.PortBinding // Operation port bindings
   116  	dbIndex         uint64
   117  	dbExists        bool
   118  }
   119  
   120  type bridgeInterface struct {
   121  	bridgeIPv4  *net.IPNet
   122  	bridgeIPv6  *net.IPNet
   123  	gatewayIPv4 net.IP
   124  	gatewayIPv6 net.IP
   125  }
   126  
   127  type bridgeNetwork struct {
   128  	id         string
   129  	bridge     *bridgeInterface
   130  	config     *networkConfiguration
   131  	endpoints  map[string]*bridgeEndpoint // key: endpoint id
   132  	portMapper *portmapper.PortMapper
   133  	driver     *driver // The network's driver
   134  	sync.Mutex
   135  }
   136  
   137  type driver struct {
   138  	config         *configuration
   139  	network        *bridgeNetwork
   140  	natChain       *iptables.ChainInfo
   141  	filterChain    *iptables.ChainInfo
   142  	isolationChain *iptables.ChainInfo
   143  	networks       map[string]*bridgeNetwork
   144  	store          datastore.DataStore
   145  	sync.Mutex
   146  	defrouteIP net.IP
   147  }
   148  
   149  // New constructs a new bridge driver
   150  func newDriver() *driver {
   151  	return &driver{networks: map[string]*bridgeNetwork{}}
   152  }
   153  
   154  // Init registers a new instance of bridge driver
   155  func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
   156  	d := newDriver()
   157  	if err := d.configure(config); err != nil {
   158  		return err
   159  	}
   160  
   161  	c := driverapi.Capability{
   162  		DataScope: datastore.LocalScope,
   163  	}
   164  	return dc.RegisterDriver(networkType, d, c)
   165  }
   166  
   167  func (d *driver) NetworkAllocate(id string, option map[string]string, ipV4Data, ipV6Data []driverapi.IPAMData) (map[string]string, error) {
   168  	return nil, types.NotImplementedErrorf("not implemented")
   169  }
   170  
   171  func (d *driver) NetworkFree(id string) error {
   172  	return types.NotImplementedErrorf("not implemented")
   173  }
   174  
   175  func (d *driver) EventNotify(etype driverapi.EventType, nid, tableName, key string, value []byte) {
   176  }
   177  
   178  func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo driverapi.NetworkInfo, ipV4Data, ipV6Data []driverapi.IPAMData) error {
   179  	if len(ipV4Data) == 0 || ipV4Data[0].Pool.String() == "0.0.0.0/0" {
   180  		return types.BadRequestErrorf("ipv4 pool is empty")
   181  	}
   182  	// Sanity checks
   183  	d.Lock()
   184  	if _, ok := d.networks[id]; ok {
   185  		d.Unlock()
   186  		return types.ForbiddenErrorf("network %s exists", id)
   187  	}
   188  	d.Unlock()
   189  
   190  	// Parse and validate the config. It should not conflict with existing networks' config
   191  	config, err := parseNetworkOptions(d, id, option)
   192  	if err != nil {
   193  		return err
   194  	}
   195  
   196  	err = config.processIPAM(id, ipV4Data, ipV6Data)
   197  	if err != nil {
   198  		return err
   199  	}
   200  
   201  	if err = d.createNetwork(config); err != nil {
   202  		return err
   203  	}
   204  
   205  	return d.storeUpdate(config)
   206  }
   207  
   208  func newInterface(config *networkConfiguration) *bridgeInterface {
   209  	i := &bridgeInterface{}
   210  
   211  	i.bridgeIPv4 = config.AddressIPv4
   212  	i.gatewayIPv4 = config.AddressIPv4.IP
   213  	if config.BridgeName == "" {
   214  		config.BridgeName = DefaultBridgeName
   215  	}
   216  	return i
   217  }
   218  
   219  // This function prunes the pf.conf for the firewall
   220  // that enable the service successfully.
   221  func fixPFConf() error {
   222  	conf := "/etc/firewall/pf.conf"
   223  	f, err := os.Open("/etc/firewall/pf.conf")
   224  	if err != nil {
   225  		return fmt.Errorf("cannot open %s: %v", conf, err)
   226  	}
   227  	defer f.Close()
   228  
   229  	// Look for line beginning with "REMOVE THIS LINE"
   230  	modify := false
   231  	lines := []string{}
   232  	scanner := bufio.NewScanner(f)
   233  	for scanner.Scan() {
   234  		l := scanner.Text()
   235  		if strings.Contains(l, "REMOVE THIS LINE") {
   236  			modify = true
   237  			continue
   238  		}
   239  		lines = append(lines, fmt.Sprintf("%s\n", l))
   240  	}
   241  	if err = scanner.Err(); err != nil {
   242  		return fmt.Errorf("cannot open %s: %v", conf, err)
   243  	}
   244  
   245  	// No changes needed to fix pf.conf
   246  	if !modify {
   247  		return nil
   248  	}
   249  
   250  	// Write back the file removing the line found above
   251  	tmpname := "/etc/firewall/pf.conf.tmp." + strconv.Itoa(os.Getpid())
   252  	tmp, err := os.OpenFile(tmpname,
   253  		os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_APPEND, 0644)
   254  	if err != nil {
   255  		return fmt.Errorf("cannot open %s: %v", tmpname, err)
   256  	}
   257  	defer tmp.Close()
   258  	for _, l := range lines {
   259  		_, err = tmp.WriteString(l)
   260  		if err != nil {
   261  			return fmt.Errorf("cannot write to %s: %v",
   262  				tmpname, err)
   263  		}
   264  	}
   265  	if err = tmp.Sync(); err != nil {
   266  		return fmt.Errorf("cannot sync %s: %v", tmpname, err)
   267  	}
   268  	if err = os.Rename(tmpname, conf); err != nil {
   269  		return fmt.Errorf("cannot rename %s to %s: %v",
   270  			tmpname, conf, err)
   271  	}
   272  	return nil
   273  }
   274  
   275  func (d *driver) initFirewall() error {
   276  	out, err := exec.Command("/usr/bin/svcs", "-Ho", "state",
   277  		"firewall").Output()
   278  	if err != nil {
   279  		return fmt.Errorf("cannot check firewall state: %v", err)
   280  	}
   281  	state := strings.TrimSpace(string(out))
   282  	if state != "online" {
   283  		if state != "disabled" {
   284  			return fmt.Errorf("firewall service is in %s state. "+
   285  				"please enable service manually.", state)
   286  		}
   287  		if err = fixPFConf(); err != nil {
   288  			return fmt.Errorf("cannot verify pf.conf: %v", err)
   289  		}
   290  		err = exec.Command("/usr/sbin/svcadm", "enable", "-ts",
   291  			"firewall").Run()
   292  		if err != nil {
   293  			return fmt.Errorf("cannot enable firewall service: %v", err)
   294  		}
   295  	}
   296  	out, err = exec.Command("/usr/sbin/pfctl", "-sr").Output()
   297  	if err != nil {
   298  		return fmt.Errorf("failed to list firewall rules: %v", err)
   299  	}
   300  	if strings.Contains(string(out), "anchor \"_auto/docker/*\" all") {
   301  		return nil
   302  	}
   303  	pfctlCmd := "(/usr/sbin/pfctl -sr; " +
   304  		"/usr/bin/echo \"anchor \\\"_auto/docker/*\\\"\") |" +
   305  		"/usr/sbin/pfctl -f -"
   306  	err = exec.Command("/usr/bin/bash", "-c", pfctlCmd).Run()
   307  	if err != nil {
   308  		return fmt.Errorf("failed to add docker firewall rules: %v", err)
   309  	}
   310  	return nil
   311  }
   312  
   313  func (d *driver) initRouting() error {
   314  	err := exec.Command("/usr/sbin/ipadm", "set-prop", "-t",
   315  		"-p", "forwarding=on", "ipv4").Run()
   316  	if err != nil {
   317  		return fmt.Errorf("cannot switch-on IP forwarding: %v", err)
   318  	}
   319  	routeCmd := "/usr/sbin/ipadm show-addr -p -o addr " +
   320  		"`/usr/sbin/route get default | /usr/bin/grep interface | " +
   321  		"/usr/bin/awk '{print $2}'`"
   322  	out, err := exec.Command("/usr/bin/bash", "-c", routeCmd).Output()
   323  	if err != nil {
   324  		return fmt.Errorf("cannot get default route: %v", err)
   325  	}
   326  	defroute := strings.SplitN(string(out), "/", 2)
   327  	d.defrouteIP = net.ParseIP(defroute[0])
   328  	if d.defrouteIP == nil {
   329  		return &ErrNoIPAddr{}
   330  	}
   331  	return nil
   332  }
   333  
   334  func (d *driver) configure(option map[string]interface{}) error {
   335  	var err error
   336  
   337  	if err = d.initFirewall(); err != nil {
   338  		return fmt.Errorf("failed to configure firewall: %v", err)
   339  	}
   340  	if err = d.initRouting(); err != nil {
   341  		return fmt.Errorf("failed to configure routing: %v", err)
   342  	}
   343  	if err = d.initStore(option); err != nil {
   344  		return fmt.Errorf("failed to initialize datastore: %v", err)
   345  	}
   346  
   347  	return nil
   348  }
   349  
   350  func (d *driver) getNetwork(id string) (*bridgeNetwork, error) {
   351  	d.Lock()
   352  	defer d.Unlock()
   353  
   354  	if id == "" {
   355  		return nil, types.BadRequestErrorf("invalid network id: %s", id)
   356  	}
   357  
   358  	if nw, ok := d.networks[id]; ok {
   359  		return nw, nil
   360  	}
   361  
   362  	return nil, types.NotFoundErrorf("network not found: %s", id)
   363  }
   364  
   365  // Return a slice of networks over which caller can iterate safely
   366  func (d *driver) getNetworks() []*bridgeNetwork {
   367  	d.Lock()
   368  	defer d.Unlock()
   369  
   370  	ls := make([]*bridgeNetwork, 0, len(d.networks))
   371  	for _, nw := range d.networks {
   372  		ls = append(ls, nw)
   373  	}
   374  	return ls
   375  }
   376  
   377  func bridgeSetup(config *networkConfiguration) error {
   378  	var err error
   379  	var bindingIntf string
   380  
   381  	bridgeName := config.BridgeName
   382  	gwName := fmt.Sprintf("%s_gw0", bridgeName)
   383  	gwIP := config.AddressIPv4.String()
   384  
   385  	if config.DefaultBindingIP == nil {
   386  		// Default to net0 if bindingIP is not provided.
   387  		bindingIntf = "net0"
   388  	} else {
   389  		ipadmCmd := "/usr/sbin/ipadm show-addr -p -o addrobj,addr |" +
   390  			"/usr/bin/grep " + config.DefaultBindingIP.String()
   391  		out, err := exec.Command("/usr/bin/bash", "-c", ipadmCmd).Output()
   392  		if err != nil {
   393  			logrus.Warnf("cannot find binding interface")
   394  			return err
   395  		}
   396  		bindingIntf = strings.SplitN(string(out), "/", 2)[0]
   397  		if bindingIntf == "" {
   398  			logrus.Warnf("cannot parse binding interface %s", string(out))
   399  			return &ErrNoIPAddr{}
   400  		}
   401  	}
   402  	config.DefaultBindingIntf = bindingIntf
   403  
   404  	err = exec.Command("/usr/sbin/dladm", "create-etherstub",
   405  		"-t", config.BridgeNameInternal).Run()
   406  	if err != nil {
   407  		logrus.Warnf("cannot create etherstub %s: %+v", config.BridgeNameInternal, err)
   408  		return err
   409  	}
   410  	err = exec.Command("/usr/sbin/dladm", "create-vnic",
   411  		"-t", "-l", config.BridgeNameInternal, gwName).Run()
   412  	if err != nil {
   413  		logrus.Warnf("cannot create vnic %s", gwName)
   414  		return err
   415  	}
   416  	err = exec.Command("/usr/sbin/ifconfig", gwName,
   417  		"plumb", gwIP, "up").Run()
   418  	if err != nil {
   419  		logrus.Warnf("cannot create gateway interface %s on %s",
   420  			gwIP, gwName)
   421  		return err
   422  	}
   423  
   424  	tableName := "bridge_nw_subnets"
   425  	pfAnchor := fmt.Sprintf("_auto/docker/%s", tableName)
   426  	err = exec.Command("/usr/sbin/pfctl", "-a", pfAnchor, "-t", tableName, "-T", "add", gwIP).Run()
   427  	if err != nil {
   428  		logrus.Warnf("cannot add bridge network '%s' to PF table", bridgeName)
   429  	}
   430  
   431  	pfCmd := fmt.Sprintf(
   432  		"/usr/bin/echo \"pass out on %s from %s:network to any nat-to (%s)\n"+
   433  			"block in quick from { <%s>, ! %s } to %s\" |"+
   434  			"/usr/sbin/pfctl -a _auto/docker/%s -f -",
   435  		bindingIntf, gwName, bindingIntf,
   436  		tableName, gwIP, gwIP,
   437  		bridgeName)
   438  	err = exec.Command("/usr/bin/bash", "-c", pfCmd).Run()
   439  	if err != nil {
   440  		logrus.Warnf("cannot add pf rule using: %s", pfCmd)
   441  		return err
   442  	}
   443  
   444  	return nil
   445  }
   446  
   447  func bridgeCleanup(config *networkConfiguration, logErr bool) {
   448  	var err error
   449  
   450  	bridgeName := config.BridgeName
   451  	tableName := "bridge_nw_subnets"
   452  	gwName := fmt.Sprintf("%s_gw0", bridgeName)
   453  	gwIP := config.AddressIPv4.String()
   454  	pfAnchor := fmt.Sprintf("_auto/docker/%s", bridgeName)
   455  	tableAnchor := fmt.Sprintf("_auto/docker/%s", tableName)
   456  
   457  	err = exec.Command("/usr/sbin/pfctl", "-a", pfAnchor, "-F", "all").Run()
   458  	if err != nil && logErr {
   459  		logrus.Warnf("cannot flush firewall rules")
   460  	}
   461  	err = exec.Command("/usr/sbin/ifconfig", gwName, "unplumb").Run()
   462  	if err != nil && logErr {
   463  		logrus.Warnf("cannot remove gateway interface")
   464  	}
   465  	err = exec.Command("/usr/sbin/dladm", "delete-vnic",
   466  		"-t", gwName).Run()
   467  	if err != nil && logErr {
   468  		logrus.Warnf("cannot delete vnic")
   469  	}
   470  	err = exec.Command("/usr/sbin/dladm", "delete-etherstub",
   471  		"-t", config.BridgeNameInternal).Run()
   472  	if err != nil && logErr {
   473  		logrus.Warnf("cannot delete etherstub")
   474  	}
   475  	err = exec.Command("/usr/sbin/pfctl", "-a", tableAnchor, "-t", tableName, "-T", "delete", gwIP).Run()
   476  	if err != nil && logErr {
   477  		logrus.Warnf("cannot remove bridge network '%s' from PF table", bridgeName)
   478  	}
   479  }
   480  
   481  func (d *driver) createNetwork(config *networkConfiguration) error {
   482  	var err error
   483  
   484  	logrus.Infof("Creating bridge network: %s %s %s", config.ID,
   485  		config.BridgeName, config.AddressIPv4)
   486  
   487  	networkList := d.getNetworks()
   488  	for i, nw := range networkList {
   489  		nw.Lock()
   490  		nwConfig := nw.config
   491  		nw.Unlock()
   492  		if err := nwConfig.Conflicts(config); err != nil {
   493  			if config.DefaultBridge {
   494  				// We encountered and identified a stale default network
   495  				// We must delete it as libnetwork is the source of thruth
   496  				// The default network being created must be the only one
   497  				// This can happen only from docker 1.12 on ward
   498  				logrus.Infof("Removing stale default bridge network %s (%s)", nwConfig.ID, nwConfig.BridgeName)
   499  				if err := d.DeleteNetwork(nwConfig.ID); err != nil {
   500  					logrus.Warnf("Failed to remove stale default network: %s (%s): %v. Will remove from store.", nwConfig.ID, nwConfig.BridgeName, err)
   501  					d.storeDelete(nwConfig)
   502  				}
   503  				networkList = append(networkList[:i], networkList[i+1:]...)
   504  			} else {
   505  				return types.ForbiddenErrorf(
   506  					"cannot create network %s (%s): "+
   507  						"conflicts with network %s (%s): %s",
   508  					nwConfig.BridgeName, config.ID, nw.id,
   509  					nw.config.BridgeName, err.Error())
   510  			}
   511  		}
   512  	}
   513  	if config.DefaultBindingIP == nil ||
   514  		config.DefaultBindingIP.IsUnspecified() {
   515  		config.DefaultBindingIP = d.defrouteIP
   516  	}
   517  
   518  	// Create and set network handler in driver
   519  	network := &bridgeNetwork{
   520  		id:         config.ID,
   521  		endpoints:  make(map[string]*bridgeEndpoint),
   522  		config:     config,
   523  		portMapper: portmapper.New(""),
   524  		driver:     d,
   525  	}
   526  
   527  	d.Lock()
   528  	d.networks[config.ID] = network
   529  	d.Unlock()
   530  
   531  	// On failure make sure to reset driver network handler to nil
   532  	defer func() {
   533  		if err != nil {
   534  			d.Lock()
   535  			delete(d.networks, config.ID)
   536  			d.Unlock()
   537  		}
   538  	}()
   539  
   540  	// Create or retrieve the bridge L3 interface
   541  	bridgeIface := newInterface(config)
   542  	network.bridge = bridgeIface
   543  
   544  	// Verify the network configuration does not conflict with previously installed
   545  	// networks. This step is needed now because driver might have now set the bridge
   546  	// name on this config struct. And because we need to check for possible address
   547  	// conflicts, so we need to check against operational networks.
   548  	if err = config.conflictsWithNetworks(config.ID, networkList); err != nil {
   549  		return err
   550  	}
   551  
   552  	// We only attempt to create the bridge when the requested device name is
   553  	// the default one.
   554  	if config.BridgeName != DefaultBridgeName && config.DefaultBridge {
   555  		return NonDefaultBridgeExistError(config.BridgeName)
   556  	}
   557  
   558  	bridgeCleanup(config, false)
   559  	err = bridgeSetup(config)
   560  	if err != nil {
   561  		return err
   562  	}
   563  	return nil
   564  }
   565  
   566  func (d *driver) DeleteNetwork(nid string) error {
   567  	var err error
   568  	// Get network handler and remove it from driver
   569  	d.Lock()
   570  	n, ok := d.networks[nid]
   571  	d.Unlock()
   572  
   573  	if !ok {
   574  		return types.InternalMaskableErrorf("network %s does not exist", nid)
   575  	}
   576  	d.Lock()
   577  	delete(d.networks, nid)
   578  	d.Unlock()
   579  
   580  	// On failure set network handler back in driver, but
   581  	// only if is not already taken over by some other thread
   582  	defer func() {
   583  		if err != nil {
   584  			d.Lock()
   585  			if _, ok := d.networks[nid]; !ok {
   586  				d.networks[nid] = n
   587  			}
   588  			d.Unlock()
   589  		}
   590  	}()
   591  
   592  	// Sanity check
   593  	if n == nil {
   594  		err = driverapi.ErrNoNetwork(nid)
   595  		return err
   596  	}
   597  
   598  	// Cannot remove network if endpoints are still present
   599  	if len(n.endpoints) != 0 {
   600  		err = ActiveEndpointsError(n.id)
   601  		return err
   602  	}
   603  	bridgeCleanup(n.config, true)
   604  	logrus.Infof("Deleting bridge network: %s", nid[:12])
   605  	return d.storeDelete(n.config)
   606  }
   607  
   608  func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
   609  	if ifInfo == nil {
   610  		return errors.New("invalid interface passed")
   611  	}
   612  
   613  	// Get the network handler and make sure it exists
   614  	d.Lock()
   615  	n, ok := d.networks[nid]
   616  	d.Unlock()
   617  
   618  	if !ok {
   619  		return types.NotFoundErrorf("network %s does not exist", nid)
   620  	}
   621  	if n == nil {
   622  		return driverapi.ErrNoNetwork(nid)
   623  	}
   624  
   625  	// Sanity check
   626  	n.Lock()
   627  	if n.id != nid {
   628  		n.Unlock()
   629  		return InvalidNetworkIDError(nid)
   630  	}
   631  	n.Unlock()
   632  
   633  	// Check if endpoint id is good and retrieve correspondent endpoint
   634  	ep, err := n.getEndpoint(eid)
   635  	if err != nil {
   636  		return err
   637  	}
   638  
   639  	// Endpoint with that id exists either on desired or other sandbox
   640  	if ep != nil {
   641  		return driverapi.ErrEndpointExists(eid)
   642  	}
   643  
   644  	// Try to convert the options to endpoint configuration
   645  	epConfig, err := parseEndpointOptions(epOptions)
   646  	if err != nil {
   647  		return err
   648  	}
   649  
   650  	// Create and add the endpoint
   651  	n.Lock()
   652  	endpoint := &bridgeEndpoint{id: eid, config: epConfig}
   653  	n.endpoints[eid] = endpoint
   654  	n.Unlock()
   655  
   656  	// On failure make sure to remove the endpoint
   657  	defer func() {
   658  		if err != nil {
   659  			n.Lock()
   660  			delete(n.endpoints, eid)
   661  			n.Unlock()
   662  		}
   663  	}()
   664  
   665  	// Create the sandbox side pipe interface
   666  	if ifInfo.MacAddress() == nil {
   667  		// No MAC address assigned to interface. Generate a random MAC to assign
   668  		endpoint.macAddress = netutils.GenerateRandomMAC()
   669  		if err := ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
   670  			logrus.Warnf("Unable to set mac address: %s to endpoint: %s",
   671  				endpoint.macAddress.String(), endpoint.id)
   672  			return err
   673  		}
   674  	} else {
   675  		endpoint.macAddress = ifInfo.MacAddress()
   676  	}
   677  	endpoint.addr = ifInfo.Address()
   678  	endpoint.addrv6 = ifInfo.AddressIPv6()
   679  	c := n.config
   680  
   681  	// Program any required port mapping and store them in the endpoint
   682  	endpoint.portMapping, err = n.allocatePorts(endpoint, c.DefaultBindingIntf, c.DefaultBindingIP, true)
   683  	if err != nil {
   684  		return err
   685  	}
   686  
   687  	return nil
   688  }
   689  
   690  func (d *driver) DeleteEndpoint(nid, eid string) error {
   691  	var err error
   692  
   693  	// Get the network handler and make sure it exists
   694  	d.Lock()
   695  	n, ok := d.networks[nid]
   696  	d.Unlock()
   697  
   698  	if !ok {
   699  		return types.InternalMaskableErrorf("network %s does not exist", nid)
   700  	}
   701  	if n == nil {
   702  		return driverapi.ErrNoNetwork(nid)
   703  	}
   704  
   705  	// Sanity Check
   706  	n.Lock()
   707  	if n.id != nid {
   708  		n.Unlock()
   709  		return InvalidNetworkIDError(nid)
   710  	}
   711  	n.Unlock()
   712  
   713  	// Check endpoint id and if an endpoint is actually there
   714  	ep, err := n.getEndpoint(eid)
   715  	if err != nil {
   716  		return err
   717  	}
   718  	if ep == nil {
   719  		return EndpointNotFoundError(eid)
   720  	}
   721  
   722  	// Remove it
   723  	n.Lock()
   724  	delete(n.endpoints, eid)
   725  	n.Unlock()
   726  
   727  	// On failure make sure to set back ep in n.endpoints, but only
   728  	// if it hasn't been taken over already by some other thread.
   729  	defer func() {
   730  		if err != nil {
   731  			n.Lock()
   732  			if _, ok := n.endpoints[eid]; !ok {
   733  				n.endpoints[eid] = ep
   734  			}
   735  			n.Unlock()
   736  		}
   737  	}()
   738  
   739  	err = n.releasePorts(ep)
   740  	if err != nil {
   741  		logrus.Warn(err)
   742  	}
   743  
   744  	return nil
   745  }
   746  
   747  func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, error) {
   748  	// Get the network handler and make sure it exists
   749  	d.Lock()
   750  	n, ok := d.networks[nid]
   751  	d.Unlock()
   752  	if !ok {
   753  		return nil, types.NotFoundErrorf("network %s does not exist", nid)
   754  	}
   755  	if n == nil {
   756  		return nil, driverapi.ErrNoNetwork(nid)
   757  	}
   758  
   759  	// Sanity check
   760  	n.Lock()
   761  	if n.id != nid {
   762  		n.Unlock()
   763  		return nil, InvalidNetworkIDError(nid)
   764  	}
   765  	n.Unlock()
   766  
   767  	// Check if endpoint id is good and retrieve correspondent endpoint
   768  	ep, err := n.getEndpoint(eid)
   769  	if err != nil {
   770  		return nil, err
   771  	}
   772  	if ep == nil {
   773  		return nil, driverapi.ErrNoEndpoint(eid)
   774  	}
   775  
   776  	m := make(map[string]interface{})
   777  
   778  	if ep.extConnConfig != nil && ep.extConnConfig.ExposedPorts != nil {
   779  		// Return a copy of the config data
   780  		epc := make([]types.TransportPort, 0, len(ep.extConnConfig.ExposedPorts))
   781  		for _, tp := range ep.extConnConfig.ExposedPorts {
   782  			epc = append(epc, tp.GetCopy())
   783  		}
   784  		m[netlabel.ExposedPorts] = epc
   785  	}
   786  
   787  	if ep.portMapping != nil {
   788  		// Return a copy of the operational data
   789  		pmc := make([]types.PortBinding, 0, len(ep.portMapping))
   790  		for _, pm := range ep.portMapping {
   791  			pmc = append(pmc, pm.GetCopy())
   792  		}
   793  		m[netlabel.PortMap] = pmc
   794  	}
   795  
   796  	if len(ep.macAddress) != 0 {
   797  		m[netlabel.MacAddress] = ep.macAddress
   798  	}
   799  	return m, nil
   800  }
   801  
   802  // Join method is invoked when a Sandbox is attached to an endpoint.
   803  func (d *driver) Join(nid, eid string, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
   804  	network, err := d.getNetwork(nid)
   805  	if err != nil {
   806  		return err
   807  	}
   808  
   809  	endpoint, err := network.getEndpoint(eid)
   810  	if err != nil {
   811  		return err
   812  	}
   813  
   814  	if endpoint == nil {
   815  		return EndpointNotFoundError(eid)
   816  	}
   817  
   818  	endpoint.containerConfig, err = parseContainerOptions(options)
   819  	if err != nil {
   820  		return err
   821  	}
   822  
   823  	err = jinfo.SetGateway(network.bridge.gatewayIPv4)
   824  	if err != nil {
   825  		return err
   826  	}
   827  
   828  	err = jinfo.SetGatewayIPv6(network.bridge.gatewayIPv6)
   829  	if err != nil {
   830  		return err
   831  	}
   832  
   833  	return nil
   834  }
   835  
   836  func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, enable bool) error {
   837  	return nil
   838  }
   839  
   840  // Leave method is invoked when a Sandbox detaches from an endpoint.
   841  func (d *driver) Leave(nid, eid string) error {
   842  	network, err := d.getNetwork(nid)
   843  	if err != nil {
   844  		return types.InternalMaskableErrorf("%s", err)
   845  	}
   846  
   847  	endpoint, err := network.getEndpoint(eid)
   848  	if err != nil {
   849  		return err
   850  	}
   851  
   852  	if endpoint == nil {
   853  		return EndpointNotFoundError(eid)
   854  	}
   855  
   856  	return nil
   857  }
   858  
   859  func (d *driver) ProgramExternalConnectivity(nid, eid string, options map[string]interface{}) error {
   860  	network, err := d.getNetwork(nid)
   861  	if err != nil {
   862  		return err
   863  	}
   864  
   865  	endpoint, err := network.getEndpoint(eid)
   866  	if err != nil {
   867  		return err
   868  	}
   869  
   870  	if endpoint == nil {
   871  		return EndpointNotFoundError(eid)
   872  	}
   873  
   874  	endpoint.extConnConfig, err = parseConnectivityOptions(options)
   875  	if err != nil {
   876  		return err
   877  	}
   878  
   879  	// Program any required port mapping and store them in the endpoint
   880  	endpoint.portMapping, err = network.allocatePorts(endpoint, network.config.DefaultBindingIntf, network.config.DefaultBindingIP, true)
   881  	if err != nil {
   882  		return err
   883  	}
   884  
   885  	if !network.config.EnableICC {
   886  		return d.link(network, endpoint, true)
   887  	}
   888  
   889  	return nil
   890  }
   891  
   892  func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
   893  	network, err := d.getNetwork(nid)
   894  	if err != nil {
   895  		return err
   896  	}
   897  
   898  	endpoint, err := network.getEndpoint(eid)
   899  	if err != nil {
   900  		return err
   901  	}
   902  
   903  	if endpoint == nil {
   904  		return EndpointNotFoundError(eid)
   905  	}
   906  
   907  	err = network.releasePorts(endpoint)
   908  	if err != nil {
   909  		logrus.Warn(err)
   910  	}
   911  
   912  	return nil
   913  }
   914  
   915  func (d *driver) Type() string {
   916  	return networkType
   917  }
   918  
   919  // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
   920  func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
   921  	return nil
   922  }
   923  
   924  // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
   925  func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
   926  	return nil
   927  }
   928  
   929  // Validate performs a static validation on the network configuration parameters.
   930  // Whatever can be assessed a priori before attempting any programming.
   931  func (c *networkConfiguration) Validate() error {
   932  	if c.Mtu < 0 {
   933  		return ErrInvalidMtu(c.Mtu)
   934  	}
   935  
   936  	// If bridge v4 subnet is specified
   937  	if c.AddressIPv4 != nil {
   938  		// If default gw is specified, it must be part of bridge subnet
   939  		if c.DefaultGatewayIPv4 != nil {
   940  			if !c.AddressIPv4.Contains(c.DefaultGatewayIPv4) {
   941  				return &ErrInvalidGateway{}
   942  			}
   943  		}
   944  	}
   945  
   946  	// If default v6 gw is specified, AddressIPv6 must be specified and gw must belong to AddressIPv6 subnet
   947  	if c.EnableIPv6 && c.DefaultGatewayIPv6 != nil {
   948  		if c.AddressIPv6 == nil || !c.AddressIPv6.Contains(c.DefaultGatewayIPv6) {
   949  			return &ErrInvalidGateway{}
   950  		}
   951  	}
   952  	return nil
   953  }
   954  
   955  // Checks whether this network's configuration for the network with this id conflicts with any of the passed networks
   956  func (c *networkConfiguration) conflictsWithNetworks(id string, others []*bridgeNetwork) error {
   957  	for _, nw := range others {
   958  
   959  		nw.Lock()
   960  		nwID := nw.id
   961  		nwConfig := nw.config
   962  		nwBridge := nw.bridge
   963  		nw.Unlock()
   964  
   965  		if nwID == id {
   966  			continue
   967  		}
   968  		// Verify the name (which may have been set by newInterface()) does not conflict with
   969  		// existing bridge interfaces. Ironically the system chosen name gets stored in the config...
   970  		// Basically we are checking if the two original configs were both empty.
   971  		if nwConfig.BridgeName == c.BridgeName {
   972  			return types.ForbiddenErrorf("conflicts with network %s (%s) by bridge name", nwID, nwConfig.BridgeName)
   973  		}
   974  		// If this network config specifies the AddressIPv4, we need
   975  		// to make sure it does not conflict with any previously allocated
   976  		// bridges. This could not be completely caught by the config conflict
   977  		// check, because networks which config does not specify the AddressIPv4
   978  		// get their address and subnet selected by the driver (see electBridgeIPv4())
   979  		if c.AddressIPv4 != nil {
   980  			if nwBridge.bridgeIPv4.Contains(c.AddressIPv4.IP) ||
   981  				c.AddressIPv4.Contains(nwBridge.bridgeIPv4.IP) {
   982  				return types.ForbiddenErrorf("conflicts with network %s (%s) by ip network", nwID, nwConfig.BridgeName)
   983  			}
   984  		}
   985  	}
   986  
   987  	return nil
   988  }
   989  
   990  // Conflicts check if two NetworkConfiguration objects overlap
   991  func (c *networkConfiguration) Conflicts(o *networkConfiguration) error {
   992  	if o == nil {
   993  		return fmt.Errorf("same configuration")
   994  	}
   995  
   996  	// Also empty, becasue only one network with empty name is allowed
   997  	if c.BridgeName == o.BridgeName {
   998  		return fmt.Errorf("networks have same bridge name")
   999  	}
  1000  
  1001  	// They must be in different subnets
  1002  	if (c.AddressIPv4 != nil && o.AddressIPv4 != nil) &&
  1003  		(c.AddressIPv4.Contains(o.AddressIPv4.IP) || o.AddressIPv4.Contains(c.AddressIPv4.IP)) {
  1004  		return fmt.Errorf("networks have overlapping IPv4")
  1005  	}
  1006  
  1007  	// They must be in different v6 subnets
  1008  	if (c.AddressIPv6 != nil && o.AddressIPv6 != nil) &&
  1009  		(c.AddressIPv6.Contains(o.AddressIPv6.IP) || o.AddressIPv6.Contains(c.AddressIPv6.IP)) {
  1010  		return fmt.Errorf("networks have overlapping IPv6")
  1011  	}
  1012  
  1013  	return nil
  1014  }
  1015  
  1016  func (c *networkConfiguration) fromLabels(labels map[string]string) error {
  1017  	var err error
  1018  	for label, value := range labels {
  1019  		switch label {
  1020  		case BridgeName:
  1021  			c.BridgeName = value
  1022  		case netlabel.DriverMTU:
  1023  			if c.Mtu, err = strconv.Atoi(value); err != nil {
  1024  				return parseErr(label, value, err.Error())
  1025  			}
  1026  		case netlabel.EnableIPv6:
  1027  			if c.EnableIPv6, err = strconv.ParseBool(value); err != nil {
  1028  				return parseErr(label, value, err.Error())
  1029  			}
  1030  		case EnableIPMasquerade:
  1031  			if c.EnableIPMasquerade, err = strconv.ParseBool(value); err != nil {
  1032  				return parseErr(label, value, err.Error())
  1033  			}
  1034  		case EnableICC:
  1035  			if c.EnableICC, err = strconv.ParseBool(value); err != nil {
  1036  				return parseErr(label, value, err.Error())
  1037  			}
  1038  		case DefaultBridge:
  1039  			if c.DefaultBridge, err = strconv.ParseBool(value); err != nil {
  1040  				return parseErr(label, value, err.Error())
  1041  			}
  1042  		case DefaultBindingIP:
  1043  			if c.DefaultBindingIP = net.ParseIP(value); c.DefaultBindingIP == nil {
  1044  				return parseErr(label, value, "nil ip")
  1045  			}
  1046  		}
  1047  	}
  1048  
  1049  	return nil
  1050  }
  1051  
  1052  func parseErr(label, value, errString string) error {
  1053  	return types.BadRequestErrorf("failed to parse %s value: %v (%s)", label, value, errString)
  1054  }
  1055  
  1056  func parseNetworkGenericOptions(data interface{}) (*networkConfiguration, error) {
  1057  	var (
  1058  		err    error
  1059  		config *networkConfiguration
  1060  	)
  1061  
  1062  	switch opt := data.(type) {
  1063  	case *networkConfiguration:
  1064  		config = opt
  1065  	case map[string]string:
  1066  		config = &networkConfiguration{
  1067  			EnableICC:          true,
  1068  			EnableIPMasquerade: true,
  1069  		}
  1070  		err = config.fromLabels(opt)
  1071  	case options.Generic:
  1072  		var opaqueConfig interface{}
  1073  		if opaqueConfig, err = options.GenerateFromModel(opt, config); err == nil {
  1074  			config = opaqueConfig.(*networkConfiguration)
  1075  		}
  1076  	default:
  1077  		err = types.BadRequestErrorf("do not recognize network configuration format: %T", opt)
  1078  	}
  1079  
  1080  	return config, err
  1081  }
  1082  
  1083  func parseNetworkOptions(d *driver, id string, option options.Generic) (*networkConfiguration, error) {
  1084  	var (
  1085  		err    error
  1086  		config = &networkConfiguration{}
  1087  	)
  1088  
  1089  	// Parse generic label first, config will be re-assigned
  1090  	if genData, ok := option[netlabel.GenericData]; ok && genData != nil {
  1091  		if config, err = parseNetworkGenericOptions(genData); err != nil {
  1092  			return nil, err
  1093  		}
  1094  	}
  1095  
  1096  	// Process well-known labels next
  1097  	if val, ok := option[netlabel.EnableIPv6]; ok {
  1098  		config.EnableIPv6 = val.(bool)
  1099  	}
  1100  
  1101  	if val, ok := option[netlabel.Internal]; ok {
  1102  		if internal, ok := val.(bool); ok && internal {
  1103  			config.Internal = true
  1104  		}
  1105  	}
  1106  
  1107  	// Finally validate the configuration
  1108  	if err = config.Validate(); err != nil {
  1109  		return nil, err
  1110  	}
  1111  
  1112  	if config.BridgeName == "" && config.DefaultBridge == false {
  1113  		config.BridgeName = "br_" + id[:12] + "_0"
  1114  	}
  1115  
  1116  	lastChar := config.BridgeName[len(config.BridgeName)-1:]
  1117  	if _, err = strconv.Atoi(lastChar); err != nil {
  1118  		config.BridgeNameInternal = config.BridgeName + "_0"
  1119  	} else {
  1120  		config.BridgeNameInternal = config.BridgeName
  1121  	}
  1122  
  1123  	config.ID = id
  1124  	return config, nil
  1125  }
  1126  
  1127  func (c *networkConfiguration) processIPAM(id string, ipamV4Data, ipamV6Data []driverapi.IPAMData) error {
  1128  	if len(ipamV4Data) > 1 || len(ipamV6Data) > 1 {
  1129  		return types.ForbiddenErrorf("bridge driver doesnt support multiple subnets")
  1130  	}
  1131  
  1132  	if len(ipamV4Data) == 0 {
  1133  		return types.BadRequestErrorf("bridge network %s requires ipv4 configuration", id)
  1134  	}
  1135  
  1136  	if ipamV4Data[0].Gateway != nil {
  1137  		c.AddressIPv4 = types.GetIPNetCopy(ipamV4Data[0].Gateway)
  1138  	}
  1139  
  1140  	if gw, ok := ipamV4Data[0].AuxAddresses[DefaultGatewayV4AuxKey]; ok {
  1141  		c.DefaultGatewayIPv4 = gw.IP
  1142  	}
  1143  
  1144  	if len(ipamV6Data) > 0 {
  1145  		c.AddressIPv6 = ipamV6Data[0].Pool
  1146  
  1147  		if ipamV6Data[0].Gateway != nil {
  1148  			c.AddressIPv6 = types.GetIPNetCopy(ipamV6Data[0].Gateway)
  1149  		}
  1150  
  1151  		if gw, ok := ipamV6Data[0].AuxAddresses[DefaultGatewayV6AuxKey]; ok {
  1152  			c.DefaultGatewayIPv6 = gw.IP
  1153  		}
  1154  	}
  1155  
  1156  	return nil
  1157  }
  1158  
  1159  func (n *bridgeNetwork) getEndpoint(eid string) (*bridgeEndpoint, error) {
  1160  	n.Lock()
  1161  	defer n.Unlock()
  1162  
  1163  	if eid == "" {
  1164  		return nil, InvalidEndpointIDError(eid)
  1165  	}
  1166  
  1167  	if ep, ok := n.endpoints[eid]; ok {
  1168  		return ep, nil
  1169  	}
  1170  
  1171  	return nil, nil
  1172  }
  1173  
  1174  func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfiguration, error) {
  1175  	if epOptions == nil {
  1176  		return nil, nil
  1177  	}
  1178  
  1179  	ec := &endpointConfiguration{}
  1180  
  1181  	if opt, ok := epOptions[netlabel.MacAddress]; ok {
  1182  		if mac, ok := opt.(net.HardwareAddr); ok {
  1183  			ec.MacAddress = mac
  1184  		} else {
  1185  			return nil, &ErrInvalidEndpointConfig{}
  1186  		}
  1187  	}
  1188  
  1189  	if opt, ok := epOptions[netlabel.PortMap]; ok {
  1190  		if bs, ok := opt.([]types.PortBinding); ok {
  1191  			ec.PortBindings = bs
  1192  		} else {
  1193  			return nil, &ErrInvalidEndpointConfig{}
  1194  		}
  1195  	}
  1196  
  1197  	if opt, ok := epOptions[netlabel.ExposedPorts]; ok {
  1198  		if ports, ok := opt.([]types.TransportPort); ok {
  1199  			ec.ExposedPorts = ports
  1200  		} else {
  1201  			return nil, &ErrInvalidEndpointConfig{}
  1202  		}
  1203  	}
  1204  
  1205  	return ec, nil
  1206  }
  1207  
  1208  func parseContainerOptions(cOptions map[string]interface{}) (*containerConfiguration, error) {
  1209  	if cOptions == nil {
  1210  		return nil, nil
  1211  	}
  1212  	genericData := cOptions[netlabel.GenericData]
  1213  	if genericData == nil {
  1214  		return nil, nil
  1215  	}
  1216  	switch opt := genericData.(type) {
  1217  	case options.Generic:
  1218  		opaqueConfig, err := options.GenerateFromModel(opt, &containerConfiguration{})
  1219  		if err != nil {
  1220  			return nil, err
  1221  		}
  1222  		return opaqueConfig.(*containerConfiguration), nil
  1223  	case *containerConfiguration:
  1224  		return opt, nil
  1225  	default:
  1226  		return nil, nil
  1227  	}
  1228  }
  1229  
  1230  func parseConnectivityOptions(cOptions map[string]interface{}) (*connectivityConfiguration, error) {
  1231  	if cOptions == nil {
  1232  		return nil, nil
  1233  	}
  1234  
  1235  	cc := &connectivityConfiguration{}
  1236  
  1237  	if opt, ok := cOptions[netlabel.PortMap]; ok {
  1238  		if pb, ok := opt.([]types.PortBinding); ok {
  1239  			cc.PortBindings = pb
  1240  		} else {
  1241  			return nil, types.BadRequestErrorf("Invalid port mapping data in connectivity configuration: %v", opt)
  1242  		}
  1243  	}
  1244  
  1245  	if opt, ok := cOptions[netlabel.ExposedPorts]; ok {
  1246  		if ports, ok := opt.([]types.TransportPort); ok {
  1247  			cc.ExposedPorts = ports
  1248  		} else {
  1249  			return nil, types.BadRequestErrorf("Invalid exposed ports data in connectivity configuration: %v", opt)
  1250  		}
  1251  	}
  1252  
  1253  	return cc, nil
  1254  }