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

     1  package overlay
     2  
     3  //go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
     4  
     5  import (
     6  	"fmt"
     7  	"net"
     8  	"sync"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/docker/libnetwork/datastore"
    12  	"github.com/docker/libnetwork/discoverapi"
    13  	"github.com/docker/libnetwork/driverapi"
    14  	"github.com/docker/libnetwork/idm"
    15  	"github.com/docker/libnetwork/netlabel"
    16  	"github.com/docker/libnetwork/osl"
    17  	"github.com/docker/libnetwork/types"
    18  	"github.com/hashicorp/serf/serf"
    19  )
    20  
    21  const (
    22  	networkType  = "overlay"
    23  	vethPrefix   = "veth"
    24  	vethLen      = 7
    25  	vxlanIDStart = 256
    26  	vxlanIDEnd   = (1 << 24) - 1
    27  	vxlanPort    = 4789
    28  	vxlanEncap   = 50
    29  	secureOption = "encrypted"
    30  )
    31  
    32  var initVxlanIdm = make(chan (bool), 1)
    33  
    34  type driver struct {
    35  	eventCh          chan serf.Event
    36  	notifyCh         chan ovNotify
    37  	exitCh           chan chan struct{}
    38  	bindAddress      string
    39  	advertiseAddress string
    40  	neighIP          string
    41  	config           map[string]interface{}
    42  	peerDb           peerNetworkMap
    43  	secMap           *encrMap
    44  	serfInstance     *serf.Serf
    45  	networks         networkTable
    46  	store            datastore.DataStore
    47  	localStore       datastore.DataStore
    48  	vxlanIdm         *idm.Idm
    49  	once             sync.Once
    50  	joinOnce         sync.Once
    51  	keys             []*key
    52  	sync.Mutex
    53  }
    54  
    55  // Init registers a new instance of overlay driver
    56  func Init(dc driverapi.DriverCallback, config map[string]interface{}) error {
    57  	c := driverapi.Capability{
    58  		DataScope: datastore.GlobalScope,
    59  	}
    60  	d := &driver{
    61  		networks: networkTable{},
    62  		peerDb: peerNetworkMap{
    63  			mp: map[string]*peerMap{},
    64  		},
    65  		secMap: &encrMap{nodes: map[string][]*spi{}},
    66  		config: config,
    67  	}
    68  
    69  	if data, ok := config[netlabel.GlobalKVClient]; ok {
    70  		var err error
    71  		dsc, ok := data.(discoverapi.DatastoreConfigData)
    72  		if !ok {
    73  			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
    74  		}
    75  		d.store, err = datastore.NewDataStoreFromConfig(dsc)
    76  		if err != nil {
    77  			return types.InternalErrorf("failed to initialize data store: %v", err)
    78  		}
    79  	}
    80  
    81  	if data, ok := config[netlabel.LocalKVClient]; ok {
    82  		var err error
    83  		dsc, ok := data.(discoverapi.DatastoreConfigData)
    84  		if !ok {
    85  			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
    86  		}
    87  		d.localStore, err = datastore.NewDataStoreFromConfig(dsc)
    88  		if err != nil {
    89  			return types.InternalErrorf("failed to initialize local data store: %v", err)
    90  		}
    91  	}
    92  
    93  	if err := d.restoreEndpoints(); err != nil {
    94  		logrus.Warnf("Failure during overlay endpoints restore: %v", err)
    95  	}
    96  
    97  	// If an error happened when the network join the sandbox during the endpoints restore
    98  	// we should reset it now along with the once variable, so that subsequent endpoint joins
    99  	// outside of the restore path can potentially fix the network join and succeed.
   100  	for nid, n := range d.networks {
   101  		if n.initErr != nil {
   102  			logrus.Infof("resetting init error and once variable for network %s after unsuccesful endpoint restore: %v", nid, n.initErr)
   103  			n.initErr = nil
   104  			n.once = &sync.Once{}
   105  		}
   106  	}
   107  
   108  	return dc.RegisterDriver(networkType, d, c)
   109  }
   110  
   111  // Endpoints are stored in the local store. Restore them and reconstruct the overlay sandbox
   112  func (d *driver) restoreEndpoints() error {
   113  	if d.localStore == nil {
   114  		logrus.Warnf("Cannot restore overlay endpoints because local datastore is missing")
   115  		return nil
   116  	}
   117  	kvol, err := d.localStore.List(datastore.Key(overlayEndpointPrefix), &endpoint{})
   118  	if err != nil && err != datastore.ErrKeyNotFound {
   119  		return fmt.Errorf("failed to read overlay endpoint from store: %v", err)
   120  	}
   121  
   122  	if err == datastore.ErrKeyNotFound {
   123  		return nil
   124  	}
   125  	for _, kvo := range kvol {
   126  		ep := kvo.(*endpoint)
   127  		n := d.network(ep.nid)
   128  		if n == nil {
   129  			logrus.Debugf("Network (%s) not found for restored endpoint (%s)", ep.nid[0:7], ep.id[0:7])
   130  			logrus.Debugf("Deleting stale overlay endpoint (%s) from store", ep.id[0:7])
   131  			if err := d.deleteEndpointFromStore(ep); err != nil {
   132  				logrus.Debugf("Failed to delete stale overlay endpoint (%s) from store", ep.id[0:7])
   133  			}
   134  			continue
   135  		}
   136  		n.addEndpoint(ep)
   137  
   138  		s := n.getSubnetforIP(ep.addr)
   139  		if s == nil {
   140  			return fmt.Errorf("could not find subnet for endpoint %s", ep.id)
   141  		}
   142  
   143  		if err := n.joinSandbox(true); err != nil {
   144  			return fmt.Errorf("restore network sandbox failed: %v", err)
   145  		}
   146  
   147  		if err := n.joinSubnetSandbox(s, true); err != nil {
   148  			return fmt.Errorf("restore subnet sandbox failed for %q: %v", s.subnetIP.String(), err)
   149  		}
   150  
   151  		Ifaces := make(map[string][]osl.IfaceOption)
   152  		vethIfaceOption := make([]osl.IfaceOption, 1)
   153  		vethIfaceOption = append(vethIfaceOption, n.sbox.InterfaceOptions().Master(s.brName))
   154  		Ifaces[fmt.Sprintf("%s+%s", "veth", "veth")] = vethIfaceOption
   155  
   156  		err := n.sbox.Restore(Ifaces, nil, nil, nil)
   157  		if err != nil {
   158  			return fmt.Errorf("failed to restore overlay sandbox: %v", err)
   159  		}
   160  
   161  		n.incEndpointCount()
   162  		d.peerDbAdd(ep.nid, ep.id, ep.addr.IP, ep.addr.Mask, ep.mac, net.ParseIP(d.advertiseAddress), true)
   163  	}
   164  	return nil
   165  }
   166  
   167  // Fini cleans up the driver resources
   168  func Fini(drv driverapi.Driver) {
   169  	d := drv.(*driver)
   170  
   171  	if d.exitCh != nil {
   172  		waitCh := make(chan struct{})
   173  
   174  		d.exitCh <- waitCh
   175  
   176  		<-waitCh
   177  	}
   178  }
   179  
   180  func (d *driver) configure() error {
   181  	if d.store == nil {
   182  		return nil
   183  	}
   184  
   185  	if d.vxlanIdm == nil {
   186  		return d.initializeVxlanIdm()
   187  	}
   188  
   189  	return nil
   190  }
   191  
   192  func (d *driver) initializeVxlanIdm() error {
   193  	var err error
   194  
   195  	initVxlanIdm <- true
   196  	defer func() { <-initVxlanIdm }()
   197  
   198  	if d.vxlanIdm != nil {
   199  		return nil
   200  	}
   201  
   202  	d.vxlanIdm, err = idm.New(d.store, "vxlan-id", vxlanIDStart, vxlanIDEnd)
   203  	if err != nil {
   204  		return fmt.Errorf("failed to initialize vxlan id manager: %v", err)
   205  	}
   206  
   207  	return nil
   208  }
   209  
   210  func (d *driver) Type() string {
   211  	return networkType
   212  }
   213  
   214  func validateSelf(node string) error {
   215  	advIP := net.ParseIP(node)
   216  	if advIP == nil {
   217  		return fmt.Errorf("invalid self address (%s)", node)
   218  	}
   219  
   220  	addrs, err := net.InterfaceAddrs()
   221  	if err != nil {
   222  		return fmt.Errorf("Unable to get interface addresses %v", err)
   223  	}
   224  	for _, addr := range addrs {
   225  		ip, _, err := net.ParseCIDR(addr.String())
   226  		if err == nil && ip.Equal(advIP) {
   227  			return nil
   228  		}
   229  	}
   230  	return fmt.Errorf("Multi-Host overlay networking requires cluster-advertise(%s) to be configured with a local ip-address that is reachable within the cluster", advIP.String())
   231  }
   232  
   233  func (d *driver) nodeJoin(advertiseAddress, bindAddress string, self bool) {
   234  	if self && !d.isSerfAlive() {
   235  		d.Lock()
   236  		d.advertiseAddress = advertiseAddress
   237  		d.bindAddress = bindAddress
   238  		d.Unlock()
   239  
   240  		// If there is no cluster store there is no need to start serf.
   241  		if d.store != nil {
   242  			if err := validateSelf(advertiseAddress); err != nil {
   243  				logrus.Warnf("%s", err.Error())
   244  			}
   245  			err := d.serfInit()
   246  			if err != nil {
   247  				logrus.Errorf("initializing serf instance failed: %v", err)
   248  				d.Lock()
   249  				d.advertiseAddress = ""
   250  				d.bindAddress = ""
   251  				d.Unlock()
   252  				return
   253  			}
   254  		}
   255  	}
   256  
   257  	d.Lock()
   258  	if !self {
   259  		d.neighIP = advertiseAddress
   260  	}
   261  	neighIP := d.neighIP
   262  	d.Unlock()
   263  
   264  	if d.serfInstance != nil && neighIP != "" {
   265  		var err error
   266  		d.joinOnce.Do(func() {
   267  			err = d.serfJoin(neighIP)
   268  			if err == nil {
   269  				d.pushLocalDb()
   270  			}
   271  		})
   272  		if err != nil {
   273  			logrus.Errorf("joining serf neighbor %s failed: %v", advertiseAddress, err)
   274  			d.Lock()
   275  			d.joinOnce = sync.Once{}
   276  			d.Unlock()
   277  			return
   278  		}
   279  	}
   280  }
   281  
   282  func (d *driver) pushLocalEndpointEvent(action, nid, eid string) {
   283  	n := d.network(nid)
   284  	if n == nil {
   285  		logrus.Debugf("Error pushing local endpoint event for network %s", nid)
   286  		return
   287  	}
   288  	ep := n.endpoint(eid)
   289  	if ep == nil {
   290  		logrus.Debugf("Error pushing local endpoint event for ep %s / %s", nid, eid)
   291  		return
   292  	}
   293  
   294  	if !d.isSerfAlive() {
   295  		return
   296  	}
   297  	d.notifyCh <- ovNotify{
   298  		action: "join",
   299  		nw:     n,
   300  		ep:     ep,
   301  	}
   302  }
   303  
   304  // DiscoverNew is a notification for a new discovery event, such as a new node joining a cluster
   305  func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) error {
   306  	var err error
   307  	switch dType {
   308  	case discoverapi.NodeDiscovery:
   309  		nodeData, ok := data.(discoverapi.NodeDiscoveryData)
   310  		if !ok || nodeData.Address == "" {
   311  			return fmt.Errorf("invalid discovery data")
   312  		}
   313  		d.nodeJoin(nodeData.Address, nodeData.BindAddress, nodeData.Self)
   314  	case discoverapi.DatastoreConfig:
   315  		if d.store != nil {
   316  			return types.ForbiddenErrorf("cannot accept datastore configuration: Overlay driver has a datastore configured already")
   317  		}
   318  		dsc, ok := data.(discoverapi.DatastoreConfigData)
   319  		if !ok {
   320  			return types.InternalErrorf("incorrect data in datastore configuration: %v", data)
   321  		}
   322  		d.store, err = datastore.NewDataStoreFromConfig(dsc)
   323  		if err != nil {
   324  			return types.InternalErrorf("failed to initialize data store: %v", err)
   325  		}
   326  	case discoverapi.EncryptionKeysConfig:
   327  		encrData, ok := data.(discoverapi.DriverEncryptionConfig)
   328  		if !ok {
   329  			return fmt.Errorf("invalid encryption key notification data")
   330  		}
   331  		keys := make([]*key, 0, len(encrData.Keys))
   332  		for i := 0; i < len(encrData.Keys); i++ {
   333  			k := &key{
   334  				value: encrData.Keys[i],
   335  				tag:   uint32(encrData.Tags[i]),
   336  			}
   337  			keys = append(keys, k)
   338  		}
   339  		if err := d.setKeys(keys); err != nil {
   340  			logrus.Warn(err)
   341  		}
   342  	case discoverapi.EncryptionKeysUpdate:
   343  		var newKey, delKey, priKey *key
   344  		encrData, ok := data.(discoverapi.DriverEncryptionUpdate)
   345  		if !ok {
   346  			return fmt.Errorf("invalid encryption key notification data")
   347  		}
   348  		if encrData.Key != nil {
   349  			newKey = &key{
   350  				value: encrData.Key,
   351  				tag:   uint32(encrData.Tag),
   352  			}
   353  		}
   354  		if encrData.Primary != nil {
   355  			priKey = &key{
   356  				value: encrData.Primary,
   357  				tag:   uint32(encrData.PrimaryTag),
   358  			}
   359  		}
   360  		if encrData.Prune != nil {
   361  			delKey = &key{
   362  				value: encrData.Prune,
   363  				tag:   uint32(encrData.PruneTag),
   364  			}
   365  		}
   366  		if err := d.updateKeys(newKey, priKey, delKey); err != nil {
   367  			logrus.Warn(err)
   368  		}
   369  	default:
   370  	}
   371  	return nil
   372  }
   373  
   374  // DiscoverDelete is a notification for a discovery delete event, such as a node leaving a cluster
   375  func (d *driver) DiscoverDelete(dType discoverapi.DiscoveryType, data interface{}) error {
   376  	return nil
   377  }