|
@@ -203,38 +203,31 @@ func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPM
|
|
return pEntry
|
|
return pEntry
|
|
}
|
|
}
|
|
|
|
|
|
-func (d *driver) peerDbUpdateSandbox(nid string) {
|
|
|
|
- d.peerDb.Lock()
|
|
|
|
- pMap, ok := d.peerDb.mp[nid]
|
|
|
|
- if !ok {
|
|
|
|
- d.peerDb.Unlock()
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- d.peerDb.Unlock()
|
|
|
|
-
|
|
|
|
- pMap.Lock()
|
|
|
|
- for pKeyStr, pEntry := range pMap.mp {
|
|
|
|
- var pKey peerKey
|
|
|
|
- if _, err := fmt.Sscan(pKeyStr, &pKey); err != nil {
|
|
|
|
- logrus.Errorf("peer key scan failed: %v", err)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if pEntry.isLocal {
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
|
|
+// The overlay uses a lazy initialization approach, this means that when a network is created
|
|
|
|
+// and the driver registered the overlay does not allocate resources till the moment that a
|
|
|
|
+// sandbox is actually created.
|
|
|
|
+// At the moment of this call, that happens when a sandbox is initialized, is possible that
|
|
|
|
+// networkDB has already delivered some events of peers already available on remote nodes,
|
|
|
|
+// these peers are saved into the peerDB and this function is used to properly configure
|
|
|
|
+// the network sandbox with all those peers that got previously notified.
|
|
|
|
+// Note also that this method sends a single message on the channel and the go routine on the
|
|
|
|
+// other side, will atomically loop on the whole table of peers and will program their state
|
|
|
|
+// in one single atomic operation. This is fundamental to guarantee consistency, and avoid that
|
|
|
|
+// new peerAdd or peerDelete gets reordered during the sandbox init.
|
|
|
|
+func (d *driver) initSandboxPeerDB(nid string) {
|
|
|
|
+ d.peerInit(nid)
|
|
|
|
+}
|
|
|
|
|
|
- // Go captures variables by reference. The pEntry could be
|
|
|
|
- // pointing to the same memory location for every iteration. Make
|
|
|
|
- // a copy of pEntry before capturing it in the following closure.
|
|
|
|
- entry := pEntry
|
|
|
|
|
|
+type peerOperationType int32
|
|
|
|
|
|
- d.peerAdd(nid, entry.eid, pKey.peerIP, entry.peerIPMask, pKey.peerMac, entry.vtep, false, false, false, false)
|
|
|
|
- }
|
|
|
|
- pMap.Unlock()
|
|
|
|
-}
|
|
|
|
|
|
+const (
|
|
|
|
+ peerOperationINIT peerOperationType = iota
|
|
|
|
+ peerOperationADD
|
|
|
|
+ peerOperationDELETE
|
|
|
|
+)
|
|
|
|
|
|
type peerOperation struct {
|
|
type peerOperation struct {
|
|
- isAdd bool
|
|
|
|
|
|
+ opType peerOperationType
|
|
networkID string
|
|
networkID string
|
|
endpointID string
|
|
endpointID string
|
|
peerIP net.IP
|
|
peerIP net.IP
|
|
@@ -255,9 +248,12 @@ func (d *driver) peerOpRoutine(ctx context.Context, ch chan *peerOperation) {
|
|
case <-ctx.Done():
|
|
case <-ctx.Done():
|
|
return
|
|
return
|
|
case op := <-ch:
|
|
case op := <-ch:
|
|
- if op.isAdd {
|
|
|
|
|
|
+ switch op.opType {
|
|
|
|
+ case peerOperationINIT:
|
|
|
|
+ err = d.peerInitOp(op.networkID)
|
|
|
|
+ case peerOperationADD:
|
|
err = d.peerAddOp(op.networkID, op.endpointID, op.peerIP, op.peerIPMask, op.peerMac, op.vtepIP, op.updateDB, op.l2Miss, op.l3Miss, op.localPeer)
|
|
err = d.peerAddOp(op.networkID, op.endpointID, op.peerIP, op.peerIPMask, op.peerMac, op.vtepIP, op.updateDB, op.l2Miss, op.l3Miss, op.localPeer)
|
|
- } else {
|
|
|
|
|
|
+ case peerOperationDELETE:
|
|
err = d.peerDeleteOp(op.networkID, op.endpointID, op.peerIP, op.peerIPMask, op.peerMac, op.vtepIP, op.localPeer)
|
|
err = d.peerDeleteOp(op.networkID, op.endpointID, op.peerIP, op.peerIPMask, op.peerMac, op.vtepIP, op.localPeer)
|
|
}
|
|
}
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -267,11 +263,33 @@ func (d *driver) peerOpRoutine(ctx context.Context, ch chan *peerOperation) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (d *driver) peerInit(nid string) {
|
|
|
|
+ callerName := common.CallerName(1)
|
|
|
|
+ d.peerOpCh <- &peerOperation{
|
|
|
|
+ opType: peerOperationINIT,
|
|
|
|
+ networkID: nid,
|
|
|
|
+ callerName: callerName,
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (d *driver) peerInitOp(nid string) error {
|
|
|
|
+ return d.peerDbNetworkWalk(nid, func(pKey *peerKey, pEntry *peerEntry) bool {
|
|
|
|
+ // Local entries do not need to be added
|
|
|
|
+ if pEntry.isLocal {
|
|
|
|
+ return false
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ d.peerAddOp(nid, pEntry.eid, pKey.peerIP, pEntry.peerIPMask, pKey.peerMac, pEntry.vtep, false, false, false, false)
|
|
|
|
+ // return false to loop on all entries
|
|
|
|
+ return false
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
|
|
func (d *driver) peerAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask,
|
|
peerMac net.HardwareAddr, vtep net.IP, updateDb, l2Miss, l3Miss, localPeer bool) {
|
|
peerMac net.HardwareAddr, vtep net.IP, updateDb, l2Miss, l3Miss, localPeer bool) {
|
|
callerName := common.CallerName(1)
|
|
callerName := common.CallerName(1)
|
|
d.peerOpCh <- &peerOperation{
|
|
d.peerOpCh <- &peerOperation{
|
|
- isAdd: true,
|
|
|
|
|
|
+ opType: peerOperationADD,
|
|
networkID: nid,
|
|
networkID: nid,
|
|
endpointID: eid,
|
|
endpointID: eid,
|
|
peerIP: peerIP,
|
|
peerIP: peerIP,
|
|
@@ -307,6 +325,9 @@ func (d *driver) peerAddOp(nid, eid string, peerIP net.IP, peerIPMask net.IPMask
|
|
|
|
|
|
sbox := n.sandbox()
|
|
sbox := n.sandbox()
|
|
if sbox == nil {
|
|
if sbox == nil {
|
|
|
|
+ // We are hitting this case for all the events that are arriving before that the sandbox
|
|
|
|
+ // is being created. The peer got already added into the database and the sanbox init will
|
|
|
|
+ // call the peerDbUpdateSandbox that will configure all these peers from the database
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -350,7 +371,7 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas
|
|
peerMac net.HardwareAddr, vtep net.IP, updateDb bool) {
|
|
peerMac net.HardwareAddr, vtep net.IP, updateDb bool) {
|
|
callerName := common.CallerName(1)
|
|
callerName := common.CallerName(1)
|
|
d.peerOpCh <- &peerOperation{
|
|
d.peerOpCh <- &peerOperation{
|
|
- isAdd: false,
|
|
|
|
|
|
+ opType: peerOperationDELETE,
|
|
networkID: nid,
|
|
networkID: nid,
|
|
endpointID: eid,
|
|
endpointID: eid,
|
|
peerIP: peerIP,
|
|
peerIP: peerIP,
|