summaryrefslogtreecommitdiffhomepage
path: root/table
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-12-21 05:53:20 -0800
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-12-21 05:53:20 -0800
commit704135410381e69e2f39fea84cd029b65148da01 (patch)
tree26e5bc4f06edeef78e1670a9b654f257ba3c9fa1 /table
parent90b0bd64e0777f0023976f92d427920f9a6b5b21 (diff)
table: implement Clone() to copy pathattributes in Path struct
In some cases, we need to modify pathattributes in Path and creates an update message based on it. Clone() is used to avoid chaning the pathattributes in the table. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'table')
-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)