diff options
-rw-r--r-- | table/path.go | 32 | ||||
-rw-r--r-- | table/table_manager_test.go | 32 |
2 files changed, 45 insertions, 19 deletions
diff --git a/table/path.go b/table/path.go index e7536f22..846c7e16 100644 --- a/table/path.go +++ b/table/path.go @@ -18,7 +18,6 @@ package table import ( "fmt" "github.com/osrg/gobgp/packet" - //"github.com/osrg/gobgp/utils" "net" "reflect" ) @@ -27,7 +26,6 @@ type Path interface { String() string GetPathAttrs() []bgp.PathAttributeInterface GetPathAttr(int) (int, bgp.PathAttributeInterface) - // clone(forWithdrawal bool) Path getRouteFamily() RouteFamily setSource(source *PeerInfo) getSource() *PeerInfo @@ -41,6 +39,7 @@ type Path interface { getPrefix() net.IP setMedSetByTargetNeighbor(medSetByTargetNeighbor bool) getMedSetByTargetNeighbor() bool + Clone() Path } type PathDefault struct { @@ -74,6 +73,18 @@ func NewPathDefault(rf RouteFamily, source *PeerInfo, nlri bgp.AddrPrefixInterfa return path } +// create new PathAttributes +func (pd *PathDefault) Clone() Path { + copiedAttrs := append([]bgp.PathAttributeInterface(nil), pd.pathAttrs...) + for i, attr := range copiedAttrs { + t, v := reflect.TypeOf(attr), reflect.ValueOf(attr) + newAttrObjp := reflect.New(t.Elem()) + newAttrObjp.Elem().Set(v.Elem()) + copiedAttrs[i] = newAttrObjp.Interface().(bgp.PathAttributeInterface) + } + return CreatePath(pd.source, pd.nlri, copiedAttrs, pd.withdraw) +} + func (pd *PathDefault) getRouteFamily() RouteFamily { return pd.routeFamily } @@ -152,23 +163,6 @@ func (pd *PathDefault) GetPathAttr(pattrType int) (int, bgp.PathAttributeInterfa return -1, nil } -// func (pi *PathDefault) clone(forWithdrawal bool) Path { -// pathAttrs := utils.NewOrderedMap() -// if !forWithdrawal { -// pathAttrs = pi.getPathAttributeMap() -// } -// def := NewPathDefault(pi.getRouteFamily(), pi.getSource(), pi.GetNlri(), pi.getSourceVerNum(), -// pi.getNexthop(), forWithdrawal, pathAttrs, pi.getMedSetByTargetNeighbor()) -// switch pi.getRouteFamily() { -// case RF_IPv4_UC: -// return &IPv4Path{PathDefault: def} -// case RF_IPv6_UC: -// return &IPv6Path{PathDefault: def} -// default: -// return def -// } -//} - // return Path's string representation func (pi *PathDefault) String() string { str := fmt.Sprintf("IPv4Path Source: %d, ", pi.getSourceVerNum()) diff --git a/table/table_manager_test.go b/table/table_manager_test.go index c0abcd84..c9d6e22a 100644 --- a/table/table_manager_test.go +++ b/table/table_manager_test.go @@ -2239,6 +2239,38 @@ func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) { } +func TestModifyPathAttribute(t *testing.T) { + tm := NewTableManager() + + bgpMessage := update_fromR1() + peer := peerR1() + pList, wList, err := tm.ProcessUpdate(peer, bgpMessage) + assert.Equal(t, len(pList), 1) + assert.Equal(t, len(wList), 0) + assert.NoError(t, err) + + path0 := pList[0] + path1 := path0.Clone() + + _, attr1 := path1.GetPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) + mx1 := attr1.(*bgp.PathAttributeMultiExitDisc) + original := mx1.Value + mx1.Value++ + + table := tm.Tables[RF_IPv4_UC] + dest := table.getDestination(table.tableKey(path0.GetNlri()).String()).(*IPv4Destination) + path2 := dest.getKnownPathList() + _, attr2 := path2[0].GetPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) + mx2 := attr2.(*bgp.PathAttributeMultiExitDisc) + assert.Equal(t, original, mx2.Value) + + path3 := path0 + _, attr3 := path3.GetPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC) + mx3 := attr3.(*bgp.PathAttributeMultiExitDisc) + mx3.Value++ + assert.Equal(t, mx2.Value, mx3.Value) +} + func update_fromR1() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) |