diff options
Diffstat (limited to 'server/server.go')
-rw-r--r-- | server/server.go | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/server/server.go b/server/server.go index fa606c44..ac435172 100644 --- a/server/server.go +++ b/server/server.go @@ -520,24 +520,31 @@ func (server *BgpServer) notifyPostPolicyUpdateWatcher(peer *Peer, pathList []*t server.notifyWatcher(WATCH_EVENT_TYPE_POST_UPDATE, ev) } -func dstsToPaths(id string, dsts []*table.Destination) ([]*table.Path, []*table.Path, [][]*table.Path) { +func dstsToPaths(id string, dsts []*table.Destination, addpath bool) ([]*table.Path, []*table.Path, [][]*table.Path) { bestList := make([]*table.Path, 0, len(dsts)) oldList := make([]*table.Path, 0, len(dsts)) mpathList := make([][]*table.Path, 0, len(dsts)) for _, dst := range dsts { - best, old, mpath := dst.GetChanges(id, false) - bestList = append(bestList, best) - oldList = append(oldList, old) - if mpath != nil { - mpathList = append(mpathList, mpath) + if addpath { + bestList = append(bestList, dst.GetAddPathChanges(id)...) + } else { + best, old, mpath := dst.GetChanges(id, false) + bestList = append(bestList, best) + oldList = append(oldList, old) + if mpath != nil { + mpathList = append(mpathList, mpath) + } } } + if addpath { + oldList = nil + } return bestList, oldList, mpathList } func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamily) { - var bestList []*table.Path + var gBestList, bestList []*table.Path var mpathList [][]*table.Path families = peer.toGlobalFamilies(families) rib := server.globalRib @@ -547,16 +554,20 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil for _, rf := range families { dsts := rib.DeletePathsByPeer(peer.fsm.peerInfo, rf) if !peer.isRouteServerClient() { - bestList, _, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts) - server.notifyBestWatcher(bestList, mpathList) + gBestList, _, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts, false) + server.notifyBestWatcher(gBestList, mpathList) } for _, targetPeer := range server.neighborMap { if peer.isRouteServerClient() != targetPeer.isRouteServerClient() || targetPeer == peer { continue } - if targetPeer.isRouteServerClient() { - bestList, _, _ = dstsToPaths(targetPeer.TableID(), dsts) + if targetPeer.isAddPathSendEnabled(rf) { + bestList, _, _ = dstsToPaths(targetPeer.TableID(), dsts, true) + } else if targetPeer.isRouteServerClient() { + bestList, _, _ = dstsToPaths(targetPeer.TableID(), dsts, false) + } else { + bestList = gBestList } if paths := targetPeer.processOutgoingPaths(bestList, nil); len(paths) > 0 { sendFsmOutgoingMsg(targetPeer, paths, nil, false) @@ -648,7 +659,7 @@ func (server *BgpServer) RSimportPaths(peer *Peer, pathList []*table.Path) []*ta func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { var dsts []*table.Destination - var bestList, oldList []*table.Path + var gBestList, gOldList, bestList, oldList []*table.Path var mpathList [][]*table.Path rib := server.globalRib @@ -729,22 +740,34 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { server.notifyPostPolicyUpdateWatcher(peer, pathList) dsts = rib.ProcessPaths(pathList) - bestList, oldList, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts) - if len(bestList) == 0 { - return - } - server.notifyBestWatcher(bestList, mpathList) + gBestList, gOldList, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts, false) + server.notifyBestWatcher(gBestList, mpathList) } - for _, targetPeer := range server.neighborMap { - if (peer == nil && targetPeer.isRouteServerClient()) || (peer != nil && peer.isRouteServerClient() != targetPeer.isRouteServerClient()) { - continue - } - if targetPeer.isRouteServerClient() { - bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), dsts) + families := make(map[bgp.RouteFamily][]*table.Destination) + for _, dst := range dsts { + if families[dst.Family()] == nil { + families[dst.Family()] = make([]*table.Destination, 0, len(dsts)) } - if paths := targetPeer.processOutgoingPaths(bestList, oldList); len(paths) > 0 { - sendFsmOutgoingMsg(targetPeer, paths, nil, false) + families[dst.Family()] = append(families[dst.Family()], dst) + } + + for family, l := range families { + for _, targetPeer := range server.neighborMap { + if (peer == nil && targetPeer.isRouteServerClient()) || (peer != nil && peer.isRouteServerClient() != targetPeer.isRouteServerClient()) { + continue + } + if targetPeer.isAddPathSendEnabled(family) { + bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), l, true) + } else if targetPeer.isRouteServerClient() { + bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), l, false) + } else { + bestList = gBestList + oldList = gOldList + } + if paths := targetPeer.processOutgoingPaths(bestList, oldList); len(paths) > 0 { + sendFsmOutgoingMsg(targetPeer, paths, nil, false) + } } } } |