func TestImplicitWithdrawCalculate(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.101") updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] path1.Filter("1", POLICY_DIRECTION_IMPORT) // suppose peer2 has import policy to prepend as-path action := &AsPathPrependAction{ asn: 100, repeat: 1, } path2 := action.Apply(path1.Clone(false), nil) path1.Filter("2", POLICY_DIRECTION_IMPORT) path2.Filter("1", POLICY_DIRECTION_IMPORT) path2.Filter("3", POLICY_DIRECTION_IMPORT) d := NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate(nil) assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) assert.Equal(t, d.GetKnownPathList("2")[0].GetAsString(), "100 65001") // peer "2" has modified path {100, 65001} assert.Equal(t, len(d.GetKnownPathList("3")), 1) assert.Equal(t, d.GetKnownPathList("3")[0].GetAsString(), "65001") // peer "3" has original path {65001} assert.Equal(t, len(d.knownPathList), 2) // say, we removed peer2's import policy and // peer1 advertised new path with the same prefix aspathParam = []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001, 65002})} aspath = bgp.NewPathAttributeAsPath(aspathParam) pathAttributes = []bgp.PathAttributeInterface{origin, aspath, nexthop, med} updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) path3 := ProcessMessage(updateMsg, peer1, time.Now())[0] path3.Filter("1", POLICY_DIRECTION_IMPORT) d.AddNewPath(path3) d.Calculate(nil) assert.Equal(t, len(d.GetKnownPathList("1")), 0) // peer "1" is the originator assert.Equal(t, len(d.GetKnownPathList("2")), 1) assert.Equal(t, d.GetKnownPathList("2")[0].GetAsString(), "65001 65002") // peer "2" has new original path {65001, 65002} assert.Equal(t, len(d.GetKnownPathList("3")), 1) assert.Equal(t, d.GetKnownPathList("3")[0].GetAsString(), "65001 65002") // peer "3" has new original path {65001, 65002} assert.Equal(t, len(d.knownPathList), 1) }
func TestCalculate2(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0") // peer1 sends normal update message 10.10.0.0/24 update1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(update1, peer1, time.Now())[0] d := NewDestination(nlri) d.AddNewPath(path1) d.Calculate(nil) // suppose peer2 sends grammaatically correct but semantically flawed update message // which has a withdrawal nlri not advertised before update2 := bgp.NewBGPUpdateMessage([]*bgp.IPAddrPrefix{nlri}, pathAttributes, nil) peer2 := &PeerInfo{AS: 2, Address: net.IP{2, 2, 2, 2}} path2 := ProcessMessage(update2, peer2, time.Now())[0] assert.Equal(t, path2.IsWithdraw, true) d.AddWithdraw(path2) d.Calculate(nil) // we have a path from peer1 here assert.Equal(t, len(d.knownPathList), 1) // after that, new update with the same nlri comes from peer2 update3 := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) path3 := ProcessMessage(update3, peer2, time.Now())[0] assert.Equal(t, path3.IsWithdraw, false) d.AddNewPath(path3) d.Calculate(nil) // this time, we have paths from peer1 and peer2 assert.Equal(t, len(d.knownPathList), 2) // now peer3 sends normal update message 10.10.0.0/24 peer3 := &PeerInfo{AS: 3, Address: net.IP{3, 3, 3, 3}} update4 := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) path4 := ProcessMessage(update4, peer3, time.Now())[0] d.AddNewPath(path4) d.Calculate(nil) // we must have paths from peer1, peer2 and peer3 assert.Equal(t, len(d.knownPathList), 3) }
func TestPathPrependAsnToExistingSeqAttr(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65100, 65101, 65102}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65100, 65101})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) p.PrependAsn(65000, 1) assert.Equal([]uint32{65000, 65001, 65002, 65003, 65004, 65005, 0, 0, 0}, p.GetAsSeqList()) fmt.Printf("asns: %v", p.GetAsSeqList()) }
func TestASPathLen(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, []uint16{65001, 65002, 65003, 65004, 65004, 65004, 65004, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65100, 65101, 65102}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65100, 65101})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) assert.Equal(10, p.GetAsPathLen()) }
// 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 TestTimeTieBreaker(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.0") updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 2, LocalAS: 1, Address: net.IP{1, 1, 1, 1}, ID: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] peer2 := &PeerInfo{AS: 2, LocalAS: 1, Address: net.IP{2, 2, 2, 2}, ID: net.IP{2, 2, 2, 2}} // weaker router-id path2 := ProcessMessage(updateMsg, peer2, time.Now().Add(-1*time.Hour))[0] // older than path1 d := NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate(nil) assert.Equal(t, len(d.knownPathList), 2) assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{2, 2, 2, 2})) // path from peer2 win // this option disables tie breaking by age SelectionOptions.ExternalCompareRouterId = true d = NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate(nil) assert.Equal(t, len(d.knownPathList), 2) assert.Equal(t, true, d.GetBestPath("").GetSource().ID.Equal(net.IP{1, 1, 1, 1})) // path from peer1 win }
// 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 updateMsgP2() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65100})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.100.1") med := bgp.NewPathAttributeMultiExitDisc(100) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "20.20.20.0")} return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) }
func updateMsgD1() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65000})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate)) return updateMsg }
func TestPathPrependAsnToNewAsPathAttr(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") pathAttributes := []bgp.PathAttributeInterface{ origin, nexthop, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) asn := uint32(65000) p.PrependAsn(asn, 1) assert.Equal([]uint32{asn}, p.GetAsSeqList()) }
func TestBMP(t *testing.T) { aspath1 := []bgp.AsPathParamInterface{ bgp.NewAs4PathParam(2, []uint32{1000000}), bgp.NewAs4PathParam(1, []uint32{1000001, 1002}), bgp.NewAs4PathParam(2, []uint32{1003, 100004}), } mp_nlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(100, "fe80:1234:1234:5667:8967:af12:8912:1023")} p := []bgp.PathAttributeInterface{ bgp.NewPathAttributeOrigin(3), bgp.NewPathAttributeAsPath(aspath1), bgp.NewPathAttributeMpUnreachNLRI(mp_nlri), } w := []*bgp.IPAddrPrefix{} n := []*bgp.IPAddrPrefix{} msg := bgp.NewBGPUpdateMessage(w, p, n) pList := ProcessMessage(msg, peerR1(), time.Now()) CreateUpdateMsgFromPaths(pList) }
func updateMsgD3() *bgp.BGPMessage { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65100})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.150.1") med := bgp.NewPathAttributeMultiExitDisc(100) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "30.30.30.0")} w1 := bgp.NewIPAddrPrefix(23, "40.40.40.0") withdrawnRoutes := []*bgp.IPAddrPrefix{w1} updateMsg := bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) UpdatePathAttrs4ByteAs(updateMsg.Body.(*bgp.BGPUpdate)) return updateMsg }
func TestCalculate(t *testing.T) { origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65001})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} nlri := bgp.NewIPAddrPrefix(24, "10.10.0.101") updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, []*bgp.IPAddrPrefix{nlri}) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] path1.Filter("1", POLICY_DIRECTION_IMPORT) action := &AsPathPrependAction{ asn: 100, repeat: 10, } path2 := action.Apply(path1.Clone(false), nil) path1.Filter("2", POLICY_DIRECTION_IMPORT) path2.Filter("1", POLICY_DIRECTION_IMPORT) d := NewDestination(nlri) d.AddNewPath(path1) d.AddNewPath(path2) d.Calculate([]string{"1", "2"}) assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 1) assert.Equal(t, len(d.knownPathList), 2) d.AddWithdraw(path1.Clone(true)) d.Calculate([]string{"1", "2"}) assert.Equal(t, len(d.GetKnownPathList("1")), 0) assert.Equal(t, len(d.GetKnownPathList("2")), 0) assert.Equal(t, len(d.knownPathList), 0) }
func TestPathPrependAsnToFullPathAttr(t *testing.T) { assert := assert.New(t) origin := bgp.NewPathAttributeOrigin(0) asns := make([]uint16, 255) for i, _ := range asns { asns[i] = 65000 + uint16(i) } aspathParam := []bgp.AsPathParamInterface{ bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, asns), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, []uint16{65001, 65002, 65003, 65004, 65005}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65100, 65101, 65102}), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65100, 65101})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} bgpmsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) update := bgpmsg.Body.(*bgp.BGPUpdate) UpdatePathAttrs4ByteAs(update) peer := PathCreatePeer() p := NewPath(peer[0], update.NLRI[0], false, update.PathAttributes, time.Now(), false) expected := []uint32{65000, 65000} for _, v := range asns { expected = append(expected, uint32(v)) } p.PrependAsn(65000, 2) assert.Equal(append(expected, []uint32{0, 0, 0}...), p.GetAsSeqList()) fmt.Printf("asns: %v", p.GetAsSeqList()) }
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)) }
func TestMultipath(t *testing.T) { UseMultiplePaths.Enabled = true origin := bgp.NewPathAttributeOrigin(0) aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000})} aspath := bgp.NewPathAttributeAsPath(aspathParam) nexthop := bgp.NewPathAttributeNextHop("192.168.150.1") med := bgp.NewPathAttributeMultiExitDisc(100) pathAttributes := []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) peer1 := &PeerInfo{AS: 1, Address: net.IP{1, 1, 1, 1}, ID: net.IP{1, 1, 1, 1}} path1 := ProcessMessage(updateMsg, peer1, time.Now())[0] peer2 := &PeerInfo{AS: 2, Address: net.IP{2, 2, 2, 2}, ID: net.IP{2, 2, 2, 2}} med = bgp.NewPathAttributeMultiExitDisc(100) nexthop = bgp.NewPathAttributeNextHop("192.168.150.2") pathAttributes = []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path2 := ProcessMessage(updateMsg, peer2, time.Now())[0] d := NewDestination(nlri[0]) d.AddNewPath(path1) d.AddNewPath(path2) best, w, multi := d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 0) assert.Equal(t, len(multi), 2) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) path3 := path2.Clone(true) d.AddWithdraw(path3) best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 1) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 1) peer3 := &PeerInfo{AS: 3, Address: net.IP{3, 3, 3, 3}, ID: net.IP{3, 3, 3, 3}} med = bgp.NewPathAttributeMultiExitDisc(50) nexthop = bgp.NewPathAttributeNextHop("192.168.150.3") pathAttributes = []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path4 := ProcessMessage(updateMsg, peer3, time.Now())[0] d.AddNewPath(path4) best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 0) assert.Equal(t, len(multi), 1) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 2) nexthop = bgp.NewPathAttributeNextHop("192.168.150.2") pathAttributes = []bgp.PathAttributeInterface{ origin, aspath, nexthop, med, } updateMsg = bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path5 := ProcessMessage(updateMsg, peer2, time.Now())[0] d.AddNewPath(path5) best, w, multi = d.Calculate([]string{GLOBAL_RIB_NAME}) assert.Equal(t, len(best), 1) assert.Equal(t, len(w), 0) assert.Equal(t, len(multi), 2) assert.Equal(t, len(d.GetKnownPathList(GLOBAL_RIB_NAME)), 3) UseMultiplePaths.Enabled = false }
func createUpdateMsgFromPath(path *Path, msg *bgp.BGPMessage) *bgp.BGPMessage { rf := path.GetRouteFamily() if rf == bgp.RF_IPv4_UC { nlri := path.GetNlri().(*bgp.IPAddrPrefix) if path.IsWithdraw { if msg != nil { u := msg.Body.(*bgp.BGPUpdate) u.WithdrawnRoutes = append(u.WithdrawnRoutes, nlri) return nil } else { return bgp.NewBGPUpdateMessage([]*bgp.IPAddrPrefix{nlri}, nil, nil) } } else { if msg != nil { u := msg.Body.(*bgp.BGPUpdate) u.NLRI = append(u.NLRI, nlri) } else { pathAttrs := path.GetPathAttrs() return bgp.NewBGPUpdateMessage(nil, pathAttrs, []*bgp.IPAddrPrefix{nlri}) } } } else { if path.IsWithdraw { if msg != nil { u := msg.Body.(*bgp.BGPUpdate) for _, p := range u.PathAttributes { if p.GetType() == bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI { unreach := p.(*bgp.PathAttributeMpUnreachNLRI) unreach.Value = append(unreach.Value, path.GetNlri()) } } } else { var nlris []bgp.AddrPrefixInterface attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI) if attr == nil { // for bmp post-policy attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI) nlris = attr.(*bgp.PathAttributeMpUnreachNLRI).Value } else { nlris = []bgp.AddrPrefixInterface{path.GetNlri()} } clonedAttrs := path.GetPathAttrs() for i, a := range clonedAttrs { if a.GetType() == bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI || a.GetType() == bgp.BGP_ATTR_TYPE_MP_REACH_NLRI { clonedAttrs[i] = bgp.NewPathAttributeMpUnreachNLRI(nlris) break } } return bgp.NewBGPUpdateMessage(nil, clonedAttrs, nil) } } else { if msg != nil { u := msg.Body.(*bgp.BGPUpdate) for _, p := range u.PathAttributes { if p.GetType() == bgp.BGP_ATTR_TYPE_MP_REACH_NLRI { reach := p.(*bgp.PathAttributeMpReachNLRI) reach.Value = append(reach.Value, path.GetNlri()) } } } else { attrs := make([]bgp.PathAttributeInterface, 0, 8) for _, p := range path.GetPathAttrs() { if p.GetType() == bgp.BGP_ATTR_TYPE_MP_REACH_NLRI { attrs = append(attrs, bgp.NewPathAttributeMpReachNLRI(path.GetNexthop().String(), []bgp.AddrPrefixInterface{path.GetNlri()})) } else { attrs = append(attrs, p) } } // we don't need to clone here but we // might merge path to this message in // the future so let's clone anyway. return bgp.NewBGPUpdateMessage(nil, attrs, nil) } } } return nil }