From de089a5f0b1d918148dc883ab9e6fce4738e3e4e Mon Sep 17 00:00:00 2001 From: Wataru Ishida Date: Sun, 18 Sep 2016 15:18:17 +0000 Subject: [PATCH] server/table: delegate lower half part of best calc to server pkg preparation for add-path send feature Signed-off-by: Wataru Ishida --- server/peer.go | 183 +++++++++++++++++++++++++++++++++++----- server/server.go | 185 ++++++++++------------------------------- table/destination.go | 116 ++++++++++---------------- table/table_manager.go | 23 +++-- 4 files changed, 259 insertions(+), 248 deletions(-) diff --git a/server/peer.go b/server/peer.go index 2feb4d86b..08fb4d17b 100644 --- a/server/peer.go +++ b/server/peer.go @@ -128,26 +128,108 @@ func (peer *Peer) getAccepted(rfList []bgp.RouteFamily) []*table.Path { return peer.adjRibIn.PathList(rfList, true) } -func (peer *Peer) filterpath(path *table.Path, withdrawals []*table.Path) *table.Path { - // special handling for RTC nlri - // see comments in (*Destination).Calculate() - if path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC && !path.IsWithdraw { - // if we already sent the same nlri, ignore this - if peer.adjRibOut.Exists(path) { - return nil +func (peer *Peer) filterpath(path *table.Path) *table.Path { + if path == nil { + return nil + } + if _, ok := peer.fsm.rfMap[path.GetRouteFamily()]; !ok { + return nil + } + + //iBGP handling + if peer.isIBGPPeer() { + ignore := false + //RFC4684 Constrained Route Distribution + if _, y := peer.fsm.rfMap[bgp.RF_RTC_UC]; y && path.GetRouteFamily() != bgp.RF_RTC_UC { + ignore = true + for _, ext := range path.GetExtCommunities() { + for _, path := range peer.adjRibIn.PathList([]bgp.RouteFamily{bgp.RF_RTC_UC}, true) { + rt := path.GetNlri().(*bgp.RouteTargetMembershipNLRI).RouteTarget + if rt == nil { + ignore = false + } else if ext.String() == rt.String() { + ignore = false + break + } + } + if !ignore { + break + } + } } - dst := peer.localRib.GetDestination(path) - path = nil - // we send a path even if it is not a best path - for _, p := range dst.GetKnownPathList(peer.TableID()) { - // just take care not to send back it - if peer.ID() != p.GetSource().Address.String() { - path = p - break + + if !path.IsLocal() { + ignore = true + info := path.GetSource() + //if the path comes from eBGP peer + if info.AS != peer.fsm.pConf.Config.PeerAs { + ignore = false + } + // RFC4456 8. Avoiding Routing Information Loops + // A router that recognizes the ORIGINATOR_ID attribute SHOULD + // ignore a route received with its BGP Identifier as the ORIGINATOR_ID. + if id := path.GetOriginatorID(); peer.fsm.gConf.Config.RouterId == id.String() { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + "OriginatorID": id, + "Data": path, + }).Debug("Originator ID is mine, ignore") + return nil + } + if info.RouteReflectorClient { + ignore = false } + if peer.isRouteReflectorClient() { + // RFC4456 8. Avoiding Routing Information Loops + // If the local CLUSTER_ID is found in the CLUSTER_LIST, + // the advertisement received SHOULD be ignored. + for _, clusterId := range path.GetClusterList() { + if clusterId.Equal(peer.fsm.peerInfo.RouteReflectorClusterID) { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + "ClusterID": clusterId, + "Data": path, + }).Debug("cluster list path attribute has local cluster id, ignore") + return nil + } + } + ignore = false + } + } + + if ignore { + + for _, adv := range peer.adjRibOut.PathList([]bgp.RouteFamily{path.GetRouteFamily()}, false) { + // we advertise a route from ebgp, + // which is the old best. We got the + // new best from ibgp. We don't + // advertise the new best and need to + // withdraw the old. + if path.GetNlri().String() == adv.GetNlri().String() { + return adv.Clone(true) + } + } + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + "Data": path, + }).Debug("From same AS, ignore.") + return nil } } - if path = filterpath(peer, path, withdrawals); path == nil { + + if peer.ID() == path.GetSource().Address.String() { + log.WithFields(log.Fields{ + "Topic": "Peer", + "Key": peer.ID(), + "Data": path, + }).Debug("From me, ignore.") + return nil + } + + if !peer.isRouteServerClient() && isASLoop(peer, path) { return nil } @@ -172,7 +254,7 @@ func (peer *Peer) getBestFromLocal(rfList []bgp.RouteFamily) ([]*table.Path, []* pathList := []*table.Path{} filtered := []*table.Path{} for _, path := range peer.localRib.GetBestPathList(peer.TableID(), rfList) { - if p := peer.filterpath(path, nil); p != nil { + if p := peer.filterpath(path); p != nil { pathList = append(pathList, p) } else { filtered = append(filtered, path) @@ -187,26 +269,81 @@ func (peer *Peer) getBestFromLocal(rfList []bgp.RouteFamily) ([]*table.Path, []* return pathList, filtered } -func (peer *Peer) processOutgoingPaths(paths, withdrawals []*table.Path) []*table.Path { +func (peer *Peer) isReadyToSend() bool { if peer.fsm.state != bgp.BGP_FSM_ESTABLISHED { - return nil + return false } if peer.fsm.pConf.GracefulRestart.State.LocalRestarting { log.WithFields(log.Fields{ "Topic": "Peer", "Key": peer.fsm.pConf.Config.NeighborAddress, }).Debug("now syncing, suppress sending updates") - return nil + return false } + return true +} - outgoing := make([]*table.Path, 0, len(paths)) +func (peer *Peer) extractOutgoingPaths(dsts []*table.Destination, withdrawals []*table.Path) []*table.Path { + outgoing := make([]*table.Path, 0, len(dsts)) + for _, dst := range dsts { + path := getBestPath(peer.TableID(), dst) + // RFC4684 3.2. Intra-AS VPN Route Distribution + // When processing RT membership NLRIs received from internal iBGP + // peers, it is necessary to consider all available iBGP paths for a + // given RT prefix, for building the outbound route filter, and **not just + // the best path**. + if path == nil && dst.Family() == bgp.RF_RTC_UC { + old := dst.GetOldBest(peer.TableID()) + if old == nil || peer.adjRibOut.Exists(old) { + return nil + } + // we send a path even if it is not a best path + for _, p := range dst.GetKnownPathList(peer.TableID()) { + // just take care not to send back it + if peer.ID() != p.GetSource().Address.String() { + path = p + break + } + } + } + if path == nil { + continue + } + if peer.ID() == path.GetSource().Address.String() { + // Say, gobgp was advertising prefix A and peer P also. + // When gobgp withdraws prefix A, best path calculation chooses + // the path from P as the best path for prefix A. + // For peers other than P, this path should be advertised + // (as implicit withdrawal). However for P, we should advertise + // the local withdraw path. + + // Note: multiple paths having the same prefix could exist the + // withdrawals list in the case of Route Server setup with + // import policies modifying paths. In such case, gobgp sends + // duplicated update messages; withdraw messages for the same + // prefix. + // However, currently we don't support local path for Route + // Server setup so this is NOT the case. + for _, w := range withdrawals { + if w.IsLocal() && path.GetNlri().String() == w.GetNlri().String() { + outgoing = append(outgoing, path) + break + } + } + } else { + outgoing = append(outgoing, path) + } + } + return outgoing +} +func (peer *Peer) processOutgoingPaths(paths []*table.Path) []*table.Path { + outgoing := make([]*table.Path, 0, len(paths)) for _, path := range paths { - if p := peer.filterpath(path, withdrawals); p != nil { + if p := peer.filterpath(path); p != nil { outgoing = append(outgoing, p) } } - peer.adjRibOut.Update(outgoing) return outgoing } diff --git a/server/server.go b/server/server.go index 9f82138b0..3ef72826c 100644 --- a/server/server.go +++ b/server/server.go @@ -267,132 +267,6 @@ func isASLoop(peer *Peer, path *table.Path) bool { return false } -func filterpath(peer *Peer, path *table.Path, withdrawals []*table.Path) *table.Path { - if path == nil { - return nil - } - if _, ok := peer.fsm.rfMap[path.GetRouteFamily()]; !ok { - return nil - } - - //iBGP handling - if peer.isIBGPPeer() { - ignore := false - //RFC4684 Constrained Route Distribution - if _, y := peer.fsm.rfMap[bgp.RF_RTC_UC]; y && path.GetRouteFamily() != bgp.RF_RTC_UC { - ignore = true - for _, ext := range path.GetExtCommunities() { - for _, path := range peer.adjRibIn.PathList([]bgp.RouteFamily{bgp.RF_RTC_UC}, true) { - rt := path.GetNlri().(*bgp.RouteTargetMembershipNLRI).RouteTarget - if rt == nil { - ignore = false - } else if ext.String() == rt.String() { - ignore = false - break - } - } - if !ignore { - break - } - } - } - - if !path.IsLocal() { - ignore = true - info := path.GetSource() - //if the path comes from eBGP peer - if info.AS != peer.fsm.pConf.Config.PeerAs { - ignore = false - } - // RFC4456 8. Avoiding Routing Information Loops - // A router that recognizes the ORIGINATOR_ID attribute SHOULD - // ignore a route received with its BGP Identifier as the ORIGINATOR_ID. - if id := path.GetOriginatorID(); peer.fsm.gConf.Config.RouterId == id.String() { - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": peer.ID(), - "OriginatorID": id, - "Data": path, - }).Debug("Originator ID is mine, ignore") - return nil - } - if info.RouteReflectorClient { - ignore = false - } - if peer.isRouteReflectorClient() { - // RFC4456 8. Avoiding Routing Information Loops - // If the local CLUSTER_ID is found in the CLUSTER_LIST, - // the advertisement received SHOULD be ignored. - for _, clusterId := range path.GetClusterList() { - if clusterId.Equal(peer.fsm.peerInfo.RouteReflectorClusterID) { - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": peer.ID(), - "ClusterID": clusterId, - "Data": path, - }).Debug("cluster list path attribute has local cluster id, ignore") - return nil - } - } - ignore = false - } - } - - if ignore { - - for _, adv := range peer.adjRibOut.PathList([]bgp.RouteFamily{path.GetRouteFamily()}, false) { - // we advertise a route from ebgp, - // which is the old best. We got the - // new best from ibgp. We don't - // advertise the new best and need to - // withdraw the old. - if path.GetNlri().String() == adv.GetNlri().String() { - return adv.Clone(true) - } - } - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": peer.ID(), - "Data": path, - }).Debug("From same AS, ignore.") - return nil - } - } - - if peer.ID() == path.GetSource().Address.String() { - // Say, gobgp was advertising prefix A and peer P also. - // When gobgp withdraws prefix A, best path calculation chooses - // the path from P as the best path for prefix A. - // For peers other than P, this path should be advertised - // (as implicit withdrawal). However for P, we should advertise - // the local withdraw path. - - // Note: multiple paths having the same prefix could exist the - // withdrawals list in the case of Route Server setup with - // import policies modifying paths. In such case, gobgp sends - // duplicated update messages; withdraw messages for the same - // prefix. - // However, currently we don't support local path for Route - // Server setup so this is NOT the case. - for _, w := range withdrawals { - if w.IsLocal() && path.GetNlri().String() == w.GetNlri().String() { - return w - } - } - log.WithFields(log.Fields{ - "Topic": "Peer", - "Key": peer.ID(), - "Data": path, - }).Debug("From me, ignore.") - return nil - } - - if !peer.isRouteServerClient() && isASLoop(peer, path) { - return nil - } - return path -} - func clonePathList(pathList []*table.Path) []*table.Path { l := make([]*table.Path, 0, len(pathList)) for _, p := range pathList { @@ -416,21 +290,28 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil ids = append(ids, table.GLOBAL_RIB_NAME) } for _, rf := range families { - best, _, multipath := server.globalRib.DeletePathsByPeer(ids, peer.fsm.peerInfo, rf) + best, _, multipath := server.globalRib.DeletePathsByPeer(peer.fsm.peerInfo, rf) if !peer.isRouteServerClient() { clonedMpath := make([][]*table.Path, len(multipath)) for i, pathList := range multipath { clonedMpath[i] = clonePathList(pathList) } - server.notifyWatcher(WATCH_EVENT_TYPE_BEST_PATH, &WatchEventBestPath{PathList: clonePathList(best[table.GLOBAL_RIB_NAME]), MultiPathList: clonedMpath}) + bestPaths := make([]*table.Path, 0, len(best)) + for _, d := range best { + if p := getBestPath(table.GLOBAL_RIB_NAME, d); p != nil { + bestPaths = append(bestPaths, p) + } + } + server.notifyWatcher(WATCH_EVENT_TYPE_BEST_PATH, &WatchEventBestPath{PathList: bestPaths, MultiPathList: clonedMpath}) } for _, targetPeer := range server.neighborMap { if peer.isRouteServerClient() != targetPeer.isRouteServerClient() || targetPeer == peer { continue } - if paths := targetPeer.processOutgoingPaths(best[targetPeer.TableID()], nil); len(paths) > 0 { + paths := targetPeer.extractOutgoingPaths(best, nil) + if paths = targetPeer.processOutgoingPaths(paths); len(paths) > 0 { sendFsmOutgoingMsg(targetPeer, paths, nil, false) } } @@ -489,10 +370,25 @@ func (server *BgpServer) RSimportPaths(peer *Peer, pathList []*table.Path) []*ta return moded } +func getBestPath(id string, dst *table.Destination) *table.Path { + old := dst.GetOldBest(id) + best := dst.GetBestPath(id) + if best != nil && best.Equal(old) { + return nil + } + if best == nil { + if old == nil { + return nil + } + return old.Clone(true) + } + return best.Clone(true) +} + func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*table.Path { rib := server.globalRib var alteredPathList, withdrawn []*table.Path - var best map[string][]*table.Path + var best []*table.Destination if peer != nil && peer.isRouteServerClient() { for _, path := range pathList { @@ -516,7 +412,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []* ids = append(ids, targetPeer.TableID()) } } - best, withdrawn, _ = rib.ProcessPaths(ids, append(pathList, moded...)) + best, withdrawn, _ = rib.ProcessPaths(append(pathList, moded...)) } else { for idx, path := range pathList { path = server.policy.ApplyPolicy(table.GLOBAL_RIB_NAME, table.POLICY_DIRECTION_IMPORT, path, nil) @@ -532,7 +428,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []* // updates (advertisements and/or withdrawls) necessary to transition // between the previous and current state of the route distribution // graph that is derived from Route Target membership information. - if peer != nil && path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC { + if peer != nil && peer.isReadyToSend() && path != nil && path.GetRouteFamily() == bgp.RF_RTC_UC { rt := path.GetNlri().(*bgp.RouteTargetMembershipNLRI).RouteTarget fs := make([]bgp.RouteFamily, 0, len(peer.configuredRFlist())) for _, f := range peer.configuredRFlist() { @@ -558,33 +454,36 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []* } } } - if path.IsWithdraw { - paths = peer.processOutgoingPaths(nil, paths) - } else { - paths = peer.processOutgoingPaths(paths, nil) + if paths = peer.processOutgoingPaths(paths); len(paths) > 0 { + sendFsmOutgoingMsg(peer, paths, nil, false) } - sendFsmOutgoingMsg(peer, paths, nil, false) } } alteredPathList = pathList var multipath [][]*table.Path - best, withdrawn, multipath = rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList) - if len(best[table.GLOBAL_RIB_NAME]) == 0 { + best, withdrawn, multipath = rib.ProcessPaths(pathList) + if len(best) == 0 { return alteredPathList } clonedMpath := make([][]*table.Path, len(multipath)) for i, pathList := range multipath { clonedMpath[i] = clonePathList(pathList) } - server.notifyWatcher(WATCH_EVENT_TYPE_BEST_PATH, &WatchEventBestPath{PathList: clonePathList(best[table.GLOBAL_RIB_NAME]), MultiPathList: clonedMpath}) - + bestPaths := make([]*table.Path, 0, len(best)) + for _, d := range best { + if p := getBestPath(table.GLOBAL_RIB_NAME, d); p != nil { + bestPaths = append(bestPaths, p) + } + } + server.notifyWatcher(WATCH_EVENT_TYPE_BEST_PATH, &WatchEventBestPath{PathList: bestPaths, MultiPathList: clonedMpath}) } for _, targetPeer := range server.neighborMap { if (peer == nil && targetPeer.isRouteServerClient()) || (peer != nil && peer.isRouteServerClient() != targetPeer.isRouteServerClient()) { continue } - if paths := targetPeer.processOutgoingPaths(best[targetPeer.TableID()], withdrawn); len(paths) > 0 { + paths := targetPeer.extractOutgoingPaths(best, withdrawn) + if paths = targetPeer.processOutgoingPaths(paths); len(paths) > 0 { sendFsmOutgoingMsg(targetPeer, paths, nil, false) } } @@ -1559,7 +1458,7 @@ func (server *BgpServer) addNeighbor(c *config.Neighbor) error { } moded := server.RSimportPaths(peer, pathList) if len(moded) > 0 { - server.globalRib.ProcessPaths(nil, moded) + server.globalRib.ProcessPaths(moded) } } server.neighborMap[addr] = peer diff --git a/table/destination.go b/table/destination.go index e12ef8502..e5828e5e8 100644 --- a/table/destination.go +++ b/table/destination.go @@ -117,12 +117,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 + oldKnownPathList paths + withdrawList paths + newPathList paths + RadixKey string } func NewDestination(nlri bgp.AddrPrefixInterface, known ...*Path) *Destination { @@ -160,6 +161,15 @@ func (dd *Destination) GetAllKnownPathList() []*Path { return dd.knownPathList } +func (dd *Destination) GetOldBest(id string) *Path { + for _, p := range dd.oldKnownPathList { + if p.Filtered(id) == POLICY_DIRECTION_NONE { + return p + } + } + return nil +} + func (dd *Destination) GetKnownPathList(id string) []*Path { list := make([]*Path, 0, len(dd.knownPathList)) for _, p := range dd.knownPathList { @@ -205,9 +215,8 @@ func (dd *Destination) validatePath(path *Path) { // // 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) (map[string]*Path, []*Path, []*Path) { - best := make(map[string]*Path, len(ids)) - oldKnownPathList := dest.knownPathList +func (dest *Destination) Calculate() ([]*Path, []*Path) { + dest.oldKnownPathList = dest.knownPathList // First remove the withdrawn paths. withdrawnList := dest.explicitWithdraw() // Do implicit withdrawal @@ -219,78 +228,45 @@ func (dest *Destination) Calculate(ids []string) (map[string]*Path, []*Path, []* // Compute new best path dest.computeKnownBestPath() - f := func(id string) *Path { - old := func() *Path { - for _, p := range oldKnownPathList { - if p.Filtered(id) == POLICY_DIRECTION_NONE { - return p - } - } - return nil - }() - best := dest.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 - // peers, it is necessary to consider all available iBGP paths for a - // given RT prefix, for building the outbound route filter, and not just - // the best path. - if best.GetRouteFamily() == bgp.RF_RTC_UC { - return best - } - return nil - } - if best == nil { - if old == nil { - return nil - } - return old.Clone(true) - } - return best - } - var multi []*Path - for _, id := range ids { - best[id] = f(id) - if id == GLOBAL_RIB_NAME && UseMultiplePaths.Enabled { - multipath := func(paths []*Path) []*Path { - mp := make([]*Path, 0, len(paths)) - var best *Path - for _, path := range paths { - if path.Filtered(id) == POLICY_DIRECTION_NONE { - if best == nil { - best = path - mp = append(mp, path) - } else if best.Compare(path) == 0 { - mp = append(mp, path) - } + if UseMultiplePaths.Enabled { + multipath := func(paths []*Path) []*Path { + mp := make([]*Path, 0, len(paths)) + var best *Path + for _, path := range paths { + if path.Filtered(GLOBAL_RIB_NAME) == POLICY_DIRECTION_NONE { + if best == nil { + best = path + mp = append(mp, path) + } else if best.Compare(path) == 0 { + mp = append(mp, path) } } - return mp } - diff := func(lhs, rhs []*Path) bool { - if len(lhs) != len(rhs) { + return mp + } + 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 := multipath(oldKnownPathList) - newM := multipath(dest.knownPathList) - if diff(oldM, newM) { - multi = newM - if len(newM) == 0 { - multi = []*Path{best[id]} - } + return false + } + oldM := multipath(dest.oldKnownPathList) + newM := multipath(dest.knownPathList) + if diff(oldM, newM) { + multi = newM + if len(newM) == 0 { + multi = []*Path{dest.oldKnownPathList[0]} } } } - return best, withdrawnList, multi + return withdrawnList, multi } // Removes withdrawn paths. diff --git a/table/table_manager.go b/table/table_manager.go index f6bebbf7d..506ea9b7b 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -216,13 +216,13 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) { return msgs, nil } -func (manager *TableManager) calculate(ids []string, destinations []*Destination) (map[string][]*Path, []*Path, [][]*Path) { +func (manager *TableManager) calculate(destinations []*Destination) ([]*Destination, []*Path, [][]*Path) { withdrawn := make([]*Path, 0, len(destinations)) - best := make(map[string][]*Path, len(ids)) + dsts := make([]*Destination, 0, len(destinations)) emptyDsts := make([]*Destination, 0, len(destinations)) var multi [][]*Path - if UseMultiplePaths.Enabled && len(ids) == 1 && ids[0] == GLOBAL_RIB_NAME { + if UseMultiplePaths.Enabled { multi = make([][]*Path, 0, len(destinations)) } @@ -231,10 +231,7 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination "Topic": "table", "Key": dst.GetNlri().String(), }).Debug("Processing destination") - paths, w, m := dst.Calculate(ids) - for id, path := range paths { - best[id] = append(best[id], path) - } + w, m := dst.Calculate() withdrawn = append(withdrawn, w...) if m != nil { multi = append(multi, m) @@ -242,6 +239,8 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination if len(dst.knownPathList) == 0 { emptyDsts = append(emptyDsts, dst) + } else { + dsts = append(dsts, dst) } } @@ -249,18 +248,18 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination t := manager.Tables[dst.Family()] t.deleteDest(dst) } - return best, withdrawn, multi + return dsts, withdrawn, multi } -func (manager *TableManager) DeletePathsByPeer(ids []string, info *PeerInfo, rf bgp.RouteFamily) (map[string][]*Path, []*Path, [][]*Path) { +func (manager *TableManager) DeletePathsByPeer(info *PeerInfo, rf bgp.RouteFamily) ([]*Destination, []*Path, [][]*Path) { if t, ok := manager.Tables[rf]; ok { dsts := t.DeleteDestByPeer(info) - return manager.calculate(ids, dsts) + return manager.calculate(dsts) } return nil, nil, nil } -func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[string][]*Path, []*Path, [][]*Path) { +func (manager *TableManager) ProcessPaths(pathList []*Path) ([]*Destination, []*Path, [][]*Path) { m := make(map[string]bool, len(pathList)) dsts := make([]*Destination, 0, len(pathList)) for _, path := range pathList { @@ -286,7 +285,7 @@ func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[s } } } - return manager.calculate(ids, dsts) + return manager.calculate(dsts) } // EVPN MAC MOBILITY HANDLING