diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-01-07 01:02:52 -0800 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-01-07 01:02:52 -0800 |
commit | 4bd5611c10bd668622f2dd1f7ad7cd72e889fcf4 (patch) | |
tree | 1386ed0775fb8d76d3a52455dbfc2e6202b9dd0d | |
parent | bdbb80e9a6eb2928f4942b432dba0fb0595fc658 (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.go | 14 | ||||
-rw-r--r-- | server/peer_test.go | 95 | ||||
-rw-r--r-- | table/message.go | 29 |
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{}) } } |