diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-05-24 07:17:04 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2018-05-24 08:08:17 +0900 |
commit | bbd98ee21154f832896c7a39468eeb50edd0e527 (patch) | |
tree | 1655e6aa008001732498cdff403ef7f4017f097d | |
parent | 87245b488bedca33b766ccd967636946416587cc (diff) |
fix withdraw with addpath and rtc enabled
Needs withdrawn paths that includes attributes. The attributes are
necessary because they are used with rtc table to check if the paths
were sent.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | server/server.go | 12 | ||||
-rw-r--r-- | table/destination.go | 23 | ||||
-rw-r--r-- | table/destination_test.go | 18 |
3 files changed, 52 insertions, 1 deletions
diff --git a/server/server.go b/server/server.go index d86e51df..f1aafe94 100644 --- a/server/server.go +++ b/server/server.go @@ -988,7 +988,17 @@ func (server *BgpServer) propagateUpdateToNeighbors(source *Peer, newPath *table return family }() if targetPeer.isAddPathSendEnabled(f) { - bestList = []*table.Path{newPath} + if newPath.IsWithdraw { + bestList = func() []*table.Path { + l := make([]*table.Path, 0, len(dsts)) + for _, d := range dsts { + l = append(l, d.GetWithdrawnPath()...) + } + return l + }() + } else { + bestList = []*table.Path{newPath} + } oldList = nil } else if targetPeer.isRouteServerClient() { bestList, oldList, _ = dstsToPaths(targetPeer.TableID(), targetPeer.AS(), dsts) diff --git a/table/destination.go b/table/destination.go index adf1c0cd..a37d2114 100644 --- a/table/destination.go +++ b/table/destination.go @@ -558,6 +558,29 @@ func getMultiBestPath(id string, pathList []*Path) []*Path { return list } +func (u *Update) GetWithdrawnPath() []*Path { + if len(u.KnownPathList) == len(u.OldKnownPathList) { + return nil + } + + l := make([]*Path, 0, len(u.OldKnownPathList)) + + for _, p := range u.OldKnownPathList { + y := func() bool { + for _, old := range u.KnownPathList { + if p == old { + return true + } + } + return false + }() + if !y { + l = append(l, p.Clone(true)) + } + } + return l +} + func (u *Update) GetChanges(id string, as uint32, peerDown bool) (*Path, *Path, []*Path) { best, old := func(id string) (*Path, *Path) { old := getBestPath(id, as, u.OldKnownPathList) diff --git a/table/destination_test.go b/table/destination_test.go index 0934057a..b5a42007 100644 --- a/table/destination_test.go +++ b/table/destination_test.go @@ -421,3 +421,21 @@ func TestIdMap(t *testing.T) { _, err := d.localIdMap.FindandSetZeroBit() assert.NotNil(t, err) } + +func TestGetWithdrawnPath(t *testing.T) { + attrs := []bgp.PathAttributeInterface{ + bgp.NewPathAttributeOrigin(0), + } + p1 := NewPath(nil, bgp.NewIPAddrPrefix(24, "13.2.3.0"), false, attrs, time.Now(), false) + p2 := NewPath(nil, bgp.NewIPAddrPrefix(24, "13.2.4.0"), false, attrs, time.Now(), false) + p3 := NewPath(nil, bgp.NewIPAddrPrefix(24, "13.2.5.0"), false, attrs, time.Now(), false) + + u := &Update{ + KnownPathList: []*Path{p2}, + OldKnownPathList: []*Path{p1, p2, p3}, + } + + l := u.GetWithdrawnPath() + assert.Equal(t, len(l), 2) + assert.Equal(t, l[0].GetNlri(), p1.GetNlri()) +} |