@@ -1594,48 +1594,65 @@ func runNewServer(t *testing.T, as uint32, routerID string, listenPort int32) *B
15941594 return s
15951595}
15961596
1597- func peerServers (t * testing.T , ctx context.Context , servers []* BgpServer , families []oc.AfiSafiType ) error {
1597+ type peerOption func (peer * BgpServer , g * oc.Global , p * oc.Neighbor )
1598+
1599+ func setPeerAddressOpt (peer * BgpServer , g * oc.Global , p * oc.Neighbor ) {
1600+ p .Transport .Config .LocalAddress = g .Config .LocalAddressList [0 ]
1601+ p .Config .NeighborAddress = peer .bgpConfig .Global .Config .LocalAddressList [0 ]
1602+ }
1603+
1604+ func peerTwoServers (t * testing.T , ctx context.Context , server , peer * BgpServer , families []oc.AfiSafiType , isPassive bool , opts ... peerOption ) error {
1605+ neighborConfig := & oc.Neighbor {
1606+ Config : oc.NeighborConfig {
1607+ NeighborAddress : netip .MustParseAddr ("127.0.0.1" ),
1608+ PeerAs : peer .bgpConfig .Global .Config .As ,
1609+ },
1610+ AfiSafis : oc.AfiSafis {},
1611+ Transport : oc.Transport {
1612+ Config : oc.TransportConfig {
1613+ RemotePort : uint16 (peer .bgpConfig .Global .Config .Port ),
1614+ },
1615+ },
1616+ Timers : oc.Timers {
1617+ Config : oc.TimersConfig {
1618+ ConnectRetry : 1 ,
1619+ IdleHoldTimeAfterReset : 1 ,
1620+ },
1621+ },
1622+ }
1623+
1624+ for _ , opt := range opts {
1625+ opt (peer , & server .bgpConfig .Global , neighborConfig )
1626+ }
1627+
1628+ if isPassive {
1629+ neighborConfig .Transport .Config .PassiveMode = true
1630+ }
1631+
1632+ for _ , family := range families {
1633+ neighborConfig .AfiSafis = append (neighborConfig .AfiSafis , oc.AfiSafi {
1634+ Config : oc.AfiSafiConfig {
1635+ AfiSafiName : family ,
1636+ Enabled : true ,
1637+ },
1638+ })
1639+ }
1640+
1641+ if err := server .AddPeer (ctx , & api.AddPeerRequest {Peer : oc .NewPeerFromConfigStruct (neighborConfig )}); err != nil {
1642+ t .Fatal (err )
1643+ }
1644+ return nil
1645+ }
1646+
1647+ func peerServers (t * testing.T , ctx context.Context , servers []* BgpServer , families []oc.AfiSafiType , opts ... peerOption ) error {
15981648 for i , server := range servers {
15991649 for j , peer := range servers {
16001650 if i == j {
16011651 continue
16021652 }
1603-
1604- neighborConfig := & oc.Neighbor {
1605- Config : oc.NeighborConfig {
1606- NeighborAddress : netip .MustParseAddr ("127.0.0.1" ),
1607- PeerAs : peer .bgpConfig .Global .Config .As ,
1608- },
1609- AfiSafis : oc.AfiSafis {},
1610- Transport : oc.Transport {
1611- Config : oc.TransportConfig {
1612- RemotePort : uint16 (peer .bgpConfig .Global .Config .Port ),
1613- },
1614- },
1615- Timers : oc.Timers {
1616- Config : oc.TimersConfig {
1617- ConnectRetry : 1 ,
1618- IdleHoldTimeAfterReset : 1 ,
1619- },
1620- },
1621- }
1622-
16231653 // first server to get neighbor config is passive to hopefully make handshake faster
1624- if j > i {
1625- neighborConfig .Transport .Config .PassiveMode = true
1626- }
1627-
1628- for _ , family := range families {
1629- neighborConfig .AfiSafis = append (neighborConfig .AfiSafis , oc.AfiSafi {
1630- Config : oc.AfiSafiConfig {
1631- AfiSafiName : family ,
1632- Enabled : true ,
1633- },
1634- })
1635- }
1636-
1637- if err := server .AddPeer (ctx , & api.AddPeerRequest {Peer : oc .NewPeerFromConfigStruct (neighborConfig )}); err != nil {
1638- t .Fatal (err )
1654+ if err := peerTwoServers (t , ctx , server , peer , families , i < j , opts ... ); err != nil {
1655+ return err
16391656 }
16401657 }
16411658 }
@@ -3003,3 +3020,114 @@ func TestAddDefinedSetReplace(t *testing.T) {
30033020 assert .Equal ("replaceme" , ns [0 ].Name )
30043021 assert .Equal ([]string {"203.0.113.2/32" }, ns [0 ].List )
30053022}
3023+
3024+ func TestEBGPRouteStuck (test * testing.T ) {
3025+ var peers []* BgpServer
3026+ for i , s := range []struct {
3027+ routerId string
3028+ asn uint32
3029+ }{
3030+ {routerId : "1.1.1.1" , asn : 1 },
3031+ {routerId : "2.2.2.1" , asn : 2 },
3032+ {routerId : "2.2.2.2" , asn : 2 },
3033+ } {
3034+ peer := NewBgpServer ()
3035+ peer .logger .SetLevel (log .InfoLevel )
3036+ go peer .Serve ()
3037+
3038+ peers = append (peers , peer )
3039+
3040+ err := peer .StartBgp (context .Background (), & api.StartBgpRequest {
3041+ Global : & api.Global {
3042+ Asn : s .asn ,
3043+ RouterId : s .routerId ,
3044+ ListenAddresses : []string {fmt .Sprintf ("127.0.0.%d" , 100 + i )},
3045+ ListenPort : 10179 ,
3046+ },
3047+ })
3048+ require .NoError (test , err )
3049+ }
3050+
3051+ wg := waitEstablished (peers [0 ])
3052+ wg1 := waitEstablished (peers [1 ])
3053+ wg2 := waitEstablished (peers [2 ])
3054+ // Use only eBGP
3055+ for i , server := range peers {
3056+ for j , peer := range peers {
3057+ if i == j || server .bgpConfig .Global .Config .As == peer .bgpConfig .Global .Config .As {
3058+ continue
3059+ }
3060+ ctx := context .Background ()
3061+ if err := peerTwoServers (test , ctx , server , peer , []oc.AfiSafiType {oc .AFI_SAFI_TYPE_IPV4_UNICAST }, i < j , setPeerAddressOpt ); err != nil {
3062+ assert .NoError (test , err )
3063+ }
3064+ }
3065+ }
3066+
3067+ wg .Wait ()
3068+ wg1 .Wait ()
3069+ wg2 .Wait ()
3070+
3071+ family4 := & api.Family {
3072+ Afi : api .Family_AFI_IP ,
3073+ Safi : api .Family_SAFI_UNICAST ,
3074+ }
3075+ attrs := []* api.Attribute {
3076+ {
3077+ Attr : & api.Attribute_Origin {Origin : & api.OriginAttribute {
3078+ Origin : 0 ,
3079+ }},
3080+ },
3081+ {
3082+ Attr : & api.Attribute_NextHop {NextHop : & api.NextHopAttribute {
3083+ NextHop : "10.0.0.1" ,
3084+ }},
3085+ },
3086+ }
3087+
3088+ nlri := & api.NLRI {Nlri : & api.NLRI_Prefix {Prefix : & api.IPAddressPrefix {
3089+ Prefix : "10.1.0.0" ,
3090+ PrefixLen : 24 ,
3091+ }}}
3092+
3093+ assertPathCount := func (t assert.TestingT , peer * BgpServer , expected int ) {
3094+ var info * table.TableInfo
3095+ if peer .active () == nil {
3096+ info , _ = peer .getRibInfo ("" , bgp .RF_IPv4_UC )
3097+ } else {
3098+ info = peer .globalRib .Tables [bgp .RF_IPv4_UC ].Info ()
3099+ }
3100+ if assert .NotNil (t , info ) {
3101+ assert .Equal (t , expected , info .NumPath )
3102+ }
3103+ }
3104+
3105+ path := & api.Path {
3106+ Family : family4 ,
3107+ Nlri : nlri ,
3108+ Pattrs : attrs ,
3109+ }
3110+ addPaths := func (peers []* BgpServer , path * api.Path ) {
3111+ for _ , peer := range peers {
3112+ _ , err := peer .AddPath (apiutil.AddPathRequest {Paths : []* apiutil.Path {mustApi2apiutilPath (path )}})
3113+ assert .NoError (test , err )
3114+ }
3115+ }
3116+
3117+ addPaths (peers , path )
3118+
3119+ assert .EventuallyWithT (test , func (collect * assert.CollectT ) {
3120+ assertPathCount (collect , peers [0 ], 3 )
3121+ assertPathCount (collect , peers [1 ], 2 )
3122+ assertPathCount (collect , peers [2 ], 2 )
3123+ }, 5 * time .Second , 1 * time .Millisecond )
3124+
3125+ err := peers [0 ].DeletePath (apiutil.DeletePathRequest {Paths : []* apiutil.Path {mustApi2apiutilPath (path )}})
3126+ assert .NoError (test , err )
3127+
3128+ assert .EventuallyWithT (test , func (collect * assert.CollectT ) {
3129+ assertPathCount (collect , peers [0 ], 2 )
3130+ assertPathCount (collect , peers [1 ], 1 )
3131+ assertPathCount (collect , peers [2 ], 1 )
3132+ }, 20 * time .Second , 1 * time .Millisecond )
3133+ }
0 commit comments