mirror of
https://github.com/osrg/gobgp.git
synced 2024-05-11 05:55:10 +00:00
table: use old best path instead of withdrawn paths
Preparation for removing in-memory adj-out. Signed-off-by: FUJITA Tomonori <[email protected]>
This commit is contained in:
+9
-5
@@ -233,7 +233,7 @@ 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 {
|
||||
func (peer *Peer) filterpath(path, old *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 {
|
||||
@@ -268,7 +268,7 @@ func (peer *Peer) filterpath(path *table.Path, withdrawals []*table.Path) *table
|
||||
}
|
||||
}
|
||||
|
||||
if path = filterpath(peer, path, withdrawals); path == nil {
|
||||
if path = filterpath(peer, path, old); path == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ 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) processOutgoingPaths(paths, olds []*table.Path) []*table.Path {
|
||||
if peer.fsm.state != bgp.BGP_FSM_ESTABLISHED {
|
||||
return nil
|
||||
}
|
||||
@@ -338,8 +338,12 @@ func (peer *Peer) processOutgoingPaths(paths, withdrawals []*table.Path) []*tabl
|
||||
|
||||
outgoing := make([]*table.Path, 0, len(paths))
|
||||
|
||||
for _, path := range paths {
|
||||
if p := peer.filterpath(path, withdrawals); p != nil {
|
||||
for idx, path := range paths {
|
||||
var old *table.Path
|
||||
if olds != nil {
|
||||
old = olds[idx]
|
||||
}
|
||||
if p := peer.filterpath(path, old); p != nil {
|
||||
outgoing = append(outgoing, p)
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -269,7 +269,7 @@ func isASLoop(peer *Peer, path *table.Path) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func filterpath(peer *Peer, path *table.Path, withdrawals []*table.Path) *table.Path {
|
||||
func filterpath(peer *Peer, path, old *table.Path) *table.Path {
|
||||
if path == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -377,10 +377,8 @@ func filterpath(peer *Peer, path *table.Path, withdrawals []*table.Path) *table.
|
||||
// the withdrawal path.
|
||||
// Thing is same when peer A and we advertized prefix P (as local
|
||||
// route), then, we withdraws the prefix.
|
||||
for _, w := range withdrawals {
|
||||
if path.GetNlri().String() == w.GetNlri().String() {
|
||||
return w
|
||||
}
|
||||
if old != nil {
|
||||
return old.Clone(true)
|
||||
}
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
@@ -512,8 +510,8 @@ func (server *BgpServer) RSimportPaths(peer *Peer, pathList []*table.Path) []*ta
|
||||
|
||||
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 alteredPathList []*table.Path
|
||||
var best, old map[string][]*table.Path
|
||||
|
||||
if peer != nil && peer.fsm.pConf.Config.Vrf != "" {
|
||||
vrf := server.globalRib.Vrfs[peer.fsm.pConf.Config.Vrf]
|
||||
@@ -544,7 +542,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
|
||||
ids = append(ids, targetPeer.TableID())
|
||||
}
|
||||
}
|
||||
best, withdrawn, _ = rib.ProcessPaths(ids, append(pathList, moded...))
|
||||
best, old, _ = rib.ProcessPaths(ids, append(pathList, moded...))
|
||||
} else {
|
||||
for idx, path := range pathList {
|
||||
path = server.policy.ApplyPolicy(table.GLOBAL_RIB_NAME, table.POLICY_DIRECTION_IMPORT, path, nil)
|
||||
@@ -596,7 +594,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
|
||||
}
|
||||
alteredPathList = pathList
|
||||
var multipath [][]*table.Path
|
||||
best, withdrawn, multipath = rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList)
|
||||
best, old, multipath = rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList)
|
||||
if len(best[table.GLOBAL_RIB_NAME]) == 0 {
|
||||
return alteredPathList
|
||||
}
|
||||
@@ -607,7 +605,7 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) []*
|
||||
if (peer == nil && targetPeer.isRouteServerClient()) || (peer != nil && peer.isRouteServerClient() != targetPeer.isRouteServerClient()) {
|
||||
continue
|
||||
}
|
||||
if paths := targetPeer.processOutgoingPaths(best[targetPeer.TableID()], withdrawn); len(paths) > 0 {
|
||||
if paths := targetPeer.processOutgoingPaths(best[targetPeer.TableID()], old[targetPeer.TableID()]); len(paths) > 0 {
|
||||
sendFsmOutgoingMsg(targetPeer, paths, nil, false)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -206,11 +206,12 @@ 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))
|
||||
func (dest *Destination) Calculate(ids []string) (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.
|
||||
withdrawnList := dest.explicitWithdraw()
|
||||
dest.explicitWithdraw()
|
||||
// Do implicit withdrawal
|
||||
dest.implicitWithdraw()
|
||||
// Collect all new paths into known paths.
|
||||
@@ -220,7 +221,7 @@ func (dest *Destination) Calculate(ids []string) (map[string]*Path, []*Path, []*
|
||||
// Compute new best path
|
||||
dest.computeKnownBestPath()
|
||||
|
||||
f := func(id string) *Path {
|
||||
f := func(id string) (*Path, *Path) {
|
||||
old := func() *Path {
|
||||
for _, p := range oldKnownPathList {
|
||||
if p.Filtered(id) == POLICY_DIRECTION_NONE {
|
||||
@@ -237,22 +238,22 @@ func (dest *Destination) Calculate(ids []string) (map[string]*Path, []*Path, []*
|
||||
// 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 best, old
|
||||
}
|
||||
return nil
|
||||
return nil, old
|
||||
}
|
||||
if best == nil {
|
||||
if old == nil {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
return old.Clone(true)
|
||||
return old.Clone(true), old
|
||||
}
|
||||
return best
|
||||
return best, old
|
||||
}
|
||||
|
||||
var multi []*Path
|
||||
for _, id := range ids {
|
||||
best[id] = f(id)
|
||||
bestList[id], oldList[id] = f(id)
|
||||
if id == GLOBAL_RIB_NAME && UseMultiplePaths.Enabled {
|
||||
multipath := func(paths []*Path) []*Path {
|
||||
mp := make([]*Path, 0, len(paths))
|
||||
@@ -285,13 +286,13 @@ func (dest *Destination) Calculate(ids []string) (map[string]*Path, []*Path, []*
|
||||
if diff(oldM, newM) {
|
||||
multi = newM
|
||||
if len(newM) == 0 {
|
||||
multi = []*Path{best[id]}
|
||||
multi = []*Path{bestList[id]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best, withdrawnList, multi
|
||||
return bestList, oldList, multi
|
||||
}
|
||||
|
||||
// Removes withdrawn paths.
|
||||
|
||||
@@ -438,17 +438,17 @@ func TestMultipath(t *testing.T) {
|
||||
d.AddNewPath(path1)
|
||||
d.AddNewPath(path2)
|
||||
|
||||
best, w, multi := d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
best, old, multi := d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
assert.Equal(t, len(best), 1)
|
||||
assert.Equal(t, len(w), 0)
|
||||
assert.Equal(t, old[GLOBAL_RIB_NAME], (*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, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
best, old, multi = d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
assert.Equal(t, len(best), 1)
|
||||
assert.Equal(t, len(w), 1)
|
||||
assert.Equal(t, old[GLOBAL_RIB_NAME], path1)
|
||||
assert.Equal(t, len(multi), 1)
|
||||
assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 1)
|
||||
|
||||
@@ -465,9 +465,8 @@ func TestMultipath(t *testing.T) {
|
||||
path4 := ProcessMessage(updateMsg, peer3, time.Now())[0]
|
||||
d.AddNewPath(path4)
|
||||
|
||||
best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
assert.Equal(t, len(best), 1)
|
||||
assert.Equal(t, len(w), 0)
|
||||
assert.Equal(t, len(multi), 1)
|
||||
assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2)
|
||||
|
||||
@@ -482,9 +481,8 @@ func TestMultipath(t *testing.T) {
|
||||
path5 := ProcessMessage(updateMsg, peer2, time.Now())[0]
|
||||
d.AddNewPath(path5)
|
||||
|
||||
best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME})
|
||||
assert.Equal(t, len(best), 1)
|
||||
assert.Equal(t, len(w), 0)
|
||||
assert.Equal(t, len(multi), 2)
|
||||
assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 3)
|
||||
|
||||
|
||||
@@ -185,9 +185,9 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) {
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func (manager *TableManager) calculate(ids []string, destinations []*Destination) (map[string][]*Path, []*Path, [][]*Path) {
|
||||
withdrawn := make([]*Path, 0, len(destinations))
|
||||
func (manager *TableManager) calculate(ids []string, destinations []*Destination) (map[string][]*Path, map[string][]*Path, [][]*Path) {
|
||||
best := make(map[string][]*Path, len(ids))
|
||||
old := make(map[string][]*Path, len(ids))
|
||||
|
||||
emptyDsts := make([]*Destination, 0, len(destinations))
|
||||
var multi [][]*Path
|
||||
@@ -200,11 +200,11 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination
|
||||
"Topic": "table",
|
||||
"Key": dst.GetNlri().String(),
|
||||
}).Debug("Processing destination")
|
||||
paths, w, m := dst.Calculate(ids)
|
||||
paths, olds, m := dst.Calculate(ids)
|
||||
for id, path := range paths {
|
||||
best[id] = append(best[id], path)
|
||||
old[id] = append(old[id], olds[id])
|
||||
}
|
||||
withdrawn = append(withdrawn, w...)
|
||||
if m != nil {
|
||||
multi = append(multi, m)
|
||||
}
|
||||
@@ -218,10 +218,10 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination
|
||||
t := manager.Tables[dst.Family()]
|
||||
t.deleteDest(dst)
|
||||
}
|
||||
return best, withdrawn, multi
|
||||
return best, old, multi
|
||||
}
|
||||
|
||||
func (manager *TableManager) DeletePathsByPeer(ids []string, info *PeerInfo, rf bgp.RouteFamily) (map[string][]*Path, []*Path, [][]*Path) {
|
||||
func (manager *TableManager) DeletePathsByPeer(ids []string, info *PeerInfo, rf bgp.RouteFamily) (map[string][]*Path, map[string][]*Path, [][]*Path) {
|
||||
if t, ok := manager.Tables[rf]; ok {
|
||||
dsts := t.DeleteDestByPeer(info)
|
||||
return manager.calculate(ids, dsts)
|
||||
@@ -229,7 +229,7 @@ func (manager *TableManager) DeletePathsByPeer(ids []string, info *PeerInfo, rf
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[string][]*Path, []*Path, [][]*Path) {
|
||||
func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[string][]*Path, map[string][]*Path, [][]*Path) {
|
||||
m := make(map[string]bool, len(pathList))
|
||||
dsts := make([]*Destination, 0, len(pathList))
|
||||
for _, path := range pathList {
|
||||
|
||||
Reference in New Issue
Block a user