diff options
-rw-r--r-- | table/destination.go | 3 | ||||
-rw-r--r-- | table/path.go | 10 | ||||
-rw-r--r-- | table/table_manager.go | 8 | ||||
-rw-r--r-- | table/table_manager_test.go | 55 |
4 files changed, 72 insertions, 4 deletions
diff --git a/table/destination.go b/table/destination.go index 865ab03e..b35d380a 100644 --- a/table/destination.go +++ b/table/destination.go @@ -368,6 +368,9 @@ func (dest *DestinationDefault) removeOldPaths() { // paths and when doing RouteRefresh (not EnhancedRouteRefresh) // we get same paths again. if newPath.getSource() == path.getSource() { + if reflect.DeepEqual(newPath.getPathAttrs(), path.getPathAttrs()) { + newPath.setTimestamp(path.getTimestamp()) + } oldPaths = append(oldPaths, path) break } diff --git a/table/path.go b/table/path.go index 2916be1d..391e3298 100644 --- a/table/path.go +++ b/table/path.go @@ -41,6 +41,8 @@ type Path interface { setMedSetByTargetNeighbor(medSetByTargetNeighbor bool) getMedSetByTargetNeighbor() bool clone(IsWithdraw bool) Path + getTimestamp() time.Time + setTimestamp(t time.Time) MarshalJSON() ([]byte, error) } @@ -74,6 +76,14 @@ func NewPathDefault(rf bgp.RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInt return path } +func (pd *PathDefault) getTimestamp() time.Time { + return pd.timestamp +} + +func (pd *PathDefault) setTimestamp(t time.Time) { + pd.timestamp = t +} + func (pd *PathDefault) MarshalJSON() ([]byte, error) { return json.Marshal(struct { Network string diff --git a/table/table_manager.go b/table/table_manager.go index 9a6f6e7b..242b8ae2 100644 --- a/table/table_manager.go +++ b/table/table_manager.go @@ -296,8 +296,8 @@ func (adj *AdjRib) DropAllIn(rf bgp.RouteFamily) { } type ReceivedRoute struct { - path Path - filtered bool + path Path + filtered bool } func (rr *ReceivedRoute) String() string { @@ -307,8 +307,8 @@ func (rr *ReceivedRoute) String() string { func NewReceivedRoute(path Path, filtered bool) *ReceivedRoute { rroute := &ReceivedRoute{ - path: path, - filtered: filtered, + path: path, + filtered: filtered, } return rroute } diff --git a/table/table_manager_test.go b/table/table_manager_test.go index 47e4d4a7..f7c126bf 100644 --- a/table/table_manager_test.go +++ b/table/table_manager_test.go @@ -2184,6 +2184,61 @@ func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) { } +func TestProcessBGPUpdate_Timestamp(t *testing.T) { + tm := NewTableManager() + + origin := bgp.NewPathAttributeOrigin(0) + aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000})} + aspath := bgp.NewPathAttributeAsPath(aspathParam) + nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") + med := bgp.NewPathAttributeMultiExitDisc(0) + + pathAttributes := []bgp.PathAttributeInterface{ + origin, + aspath, + nexthop, + med, + } + + nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.10.0")} + withdrawnRoutes := []bgp.WithdrawnRoute{} + + bgpMessage1 := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + + peer := peerR1() + pList, wList, err := tm.ProcessUpdate(peer, bgpMessage1) + assert.Equal(t, len(pList), 1) + assert.Equal(t, len(wList), 0) + assert.NoError(t, err) + + path1 := pList[0].(*IPv4Path) + + bgpMessage2 := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) + pList, wList, err = tm.ProcessUpdate(peer, bgpMessage2) + assert.Equal(t, len(pList), 1) + assert.Equal(t, len(wList), 0) + + path2 := pList[0].(*IPv4Path) + + assert.Equal(t, path1.timestamp, path2.timestamp) + + med2 := bgp.NewPathAttributeMultiExitDisc(1) + pathAttributes2 := []bgp.PathAttributeInterface{ + origin, + aspath, + nexthop, + med2, + } + + bgpMessage3 := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes2, nlri) + pList, wList, err = tm.ProcessUpdate(peer, bgpMessage3) + assert.Equal(t, len(pList), 1) + assert.Equal(t, len(wList), 0) + + path3 := pList[0].(*IPv4Path) + assert.NotEqual(t, path2.timestamp, path3.timestamp) +} + func update_fromR1() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) |