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