// 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)) }
func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error { ps := msg.PathAttributes msg.PathAttributes = make([]bgp.PathAttributeInterface, len(ps)) copy(msg.PathAttributes, ps) var asAttr *bgp.PathAttributeAsPath idx := 0 for i, attr := range msg.PathAttributes { if a, ok := attr.(*bgp.PathAttributeAsPath); ok { asAttr = a idx = i break } } if asAttr == nil { return nil } 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 { as2Path = append(as2Path, uint16(as)) } } as2Params = append(as2Params, bgp.NewAsPathParam(as4Param.Type, as2Path)) // 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(as2Params) if mkAs4 { msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Path(as4Params)) } return nil }