summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-12-30 21:04:01 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-12-30 21:04:01 +0900
commitde9a26d9f36ebd9c918c3f7c88764093a54152dc (patch)
tree9b54677b50b30b04b750677b074b86b86ef243c7
parent7e7b78e775bb40e0998418c5c294ed2668e3ea1a (diff)
table: add helper functions to modify PathAttributes for 4 and 2 byte AS.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--table/message.go109
-rw-r--r--table/message_test.go142
2 files changed, 251 insertions, 0 deletions
diff --git a/table/message.go b/table/message.go
new file mode 100644
index 00000000..35eb501a
--- /dev/null
+++ b/table/message.go
@@ -0,0 +1,109 @@
+// 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 table
+
+import (
+ "github.com/osrg/gobgp/packet"
+)
+
+func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error {
+ var asAttr *bgp.PathAttributeAsPath
+ for _, attr := range msg.PathAttributes {
+ switch attr.(type) {
+ case *bgp.PathAttributeAsPath:
+ asAttr = attr.(*bgp.PathAttributeAsPath)
+ }
+ }
+
+ as4pathParam := make([]*bgp.As4PathParam, 0)
+ for i, param := range asAttr.Value {
+ asParam, y := param.(*bgp.As4PathParam)
+ if !y {
+ continue
+ }
+
+ newAs := make([]uint32, 0)
+ oldAs := make([]uint16, len(asParam.AS))
+ for j := 0; j < len(asParam.AS); j++ {
+ if asParam.AS[j] > (1<<16)-1 {
+ oldAs[j] = bgp.AS_TRANS
+ newAs = append(newAs, asParam.AS[j])
+ } else {
+ oldAs[j] = uint16(asParam.AS[j])
+ }
+ }
+ asAttr.Value[i] = bgp.NewAsPathParam(asParam.Type, oldAs)
+ if len(newAs) > 0 {
+ as4pathParam = append(as4pathParam, bgp.NewAs4PathParam(asParam.Type, newAs))
+ }
+ }
+ if len(as4pathParam) > 0 {
+ msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Path(as4pathParam))
+ }
+ return nil
+}
+
+func UpdatePathAttrs4ByteAs(msg *bgp.BGPUpdate) error {
+ newPathAttrs := make([]bgp.PathAttributeInterface, 0)
+ var asAttr *bgp.PathAttributeAsPath
+ var as4Attr *bgp.PathAttributeAs4Path
+
+ for _, attr := range msg.PathAttributes {
+ switch attr.(type) {
+ case *bgp.PathAttributeAsPath:
+ asAttr = attr.(*bgp.PathAttributeAsPath)
+ newPathAttrs = append(newPathAttrs, attr)
+ case *bgp.PathAttributeAs4Path:
+ as4Attr = attr.(*bgp.PathAttributeAs4Path)
+ default:
+ newPathAttrs = append(newPathAttrs, attr)
+ }
+ }
+
+ AS := make([]uint32, 0)
+ if as4Attr != nil {
+ for _, p := range as4Attr.Value {
+ AS = append(AS, p.AS...)
+ }
+ msg.PathAttributes = newPathAttrs
+ }
+
+ transIdx := 0
+ for i, param := range asAttr.Value {
+ asParam, y := param.(*bgp.AsPathParam)
+ if !y {
+ continue
+ }
+
+ newAS := make([]uint32, len(asParam.AS))
+ for j := 0; j < len(asParam.AS); j++ {
+ if asParam.AS[j] == bgp.AS_TRANS {
+ if transIdx == len(AS) {
+ //return error
+ }
+ newAS[j] = AS[transIdx]
+ transIdx++
+ } else {
+ newAS[j] = uint32(asParam.AS[j])
+ }
+ }
+ asAttr.Value[i] = bgp.NewAs4PathParam(asParam.Type, newAS)
+ }
+ if len(AS) != transIdx {
+ //return error
+ }
+ return nil
+}
diff --git a/table/message_test.go b/table/message_test.go
new file mode 100644
index 00000000..ce29d899
--- /dev/null
+++ b/table/message_test.go
@@ -0,0 +1,142 @@
+// 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 table
+
+import (
+ "github.com/osrg/gobgp/packet"
+ "github.com/stretchr/testify/assert"
+ "reflect"
+ "testing"
+)
+
+func updateMsg1(as []uint16) *bgp.BGPMessage {
+ origin := bgp.NewPathAttributeOrigin(0)
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, as)}
+ aspath := bgp.NewPathAttributeAsPath(aspathParam)
+ nexthop := bgp.NewPathAttributeNextHop("192.168.50.1")
+ med := bgp.NewPathAttributeMultiExitDisc(0)
+
+ pathAttributes := []bgp.PathAttributeInterface{
+ origin,
+ aspath,
+ nexthop,
+ med,
+ }
+
+ nlri := []bgp.NLRInfo{*bgp.NewNLRInfo(24, "10.10.10.0")}
+ return bgp.NewBGPUpdateMessage([]bgp.WithdrawnRoute{}, pathAttributes, nlri)
+}
+
+func TestAs4PathNonAsTrans(t *testing.T) {
+ as := []uint16{65000, 4000, 40001}
+ m := updateMsg1(as).Body.(*bgp.BGPUpdate)
+ originalAsPath := m.PathAttributes[1]
+ UpdatePathAttrs4ByteAs(m)
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[0]).String(), "*bgp.PathAttributeOrigin")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[1]).String(), "*bgp.PathAttributeAsPath")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[2]).String(), "*bgp.PathAttributeNextHop")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[3]).String(), "*bgp.PathAttributeMultiExitDisc")
+
+ asAttr := m.PathAttributes[1].(*bgp.PathAttributeAsPath)
+ assert.Equal(t, len(asAttr.Value), 1)
+ for _, param := range asAttr.Value {
+ asParam := param.(*bgp.As4PathParam)
+ for i, v := range asParam.AS {
+ assert.Equal(t, v, as[i])
+ }
+ }
+ UpdatePathAttrs2ByteAs(m)
+ assert.Equal(t, m.PathAttributes[1], originalAsPath)
+}
+
+func TestAsPathAsTrans(t *testing.T) {
+ as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
+ m := updateMsg1(as).Body.(*bgp.BGPUpdate)
+
+ m.PathAttributes = append(m.PathAttributes, m.PathAttributes[3])
+ as4 := []uint32{400000, 300000}
+ aspathParam := []*bgp.As4PathParam{bgp.NewAs4PathParam(2, as4)}
+ m.PathAttributes[3] = bgp.NewPathAttributeAs4Path(aspathParam)
+ assert.Equal(t, len(m.PathAttributes), 5)
+
+ originalAsPath := m.PathAttributes[1]
+ originalAs4Path := m.PathAttributes[3]
+ UpdatePathAttrs4ByteAs(m)
+ assert.Equal(t, len(m.PathAttributes), 4)
+
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[0]).String(), "*bgp.PathAttributeOrigin")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[1]).String(), "*bgp.PathAttributeAsPath")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[2]).String(), "*bgp.PathAttributeNextHop")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[3]).String(), "*bgp.PathAttributeMultiExitDisc")
+
+ newAS := []uint32{65000, 4000, 400000, 300000, 40001}
+ asAttr := m.PathAttributes[1].(*bgp.PathAttributeAsPath)
+ assert.Equal(t, len(asAttr.Value), 1)
+ for _, param := range asAttr.Value {
+ asParam := param.(*bgp.As4PathParam)
+ for i, v := range asParam.AS {
+ assert.Equal(t, v, newAS[i])
+ }
+ }
+ UpdatePathAttrs2ByteAs(m)
+ assert.Equal(t, len(m.PathAttributes), 5)
+ assert.Equal(t, m.PathAttributes[1], originalAsPath)
+ assert.Equal(t, m.PathAttributes[4], originalAs4Path)
+}
+
+func TestAs4PathUnchanged(t *testing.T) {
+ as4 := []uint32{65000, 4000, 500000, 400010}
+ m := updateMsg1([]uint16{}).Body.(*bgp.BGPUpdate)
+ aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, as4)}
+ m.PathAttributes[1] = bgp.NewPathAttributeAsPath(aspathParam)
+ UpdatePathAttrs4ByteAs(m)
+ assert.Equal(t, len(m.PathAttributes), 4)
+
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[0]).String(), "*bgp.PathAttributeOrigin")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[1]).String(), "*bgp.PathAttributeAsPath")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[2]).String(), "*bgp.PathAttributeNextHop")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[3]).String(), "*bgp.PathAttributeMultiExitDisc")
+
+ asAttr := m.PathAttributes[1].(*bgp.PathAttributeAsPath)
+ assert.Equal(t, len(asAttr.Value), 1)
+ for _, param := range asAttr.Value {
+ asParam := param.(*bgp.As4PathParam)
+ for i, v := range asParam.AS {
+ assert.Equal(t, v, as4[i])
+ }
+ }
+}
+
+func TestAsPathUnchanged(t *testing.T) {
+ as := []uint16{65000, 4000, 5000, 4001}
+ m := updateMsg1(as).Body.(*bgp.BGPUpdate)
+ UpdatePathAttrs2ByteAs(m)
+ assert.Equal(t, len(m.PathAttributes), 4)
+
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[0]).String(), "*bgp.PathAttributeOrigin")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[1]).String(), "*bgp.PathAttributeAsPath")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[2]).String(), "*bgp.PathAttributeNextHop")
+ assert.Equal(t, reflect.TypeOf(m.PathAttributes[3]).String(), "*bgp.PathAttributeMultiExitDisc")
+
+ asAttr := m.PathAttributes[1].(*bgp.PathAttributeAsPath)
+ assert.Equal(t, len(asAttr.Value), 1)
+ for _, param := range asAttr.Value {
+ asParam := param.(*bgp.AsPathParam)
+ for i, v := range asParam.AS {
+ assert.Equal(t, v, as[i])
+ }
+ }
+}