summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--table/path.go32
-rw-r--r--table/table_manager_test.go32
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)