summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-07-26 09:52:10 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-07-26 09:52:10 +0900
commit511f487dd1dcdf836d15a231293189aaf0dbf528 (patch)
tree10fe5924b49c76df9d7f051698abb0402222edc8
parent6bf07e5c0f83e9b879d85436844def9aab36e28d (diff)
clone Paths before notifying watchers
Path object has data (map, slice) that mutiple goroutines can't access. So needs to clone them before passing them to wathers. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--server/server.go32
1 files changed, 25 insertions, 7 deletions
diff --git a/server/server.go b/server/server.go
index 1c6a738d..37ea1f8d 100644
--- a/server/server.go
+++ b/server/server.go
@@ -351,6 +351,16 @@ func filterpath(peer *Peer, path *table.Path) *table.Path {
return path
}
+func clonePathList(pathList []*table.Path) []*table.Path {
+ l := make([]*table.Path, 0, len(pathList))
+ for _, p := range pathList {
+ if p != nil {
+ l = append(l, p.Clone(p.IsWithdraw))
+ }
+ }
+ return l
+}
+
func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamily) {
ids := make([]string, 0, len(server.neighborMap))
if peer.isRouteServerClient() {
@@ -367,7 +377,11 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil
best, _, multipath := server.globalRib.DeletePathsByPeer(ids, peer.fsm.peerInfo, rf)
if !peer.isRouteServerClient() {
- server.notifyWatcher(WATCH_TYPE_BESTPATH, &watcherEventBestPathMsg{pathList: best[table.GLOBAL_RIB_NAME], multiPathList: multipath})
+ clonedMpath := make([][]*table.Path, len(multipath))
+ for i, pathList := range multipath {
+ clonedMpath[i] = clonePathList(pathList)
+ }
+ server.notifyWatcher(WATCH_TYPE_BESTPATH, &watcherEventBestPathMsg{pathList: clonePathList(best[table.GLOBAL_RIB_NAME]), multiPathList: clonedMpath})
}
for _, targetPeer := range server.neighborMap {
@@ -511,12 +525,16 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
}
}
alteredPathList = pathList
- var multi [][]*table.Path
- best, withdrawn, multi = rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList)
+ var multipath [][]*table.Path
+ best, withdrawn, multipath = rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList)
if len(best[table.GLOBAL_RIB_NAME]) == 0 {
return alteredPathList
}
- server.notifyWatcher(WATCH_TYPE_BESTPATH, &watcherEventBestPathMsg{pathList: best[table.GLOBAL_RIB_NAME], multiPathList: multi})
+ clonedMpath := make([][]*table.Path, len(multipath))
+ for i, pathList := range multipath {
+ clonedMpath[i] = clonePathList(pathList)
+ }
+ server.notifyWatcher(WATCH_TYPE_BESTPATH, &watcherEventBestPathMsg{pathList: clonePathList(best[table.GLOBAL_RIB_NAME]), multiPathList: clonedMpath})
}
@@ -674,7 +692,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
timestamp: e.timestamp,
payload: e.payload,
postPolicy: false,
- pathList: pathList,
+ pathList: clonePathList(pathList),
}
server.notifyWatcher(WATCH_TYPE_PRE_UPDATE, ev)
}
@@ -694,7 +712,7 @@ func (server *BgpServer) handleFSMMessage(peer *Peer, e *FsmMsg) {
fourBytesAs: y,
timestamp: e.timestamp,
postPolicy: true,
- pathList: altered,
+ pathList: clonePathList(altered),
}
for _, u := range table.CreateUpdateMsgFromPaths(altered) {
payload, _ := u.Serialize()
@@ -2717,7 +2735,7 @@ func (w *Watcher) Generate(t watchType) (err error) {
for _, peer := range w.s.neighborMap {
pathList = append(pathList, peer.adjRibIn.PathList(peer.configuredRFlist(), false)...)
}
- w.notify(&watcherEventAdjInMsg{pathList: pathList})
+ w.notify(&watcherEventAdjInMsg{pathList: clonePathList(pathList)})
}
return err
}