summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-01-07 01:02:52 -0800
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-01-07 01:02:52 -0800
commit4bd5611c10bd668622f2dd1f7ad7cd72e889fcf4 (patch)
tree1386ed0775fb8d76d3a52455dbfc2e6202b9dd0d
parentbdbb80e9a6eb2928f4942b432dba0fb0595fc658 (diff)
table: fix UpdatePathAttrs2ByteAS
Fix the bug that UpdatePathAttrs2ByteAS modifies the _ORIGINAL_ path attributes in rib. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--packet/bgp.go14
-rw-r--r--server/peer_test.go95
-rw-r--r--table/message.go29
3 files changed, 120 insertions, 18 deletions
diff --git a/packet/bgp.go b/packet/bgp.go
index 32690745..2d84d6a3 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -1954,6 +1954,20 @@ func (p *PathAttributeAs4Path) Serialize() ([]byte, error) {
return p.PathAttribute.Serialize()
}
+func (p *PathAttributeAs4Path) MarshalJSON() ([]byte, error) {
+ aslist := make([]uint32, 0)
+ for _, a := range p.Value {
+ aslist = append(aslist, a.AS...)
+ }
+ return json.Marshal(struct {
+ Type string
+ AsPath []uint32
+ }{
+ Type: p.Type.String(),
+ AsPath: aslist,
+ })
+}
+
func NewPathAttributeAs4Path(value []*As4PathParam) *PathAttributeAs4Path {
return &PathAttributeAs4Path{
PathAttribute: PathAttribute{
diff --git a/server/peer_test.go b/server/peer_test.go
new file mode 100644
index 00000000..eaea842a
--- /dev/null
+++ b/server/peer_test.go
@@ -0,0 +1,95 @@
+// Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+// implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package server
+
+import (
+ "fmt"
+ //"encoding/json"
+ "github.com/osrg/gobgp/packet"
+ "github.com/osrg/gobgp/table"
+ "github.com/stretchr/testify/assert"
+ "net"
+ "reflect"
+ "testing"
+)
+
+func peerRC3() *table.PeerInfo {
+ peer := &table.PeerInfo{
+ AS: 66003,
+ ID: net.ParseIP("10.0.255.3").To4(),
+ LocalID: net.ParseIP("10.0.255.1").To4(),
+ }
+ return peer
+}
+
+func createAsPathAttribute(ases []uint32) *bgp.PathAttributeAsPath {
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, ases)}
+ aspath := bgp.NewPathAttributeAsPath(aspathParam)
+ return aspath
+}
+
+func createMpReach(nexthop string, prefix []bgp.AddrPrefixInterface) *bgp.PathAttributeMpReachNLRI {
+ mp_reach := bgp.NewPathAttributeMpReachNLRI(nexthop, prefix)
+ return mp_reach
+}
+
+func update_fromRC3() *bgp.BGPMessage {
+ pathAttributes := []bgp.PathAttributeInterface{
+ bgp.NewPathAttributeOrigin(1),
+ createAsPathAttribute([]uint32{66003, 4000, 70000}),
+ createMpReach("2001:db8::3",
+ []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "38:38:38:38::")}),
+ }
+ return bgp.NewBGPUpdateMessage([]bgp.WithdrawnRoute{}, pathAttributes, []bgp.NLRInfo{})
+}
+
+func TestProcessBGPUpdate_fourbyteAS(t *testing.T) {
+ rib1 := table.NewTableManager()
+
+ m := update_fromRC3()
+ peerInfo := peerRC3()
+ msg := table.NewProcessMessage(m, peerInfo)
+ pathList := msg.ToPathList()
+
+ pList, wList, _ := rib1.ProcessPaths(pathList)
+ assert.Equal(t, len(pList), 1)
+ assert.Equal(t, len(wList), 0)
+ fmt.Println(pList)
+ sendMsg := table.CreateUpdateMsgFromPaths(pList)
+ assert.Equal(t, len(sendMsg), 1)
+ table.UpdatePathAttrs2ByteAs(sendMsg[0].Body.(*bgp.BGPUpdate))
+ update := sendMsg[0].Body.(*bgp.BGPUpdate)
+ assert.Equal(t, len(update.PathAttributes), 4)
+ assert.Equal(t, reflect.TypeOf(update.PathAttributes[3]).String(), "*bgp.PathAttributeAs4Path")
+ attr := update.PathAttributes[3].(*bgp.PathAttributeAs4Path)
+ assert.Equal(t, len(attr.Value), 1)
+ assert.Equal(t, attr.Value[0].AS, []uint32{66003, 70000})
+ attrAS := update.PathAttributes[1].(*bgp.PathAttributeAsPath)
+ assert.Equal(t, len(attrAS.Value), 1)
+ assert.Equal(t, attrAS.Value[0].(*bgp.AsPathParam).AS, []uint16{bgp.AS_TRANS, 4000, bgp.AS_TRANS})
+
+ rib2 := table.NewTableManager()
+ pList2, wList2, _ := rib2.ProcessPaths(pathList)
+ assert.Equal(t, len(pList2), 1)
+ assert.Equal(t, len(wList2), 0)
+ sendMsg2 := table.CreateUpdateMsgFromPaths(pList2)
+ assert.Equal(t, len(sendMsg2), 1)
+ update2 := sendMsg2[0].Body.(*bgp.BGPUpdate)
+ assert.Equal(t, len(update2.PathAttributes), 3)
+ attrAS2 := update2.PathAttributes[1].(*bgp.PathAttributeAsPath)
+ assert.Equal(t, len(attrAS2.Value), 1)
+ assert.Equal(t, attrAS2.Value[0].(*bgp.As4PathParam).AS, []uint32{66003, 4000, 70000})
+}
diff --git a/table/message.go b/table/message.go
index 4539834b..acd6a256 100644
--- a/table/message.go
+++ b/table/message.go
@@ -18,7 +18,6 @@ package table
import (
"bytes"
"github.com/osrg/gobgp/packet"
- "reflect"
)
func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
@@ -35,15 +34,13 @@ func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
if asAttr == nil {
return nil
}
- msg.PathAttributes = clonePathAttributes(msg.PathAttributes)
- asAttr = msg.PathAttributes[idx].(*bgp.PathAttributeAsPath)
+ msg.PathAttributes = cloneAttrSlice(msg.PathAttributes)
+ asAttr = msg.PathAttributes[idx].(*bgp.PathAttributeAsPath)
as4pathParam := make([]*bgp.As4PathParam, 0)
+ newASparams := make([]bgp.AsPathParamInterface, len(asAttr.Value))
for i, param := range asAttr.Value {
- asParam, y := param.(*bgp.As4PathParam)
- if !y {
- continue
- }
+ asParam := param.(*bgp.As4PathParam)
newAs := make([]uint32, 0)
oldAs := make([]uint16, len(asParam.AS))
@@ -55,11 +52,13 @@ func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
oldAs[j] = uint16(asParam.AS[j])
}
}
- asAttr.Value[i] = bgp.NewAsPathParam(asParam.Type, oldAs)
+
+ newASparams[i] = bgp.NewAsPathParam(asParam.Type, oldAs)
if len(newAs) > 0 {
as4pathParam = append(as4pathParam, bgp.NewAs4PathParam(asParam.Type, newAs))
}
}
+ msg.PathAttributes[idx] = bgp.NewPathAttributeAsPath(newASparams)
if len(as4pathParam) > 0 {
msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Path(as4pathParam))
}
@@ -122,15 +121,9 @@ func UpdatePathAttrs4ByteAs(msg *bgp.BGPUpdate) error {
return nil
}
-func clonePathAttributes(attrs []bgp.PathAttributeInterface) []bgp.PathAttributeInterface {
- clonedAttrs := []bgp.PathAttributeInterface(nil)
+func cloneAttrSlice(attrs []bgp.PathAttributeInterface) []bgp.PathAttributeInterface {
+ clonedAttrs := make([]bgp.PathAttributeInterface, 0)
clonedAttrs = append(clonedAttrs, attrs...)
- for i, attr := range clonedAttrs {
- t, v := reflect.TypeOf(attr), reflect.ValueOf(attr)
- newAttrObjp := reflect.New(t.Elem())
- newAttrObjp.Elem().Set(v.Elem())
- clonedAttrs[i] = newAttrObjp.Interface().(bgp.PathAttributeInterface)
- }
return clonedAttrs
}
@@ -165,7 +158,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage {
unreach := u.PathAttributes[idx].(*bgp.PathAttributeMpUnreachNLRI)
unreach.Value = append(unreach.Value, path.getNlri())
} else {
- clonedAttrs := clonePathAttributes(path.getPathAttrs())
+ clonedAttrs := cloneAttrSlice(path.getPathAttrs())
idx, attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
reach := attr.(*bgp.PathAttributeMpReachNLRI)
clonedAttrs[idx] = bgp.NewPathAttributeMpUnreachNLRI(reach.Value)
@@ -181,7 +174,7 @@ func createUpdateMsgFromPath(path Path, msg *bgp.BGPMessage) *bgp.BGPMessage {
// we don't need to clone here but we
// might merge path to this message in
// the future so let's clone anyway.
- clonedAttrs := clonePathAttributes(path.getPathAttrs())
+ clonedAttrs := cloneAttrSlice(path.getPathAttrs())
return bgp.NewBGPUpdateMessage([]bgp.WithdrawnRoute{}, clonedAttrs, []bgp.NLRInfo{})
}
}