github.com/osrg/gobgp@v2.0.0+incompatible/pkg/server/server_test.go (about) 1 // Copyright (C) 2016 Nippon Telegraph and Telephone Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package server 17 18 import ( 19 "context" 20 "fmt" 21 "net" 22 "runtime" 23 "testing" 24 "time" 25 26 "github.com/golang/protobuf/ptypes" 27 "github.com/golang/protobuf/ptypes/any" 28 log "github.com/sirupsen/logrus" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 32 api "github.com/osrg/gobgp/api" 33 "github.com/osrg/gobgp/internal/pkg/apiutil" 34 "github.com/osrg/gobgp/internal/pkg/config" 35 "github.com/osrg/gobgp/internal/pkg/table" 36 "github.com/osrg/gobgp/pkg/packet/bgp" 37 ) 38 39 func TestModPolicyAssign(t *testing.T) { 40 assert := assert.New(t) 41 s := NewBgpServer() 42 go s.Serve() 43 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 44 Global: &api.Global{ 45 As: 1, 46 RouterId: "1.1.1.1", 47 ListenPort: -1, 48 }, 49 }) 50 assert.Nil(err) 51 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 52 53 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: "p1"})}) 54 assert.Nil(err) 55 56 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: "p2"})}) 57 assert.Nil(err) 58 59 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: "p3"})}) 60 assert.Nil(err) 61 62 f := func(l []*config.PolicyDefinition) *api.PolicyAssignment { 63 pl := make([]*api.Policy, 0, len(l)) 64 for _, d := range l { 65 pl = append(pl, table.ToPolicyApi(d)) 66 } 67 return &api.PolicyAssignment{ 68 Policies: pl, 69 } 70 } 71 72 r := f([]*config.PolicyDefinition{&config.PolicyDefinition{Name: "p1"}, &config.PolicyDefinition{Name: "p2"}, &config.PolicyDefinition{Name: "p3"}}) 73 r.Direction = api.PolicyDirection_IMPORT 74 r.DefaultAction = api.RouteAction_ACCEPT 75 r.Name = table.GLOBAL_RIB_NAME 76 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{Assignment: r}) 77 assert.Nil(err) 78 79 r.Direction = api.PolicyDirection_EXPORT 80 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{Assignment: r}) 81 assert.Nil(err) 82 83 var ps []*api.PolicyAssignment 84 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 85 Name: table.GLOBAL_RIB_NAME, 86 Direction: api.PolicyDirection_IMPORT}, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 87 assert.Nil(err) 88 assert.Equal(len(ps[0].Policies), 3) 89 90 r = f([]*config.PolicyDefinition{&config.PolicyDefinition{Name: "p1"}}) 91 r.Direction = api.PolicyDirection_IMPORT 92 r.DefaultAction = api.RouteAction_ACCEPT 93 r.Name = table.GLOBAL_RIB_NAME 94 err = s.DeletePolicyAssignment(context.Background(), &api.DeletePolicyAssignmentRequest{Assignment: r}) 95 assert.Nil(err) 96 97 ps = []*api.PolicyAssignment{} 98 s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 99 Name: table.GLOBAL_RIB_NAME, 100 Direction: api.PolicyDirection_IMPORT}, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 101 assert.Equal(len(ps[0].Policies), 2) 102 103 ps = []*api.PolicyAssignment{} 104 s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 105 Name: table.GLOBAL_RIB_NAME, 106 }, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 107 assert.Equal(len(ps), 2) 108 } 109 110 func TestListPolicyAssignment(t *testing.T) { 111 assert := assert.New(t) 112 113 s := NewBgpServer() 114 go s.Serve() 115 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 116 Global: &api.Global{ 117 As: 1, 118 RouterId: "1.1.1.1", 119 ListenPort: -1, 120 }, 121 }) 122 assert.Nil(err) 123 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 124 125 for i := 1; i < 4; i++ { 126 addr := fmt.Sprintf("127.0.0.%d", i) 127 p := &api.Peer{ 128 Conf: &api.PeerConf{ 129 NeighborAddress: addr, 130 PeerAs: uint32(i + 1), 131 }, 132 RouteServer: &api.RouteServer{ 133 RouteServerClient: true, 134 }, 135 } 136 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p}) 137 assert.Nil(err) 138 139 err = s.AddPolicy(context.Background(), 140 &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: fmt.Sprintf("p%d", i)})}) 141 assert.Nil(err) 142 143 pa := &api.PolicyAssignment{ 144 Direction: api.PolicyDirection_IMPORT, 145 DefaultAction: api.RouteAction_ACCEPT, 146 Name: addr, 147 Policies: []*api.Policy{&api.Policy{Name: fmt.Sprintf("p%d", i)}}, 148 } 149 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{Assignment: pa}) 150 assert.Nil(err) 151 } 152 153 ps := []*api.PolicyAssignment{} 154 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 155 Name: table.GLOBAL_RIB_NAME, 156 }, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 157 assert.Nil(err) 158 assert.Equal(len(ps), 0) 159 160 ps = []*api.PolicyAssignment{} 161 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{}, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 162 assert.Nil(err) 163 assert.Equal(len(ps), 3) 164 165 ps = []*api.PolicyAssignment{} 166 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 167 Direction: api.PolicyDirection_EXPORT, 168 }, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 169 assert.Nil(err) 170 assert.Equal(len(ps), 0) 171 } 172 173 func TestMonitor(test *testing.T) { 174 minConnectRetry = 5 175 176 assert := assert.New(test) 177 s := NewBgpServer() 178 go s.Serve() 179 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 180 Global: &api.Global{ 181 As: 1, 182 RouterId: "1.1.1.1", 183 ListenPort: 10179, 184 }, 185 }) 186 assert.Nil(err) 187 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 188 189 n := &config.Neighbor{ 190 Config: config.NeighborConfig{ 191 NeighborAddress: "127.0.0.1", 192 PeerAs: 2, 193 }, 194 Transport: config.Transport{ 195 Config: config.TransportConfig{ 196 PassiveMode: true, 197 }, 198 }, 199 } 200 err = s.addNeighbor(n) 201 assert.Nil(err) 202 203 t := NewBgpServer() 204 go t.Serve() 205 err = t.StartBgp(context.Background(), &api.StartBgpRequest{ 206 Global: &api.Global{ 207 As: 2, 208 RouterId: "2.2.2.2", 209 ListenPort: -1, 210 }, 211 }) 212 assert.Nil(err) 213 defer t.StopBgp(context.Background(), &api.StopBgpRequest{}) 214 215 m := &config.Neighbor{ 216 Config: config.NeighborConfig{ 217 NeighborAddress: "127.0.0.1", 218 PeerAs: 1, 219 }, 220 Transport: config.Transport{ 221 Config: config.TransportConfig{ 222 RemotePort: 10179, 223 }, 224 }, 225 Timers: config.Timers{ 226 Config: config.TimersConfig{ 227 ConnectRetry: 5, 228 }, 229 }, 230 } 231 ch := make(chan struct{}) 232 go t.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(peer *api.Peer) { 233 if peer.State.SessionState == api.PeerState_ESTABLISHED { 234 close(ch) 235 } 236 }) 237 238 err = t.AddPeer(context.Background(), &api.AddPeerRequest{Peer: config.NewPeerFromConfigStruct(m)}) 239 assert.Nil(err) 240 241 <-ch 242 243 // Test WatchBestPath. 244 w := s.watch(watchBestPath(false)) 245 246 // Advertises a route. 247 attrs := []bgp.PathAttributeInterface{ 248 bgp.NewPathAttributeOrigin(0), 249 bgp.NewPathAttributeNextHop("10.0.0.1"), 250 } 251 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), false, attrs, time.Now(), false)}); err != nil { 252 log.Fatal(err) 253 } 254 ev := <-w.Event() 255 b := ev.(*watchEventBestPath) 256 assert.Equal(1, len(b.PathList)) 257 assert.Equal("10.0.0.0/24", b.PathList[0].GetNlri().String()) 258 assert.False(b.PathList[0].IsWithdraw) 259 260 // Withdraws the previous route. 261 // NOTE: Withdow should not require any path attribute. 262 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), true, nil, time.Now(), false)}); err != nil { 263 log.Fatal(err) 264 } 265 ev = <-w.Event() 266 b = ev.(*watchEventBestPath) 267 assert.Equal(1, len(b.PathList)) 268 assert.Equal("10.0.0.0/24", b.PathList[0].GetNlri().String()) 269 assert.True(b.PathList[0].IsWithdraw) 270 271 // Stops the watcher still having an item. 272 w.Stop() 273 274 // Prepares an initial route to test WatchUpdate with "current" flag. 275 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.1.0.0"), false, attrs, time.Now(), false)}); err != nil { 276 log.Fatal(err) 277 } 278 for { 279 // Waits for the initial route will be advertised. 280 rib, _, err := s.getRib("", bgp.RF_IPv4_UC, nil) 281 if err != nil { 282 log.Fatal(err) 283 } 284 if len(rib.GetKnownPathList("", 0)) > 0 { 285 break 286 } 287 time.Sleep(100 * time.Millisecond) 288 } 289 290 // Test WatchUpdate with "current" flag. 291 w = s.watch(watchUpdate(true)) 292 293 // Test the initial route. 294 ev = <-w.Event() 295 u := ev.(*watchEventUpdate) 296 assert.Equal(1, len(u.PathList)) 297 assert.Equal("10.1.0.0/24", u.PathList[0].GetNlri().String()) 298 assert.False(u.PathList[0].IsWithdraw) 299 ev = <-w.Event() 300 u = ev.(*watchEventUpdate) 301 assert.Equal(len(u.PathList), 0) // End of RIB 302 303 // Advertises an additional route. 304 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.2.0.0"), false, attrs, time.Now(), false)}); err != nil { 305 log.Fatal(err) 306 } 307 ev = <-w.Event() 308 u = ev.(*watchEventUpdate) 309 assert.Equal(1, len(u.PathList)) 310 assert.Equal("10.2.0.0/24", u.PathList[0].GetNlri().String()) 311 assert.False(u.PathList[0].IsWithdraw) 312 313 // Withdraws the previous route. 314 // NOTE: Withdow should not require any path attribute. 315 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.2.0.0"), true, nil, time.Now(), false)}); err != nil { 316 log.Fatal(err) 317 } 318 ev = <-w.Event() 319 u = ev.(*watchEventUpdate) 320 assert.Equal(1, len(u.PathList)) 321 assert.Equal("10.2.0.0/24", u.PathList[0].GetNlri().String()) 322 assert.True(u.PathList[0].IsWithdraw) 323 324 // Stops the watcher still having an item. 325 w.Stop() 326 } 327 328 func TestNumGoroutineWithAddDeleteNeighbor(t *testing.T) { 329 assert := assert.New(t) 330 s := NewBgpServer() 331 go s.Serve() 332 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 333 Global: &api.Global{ 334 As: 1, 335 RouterId: "1.1.1.1", 336 ListenPort: -1, 337 }, 338 }) 339 assert.Nil(err) 340 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 341 342 // wait a few seconds to avoid taking effect from other test cases. 343 time.Sleep(time.Second * 5) 344 345 num := runtime.NumGoroutine() 346 347 p := &api.Peer{ 348 Conf: &api.PeerConf{ 349 NeighborAddress: "127.0.0.1", 350 PeerAs: 2, 351 }, 352 Transport: &api.Transport{ 353 PassiveMode: true, 354 }, 355 } 356 357 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p}) 358 assert.Nil(err) 359 360 err = s.DeletePeer(context.Background(), &api.DeletePeerRequest{Address: "127.0.0.1"}) 361 assert.Nil(err) 362 // wait goroutines to finish (e.g. internal goroutine for 363 // InfiniteChannel) 364 time.Sleep(time.Second * 5) 365 for i := 0; i < 5; i++ { 366 if num == runtime.NumGoroutine() { 367 return 368 } 369 } 370 assert.Equal(num, runtime.NumGoroutine()) 371 } 372 373 func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (*peer, *table.PeerInfo) { 374 nConf := &config.Neighbor{Config: config.NeighborConfig{PeerAs: as, NeighborAddress: address}} 375 gConf := &config.Global{Config: config.GlobalConfig{As: myAs}} 376 config.SetDefaultNeighborConfigValues(nConf, nil, gConf) 377 policy := table.NewRoutingPolicy() 378 policy.Reset(&config.RoutingPolicy{}, nil) 379 p := newPeer( 380 &config.Global{Config: config.GlobalConfig{As: myAs}}, 381 nConf, 382 rib, 383 policy) 384 for _, f := range rib.GetRFlist() { 385 p.fsm.rfMap[f] = bgp.BGP_ADD_PATH_NONE 386 } 387 return p, &table.PeerInfo{AS: as, Address: net.ParseIP(address)} 388 } 389 390 func process(rib *table.TableManager, l []*table.Path) (*table.Path, *table.Path) { 391 dsts := make([]*table.Update, 0) 392 for _, path := range l { 393 dsts = append(dsts, rib.Update(path)...) 394 } 395 news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, 0, dsts) 396 if len(news) != 1 { 397 panic("can't handle multiple paths") 398 } 399 400 return news[0], olds[0] 401 } 402 403 func TestFilterpathWitheBGP(t *testing.T) { 404 as := uint32(65000) 405 p1As := uint32(65001) 406 p2As := uint32(65002) 407 rib := table.NewTableManager([]bgp.RouteFamily{bgp.RF_IPv4_UC}) 408 p1, pi1 := newPeerandInfo(as, p1As, "192.168.0.1", rib) 409 p2, pi2 := newPeerandInfo(as, p2As, "192.168.0.2", rib) 410 411 nlri := bgp.NewIPAddrPrefix(24, "10.10.10.0") 412 pa1 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{p1As})}), bgp.NewPathAttributeLocalPref(200)} 413 pa2 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{p2As})})} 414 415 path1 := table.NewPath(pi1, nlri, false, pa1, time.Now(), false) 416 path2 := table.NewPath(pi2, nlri, false, pa2, time.Now(), false) 417 rib.Update(path2) 418 d := rib.Update(path1) 419 new, old, _ := d[0].GetChanges(table.GLOBAL_RIB_NAME, 0, false) 420 assert.Equal(t, new, path1) 421 filterpath(p1, new, old) 422 filterpath(p2, new, old) 423 424 new, old = process(rib, []*table.Path{path1.Clone(true)}) 425 assert.Equal(t, new, path2) 426 // p1 and p2 advertized the same prefix and p1's was best. Then p1 withdraw it, so p2 must get withdawal. 427 path := filterpath(p2, new, old) 428 assert.NotNil(t, path) 429 assert.True(t, path.IsWithdraw) 430 431 // p1 should get the new best (from p2) 432 assert.Equal(t, filterpath(p1, new, old), path2) 433 434 new, old = process(rib, []*table.Path{path2.Clone(true)}) 435 assert.True(t, new.IsWithdraw) 436 // p2 withdraw so p1 should get withdrawal. 437 path = filterpath(p1, new, old) 438 assert.True(t, path.IsWithdraw) 439 440 // p2 withdraw so p2 should get nothing. 441 path = filterpath(p2, new, old) 442 assert.Nil(t, path) 443 } 444 445 func TestFilterpathWithiBGP(t *testing.T) { 446 as := uint32(65000) 447 448 rib := table.NewTableManager([]bgp.RouteFamily{bgp.RF_IPv4_UC}) 449 p1, pi1 := newPeerandInfo(as, as, "192.168.0.1", rib) 450 //p2, pi2 := newPeerandInfo(as, as, "192.168.0.2", rib) 451 p2, _ := newPeerandInfo(as, as, "192.168.0.2", rib) 452 453 nlri := bgp.NewIPAddrPrefix(24, "10.10.10.0") 454 pa1 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{as})}), bgp.NewPathAttributeLocalPref(200)} 455 //pa2 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{as})})} 456 457 path1 := table.NewPath(pi1, nlri, false, pa1, time.Now(), false) 458 //path2 := table.NewPath(pi2, nlri, false, pa2, time.Now(), false) 459 460 new, old := process(rib, []*table.Path{path1}) 461 assert.Equal(t, new, path1) 462 path := filterpath(p1, new, old) 463 assert.Nil(t, path) 464 path = filterpath(p2, new, old) 465 assert.Nil(t, path) 466 467 new, old = process(rib, []*table.Path{path1.Clone(true)}) 468 path = filterpath(p1, new, old) 469 assert.Nil(t, path) 470 path = filterpath(p2, new, old) 471 assert.Nil(t, path) 472 473 } 474 475 func TestFilterpathWithRejectPolicy(t *testing.T) { 476 rib1 := table.NewTableManager([]bgp.RouteFamily{bgp.RF_IPv4_UC}) 477 _, pi1 := newPeerandInfo(1, 2, "192.168.0.1", rib1) 478 rib2 := table.NewTableManager([]bgp.RouteFamily{bgp.RF_IPv4_UC}) 479 p2, _ := newPeerandInfo(1, 3, "192.168.0.2", rib2) 480 481 comSet1 := config.CommunitySet{ 482 CommunitySetName: "comset1", 483 CommunityList: []string{"100:100"}, 484 } 485 s, _ := table.NewCommunitySet(comSet1) 486 p2.policy.AddDefinedSet(s) 487 488 statement := config.Statement{ 489 Name: "stmt1", 490 Conditions: config.Conditions{ 491 BgpConditions: config.BgpConditions{ 492 MatchCommunitySet: config.MatchCommunitySet{ 493 CommunitySet: "comset1", 494 }, 495 }, 496 }, 497 Actions: config.Actions{ 498 RouteDisposition: config.ROUTE_DISPOSITION_REJECT_ROUTE, 499 }, 500 } 501 policy := config.PolicyDefinition{ 502 Name: "policy1", 503 Statements: []config.Statement{statement}, 504 } 505 p, _ := table.NewPolicy(policy) 506 p2.policy.AddPolicy(p, false) 507 policies := []*config.PolicyDefinition{ 508 &config.PolicyDefinition{ 509 Name: "policy1", 510 }, 511 } 512 p2.policy.AddPolicyAssignment(p2.TableID(), table.POLICY_DIRECTION_EXPORT, policies, table.ROUTE_TYPE_ACCEPT) 513 514 for _, addCommunity := range []bool{false, true, false, true} { 515 nlri := bgp.NewIPAddrPrefix(24, "10.10.10.0") 516 pa1 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{1})}), bgp.NewPathAttributeLocalPref(200)} 517 if addCommunity { 518 pa1 = append(pa1, bgp.NewPathAttributeCommunities([]uint32{100<<16 | 100})) 519 } 520 path1 := table.NewPath(pi1, nlri, false, pa1, time.Now(), false) 521 new, old := process(rib2, []*table.Path{path1}) 522 assert.Equal(t, new, path1) 523 s := NewBgpServer() 524 path2 := s.filterpath(p2, new, old) 525 if addCommunity { 526 assert.True(t, path2.IsWithdraw) 527 } else { 528 assert.False(t, path2.IsWithdraw) 529 } 530 } 531 532 } 533 534 func TestPeerGroup(test *testing.T) { 535 minConnectRetry = 5 536 537 assert := assert.New(test) 538 log.SetLevel(log.DebugLevel) 539 s := NewBgpServer() 540 go s.Serve() 541 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 542 Global: &api.Global{ 543 As: 1, 544 RouterId: "1.1.1.1", 545 ListenPort: 10179, 546 }, 547 }) 548 assert.Nil(err) 549 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 550 551 g := &config.PeerGroup{ 552 Config: config.PeerGroupConfig{ 553 PeerAs: 2, 554 PeerGroupName: "g", 555 }, 556 Timers: config.Timers{ 557 Config: config.TimersConfig{ 558 ConnectRetry: 5, 559 }, 560 }, 561 } 562 err = s.addPeerGroup(g) 563 assert.Nil(err) 564 565 n := &config.Neighbor{ 566 Config: config.NeighborConfig{ 567 NeighborAddress: "127.0.0.1", 568 PeerGroup: "g", 569 }, 570 Transport: config.Transport{ 571 Config: config.TransportConfig{ 572 PassiveMode: true, 573 }, 574 }, 575 Timers: config.Timers{ 576 Config: config.TimersConfig{ 577 ConnectRetry: 5, 578 }, 579 }, 580 } 581 configured := map[string]interface{}{ 582 "config": map[string]interface{}{ 583 "neigbor-address": "127.0.0.1", 584 "peer-group": "g", 585 }, 586 "transport": map[string]interface{}{ 587 "config": map[string]interface{}{ 588 "passive-mode": true, 589 }, 590 }, 591 } 592 config.RegisterConfiguredFields("127.0.0.1", configured) 593 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: config.NewPeerFromConfigStruct(n)}) 594 assert.Nil(err) 595 596 t := NewBgpServer() 597 go t.Serve() 598 err = t.StartBgp(context.Background(), &api.StartBgpRequest{ 599 Global: &api.Global{ 600 As: 2, 601 RouterId: "2.2.2.2", 602 ListenPort: -1, 603 }, 604 }) 605 assert.Nil(err) 606 defer t.StopBgp(context.Background(), &api.StopBgpRequest{}) 607 608 m := &config.Neighbor{ 609 Config: config.NeighborConfig{ 610 NeighborAddress: "127.0.0.1", 611 PeerAs: 1, 612 }, 613 Transport: config.Transport{ 614 Config: config.TransportConfig{ 615 RemotePort: 10179, 616 }, 617 }, 618 Timers: config.Timers{ 619 Config: config.TimersConfig{ 620 ConnectRetry: 5, 621 }, 622 }, 623 } 624 ch := make(chan struct{}) 625 go t.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(peer *api.Peer) { 626 if peer.State.SessionState == api.PeerState_ESTABLISHED { 627 close(ch) 628 } 629 }) 630 err = t.AddPeer(context.Background(), &api.AddPeerRequest{Peer: config.NewPeerFromConfigStruct(m)}) 631 assert.Nil(err) 632 <-ch 633 } 634 635 func TestDynamicNeighbor(t *testing.T) { 636 minConnectRetry = 5 637 638 assert := assert.New(t) 639 log.SetLevel(log.DebugLevel) 640 s1 := NewBgpServer() 641 go s1.Serve() 642 err := s1.StartBgp(context.Background(), &api.StartBgpRequest{ 643 Global: &api.Global{ 644 As: 1, 645 RouterId: "1.1.1.1", 646 ListenPort: 10179, 647 }, 648 }) 649 assert.Nil(err) 650 defer s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 651 652 g := &config.PeerGroup{ 653 Config: config.PeerGroupConfig{ 654 PeerAs: 2, 655 PeerGroupName: "g", 656 }, 657 Timers: config.Timers{ 658 Config: config.TimersConfig{ 659 ConnectRetry: 5, 660 }, 661 }, 662 } 663 err = s1.addPeerGroup(g) 664 assert.Nil(err) 665 666 d := &api.AddDynamicNeighborRequest{ 667 DynamicNeighbor: &api.DynamicNeighbor{ 668 Prefix: "127.0.0.0/24", 669 PeerGroup: "g", 670 }, 671 } 672 err = s1.AddDynamicNeighbor(context.Background(), d) 673 assert.Nil(err) 674 675 s2 := NewBgpServer() 676 go s2.Serve() 677 err = s2.StartBgp(context.Background(), &api.StartBgpRequest{ 678 Global: &api.Global{ 679 As: 2, 680 RouterId: "2.2.2.2", 681 ListenPort: -1, 682 }, 683 }) 684 assert.Nil(err) 685 defer s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 686 687 m := &config.Neighbor{ 688 Config: config.NeighborConfig{ 689 NeighborAddress: "127.0.0.1", 690 PeerAs: 1, 691 }, 692 Transport: config.Transport{ 693 Config: config.TransportConfig{ 694 RemotePort: 10179, 695 }, 696 }, 697 Timers: config.Timers{ 698 Config: config.TimersConfig{ 699 ConnectRetry: 5, 700 }, 701 }, 702 } 703 ch := make(chan struct{}) 704 go s2.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(peer *api.Peer) { 705 if peer.State.SessionState == api.PeerState_ESTABLISHED { 706 close(ch) 707 } 708 }) 709 err = s2.AddPeer(context.Background(), &api.AddPeerRequest{Peer: config.NewPeerFromConfigStruct(m)}) 710 assert.Nil(err) 711 <-ch 712 } 713 714 func TestGracefulRestartTimerExpired(t *testing.T) { 715 minConnectRetry = 5 716 717 assert := assert.New(t) 718 s1 := NewBgpServer() 719 go s1.Serve() 720 err := s1.StartBgp(context.Background(), &api.StartBgpRequest{ 721 Global: &api.Global{ 722 As: 1, 723 RouterId: "1.1.1.1", 724 ListenPort: 10179, 725 }, 726 }) 727 assert.Nil(err) 728 defer s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 729 730 n := &config.Neighbor{ 731 Config: config.NeighborConfig{ 732 NeighborAddress: "127.0.0.1", 733 PeerAs: 2, 734 }, 735 Transport: config.Transport{ 736 Config: config.TransportConfig{ 737 PassiveMode: true, 738 }, 739 }, 740 GracefulRestart: config.GracefulRestart{ 741 Config: config.GracefulRestartConfig{ 742 Enabled: true, 743 RestartTime: 5, 744 }, 745 }, 746 } 747 err = s1.addNeighbor(n) 748 assert.Nil(err) 749 750 s2 := NewBgpServer() 751 go s2.Serve() 752 err = s2.StartBgp(context.Background(), &api.StartBgpRequest{ 753 Global: &api.Global{ 754 As: 2, 755 RouterId: "2.2.2.2", 756 ListenPort: -1, 757 }, 758 }) 759 require.NoError(t, err) 760 defer s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 761 762 m := &config.Neighbor{ 763 Config: config.NeighborConfig{ 764 NeighborAddress: "127.0.0.1", 765 PeerAs: 1, 766 }, 767 Transport: config.Transport{ 768 Config: config.TransportConfig{ 769 RemotePort: 10179, 770 }, 771 }, 772 GracefulRestart: config.GracefulRestart{ 773 Config: config.GracefulRestartConfig{ 774 Enabled: true, 775 RestartTime: 1, 776 }, 777 }, 778 Timers: config.Timers{ 779 Config: config.TimersConfig{ 780 ConnectRetry: 5, 781 }, 782 }, 783 } 784 ch := make(chan struct{}) 785 go s2.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(peer *api.Peer) { 786 if peer.State.SessionState == api.PeerState_ESTABLISHED { 787 close(ch) 788 } 789 }) 790 err = s2.addNeighbor(m) 791 assert.Nil(err) 792 <-ch 793 794 // Force TCP session disconnected in order to cause Graceful Restart at s1 795 // side. 796 for _, n := range s2.neighborMap { 797 n.fsm.conn.Close() 798 } 799 s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 800 801 time.Sleep(5 * time.Second) 802 803 // Create dummy session which does NOT send BGP OPEN message in order to 804 // cause Graceful Restart timer expired. 805 var conn net.Conn 806 807 conn, err = net.Dial("tcp", "127.0.0.1:10179") 808 require.NoError(t, err) 809 defer conn.Close() 810 811 // this seems to take around 22 seconds... need to address this whole thing 812 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) 813 defer cancel() 814 815 done := make(chan struct{}) 816 // Waiting for Graceful Restart timer expired and moving on to IDLE state. 817 for { 818 s1.ListPeer(context.Background(), &api.ListPeerRequest{}, func(peer *api.Peer) { 819 if peer.State.SessionState == api.PeerState_IDLE { 820 close(done) 821 } 822 }) 823 824 select { 825 case <-done: 826 return 827 case <-ctx.Done(): 828 t.Fatalf("failed to enter IDLE state in the deadline") 829 return 830 } 831 } 832 } 833 834 func TestFamiliesForSoftreset(t *testing.T) { 835 f := func(f bgp.RouteFamily) config.AfiSafi { 836 return config.AfiSafi{ 837 State: config.AfiSafiState{ 838 Family: f, 839 }, 840 } 841 } 842 peer := &peer{ 843 fsm: &fsm{ 844 pConf: &config.Neighbor{ 845 AfiSafis: []config.AfiSafi{f(bgp.RF_RTC_UC), f(bgp.RF_IPv4_UC), f(bgp.RF_IPv6_UC)}, 846 }, 847 }, 848 } 849 850 families := familiesForSoftreset(peer, bgp.RF_IPv4_UC) 851 assert.Equal(t, len(families), 1) 852 assert.Equal(t, families[0], bgp.RF_IPv4_UC) 853 854 families = familiesForSoftreset(peer, bgp.RF_RTC_UC) 855 assert.Equal(t, len(families), 1) 856 assert.Equal(t, families[0], bgp.RF_RTC_UC) 857 858 families = familiesForSoftreset(peer, bgp.RouteFamily(0)) 859 assert.Equal(t, len(families), 2) 860 assert.NotContains(t, families, bgp.RF_RTC_UC) 861 } 862 863 func runNewServer(as uint32, routerID string, listenPort int32) *BgpServer { 864 s := NewBgpServer() 865 go s.Serve() 866 if err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 867 Global: &api.Global{ 868 As: as, 869 RouterId: routerID, 870 ListenPort: listenPort, 871 }, 872 }); err != nil { 873 log.Fatalf("Failed to start server %s: %s", s.bgpConfig.Global.Config.RouterId, err) 874 } 875 return s 876 } 877 878 func peerServers(t *testing.T, ctx context.Context, servers []*BgpServer, families []config.AfiSafiType) error { 879 for i, server := range servers { 880 for j, peer := range servers { 881 if i == j { 882 continue 883 } 884 885 neighborConfig := &config.Neighbor{ 886 Config: config.NeighborConfig{ 887 NeighborAddress: "127.0.0.1", 888 PeerAs: peer.bgpConfig.Global.Config.As, 889 }, 890 AfiSafis: config.AfiSafis{}, 891 Transport: config.Transport{ 892 Config: config.TransportConfig{ 893 RemotePort: uint16(peer.bgpConfig.Global.Config.Port), 894 }, 895 }, 896 Timers: config.Timers{ 897 Config: config.TimersConfig{ 898 ConnectRetry: 5, 899 }, 900 }, 901 } 902 903 // first server to get neighbor config is passive to hopefully make handshake faster 904 if j > i { 905 neighborConfig.Transport.Config.PassiveMode = true 906 } 907 908 for _, family := range families { 909 neighborConfig.AfiSafis = append(neighborConfig.AfiSafis, config.AfiSafi{ 910 Config: config.AfiSafiConfig{ 911 AfiSafiName: family, 912 Enabled: true, 913 }, 914 }) 915 } 916 917 if err := server.AddPeer(ctx, &api.AddPeerRequest{Peer: config.NewPeerFromConfigStruct(neighborConfig)}); err != nil { 918 t.Fatal(err) 919 } 920 } 921 } 922 923 return nil 924 } 925 926 func parseRDRT(rdStr string) (bgp.RouteDistinguisherInterface, bgp.ExtendedCommunityInterface, error) { 927 rd, err := bgp.ParseRouteDistinguisher(rdStr) 928 if err != nil { 929 return nil, nil, err 930 } 931 932 rt, err := bgp.ParseExtendedCommunity(bgp.EC_SUBTYPE_ROUTE_TARGET, rdStr) 933 if err != nil { 934 return nil, nil, err 935 } 936 return rd, rt, nil 937 } 938 939 func addVrf(t *testing.T, s *BgpServer, vrfName, rdStr string, id uint32) { 940 rd, rt, err := parseRDRT(rdStr) 941 if err != nil { 942 t.Fatal(err) 943 } 944 945 req := &api.AddVrfRequest{ 946 Vrf: &api.Vrf{ 947 Name: vrfName, 948 ImportRt: apiutil.MarshalRTs([]bgp.ExtendedCommunityInterface{rt}), 949 ExportRt: apiutil.MarshalRTs([]bgp.ExtendedCommunityInterface{rt}), 950 Rd: apiutil.MarshalRD(rd), 951 Id: id, 952 }, 953 } 954 if err = s.AddVrf(context.Background(), req); err != nil { 955 t.Fatal(err) 956 } 957 } 958 959 func TestDoNotReactToDuplicateRTCMemberships(t *testing.T) { 960 minConnectRetry = 5 961 962 ctx := context.Background() 963 log.SetLevel(log.DebugLevel) 964 965 s1 := runNewServer(1, "1.1.1.1", 10179) 966 s2 := runNewServer(1, "2.2.2.2", 20179) 967 968 addVrf(t, s1, "vrf1", "111:111", 1) 969 addVrf(t, s2, "vrf1", "111:111", 1) 970 971 if err := peerServers(t, ctx, []*BgpServer{s1, s2}, []config.AfiSafiType{config.AFI_SAFI_TYPE_L3VPN_IPV4_UNICAST, config.AFI_SAFI_TYPE_RTC}); err != nil { 972 t.Fatal(err) 973 } 974 watcher := s1.watch(watchUpdate(true)) 975 976 // Add route to vrf1 on s2 977 attrs := []bgp.PathAttributeInterface{ 978 bgp.NewPathAttributeOrigin(0), 979 bgp.NewPathAttributeNextHop("2.2.2.2"), 980 } 981 prefix := bgp.NewIPAddrPrefix(24, "10.30.2.0") 982 path := apiutil.NewPath(prefix, false, attrs, time.Now()) 983 984 if _, err := s2.AddPath(ctx, &api.AddPathRequest{ 985 TableType: api.TableType_VRF, 986 VrfId: "vrf1", 987 Path: path, 988 }); err != nil { 989 t.Fatal(err) 990 } 991 992 // s1 should receive this route from s2 993 t1 := time.NewTimer(time.Duration(30 * time.Second)) 994 for found := false; !found; { 995 select { 996 case ev := <-watcher.Event(): 997 switch msg := ev.(type) { 998 case *watchEventUpdate: 999 for _, path := range msg.PathList { 1000 log.Infof("tester received path: %s", path.String()) 1001 if vpnPath, ok := path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix); ok { 1002 if vpnPath.Prefix.Equal(prefix.Prefix) { 1003 log.Infof("tester found expected prefix: %s", vpnPath.Prefix) 1004 found = true 1005 } else { 1006 log.Infof("unknown prefix %s != %s", vpnPath.Prefix, prefix.Prefix) 1007 } 1008 } 1009 } 1010 } 1011 case <-t1.C: 1012 t.Fatalf("timeout while waiting for update path event") 1013 } 1014 } 1015 t1.Stop() 1016 1017 // fabricate duplicated rtc message from s1 1018 // s2 should not send vpn route again 1019 _, rt, err := parseRDRT("111:111") 1020 if err != nil { 1021 t.Fatal(err) 1022 } 1023 rtcNLRI := bgp.NewRouteTargetMembershipNLRI(1, rt) 1024 rtcPath := table.NewPath(&table.PeerInfo{ 1025 AS: 1, 1026 Address: net.ParseIP("127.0.0.1"), 1027 LocalID: net.ParseIP("2.2.2.2"), 1028 ID: net.ParseIP("1.1.1.1"), 1029 }, rtcNLRI, false, []bgp.PathAttributeInterface{ 1030 bgp.NewPathAttributeOrigin(0), 1031 bgp.NewPathAttributeNextHop("1.1.1.1"), 1032 }, time.Now(), false) 1033 1034 s1Peer := s2.neighborMap["127.0.0.1"] 1035 s2.propagateUpdate(s1Peer, []*table.Path{rtcPath}) 1036 1037 t2 := time.NewTimer(time.Duration(2 * time.Second)) 1038 for done := false; !done; { 1039 select { 1040 case ev := <-watcher.Event(): 1041 switch msg := ev.(type) { 1042 case *watchEventUpdate: 1043 for _, path := range msg.PathList { 1044 log.Infof("tester received path: %s", path.String()) 1045 if vpnPath, ok := path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix); ok { 1046 t.Fatalf("vpn prefix %s was unexpectedly received", vpnPath.Prefix) 1047 } 1048 } 1049 } 1050 case <-t2.C: 1051 log.Infof("await update done") 1052 done = true 1053 } 1054 } 1055 1056 s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 1057 s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 1058 } 1059 1060 func TestAddDeletePath(t *testing.T) { 1061 ctx := context.Background() 1062 s := runNewServer(1, "1.1.1.1", 10179) 1063 1064 nlri, _ := ptypes.MarshalAny(&api.IPAddressPrefix{ 1065 Prefix: "10.0.0.0", 1066 PrefixLen: 24, 1067 }) 1068 1069 a1, _ := ptypes.MarshalAny(&api.OriginAttribute{ 1070 Origin: 0, 1071 }) 1072 a2, _ := ptypes.MarshalAny(&api.NextHopAttribute{ 1073 NextHop: "10.0.0.1", 1074 }) 1075 attrs := []*any.Any{a1, a2} 1076 1077 family := &api.Family{ 1078 Afi: api.Family_AFI_IP, 1079 Safi: api.Family_SAFI_UNICAST, 1080 } 1081 1082 listRib := func() []*api.Destination { 1083 l := make([]*api.Destination, 0) 1084 s.ListPath(ctx, &api.ListPathRequest{TableType: api.TableType_GLOBAL, Family: family}, func(d *api.Destination) { l = append(l, d) }) 1085 return l 1086 } 1087 1088 var err error 1089 // DeletePath(AddPath()) without PeerInfo 1090 getPath := func() *api.Path { 1091 return &api.Path{ 1092 Family: family, 1093 Nlri: nlri, 1094 Pattrs: attrs, 1095 } 1096 } 1097 1098 p1 := getPath() 1099 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1100 TableType: api.TableType_GLOBAL, 1101 Path: p1, 1102 }) 1103 assert.Nil(t, err) 1104 assert.Equal(t, len(listRib()), 1) 1105 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1106 TableType: api.TableType_GLOBAL, 1107 Path: p1, 1108 }) 1109 assert.Nil(t, err) 1110 assert.Equal(t, len(listRib()), 0) 1111 1112 // DeletePath(ListPath()) without PeerInfo 1113 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1114 TableType: api.TableType_GLOBAL, 1115 Path: p1, 1116 }) 1117 assert.Nil(t, err) 1118 l := listRib() 1119 assert.Equal(t, len(l), 1) 1120 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1121 TableType: api.TableType_GLOBAL, 1122 Path: l[0].Paths[0], 1123 }) 1124 assert.Nil(t, err) 1125 assert.Equal(t, len(listRib()), 0) 1126 1127 p2 := getPath() 1128 p2.SourceAsn = 1 1129 p2.SourceId = "1.1.1.1" 1130 1131 // DeletePath(AddPath()) with PeerInfo 1132 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1133 TableType: api.TableType_GLOBAL, 1134 Path: p2, 1135 }) 1136 assert.Nil(t, err) 1137 assert.Equal(t, len(listRib()), 1) 1138 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1139 TableType: api.TableType_GLOBAL, 1140 Path: p2, 1141 }) 1142 assert.Nil(t, err) 1143 assert.Equal(t, len(listRib()), 0) 1144 1145 // DeletePath(ListPath()) with PeerInfo 1146 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1147 TableType: api.TableType_GLOBAL, 1148 Path: p2, 1149 }) 1150 assert.Nil(t, err) 1151 l = listRib() 1152 assert.Equal(t, len(l), 1) 1153 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1154 TableType: api.TableType_GLOBAL, 1155 Path: l[0].Paths[0], 1156 }) 1157 assert.Nil(t, err) 1158 assert.Equal(t, len(listRib()), 0) 1159 1160 // DeletePath(AddPath()) with different PeerInfo 1161 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1162 TableType: api.TableType_GLOBAL, 1163 Path: p2, 1164 }) 1165 assert.Nil(t, err) 1166 assert.Equal(t, len(listRib()), 1) 1167 p3 := getPath() 1168 p3.SourceAsn = 2 1169 p3.SourceId = "1.1.1.2" 1170 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1171 TableType: api.TableType_GLOBAL, 1172 Path: p3, 1173 }) 1174 assert.Nil(t, err) 1175 assert.Equal(t, len(listRib()), 1) 1176 }