diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-12-30 21:04:01 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-12-30 21:04:01 +0900 |
commit | de9a26d9f36ebd9c918c3f7c88764093a54152dc (patch) | |
tree | 9b54677b50b30b04b750677b074b86b86ef243c7 | |
parent | 7e7b78e775bb40e0998418c5c294ed2668e3ea1a (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.go | 109 | ||||
-rw-r--r-- | table/message_test.go | 142 |
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]) + } + } +} |