github.com/osrg/gobgp/v3@v3.30.0/pkg/server/server_test.go (about) 1 // Copyright (C) 2016-2021 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 "sort" 24 "strconv" 25 "testing" 26 "time" 27 28 "github.com/google/go-cmp/cmp" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 apb "google.golang.org/protobuf/types/known/anypb" 32 33 api "github.com/osrg/gobgp/v3/api" 34 "github.com/osrg/gobgp/v3/internal/pkg/table" 35 "github.com/osrg/gobgp/v3/pkg/apiutil" 36 "github.com/osrg/gobgp/v3/pkg/config/oc" 37 "github.com/osrg/gobgp/v3/pkg/log" 38 "github.com/osrg/gobgp/v3/pkg/packet/bgp" 39 ) 40 41 var logger = log.NewDefaultLogger() 42 43 func TestStop(t *testing.T) { 44 assert := assert.New(t) 45 s := NewBgpServer() 46 go s.Serve() 47 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 48 Global: &api.Global{ 49 Asn: 1, 50 RouterId: "1.1.1.1", 51 ListenPort: -1, 52 }, 53 }) 54 assert.Nil(err) 55 s.StopBgp(context.Background(), &api.StopBgpRequest{}) 56 57 s = NewBgpServer() 58 go s.Serve() 59 err = s.StartBgp(context.Background(), &api.StartBgpRequest{ 60 Global: &api.Global{ 61 Asn: 1, 62 RouterId: "1.1.1.1", 63 ListenPort: -1, 64 }, 65 }) 66 assert.Nil(err) 67 p := &api.Peer{ 68 Conf: &api.PeerConf{ 69 NeighborAddress: "2.2.2.2", 70 PeerAsn: 1, 71 }, 72 RouteServer: &api.RouteServer{ 73 RouteServerClient: true, 74 }, 75 } 76 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p}) 77 assert.Nil(err) 78 79 err = s.AddPeer(context.Background(), &api.AddPeerRequest{}) 80 assert.Error(err) 81 82 s.StopBgp(context.Background(), &api.StopBgpRequest{}) 83 } 84 85 func TestModPolicyAssign(t *testing.T) { 86 assert := assert.New(t) 87 s := NewBgpServer() 88 go s.Serve() 89 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 90 Global: &api.Global{ 91 Asn: 1, 92 RouterId: "1.1.1.1", 93 ListenPort: -1, 94 }, 95 }) 96 assert.Nil(err) 97 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 98 99 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: "p1"})}) 100 assert.Nil(err) 101 102 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: "p2"})}) 103 assert.Nil(err) 104 105 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: "p3"})}) 106 assert.Nil(err) 107 108 f := func(l []*oc.PolicyDefinition) *api.PolicyAssignment { 109 pl := make([]*api.Policy, 0, len(l)) 110 for _, d := range l { 111 pl = append(pl, table.ToPolicyApi(d)) 112 } 113 return &api.PolicyAssignment{ 114 Policies: pl, 115 } 116 } 117 118 r := f([]*oc.PolicyDefinition{{Name: "p1"}, {Name: "p2"}, {Name: "p3"}}) 119 r.Direction = api.PolicyDirection_IMPORT 120 r.DefaultAction = api.RouteAction_ACCEPT 121 r.Name = table.GLOBAL_RIB_NAME 122 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{Assignment: r}) 123 assert.Nil(err) 124 125 r.Direction = api.PolicyDirection_EXPORT 126 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{Assignment: r}) 127 assert.Nil(err) 128 129 var ps []*api.PolicyAssignment 130 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 131 Name: table.GLOBAL_RIB_NAME, 132 Direction: api.PolicyDirection_IMPORT}, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 133 assert.Nil(err) 134 assert.Equal(len(ps[0].Policies), 3) 135 136 r = f([]*oc.PolicyDefinition{{Name: "p1"}}) 137 r.Direction = api.PolicyDirection_IMPORT 138 r.DefaultAction = api.RouteAction_ACCEPT 139 r.Name = table.GLOBAL_RIB_NAME 140 err = s.DeletePolicyAssignment(context.Background(), &api.DeletePolicyAssignmentRequest{Assignment: r}) 141 assert.Nil(err) 142 143 ps = []*api.PolicyAssignment{} 144 s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 145 Name: table.GLOBAL_RIB_NAME, 146 Direction: api.PolicyDirection_IMPORT}, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 147 assert.Equal(len(ps[0].Policies), 2) 148 149 ps = []*api.PolicyAssignment{} 150 s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 151 Name: table.GLOBAL_RIB_NAME, 152 }, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 153 assert.Equal(len(ps), 2) 154 } 155 156 func TestListPolicyAssignment(t *testing.T) { 157 assert := assert.New(t) 158 159 s := NewBgpServer() 160 go s.Serve() 161 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 162 Global: &api.Global{ 163 Asn: 1, 164 RouterId: "1.1.1.1", 165 ListenPort: -1, 166 }, 167 }) 168 assert.Nil(err) 169 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 170 171 for i := 1; i < 4; i++ { 172 addr := "127.0.0." + strconv.Itoa(i) 173 p := &api.Peer{ 174 Conf: &api.PeerConf{ 175 NeighborAddress: addr, 176 PeerAsn: uint32(i + 1), 177 }, 178 RouteServer: &api.RouteServer{ 179 RouteServerClient: true, 180 }, 181 } 182 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p}) 183 assert.Nil(err) 184 185 err = s.AddPolicy(context.Background(), 186 &api.AddPolicyRequest{Policy: table.NewAPIPolicyFromTableStruct(&table.Policy{Name: fmt.Sprintf("p%d", i)})}) 187 assert.Nil(err) 188 189 pa := &api.PolicyAssignment{ 190 Direction: api.PolicyDirection_IMPORT, 191 DefaultAction: api.RouteAction_ACCEPT, 192 Name: addr, 193 Policies: []*api.Policy{{Name: fmt.Sprintf("p%d", i)}}, 194 } 195 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{Assignment: pa}) 196 assert.Nil(err) 197 } 198 199 ps := []*api.PolicyAssignment{} 200 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 201 Name: table.GLOBAL_RIB_NAME, 202 }, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 203 assert.Nil(err) 204 assert.Equal(2, len(ps)) 205 206 ps = []*api.PolicyAssignment{} 207 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{}, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 208 assert.Nil(err) 209 assert.Equal(8, len(ps)) 210 211 ps = []*api.PolicyAssignment{} 212 err = s.ListPolicyAssignment(context.Background(), &api.ListPolicyAssignmentRequest{ 213 Direction: api.PolicyDirection_EXPORT, 214 }, func(p *api.PolicyAssignment) { ps = append(ps, p) }) 215 assert.Nil(err) 216 assert.Equal(4, len(ps)) 217 } 218 219 func waitState(s *BgpServer, ch chan struct{}, state api.PeerState_SessionState) { 220 watchCtx, watchCancel := context.WithCancel(context.Background()) 221 s.WatchEvent(watchCtx, &api.WatchEventRequest{Peer: &api.WatchEventRequest_Peer{}}, func(r *api.WatchEventResponse) { 222 if peer := r.GetPeer(); peer != nil { 223 if peer.Type == api.WatchEventResponse_PeerEvent_STATE && peer.Peer.State.SessionState == state { 224 close(ch) 225 watchCancel() 226 } 227 } 228 }) 229 } 230 231 func waitActive(s *BgpServer, ch chan struct{}) { 232 waitState(s, ch, api.PeerState_ACTIVE) 233 } 234 235 func waitEstablished(s *BgpServer, ch chan struct{}) { 236 waitState(s, ch, api.PeerState_ESTABLISHED) 237 } 238 239 func TestListPathEnableFiltered(test *testing.T) { 240 assert := assert.New(test) 241 242 // Create servers and add peers 243 server1 := NewBgpServer() 244 go server1.Serve() 245 err := server1.StartBgp(context.Background(), &api.StartBgpRequest{ 246 Global: &api.Global{ 247 Asn: 1, 248 RouterId: "1.1.1.1", 249 ListenPort: 10179, 250 }, 251 }) 252 assert.Nil(err) 253 defer server1.StopBgp(context.Background(), &api.StopBgpRequest{}) 254 255 server2 := NewBgpServer() 256 go server2.Serve() 257 err = server2.StartBgp(context.Background(), &api.StartBgpRequest{ 258 Global: &api.Global{ 259 Asn: 2, 260 RouterId: "2.2.2.2", 261 ListenPort: -1, 262 }, 263 }) 264 assert.Nil(err) 265 defer server2.StopBgp(context.Background(), &api.StopBgpRequest{}) 266 267 peer1 := &api.Peer{ 268 Conf: &api.PeerConf{ 269 NeighborAddress: "127.0.0.1", 270 PeerAsn: 2, 271 }, 272 Transport: &api.Transport{ 273 PassiveMode: true, 274 }, 275 } 276 err = server1.AddPeer(context.Background(), &api.AddPeerRequest{Peer: peer1}) 277 assert.Nil(err) 278 279 peer2 := &api.Peer{ 280 Conf: &api.PeerConf{ 281 NeighborAddress: "127.0.0.1", 282 PeerAsn: 1, 283 }, 284 Transport: &api.Transport{ 285 RemotePort: 10179, 286 }, 287 Timers: &api.Timers{ 288 Config: &api.TimersConfig{ 289 ConnectRetry: 1, 290 IdleHoldTimeAfterReset: 1, 291 }, 292 }, 293 } 294 ch := make(chan struct{}) 295 go waitEstablished(server1, ch) 296 297 err = server2.AddPeer(context.Background(), &api.AddPeerRequest{Peer: peer2}) 298 assert.Nil(err) 299 <-ch 300 301 // Add IMPORT policy at server1 for rejecting 10.1.0.0/24 302 d1 := &api.DefinedSet{ 303 DefinedType: api.DefinedType_PREFIX, 304 Name: "d1", 305 Prefixes: []*api.Prefix{ 306 { 307 IpPrefix: "10.1.0.0/24", 308 MaskLengthMax: 24, 309 MaskLengthMin: 24, 310 }, 311 }, 312 } 313 s1 := &api.Statement{ 314 Name: "s1", 315 Conditions: &api.Conditions{ 316 PrefixSet: &api.MatchSet{ 317 Name: "d1", 318 }, 319 }, 320 Actions: &api.Actions{ 321 RouteAction: api.RouteAction_REJECT, 322 }, 323 } 324 err = server1.AddDefinedSet(context.Background(), &api.AddDefinedSetRequest{DefinedSet: d1}) 325 assert.Nil(err) 326 p1 := &api.Policy{ 327 Name: "p1", 328 Statements: []*api.Statement{s1}, 329 } 330 err = server1.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: p1}) 331 assert.Nil(err) 332 err = server1.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{ 333 Assignment: &api.PolicyAssignment{ 334 Name: table.GLOBAL_RIB_NAME, 335 Direction: api.PolicyDirection_IMPORT, 336 Policies: []*api.Policy{p1}, 337 DefaultAction: api.RouteAction_ACCEPT, 338 }, 339 }) 340 assert.Nil(err) 341 342 // Add EXPORT policy at server2 for accepting all routes and adding communities. 343 commSet, _ := table.NewCommunitySet(oc.CommunitySet{ 344 CommunitySetName: "comset1", 345 CommunityList: []string{"100:100"}, 346 }) 347 server2.policy.AddDefinedSet(commSet, false) 348 349 statement := oc.Statement{ 350 Name: "stmt1", 351 Actions: oc.Actions{ 352 BgpActions: oc.BgpActions{ 353 SetCommunity: oc.SetCommunity{ 354 SetCommunityMethod: oc.SetCommunityMethod{ 355 CommunitiesList: []string{"100:100"}, 356 }, 357 Options: string(oc.BGP_SET_COMMUNITY_OPTION_TYPE_ADD), 358 }, 359 }, 360 RouteDisposition: oc.ROUTE_DISPOSITION_ACCEPT_ROUTE, 361 }, 362 } 363 policy := oc.PolicyDefinition{ 364 Name: "policy1", 365 Statements: []oc.Statement{statement}, 366 } 367 p, err := table.NewPolicy(policy) 368 if err != nil { 369 test.Fatalf("cannot create new policy: %v", err) 370 } 371 server2.policy.AddPolicy(p, false) 372 policies := []*oc.PolicyDefinition{ 373 { 374 Name: "policy1", 375 }, 376 } 377 server2.policy.AddPolicyAssignment(table.GLOBAL_RIB_NAME, table.POLICY_DIRECTION_EXPORT, policies, table.ROUTE_TYPE_REJECT) 378 379 // Add IMPORT policy at server1 for accepting all routes and replacing communities. 380 statement = oc.Statement{ 381 Name: "stmt1", 382 Actions: oc.Actions{ 383 BgpActions: oc.BgpActions{ 384 SetCommunity: oc.SetCommunity{ 385 SetCommunityMethod: oc.SetCommunityMethod{ 386 CommunitiesList: []string{"200:200"}, 387 }, 388 Options: string(oc.BGP_SET_COMMUNITY_OPTION_TYPE_REPLACE), 389 }, 390 }, 391 RouteDisposition: oc.ROUTE_DISPOSITION_ACCEPT_ROUTE, 392 }, 393 } 394 policy = oc.PolicyDefinition{ 395 Name: "policy1", 396 Statements: []oc.Statement{statement}, 397 } 398 p, err = table.NewPolicy(policy) 399 if err != nil { 400 test.Fatalf("cannot create new policy: %v", err) 401 } 402 server1.policy.AddPolicy(p, false) 403 policies = []*oc.PolicyDefinition{ 404 { 405 Name: "policy1", 406 }, 407 } 408 server1.policy.AddPolicyAssignment(table.GLOBAL_RIB_NAME, table.POLICY_DIRECTION_IMPORT, policies, table.ROUTE_TYPE_REJECT) 409 410 // Add paths 411 family := &api.Family{ 412 Afi: api.Family_AFI_IP, 413 Safi: api.Family_SAFI_UNICAST, 414 } 415 416 nlri1, _ := apb.New(&api.IPAddressPrefix{ 417 Prefix: "10.1.0.0", 418 PrefixLen: 24, 419 }) 420 421 a1, _ := apb.New(&api.OriginAttribute{ 422 Origin: 0, 423 }) 424 a2, _ := apb.New(&api.NextHopAttribute{ 425 NextHop: "10.0.0.1", 426 }) 427 attrs := []*apb.Any{a1, a2} 428 429 server2.AddPath(context.Background(), &api.AddPathRequest{ 430 TableType: api.TableType_GLOBAL, 431 Path: &api.Path{ 432 Family: family, 433 Nlri: nlri1, 434 Pattrs: attrs, 435 }, 436 }) 437 438 nlri2, _ := apb.New(&api.IPAddressPrefix{ 439 Prefix: "10.2.0.0", 440 PrefixLen: 24, 441 }) 442 server2.AddPath(context.Background(), &api.AddPathRequest{ 443 TableType: api.TableType_GLOBAL, 444 Path: &api.Path{ 445 Family: family, 446 Nlri: nlri2, 447 Pattrs: attrs, 448 }, 449 }) 450 451 var wantEmptyCommunities []uint32 452 wantCommunitiesAfterExportPolicies := []uint32{100<<16 | 100} 453 wantCommunitiesAfterImportPolicies := []uint32{200<<16 | 200} 454 455 // Check ADJ_OUT routes before applying export policies. 456 for { 457 count := 0 458 server2.ListPath(context.Background(), &api.ListPathRequest{ 459 TableType: api.TableType_ADJ_OUT, 460 Family: family, Name: "127.0.0.1", 461 // TODO(wenovus): This is confusing and we may want to change this. 462 EnableFiltered: true, 463 }, func(d *api.Destination) { 464 count++ 465 for _, path := range d.Paths { 466 var comms []uint32 467 for _, attr := range path.GetPattrs() { 468 m, err := attr.UnmarshalNew() 469 if err != nil { 470 test.Fatalf("Unable to unmarshal a GoBGP path attribute: %v", err) 471 continue 472 } 473 switch m := m.(type) { 474 case *api.CommunitiesAttribute: 475 comms = m.GetCommunities() 476 } 477 } 478 if diff := cmp.Diff(wantEmptyCommunities, comms); diff != "" { 479 test.Errorf("AdjRibOutPre communities for %v (-want, +got):\n%s", d.GetPrefix(), diff) 480 } else { 481 test.Logf("Got expected communities for %v: %v", d.GetPrefix(), comms) 482 } 483 } 484 }) 485 if count == 2 { 486 break 487 } 488 } 489 // Check ADJ_OUT routes after applying export policies. 490 for { 491 count := 0 492 server2.ListPath(context.Background(), &api.ListPathRequest{ 493 TableType: api.TableType_ADJ_OUT, 494 Family: family, Name: "127.0.0.1", 495 // TODO(wenovus): This is confusing and we may want to change this. 496 EnableFiltered: false, 497 }, func(d *api.Destination) { 498 count++ 499 for _, path := range d.Paths { 500 if path.Filtered { 501 continue 502 } 503 var comms []uint32 504 for _, attr := range path.GetPattrs() { 505 m, err := attr.UnmarshalNew() 506 if err != nil { 507 test.Fatalf("Unable to unmarshal a GoBGP path attribute: %v", err) 508 continue 509 } 510 switch m := m.(type) { 511 case *api.CommunitiesAttribute: 512 comms = m.GetCommunities() 513 } 514 } 515 if diff := cmp.Diff(wantCommunitiesAfterExportPolicies, comms); diff != "" { 516 test.Errorf("AdjRibOutPost communities for %v (-want, +got):\n%s", d.GetPrefix(), diff) 517 } else { 518 test.Logf("Got expected communities for %v: %v", d.GetPrefix(), comms) 519 } 520 } 521 }) 522 if count == 2 { 523 break 524 } 525 } 526 // Check ADJ_IN routes before applying import policies. 527 for { 528 count := 0 529 server1.ListPath(context.Background(), &api.ListPathRequest{ 530 TableType: api.TableType_ADJ_IN, 531 Family: family, 532 Name: "127.0.0.1", 533 EnableFiltered: false, 534 }, func(d *api.Destination) { 535 count++ 536 for _, path := range d.Paths { 537 var comms []uint32 538 for _, attr := range path.GetPattrs() { 539 m, err := attr.UnmarshalNew() 540 if err != nil { 541 test.Fatalf("Unable to unmarshal a GoBGP path attribute: %v", err) 542 continue 543 } 544 switch m := m.(type) { 545 case *api.CommunitiesAttribute: 546 comms = m.GetCommunities() 547 } 548 } 549 if diff := cmp.Diff(wantCommunitiesAfterExportPolicies, comms); diff != "" { 550 test.Errorf("AdjRibInPre communities for %v (-want, +got):\n%s", d.GetPrefix(), diff) 551 } else { 552 test.Logf("Got expected communities for %v: %v", d.GetPrefix(), comms) 553 } 554 } 555 }) 556 if count == 2 { 557 break 558 } 559 } 560 // Check ADJ_IN routes after applying import policies. 561 for { 562 count := 0 563 server1.ListPath(context.Background(), &api.ListPathRequest{ 564 TableType: api.TableType_ADJ_IN, 565 Family: family, 566 Name: "127.0.0.1", 567 EnableFiltered: true, 568 }, func(d *api.Destination) { 569 count++ 570 for _, path := range d.Paths { 571 if path.Filtered { 572 continue 573 } 574 var comms []uint32 575 for _, attr := range path.GetPattrs() { 576 m, err := attr.UnmarshalNew() 577 if err != nil { 578 test.Fatalf("Unable to unmarshal a GoBGP path attribute: %v", err) 579 continue 580 } 581 switch m := m.(type) { 582 case *api.CommunitiesAttribute: 583 comms = m.GetCommunities() 584 } 585 } 586 if diff := cmp.Diff(wantCommunitiesAfterImportPolicies, comms); diff != "" { 587 test.Errorf("AdjRibInPost communities for %v (-want, +got):\n%s", d.GetPrefix(), diff) 588 } else { 589 test.Logf("Got expected communities for %v: %v", d.GetPrefix(), comms) 590 } 591 } 592 }) 593 if count == 2 { 594 break 595 } 596 } 597 598 // Check that 10.1.0.0/24 is filtered at the import side. 599 count := 0 600 server1.ListPath(context.Background(), &api.ListPathRequest{TableType: api.TableType_GLOBAL, Family: family}, func(d *api.Destination) { 601 count++ 602 }) 603 assert.Equal(1, count) 604 605 filtered := 0 606 server1.ListPath(context.Background(), &api.ListPathRequest{TableType: api.TableType_ADJ_IN, Family: family, Name: "127.0.0.1", EnableFiltered: true}, func(d *api.Destination) { 607 if d.Paths[0].Filtered { 608 filtered++ 609 } 610 }) 611 assert.Equal(1, filtered) 612 613 // Validate filtering at the export side. 614 d2 := &api.DefinedSet{ 615 DefinedType: api.DefinedType_PREFIX, 616 Name: "d2", 617 Prefixes: []*api.Prefix{ 618 { 619 IpPrefix: "10.3.0.0/24", 620 MaskLengthMax: 24, 621 MaskLengthMin: 24, 622 }, 623 }, 624 } 625 s2 := &api.Statement{ 626 Name: "s2", 627 Conditions: &api.Conditions{ 628 PrefixSet: &api.MatchSet{ 629 Name: "d2", 630 }, 631 }, 632 Actions: &api.Actions{ 633 RouteAction: api.RouteAction_REJECT, 634 }, 635 } 636 err = server1.AddDefinedSet(context.Background(), &api.AddDefinedSetRequest{DefinedSet: d2}) 637 assert.Nil(err) 638 p2 := &api.Policy{ 639 Name: "p2", 640 Statements: []*api.Statement{s2}, 641 } 642 err = server1.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: p2}) 643 assert.Nil(err) 644 err = server1.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{ 645 Assignment: &api.PolicyAssignment{ 646 Name: table.GLOBAL_RIB_NAME, 647 Direction: api.PolicyDirection_EXPORT, 648 Policies: []*api.Policy{p2}, 649 DefaultAction: api.RouteAction_ACCEPT, 650 }, 651 }) 652 assert.Nil(err) 653 654 nlri3, _ := apb.New(&api.IPAddressPrefix{ 655 Prefix: "10.3.0.0", 656 PrefixLen: 24, 657 }) 658 server1.AddPath(context.Background(), &api.AddPathRequest{ 659 TableType: api.TableType_GLOBAL, 660 Path: &api.Path{ 661 Family: family, 662 Nlri: nlri3, 663 Pattrs: attrs, 664 }, 665 }) 666 667 nlri4, _ := apb.New(&api.IPAddressPrefix{ 668 Prefix: "10.4.0.0", 669 PrefixLen: 24, 670 }) 671 server1.AddPath(context.Background(), &api.AddPathRequest{ 672 TableType: api.TableType_GLOBAL, 673 Path: &api.Path{ 674 Family: family, 675 Nlri: nlri4, 676 Pattrs: attrs, 677 }, 678 }) 679 680 count = 0 681 server1.ListPath(context.Background(), &api.ListPathRequest{TableType: api.TableType_GLOBAL, Family: family}, func(d *api.Destination) { 682 count++ 683 }) 684 assert.Equal(3, count) 685 686 count = 0 687 filtered = 0 688 server1.ListPath(context.Background(), &api.ListPathRequest{TableType: api.TableType_ADJ_OUT, Family: family, Name: "127.0.0.1", EnableFiltered: true}, func(d *api.Destination) { 689 count++ 690 if d.Paths[0].Filtered { 691 filtered++ 692 } 693 }) 694 assert.Equal(2, count) 695 assert.Equal(1, filtered) 696 } 697 698 func TestMonitor(test *testing.T) { 699 assert := assert.New(test) 700 s := NewBgpServer() 701 go s.Serve() 702 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 703 Global: &api.Global{ 704 Asn: 1, 705 RouterId: "1.1.1.1", 706 ListenPort: 10179, 707 }, 708 }) 709 assert.Nil(err) 710 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 711 712 // Vrf1 111:111 and vrf2 import 111:111 and 222:222 713 addVrf(test, s, "vrf1", "111:111", []string{"111:111"}, []string{"111:111"}, 1) 714 addVrf(test, s, "vrf2", "222:222", []string{"111:111", "222:222"}, []string{"222:222"}, 2) 715 716 p1 := &api.Peer{ 717 Conf: &api.PeerConf{ 718 NeighborAddress: "127.0.0.1", 719 PeerAsn: 2, 720 }, 721 Transport: &api.Transport{ 722 PassiveMode: true, 723 }, 724 } 725 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p1}) 726 assert.Nil(err) 727 728 t := NewBgpServer() 729 go t.Serve() 730 err = t.StartBgp(context.Background(), &api.StartBgpRequest{ 731 Global: &api.Global{ 732 Asn: 2, 733 RouterId: "2.2.2.2", 734 ListenPort: -1, 735 }, 736 }) 737 assert.Nil(err) 738 defer t.StopBgp(context.Background(), &api.StopBgpRequest{}) 739 740 p2 := &api.Peer{ 741 Conf: &api.PeerConf{ 742 NeighborAddress: "127.0.0.1", 743 PeerAsn: 1, 744 }, 745 Transport: &api.Transport{ 746 RemotePort: 10179, 747 }, 748 Timers: &api.Timers{ 749 Config: &api.TimersConfig{ 750 ConnectRetry: 1, 751 IdleHoldTimeAfterReset: 1, 752 }, 753 }, 754 } 755 ch := make(chan struct{}) 756 go waitEstablished(s, ch) 757 // go t.MonitorPeer(context.Background(), &api.MonitorPeerRequest{}, func(peer *api.Peer) { 758 // if peer.State.SessionState == api.PeerState_ESTABLISHED { 759 // close(ch) 760 // } 761 // }) 762 763 err = t.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p2}) 764 assert.Nil(err) 765 766 <-ch 767 768 // Test WatchBestPath. 769 w := s.watch(watchBestPath(false)) 770 771 // Advertises a route. 772 attrs := []bgp.PathAttributeInterface{ 773 bgp.NewPathAttributeOrigin(0), 774 bgp.NewPathAttributeNextHop("10.0.0.1"), 775 } 776 prefix := bgp.NewIPAddrPrefix(24, "10.0.0.0") 777 path, _ := apiutil.NewPath(prefix, false, attrs, time.Now()) 778 if _, err := t.AddPath(context.Background(), &api.AddPathRequest{ 779 TableType: api.TableType_GLOBAL, 780 Path: path, 781 }); err != nil { 782 test.Fatal(err) 783 } 784 785 ev := <-w.Event() 786 b := ev.(*watchEventBestPath) 787 assert.Equal(1, len(b.PathList)) 788 assert.Equal("10.0.0.0/24", b.PathList[0].GetNlri().String()) 789 assert.False(b.PathList[0].IsWithdraw) 790 assert.Equal(1, len(b.Vrf)) 791 assert.True(b.Vrf[0]) 792 793 // Withdraws the previous route. 794 // NOTE: Withdraw should not require any path attribute. 795 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), true, nil, time.Now(), false)}); err != nil { 796 test.Error(err) 797 } 798 ev = <-w.Event() 799 b = ev.(*watchEventBestPath) 800 assert.Equal(1, len(b.PathList)) 801 assert.Equal("10.0.0.0/24", b.PathList[0].GetNlri().String()) 802 assert.True(b.PathList[0].IsWithdraw) 803 assert.Equal(1, len(b.Vrf)) 804 assert.True(b.Vrf[0]) 805 806 // Stops the watcher still having an item. 807 w.Stop() 808 809 // Prepares an initial route to test WatchUpdate with "current" flag. 810 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.1.0.0"), false, attrs, time.Now(), false)}); err != nil { 811 test.Error(err) 812 } 813 for { 814 // Waits for the initial route will be advertised. 815 rib, _, err := s.getRib("", bgp.RF_IPv4_UC, nil) 816 if err != nil { 817 test.Error(err) 818 } 819 if len(rib.GetKnownPathList("", 0)) > 0 { 820 break 821 } 822 time.Sleep(100 * time.Millisecond) 823 } 824 825 // Test WatchUpdate with "current" flag. 826 w = s.watch(watchUpdate(true, "", "")) 827 828 // Test the initial route. 829 ev = <-w.Event() 830 u := ev.(*watchEventUpdate) 831 assert.Equal(1, len(u.PathList)) 832 assert.Equal("10.1.0.0/24", u.PathList[0].GetNlri().String()) 833 assert.False(u.PathList[0].IsWithdraw) 834 ev = <-w.Event() 835 u = ev.(*watchEventUpdate) 836 assert.Equal(len(u.PathList), 0) // End of RIB 837 838 // Advertises an additional route. 839 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.2.0.0"), false, attrs, time.Now(), false)}); err != nil { 840 test.Error(err) 841 } 842 ev = <-w.Event() 843 u = ev.(*watchEventUpdate) 844 assert.Equal(1, len(u.PathList)) 845 assert.Equal("10.2.0.0/24", u.PathList[0].GetNlri().String()) 846 assert.False(u.PathList[0].IsWithdraw) 847 848 // Withdraws the previous route. 849 // NOTE: Withdraw should not require any path attribute. 850 if err := t.addPathList("", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.2.0.0"), true, nil, time.Now(), false)}); err != nil { 851 test.Error(err) 852 } 853 ev = <-w.Event() 854 u = ev.(*watchEventUpdate) 855 assert.Equal(1, len(u.PathList)) 856 assert.Equal("10.2.0.0/24", u.PathList[0].GetNlri().String()) 857 assert.True(u.PathList[0].IsWithdraw) 858 859 // Test bestpath events with vrf and rt import 860 w.Stop() 861 w = s.watch(watchBestPath(false)) 862 attrs = []bgp.PathAttributeInterface{ 863 bgp.NewPathAttributeOrigin(0), 864 bgp.NewPathAttributeNextHop("10.0.0.1"), 865 } 866 867 if err := s.addPathList("vrf1", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), false, attrs, time.Now(), false)}); err != nil { 868 test.Error(err) 869 } 870 ev = <-w.Event() 871 b = ev.(*watchEventBestPath) 872 assert.Equal(1, len(b.PathList)) 873 assert.Equal("111:111:10.0.0.0/24", b.PathList[0].GetNlri().String()) 874 assert.False(b.PathList[0].IsWithdraw) 875 assert.Equal(2, len(b.Vrf)) 876 assert.True(b.Vrf[1]) 877 assert.True(b.Vrf[2]) 878 879 // Withdraw the route 880 if err := s.addPathList("vrf1", []*table.Path{table.NewPath(nil, bgp.NewIPAddrPrefix(24, "10.0.0.0"), true, attrs, time.Now(), false)}); err != nil { 881 test.Error(err) 882 } 883 ev = <-w.Event() 884 b = ev.(*watchEventBestPath) 885 assert.Equal(1, len(b.PathList)) 886 assert.Equal("111:111:10.0.0.0/24", b.PathList[0].GetNlri().String()) 887 assert.True(b.PathList[0].IsWithdraw) 888 assert.Equal(2, len(b.Vrf)) 889 assert.True(b.Vrf[1]) 890 assert.True(b.Vrf[2]) 891 892 w.Stop() 893 } 894 895 func TestNumGoroutineWithAddDeleteNeighbor(t *testing.T) { 896 assert := assert.New(t) 897 s := NewBgpServer() 898 go s.Serve() 899 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 900 Global: &api.Global{ 901 Asn: 1, 902 RouterId: "1.1.1.1", 903 ListenPort: -1, 904 }, 905 }) 906 assert.Nil(err) 907 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 908 909 // wait a few seconds to avoid taking effect from other test cases. 910 time.Sleep(time.Second * 5) 911 912 num := runtime.NumGoroutine() 913 914 p := &api.Peer{ 915 Conf: &api.PeerConf{ 916 NeighborAddress: "127.0.0.1", 917 PeerAsn: 2, 918 }, 919 Transport: &api.Transport{ 920 PassiveMode: true, 921 }, 922 } 923 924 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p}) 925 assert.Nil(err) 926 927 err = s.DeletePeer(context.Background(), &api.DeletePeerRequest{Address: "127.0.0.1"}) 928 assert.Nil(err) 929 // wait goroutines to finish (e.g. internal goroutine for 930 // InfiniteChannel) 931 time.Sleep(time.Second * 5) 932 for i := 0; i < 5; i++ { 933 if num == runtime.NumGoroutine() { 934 return 935 } 936 } 937 assert.Equal(num, runtime.NumGoroutine()) 938 } 939 940 func newPeerandInfo(myAs, as uint32, address string, rib *table.TableManager) (*peer, *table.PeerInfo) { 941 nConf := &oc.Neighbor{Config: oc.NeighborConfig{PeerAs: as, NeighborAddress: address}} 942 gConf := &oc.Global{Config: oc.GlobalConfig{As: myAs}} 943 oc.SetDefaultNeighborConfigValues(nConf, nil, gConf) 944 policy := table.NewRoutingPolicy(logger) 945 policy.Reset(&oc.RoutingPolicy{}, nil) 946 p := newPeer( 947 &oc.Global{Config: oc.GlobalConfig{As: myAs}}, 948 nConf, 949 rib, 950 policy, 951 logger) 952 p.fsm.peerInfo.ID = net.ParseIP(address) 953 for _, f := range rib.GetRFlist() { 954 p.fsm.rfMap[f] = bgp.BGP_ADD_PATH_NONE 955 } 956 return p, &table.PeerInfo{AS: as, Address: net.ParseIP(address), ID: net.ParseIP(address)} 957 } 958 959 func process(rib *table.TableManager, l []*table.Path) (*table.Path, *table.Path) { 960 dsts := make([]*table.Update, 0) 961 for _, path := range l { 962 dsts = append(dsts, rib.Update(path)...) 963 } 964 news, olds, _ := dstsToPaths(table.GLOBAL_RIB_NAME, 0, dsts) 965 if len(news) != 1 { 966 panic("can't handle multiple paths") 967 } 968 969 return news[0], olds[0] 970 } 971 972 func TestFilterpathWitheBGP(t *testing.T) { 973 as := uint32(65000) 974 p1As := uint32(65001) 975 p2As := uint32(65002) 976 rib := table.NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC}) 977 p1, pi1 := newPeerandInfo(as, p1As, "192.168.0.1", rib) 978 p2, pi2 := newPeerandInfo(as, p2As, "192.168.0.2", rib) 979 980 nlri := bgp.NewIPAddrPrefix(24, "10.10.10.0") 981 pa1 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{p1As})}), bgp.NewPathAttributeLocalPref(200)} 982 pa2 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{p2As})})} 983 984 path1 := table.NewPath(pi1, nlri, false, pa1, time.Now(), false) 985 path2 := table.NewPath(pi2, nlri, false, pa2, time.Now(), false) 986 rib.Update(path2) 987 d := rib.Update(path1) 988 new, old, _ := d[0].GetChanges(table.GLOBAL_RIB_NAME, 0, false) 989 assert.Equal(t, new, path1) 990 filterpath(p1, new, old) 991 filterpath(p2, new, old) 992 993 new, old = process(rib, []*table.Path{path1.Clone(true)}) 994 assert.Equal(t, new, path2) 995 // p1 and p2 advertized the same prefix and p1's was best. Then p1 withdraw it, so p2 must get withdawal. 996 path := filterpath(p2, new, old) 997 assert.NotNil(t, path) 998 assert.True(t, path.IsWithdraw) 999 1000 // p1 should get the new best (from p2) 1001 assert.Equal(t, filterpath(p1, new, old), path2) 1002 1003 new, old = process(rib, []*table.Path{path2.Clone(true)}) 1004 assert.True(t, new.IsWithdraw) 1005 // p2 withdraw so p1 should get withdrawal. 1006 path = filterpath(p1, new, old) 1007 assert.True(t, path.IsWithdraw) 1008 1009 // p2 withdraw so p2 should get nothing. 1010 path = filterpath(p2, new, old) 1011 assert.Nil(t, path) 1012 } 1013 1014 func TestFilterpathWithiBGP(t *testing.T) { 1015 as := uint32(65000) 1016 1017 rib := table.NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC}) 1018 p1, pi1 := newPeerandInfo(as, as, "192.168.0.1", rib) 1019 //p2, pi2 := newPeerandInfo(as, as, "192.168.0.2", rib) 1020 p2, _ := newPeerandInfo(as, as, "192.168.0.2", rib) 1021 1022 nlri := bgp.NewIPAddrPrefix(24, "10.10.10.0") 1023 pa1 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{as})}), bgp.NewPathAttributeLocalPref(200)} 1024 //pa2 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{as})})} 1025 1026 path1 := table.NewPath(pi1, nlri, false, pa1, time.Now(), false) 1027 //path2 := table.NewPath(pi2, nlri, false, pa2, time.Now(), false) 1028 1029 new, old := process(rib, []*table.Path{path1}) 1030 assert.Equal(t, new, path1) 1031 path := filterpath(p1, new, old) 1032 assert.Nil(t, path) 1033 path = filterpath(p2, new, old) 1034 assert.Nil(t, path) 1035 1036 new, old = process(rib, []*table.Path{path1.Clone(true)}) 1037 path = filterpath(p1, new, old) 1038 assert.Nil(t, path) 1039 path = filterpath(p2, new, old) 1040 assert.Nil(t, path) 1041 1042 } 1043 1044 func TestFilterpathWithRejectPolicy(t *testing.T) { 1045 rib1 := table.NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC}) 1046 _, pi1 := newPeerandInfo(1, 2, "192.168.0.1", rib1) 1047 rib2 := table.NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC}) 1048 p2, _ := newPeerandInfo(1, 3, "192.168.0.2", rib2) 1049 1050 comSet1 := oc.CommunitySet{ 1051 CommunitySetName: "comset1", 1052 CommunityList: []string{"100:100"}, 1053 } 1054 s, _ := table.NewCommunitySet(comSet1) 1055 p2.policy.AddDefinedSet(s, false) 1056 1057 statement := oc.Statement{ 1058 Name: "stmt1", 1059 Conditions: oc.Conditions{ 1060 BgpConditions: oc.BgpConditions{ 1061 MatchCommunitySet: oc.MatchCommunitySet{ 1062 CommunitySet: "comset1", 1063 }, 1064 }, 1065 }, 1066 Actions: oc.Actions{ 1067 RouteDisposition: oc.ROUTE_DISPOSITION_REJECT_ROUTE, 1068 }, 1069 } 1070 policy := oc.PolicyDefinition{ 1071 Name: "policy1", 1072 Statements: []oc.Statement{statement}, 1073 } 1074 p, _ := table.NewPolicy(policy) 1075 p2.policy.AddPolicy(p, false) 1076 policies := []*oc.PolicyDefinition{ 1077 { 1078 Name: "policy1", 1079 }, 1080 } 1081 p2.policy.AddPolicyAssignment(p2.TableID(), table.POLICY_DIRECTION_EXPORT, policies, table.ROUTE_TYPE_ACCEPT) 1082 1083 for _, addCommunity := range []bool{false, true, false, true} { 1084 nlri := bgp.NewIPAddrPrefix(24, "10.10.10.0") 1085 pa1 := []bgp.PathAttributeInterface{bgp.NewPathAttributeAsPath([]bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{1})}), bgp.NewPathAttributeLocalPref(200)} 1086 if addCommunity { 1087 pa1 = append(pa1, bgp.NewPathAttributeCommunities([]uint32{100<<16 | 100})) 1088 } 1089 path1 := table.NewPath(pi1, nlri, false, pa1, time.Now(), false) 1090 new, old := process(rib2, []*table.Path{path1}) 1091 assert.Equal(t, new, path1) 1092 s := NewBgpServer() 1093 path2 := s.filterpath(p2, new, old) 1094 if addCommunity { 1095 assert.True(t, path2.IsWithdraw) 1096 } else { 1097 assert.False(t, path2.IsWithdraw) 1098 } 1099 } 1100 1101 } 1102 1103 func TestPeerGroup(test *testing.T) { 1104 assert := assert.New(test) 1105 s := NewBgpServer() 1106 s.logger.SetLevel(log.DebugLevel) 1107 go s.Serve() 1108 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 1109 Global: &api.Global{ 1110 Asn: 1, 1111 RouterId: "1.1.1.1", 1112 ListenPort: 10179, 1113 }, 1114 }) 1115 assert.Nil(err) 1116 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 1117 1118 g := &oc.PeerGroup{ 1119 Config: oc.PeerGroupConfig{ 1120 PeerAs: 2, 1121 PeerGroupName: "g", 1122 }, 1123 } 1124 err = s.addPeerGroup(g) 1125 assert.Nil(err) 1126 1127 n := &oc.Neighbor{ 1128 Config: oc.NeighborConfig{ 1129 NeighborAddress: "127.0.0.1", 1130 PeerGroup: "g", 1131 }, 1132 Transport: oc.Transport{ 1133 Config: oc.TransportConfig{ 1134 PassiveMode: true, 1135 }, 1136 }, 1137 } 1138 configured := map[string]interface{}{ 1139 "config": map[string]interface{}{ 1140 "neigbor-address": "127.0.0.1", 1141 "peer-group": "g", 1142 }, 1143 "transport": map[string]interface{}{ 1144 "config": map[string]interface{}{ 1145 "passive-mode": true, 1146 }, 1147 }, 1148 } 1149 oc.RegisterConfiguredFields("127.0.0.1", configured) 1150 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: oc.NewPeerFromConfigStruct(n)}) 1151 assert.Nil(err) 1152 1153 t := NewBgpServer() 1154 go t.Serve() 1155 err = t.StartBgp(context.Background(), &api.StartBgpRequest{ 1156 Global: &api.Global{ 1157 Asn: 2, 1158 RouterId: "2.2.2.2", 1159 ListenPort: -1, 1160 }, 1161 }) 1162 assert.Nil(err) 1163 defer t.StopBgp(context.Background(), &api.StopBgpRequest{}) 1164 1165 m := &oc.Neighbor{ 1166 Config: oc.NeighborConfig{ 1167 NeighborAddress: "127.0.0.1", 1168 PeerAs: 1, 1169 }, 1170 Transport: oc.Transport{ 1171 Config: oc.TransportConfig{ 1172 RemotePort: 10179, 1173 }, 1174 }, 1175 Timers: oc.Timers{ 1176 Config: oc.TimersConfig{ 1177 ConnectRetry: 1, 1178 IdleHoldTimeAfterReset: 1, 1179 }, 1180 }, 1181 } 1182 ch := make(chan struct{}) 1183 go waitEstablished(s, ch) 1184 err = t.AddPeer(context.Background(), &api.AddPeerRequest{Peer: oc.NewPeerFromConfigStruct(m)}) 1185 assert.Nil(err) 1186 <-ch 1187 } 1188 1189 func TestDynamicNeighbor(t *testing.T) { 1190 assert := assert.New(t) 1191 s1 := NewBgpServer() 1192 s1.logger.SetLevel(log.DebugLevel) 1193 go s1.Serve() 1194 err := s1.StartBgp(context.Background(), &api.StartBgpRequest{ 1195 Global: &api.Global{ 1196 Asn: 1, 1197 RouterId: "1.1.1.1", 1198 ListenPort: 10179, 1199 }, 1200 }) 1201 assert.Nil(err) 1202 defer s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 1203 1204 g := &oc.PeerGroup{ 1205 Config: oc.PeerGroupConfig{ 1206 PeerAs: 2, 1207 PeerGroupName: "g", 1208 }, 1209 } 1210 err = s1.addPeerGroup(g) 1211 assert.Nil(err) 1212 1213 d := &api.AddDynamicNeighborRequest{ 1214 DynamicNeighbor: &api.DynamicNeighbor{ 1215 Prefix: "127.0.0.0/24", 1216 PeerGroup: "g", 1217 }, 1218 } 1219 err = s1.AddDynamicNeighbor(context.Background(), d) 1220 assert.Nil(err) 1221 1222 s2 := NewBgpServer() 1223 go s2.Serve() 1224 err = s2.StartBgp(context.Background(), &api.StartBgpRequest{ 1225 Global: &api.Global{ 1226 Asn: 2, 1227 RouterId: "2.2.2.2", 1228 ListenPort: -1, 1229 }, 1230 }) 1231 assert.Nil(err) 1232 defer s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 1233 1234 m := &oc.Neighbor{ 1235 Config: oc.NeighborConfig{ 1236 NeighborAddress: "127.0.0.1", 1237 PeerAs: 1, 1238 }, 1239 Transport: oc.Transport{ 1240 Config: oc.TransportConfig{ 1241 RemotePort: 10179, 1242 }, 1243 }, 1244 Timers: oc.Timers{ 1245 Config: oc.TimersConfig{ 1246 ConnectRetry: 1, 1247 IdleHoldTimeAfterReset: 1, 1248 }, 1249 }, 1250 } 1251 ch := make(chan struct{}) 1252 go waitEstablished(s2, ch) 1253 err = s2.AddPeer(context.Background(), &api.AddPeerRequest{Peer: oc.NewPeerFromConfigStruct(m)}) 1254 assert.Nil(err) 1255 <-ch 1256 } 1257 1258 func TestGracefulRestartTimerExpired(t *testing.T) { 1259 assert := assert.New(t) 1260 s1 := NewBgpServer() 1261 go s1.Serve() 1262 err := s1.StartBgp(context.Background(), &api.StartBgpRequest{ 1263 Global: &api.Global{ 1264 Asn: 1, 1265 RouterId: "1.1.1.1", 1266 ListenPort: 10179, 1267 }, 1268 }) 1269 assert.Nil(err) 1270 defer s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 1271 1272 p1 := &api.Peer{ 1273 Conf: &api.PeerConf{ 1274 NeighborAddress: "127.0.0.1", 1275 PeerAsn: 2, 1276 }, 1277 Transport: &api.Transport{ 1278 PassiveMode: true, 1279 }, 1280 GracefulRestart: &api.GracefulRestart{ 1281 Enabled: true, 1282 RestartTime: minConnectRetryInterval, 1283 }, 1284 } 1285 err = s1.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p1}) 1286 assert.Nil(err) 1287 1288 s2 := NewBgpServer() 1289 go s2.Serve() 1290 err = s2.StartBgp(context.Background(), &api.StartBgpRequest{ 1291 Global: &api.Global{ 1292 Asn: 2, 1293 RouterId: "2.2.2.2", 1294 ListenPort: -1, 1295 }, 1296 }) 1297 require.NoError(t, err) 1298 defer s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 1299 1300 p2 := &api.Peer{ 1301 Conf: &api.PeerConf{ 1302 NeighborAddress: "127.0.0.1", 1303 PeerAsn: 1, 1304 }, 1305 Transport: &api.Transport{ 1306 RemotePort: 10179, 1307 }, 1308 GracefulRestart: &api.GracefulRestart{ 1309 Enabled: true, 1310 RestartTime: 1, 1311 }, 1312 Timers: &api.Timers{ 1313 Config: &api.TimersConfig{ 1314 ConnectRetry: 1, 1315 IdleHoldTimeAfterReset: 1, 1316 }, 1317 }, 1318 } 1319 1320 ch := make(chan struct{}) 1321 go waitEstablished(s2, ch) 1322 err = s2.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p2}) 1323 assert.Nil(err) 1324 <-ch 1325 1326 // Force TCP session disconnected in order to cause Graceful Restart at s1 1327 // side. 1328 for _, n := range s2.neighborMap { 1329 n.fsm.conn.Close() 1330 } 1331 s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 1332 1333 time.Sleep(5 * time.Second) 1334 1335 // Create dummy session which does NOT send BGP OPEN message in order to 1336 // cause Graceful Restart timer expired. 1337 var conn net.Conn 1338 1339 conn, err = net.Dial("tcp", "127.0.0.1:10179") 1340 require.NoError(t, err) 1341 defer conn.Close() 1342 1343 // this seems to take around 22 seconds... need to address this whole thing 1344 ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) 1345 defer cancel() 1346 1347 done := make(chan struct{}) 1348 // Waiting for Graceful Restart timer expired and moving on to IDLE state. 1349 for { 1350 s1.ListPeer(context.Background(), &api.ListPeerRequest{}, func(peer *api.Peer) { 1351 if peer.State.SessionState == api.PeerState_IDLE { 1352 close(done) 1353 } 1354 }) 1355 1356 select { 1357 case <-done: 1358 return 1359 case <-ctx.Done(): 1360 t.Fatalf("failed to enter IDLE state in the deadline") 1361 return 1362 } 1363 } 1364 } 1365 1366 func TestTcpConnectionClosedAfterPeerDel(t *testing.T) { 1367 assert := assert.New(t) 1368 s1 := NewBgpServer() 1369 go s1.Serve() 1370 err := s1.StartBgp(context.Background(), &api.StartBgpRequest{ 1371 Global: &api.Global{ 1372 Asn: 1, 1373 RouterId: "1.1.1.1", 1374 ListenPort: 10179, 1375 }, 1376 }) 1377 assert.Nil(err) 1378 defer s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 1379 1380 p1 := &api.Peer{ 1381 Conf: &api.PeerConf{ 1382 NeighborAddress: "127.0.0.1", 1383 PeerAsn: 2, 1384 }, 1385 Transport: &api.Transport{ 1386 PassiveMode: true, 1387 }, 1388 } 1389 1390 activeCh := make(chan struct{}) 1391 go waitActive(s1, activeCh) 1392 err = s1.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p1}) 1393 assert.Nil(err) 1394 <-activeCh 1395 1396 // We delete the peer incoming channel from the server list so that we can 1397 // intercept the transition from ACTIVE state to OPENSENT state. 1398 neighbor1 := s1.neighborMap[p1.Conf.NeighborAddress] 1399 incoming := neighbor1.fsm.incomingCh 1400 err = s1.mgmtOperation(func() error { 1401 s1.delIncoming(incoming) 1402 return nil 1403 }, true) 1404 assert.Nil(err) 1405 1406 s2 := NewBgpServer() 1407 go s2.Serve() 1408 err = s2.StartBgp(context.Background(), &api.StartBgpRequest{ 1409 Global: &api.Global{ 1410 Asn: 2, 1411 RouterId: "2.2.2.2", 1412 ListenPort: -1, 1413 }, 1414 }) 1415 require.NoError(t, err) 1416 defer s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 1417 1418 p2 := &api.Peer{ 1419 Conf: &api.PeerConf{ 1420 NeighborAddress: "127.0.0.1", 1421 PeerAsn: 1, 1422 }, 1423 Transport: &api.Transport{ 1424 RemotePort: 10179, 1425 }, 1426 Timers: &api.Timers{ 1427 Config: &api.TimersConfig{ 1428 ConnectRetry: 1, 1429 IdleHoldTimeAfterReset: 1, 1430 }, 1431 }, 1432 } 1433 1434 err = s2.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p2}) 1435 assert.Nil(err) 1436 1437 // Wait for the s1 to receive the tcp connection from s2. 1438 ev := <-incoming.Out() 1439 msg := ev.(*fsmMsg) 1440 nextState := msg.MsgData.(bgp.FSMState) 1441 assert.Equal(nextState, bgp.BGP_FSM_OPENSENT) 1442 assert.NotEmpty(msg.fsm.conn) 1443 1444 // Add the peer incoming channel back to the server 1445 err = s1.mgmtOperation(func() error { 1446 s1.addIncoming(incoming) 1447 return nil 1448 }, true) 1449 assert.Nil(err) 1450 1451 // Delete the peer from s1. 1452 err = s1.DeletePeer(context.Background(), &api.DeletePeerRequest{Address: p1.Conf.NeighborAddress}) 1453 assert.Nil(err) 1454 1455 // Send the message OPENSENT transition message again to the server. 1456 incoming.In() <- msg 1457 1458 // Wait for peer connection channel to be closed and check that the open 1459 // tcp connection has also been closed. 1460 <-neighbor1.fsm.connCh 1461 assert.Empty(neighbor1.fsm.conn) 1462 1463 // Check that we can establish the peering when re-adding the peer. 1464 establishedCh := make(chan struct{}) 1465 go waitEstablished(s2, establishedCh) 1466 err = s1.AddPeer(context.Background(), &api.AddPeerRequest{Peer: p1}) 1467 assert.Nil(err) 1468 <-establishedCh 1469 } 1470 1471 func TestFamiliesForSoftreset(t *testing.T) { 1472 f := func(f bgp.RouteFamily) oc.AfiSafi { 1473 return oc.AfiSafi{ 1474 State: oc.AfiSafiState{ 1475 Family: f, 1476 }, 1477 } 1478 } 1479 peer := &peer{ 1480 fsm: &fsm{ 1481 pConf: &oc.Neighbor{ 1482 AfiSafis: []oc.AfiSafi{f(bgp.RF_RTC_UC), f(bgp.RF_IPv4_UC), f(bgp.RF_IPv6_UC)}, 1483 }, 1484 }, 1485 } 1486 1487 families := familiesForSoftreset(peer, bgp.RF_IPv4_UC) 1488 assert.Equal(t, len(families), 1) 1489 assert.Equal(t, families[0], bgp.RF_IPv4_UC) 1490 1491 families = familiesForSoftreset(peer, bgp.RF_RTC_UC) 1492 assert.Equal(t, len(families), 1) 1493 assert.Equal(t, families[0], bgp.RF_RTC_UC) 1494 1495 families = familiesForSoftreset(peer, bgp.RouteFamily(0)) 1496 assert.Equal(t, len(families), 2) 1497 assert.NotContains(t, families, bgp.RF_RTC_UC) 1498 } 1499 1500 func runNewServer(t *testing.T, as uint32, routerID string, listenPort int32) *BgpServer { 1501 s := NewBgpServer() 1502 go s.Serve() 1503 if err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 1504 Global: &api.Global{ 1505 Asn: as, 1506 RouterId: routerID, 1507 ListenPort: listenPort, 1508 }, 1509 }); err != nil { 1510 t.Errorf("Failed to start server %s: %s", s.bgpConfig.Global.Config.RouterId, err) 1511 } 1512 return s 1513 } 1514 1515 func peerServers(t *testing.T, ctx context.Context, servers []*BgpServer, families []oc.AfiSafiType) error { 1516 for i, server := range servers { 1517 for j, peer := range servers { 1518 if i == j { 1519 continue 1520 } 1521 1522 neighborConfig := &oc.Neighbor{ 1523 Config: oc.NeighborConfig{ 1524 NeighborAddress: "127.0.0.1", 1525 PeerAs: peer.bgpConfig.Global.Config.As, 1526 }, 1527 AfiSafis: oc.AfiSafis{}, 1528 Transport: oc.Transport{ 1529 Config: oc.TransportConfig{ 1530 RemotePort: uint16(peer.bgpConfig.Global.Config.Port), 1531 }, 1532 }, 1533 Timers: oc.Timers{ 1534 Config: oc.TimersConfig{ 1535 ConnectRetry: 1, 1536 IdleHoldTimeAfterReset: 1, 1537 }, 1538 }, 1539 } 1540 1541 // first server to get neighbor config is passive to hopefully make handshake faster 1542 if j > i { 1543 neighborConfig.Transport.Config.PassiveMode = true 1544 } 1545 1546 for _, family := range families { 1547 neighborConfig.AfiSafis = append(neighborConfig.AfiSafis, oc.AfiSafi{ 1548 Config: oc.AfiSafiConfig{ 1549 AfiSafiName: family, 1550 Enabled: true, 1551 }, 1552 }) 1553 } 1554 1555 if err := server.AddPeer(ctx, &api.AddPeerRequest{Peer: oc.NewPeerFromConfigStruct(neighborConfig)}); err != nil { 1556 t.Fatal(err) 1557 } 1558 } 1559 } 1560 1561 return nil 1562 } 1563 1564 func parseRDRT(rdStr string) (bgp.RouteDistinguisherInterface, bgp.ExtendedCommunityInterface, error) { 1565 rd, err := bgp.ParseRouteDistinguisher(rdStr) 1566 if err != nil { 1567 return nil, nil, err 1568 } 1569 1570 rt, err := bgp.ParseExtendedCommunity(bgp.EC_SUBTYPE_ROUTE_TARGET, rdStr) 1571 if err != nil { 1572 return nil, nil, err 1573 } 1574 return rd, rt, nil 1575 } 1576 1577 func addVrf(t *testing.T, s *BgpServer, vrfName, rdStr string, importRtsStr []string, exportRtsStr []string, id uint32) { 1578 rd, _, err := parseRDRT(rdStr) 1579 if err != nil { 1580 t.Fatal(err) 1581 } 1582 1583 importRts := make([]bgp.ExtendedCommunityInterface, 0, len(importRtsStr)) 1584 for _, importRtStr := range importRtsStr { 1585 _, rt, err := parseRDRT(importRtStr) 1586 if err != nil { 1587 t.Fatal(err) 1588 } 1589 importRts = append(importRts, rt) 1590 } 1591 1592 exportRts := make([]bgp.ExtendedCommunityInterface, 0, len(exportRtsStr)) 1593 for _, exportRtStr := range exportRtsStr { 1594 _, rt, err := parseRDRT(exportRtStr) 1595 if err != nil { 1596 t.Fatal(err) 1597 } 1598 exportRts = append(exportRts, rt) 1599 } 1600 irt, _ := apiutil.MarshalRTs(importRts) 1601 ert, _ := apiutil.MarshalRTs(exportRts) 1602 v, _ := apiutil.MarshalRD(rd) 1603 1604 req := &api.AddVrfRequest{ 1605 Vrf: &api.Vrf{ 1606 Name: vrfName, 1607 ImportRt: irt, 1608 ExportRt: ert, 1609 Rd: v, 1610 Id: id, 1611 }, 1612 } 1613 if err = s.AddVrf(context.Background(), req); err != nil { 1614 t.Fatal(err) 1615 } 1616 } 1617 1618 func TestDoNotReactToDuplicateRTCMemberships(t *testing.T) { 1619 ctx := context.Background() 1620 1621 s1 := runNewServer(t, 1, "1.1.1.1", 10179) 1622 s1.logger.SetLevel(log.DebugLevel) 1623 s2 := runNewServer(t, 1, "2.2.2.2", 20179) 1624 s2.logger.SetLevel(log.DebugLevel) 1625 1626 addVrf(t, s1, "vrf1", "111:111", []string{"111:111"}, []string{"111:111"}, 1) 1627 addVrf(t, s2, "vrf1", "111:111", []string{"111:111"}, []string{"111:111"}, 1) 1628 1629 if err := peerServers(t, ctx, []*BgpServer{s1, s2}, []oc.AfiSafiType{oc.AFI_SAFI_TYPE_L3VPN_IPV4_UNICAST, oc.AFI_SAFI_TYPE_RTC}); err != nil { 1630 t.Fatal(err) 1631 } 1632 watcher := s1.watch(watchUpdate(true, "", "")) 1633 1634 // Add route to vrf1 on s2 1635 attrs := []bgp.PathAttributeInterface{ 1636 bgp.NewPathAttributeOrigin(0), 1637 bgp.NewPathAttributeNextHop("2.2.2.2"), 1638 } 1639 prefix := bgp.NewIPAddrPrefix(24, "10.30.2.0") 1640 path, _ := apiutil.NewPath(prefix, false, attrs, time.Now()) 1641 1642 if _, err := s2.AddPath(ctx, &api.AddPathRequest{ 1643 TableType: api.TableType_VRF, 1644 VrfId: "vrf1", 1645 Path: path, 1646 }); err != nil { 1647 t.Fatal(err) 1648 } 1649 1650 // s1 should receive this route from s2 1651 t1 := time.NewTimer(time.Duration(30 * time.Second)) 1652 for found := false; !found; { 1653 select { 1654 case ev := <-watcher.Event(): 1655 switch msg := ev.(type) { 1656 case *watchEventUpdate: 1657 for _, path := range msg.PathList { 1658 t.Logf("tester received path: %s", path.String()) 1659 if vpnPath, ok := path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix); ok { 1660 if vpnPath.Prefix.Equal(prefix.Prefix) { 1661 t.Logf("tester found expected prefix: %s", vpnPath.Prefix) 1662 found = true 1663 } else { 1664 t.Logf("unknown prefix %s != %s", vpnPath.Prefix, prefix.Prefix) 1665 } 1666 } 1667 } 1668 } 1669 case <-t1.C: 1670 t.Fatalf("timeout while waiting for update path event") 1671 } 1672 } 1673 t1.Stop() 1674 1675 // fabricate duplicated rtc message from s1 1676 // s2 should not send vpn route again 1677 _, rt, err := parseRDRT("111:111") 1678 if err != nil { 1679 t.Fatal(err) 1680 } 1681 rtcNLRI := bgp.NewRouteTargetMembershipNLRI(1, rt) 1682 rtcPath := table.NewPath(&table.PeerInfo{ 1683 AS: 1, 1684 Address: net.ParseIP("127.0.0.1"), 1685 LocalID: net.ParseIP("2.2.2.2"), 1686 ID: net.ParseIP("1.1.1.1"), 1687 }, rtcNLRI, false, []bgp.PathAttributeInterface{ 1688 bgp.NewPathAttributeOrigin(0), 1689 bgp.NewPathAttributeNextHop("1.1.1.1"), 1690 }, time.Now(), false) 1691 1692 s1Peer := s2.neighborMap["127.0.0.1"] 1693 s2.propagateUpdate(s1Peer, []*table.Path{rtcPath}) 1694 1695 t2 := time.NewTimer(time.Duration(2 * time.Second)) 1696 for done := false; !done; { 1697 select { 1698 case ev := <-watcher.Event(): 1699 switch msg := ev.(type) { 1700 case *watchEventUpdate: 1701 for _, path := range msg.PathList { 1702 t.Logf("tester received path: %s", path.String()) 1703 if vpnPath, ok := path.GetNlri().(*bgp.LabeledVPNIPAddrPrefix); ok { 1704 t.Fatalf("vpn prefix %s was unexpectedly received", vpnPath.Prefix) 1705 } 1706 } 1707 } 1708 case <-t2.C: 1709 t.Logf("await update done") 1710 done = true 1711 } 1712 } 1713 1714 s1.StopBgp(context.Background(), &api.StopBgpRequest{}) 1715 s2.StopBgp(context.Background(), &api.StopBgpRequest{}) 1716 } 1717 1718 func TestAddDeletePath(t *testing.T) { 1719 ctx := context.Background() 1720 s := runNewServer(t, 1, "1.1.1.1", 10179) 1721 1722 nlri, _ := apb.New(&api.IPAddressPrefix{ 1723 Prefix: "10.0.0.0", 1724 PrefixLen: 24, 1725 }) 1726 1727 nlri6, _ := apb.New(&api.IPAddressPrefix{ 1728 Prefix: "2001:DB8::", 1729 PrefixLen: 32, 1730 }) 1731 1732 nh1, _ := apb.New(&api.NextHopAttribute{ 1733 NextHop: "fd00::1", 1734 }) 1735 1736 nh2, _ := apb.New(&api.NextHopAttribute{ 1737 NextHop: "fd00::2", 1738 }) 1739 1740 nh3, _ := apb.New(&api.NextHopAttribute{ 1741 NextHop: "10.0.0.1", 1742 }) 1743 1744 nh4, _ := apb.New(&api.NextHopAttribute{ 1745 NextHop: "10.0.0.2", 1746 }) 1747 1748 a1, _ := apb.New(&api.OriginAttribute{ 1749 Origin: 0, 1750 }) 1751 1752 attrs := []*apb.Any{a1, nh3} 1753 1754 family := &api.Family{ 1755 Afi: api.Family_AFI_IP, 1756 Safi: api.Family_SAFI_UNICAST, 1757 } 1758 1759 family6 := &api.Family{ 1760 Afi: api.Family_AFI_IP6, 1761 Safi: api.Family_SAFI_UNICAST, 1762 } 1763 1764 listRib := func(f *api.Family) []*api.Destination { 1765 l := make([]*api.Destination, 0) 1766 s.ListPath(ctx, &api.ListPathRequest{TableType: api.TableType_GLOBAL, Family: f}, func(d *api.Destination) { l = append(l, d) }) 1767 return l 1768 } 1769 1770 numPaths := func(f *api.Family) int { 1771 c := 0 1772 for _, d := range listRib(f) { 1773 c += len(d.Paths) 1774 } 1775 return c 1776 } 1777 1778 var err error 1779 // DeletePath(AddPath()) without PeerInfo 1780 getPath := func() *api.Path { 1781 return &api.Path{ 1782 Family: family, 1783 Nlri: nlri, 1784 Pattrs: attrs, 1785 } 1786 } 1787 1788 p1 := getPath() 1789 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1790 TableType: api.TableType_GLOBAL, 1791 Path: p1, 1792 }) 1793 assert.Nil(t, err) 1794 assert.Equal(t, len(listRib(family)), 1) 1795 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1796 TableType: api.TableType_GLOBAL, 1797 Path: p1, 1798 }) 1799 assert.Nil(t, err) 1800 assert.Equal(t, len(listRib(family)), 0) 1801 1802 // DeletePath(ListPath()) without PeerInfo 1803 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1804 TableType: api.TableType_GLOBAL, 1805 Path: p1, 1806 }) 1807 assert.Nil(t, err) 1808 l := listRib(family) 1809 assert.Equal(t, len(l), 1) 1810 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1811 TableType: api.TableType_GLOBAL, 1812 Path: l[0].Paths[0], 1813 }) 1814 assert.Nil(t, err) 1815 assert.Equal(t, len(listRib(family)), 0) 1816 1817 p2 := getPath() 1818 p2.SourceAsn = 1 1819 p2.SourceId = "1.1.1.1" 1820 1821 // DeletePath(AddPath()) with PeerInfo 1822 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1823 TableType: api.TableType_GLOBAL, 1824 Path: p2, 1825 }) 1826 assert.Nil(t, err) 1827 assert.Equal(t, len(listRib(family)), 1) 1828 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1829 TableType: api.TableType_GLOBAL, 1830 Path: p2, 1831 }) 1832 assert.Nil(t, err) 1833 assert.Equal(t, len(listRib(family)), 0) 1834 1835 // DeletePath(ListPath()) with PeerInfo 1836 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1837 TableType: api.TableType_GLOBAL, 1838 Path: p2, 1839 }) 1840 assert.Nil(t, err) 1841 l = listRib(family) 1842 assert.Equal(t, len(l), 1) 1843 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1844 TableType: api.TableType_GLOBAL, 1845 Path: l[0].Paths[0], 1846 }) 1847 assert.Nil(t, err) 1848 assert.Equal(t, len(listRib(family)), 0) 1849 1850 // DeletePath(AddPath()) with different identifiers (ipv6) 1851 path1 := &api.Path{ 1852 Family: &api.Family{ 1853 Afi: api.Family_AFI_IP6, 1854 Safi: api.Family_SAFI_UNICAST, 1855 }, 1856 Nlri: nlri6, 1857 Pattrs: []*apb.Any{a1, nh1}, 1858 Identifier: 1, 1859 } 1860 1861 path2 := &api.Path{ 1862 Family: &api.Family{ 1863 Afi: api.Family_AFI_IP6, 1864 Safi: api.Family_SAFI_UNICAST, 1865 }, 1866 Nlri: nlri6, 1867 Pattrs: []*apb.Any{a1, nh2}, 1868 Identifier: 2, 1869 } 1870 1871 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1872 TableType: api.TableType_GLOBAL, 1873 Path: path1, 1874 }) 1875 assert.Nil(t, err) 1876 assert.Equal(t, numPaths(family6), 1) 1877 1878 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1879 TableType: api.TableType_GLOBAL, 1880 Path: path2, 1881 }) 1882 assert.Nil(t, err) 1883 assert.Equal(t, numPaths(family6), 2) 1884 1885 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1886 TableType: api.TableType_GLOBAL, 1887 Path: path1, 1888 }) 1889 assert.Nil(t, err) 1890 assert.Equal(t, numPaths(family6), 1) 1891 1892 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1893 TableType: api.TableType_GLOBAL, 1894 Path: path2, 1895 }) 1896 assert.Nil(t, err) 1897 assert.Equal(t, numPaths(family6), 0) 1898 1899 // DeletePath(AddPath()) with different identifiers (ipv4) 1900 path1 = &api.Path{ 1901 Family: &api.Family{ 1902 Afi: api.Family_AFI_IP, 1903 Safi: api.Family_SAFI_UNICAST, 1904 }, 1905 Nlri: nlri, 1906 Pattrs: []*apb.Any{a1, nh3}, 1907 Identifier: 1, 1908 } 1909 1910 path2 = &api.Path{ 1911 Family: &api.Family{ 1912 Afi: api.Family_AFI_IP, 1913 Safi: api.Family_SAFI_UNICAST, 1914 }, 1915 Nlri: nlri, 1916 Pattrs: []*apb.Any{a1, nh4}, 1917 Identifier: 2, 1918 } 1919 1920 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1921 TableType: api.TableType_GLOBAL, 1922 Path: path1, 1923 }) 1924 assert.Nil(t, err) 1925 assert.Equal(t, numPaths(family), 1) 1926 1927 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1928 TableType: api.TableType_GLOBAL, 1929 Path: path2, 1930 }) 1931 assert.Nil(t, err) 1932 assert.Equal(t, numPaths(family), 2) 1933 1934 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1935 TableType: api.TableType_GLOBAL, 1936 Path: path1, 1937 }) 1938 assert.Nil(t, err) 1939 assert.Equal(t, numPaths(family), 1) 1940 1941 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1942 TableType: api.TableType_GLOBAL, 1943 Path: path2, 1944 }) 1945 assert.Nil(t, err) 1946 assert.Equal(t, numPaths(family), 0) 1947 1948 // DeletePath(AddPath()) with different PeerInfo 1949 _, err = s.AddPath(ctx, &api.AddPathRequest{ 1950 TableType: api.TableType_GLOBAL, 1951 Path: p2, 1952 }) 1953 assert.Nil(t, err) 1954 assert.Equal(t, len(listRib(family)), 1) 1955 p3 := getPath() 1956 p3.SourceAsn = 2 1957 p3.SourceId = "1.1.1.2" 1958 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1959 TableType: api.TableType_GLOBAL, 1960 Path: p3, 1961 }) 1962 assert.Nil(t, err) 1963 assert.Equal(t, len(listRib(family)), 1) 1964 1965 // DeletePath(AddPath()) with uuid 1966 r, err := s.AddPath(ctx, &api.AddPathRequest{ 1967 TableType: api.TableType_GLOBAL, 1968 Path: p2, 1969 }) 1970 assert.Nil(t, err) 1971 assert.Equal(t, len(listRib(family)), 1) 1972 err = s.DeletePath(ctx, &api.DeletePathRequest{ 1973 TableType: api.TableType_GLOBAL, 1974 Uuid: r.Uuid, 1975 }) 1976 assert.Nil(t, err) 1977 assert.Equal(t, len(listRib(family)), 0) 1978 assert.Equal(t, len(s.uuidMap), 0) 1979 1980 r, err = s.AddPath(ctx, &api.AddPathRequest{ 1981 TableType: api.TableType_GLOBAL, 1982 Path: p2, 1983 }) 1984 assert.Nil(t, err) 1985 assert.Equal(t, len(listRib(family)), 1) 1986 assert.Equal(t, len(s.uuidMap), 1) 1987 u := r.Uuid 1988 1989 asPath, _ := apb.New(&api.AsPathAttribute{ 1990 Segments: []*api.AsSegment{ 1991 { 1992 Type: 1, // SET 1993 Numbers: []uint32{100, 200, 300}, 1994 }, 1995 }, 1996 }) 1997 1998 p2.Pattrs = append(p2.Pattrs, asPath) 1999 r, err = s.AddPath(ctx, &api.AddPathRequest{ 2000 TableType: api.TableType_GLOBAL, 2001 Path: p2, 2002 }) 2003 assert.Nil(t, err) 2004 assert.Equal(t, len(listRib(family)), 1) 2005 assert.Equal(t, len(s.uuidMap), 1) 2006 assert.NotEqual(t, u, r.Uuid) 2007 s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2008 } 2009 2010 func TestDeleteNonExistingVrf(t *testing.T) { 2011 s := runNewServer(t, 1, "1.1.1.1", 10179) 2012 s.logger.SetLevel(log.DebugLevel) 2013 2014 addVrf(t, s, "vrf1", "111:111", []string{"111:111"}, []string{"111:111"}, 1) 2015 req := &api.DeleteVrfRequest{Name: "Invalidvrf"} 2016 if err := s.DeleteVrf(context.Background(), req); err == nil { 2017 t.Fatal("Did not raise error for invalid vrf deletion.", err) 2018 } 2019 s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2020 } 2021 2022 func TestDeleteVrf(t *testing.T) { 2023 s := runNewServer(t, 1, "1.1.1.1", 10179) 2024 s.logger.SetLevel(log.DebugLevel) 2025 2026 addVrf(t, s, "vrf1", "111:111", []string{"111:111"}, []string{"111:111"}, 1) 2027 req := &api.DeleteVrfRequest{Name: "vrf1"} 2028 if err := s.DeleteVrf(context.Background(), req); err != nil { 2029 t.Fatal("Vrf delete failed", err) 2030 } 2031 s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2032 } 2033 2034 func TestAddBogusPath(t *testing.T) { 2035 ctx := context.Background() 2036 s := runNewServer(t, 1, "1.1.1.1", 10179) 2037 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2038 2039 nlri, _ := apb.New(&api.IPAddressPrefix{}) 2040 2041 a, _ := apb.New(&api.MpReachNLRIAttribute{}) 2042 2043 _, err := s.AddPath(ctx, &api.AddPathRequest{ 2044 Path: &api.Path{ 2045 Family: &api.Family{Afi: api.Family_AFI_IP, Safi: api.Family_SAFI_UNICAST}, 2046 Nlri: nlri, 2047 Pattrs: []*apb.Any{a}, 2048 }, 2049 }) 2050 assert.NotNil(t, err) 2051 2052 nlri, _ = apb.New(&api.IPAddressPrefix{}) 2053 2054 a, _ = apb.New(&api.MpReachNLRIAttribute{ 2055 Family: &api.Family{Afi: api.Family_AFI_IP, Safi: api.Family_SAFI_FLOW_SPEC_UNICAST}, 2056 }) 2057 2058 _, err = s.AddPath(ctx, &api.AddPathRequest{ 2059 Path: &api.Path{ 2060 Family: &api.Family{Afi: api.Family_AFI_IP, Safi: api.Family_SAFI_UNICAST}, 2061 Nlri: nlri, 2062 Pattrs: []*apb.Any{a}, 2063 }, 2064 }) 2065 assert.NotNil(t, err) 2066 } 2067 2068 // TestListPathWithIdentifiers confirms whether ListPath properly returns the 2069 // identifier information for paths for the Global RIB and for VRF RIBs. 2070 func TestListPathWithIdentifiers(t *testing.T) { 2071 ctx := context.Background() 2072 2073 assert := assert.New(t) 2074 s := NewBgpServer() 2075 go s.Serve() 2076 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 2077 Global: &api.Global{ 2078 Asn: 1, 2079 RouterId: "1.1.1.1", 2080 ListenPort: -1, 2081 }, 2082 }) 2083 assert.Nil(err) 2084 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2085 2086 family := &api.Family{ 2087 Afi: api.Family_AFI_IP, 2088 Safi: api.Family_SAFI_UNICAST, 2089 } 2090 2091 nlri1, _ := apb.New(&api.IPAddressPrefix{ 2092 Prefix: "10.1.0.0", 2093 PrefixLen: 24, 2094 }) 2095 2096 a1, _ := apb.New(&api.OriginAttribute{ 2097 Origin: 0, 2098 }) 2099 a2, _ := apb.New(&api.NextHopAttribute{ 2100 NextHop: "10.0.0.1", 2101 }) 2102 attrs := []*apb.Any{a1, a2} 2103 paths := []*api.Path{ 2104 { 2105 Family: family, 2106 Nlri: nlri1, 2107 Pattrs: attrs, 2108 Identifier: 1, 2109 }, 2110 { 2111 Family: family, 2112 Nlri: nlri1, 2113 Pattrs: attrs, 2114 Identifier: 2, 2115 }, 2116 } 2117 wantIDs := []uint32{1, 2} 2118 applyPathsTo := func(vrf string) { 2119 for _, path := range paths { 2120 _, err = s.AddPath(context.Background(), &api.AddPathRequest{ 2121 TableType: api.TableType_GLOBAL, 2122 Path: path, 2123 VrfId: vrf, 2124 }) 2125 assert.Nil(err) 2126 } 2127 } 2128 destinationsFrom := func(name string, tableType api.TableType) []*api.Destination { 2129 var destinations []*api.Destination 2130 err = s.ListPath(ctx, &api.ListPathRequest{ 2131 Name: name, 2132 TableType: tableType, 2133 Family: family, 2134 }, func(d *api.Destination) { 2135 destinations = append(destinations, d) 2136 }) 2137 assert.Nil(err) 2138 return destinations 2139 } 2140 identifiersFrom := func(destinations []*api.Destination) []uint32 { 2141 var ids []uint32 2142 for _, d := range destinations { 2143 for _, p := range d.Paths { 2144 ids = append(ids, p.Identifier) 2145 } 2146 } 2147 sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] }) 2148 return ids 2149 } 2150 2151 t.Logf("For Global RIB") 2152 applyPathsTo("") 2153 gotDestinations := destinationsFrom("", api.TableType_GLOBAL) 2154 gotIDs := identifiersFrom(gotDestinations) 2155 if diff := cmp.Diff(gotIDs, wantIDs); diff != "" { 2156 t.Errorf("IDs differed for global RIB (-got, +want):\n%s", diff) 2157 } 2158 2159 t.Logf("For VRF RIB") 2160 vrfName := "vrf" 2161 addVrf(t, s, vrfName, "0:0", []string{"0:0"}, []string{"0:0"}, 0) 2162 applyPathsTo(vrfName) 2163 gotDestinations = destinationsFrom(vrfName, api.TableType_VRF) 2164 gotIDs = identifiersFrom(gotDestinations) 2165 if diff := cmp.Diff(gotIDs, wantIDs); diff != "" { 2166 t.Errorf("IDs differed for VRF RIB (-got, +want):\n%s", diff) 2167 } 2168 } 2169 2170 func TestWatchEvent(test *testing.T) { 2171 assert := assert.New(test) 2172 s := NewBgpServer() 2173 go s.Serve() 2174 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 2175 Global: &api.Global{ 2176 Asn: 1, 2177 RouterId: "1.1.1.1", 2178 ListenPort: 10179, 2179 }, 2180 }) 2181 assert.Nil(err) 2182 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2183 2184 peer1 := &api.Peer{ 2185 Conf: &api.PeerConf{ 2186 NeighborAddress: "127.0.0.1", 2187 PeerAsn: 2, 2188 }, 2189 Transport: &api.Transport{ 2190 PassiveMode: true, 2191 }, 2192 } 2193 err = s.AddPeer(context.Background(), &api.AddPeerRequest{Peer: peer1}) 2194 assert.Nil(err) 2195 2196 d1 := &api.DefinedSet{ 2197 DefinedType: api.DefinedType_PREFIX, 2198 Name: "d1", 2199 Prefixes: []*api.Prefix{ 2200 { 2201 IpPrefix: "10.1.0.0/24", 2202 MaskLengthMax: 24, 2203 MaskLengthMin: 24, 2204 }, 2205 }, 2206 } 2207 s1 := &api.Statement{ 2208 Name: "s1", 2209 Conditions: &api.Conditions{ 2210 PrefixSet: &api.MatchSet{ 2211 Name: "d1", 2212 }, 2213 }, 2214 Actions: &api.Actions{ 2215 RouteAction: api.RouteAction_REJECT, 2216 }, 2217 } 2218 err = s.AddDefinedSet(context.Background(), &api.AddDefinedSetRequest{DefinedSet: d1}) 2219 assert.Nil(err) 2220 p1 := &api.Policy{ 2221 Name: "p1", 2222 Statements: []*api.Statement{s1}, 2223 } 2224 err = s.AddPolicy(context.Background(), &api.AddPolicyRequest{Policy: p1}) 2225 assert.Nil(err) 2226 err = s.AddPolicyAssignment(context.Background(), &api.AddPolicyAssignmentRequest{ 2227 Assignment: &api.PolicyAssignment{ 2228 Name: table.GLOBAL_RIB_NAME, 2229 Direction: api.PolicyDirection_IMPORT, 2230 Policies: []*api.Policy{p1}, 2231 DefaultAction: api.RouteAction_ACCEPT, 2232 }, 2233 }) 2234 assert.Nil(err) 2235 2236 t := NewBgpServer() 2237 go t.Serve() 2238 err = t.StartBgp(context.Background(), &api.StartBgpRequest{ 2239 Global: &api.Global{ 2240 Asn: 2, 2241 RouterId: "2.2.2.2", 2242 ListenPort: -1, 2243 }, 2244 }) 2245 assert.Nil(err) 2246 defer t.StopBgp(context.Background(), &api.StopBgpRequest{}) 2247 2248 family := &api.Family{ 2249 Afi: api.Family_AFI_IP, 2250 Safi: api.Family_SAFI_UNICAST, 2251 } 2252 2253 nlri1, _ := apb.New(&api.IPAddressPrefix{ 2254 Prefix: "10.1.0.0", 2255 PrefixLen: 24, 2256 }) 2257 2258 a1, _ := apb.New(&api.OriginAttribute{ 2259 Origin: 0, 2260 }) 2261 a2, _ := apb.New(&api.NextHopAttribute{ 2262 NextHop: "10.0.0.1", 2263 }) 2264 attrs := []*apb.Any{a1, a2} 2265 2266 _, err = t.AddPath(context.Background(), &api.AddPathRequest{ 2267 TableType: api.TableType_GLOBAL, 2268 Path: &api.Path{ 2269 Family: family, 2270 Nlri: nlri1, 2271 Pattrs: attrs, 2272 }, 2273 }) 2274 assert.Nil(err) 2275 2276 nlri2, _ := apb.New(&api.IPAddressPrefix{ 2277 Prefix: "10.2.0.0", 2278 PrefixLen: 24, 2279 }) 2280 _, err = t.AddPath(context.Background(), &api.AddPathRequest{ 2281 TableType: api.TableType_GLOBAL, 2282 Path: &api.Path{ 2283 Family: family, 2284 Nlri: nlri2, 2285 Pattrs: attrs, 2286 }, 2287 }) 2288 assert.Nil(err) 2289 2290 peer2 := &api.Peer{ 2291 Conf: &api.PeerConf{ 2292 NeighborAddress: "127.0.0.1", 2293 PeerAsn: 1, 2294 }, 2295 Transport: &api.Transport{ 2296 RemotePort: 10179, 2297 }, 2298 Timers: &api.Timers{ 2299 Config: &api.TimersConfig{ 2300 ConnectRetry: 1, 2301 IdleHoldTimeAfterReset: 1, 2302 }, 2303 }, 2304 } 2305 ch := make(chan struct{}) 2306 go waitEstablished(s, ch) 2307 2308 err = t.AddPeer(context.Background(), &api.AddPeerRequest{Peer: peer2}) 2309 assert.Nil(err) 2310 <-ch 2311 2312 count := 0 2313 done := make(chan struct{}) 2314 err = s.WatchEvent(context.Background(), &api.WatchEventRequest{ 2315 Table: &api.WatchEventRequest_Table{ 2316 Filters: []*api.WatchEventRequest_Table_Filter{ 2317 { 2318 Type: api.WatchEventRequest_Table_Filter_ADJIN, 2319 PeerAddress: "127.0.0.1", 2320 Init: true, 2321 }, 2322 }, 2323 }, 2324 }, func(resp *api.WatchEventResponse) { 2325 t := resp.Event.(*api.WatchEventResponse_Table) 2326 count += len(t.Table.Paths) 2327 if count == 2 { 2328 close(done) 2329 } 2330 }) 2331 assert.Nil(err) 2332 <-done 2333 2334 assert.Equal(2, count) 2335 } 2336 2337 func TestAddDefinedSetReplace(t *testing.T) { 2338 assert := assert.New(t) 2339 s := NewBgpServer() 2340 go s.Serve() 2341 err := s.StartBgp(context.Background(), &api.StartBgpRequest{ 2342 Global: &api.Global{ 2343 Asn: 1, 2344 RouterId: "1.1.1.1", 2345 ListenPort: 10179, 2346 }, 2347 }) 2348 assert.Nil(err) 2349 defer s.StopBgp(context.Background(), &api.StopBgpRequest{}) 2350 2351 // set an initial policy 2352 n1 := &api.DefinedSet{ 2353 DefinedType: api.DefinedType_NEIGHBOR, 2354 Name: "replaceme", 2355 List: []string{"203.0.113.1/32"}, 2356 } 2357 err = s.AddDefinedSet(context.Background(), &api.AddDefinedSetRequest{DefinedSet: n1}) 2358 assert.Nil(err) 2359 2360 // confirm the policy is what we set 2361 ns := make([]*api.DefinedSet, 0) 2362 fn := func(ds *api.DefinedSet) { 2363 ns = append(ns, ds) 2364 } 2365 err = s.ListDefinedSet(context.Background(), &api.ListDefinedSetRequest{ 2366 DefinedType: api.DefinedType_NEIGHBOR, 2367 Name: "replaceme", 2368 }, fn) 2369 assert.Nil(err) 2370 assert.Equal(1, len(ns)) 2371 assert.Equal("replaceme", ns[0].Name) 2372 assert.Equal([]string{"203.0.113.1/32"}, ns[0].List) 2373 2374 // now replace the policy 2375 n2 := &api.DefinedSet{ 2376 DefinedType: api.DefinedType_NEIGHBOR, 2377 Name: "replaceme", 2378 List: []string{"203.0.113.2/32"}, 2379 } 2380 err = s.AddDefinedSet(context.Background(), &api.AddDefinedSetRequest{DefinedSet: n2, Replace: true}) 2381 assert.Nil(err) 2382 2383 // confirm the policy was replaced 2384 ns = make([]*api.DefinedSet, 0) 2385 err = s.ListDefinedSet(context.Background(), &api.ListDefinedSetRequest{ 2386 DefinedType: api.DefinedType_NEIGHBOR, 2387 Name: "replaceme", 2388 }, fn) 2389 assert.Nil(err) 2390 assert.Equal(1, len(ns)) 2391 assert.Equal("replaceme", ns[0].Name) 2392 assert.Equal([]string{"203.0.113.2/32"}, ns[0].List) 2393 }