diff options
-rw-r--r-- | table/message.go | 173 | ||||
-rw-r--r-- | table/message_test.go | 365 |
2 files changed, 417 insertions, 121 deletions
diff --git a/table/message.go b/table/message.go index ee31f18d..ad44a88f 100644 --- a/table/message.go +++ b/table/message.go @@ -17,6 +17,7 @@ package table import ( "bytes" + log "github.com/Sirupsen/logrus" "github.com/osrg/gobgp/packet" "hash/fnv" ) @@ -25,10 +26,10 @@ func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error { var asAttr *bgp.PathAttributeAsPath idx := 0 for i, attr := range msg.PathAttributes { - switch attr.(type) { - case *bgp.PathAttributeAsPath: - asAttr = attr.(*bgp.PathAttributeAsPath) + if a, ok := attr.(*bgp.PathAttributeAsPath); ok { + asAttr = a idx = i + break } } @@ -36,89 +37,161 @@ func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error { return nil } - 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 := param.(*bgp.As4PathParam) - - 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]) + as4Params := make([]*bgp.As4PathParam, 0, len(asAttr.Value)) + as2Params := make([]bgp.AsPathParamInterface, 0, len(asAttr.Value)) + mkAs4 := false + for _, param := range asAttr.Value { + as4Param := param.(*bgp.As4PathParam) + as2Path := make([]uint16, 0, len(as4Param.AS)) + for _, as := range as4Param.AS { + if as > (1<<16)-1 { + mkAs4 = true + as2Path = append(as2Path, bgp.AS_TRANS) } else { - oldAs[j] = uint16(asParam.AS[j]) + as2Path = append(as2Path, uint16(as)) } } + as2Params = append(as2Params, bgp.NewAsPathParam(as4Param.Type, as2Path)) - newASparams[i] = bgp.NewAsPathParam(asParam.Type, oldAs) - if len(newAs) > 0 { - as4pathParam = append(as4pathParam, bgp.NewAs4PathParam(asParam.Type, newAs)) + // RFC 6793 4.2.2 Generating Updates + // + // Whenever the AS path information contains the AS_CONFED_SEQUENCE or + // AS_CONFED_SET path segment, the NEW BGP speaker MUST exclude such + // path segments from the AS4_PATH attribute being constructed. + if as4Param.Type != bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ && as4Param.Type != bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET { + as4Params = append(as4Params, as4Param) } } - msg.PathAttributes[idx] = bgp.NewPathAttributeAsPath(newASparams) - if len(as4pathParam) > 0 { - msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Path(as4pathParam)) + msg.PathAttributes[idx] = bgp.NewPathAttributeAsPath(as2Params) + if mkAs4 { + msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Path(as4Params)) } 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 { + asAttrPos := 0 + as4AttrPos := 0 + for i, attr := range msg.PathAttributes { switch attr.(type) { case *bgp.PathAttributeAsPath: asAttr = attr.(*bgp.PathAttributeAsPath) - newPathAttrs = append(newPathAttrs, attr) + for j, param := range asAttr.Value { + as2Param, ok := param.(*bgp.AsPathParam) + if ok { + asPath := make([]uint32, 0, len(as2Param.AS)) + for _, as := range as2Param.AS { + asPath = append(asPath, uint32(as)) + } + as4Param := bgp.NewAs4PathParam(as2Param.Type, asPath) + asAttr.Value[j] = as4Param + } + } + asAttrPos = i + msg.PathAttributes[i] = asAttr case *bgp.PathAttributeAs4Path: + as4AttrPos = i as4Attr = attr.(*bgp.PathAttributeAs4Path) - default: - newPathAttrs = append(newPathAttrs, attr) } } - if asAttr == nil { + if as4Attr != nil { + msg.PathAttributes = append(msg.PathAttributes[:as4AttrPos], msg.PathAttributes[as4AttrPos+1:]...) + } + + if asAttr == nil || as4Attr == nil { return nil } - AS := make([]uint32, 0) + asLen := 0 + asConfedLen := 0 + asParams := make([]*bgp.As4PathParam, 0, len(asAttr.Value)) + for _, param := range asAttr.Value { + asLen += param.ASLen() + p := param.(*bgp.As4PathParam) + switch p.Type { + case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET: + asConfedLen += 1 + case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ: + asConfedLen += len(p.AS) + } + asParams = append(asParams, p) + } + + as4Len := 0 + as4Params := make([]*bgp.As4PathParam, 0, len(as4Attr.Value)) if as4Attr != nil { for _, p := range as4Attr.Value { - AS = append(AS, p.AS...) + // RFC 6793 6. Error Handling + // + // the path segment types AS_CONFED_SEQUENCE and AS_CONFED_SET [RFC5065] + // MUST NOT be carried in the AS4_PATH attribute of an UPDATE message. + // A NEW BGP speaker that receives these path segment types in the AS4_PATH + // attribute of an UPDATE message from an OLD BGP speaker MUST discard + // these path segments, adjust the relevant attribute fields accordingly, + // and continue processing the UPDATE message. + // This case SHOULD be logged locally for analysis. + switch p.Type { + case bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET: + typ := "CONFED_SEQ" + if p.Type == bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET { + typ = "CONFED_SET" + } + log.Warnf("AS4_PATH contains %s segment %s. ignore", typ, p.String()) + continue + } + as4Len += p.ASLen() + as4Params = append(as4Params, p) } - msg.PathAttributes = newPathAttrs } - transIdx := 0 - for i, param := range asAttr.Value { - asParam, y := param.(*bgp.AsPathParam) - if !y { - continue + if asLen+asConfedLen < as4Len { + log.Warnf("AS4_PATH is longer than AS_PATH. ignore AS4_PATH") + return nil + } + + keepNum := asLen + asConfedLen - as4Len + + newParams := make([]*bgp.As4PathParam, 0, len(asAttr.Value)) + for _, param := range asParams { + if keepNum-param.ASLen() >= 0 { + newParams = append(newParams, param) + keepNum -= param.ASLen() + } else { + // only SEQ param reaches here + param.AS = param.AS[:keepNum] + newParams = append(newParams, param) + keepNum = 0 } - 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++ + if keepNum <= 0 { + break + } + } + + for _, param := range as4Params { + lastParam := newParams[len(newParams)-1] + if param.Type == lastParam.Type && param.Type == bgp.BGP_ASPATH_ATTR_TYPE_SEQ { + if len(lastParam.AS)+len(param.AS) > 255 { + lastParam.AS = append(lastParam.AS, param.AS[:255-len(lastParam.AS)]...) + param.AS = param.AS[255-len(lastParam.AS):] + newParams = append(newParams, param) } else { - newAS[j] = uint32(asParam.AS[j]) + lastParam.AS = append(lastParam.AS, param.AS...) } + } else { + newParams = append(newParams, param) } - asAttr.Value[i] = bgp.NewAs4PathParam(asParam.Type, newAS) } - if len(AS) != transIdx { - //return error + + newIntfParams := make([]bgp.AsPathParamInterface, 0, len(asAttr.Value)) + for _, p := range newParams { + newIntfParams = append(newIntfParams, p) } + + msg.PathAttributes[asAttrPos] = bgp.NewPathAttributeAsPath(newIntfParams) return nil } diff --git a/table/message_test.go b/table/message_test.go index 5d1e50a9..1f559c0e 100644 --- a/table/message_test.go +++ b/table/message_test.go @@ -18,87 +18,310 @@ package table import ( "github.com/osrg/gobgp/packet" "github.com/stretchr/testify/assert" - "reflect" "testing" "time" ) -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, - } +// before: +// as-path : 65000, 4000, 400000, 300000, 40001 +// expected result: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : 65000, 4000, 400000, 300000, 40001 +func TestAsPathAs2Trans1(t *testing.T) { + as := []uint32{65000, 4000, 400000, 300000, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs2ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 2) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[0], uint16(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[1], uint16(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[2], uint16(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[3], uint16(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[4], uint16(40001)) + assert.Equal(t, len(msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value), 1) + assert.Equal(t, len(msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS), 5) + assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[2], uint32(400000)) + assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[3], uint32(300000)) + assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[4], uint32(40001)) +} - nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} - return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) +// before: +// as-path : 65000, 4000, 40000, 30000, 40001 +// expected result: +// as-path : 65000, 4000, 40000, 30000, 40001 +func TestAsPathAs2Trans2(t *testing.T) { + as := []uint32{65000, 4000, 40000, 30000, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs2ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[0], uint16(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[1], uint16(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[2], uint16(40000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[3], uint16(30000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[4], uint16(40001)) } -func TestAsPathAsTrans(t *testing.T) { +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : 400000, 300000, 40001 +// expected result: +// as-path : 65000, 4000, 400000, 300000, 40001 +func TestAsPathAs4Trans1(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) - - 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) - attr := m.PathAttributes[1].(*bgp.PathAttributeAsPath) - assert.Equal(t, len(attr.Value), 1) - assert.Equal(t, attr.Value[0].(*bgp.AsPathParam).AS, as) - attr2 := m.PathAttributes[4].(*bgp.PathAttributeAs4Path) - assert.Equal(t, len(attr2.Value), 1) - assert.Equal(t, attr2.Value[0].AS, as4) + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{400000, 300000, 40001} + param4s := []*bgp.As4PathParam{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(400000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(300000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001)) } -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]) - } - } +// before: +// as-path : 65000, 4000, {10, 20, 30}, 23456, 23456, 40001 +// as4-path : 400000, 300000, 40001 +// expected result: +// as-path : 65000, 4000, {10, 20, 30}, 400000, 300000, 40001 +func TestAsPathAs4Trans2(t *testing.T) { + as1 := []uint16{65000, 4000} + param1 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as1) + as2 := []uint16{10, 20, 30} + param2 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as2) + as3 := []uint16{bgp.AS_TRANS, bgp.AS_TRANS, 40001} + param3 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as3) + params := []bgp.AsPathParamInterface{param1, param2, param3} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{400000, 300000, 40001} + param4s := []*bgp.As4PathParam{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 3) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 2) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS), 3) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[0], uint32(10)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[1], uint32(20)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[2], uint32(30)) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS), 3) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[0], uint32(400000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[1], uint32(300000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[2], uint32(40001)) +} + +// before: +// as-path : 65000, 4000, {10, 20, 30}, 23456, 23456, 40001 +// as4-path : 3000, 400000, 300000, 40001 +// expected result: +// as-path : 65000, 4000, 3000, 400000, 300000, 40001 +func TestAsPathAs4Trans3(t *testing.T) { + as1 := []uint16{65000, 4000} + param1 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as1) + as2 := []uint16{10, 20, 30} + param2 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as2) + as3 := []uint16{bgp.AS_TRANS, bgp.AS_TRANS, 40001} + param3 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as3) + params := []bgp.AsPathParamInterface{param1, param2, param3} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{3000, 400000, 300000, 40001} + param4s := []*bgp.As4PathParam{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 6) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(3000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(400000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(300000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[5], uint32(40001)) +} + +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : 400000, 300000, 40001, {10, 20, 30} +// expected result: +// as-path : 65000, 400000, 300000, 40001, {10, 20, 30} +func TestAsPathAs4Trans4(t *testing.T) { + as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{400000, 300000, 40001} + as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4) + as5 := []uint32{10, 20, 30} + as4param2 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as5) + param4s := []*bgp.As4PathParam{as4param1, as4param2} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 2) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 4) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(400000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(300000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(40001)) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS), 3) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[0], uint32(10)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[1], uint32(20)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[2], uint32(30)) +} + +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : {10, 20, 30} 400000, 300000, 40001 +// expected result: +// as-path : 65000, {10, 20, 30}, 400000, 300000, 40001 +func TestAsPathAs4Trans5(t *testing.T) { + as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{400000, 300000, 40001} + as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4) + as5 := []uint32{10, 20, 30} + as4param2 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as5) + param4s := []*bgp.As4PathParam{as4param2, as4param1} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 3) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 1) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS), 3) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[0], uint32(10)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[1], uint32(20)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[2], uint32(30)) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS), 3) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[0], uint32(400000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[1], uint32(300000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[2], uint32(40001)) +} + +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : 100000, 65000, 4000, 400000, 300000, 40001 +// expected result: +// as-path : 65000, 4000, 23456, 23456, 40001 +func TestAsPathAs4TransInvalid1(t *testing.T) { + as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{100000, 65000, 4000, 400000, 300000, 40001} + as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4) + param4s := []*bgp.As4PathParam{as4param1} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001)) +} + +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : 300000, 40001 +// expected result: +// as-path : 65000, 4000, 23456, 300000, 40001 +func TestAsPathAs4TransInvalid2(t *testing.T) { + as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{300000, 40001} + as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4) + param4s := []*bgp.As4PathParam{as4param1} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(300000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001)) +} + +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : nil +// expected result: +// as-path : 65000, 4000, 23456, 23456, 40001 +func TestAsPathAs4TransInvalid3(t *testing.T) { + as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001)) +} + +// before: +// as-path : 65000, 4000, 23456, 23456, 40001 +// as4-path : empty +// expected result: +// as-path : 65000, 4000, 23456, 23456, 40001 +func TestAsPathAs4TransInvalid4(t *testing.T) { + as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001} + params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)} + aspath := bgp.NewPathAttributeAsPath(params) + + as4 := []uint32{} + as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4) + param4s := []*bgp.As4PathParam{as4param1} + as4path := bgp.NewPathAttributeAs4Path(param4s) + msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate) + UpdatePathAttrs4ByteAs(msg) + assert.Equal(t, len(msg.PathAttributes), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1) + assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(bgp.AS_TRANS)) + assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001)) } func TestBMP(t *testing.T) { |