func UpdatePathAggregator2ByteAs(msg *bgp.BGPUpdate) { as := uint32(0) var addr string for i, attr := range msg.PathAttributes { switch attr.(type) { case *bgp.PathAttributeAggregator: agg := attr.(*bgp.PathAttributeAggregator) addr = agg.Value.Address.String() if agg.Value.AS > (1<<16)-1 { as = agg.Value.AS msg.PathAttributes[i] = bgp.NewPathAttributeAggregator(uint16(bgp.AS_TRANS), addr) } else { msg.PathAttributes[i] = bgp.NewPathAttributeAggregator(uint16(agg.Value.AS), addr) } } } if as != 0 { msg.PathAttributes = append(msg.PathAttributes, bgp.NewPathAttributeAs4Aggregator(as, addr)) } }
func extractAggregator(args []string) ([]string, bgp.PathAttributeInterface, error) { for idx, arg := range args { if arg == "aggregator" { if len(args) < (idx + 1) { return nil, nil, fmt.Errorf("invalid aggregator format") } v := strings.SplitN(args[idx+1], ":", 2) if len(v) != 2 { return nil, nil, fmt.Errorf("invalid aggregator format") } as, err := strconv.ParseUint(v[0], 10, 32) if err != nil { return nil, nil, fmt.Errorf("invalid aggregator format") } attr := bgp.NewPathAttributeAggregator(uint32(as), net.ParseIP(v[1]).String()) return append(args[:idx], args[idx+2:]...), attr, nil } } return args, nil, nil }
func TestAggregator4BytesASes(t *testing.T) { getAggr := func(msg *bgp.BGPUpdate) *bgp.PathAttributeAggregator { for _, attr := range msg.PathAttributes { switch attr.(type) { case *bgp.PathAttributeAggregator: return attr.(*bgp.PathAttributeAggregator) } } return nil } getAggr4 := func(msg *bgp.BGPUpdate) *bgp.PathAttributeAs4Aggregator { for _, attr := range msg.PathAttributes { switch attr.(type) { case *bgp.PathAttributeAs4Aggregator: return attr.(*bgp.PathAttributeAs4Aggregator) } } return nil } addr := "192.168.0.1" as4 := uint32(100000) as := uint32(1000) msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(as4, addr)}, nil).Body.(*bgp.BGPUpdate) // 4byte capable to 4byte capable for 4 bytes AS assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil) assert.Equal(t, getAggr(msg).Value.AS, as4) assert.Equal(t, getAggr(msg).Value.Address.String(), addr) // 4byte capable to 2byte capable for 4 bytes AS UpdatePathAggregator2ByteAs(msg) assert.Equal(t, getAggr(msg).Value.AS, uint32(bgp.AS_TRANS)) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16) assert.Equal(t, getAggr4(msg).Value.AS, as4) assert.Equal(t, getAggr4(msg).Value.Address.String(), addr) msg = bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(uint16(bgp.AS_TRANS), addr), bgp.NewPathAttributeAs4Aggregator(as4, addr)}, nil).Body.(*bgp.BGPUpdate) assert.Equal(t, getAggr(msg).Value.AS, uint32(bgp.AS_TRANS)) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16) // non 4byte capable to 4byte capable for 4 bytes AS assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil) assert.Equal(t, getAggr(msg).Value.AS, as4) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32) assert.Equal(t, getAggr(msg).Value.Address.String(), addr) assert.Equal(t, getAggr4(msg), (*bgp.PathAttributeAs4Aggregator)(nil)) // non 4byte capable to non 4byte capable for 4 bytes AS UpdatePathAggregator2ByteAs(msg) assert.Equal(t, getAggr(msg).Value.AS, uint32(bgp.AS_TRANS)) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16) assert.Equal(t, getAggr4(msg).Value.AS, as4) assert.Equal(t, getAggr4(msg).Value.Address.String(), addr) msg = bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(uint32(as), addr)}, nil).Body.(*bgp.BGPUpdate) // 4byte capable to 4byte capable for 2 bytes AS assert.Equal(t, getAggr(msg).Value.AS, as) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32) assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil) assert.Equal(t, getAggr(msg).Value.AS, as) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32) // 4byte capable to non 4byte capable for 2 bytes AS UpdatePathAggregator2ByteAs(msg) assert.Equal(t, getAggr4(msg), (*bgp.PathAttributeAs4Aggregator)(nil)) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16) assert.Equal(t, getAggr(msg).Value.AS, as) msg = bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(uint16(as), addr)}, nil).Body.(*bgp.BGPUpdate) // non 4byte capable to 4byte capable for 2 bytes AS assert.Equal(t, getAggr(msg).Value.AS, as) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16) assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil) assert.Equal(t, getAggr(msg).Value.AS, as) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32) // non 4byte capable to non 4byte capable for 2 bytes AS UpdatePathAggregator2ByteAs(msg) assert.Equal(t, getAggr(msg).Value.AS, as) assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16) assert.Equal(t, getAggr4(msg), (*bgp.PathAttributeAs4Aggregator)(nil)) }