diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-04-25 13:26:45 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2017-04-27 16:00:54 +0900 |
commit | aa5a11501251da31a542553c0abcb81d5857b924 (patch) | |
tree | bb1dca2a3f408211532532d664b36002ca8a8ffd /table | |
parent | 6faa02f93c91022420bd53631973a96ed5938f2a (diff) |
table: avoid cloning path for withdraw
when a peer having lots of routes goes down, the cloning paths consume
too much memory.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'table')
-rw-r--r-- | table/destination.go | 9 | ||||
-rw-r--r-- | table/destination_test.go | 28 | ||||
-rw-r--r-- | table/table_manager.go | 8 |
3 files changed, 26 insertions, 19 deletions
diff --git a/table/destination.go b/table/destination.go index 50d779df..2216abca 100644 --- a/table/destination.go +++ b/table/destination.go @@ -234,7 +234,7 @@ 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, map[string]*Path, []*Path) { +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 @@ -272,6 +272,13 @@ func (dest *Destination) Calculate(ids []string) (map[string]*Path, map[string]* if old == nil { return nil, nil } + if peerDown { + // withdraws were generated by peer + // down so paths are not in knowpath + // or adjin. + old.IsWithdraw = true + return old, old + } return old.Clone(true), old } return best, old diff --git a/table/destination_test.go b/table/destination_test.go index 7bcf6599..49c63e32 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -90,7 +90,7 @@ func TestCalculate(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate([]string{"1", "2"}) + d.Calculate([]string{"1", "2"}, false) assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 1) @@ -98,7 +98,7 @@ func TestCalculate(t *testing.T) { d.AddWithdraw(path1.Clone(true)) - d.Calculate([]string{"1", "2"}) + d.Calculate([]string{"1", "2"}, false) assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 0) @@ -122,7 +122,7 @@ func TestCalculate2(t *testing.T) { d := NewDestination(nlri) d.AddNewPath(path1) - d.Calculate(nil) + d.Calculate(nil, false) // suppose peer2 sends grammaatically correct but semantically flawed update message // which has a withdrawal nlri not advertised before @@ -132,7 +132,7 @@ func TestCalculate2(t *testing.T) { assert.Equal(t, path2.IsWithdraw, true) d.AddWithdraw(path2) - d.Calculate(nil) + d.Calculate(nil, false) // we have a path from peer1 here assert.Equal(t, len(d.knownPathList), 1) @@ -143,7 +143,7 @@ func TestCalculate2(t *testing.T) { assert.Equal(t, path3.IsWithdraw, false) d.AddNewPath(path3) - d.Calculate(nil) + d.Calculate(nil, false) // this time, we have paths from peer1 and peer2 assert.Equal(t, len(d.knownPathList), 2) @@ -154,7 +154,7 @@ func TestCalculate2(t *testing.T) { path4 := ProcessMessage(update4, peer3, time.Now())[0] d.AddNewPath(path4) - d.Calculate(nil) + d.Calculate(nil, false) // we must have paths from peer1, peer2 and peer3 assert.Equal(t, len(d.knownPathList), 3) @@ -188,7 +188,7 @@ func TestImplicitWithdrawCalculate(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate(nil) + d.Calculate(nil, false) assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) @@ -207,7 +207,7 @@ func TestImplicitWithdrawCalculate(t *testing.T) { path3.Filter("1", POLICY_DIRECTION_IMPORT) d.AddNewPath(path3) - d.Calculate(nil) + d.Calculate(nil, false) assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) @@ -292,7 +292,7 @@ func TestTimeTieBreaker(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate(nil) + d.Calculate(nil, false) 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 @@ -303,7 +303,7 @@ func TestTimeTieBreaker(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - d.Calculate(nil) + d.Calculate(nil, false) 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 @@ -438,7 +438,7 @@ func TestMultipath(t *testing.T) { d.AddNewPath(path1) d.AddNewPath(path2) - best, old, multi := d.Calculate([]string{GLOBAL_RIB_NAME}) + 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)) assert.Equal(t, len(multi), 2) @@ -446,7 +446,7 @@ func TestMultipath(t *testing.T) { path3 := path2.Clone(true) d.AddWithdraw(path3) - best, old, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) + best, old, multi = d.Calculate([]string{GLOBAL_RIB_NAME}, false) assert.Equal(t, len(best), 1) assert.Equal(t, old[GLOBAL_RIB_NAME], path1) assert.Equal(t, len(multi), 1) @@ -465,7 +465,7 @@ func TestMultipath(t *testing.T) { path4 := ProcessMessage(updateMsg, peer3, time.Now())[0] d.AddNewPath(path4) - best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) + best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME}, false) assert.Equal(t, len(best), 1) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) @@ -481,7 +481,7 @@ func TestMultipath(t *testing.T) { path5 := ProcessMessage(updateMsg, peer2, time.Now())[0] d.AddNewPath(path5) - best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) + best, _, multi = d.Calculate([]string{GLOBAL_RIB_NAME}, false) assert.Equal(t, len(best), 1) 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 32531056..3060dda0 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -185,7 +185,7 @@ func (manager *TableManager) DeleteVrf(name string) ([]*Path, error) { return msgs, nil } -func (manager *TableManager) calculate(ids []string, destinations []*Destination) (map[string][]*Path, map[string][]*Path, [][]*Path) { +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)) @@ -200,7 +200,7 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination "Topic": "table", "Key": dst.GetNlri().String(), }).Debug("Processing destination") - paths, olds, m := dst.Calculate(ids) + 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]) @@ -224,7 +224,7 @@ func (manager *TableManager) calculate(ids []string, destinations []*Destination 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) + return manager.calculate(ids, dsts, true) } return nil, nil, nil } @@ -255,7 +255,7 @@ func (manager *TableManager) ProcessPaths(ids []string, pathList []*Path) (map[s } } } - return manager.calculate(ids, dsts) + return manager.calculate(ids, dsts, false) } // EVPN MAC MOBILITY HANDLING |