diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-07-26 09:52:10 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-07-26 09:52:10 +0900 |
commit | 511f487dd1dcdf836d15a231293189aaf0dbf528 (patch) | |
tree | 10fe5924b49c76df9d7f051698abb0402222edc8 | |
parent | 6bf07e5c0f83e9b879d85436844def9aab36e28d (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.go | 32 |
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 } |