diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/peer.go | 31 | ||||
-rw-r--r-- | server/server.go | 73 | ||||
-rw-r--r-- | server/server_test.go | 2 |
3 files changed, 72 insertions, 34 deletions
diff --git a/server/peer.go b/server/peer.go index e51efc93..4d2d1ceb 100644 --- a/server/peer.go +++ b/server/peer.go @@ -17,13 +17,14 @@ package server import ( "fmt" + "net" + "time" + "github.com/eapache/channels" "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" "github.com/osrg/gobgp/table" log "github.com/sirupsen/logrus" - "net" - "time" ) const ( @@ -143,6 +144,13 @@ func (peer *Peer) isGracefulRestartEnabled() bool { return peer.fsm.pConf.GracefulRestart.State.Enabled } +func (peer *Peer) isAddPathSendEnabled(family bgp.RouteFamily) bool { + if mode, y := peer.fsm.rfMap[family]; y && (mode&bgp.BGP_ADD_PATH_SEND) > 0 { + return true + } + return false +} + func (peer *Peer) isDynamicNeighbor() bool { return peer.fsm.pConf.Config.NeighborAddress == "" && peer.fsm.pConf.Config.NeighborInterface == "" } @@ -380,13 +388,20 @@ func (peer *Peer) filterpath(path, old *table.Path) *table.Path { func (peer *Peer) getBestFromLocal(rfList []bgp.RouteFamily) ([]*table.Path, []*table.Path) { pathList := []*table.Path{} filtered := []*table.Path{} - for _, path := range peer.localRib.GetBestPathList(peer.TableID(), peer.toGlobalFamilies(rfList)) { - if p := peer.filterpath(path, nil); p != nil { - pathList = append(pathList, p) - } else { - filtered = append(filtered, path) + for _, family := range peer.toGlobalFamilies(rfList) { + pl := func() []*table.Path { + if peer.isAddPathSendEnabled(family) { + return peer.localRib.GetPathList(peer.TableID(), []bgp.RouteFamily{family}) + } + return peer.localRib.GetBestPathList(peer.TableID(), []bgp.RouteFamily{family}) + }() + for _, path := range pl { + if p := peer.filterpath(path, nil); p != nil { + pathList = append(pathList, p) + } else { + filtered = append(filtered, path) + } } - } if peer.isGracefulRestartEnabled() { for _, family := range rfList { 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) + } } } } diff --git a/server/server_test.go b/server/server_test.go index b8dc58f5..ac762176 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -215,7 +215,7 @@ func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (* } func process(rib *table.TableManager, l []*table.Path) (*table.Path, *table.Path) { - news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, rib.ProcessPaths(l)) + news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, rib.ProcessPaths(l), false) if len(news) != 1 { panic("can't handle multiple paths") } |