github.com/osrg/gobgp/v3@v3.30.0/internal/pkg/table/table_manager_test.go (about)

     1  // Copyright (C) 2014 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 table
    17  
    18  import (
    19  	_ "fmt"
    20  	"net"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/osrg/gobgp/v3/pkg/log"
    25  	"github.com/osrg/gobgp/v3/pkg/packet/bgp"
    26  
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  var logger = log.NewDefaultLogger()
    31  
    32  // process BGPUpdate message
    33  // this function processes only BGPUpdate
    34  func (manager *TableManager) ProcessUpdate(fromPeer *PeerInfo, message *bgp.BGPMessage) ([]*Path, error) {
    35  	pathList := make([]*Path, 0)
    36  	dsts := make([]*Update, 0)
    37  	for _, path := range ProcessMessage(message, fromPeer, time.Now()) {
    38  		dsts = append(dsts, manager.Update(path)...)
    39  	}
    40  	for _, d := range dsts {
    41  		b, _, _ := d.GetChanges(GLOBAL_RIB_NAME, 0, false)
    42  		pathList = append(pathList, b)
    43  	}
    44  	return pathList, nil
    45  }
    46  
    47  func peerR1() *PeerInfo {
    48  	peer := &PeerInfo{
    49  		AS:      65000,
    50  		LocalAS: 65000,
    51  		ID:      net.ParseIP("10.0.0.3").To4(),
    52  		LocalID: net.ParseIP("10.0.0.1").To4(),
    53  		Address: net.ParseIP("10.0.0.1").To4(),
    54  	}
    55  	return peer
    56  }
    57  
    58  func peerR2() *PeerInfo {
    59  	peer := &PeerInfo{
    60  		AS:      65100,
    61  		LocalAS: 65000,
    62  		Address: net.ParseIP("10.0.0.2").To4(),
    63  	}
    64  	return peer
    65  }
    66  
    67  func peerR3() *PeerInfo {
    68  	peer := &PeerInfo{
    69  		AS:      65000,
    70  		LocalAS: 65000,
    71  		ID:      net.ParseIP("10.0.0.2").To4(),
    72  		LocalID: net.ParseIP("10.0.0.1").To4(),
    73  		Address: net.ParseIP("10.0.0.3").To4(),
    74  	}
    75  	return peer
    76  }
    77  
    78  // test best path calculation and check the result path is from R1
    79  func TestProcessBGPUpdate_0_select_onlypath_ipv4(t *testing.T) {
    80  
    81  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
    82  
    83  	bgpMessage := update_fromR1()
    84  	peer := peerR1()
    85  	pList, err := tm.ProcessUpdate(peer, bgpMessage)
    86  	assert.Equal(t, len(pList), 1)
    87  	assert.Equal(t, pList[0].IsWithdraw, false)
    88  	assert.NoError(t, err)
    89  
    90  	// check type
    91  	path := pList[0]
    92  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
    93  
    94  	// check PathAttribute
    95  	pathAttributes := bgpMessage.Body.(*bgp.BGPUpdate).PathAttributes
    96  	expectedOrigin := pathAttributes[0]
    97  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
    98  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
    99  	assert.Equal(t, expectedOrigin, pathOrigin)
   100  
   101  	expectedAsPath := pathAttributes[1]
   102  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   103  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   104  	assert.Equal(t, expectedAsPath, pathAspath)
   105  
   106  	expectedNexthopAttr := pathAttributes[2]
   107  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
   108  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
   109  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   110  
   111  	expectedMed := pathAttributes[3]
   112  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   113  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   114  	assert.Equal(t, expectedMed, pathMed)
   115  
   116  	// check PathAttribute length
   117  	assert.Equal(t, 4, len(path.GetPathAttrs()))
   118  
   119  	// check destination
   120  	expectedPrefix := "10.10.10.0/24"
   121  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   122  	// check nexthop
   123  	expectedNexthop := "192.168.50.1"
   124  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   125  
   126  }
   127  
   128  // test best path calculation and check the result path is from R1
   129  func TestProcessBGPUpdate_0_select_onlypath_ipv6(t *testing.T) {
   130  
   131  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
   132  
   133  	bgpMessage := update_fromR1_ipv6()
   134  	peer := peerR1()
   135  	pList, err := tm.ProcessUpdate(peer, bgpMessage)
   136  	assert.Equal(t, 1, len(pList))
   137  	assert.Equal(t, pList[0].IsWithdraw, false)
   138  	assert.NoError(t, err)
   139  
   140  	// check type
   141  	path := pList[0]
   142  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
   143  
   144  	// check PathAttribute
   145  	pathAttributes := bgpMessage.Body.(*bgp.BGPUpdate).PathAttributes
   146  
   147  	expectedNexthopAttr := pathAttributes[0]
   148  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
   149  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
   150  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   151  
   152  	expectedOrigin := pathAttributes[1]
   153  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   154  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   155  	assert.Equal(t, expectedOrigin, pathOrigin)
   156  
   157  	expectedAsPath := pathAttributes[2]
   158  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   159  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   160  	assert.Equal(t, expectedAsPath, pathAspath)
   161  
   162  	expectedMed := pathAttributes[3]
   163  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   164  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   165  	assert.Equal(t, expectedMed, pathMed)
   166  
   167  	// check PathAttribute length
   168  	assert.Equal(t, 4, len(path.GetPathAttrs()))
   169  
   170  	// check destination
   171  	expectedPrefix := "2001:123:123:1::/64"
   172  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   173  	// check nexthop
   174  	expectedNexthop := "2001::192:168:50:1"
   175  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   176  
   177  }
   178  
   179  // test: compare localpref
   180  func TestProcessBGPUpdate_1_select_high_localpref_ipv4(t *testing.T) {
   181  
   182  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
   183  
   184  	// low localpref message
   185  	origin1 := bgp.NewPathAttributeOrigin(0)
   186  	aspath1 := createAsPathAttribute([]uint32{65000})
   187  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
   188  	med1 := bgp.NewPathAttributeMultiExitDisc(0)
   189  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   190  
   191  	pathAttributes1 := []bgp.PathAttributeInterface{
   192  		origin1, aspath1, nexthop1, med1, localpref1,
   193  	}
   194  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   195  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
   196  
   197  	// high localpref message
   198  	origin2 := bgp.NewPathAttributeOrigin(0)
   199  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   200  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.50.1")
   201  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   202  	localpref2 := bgp.NewPathAttributeLocalPref(200)
   203  
   204  	pathAttributes2 := []bgp.PathAttributeInterface{
   205  		origin2, aspath2, nexthop2, med2, localpref2,
   206  	}
   207  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   208  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
   209  
   210  	peer1 := peerR1()
   211  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   212  	assert.Equal(t, 1, len(pList))
   213  	assert.Equal(t, pList[0].IsWithdraw, false)
   214  	assert.NoError(t, err)
   215  
   216  	peer2 := peerR2()
   217  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   218  	assert.Equal(t, 1, len(pList))
   219  	assert.Equal(t, pList[0].IsWithdraw, false)
   220  	assert.NoError(t, err)
   221  
   222  	// check type
   223  	path := pList[0]
   224  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
   225  
   226  	// check PathAttribute
   227  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   228  	expectedOrigin := pathAttributes[0]
   229  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   230  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   231  	assert.Equal(t, expectedOrigin, pathOrigin)
   232  
   233  	expectedAsPath := pathAttributes[1]
   234  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   235  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   236  	assert.Equal(t, expectedAsPath, pathAspath)
   237  
   238  	expectedNexthopAttr := pathAttributes[2]
   239  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
   240  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
   241  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   242  
   243  	expectedMed := pathAttributes[3]
   244  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   245  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   246  	assert.Equal(t, expectedMed, pathMed)
   247  
   248  	// check PathAttribute length
   249  	assert.Equal(t, len(pathAttributes2), len(path.GetPathAttrs()))
   250  
   251  	// check destination
   252  	expectedPrefix := "10.10.10.0/24"
   253  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   254  	// check nexthop
   255  	expectedNexthop := "192.168.50.1"
   256  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   257  
   258  }
   259  
   260  func TestProcessBGPUpdate_1_select_high_localpref_ipv6(t *testing.T) {
   261  
   262  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
   263  
   264  	origin1 := bgp.NewPathAttributeOrigin(0)
   265  	aspath1 := createAsPathAttribute([]uint32{65000})
   266  	mp_reach1 := createMpReach("2001::192:168:50:1",
   267  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   268  	med1 := bgp.NewPathAttributeMultiExitDisc(100)
   269  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   270  
   271  	pathAttributes1 := []bgp.PathAttributeInterface{
   272  		mp_reach1, origin1, aspath1, med1, localpref1,
   273  	}
   274  
   275  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
   276  
   277  	origin2 := bgp.NewPathAttributeOrigin(0)
   278  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   279  	mp_reach2 := createMpReach("2001::192:168:100:1",
   280  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   281  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   282  	localpref2 := bgp.NewPathAttributeLocalPref(200)
   283  
   284  	pathAttributes2 := []bgp.PathAttributeInterface{
   285  		mp_reach2, origin2, aspath2, med2, localpref2,
   286  	}
   287  
   288  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
   289  
   290  	peer1 := peerR1()
   291  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   292  	assert.Equal(t, 1, len(pList))
   293  	assert.Equal(t, pList[0].IsWithdraw, false)
   294  	assert.NoError(t, err)
   295  
   296  	peer2 := peerR2()
   297  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   298  	assert.Equal(t, 1, len(pList))
   299  	assert.Equal(t, pList[0].IsWithdraw, false)
   300  	assert.NoError(t, err)
   301  
   302  	// check type
   303  	path := pList[0]
   304  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
   305  
   306  	// check PathAttribute
   307  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   308  
   309  	expectedNexthopAttr := pathAttributes[0]
   310  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
   311  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
   312  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   313  
   314  	expectedOrigin := pathAttributes[1]
   315  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   316  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   317  	assert.Equal(t, expectedOrigin, pathOrigin)
   318  
   319  	expectedAsPath := pathAttributes[2]
   320  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   321  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   322  	assert.Equal(t, expectedAsPath, pathAspath)
   323  
   324  	expectedMed := pathAttributes[3]
   325  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   326  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   327  	assert.Equal(t, expectedMed, pathMed)
   328  
   329  	// check PathAttribute length
   330  	assert.Equal(t, 5, len(path.GetPathAttrs()))
   331  
   332  	// check destination
   333  	expectedPrefix := "2001:123:123:1::/64"
   334  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   335  	// check nexthop
   336  	expectedNexthop := "2001::192:168:100:1"
   337  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   338  
   339  }
   340  
   341  // test: compare localOrigin
   342  func TestProcessBGPUpdate_2_select_local_origin_ipv4(t *testing.T) {
   343  
   344  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
   345  
   346  	// low localpref message
   347  	origin1 := bgp.NewPathAttributeOrigin(0)
   348  	aspath1 := createAsPathAttribute([]uint32{65000})
   349  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
   350  	med1 := bgp.NewPathAttributeMultiExitDisc(0)
   351  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   352  
   353  	pathAttributes1 := []bgp.PathAttributeInterface{
   354  		origin1, aspath1, nexthop1, med1, localpref1,
   355  	}
   356  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   357  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
   358  
   359  	// high localpref message
   360  	origin2 := bgp.NewPathAttributeOrigin(0)
   361  	aspath2 := createAsPathAttribute([]uint32{})
   362  	nexthop2 := bgp.NewPathAttributeNextHop("0.0.0.0")
   363  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   364  	localpref2 := bgp.NewPathAttributeLocalPref(100)
   365  
   366  	pathAttributes2 := []bgp.PathAttributeInterface{
   367  		origin2, aspath2, nexthop2, med2, localpref2,
   368  	}
   369  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   370  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
   371  
   372  	peer1 := peerR1()
   373  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   374  	assert.Equal(t, 1, len(pList))
   375  	assert.Equal(t, pList[0].IsWithdraw, false)
   376  	assert.NoError(t, err)
   377  
   378  	var peer2 *PeerInfo = &PeerInfo{
   379  		Address: net.ParseIP("0.0.0.0"),
   380  	}
   381  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   382  	assert.Equal(t, 1, len(pList))
   383  	assert.Equal(t, pList[0].IsWithdraw, false)
   384  	assert.NoError(t, err)
   385  
   386  	// check type
   387  	path := pList[0]
   388  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
   389  
   390  	// check PathAttribute
   391  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   392  	expectedOrigin := pathAttributes[0]
   393  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   394  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   395  	assert.Equal(t, expectedOrigin, pathOrigin)
   396  
   397  	expectedAsPath := pathAttributes[1]
   398  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   399  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   400  	assert.Equal(t, expectedAsPath, pathAspath)
   401  
   402  	expectedNexthopAttr := pathAttributes[2]
   403  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
   404  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
   405  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   406  
   407  	expectedMed := pathAttributes[3]
   408  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   409  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   410  	assert.Equal(t, expectedMed, pathMed)
   411  
   412  	// check PathAttribute length
   413  	assert.Equal(t, len(pathAttributes2), len(path.GetPathAttrs()))
   414  
   415  	// check destination
   416  	expectedPrefix := "10.10.10.0/24"
   417  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   418  	// check nexthop
   419  	expectedNexthop := "0.0.0.0"
   420  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   421  
   422  }
   423  
   424  func TestProcessBGPUpdate_2_select_local_origin_ipv6(t *testing.T) {
   425  
   426  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
   427  
   428  	origin1 := bgp.NewPathAttributeOrigin(0)
   429  	aspath1 := createAsPathAttribute([]uint32{65000})
   430  	mp_reach1 := createMpReach("2001::192:168:50:1",
   431  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   432  	med1 := bgp.NewPathAttributeMultiExitDisc(100)
   433  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   434  
   435  	pathAttributes1 := []bgp.PathAttributeInterface{
   436  		mp_reach1, origin1, aspath1, med1, localpref1,
   437  	}
   438  
   439  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
   440  
   441  	origin2 := bgp.NewPathAttributeOrigin(0)
   442  	aspath2 := createAsPathAttribute([]uint32{})
   443  	mp_reach2 := createMpReach("::",
   444  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   445  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   446  	localpref2 := bgp.NewPathAttributeLocalPref(100)
   447  
   448  	pathAttributes2 := []bgp.PathAttributeInterface{
   449  		mp_reach2, origin2, aspath2, med2, localpref2,
   450  	}
   451  
   452  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
   453  
   454  	peer1 := peerR1()
   455  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   456  	assert.Equal(t, 1, len(pList))
   457  	assert.Equal(t, pList[0].IsWithdraw, false)
   458  	assert.NoError(t, err)
   459  
   460  	var peer2 *PeerInfo = &PeerInfo{
   461  		Address: net.ParseIP("0.0.0.0"),
   462  	}
   463  
   464  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   465  	assert.Equal(t, 1, len(pList))
   466  	assert.Equal(t, pList[0].IsWithdraw, false)
   467  	assert.NoError(t, err)
   468  
   469  	// check type
   470  	path := pList[0]
   471  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
   472  
   473  	// check PathAttribute
   474  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   475  
   476  	expectedNexthopAttr := pathAttributes[0]
   477  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
   478  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
   479  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   480  
   481  	expectedOrigin := pathAttributes[1]
   482  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   483  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   484  	assert.Equal(t, expectedOrigin, pathOrigin)
   485  
   486  	expectedAsPath := pathAttributes[2]
   487  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   488  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   489  	assert.Equal(t, expectedAsPath, pathAspath)
   490  
   491  	expectedMed := pathAttributes[3]
   492  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   493  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   494  	assert.Equal(t, expectedMed, pathMed)
   495  
   496  	// check PathAttribute length
   497  	assert.Equal(t, 5, len(path.GetPathAttrs()))
   498  
   499  	// check destination
   500  	expectedPrefix := "2001:123:123:1::/64"
   501  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   502  	// check nexthop
   503  	expectedNexthop := "::"
   504  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   505  
   506  }
   507  
   508  // test: compare AS_PATH
   509  func TestProcessBGPUpdate_3_select_aspath_ipv4(t *testing.T) {
   510  
   511  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
   512  
   513  	bgpMessage1 := update_fromR2viaR1()
   514  	peer1 := peerR1()
   515  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   516  	assert.Equal(t, 1, len(pList))
   517  	assert.Equal(t, pList[0].IsWithdraw, false)
   518  	assert.NoError(t, err)
   519  	bgpMessage2 := update_fromR2()
   520  	peer2 := peerR2()
   521  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   522  	assert.Equal(t, 1, len(pList))
   523  	assert.Equal(t, pList[0].IsWithdraw, false)
   524  	assert.NoError(t, err)
   525  
   526  	// check type
   527  	path := pList[0]
   528  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
   529  
   530  	// check PathAttribute
   531  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   532  	expectedOrigin := pathAttributes[0]
   533  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   534  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   535  	assert.Equal(t, expectedOrigin, pathOrigin)
   536  
   537  	expectedAsPath := pathAttributes[1]
   538  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   539  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   540  	assert.Equal(t, expectedAsPath, pathAspath)
   541  
   542  	expectedNexthopAttr := pathAttributes[2]
   543  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
   544  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
   545  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   546  
   547  	expectedMed := pathAttributes[3]
   548  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   549  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   550  	assert.Equal(t, expectedMed, pathMed)
   551  
   552  	// check PathAttribute length
   553  	assert.Equal(t, 4, len(path.GetPathAttrs()))
   554  
   555  	// check destination
   556  	expectedPrefix := "20.20.20.0/24"
   557  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   558  	// check nexthop
   559  	expectedNexthop := "192.168.100.1"
   560  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   561  
   562  }
   563  
   564  func TestProcessBGPUpdate_3_select_aspath_ipv6(t *testing.T) {
   565  
   566  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
   567  
   568  	bgpMessage1 := update_fromR2viaR1_ipv6()
   569  	peer1 := peerR1()
   570  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   571  	assert.Equal(t, 1, len(pList))
   572  	assert.Equal(t, pList[0].IsWithdraw, false)
   573  	assert.NoError(t, err)
   574  	bgpMessage2 := update_fromR2_ipv6()
   575  	peer2 := peerR2()
   576  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   577  	assert.Equal(t, 1, len(pList))
   578  	assert.Equal(t, pList[0].IsWithdraw, false)
   579  	assert.NoError(t, err)
   580  
   581  	// check type
   582  	path := pList[0]
   583  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
   584  
   585  	// check PathAttribute
   586  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   587  
   588  	expectedNexthopAttr := pathAttributes[0]
   589  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
   590  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
   591  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   592  
   593  	expectedOrigin := pathAttributes[1]
   594  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   595  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   596  	assert.Equal(t, expectedOrigin, pathOrigin)
   597  
   598  	expectedAsPath := pathAttributes[2]
   599  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   600  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   601  	assert.Equal(t, expectedAsPath, pathAspath)
   602  
   603  	expectedMed := pathAttributes[3]
   604  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   605  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   606  	assert.Equal(t, expectedMed, pathMed)
   607  
   608  	// check PathAttribute length
   609  	assert.Equal(t, 4, len(path.GetPathAttrs()))
   610  
   611  	// check destination
   612  	expectedPrefix := "2002:223:123:1::/64"
   613  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   614  	// check nexthop
   615  	expectedNexthop := "2001::192:168:100:1"
   616  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   617  
   618  }
   619  
   620  // test: compare Origin
   621  func TestProcessBGPUpdate_4_select_low_origin_ipv4(t *testing.T) {
   622  
   623  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
   624  
   625  	// low origin message
   626  	origin1 := bgp.NewPathAttributeOrigin(1)
   627  	aspath1 := createAsPathAttribute([]uint32{65200, 65000})
   628  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
   629  	med1 := bgp.NewPathAttributeMultiExitDisc(100)
   630  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   631  
   632  	pathAttributes1 := []bgp.PathAttributeInterface{
   633  		origin1, aspath1, nexthop1, med1, localpref1,
   634  	}
   635  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   636  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
   637  
   638  	// high origin message
   639  	origin2 := bgp.NewPathAttributeOrigin(0)
   640  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   641  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.100.1")
   642  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   643  	localpref2 := bgp.NewPathAttributeLocalPref(100)
   644  
   645  	pathAttributes2 := []bgp.PathAttributeInterface{
   646  		origin2, aspath2, nexthop2, med2, localpref2,
   647  	}
   648  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   649  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
   650  
   651  	peer1 := peerR1()
   652  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   653  	assert.Equal(t, 1, len(pList))
   654  	assert.Equal(t, pList[0].IsWithdraw, false)
   655  	assert.NoError(t, err)
   656  
   657  	peer2 := peerR2()
   658  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   659  	assert.Equal(t, 1, len(pList))
   660  	assert.Equal(t, pList[0].IsWithdraw, false)
   661  	assert.NoError(t, err)
   662  
   663  	// check type
   664  	path := pList[0]
   665  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
   666  
   667  	// check PathAttribute
   668  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   669  	expectedOrigin := pathAttributes[0]
   670  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   671  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   672  	assert.Equal(t, expectedOrigin, pathOrigin)
   673  
   674  	expectedAsPath := pathAttributes[1]
   675  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   676  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   677  	assert.Equal(t, expectedAsPath, pathAspath)
   678  
   679  	expectedNexthopAttr := pathAttributes[2]
   680  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
   681  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
   682  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   683  
   684  	expectedMed := pathAttributes[3]
   685  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   686  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   687  	assert.Equal(t, expectedMed, pathMed)
   688  
   689  	// check PathAttribute length
   690  	assert.Equal(t, len(pathAttributes2), len(path.GetPathAttrs()))
   691  
   692  	// check destination
   693  	expectedPrefix := "10.10.10.0/24"
   694  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   695  	// check nexthop
   696  	expectedNexthop := "192.168.100.1"
   697  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   698  
   699  }
   700  
   701  func TestProcessBGPUpdate_4_select_low_origin_ipv6(t *testing.T) {
   702  
   703  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
   704  
   705  	origin1 := bgp.NewPathAttributeOrigin(1)
   706  	aspath1 := createAsPathAttribute([]uint32{65200, 65000})
   707  	mp_reach1 := createMpReach("2001::192:168:50:1",
   708  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   709  	med1 := bgp.NewPathAttributeMultiExitDisc(100)
   710  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   711  
   712  	pathAttributes1 := []bgp.PathAttributeInterface{
   713  		mp_reach1, origin1, aspath1, med1, localpref1,
   714  	}
   715  
   716  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
   717  
   718  	origin2 := bgp.NewPathAttributeOrigin(0)
   719  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   720  	mp_reach2 := createMpReach("2001::192:168:100:1",
   721  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   722  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   723  	localpref2 := bgp.NewPathAttributeLocalPref(200)
   724  
   725  	pathAttributes2 := []bgp.PathAttributeInterface{
   726  		mp_reach2, origin2, aspath2, med2, localpref2,
   727  	}
   728  
   729  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
   730  
   731  	peer1 := peerR1()
   732  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   733  	assert.Equal(t, 1, len(pList))
   734  	assert.Equal(t, pList[0].IsWithdraw, false)
   735  	assert.NoError(t, err)
   736  
   737  	peer2 := peerR2()
   738  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   739  	assert.Equal(t, 1, len(pList))
   740  	assert.Equal(t, pList[0].IsWithdraw, false)
   741  	assert.NoError(t, err)
   742  
   743  	// check type
   744  	path := pList[0]
   745  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
   746  
   747  	// check PathAttribute
   748  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   749  
   750  	expectedNexthopAttr := pathAttributes[0]
   751  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
   752  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
   753  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   754  
   755  	expectedOrigin := pathAttributes[1]
   756  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   757  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   758  	assert.Equal(t, expectedOrigin, pathOrigin)
   759  
   760  	expectedAsPath := pathAttributes[2]
   761  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   762  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   763  	assert.Equal(t, expectedAsPath, pathAspath)
   764  
   765  	expectedMed := pathAttributes[3]
   766  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   767  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   768  	assert.Equal(t, expectedMed, pathMed)
   769  
   770  	// check PathAttribute length
   771  	assert.Equal(t, 5, len(path.GetPathAttrs()))
   772  
   773  	// check destination
   774  	expectedPrefix := "2001:123:123:1::/64"
   775  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   776  	// check nexthop
   777  	expectedNexthop := "2001::192:168:100:1"
   778  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   779  
   780  }
   781  
   782  // test: compare MED
   783  func TestProcessBGPUpdate_5_select_low_med_ipv4(t *testing.T) {
   784  
   785  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
   786  
   787  	// low origin message
   788  	origin1 := bgp.NewPathAttributeOrigin(0)
   789  	aspath1 := createAsPathAttribute([]uint32{65200, 65000})
   790  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
   791  	med1 := bgp.NewPathAttributeMultiExitDisc(500)
   792  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   793  
   794  	pathAttributes1 := []bgp.PathAttributeInterface{
   795  		origin1, aspath1, nexthop1, med1, localpref1,
   796  	}
   797  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   798  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
   799  
   800  	// high origin message
   801  	origin2 := bgp.NewPathAttributeOrigin(0)
   802  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   803  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.100.1")
   804  	med2 := bgp.NewPathAttributeMultiExitDisc(100)
   805  	localpref2 := bgp.NewPathAttributeLocalPref(100)
   806  
   807  	pathAttributes2 := []bgp.PathAttributeInterface{
   808  		origin2, aspath2, nexthop2, med2, localpref2,
   809  	}
   810  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   811  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
   812  
   813  	peer1 := peerR1()
   814  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   815  	assert.Equal(t, 1, len(pList))
   816  	assert.Equal(t, pList[0].IsWithdraw, false)
   817  	assert.NoError(t, err)
   818  
   819  	peer2 := peerR2()
   820  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   821  	assert.Equal(t, 1, len(pList))
   822  	assert.Equal(t, pList[0].IsWithdraw, false)
   823  	assert.NoError(t, err)
   824  
   825  	// check type
   826  	path := pList[0]
   827  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
   828  
   829  	// check PathAttribute
   830  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   831  	expectedOrigin := pathAttributes[0]
   832  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   833  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   834  	assert.Equal(t, expectedOrigin, pathOrigin)
   835  
   836  	expectedAsPath := pathAttributes[1]
   837  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   838  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   839  	assert.Equal(t, expectedAsPath, pathAspath)
   840  
   841  	expectedNexthopAttr := pathAttributes[2]
   842  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
   843  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
   844  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   845  
   846  	expectedMed := pathAttributes[3]
   847  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   848  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   849  	assert.Equal(t, expectedMed, pathMed)
   850  
   851  	// check PathAttribute length
   852  	assert.Equal(t, len(pathAttributes2), len(path.GetPathAttrs()))
   853  
   854  	// check destination
   855  	expectedPrefix := "10.10.10.0/24"
   856  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   857  	// check nexthop
   858  	expectedNexthop := "192.168.100.1"
   859  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   860  
   861  }
   862  
   863  func TestProcessBGPUpdate_5_select_low_med_ipv6(t *testing.T) {
   864  
   865  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
   866  
   867  	origin1 := bgp.NewPathAttributeOrigin(0)
   868  	aspath1 := createAsPathAttribute([]uint32{65200, 65000})
   869  	mp_reach1 := createMpReach("2001::192:168:50:1",
   870  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   871  	med1 := bgp.NewPathAttributeMultiExitDisc(500)
   872  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   873  
   874  	pathAttributes1 := []bgp.PathAttributeInterface{
   875  		mp_reach1, origin1, aspath1, med1, localpref1,
   876  	}
   877  
   878  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
   879  
   880  	origin2 := bgp.NewPathAttributeOrigin(0)
   881  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   882  	mp_reach2 := createMpReach("2001::192:168:100:1",
   883  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
   884  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
   885  	localpref2 := bgp.NewPathAttributeLocalPref(100)
   886  
   887  	pathAttributes2 := []bgp.PathAttributeInterface{
   888  		mp_reach2, origin2, aspath2, med2, localpref2,
   889  	}
   890  
   891  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
   892  
   893  	peer1 := peerR1()
   894  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   895  	assert.Equal(t, 1, len(pList))
   896  	assert.Equal(t, pList[0].IsWithdraw, false)
   897  	assert.NoError(t, err)
   898  
   899  	peer2 := peerR2()
   900  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   901  	assert.Equal(t, 1, len(pList))
   902  	assert.Equal(t, pList[0].IsWithdraw, false)
   903  	assert.NoError(t, err)
   904  
   905  	// check type
   906  	path := pList[0]
   907  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
   908  
   909  	// check PathAttribute
   910  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   911  
   912  	expectedNexthopAttr := pathAttributes[0]
   913  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
   914  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
   915  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
   916  
   917  	expectedOrigin := pathAttributes[1]
   918  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   919  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   920  	assert.Equal(t, expectedOrigin, pathOrigin)
   921  
   922  	expectedAsPath := pathAttributes[2]
   923  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
   924  	pathAspath := attr.(*bgp.PathAttributeAsPath)
   925  	assert.Equal(t, expectedAsPath, pathAspath)
   926  
   927  	expectedMed := pathAttributes[3]
   928  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
   929  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
   930  	assert.Equal(t, expectedMed, pathMed)
   931  
   932  	// check PathAttribute length
   933  	assert.Equal(t, 5, len(path.GetPathAttrs()))
   934  
   935  	// check destination
   936  	expectedPrefix := "2001:123:123:1::/64"
   937  	assert.Equal(t, expectedPrefix, path.GetPrefix())
   938  	// check nexthop
   939  	expectedNexthop := "2001::192:168:100:1"
   940  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
   941  
   942  }
   943  
   944  // test: compare AS_NUMBER(prefer eBGP path)
   945  func TestProcessBGPUpdate_6_select_ebgp_path_ipv4(t *testing.T) {
   946  
   947  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
   948  
   949  	// low origin message
   950  	origin1 := bgp.NewPathAttributeOrigin(0)
   951  	aspath1 := createAsPathAttribute([]uint32{65000, 65200})
   952  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
   953  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
   954  	localpref1 := bgp.NewPathAttributeLocalPref(100)
   955  
   956  	pathAttributes1 := []bgp.PathAttributeInterface{
   957  		origin1, aspath1, nexthop1, med1, localpref1,
   958  	}
   959  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   960  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
   961  
   962  	// high origin message
   963  	origin2 := bgp.NewPathAttributeOrigin(0)
   964  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
   965  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.100.1")
   966  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
   967  	localpref2 := bgp.NewPathAttributeLocalPref(100)
   968  
   969  	pathAttributes2 := []bgp.PathAttributeInterface{
   970  		origin2, aspath2, nexthop2, med2, localpref2,
   971  	}
   972  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
   973  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
   974  
   975  	peer1 := peerR1()
   976  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
   977  	assert.Equal(t, 1, len(pList))
   978  	assert.Equal(t, pList[0].IsWithdraw, false)
   979  	assert.NoError(t, err)
   980  
   981  	peer2 := peerR2()
   982  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
   983  	assert.Equal(t, 1, len(pList))
   984  	assert.Equal(t, pList[0].IsWithdraw, false)
   985  	assert.NoError(t, err)
   986  
   987  	// check type
   988  	path := pList[0]
   989  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
   990  
   991  	// check PathAttribute
   992  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
   993  	expectedOrigin := pathAttributes[0]
   994  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
   995  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
   996  	assert.Equal(t, expectedOrigin, pathOrigin)
   997  
   998  	expectedAsPath := pathAttributes[1]
   999  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1000  	pathAspath := attr.(*bgp.PathAttributeAsPath)
  1001  	assert.Equal(t, expectedAsPath, pathAspath)
  1002  
  1003  	expectedNexthopAttr := pathAttributes[2]
  1004  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
  1005  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
  1006  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1007  
  1008  	expectedMed := pathAttributes[3]
  1009  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1010  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1011  	assert.Equal(t, expectedMed, pathMed)
  1012  
  1013  	// check PathAttribute length
  1014  	assert.Equal(t, len(pathAttributes2), len(path.GetPathAttrs()))
  1015  
  1016  	// check destination
  1017  	expectedPrefix := "10.10.10.0/24"
  1018  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1019  	// check nexthop
  1020  	expectedNexthop := "192.168.100.1"
  1021  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1022  
  1023  }
  1024  
  1025  func TestProcessBGPUpdate_6_select_ebgp_path_ipv6(t *testing.T) {
  1026  
  1027  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
  1028  
  1029  	origin1 := bgp.NewPathAttributeOrigin(0)
  1030  	aspath1 := createAsPathAttribute([]uint32{65000, 65200})
  1031  	mp_reach1 := createMpReach("2001::192:168:50:1",
  1032  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1033  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1034  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1035  
  1036  	pathAttributes1 := []bgp.PathAttributeInterface{
  1037  		mp_reach1, origin1, aspath1, med1, localpref1,
  1038  	}
  1039  
  1040  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
  1041  
  1042  	origin2 := bgp.NewPathAttributeOrigin(0)
  1043  	aspath2 := createAsPathAttribute([]uint32{65100, 65200})
  1044  	mp_reach2 := createMpReach("2001::192:168:100:1",
  1045  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1046  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1047  	localpref2 := bgp.NewPathAttributeLocalPref(100)
  1048  
  1049  	pathAttributes2 := []bgp.PathAttributeInterface{
  1050  		mp_reach2, origin2, aspath2, med2, localpref2,
  1051  	}
  1052  
  1053  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
  1054  
  1055  	peer1 := peerR1()
  1056  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1057  	assert.Equal(t, 1, len(pList))
  1058  	assert.Equal(t, pList[0].IsWithdraw, false)
  1059  	assert.NoError(t, err)
  1060  
  1061  	peer2 := peerR2()
  1062  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
  1063  	assert.Equal(t, 1, len(pList))
  1064  	assert.Equal(t, pList[0].IsWithdraw, false)
  1065  	assert.NoError(t, err)
  1066  
  1067  	// check type
  1068  	path := pList[0]
  1069  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
  1070  
  1071  	// check PathAttribute
  1072  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
  1073  
  1074  	expectedNexthopAttr := pathAttributes[0]
  1075  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1076  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1077  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1078  
  1079  	expectedOrigin := pathAttributes[1]
  1080  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1081  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1082  	assert.Equal(t, expectedOrigin, pathOrigin)
  1083  
  1084  	expectedAsPath := pathAttributes[2]
  1085  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1086  	pathAspath := attr.(*bgp.PathAttributeAsPath)
  1087  	assert.Equal(t, expectedAsPath, pathAspath)
  1088  
  1089  	expectedMed := pathAttributes[3]
  1090  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1091  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1092  	assert.Equal(t, expectedMed, pathMed)
  1093  
  1094  	// check PathAttribute length
  1095  	assert.Equal(t, 5, len(path.GetPathAttrs()))
  1096  
  1097  	// check destination
  1098  	expectedPrefix := "2001:123:123:1::/64"
  1099  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1100  	// check nexthop
  1101  	expectedNexthop := "2001::192:168:100:1"
  1102  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1103  
  1104  }
  1105  
  1106  // test: compare IGP cost -> N/A
  1107  
  1108  // test: compare Router ID
  1109  func TestProcessBGPUpdate_7_select_low_routerid_path_ipv4(t *testing.T) {
  1110  
  1111  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
  1112  	SelectionOptions.ExternalCompareRouterId = true
  1113  
  1114  	// low origin message
  1115  	origin1 := bgp.NewPathAttributeOrigin(0)
  1116  	aspath1 := createAsPathAttribute([]uint32{65000, 65200})
  1117  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
  1118  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1119  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1120  
  1121  	pathAttributes1 := []bgp.PathAttributeInterface{
  1122  		origin1, aspath1, nexthop1, med1, localpref1,
  1123  	}
  1124  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1125  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
  1126  
  1127  	// high origin message
  1128  	origin2 := bgp.NewPathAttributeOrigin(0)
  1129  	aspath2 := createAsPathAttribute([]uint32{65000, 65100})
  1130  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.100.1")
  1131  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1132  	localpref2 := bgp.NewPathAttributeLocalPref(100)
  1133  
  1134  	pathAttributes2 := []bgp.PathAttributeInterface{
  1135  		origin2, aspath2, nexthop2, med2, localpref2,
  1136  	}
  1137  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1138  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
  1139  
  1140  	peer1 := peerR1()
  1141  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1142  	assert.Equal(t, 1, len(pList))
  1143  	assert.Equal(t, pList[0].IsWithdraw, false)
  1144  	assert.NoError(t, err)
  1145  
  1146  	peer3 := peerR3()
  1147  	pList, err = tm.ProcessUpdate(peer3, bgpMessage2)
  1148  	assert.Equal(t, 1, len(pList))
  1149  	assert.Equal(t, pList[0].IsWithdraw, false)
  1150  	assert.NoError(t, err)
  1151  
  1152  	// check type
  1153  	path := pList[0]
  1154  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
  1155  
  1156  	// check PathAttribute
  1157  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
  1158  	expectedOrigin := pathAttributes[0]
  1159  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1160  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1161  	assert.Equal(t, expectedOrigin, pathOrigin)
  1162  
  1163  	expectedAsPath := pathAttributes[1]
  1164  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1165  	pathAspath := attr.(*bgp.PathAttributeAsPath)
  1166  	assert.Equal(t, expectedAsPath, pathAspath)
  1167  
  1168  	expectedNexthopAttr := pathAttributes[2]
  1169  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
  1170  	pathNexthop := attr.(*bgp.PathAttributeNextHop)
  1171  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1172  
  1173  	expectedMed := pathAttributes[3]
  1174  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1175  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1176  	assert.Equal(t, expectedMed, pathMed)
  1177  
  1178  	// check PathAttribute length
  1179  	assert.Equal(t, len(pathAttributes2), len(path.GetPathAttrs()))
  1180  
  1181  	// check destination
  1182  	expectedPrefix := "10.10.10.0/24"
  1183  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1184  	// check nexthop
  1185  	expectedNexthop := "192.168.100.1"
  1186  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1187  
  1188  }
  1189  
  1190  func TestProcessBGPUpdate_7_select_low_routerid_path_ipv6(t *testing.T) {
  1191  
  1192  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
  1193  
  1194  	origin1 := bgp.NewPathAttributeOrigin(0)
  1195  	aspath1 := createAsPathAttribute([]uint32{65000, 65200})
  1196  	mp_reach1 := createMpReach("2001::192:168:50:1",
  1197  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1198  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1199  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1200  
  1201  	pathAttributes1 := []bgp.PathAttributeInterface{
  1202  		mp_reach1, origin1, aspath1, med1, localpref1,
  1203  	}
  1204  
  1205  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
  1206  
  1207  	origin2 := bgp.NewPathAttributeOrigin(0)
  1208  	aspath2 := createAsPathAttribute([]uint32{65100, 65200})
  1209  	mp_reach2 := createMpReach("2001::192:168:100:1",
  1210  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1211  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1212  	localpref2 := bgp.NewPathAttributeLocalPref(100)
  1213  
  1214  	pathAttributes2 := []bgp.PathAttributeInterface{
  1215  		mp_reach2, origin2, aspath2, med2, localpref2,
  1216  	}
  1217  
  1218  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
  1219  
  1220  	peer1 := peerR1()
  1221  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1222  	assert.Equal(t, 1, len(pList))
  1223  	assert.Equal(t, pList[0].IsWithdraw, false)
  1224  	assert.NoError(t, err)
  1225  
  1226  	peer3 := peerR3()
  1227  	pList, err = tm.ProcessUpdate(peer3, bgpMessage2)
  1228  	assert.Equal(t, 1, len(pList))
  1229  	assert.Equal(t, pList[0].IsWithdraw, false)
  1230  	assert.NoError(t, err)
  1231  
  1232  	// check type
  1233  	path := pList[0]
  1234  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
  1235  
  1236  	// check PathAttribute
  1237  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
  1238  
  1239  	expectedNexthopAttr := pathAttributes[0]
  1240  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1241  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1242  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1243  
  1244  	expectedOrigin := pathAttributes[1]
  1245  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1246  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1247  	assert.Equal(t, expectedOrigin, pathOrigin)
  1248  
  1249  	expectedAsPath := pathAttributes[2]
  1250  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1251  	pathAspath := attr.(*bgp.PathAttributeAsPath)
  1252  	assert.Equal(t, expectedAsPath, pathAspath)
  1253  
  1254  	expectedMed := pathAttributes[3]
  1255  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1256  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1257  	assert.Equal(t, expectedMed, pathMed)
  1258  
  1259  	// check PathAttribute length
  1260  	assert.Equal(t, 5, len(path.GetPathAttrs()))
  1261  
  1262  	// check destination
  1263  	expectedPrefix := "2001:123:123:1::/64"
  1264  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1265  	// check nexthop
  1266  	expectedNexthop := "2001::192:168:100:1"
  1267  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1268  
  1269  }
  1270  
  1271  // test: withdraw and mpunreach path
  1272  func TestProcessBGPUpdate_8_withdraw_path_ipv4(t *testing.T) {
  1273  
  1274  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
  1275  
  1276  	// path1
  1277  	origin1 := bgp.NewPathAttributeOrigin(0)
  1278  	aspath1 := createAsPathAttribute([]uint32{65000})
  1279  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
  1280  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1281  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1282  
  1283  	pathAttributes1 := []bgp.PathAttributeInterface{
  1284  		origin1, aspath1, nexthop1, med1, localpref1,
  1285  	}
  1286  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1287  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
  1288  
  1289  	// path 2
  1290  	origin2 := bgp.NewPathAttributeOrigin(0)
  1291  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
  1292  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.100.1")
  1293  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1294  	localpref2 := bgp.NewPathAttributeLocalPref(200)
  1295  
  1296  	pathAttributes2 := []bgp.PathAttributeInterface{
  1297  		origin2, aspath2, nexthop2, med2, localpref2,
  1298  	}
  1299  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1300  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
  1301  
  1302  	peer1 := peerR1()
  1303  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1304  	assert.Equal(t, 1, len(pList))
  1305  	assert.Equal(t, pList[0].IsWithdraw, false)
  1306  	assert.NoError(t, err)
  1307  
  1308  	peer2 := peerR2()
  1309  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
  1310  	assert.Equal(t, 1, len(pList))
  1311  	assert.Equal(t, pList[0].IsWithdraw, false)
  1312  	assert.NoError(t, err)
  1313  
  1314  	// check type
  1315  	path := pList[0]
  1316  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
  1317  
  1318  	// check PathAttribute
  1319  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1320  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1321  		expectedOrigin := pathAttributes[0]
  1322  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1323  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1324  		assert.Equal(t, expectedOrigin, pathOrigin)
  1325  
  1326  		expectedAsPath := pathAttributes[1]
  1327  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1328  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1329  		assert.Equal(t, expectedAsPath, pathAspath)
  1330  
  1331  		expectedNexthopAttr := pathAttributes[2]
  1332  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
  1333  		pathNexthop := attr.(*bgp.PathAttributeNextHop)
  1334  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1335  
  1336  		expectedMed := pathAttributes[3]
  1337  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1338  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1339  		assert.Equal(t, expectedMed, pathMed)
  1340  
  1341  		// check PathAttribute length
  1342  		assert.Equal(t, len(pathAttributes), len(path.GetPathAttrs()))
  1343  	}
  1344  	checkPattr(bgpMessage2, path)
  1345  	// check destination
  1346  	expectedPrefix := "10.10.10.0/24"
  1347  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1348  	// check nexthop
  1349  	expectedNexthop := "192.168.100.1"
  1350  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1351  
  1352  	//withdraw path
  1353  	w1 := bgp.NewIPAddrPrefix(24, "10.10.10.0")
  1354  	w := []*bgp.IPAddrPrefix{w1}
  1355  	bgpMessage3 := bgp.NewBGPUpdateMessage(w, nil, nil)
  1356  
  1357  	pList, err = tm.ProcessUpdate(peer2, bgpMessage3)
  1358  	assert.Equal(t, 1, len(pList))
  1359  	assert.Equal(t, pList[0].IsWithdraw, false)
  1360  	assert.NoError(t, err)
  1361  
  1362  	path = pList[0]
  1363  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
  1364  
  1365  	checkPattr(bgpMessage1, path)
  1366  	// check destination
  1367  	expectedPrefix = "10.10.10.0/24"
  1368  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1369  	// check nexthop
  1370  	expectedNexthop = "192.168.50.1"
  1371  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1372  }
  1373  
  1374  // TODO MP_UNREACH
  1375  func TestProcessBGPUpdate_8_mpunreach_path_ipv6(t *testing.T) {
  1376  
  1377  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
  1378  
  1379  	origin1 := bgp.NewPathAttributeOrigin(0)
  1380  	aspath1 := createAsPathAttribute([]uint32{65000})
  1381  	mp_reach1 := createMpReach("2001::192:168:50:1",
  1382  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1383  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1384  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1385  
  1386  	pathAttributes1 := []bgp.PathAttributeInterface{
  1387  		mp_reach1, origin1, aspath1, med1, localpref1,
  1388  	}
  1389  
  1390  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
  1391  
  1392  	origin2 := bgp.NewPathAttributeOrigin(0)
  1393  	aspath2 := createAsPathAttribute([]uint32{65100, 65000})
  1394  	mp_reach2 := createMpReach("2001::192:168:100:1",
  1395  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1396  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1397  	localpref2 := bgp.NewPathAttributeLocalPref(200)
  1398  
  1399  	pathAttributes2 := []bgp.PathAttributeInterface{
  1400  		mp_reach2, origin2, aspath2, med2, localpref2,
  1401  	}
  1402  
  1403  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
  1404  
  1405  	peer1 := peerR1()
  1406  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1407  	assert.Equal(t, 1, len(pList))
  1408  	assert.Equal(t, pList[0].IsWithdraw, false)
  1409  	assert.NoError(t, err)
  1410  
  1411  	peer2 := peerR2()
  1412  	pList, err = tm.ProcessUpdate(peer2, bgpMessage2)
  1413  	assert.Equal(t, 1, len(pList))
  1414  	assert.Equal(t, pList[0].IsWithdraw, false)
  1415  	assert.NoError(t, err)
  1416  
  1417  	// check type
  1418  	path := pList[0]
  1419  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
  1420  
  1421  	// check PathAttribute
  1422  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
  1423  
  1424  	expectedNexthopAttr := pathAttributes[0]
  1425  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1426  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1427  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1428  
  1429  	expectedOrigin := pathAttributes[1]
  1430  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1431  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1432  	assert.Equal(t, expectedOrigin, pathOrigin)
  1433  
  1434  	expectedAsPath := pathAttributes[2]
  1435  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1436  	pathAspath := attr.(*bgp.PathAttributeAsPath)
  1437  	assert.Equal(t, expectedAsPath, pathAspath)
  1438  
  1439  	expectedMed := pathAttributes[3]
  1440  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1441  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1442  	assert.Equal(t, expectedMed, pathMed)
  1443  
  1444  	// check PathAttribute
  1445  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1446  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1447  
  1448  		expectedNexthopAttr := pathAttributes[0]
  1449  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1450  		pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1451  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1452  
  1453  		expectedOrigin := pathAttributes[1]
  1454  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1455  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1456  		assert.Equal(t, expectedOrigin, pathOrigin)
  1457  
  1458  		expectedAsPath := pathAttributes[2]
  1459  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1460  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1461  		assert.Equal(t, expectedAsPath, pathAspath)
  1462  
  1463  		expectedMed := pathAttributes[3]
  1464  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1465  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1466  		assert.Equal(t, expectedMed, pathMed)
  1467  		// check PathAttribute length
  1468  		assert.Equal(t, len(pathAttributes), len(path.GetPathAttrs()))
  1469  	}
  1470  
  1471  	checkPattr(bgpMessage2, path)
  1472  
  1473  	// check destination
  1474  	expectedPrefix := "2001:123:123:1::/64"
  1475  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1476  	// check nexthop
  1477  	expectedNexthop := "2001::192:168:100:1"
  1478  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1479  
  1480  	//mpunreach path
  1481  	mp_unreach := createMpUNReach("2001:123:123:1::", 64)
  1482  	bgpMessage3 := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{mp_unreach}, nil)
  1483  
  1484  	pList, err = tm.ProcessUpdate(peer2, bgpMessage3)
  1485  	assert.Equal(t, 1, len(pList))
  1486  	assert.Equal(t, pList[0].IsWithdraw, false)
  1487  	assert.NoError(t, err)
  1488  
  1489  	path = pList[0]
  1490  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
  1491  
  1492  	checkPattr(bgpMessage1, path)
  1493  	// check destination
  1494  	expectedPrefix = "2001:123:123:1::/64"
  1495  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1496  	// check nexthop
  1497  	expectedNexthop = "2001::192:168:50:1"
  1498  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1499  
  1500  }
  1501  
  1502  // handle bestpath lost
  1503  func TestProcessBGPUpdate_bestpath_lost_ipv4(t *testing.T) {
  1504  
  1505  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
  1506  
  1507  	// path1
  1508  	origin1 := bgp.NewPathAttributeOrigin(0)
  1509  	aspath1 := createAsPathAttribute([]uint32{65000})
  1510  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
  1511  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1512  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1513  
  1514  	pathAttributes1 := []bgp.PathAttributeInterface{
  1515  		origin1, aspath1, nexthop1, med1, localpref1,
  1516  	}
  1517  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1518  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
  1519  
  1520  	// path 1 withdraw
  1521  	w1 := bgp.NewIPAddrPrefix(24, "10.10.10.0")
  1522  	w := []*bgp.IPAddrPrefix{w1}
  1523  	bgpMessage1_w := bgp.NewBGPUpdateMessage(w, nil, nil)
  1524  
  1525  	peer1 := peerR1()
  1526  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1527  	assert.Equal(t, 1, len(pList))
  1528  	assert.Equal(t, pList[0].IsWithdraw, false)
  1529  	assert.NoError(t, err)
  1530  
  1531  	pList, err = tm.ProcessUpdate(peer1, bgpMessage1_w)
  1532  	assert.Equal(t, 1, len(pList))
  1533  	assert.Equal(t, pList[0].IsWithdraw, true)
  1534  	assert.NoError(t, err)
  1535  
  1536  	// check old best path
  1537  	path := pList[0]
  1538  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
  1539  
  1540  	// check PathAttribute
  1541  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1542  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1543  		expectedOrigin := pathAttributes[0]
  1544  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1545  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1546  		assert.Equal(t, expectedOrigin, pathOrigin)
  1547  
  1548  		expectedAsPath := pathAttributes[1]
  1549  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1550  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1551  		assert.Equal(t, expectedAsPath, pathAspath)
  1552  
  1553  		expectedNexthopAttr := pathAttributes[2]
  1554  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
  1555  		pathNexthop := attr.(*bgp.PathAttributeNextHop)
  1556  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1557  
  1558  		expectedMed := pathAttributes[3]
  1559  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1560  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1561  		assert.Equal(t, expectedMed, pathMed)
  1562  
  1563  		// check PathAttribute length
  1564  		assert.Equal(t, len(pathAttributes), len(path.GetPathAttrs()))
  1565  	}
  1566  
  1567  	checkPattr(bgpMessage1, path)
  1568  	// check destination
  1569  	expectedPrefix := "10.10.10.0/24"
  1570  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1571  }
  1572  
  1573  func TestProcessBGPUpdate_bestpath_lost_ipv6(t *testing.T) {
  1574  
  1575  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
  1576  
  1577  	origin1 := bgp.NewPathAttributeOrigin(0)
  1578  	aspath1 := createAsPathAttribute([]uint32{65000})
  1579  	mp_reach1 := createMpReach("2001::192:168:50:1",
  1580  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1581  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1582  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1583  
  1584  	pathAttributes1 := []bgp.PathAttributeInterface{
  1585  		mp_reach1, origin1, aspath1, med1, localpref1,
  1586  	}
  1587  
  1588  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
  1589  
  1590  	peer1 := peerR1()
  1591  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1592  	assert.Equal(t, 1, len(pList))
  1593  	assert.Equal(t, pList[0].IsWithdraw, false)
  1594  	assert.NoError(t, err)
  1595  
  1596  	// path1 mpunreach
  1597  	mp_unreach := createMpUNReach("2001:123:123:1::", 64)
  1598  	bgpMessage1_w := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{mp_unreach}, nil)
  1599  
  1600  	pList, err = tm.ProcessUpdate(peer1, bgpMessage1_w)
  1601  	assert.Equal(t, 1, len(pList))
  1602  	assert.Equal(t, pList[0].IsWithdraw, true)
  1603  	assert.NoError(t, err)
  1604  
  1605  	// check old best path
  1606  	path := pList[0]
  1607  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
  1608  
  1609  	// check PathAttribute
  1610  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1611  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1612  
  1613  		expectedNexthopAttr := pathAttributes[0]
  1614  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1615  		pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1616  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1617  
  1618  		expectedOrigin := pathAttributes[1]
  1619  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1620  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1621  		assert.Equal(t, expectedOrigin, pathOrigin)
  1622  
  1623  		expectedAsPath := pathAttributes[2]
  1624  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1625  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1626  		assert.Equal(t, expectedAsPath, pathAspath)
  1627  
  1628  		expectedMed := pathAttributes[3]
  1629  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1630  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1631  		assert.Equal(t, expectedMed, pathMed)
  1632  		// check PathAttribute length
  1633  		assert.Equal(t, len(pathAttributes), len(path.GetPathAttrs()))
  1634  	}
  1635  
  1636  	checkPattr(bgpMessage1, path)
  1637  
  1638  	// check destination
  1639  	expectedPrefix := "2001:123:123:1::/64"
  1640  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1641  }
  1642  
  1643  // test: implicit withdrawal case
  1644  func TestProcessBGPUpdate_implicit_withdrwal_ipv4(t *testing.T) {
  1645  
  1646  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
  1647  
  1648  	// path1
  1649  	origin1 := bgp.NewPathAttributeOrigin(0)
  1650  	aspath1 := createAsPathAttribute([]uint32{65000, 65100, 65200})
  1651  	nexthop1 := bgp.NewPathAttributeNextHop("192.168.50.1")
  1652  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1653  	localpref1 := bgp.NewPathAttributeLocalPref(100)
  1654  
  1655  	pathAttributes1 := []bgp.PathAttributeInterface{
  1656  		origin1, aspath1, nexthop1, med1, localpref1,
  1657  	}
  1658  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1659  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
  1660  
  1661  	// path 1 from same peer but short AS_PATH
  1662  	origin2 := bgp.NewPathAttributeOrigin(0)
  1663  	aspath2 := createAsPathAttribute([]uint32{65000, 65100})
  1664  	nexthop2 := bgp.NewPathAttributeNextHop("192.168.50.1")
  1665  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1666  	localpref2 := bgp.NewPathAttributeLocalPref(100)
  1667  
  1668  	pathAttributes2 := []bgp.PathAttributeInterface{
  1669  		origin2, aspath2, nexthop2, med2, localpref2,
  1670  	}
  1671  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  1672  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
  1673  
  1674  	peer1 := peerR1()
  1675  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1676  	assert.Equal(t, 1, len(pList))
  1677  	assert.Equal(t, pList[0].IsWithdraw, false)
  1678  	assert.NoError(t, err)
  1679  
  1680  	pList, err = tm.ProcessUpdate(peer1, bgpMessage2)
  1681  	assert.Equal(t, 1, len(pList))
  1682  	assert.Equal(t, pList[0].IsWithdraw, false)
  1683  	assert.NoError(t, err)
  1684  
  1685  	// check type
  1686  	path := pList[0]
  1687  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv4_UC)
  1688  
  1689  	// check PathAttribute
  1690  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1691  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1692  		expectedOrigin := pathAttributes[0]
  1693  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1694  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1695  		assert.Equal(t, expectedOrigin, pathOrigin)
  1696  
  1697  		expectedAsPath := pathAttributes[1]
  1698  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1699  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1700  		assert.Equal(t, expectedAsPath, pathAspath)
  1701  
  1702  		expectedNexthopAttr := pathAttributes[2]
  1703  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
  1704  		pathNexthop := attr.(*bgp.PathAttributeNextHop)
  1705  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1706  
  1707  		expectedMed := pathAttributes[3]
  1708  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1709  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1710  		assert.Equal(t, expectedMed, pathMed)
  1711  
  1712  		// check PathAttribute length
  1713  		assert.Equal(t, len(pathAttributes), len(path.GetPathAttrs()))
  1714  	}
  1715  	checkPattr(bgpMessage2, path)
  1716  	// check destination
  1717  	expectedPrefix := "10.10.10.0/24"
  1718  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1719  	// check nexthop
  1720  	expectedNexthop := "192.168.50.1"
  1721  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1722  
  1723  }
  1724  
  1725  func TestProcessBGPUpdate_implicit_withdrwal_ipv6(t *testing.T) {
  1726  
  1727  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
  1728  
  1729  	origin1 := bgp.NewPathAttributeOrigin(0)
  1730  	aspath1 := createAsPathAttribute([]uint32{65000, 65100, 65200})
  1731  	mp_reach1 := createMpReach("2001::192:168:50:1",
  1732  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1733  	med1 := bgp.NewPathAttributeMultiExitDisc(200)
  1734  	localpref1 := bgp.NewPathAttributeLocalPref(200)
  1735  
  1736  	pathAttributes1 := []bgp.PathAttributeInterface{
  1737  		mp_reach1, origin1, aspath1, med1, localpref1,
  1738  	}
  1739  
  1740  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
  1741  
  1742  	origin2 := bgp.NewPathAttributeOrigin(0)
  1743  	aspath2 := createAsPathAttribute([]uint32{65000, 65100})
  1744  	mp_reach2 := createMpReach("2001::192:168:50:1",
  1745  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")})
  1746  	med2 := bgp.NewPathAttributeMultiExitDisc(200)
  1747  	localpref2 := bgp.NewPathAttributeLocalPref(200)
  1748  
  1749  	pathAttributes2 := []bgp.PathAttributeInterface{
  1750  		mp_reach2, origin2, aspath2, med2, localpref2,
  1751  	}
  1752  
  1753  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
  1754  
  1755  	peer1 := peerR1()
  1756  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1757  	assert.Equal(t, 1, len(pList))
  1758  	assert.Equal(t, pList[0].IsWithdraw, false)
  1759  	assert.NoError(t, err)
  1760  
  1761  	pList, err = tm.ProcessUpdate(peer1, bgpMessage2)
  1762  	assert.Equal(t, 1, len(pList))
  1763  	assert.Equal(t, pList[0].IsWithdraw, false)
  1764  	assert.NoError(t, err)
  1765  
  1766  	// check type
  1767  	path := pList[0]
  1768  	assert.Equal(t, path.GetRouteFamily(), bgp.RF_IPv6_UC)
  1769  
  1770  	// check PathAttribute
  1771  	pathAttributes := bgpMessage2.Body.(*bgp.BGPUpdate).PathAttributes
  1772  
  1773  	expectedNexthopAttr := pathAttributes[0]
  1774  	attr := path.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1775  	pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1776  	assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1777  
  1778  	expectedOrigin := pathAttributes[1]
  1779  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1780  	pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1781  	assert.Equal(t, expectedOrigin, pathOrigin)
  1782  
  1783  	expectedAsPath := pathAttributes[2]
  1784  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1785  	pathAspath := attr.(*bgp.PathAttributeAsPath)
  1786  	assert.Equal(t, expectedAsPath, pathAspath)
  1787  
  1788  	expectedMed := pathAttributes[3]
  1789  	attr = path.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1790  	pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1791  	assert.Equal(t, expectedMed, pathMed)
  1792  
  1793  	// check PathAttribute
  1794  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1795  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1796  
  1797  		expectedNexthopAttr := pathAttributes[0]
  1798  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1799  		pathNexthop := attr.(*bgp.PathAttributeMpReachNLRI)
  1800  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1801  
  1802  		expectedOrigin := pathAttributes[1]
  1803  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1804  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1805  		assert.Equal(t, expectedOrigin, pathOrigin)
  1806  
  1807  		expectedAsPath := pathAttributes[2]
  1808  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1809  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1810  		assert.Equal(t, expectedAsPath, pathAspath)
  1811  
  1812  		expectedMed := pathAttributes[3]
  1813  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1814  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1815  		assert.Equal(t, expectedMed, pathMed)
  1816  		// check PathAttribute length
  1817  		assert.Equal(t, len(pathAttributes), len(path.GetPathAttrs()))
  1818  	}
  1819  
  1820  	checkPattr(bgpMessage2, path)
  1821  
  1822  	// check destination
  1823  	expectedPrefix := "2001:123:123:1::/64"
  1824  	assert.Equal(t, expectedPrefix, path.GetPrefix())
  1825  	// check nexthop
  1826  	expectedNexthop := "2001::192:168:50:1"
  1827  	assert.Equal(t, expectedNexthop, path.GetNexthop().String())
  1828  
  1829  }
  1830  
  1831  // check multiple paths
  1832  func TestProcessBGPUpdate_multiple_nlri_ipv4(t *testing.T) {
  1833  
  1834  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC})
  1835  
  1836  	createPathAttr := func(aspaths []uint32, nh string) []bgp.PathAttributeInterface {
  1837  		origin := bgp.NewPathAttributeOrigin(0)
  1838  		aspath := createAsPathAttribute(aspaths)
  1839  		nexthop := bgp.NewPathAttributeNextHop(nh)
  1840  		med := bgp.NewPathAttributeMultiExitDisc(200)
  1841  		localpref := bgp.NewPathAttributeLocalPref(100)
  1842  		pathAttr := []bgp.PathAttributeInterface{
  1843  			origin, aspath, nexthop, med, localpref,
  1844  		}
  1845  		return pathAttr
  1846  	}
  1847  
  1848  	// check PathAttribute
  1849  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1850  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1851  		expectedOrigin := pathAttributes[0]
  1852  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1853  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1854  		assert.Equal(t, expectedOrigin, pathOrigin)
  1855  
  1856  		expectedAsPath := pathAttributes[1]
  1857  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1858  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1859  		assert.Equal(t, expectedAsPath, pathAspath)
  1860  
  1861  		expectedNexthopAttr := pathAttributes[2]
  1862  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_NEXT_HOP)
  1863  		pathNexthop := attr.(*bgp.PathAttributeNextHop)
  1864  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1865  
  1866  		expectedMed := pathAttributes[3]
  1867  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  1868  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  1869  		assert.Equal(t, expectedMed, pathMed)
  1870  
  1871  		// check PathAttribute length
  1872  		assert.Equal(t, len(pathAttributes), len(actual.GetPathAttrs()))
  1873  	}
  1874  
  1875  	checkBestPathResult := func(rf bgp.RouteFamily, prefix, nexthop string, p *Path, m *bgp.BGPMessage) {
  1876  		assert.Equal(t, p.GetRouteFamily(), rf)
  1877  		checkPattr(m, p)
  1878  		// check destination
  1879  		assert.Equal(t, prefix, p.GetPrefix())
  1880  		// check nexthop
  1881  		assert.Equal(t, nexthop, p.GetNexthop().String())
  1882  	}
  1883  
  1884  	// path1
  1885  	pathAttributes1 := createPathAttr([]uint32{65000, 65100, 65200}, "192.168.50.1")
  1886  	nlri1 := []*bgp.IPAddrPrefix{
  1887  		bgp.NewIPAddrPrefix(24, "10.10.10.0"),
  1888  		bgp.NewIPAddrPrefix(24, "20.20.20.0"),
  1889  		bgp.NewIPAddrPrefix(24, "30.30.30.0"),
  1890  		bgp.NewIPAddrPrefix(24, "40.40.40.0"),
  1891  		bgp.NewIPAddrPrefix(24, "50.50.50.0")}
  1892  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nlri1)
  1893  
  1894  	// path2
  1895  	pathAttributes2 := createPathAttr([]uint32{65000, 65100, 65300}, "192.168.50.1")
  1896  	nlri2 := []*bgp.IPAddrPrefix{
  1897  		bgp.NewIPAddrPrefix(24, "11.11.11.0"),
  1898  		bgp.NewIPAddrPrefix(24, "22.22.22.0"),
  1899  		bgp.NewIPAddrPrefix(24, "33.33.33.0"),
  1900  		bgp.NewIPAddrPrefix(24, "44.44.44.0"),
  1901  		bgp.NewIPAddrPrefix(24, "55.55.55.0")}
  1902  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri2)
  1903  
  1904  	// path3
  1905  	pathAttributes3 := createPathAttr([]uint32{65000, 65100, 65400}, "192.168.50.1")
  1906  	nlri3 := []*bgp.IPAddrPrefix{
  1907  		bgp.NewIPAddrPrefix(24, "77.77.77.0"),
  1908  		bgp.NewIPAddrPrefix(24, "88.88.88.0"),
  1909  	}
  1910  	bgpMessage3 := bgp.NewBGPUpdateMessage(nil, pathAttributes3, nlri3)
  1911  
  1912  	// path4
  1913  	pathAttributes4 := createPathAttr([]uint32{65000, 65100, 65500}, "192.168.50.1")
  1914  	nlri4 := []*bgp.IPAddrPrefix{
  1915  		bgp.NewIPAddrPrefix(24, "99.99.99.0"),
  1916  	}
  1917  	bgpMessage4 := bgp.NewBGPUpdateMessage(nil, pathAttributes4, nlri4)
  1918  
  1919  	peer1 := peerR1()
  1920  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  1921  	assert.Equal(t, 5, len(pList))
  1922  	for _, p := range pList {
  1923  		assert.Equal(t, p.IsWithdraw, false)
  1924  	}
  1925  	assert.NoError(t, err)
  1926  
  1927  	checkBestPathResult(bgp.RF_IPv4_UC, "10.10.10.0/24", "192.168.50.1", pList[0], bgpMessage1)
  1928  	checkBestPathResult(bgp.RF_IPv4_UC, "20.20.20.0/24", "192.168.50.1", pList[1], bgpMessage1)
  1929  	checkBestPathResult(bgp.RF_IPv4_UC, "30.30.30.0/24", "192.168.50.1", pList[2], bgpMessage1)
  1930  	checkBestPathResult(bgp.RF_IPv4_UC, "40.40.40.0/24", "192.168.50.1", pList[3], bgpMessage1)
  1931  	checkBestPathResult(bgp.RF_IPv4_UC, "50.50.50.0/24", "192.168.50.1", pList[4], bgpMessage1)
  1932  
  1933  	pList, err = tm.ProcessUpdate(peer1, bgpMessage2)
  1934  	assert.Equal(t, 5, len(pList))
  1935  	for _, p := range pList {
  1936  		assert.Equal(t, p.IsWithdraw, false)
  1937  	}
  1938  	assert.NoError(t, err)
  1939  
  1940  	checkBestPathResult(bgp.RF_IPv4_UC, "11.11.11.0/24", "192.168.50.1", pList[0], bgpMessage2)
  1941  	checkBestPathResult(bgp.RF_IPv4_UC, "22.22.22.0/24", "192.168.50.1", pList[1], bgpMessage2)
  1942  	checkBestPathResult(bgp.RF_IPv4_UC, "33.33.33.0/24", "192.168.50.1", pList[2], bgpMessage2)
  1943  	checkBestPathResult(bgp.RF_IPv4_UC, "44.44.44.0/24", "192.168.50.1", pList[3], bgpMessage2)
  1944  	checkBestPathResult(bgp.RF_IPv4_UC, "55.55.55.0/24", "192.168.50.1", pList[4], bgpMessage2)
  1945  
  1946  	pList, err = tm.ProcessUpdate(peer1, bgpMessage3)
  1947  	assert.Equal(t, 2, len(pList))
  1948  	for _, p := range pList {
  1949  		assert.Equal(t, p.IsWithdraw, false)
  1950  	}
  1951  	assert.NoError(t, err)
  1952  
  1953  	pList, err = tm.ProcessUpdate(peer1, bgpMessage4)
  1954  	assert.Equal(t, 1, len(pList))
  1955  	assert.Equal(t, pList[0].IsWithdraw, false)
  1956  	assert.NoError(t, err)
  1957  
  1958  	// check table
  1959  	table := tm.Tables[bgp.RF_IPv4_UC]
  1960  	assert.Equal(t, 13, len(table.GetDestinations()))
  1961  
  1962  }
  1963  
  1964  // check multiple paths
  1965  func TestProcessBGPUpdate_multiple_nlri_ipv6(t *testing.T) {
  1966  
  1967  	tm := NewTableManager(logger, []bgp.RouteFamily{bgp.RF_IPv6_UC})
  1968  
  1969  	createPathAttr := func(aspaths []uint32) []bgp.PathAttributeInterface {
  1970  		origin := bgp.NewPathAttributeOrigin(0)
  1971  		aspath := createAsPathAttribute(aspaths)
  1972  		med := bgp.NewPathAttributeMultiExitDisc(100)
  1973  		localpref := bgp.NewPathAttributeLocalPref(100)
  1974  		pathAttr := []bgp.PathAttributeInterface{
  1975  			origin, aspath, med, localpref,
  1976  		}
  1977  		return pathAttr
  1978  	}
  1979  
  1980  	// check PathAttribute
  1981  	checkPattr := func(expected *bgp.BGPMessage, actual *Path) {
  1982  		pathAttributes := expected.Body.(*bgp.BGPUpdate).PathAttributes
  1983  		pathNexthop := pathAttributes[4]
  1984  		attr := actual.getPathAttr(bgp.BGP_ATTR_TYPE_MP_REACH_NLRI)
  1985  		expectedNexthopAttr := attr.(*bgp.PathAttributeMpReachNLRI)
  1986  		assert.Equal(t, expectedNexthopAttr, pathNexthop)
  1987  
  1988  		expectedOrigin := pathAttributes[0]
  1989  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_ORIGIN)
  1990  		pathOrigin := attr.(*bgp.PathAttributeOrigin)
  1991  		assert.Equal(t, expectedOrigin, pathOrigin)
  1992  
  1993  		expectedAsPath := pathAttributes[1]
  1994  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_AS_PATH)
  1995  		pathAspath := attr.(*bgp.PathAttributeAsPath)
  1996  		assert.Equal(t, expectedAsPath, pathAspath)
  1997  
  1998  		expectedMed := pathAttributes[2]
  1999  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_MULTI_EXIT_DISC)
  2000  		pathMed := attr.(*bgp.PathAttributeMultiExitDisc)
  2001  		assert.Equal(t, expectedMed, pathMed)
  2002  
  2003  		expectedLocalpref := pathAttributes[3]
  2004  		attr = actual.getPathAttr(bgp.BGP_ATTR_TYPE_LOCAL_PREF)
  2005  		localpref := attr.(*bgp.PathAttributeLocalPref)
  2006  		assert.Equal(t, expectedLocalpref, localpref)
  2007  
  2008  		// check PathAttribute length
  2009  		assert.Equal(t, len(pathAttributes), len(actual.GetPathAttrs()))
  2010  
  2011  	}
  2012  
  2013  	checkBestPathResult := func(rf bgp.RouteFamily, prefix, nexthop string, p *Path, m *bgp.BGPMessage) {
  2014  		assert.Equal(t, p.GetRouteFamily(), rf)
  2015  		checkPattr(m, p)
  2016  		// check destination
  2017  		assert.Equal(t, prefix, p.GetPrefix())
  2018  		// check nexthop
  2019  		assert.Equal(t, nexthop, p.GetNexthop().String())
  2020  	}
  2021  
  2022  	// path1
  2023  	pathAttributes1 := createPathAttr([]uint32{65000, 65100, 65200})
  2024  	mpreach1 := createMpReach("2001::192:168:50:1", []bgp.AddrPrefixInterface{
  2025  		bgp.NewIPv6AddrPrefix(64, "2001:123:1210:11::"),
  2026  		bgp.NewIPv6AddrPrefix(64, "2001:123:1220:11::"),
  2027  		bgp.NewIPv6AddrPrefix(64, "2001:123:1230:11::"),
  2028  		bgp.NewIPv6AddrPrefix(64, "2001:123:1240:11::"),
  2029  		bgp.NewIPv6AddrPrefix(64, "2001:123:1250:11::"),
  2030  	})
  2031  	pathAttributes1 = append(pathAttributes1, mpreach1)
  2032  	bgpMessage1 := bgp.NewBGPUpdateMessage(nil, pathAttributes1, nil)
  2033  
  2034  	// path2
  2035  	pathAttributes2 := createPathAttr([]uint32{65000, 65100, 65300})
  2036  	mpreach2 := createMpReach("2001::192:168:50:1", []bgp.AddrPrefixInterface{
  2037  		bgp.NewIPv6AddrPrefix(64, "2001:123:1211:11::"),
  2038  		bgp.NewIPv6AddrPrefix(64, "2001:123:1222:11::"),
  2039  		bgp.NewIPv6AddrPrefix(64, "2001:123:1233:11::"),
  2040  		bgp.NewIPv6AddrPrefix(64, "2001:123:1244:11::"),
  2041  		bgp.NewIPv6AddrPrefix(64, "2001:123:1255:11::"),
  2042  	})
  2043  	pathAttributes2 = append(pathAttributes2, mpreach2)
  2044  	bgpMessage2 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nil)
  2045  
  2046  	// path3
  2047  	pathAttributes3 := createPathAttr([]uint32{65000, 65100, 65400})
  2048  	mpreach3 := createMpReach("2001::192:168:50:1", []bgp.AddrPrefixInterface{
  2049  		bgp.NewIPv6AddrPrefix(64, "2001:123:1277:11::"),
  2050  		bgp.NewIPv6AddrPrefix(64, "2001:123:1288:11::"),
  2051  	})
  2052  	pathAttributes3 = append(pathAttributes3, mpreach3)
  2053  	bgpMessage3 := bgp.NewBGPUpdateMessage(nil, pathAttributes3, nil)
  2054  
  2055  	// path4
  2056  	pathAttributes4 := createPathAttr([]uint32{65000, 65100, 65500})
  2057  	mpreach4 := createMpReach("2001::192:168:50:1", []bgp.AddrPrefixInterface{
  2058  		bgp.NewIPv6AddrPrefix(64, "2001:123:1299:11::"),
  2059  	})
  2060  	pathAttributes4 = append(pathAttributes4, mpreach4)
  2061  	bgpMessage4 := bgp.NewBGPUpdateMessage(nil, pathAttributes4, nil)
  2062  
  2063  	peer1 := peerR1()
  2064  	pList, err := tm.ProcessUpdate(peer1, bgpMessage1)
  2065  	assert.Equal(t, 5, len(pList))
  2066  	for _, p := range pList {
  2067  		assert.Equal(t, p.IsWithdraw, false)
  2068  	}
  2069  	assert.NoError(t, err)
  2070  
  2071  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1210:11::/64", "2001::192:168:50:1", pList[0], bgpMessage1)
  2072  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1220:11::/64", "2001::192:168:50:1", pList[1], bgpMessage1)
  2073  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1230:11::/64", "2001::192:168:50:1", pList[2], bgpMessage1)
  2074  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1240:11::/64", "2001::192:168:50:1", pList[3], bgpMessage1)
  2075  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1250:11::/64", "2001::192:168:50:1", pList[4], bgpMessage1)
  2076  
  2077  	pList, err = tm.ProcessUpdate(peer1, bgpMessage2)
  2078  	assert.Equal(t, 5, len(pList))
  2079  	for _, p := range pList {
  2080  		assert.Equal(t, p.IsWithdraw, false)
  2081  	}
  2082  	assert.NoError(t, err)
  2083  
  2084  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1211:11::/64", "2001::192:168:50:1", pList[0], bgpMessage2)
  2085  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1222:11::/64", "2001::192:168:50:1", pList[1], bgpMessage2)
  2086  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1233:11::/64", "2001::192:168:50:1", pList[2], bgpMessage2)
  2087  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1244:11::/64", "2001::192:168:50:1", pList[3], bgpMessage2)
  2088  	checkBestPathResult(bgp.RF_IPv6_UC, "2001:123:1255:11::/64", "2001::192:168:50:1", pList[4], bgpMessage2)
  2089  
  2090  	pList, err = tm.ProcessUpdate(peer1, bgpMessage3)
  2091  	assert.Equal(t, 2, len(pList))
  2092  	for _, p := range pList {
  2093  		assert.Equal(t, p.IsWithdraw, false)
  2094  	}
  2095  	assert.NoError(t, err)
  2096  
  2097  	pList, err = tm.ProcessUpdate(peer1, bgpMessage4)
  2098  	assert.Equal(t, 1, len(pList))
  2099  	assert.Equal(t, pList[0].IsWithdraw, false)
  2100  	assert.NoError(t, err)
  2101  
  2102  	// check table
  2103  	table := tm.Tables[bgp.RF_IPv6_UC]
  2104  	assert.Equal(t, 13, len(table.GetDestinations()))
  2105  
  2106  }
  2107  
  2108  func TestProcessBGPUpdate_Timestamp(t *testing.T) {
  2109  	origin := bgp.NewPathAttributeOrigin(0)
  2110  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000})}
  2111  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2112  	nexthop := bgp.NewPathAttributeNextHop("192.168.50.1")
  2113  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2114  
  2115  	pathAttributes := []bgp.PathAttributeInterface{
  2116  		origin,
  2117  		aspath,
  2118  		nexthop,
  2119  		med,
  2120  	}
  2121  
  2122  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  2123  
  2124  	adjRib := NewAdjRib(logger, []bgp.RouteFamily{bgp.RF_IPv4_UC, bgp.RF_IPv6_UC})
  2125  	m1 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2126  	peer := peerR1()
  2127  	pList1 := ProcessMessage(m1, peer, time.Now())
  2128  	path1 := pList1[0]
  2129  	t1 := path1.GetTimestamp()
  2130  	adjRib.Update(pList1)
  2131  
  2132  	m2 := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2133  	pList2 := ProcessMessage(m2, peer, time.Now())
  2134  	//path2 := pList2[0].(*IPv4Path)
  2135  	//t2 = path2.timestamp
  2136  	adjRib.Update(pList2)
  2137  
  2138  	inList := adjRib.PathList([]bgp.RouteFamily{bgp.RF_IPv4_UC}, false)
  2139  	assert.Equal(t, len(inList), 1)
  2140  	assert.Equal(t, inList[0].GetTimestamp(), t1)
  2141  
  2142  	med2 := bgp.NewPathAttributeMultiExitDisc(1)
  2143  	pathAttributes2 := []bgp.PathAttributeInterface{
  2144  		origin,
  2145  		aspath,
  2146  		nexthop,
  2147  		med2,
  2148  	}
  2149  
  2150  	m3 := bgp.NewBGPUpdateMessage(nil, pathAttributes2, nlri)
  2151  	pList3 := ProcessMessage(m3, peer, time.Now())
  2152  	t3 := pList3[0].GetTimestamp()
  2153  	adjRib.Update(pList3)
  2154  
  2155  	inList = adjRib.PathList([]bgp.RouteFamily{bgp.RF_IPv4_UC}, false)
  2156  	assert.Equal(t, len(inList), 1)
  2157  	assert.Equal(t, inList[0].GetTimestamp(), t3)
  2158  }
  2159  
  2160  func update_fromR1() *bgp.BGPMessage {
  2161  
  2162  	origin := bgp.NewPathAttributeOrigin(0)
  2163  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000})}
  2164  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2165  	nexthop := bgp.NewPathAttributeNextHop("192.168.50.1")
  2166  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2167  
  2168  	pathAttributes := []bgp.PathAttributeInterface{
  2169  		origin,
  2170  		aspath,
  2171  		nexthop,
  2172  		med,
  2173  	}
  2174  
  2175  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")}
  2176  
  2177  	return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2178  }
  2179  
  2180  func update_fromR1_ipv6() *bgp.BGPMessage {
  2181  
  2182  	origin := bgp.NewPathAttributeOrigin(0)
  2183  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000})}
  2184  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2185  
  2186  	mp_nlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2001:123:123:1::")}
  2187  	mp_reach := bgp.NewPathAttributeMpReachNLRI("2001::192:168:50:1", mp_nlri)
  2188  	med := bgp.NewPathAttributeMultiExitDisc(0)
  2189  
  2190  	pathAttributes := []bgp.PathAttributeInterface{
  2191  		mp_reach,
  2192  		origin,
  2193  		aspath,
  2194  		med,
  2195  	}
  2196  	return bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
  2197  }
  2198  
  2199  func update_fromR2() *bgp.BGPMessage {
  2200  
  2201  	origin := bgp.NewPathAttributeOrigin(0)
  2202  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65100})}
  2203  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2204  	nexthop := bgp.NewPathAttributeNextHop("192.168.100.1")
  2205  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2206  
  2207  	pathAttributes := []bgp.PathAttributeInterface{
  2208  		origin,
  2209  		aspath,
  2210  		nexthop,
  2211  		med,
  2212  	}
  2213  
  2214  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "20.20.20.0")}
  2215  	return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2216  }
  2217  
  2218  func update_fromR2_ipv6() *bgp.BGPMessage {
  2219  
  2220  	origin := bgp.NewPathAttributeOrigin(0)
  2221  	aspath := createAsPathAttribute([]uint32{65100})
  2222  	mp_reach := createMpReach("2001::192:168:100:1",
  2223  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2002:223:123:1::")})
  2224  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2225  
  2226  	pathAttributes := []bgp.PathAttributeInterface{
  2227  		mp_reach,
  2228  		origin,
  2229  		aspath,
  2230  		med,
  2231  	}
  2232  	return bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
  2233  }
  2234  
  2235  func createAsPathAttribute(ases []uint32) *bgp.PathAttributeAsPath {
  2236  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, ases)}
  2237  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2238  	return aspath
  2239  }
  2240  
  2241  func createMpReach(nexthop string, prefix []bgp.AddrPrefixInterface) *bgp.PathAttributeMpReachNLRI {
  2242  	mp_reach := bgp.NewPathAttributeMpReachNLRI(nexthop, prefix)
  2243  	return mp_reach
  2244  }
  2245  
  2246  func createMpUNReach(nlri string, len uint8) *bgp.PathAttributeMpUnreachNLRI {
  2247  	mp_nlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(len, nlri)}
  2248  	mp_unreach := bgp.NewPathAttributeMpUnreachNLRI(mp_nlri)
  2249  	return mp_unreach
  2250  }
  2251  
  2252  func update_fromR2viaR1() *bgp.BGPMessage {
  2253  
  2254  	origin := bgp.NewPathAttributeOrigin(0)
  2255  	aspathParam := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(2, []uint32{65000, 65100})}
  2256  	aspath := bgp.NewPathAttributeAsPath(aspathParam)
  2257  	nexthop := bgp.NewPathAttributeNextHop("192.168.50.1")
  2258  
  2259  	pathAttributes := []bgp.PathAttributeInterface{
  2260  		origin,
  2261  		aspath,
  2262  		nexthop,
  2263  	}
  2264  
  2265  	nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "20.20.20.0")}
  2266  	return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri)
  2267  }
  2268  
  2269  func update_fromR2viaR1_ipv6() *bgp.BGPMessage {
  2270  
  2271  	origin := bgp.NewPathAttributeOrigin(0)
  2272  	aspath := createAsPathAttribute([]uint32{65000, 65100})
  2273  	mp_reach := createMpReach("2001::192:168:50:1",
  2274  		[]bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(64, "2002:223:123:1::")})
  2275  	med := bgp.NewPathAttributeMultiExitDisc(100)
  2276  
  2277  	pathAttributes := []bgp.PathAttributeInterface{
  2278  		mp_reach,
  2279  		origin,
  2280  		aspath,
  2281  		med,
  2282  	}
  2283  	return bgp.NewBGPUpdateMessage(nil, pathAttributes, nil)
  2284  
  2285  }