summaryrefslogtreecommitdiffhomepage
path: root/server/server.go
diff options
context:
space:
mode:
Diffstat (limited to 'server/server.go')
-rw-r--r--server/server.go73
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)
+ }
}
}
}