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  }