summaryrefslogtreecommitdiffhomepage
path: root/table
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-04-25 13:26:45 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-04-27 16:00:54 +0900
commitaa5a11501251da31a542553c0abcb81d5857b924 (patch)
treebb1dca2a3f408211532532d664b36002ca8a8ffd /table
parent6faa02f93c91022420bd53631973a96ed5938f2a (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.go9
-rw-r--r--table/destination_test.go28
-rw-r--r--table/table_manager.go8
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