diff options
-rw-r--r-- | gobgp/cmd/mrt.go | 6 | ||||
-rw-r--r-- | server/server.go | 75 | ||||
-rw-r--r-- | server/server_test.go | 15 | ||||
-rw-r--r-- | table/destination.go | 145 | ||||
-rw-r--r-- | table/destination_test.go | 41 | ||||
-rw-r--r-- | table/table_manager.go | 41 | ||||
-rw-r--r-- | table/table_manager_test.go | 13 |
7 files changed, 169 insertions, 167 deletions
diff --git a/gobgp/cmd/mrt.go b/gobgp/cmd/mrt.go index f89e801f..8aa6be95 100644 --- a/gobgp/cmd/mrt.go +++ b/gobgp/cmd/mrt.go @@ -112,11 +112,11 @@ func injectMrt(filename string, count int, skip int, onlyBest bool) error { for _, p := range paths { dst.AddNewPath(p) } - best, _, _ := dst.Calculate([]string{table.GLOBAL_RIB_NAME}, false) - if best[table.GLOBAL_RIB_NAME] == nil { + best, _, _ := dst.Calculate().GetChanges(table.GLOBAL_RIB_NAME, false) + if best == nil { exitWithError(fmt.Errorf("Can't find the best %v", nlri)) } - paths = []*table.Path{best[table.GLOBAL_RIB_NAME]} + paths = []*table.Path{best} } if idx >= skip { 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 } diff --git a/table/destination.go b/table/destination.go index af74f8fd..6f4f95ad 100644 --- a/table/destination.go +++ b/table/destination.go @@ -140,12 +140,13 @@ func NewPeerInfo(g *config.Global, p *config.Neighbor) *PeerInfo { } type Destination struct { - routeFamily bgp.RouteFamily - nlri bgp.AddrPrefixInterface - knownPathList paths - withdrawList paths - newPathList paths - RadixKey string + routeFamily bgp.RouteFamily + nlri bgp.AddrPrefixInterface + knownPathList paths + withdrawList paths + newPathList paths + oldKnownPathList paths + RadixKey string } func NewDestination(nlri bgp.AddrPrefixInterface, known ...*Path) *Destination { @@ -226,50 +227,10 @@ func (dd *Destination) GetMultiBestPath(id string) []*Path { return getMultiBestPath(id, &dd.knownPathList) } -func (dd *Destination) AddWithdraw(withdraw *Path) { - dd.validatePath(withdraw) - dd.withdrawList = append(dd.withdrawList, withdraw) -} - -func (dd *Destination) AddNewPath(newPath *Path) { - dd.validatePath(newPath) - dd.newPathList = append(dd.newPathList, newPath) -} - -func (dd *Destination) validatePath(path *Path) { - if path == nil || path.GetRouteFamily() != dd.routeFamily { - - log.WithFields(log.Fields{ - "Topic": "Table", - "Key": dd.GetNlri().String(), - "Path": path, - "ExpectedRF": dd.routeFamily, - }).Error("path is nil or invalid route family") - } -} - -// Calculates best-path among known paths for this destination. -// -// Modifies destination's state related to stored paths. Removes withdrawn -// paths from known paths. Also, adds new paths to known paths. -func (dest *Destination) Calculate(ids []string, peerDown bool) (map[string]*Path, map[string]*Path, []*Path) { - bestList := make(map[string]*Path, len(ids)) - oldList := make(map[string]*Path, len(ids)) - oldKnownPathList := dest.knownPathList - // First remove the withdrawn paths. - dest.explicitWithdraw() - // Do implicit withdrawal - dest.implicitWithdraw() - // Collect all new paths into known paths. - dest.knownPathList = append(dest.knownPathList, dest.newPathList...) - // Clear new paths as we copied them. - dest.newPathList = make([]*Path, 0) - // Compute new best path - dest.computeKnownBestPath() - - f := func(id string) (*Path, *Path) { - old := getBestPath(id, &oldKnownPathList) - best := dest.GetBestPath(id) +func (dd *Destination) GetChanges(id string, peerDown bool) (*Path, *Path, []*Path) { + best, old := func(id string) (*Path, *Path) { + old := getBestPath(id, &dd.oldKnownPathList) + best := dd.GetBestPath(id) if best != nil && best.Equal(old) { // RFC4684 3.2. Intra-AS VPN Route Distribution // When processing RT membership NLRIs received from internal iBGP @@ -300,35 +261,79 @@ func (dest *Destination) Calculate(ids []string, peerDown bool) (map[string]*Pat return old.Clone(true), old } return best, old - } + }(id) var multi []*Path - for _, id := range ids { - bestList[id], oldList[id] = f(id) - if id == GLOBAL_RIB_NAME && UseMultiplePaths.Enabled { - diff := func(lhs, rhs []*Path) bool { - if len(lhs) != len(rhs) { + + if id == GLOBAL_RIB_NAME && UseMultiplePaths.Enabled { + diff := func(lhs, rhs []*Path) bool { + if len(lhs) != len(rhs) { + return true + } + for idx, l := range lhs { + if !l.Equal(rhs[idx]) { return true } - for idx, l := range lhs { - if !l.Equal(rhs[idx]) { - return true - } - } - return false } - oldM := getMultiBestPath(id, &oldKnownPathList) - newM := dest.GetMultiBestPath(id) - if diff(oldM, newM) { - multi = newM - if len(newM) == 0 { - multi = []*Path{bestList[id]} - } + return false + } + oldM := getMultiBestPath(id, &dd.oldKnownPathList) + newM := dd.GetMultiBestPath(id) + if diff(oldM, newM) { + multi = newM + if len(newM) == 0 { + multi = []*Path{best} } } } + return best, old, multi +} + +func (dd *Destination) AddWithdraw(withdraw *Path) { + dd.validatePath(withdraw) + dd.withdrawList = append(dd.withdrawList, withdraw) +} + +func (dd *Destination) AddNewPath(newPath *Path) { + dd.validatePath(newPath) + dd.newPathList = append(dd.newPathList, newPath) +} + +func (dd *Destination) validatePath(path *Path) { + if path == nil || path.GetRouteFamily() != dd.routeFamily { - return bestList, oldList, multi + log.WithFields(log.Fields{ + "Topic": "Table", + "Key": dd.GetNlri().String(), + "Path": path, + "ExpectedRF": dd.routeFamily, + }).Error("path is nil or invalid route family") + } +} + +// Calculates best-path among known paths for this destination. +// +// Modifies destination's state related to stored paths. Removes withdrawn +// paths from known paths. Also, adds new paths to known paths. +func (dest *Destination) Calculate() *Destination { + oldKnownPathList := dest.knownPathList + // First remove the withdrawn paths. + dest.explicitWithdraw() + // Do implicit withdrawal + dest.implicitWithdraw() + // Collect all new paths into known paths. + dest.knownPathList = append(dest.knownPathList, dest.newPathList...) + // Clear new paths as we copied them. + dest.newPathList = make([]*Path, 0) + // Compute new best path + dest.computeKnownBestPath() + + return &Destination{ + routeFamily: dest.routeFamily, + nlri: dest.nlri, + knownPathList: dest.knownPathList, + oldKnownPathList: oldKnownPathList, + } } // Removes withdrawn paths. diff --git a/table/destination_test.go b/table/destination_test.go index e1f13410..d1124b4b 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -92,7 +92,7 @@ func TestCalculate(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate([]string{"1", "2"}, false) + d.Calculate() assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 1) @@ -100,7 +100,7 @@ func TestCalculate(t *testing.T) { d.AddWithdraw(path1.Clone(true)) - d.Calculate([]string{"1", "2"}, false) + d.Calculate() assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 0) @@ -124,7 +124,7 @@ func TestCalculate2(t *testing.T) { d := NewDestination(nlri) d.AddNewPath(path1) - d.Calculate(nil, false) + d.Calculate() // suppose peer2 sends grammaatically correct but semantically flawed update message // which has a withdrawal nlri not advertised before @@ -134,7 +134,7 @@ func TestCalculate2(t *testing.T) { assert.Equal(t, path2.IsWithdraw, true) d.AddWithdraw(path2) - d.Calculate(nil, false) + d.Calculate() // we have a path from peer1 here assert.Equal(t, len(d.knownPathList), 1) @@ -145,7 +145,7 @@ func TestCalculate2(t *testing.T) { assert.Equal(t, path3.IsWithdraw, false) d.AddNewPath(path3) - d.Calculate(nil, false) + d.Calculate() // this time, we have paths from peer1 and peer2 assert.Equal(t, len(d.knownPathList), 2) @@ -156,7 +156,7 @@ func TestCalculate2(t *testing.T) { path4 := ProcessMessage(update4, peer3, time.Now())[0] d.AddNewPath(path4) - d.Calculate(nil, false) + d.Calculate() // we must have paths from peer1, peer2 and peer3 assert.Equal(t, len(d.knownPathList), 3) @@ -190,7 +190,7 @@ func TestImplicitWithdrawCalculate(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate(nil, false) + d.Calculate() assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) @@ -209,7 +209,7 @@ func TestImplicitWithdrawCalculate(t *testing.T) { path3.Filter("1", POLICY_DIRECTION_IMPORT) d.AddNewPath(path3) - d.Calculate(nil, false) + d.Calculate() assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) @@ -294,7 +294,7 @@ func TestTimeTieBreaker(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate(nil, false) + d.Calculate() assert.Equal(t, len(d.knownPathList), 2) assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{2, 2, 2, 2})) // path from peer2 win @@ -305,7 +305,7 @@ func TestTimeTieBreaker(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate(nil, false) + d.Calculate() assert.Equal(t, len(d.knownPathList), 2) assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{1, 1, 1, 1})) // path from peer1 win @@ -462,17 +462,18 @@ func TestMultipath(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - best, old, multi := d.Calculate([]string{GLOBAL_RIB_NAME}, false) - assert.Equal(t, len(best), 1) - assert.Equal(t, old[GLOBAL_RIB_NAME], (*Path)(nil)) + best, old, multi := d.Calculate().GetChanges(GLOBAL_RIB_NAME, false) + assert.NotNil(t, best) + assert.Equal(t, old, (*Path)(nil)) assert.Equal(t, len(multi), 2) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) path3 := path2.Clone(true) d.AddWithdraw(path3) - best, old, multi = d.Calculate([]string{GLOBAL_RIB_NAME}, false) - assert.Equal(t, len(best), 1) - assert.Equal(t, old[GLOBAL_RIB_NAME], path1) + dd := d.Calculate() + best, old, multi = dd.GetChanges(GLOBAL_RIB_NAME, false) + assert.Nil(t, best) + assert.Equal(t, old, path1) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 1) @@ -489,8 +490,8 @@ func TestMultipath(t *testing.T) { path4 := ProcessMessage(updateMsg, peer3, time.Now())[0] d.AddNewPath(path4) - best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME}, false) - assert.Equal(t, len(best), 1) + best, _, multi = d.Calculate().GetChanges(GLOBAL_RIB_NAME, false) + assert.NotNil(t, best) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) @@ -505,8 +506,8 @@ func TestMultipath(t *testing.T) { path5 := ProcessMessage(updateMsg, peer2, time.Now())[0] d.AddNewPath(path5) - best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME}, false) - assert.Equal(t, len(best), 1) + best, _, multi = d.Calculate().GetChanges(GLOBAL_RIB_NAME, false) + assert.NotNil(t, best) assert.Equal(t, len(multi), 2) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 3) diff --git a/table/table_manager.go b/table/table_manager.go index e41c2798..023672fc 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -18,10 +18,11 @@ package table import ( "bytes" "fmt" - "github.com/osrg/gobgp/packet/bgp" - log "github.com/sirupsen/logrus" "net" "time" + + "github.com/osrg/gobgp/packet/bgp" + log "github.com/sirupsen/logrus" ) const ( @@ -185,29 +186,17 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) { return msgs, nil } -func (manager *TableManager) calculate(ids []string, destinations []*Destination, peerDown bool) (map[string][]*Path, map[string][]*Path, [][]*Path) { - best := make(map[string][]*Path, len(ids)) - old := make(map[string][]*Path, len(ids)) +func (manager *TableManager) calculate(dsts []*Destination) []*Destination { + emptyDsts := make([]*Destination, 0, len(dsts)) + clonedDsts := make([]*Destination, 0, len(dsts)) - emptyDsts := make([]*Destination, 0, len(destinations)) - var multi [][]*Path - if UseMultiplePaths.Enabled && len(ids) == 1 && ids[0] == GLOBAL_RIB_NAME { - multi = make([][]*Path, 0, len(destinations)) - } - - for _, dst := range destinations { + for _, dst := range dsts { log.WithFields(log.Fields{ "Topic": "table", "Key": dst.GetNlri().String(), }).Debug("Processing destination") - paths, olds, m := dst.Calculate(ids, peerDown) - for id, path := range paths { - best[id] = append(best[id], path) - old[id] = append(old[id], olds[id]) - } - if m != nil { - multi = append(multi, m) - } + + clonedDsts = append(clonedDsts, dst.Calculate()) if len(dst.knownPathList) == 0 { emptyDsts = append(emptyDsts, dst) @@ -218,18 +207,18 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination t := manager.Tables[dst.Family()] t.deleteDest(dst) } - return best, old, multi + return clonedDsts } -func (manager *TableManager) DeletePathsByPeer(ids []string, info *PeerInfo, rf bgp.RouteFamily) (map[string][]*Path, map[string][]*Path, [][]*Path) { +func (manager *TableManager) DeletePathsByPeer(info *PeerInfo, rf bgp.RouteFamily) []*Destination { if t, ok := manager.Tables[rf]; ok { dsts := t.DeleteDestByPeer(info) - return manager.calculate(ids, dsts, true) + return manager.calculate(dsts) } - return nil, nil, nil + return nil } -func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[string][]*Path, map[string][]*Path, [][]*Path) { +func (manager *TableManager) ProcessPaths(pathList []*Path) []*Destination { m := make(map[string]bool, len(pathList)) dsts := make([]*Destination, 0, len(pathList)) for _, path := range pathList { @@ -255,7 +244,7 @@ func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[s } } } - return manager.calculate(ids, dsts, false) + return manager.calculate(dsts) } // EVPN MAC MOBILITY HANDLING diff --git a/table/table_manager_test.go b/table/table_manager_test.go index 2a8ed2f6..ec979bf6 100644 --- a/table/table_manager_test.go +++ b/table/table_manager_test.go @@ -29,15 +29,12 @@ import ( // process BGPUpdate message // this function processes only BGPUpdate func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) { - paths := ProcessMessage(message, fromPeer, time.Now()) - best, _, _ := manager.ProcessPaths([]string{GLOBAL_RIB_NAME}, paths) - paths2 := make([]*Path, 0, len(paths)) - for _, p := range best[GLOBAL_RIB_NAME] { - if p != nil { - paths2 = append(paths2, p) - } + pathList := make([]*Path, 0) + for _, d := range manager.ProcessPaths(ProcessMessage(message, fromPeer, time.Now())) { + b, _, _ := d.GetChanges(GLOBAL_RIB_NAME, false) + pathList = append(pathList, b) } - return paths2, nil + return pathList, nil } func getLogger(lv log.Level) *log.Logger { |