summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-03-10 20:12:25 -0800
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2016-03-14 00:44:15 +0900
commit2ef757bc5f71d4131910d0973ffd7026cca73f9f (patch)
tree004801d58a78bcef11892bb144bff870ead7c291
parent7d68855c86daa8fa8202f5cbdf585d9d8c1d3d21 (diff)
table: remove Destination's oldKnownPathList
Withdrawn pathes are kept to be referenced thus the memory for them are not freed. Kill oldKnownPathList and Destination's NewFeed(). Destination's Calculate() returns the best paths. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--server/server.go60
-rw-r--r--table/destination.go62
-rw-r--r--table/table_manager.go22
-rw-r--r--table/table_manager_test.go5
4 files changed, 89 insertions, 60 deletions
diff --git a/server/server.go b/server/server.go
index ef10f1f6..336a2b0e 100644
--- a/server/server.go
+++ b/server/server.go
@@ -428,7 +428,7 @@ func (server *BgpServer) Serve() {
}
moded := server.RSimportPaths(peer, pathList)
if len(moded) > 0 {
- server.globalRib.ProcessPaths(moded)
+ server.globalRib.ProcessPaths(nil, moded)
}
}
server.neighborMap[addr] = peer
@@ -588,9 +588,21 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil
msgs := make([]*SenderMsg, 0)
options := &table.PolicyOptions{}
+ ids := make([]string, 0, len(server.neighborMap))
+ if peer.isRouteServerClient() {
+ 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 {
- dsts, withdrawn := server.globalRib.DeletePathsByPeer(peer.fsm.peerInfo, rf)
+ best, withdrawn := server.globalRib.DeletePathsByPeer(ids, peer.fsm.peerInfo, rf)
server.validatePaths(nil, withdrawn, true)
+
if peer.isRouteServerClient() {
for _, targetPeer := range server.neighborMap {
if !targetPeer.isRouteServerClient() || targetPeer == peer || targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED {
@@ -599,10 +611,10 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil
if _, ok := targetPeer.fsm.rfMap[rf]; !ok {
continue
}
- pathList := make([]*table.Path, 0, len(dsts))
+ pathList := make([]*table.Path, 0, len(best[targetPeer.TableID()]))
options.Neighbor = targetPeer.fsm.peerInfo.Address
- for _, dst := range dsts {
- if path := server.policy.ApplyPolicy(targetPeer.TableID(), table.POLICY_DIRECTION_EXPORT, filterpath(targetPeer, dst.NewFeed(targetPeer.TableID())), options); path != nil {
+ for _, bestPath := range best[targetPeer.TableID()] {
+ if path := server.policy.ApplyPolicy(targetPeer.TableID(), table.POLICY_DIRECTION_EXPORT, filterpath(targetPeer, bestPath), options); path != nil {
pathList = append(pathList, path)
}
}
@@ -611,9 +623,8 @@ func (server *BgpServer) dropPeerAllRoutes(peer *Peer, families []bgp.RouteFamil
targetPeer.adjRibOut.Update(pathList)
}
} else {
- sendPathList := make([]*table.Path, 0, len(dsts))
- for _, dst := range dsts {
- path := dst.NewFeed(table.GLOBAL_RIB_NAME)
+ sendPathList := make([]*table.Path, 0, len(best[table.GLOBAL_RIB_NAME]))
+ for _, path := range best[table.GLOBAL_RIB_NAME] {
if path != nil {
sendPathList = append(sendPathList, path)
}
@@ -874,16 +885,30 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) ([]
}
moded = append(moded, server.RSimportPaths(targetPeer, pathList)...)
}
- dsts, newly, withdrawn := rib.ProcessPaths(append(pathList, moded...))
+ isTarget := func(p *Peer) bool {
+ if !p.isRouteServerClient() || p.fsm.state != bgp.BGP_FSM_ESTABLISHED || p.fsm.pConf.GracefulRestart.State.LocalRestarting {
+ return false
+ }
+ return true
+ }
+
+ ids := make([]string, 0, len(server.neighborMap))
+ for _, targetPeer := range server.neighborMap {
+ if isTarget(targetPeer) {
+ ids = append(ids, targetPeer.TableID())
+ }
+ }
+ best, newly, withdrawn := rib.ProcessPaths(ids, append(pathList, moded...))
server.validatePaths(newly, withdrawn, false)
+
for _, targetPeer := range server.neighborMap {
- if !targetPeer.isRouteServerClient() || targetPeer.fsm.state != bgp.BGP_FSM_ESTABLISHED || targetPeer.fsm.pConf.GracefulRestart.State.LocalRestarting {
+ if !isTarget(targetPeer) {
continue
}
- sendPathList := make([]*table.Path, 0, len(dsts))
+ sendPathList := make([]*table.Path, 0, len(best[targetPeer.TableID()]))
options.Neighbor = targetPeer.fsm.peerInfo.Address
- for _, dst := range dsts {
- path := server.policy.ApplyPolicy(targetPeer.TableID(), table.POLICY_DIRECTION_EXPORT, filterpath(targetPeer, dst.NewFeed(targetPeer.TableID())), options)
+ for _, bestPath := range best[targetPeer.TableID()] {
+ path := server.policy.ApplyPolicy(targetPeer.TableID(), table.POLICY_DIRECTION_EXPORT, filterpath(targetPeer, bestPath), options)
if path != nil {
sendPathList = append(sendPathList, path)
}
@@ -897,14 +922,13 @@ func (server *BgpServer) propagateUpdate(peer *Peer, pathList []*table.Path) ([]
pathList[idx] = server.policy.ApplyPolicy(table.GLOBAL_RIB_NAME, table.POLICY_DIRECTION_IMPORT, path, nil)
}
alteredPathList = pathList
- dsts, newly, withdrawn := rib.ProcessPaths(pathList)
+ best, newly, withdrawn := rib.ProcessPaths([]string{table.GLOBAL_RIB_NAME}, pathList)
server.validatePaths(newly, withdrawn, false)
- sendPathList := make([]*table.Path, 0, len(dsts))
+ sendPathList := make([]*table.Path, 0, len(best[table.GLOBAL_RIB_NAME]))
if server.bgpConfig.Global.Collector.Enabled {
sendPathList = pathList
} else {
- for _, dst := range dsts {
- path := dst.NewFeed(table.GLOBAL_RIB_NAME)
+ for _, path := range best[table.GLOBAL_RIB_NAME] {
if path != nil {
sendPathList = append(sendPathList, path)
}
@@ -2400,7 +2424,7 @@ func (server *BgpServer) handleGrpcModNeighbor(grpcReq *GrpcRequest) (sMsgs []*S
}
moded := server.RSimportPaths(peer, pathList)
if len(moded) > 0 {
- server.globalRib.ProcessPaths(moded)
+ server.globalRib.ProcessPaths(nil, moded)
}
}
server.neighborMap[addr] = peer
diff --git a/table/destination.go b/table/destination.go
index 31072561..8f9676b1 100644
--- a/table/destination.go
+++ b/table/destination.go
@@ -111,13 +111,12 @@ func NewPeerInfo(g *config.Global, p *config.Neighbor) *PeerInfo {
}
type Destination struct {
- routeFamily bgp.RouteFamily
- nlri bgp.AddrPrefixInterface
- oldKnownPathList paths
- knownPathList paths
- withdrawList paths
- newPathList paths
- RadixKey string
+ routeFamily bgp.RouteFamily
+ nlri bgp.AddrPrefixInterface
+ knownPathList paths
+ withdrawList paths
+ newPathList paths
+ RadixKey string
}
func NewDestination(nlri bgp.AddrPrefixInterface) *Destination {
@@ -201,15 +200,6 @@ func (dd *Destination) GetBestPath(id string) *Path {
return nil
}
-func (dd *Destination) oldBest(id string) *Path {
- for _, p := range dd.oldKnownPathList {
- if p.Filtered(id) == POLICY_DIRECTION_NONE {
- return p
- }
- }
- return nil
-}
-
func (dd *Destination) addWithdraw(withdraw *Path) {
dd.validatePath(withdraw)
dd.withdrawList = append(dd.withdrawList, withdraw)
@@ -236,8 +226,9 @@ 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() ([]*Path, []*Path) {
- dest.oldKnownPathList = dest.knownPathList
+func (dest *Destination) Calculate(ids []string) (map[string]*Path, []*Path, []*Path) {
+ best := make(map[string]*Path, len(ids))
+ oldKnownPathList := dest.knownPathList
updated := dest.newPathList
// First remove the withdrawn paths.
withdrawnList := dest.explicitWithdraw()
@@ -249,22 +240,33 @@ func (dest *Destination) Calculate() ([]*Path, []*Path) {
dest.newPathList = make([]*Path, 0)
// Compute new best path
dest.computeKnownBestPath()
- return updated, withdrawnList
-}
-func (dest *Destination) NewFeed(id string) *Path {
- old := dest.oldBest(id)
- best := dest.GetBestPath(id)
- if best != nil && best.Equal(old) {
- return nil
- }
- if best == nil {
- if old == nil {
+ 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) {
return nil
}
- return old.Clone(true)
+ if best == nil {
+ if old == nil {
+ return nil
+ }
+ return old.Clone(true)
+ }
+ return best
+ }
+
+ for _, id := range ids {
+ best[id] = f(id)
}
- return best
+ return best, updated, withdrawnList
}
// Removes withdrawn paths.
diff --git a/table/table_manager.go b/table/table_manager.go
index f908bd69..8eeff459 100644
--- a/table/table_manager.go
+++ b/table/table_manager.go
@@ -216,32 +216,37 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) {
return msgs, nil
}
-func (manager *TableManager) calculate(destinations []*Destination) ([]*Path, []*Path) {
+func (manager *TableManager) calculate(ids []string, destinations []*Destination) (map[string][]*Path, []*Path, []*Path) {
newly := make([]*Path, 0, len(destinations))
withdrawn := make([]*Path, 0, len(destinations))
+ best := make(map[string][]*Path, len(ids))
+
for _, destination := range destinations {
log.WithFields(log.Fields{
"Topic": "table",
"Key": destination.GetNlri().String(),
}).Debug("Processing destination")
- n, w := destination.Calculate()
+ paths, n, w := destination.Calculate(ids)
+ for id, path := range paths {
+ best[id] = append(best[id], path)
+ }
newly = append(newly, n...)
withdrawn = append(withdrawn, w...)
}
- return newly, withdrawn
+ return best, newly, withdrawn
}
-func (manager *TableManager) DeletePathsByPeer(info *PeerInfo, rf bgp.RouteFamily) ([]*Destination, []*Path) {
+func (manager *TableManager) DeletePathsByPeer(ids []string, info *PeerInfo, rf bgp.RouteFamily) (map[string][]*Path, []*Path) {
if t, ok := manager.Tables[rf]; ok {
dsts := t.DeleteDestByPeer(info)
// no newly added paths
- _, withdrawn := manager.calculate(dsts)
- return dsts, withdrawn
+ best, _, withdrawn := manager.calculate(ids, dsts)
+ return best, withdrawn
}
return nil, nil
}
-func (manager *TableManager) ProcessPaths(pathList []*Path) ([]*Destination, []*Path, []*Path) {
+func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[string][]*Path, []*Path, []*Path) {
m := make(map[string]bool, len(pathList))
dsts := make([]*Destination, 0, len(pathList))
for _, path := range pathList {
@@ -267,8 +272,7 @@ func (manager *TableManager) ProcessPaths(pathList []*Path) ([]*Destination, []*
}
}
}
- newly, withdrawn := manager.calculate(dsts)
- return dsts, newly, withdrawn
+ return manager.calculate(ids, dsts)
}
// EVPN MAC MOBILITY HANDLING
diff --git a/table/table_manager_test.go b/table/table_manager_test.go
index becf69a1..4732d3a3 100644
--- a/table/table_manager_test.go
+++ b/table/table_manager_test.go
@@ -30,10 +30,9 @@ import (
// this function processes only BGPUpdate
func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) {
paths := ProcessMessage(message, fromPeer, time.Now())
- dsts, _, _ := manager.ProcessPaths(paths)
+ best, _, _ := manager.ProcessPaths([]string{GLOBAL_RIB_NAME}, paths)
paths2 := make([]*Path, 0, len(paths))
- for _, dst := range dsts {
- p := dst.NewFeed(GLOBAL_RIB_NAME)
+ for _, p := range best[GLOBAL_RIB_NAME] {
if p != nil {
paths2 = append(paths2, p)
}