diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-06-27 14:47:48 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-07-04 09:30:48 +0900 |
commit | 04ce5ce2956d4e77dd4782adce7ab889625e3f08 (patch) | |
tree | 9167b91b72f581eb4d0f02387c94983f4f2cf0d2 /server | |
parent | 547cd0893a5d426a1c34713026291f5cd55516fe (diff) |
use Destination instead of Path for path selection API
With Destination struct, multiple Paths can be moved from the table
package to the server package in a cleaner way; for features such as
add-path.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'server')
-rw-r--r-- | server/server.go | 75 | ||||
-rw-r--r-- | server/server_test.go | 15 |
2 files changed, 50 insertions, 40 deletions
diff --git a/server/server.go b/server/server.go index 1885c7a7..b821ea82 100644 --- a/server/server.go +++ b/server/server.go @@ -467,12 +467,12 @@ func clonePathList(pathList []*table.Path) []*table.Path { return l } -func (server *BgpServer) notifyBestWatcher(best map[string][]*table.Path, multipath [][]*table.Path) { +func (server *BgpServer) notifyBestWatcher(best []*table.Path, multipath [][]*table.Path) { clonedM := make([][]*table.Path, len(multipath)) for i, pathList := range multipath { clonedM[i] = clonePathList(pathList) } - clonedB := clonePathList(best[table.GLOBAL_RIB_NAME]) + clonedB := clonePathList(best) for _, p := range clonedB { switch p.GetRouteFamily() { case bgp.RF_IPv4_VPN, bgp.RF_IPv6_VPN: @@ -510,33 +510,45 @@ func (server *BgpServer) notifyPostPolicyUpdateWatcher(peer *Peer, pathList []*t server.notifyWatcher(WATCH_EVENT_TYPE_POST_UPDATE, ev) } -func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamily) { +func dstsToPaths(id string, dsts []*table.Destination) ([]*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) + } + } + return bestList, oldList, mpathList +} +func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamily) { + var bestList []*table.Path + var mpathList [][]*table.Path families = peer.toGlobalFamilies(families) rib := server.globalRib - ids := make([]string, 0, len(server.neighborMap)) if peer.isRouteServerClient() { rib = server.rsRib - for _, targetPeer := range server.neighborMap { - if !targetPeer.isRouteServerClient() || targetPeer == peer || targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED { - continue - } - ids = append(ids, targetPeer.TableID()) - } - } else { - ids = append(ids, table.GLOBAL_RIB_NAME) } for _, rf := range families { - best, _, multipath := rib.DeletePathsByPeer(ids, peer.fsm.peerInfo, rf) + dsts := rib.DeletePathsByPeer(peer.fsm.peerInfo, rf) if !peer.isRouteServerClient() { - server.notifyBestWatcher(best, multipath) + bestList, _, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts) + server.notifyBestWatcher(bestList, mpathList) } for _, targetPeer := range server.neighborMap { if peer.isRouteServerClient() != targetPeer.isRouteServerClient() || targetPeer == peer { continue } - if paths := targetPeer.processOutgoingPaths(best[targetPeer.TableID()], nil); len(paths) > 0 { + if targetPeer.isRouteServerClient() { + bestList, _, _ = dstsToPaths(targetPeer.TableID(), dsts) + } + if paths := targetPeer.processOutgoingPaths(bestList, nil); len(paths) > 0 { sendFsmOutgoingMsg(targetPeer, paths, nil, false) } } @@ -624,8 +636,12 @@ 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 mpathList [][]*table.Path + rib := server.globalRib - var best, old map[string][]*table.Path if peer != nil && peer.fsm.pConf.Config.Vrf != "" { vrf := server.globalRib.Vrfs[peer.fsm.pConf.Config.Vrf] @@ -647,17 +663,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { } moded = append(moded, server.RSimportPaths(targetPeer, pathList)...) } - isTarget := func(p *Peer) bool { - return p.isRouteServerClient() && p.fsm.state == bgp.BGP_FSM_ESTABLISHED && !p.fsm.pConf.GracefulRestart.State.LocalRestarting - } - - ids := make([]string, 0, len(server.neighborMap)) - for _, targetPeer := range server.neighborMap { - if isTarget(targetPeer) { - ids = append(ids, targetPeer.TableID()) - } - } - best, old, _ = rib.ProcessPaths(ids, append(pathList, moded...)) + dsts = rib.ProcessPaths(append(pathList, moded...)) } else { for idx, path := range pathList { if p := server.policy.ApplyPolicy(table.GLOBAL_RIB_NAME, table.POLICY_DIRECTION_IMPORT, path, nil); p != nil { @@ -712,20 +718,23 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) { } } server.notifyPostPolicyUpdateWatcher(peer, pathList) - var multipath [][]*table.Path - best, old, multipath = rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList) + dsts = rib.ProcessPaths(pathList) - if len(best[table.GLOBAL_RIB_NAME]) == 0 { + bestList, oldList, mpathList = dstsToPaths(table.GLOBAL_RIB_NAME, dsts) + if len(bestList) == 0 { return } - server.notifyBestWatcher(best, multipath) + server.notifyBestWatcher(bestList, mpathList) } for _, targetPeer := range server.neighborMap { if (peer == nil && targetPeer.isRouteServerClient()) || (peer != nil && peer.isRouteServerClient() != targetPeer.isRouteServerClient()) { continue } - if paths := targetPeer.processOutgoingPaths(best[targetPeer.TableID()], old[targetPeer.TableID()]); len(paths) > 0 { + if targetPeer.isRouteServerClient() { + bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), dsts) + } + if paths := targetPeer.processOutgoingPaths(bestList, oldList); len(paths) > 0 { sendFsmOutgoingMsg(targetPeer, paths, nil, false) } } @@ -1743,7 +1752,7 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error { } moded := server.RSimportPaths(peer, pathList) if len(moded) > 0 { - server.rsRib.ProcessPaths(nil, moded) + server.rsRib.ProcessPaths(moded) } } server.neighborMap[addr] = peer diff --git a/server/server_test.go b/server/server_test.go index e5deb975..fb7b97f3 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -16,15 +16,16 @@ package server import ( + "net" + "runtime" + "testing" + "time" + "github.com/osrg/gobgp/config" "github.com/osrg/gobgp/packet/bgp" "github.com/osrg/gobgp/table" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" - "net" - "runtime" - "testing" - "time" ) func TestModPolicyAssign(t *testing.T) { @@ -214,14 +215,14 @@ func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (* } func process(rib *table.TableManager, l []*table.Path) (*table.Path, *table.Path) { - news, olds, _ := rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, l) + news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, rib.ProcessPaths(l)) if len(news) != 1 { panic("can't handle multiple paths") } - for idx, path := range news[table.GLOBAL_RIB_NAME] { + for idx, path := range news { var old *table.Path if olds != nil { - old = olds[table.GLOBAL_RIB_NAME][idx] + old = olds[idx] } return path, old } |