github.com/osrg/gobgp@v2.0.0+incompatible/internal/pkg/table/message_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  	"reflect"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/osrg/gobgp/pkg/packet/bgp"
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  // before:
    29  //  as-path  : 65000, 4000, 400000, 300000, 40001
    30  // expected result:
    31  //  as-path  : 65000, 4000, 23456, 23456, 40001
    32  //  as4-path : 65000, 4000, 400000, 300000, 40001
    33  func TestAsPathAs2Trans1(t *testing.T) {
    34  	as := []uint32{65000, 4000, 400000, 300000, 40001}
    35  	params := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
    36  	aspath := bgp.NewPathAttributeAsPath(params)
    37  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath}, nil).Body.(*bgp.BGPUpdate)
    38  	UpdatePathAttrs2ByteAs(msg)
    39  	assert.Equal(t, len(msg.PathAttributes), 2)
    40  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
    41  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS), 5)
    42  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[0], uint16(65000))
    43  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[1], uint16(4000))
    44  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[2], uint16(bgp.AS_TRANS))
    45  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[3], uint16(bgp.AS_TRANS))
    46  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[4], uint16(40001))
    47  	assert.Equal(t, len(msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value), 1)
    48  	assert.Equal(t, len(msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS), 5)
    49  	assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[0], uint32(65000))
    50  	assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[1], uint32(4000))
    51  	assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[2], uint32(400000))
    52  	assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[3], uint32(300000))
    53  	assert.Equal(t, msg.PathAttributes[1].(*bgp.PathAttributeAs4Path).Value[0].AS[4], uint32(40001))
    54  }
    55  
    56  // before:
    57  //  as-path  : 65000, 4000, 40000, 30000, 40001
    58  // expected result:
    59  //  as-path  : 65000, 4000, 40000, 30000, 40001
    60  func TestAsPathAs2Trans2(t *testing.T) {
    61  	as := []uint32{65000, 4000, 40000, 30000, 40001}
    62  	params := []bgp.AsPathParamInterface{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
    63  	aspath := bgp.NewPathAttributeAsPath(params)
    64  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath}, nil).Body.(*bgp.BGPUpdate)
    65  	UpdatePathAttrs2ByteAs(msg)
    66  	assert.Equal(t, len(msg.PathAttributes), 1)
    67  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
    68  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS), 5)
    69  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[0], uint16(65000))
    70  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[1], uint16(4000))
    71  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[2], uint16(40000))
    72  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[3], uint16(30000))
    73  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.AsPathParam).AS[4], uint16(40001))
    74  }
    75  
    76  // before:
    77  //  as-path  : 65000, 4000, 23456, 23456, 40001
    78  //  as4-path : 400000, 300000, 40001
    79  // expected result:
    80  //  as-path  : 65000, 4000, 400000, 300000, 40001
    81  func TestAsPathAs4Trans1(t *testing.T) {
    82  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
    83  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
    84  	aspath := bgp.NewPathAttributeAsPath(params)
    85  
    86  	as4 := []uint32{400000, 300000, 40001}
    87  	param4s := []*bgp.As4PathParam{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)}
    88  	as4path := bgp.NewPathAttributeAs4Path(param4s)
    89  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
    90  	UpdatePathAttrs4ByteAs(msg)
    91  	assert.Equal(t, len(msg.PathAttributes), 1)
    92  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
    93  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5)
    94  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
    95  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
    96  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(400000))
    97  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(300000))
    98  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001))
    99  }
   100  
   101  // before:
   102  //  as-path  : 65000, 4000, {10, 20, 30}, 23456, 23456, 40001
   103  //  as4-path : 400000, 300000, 40001
   104  // expected result:
   105  //  as-path  : 65000, 4000, {10, 20, 30}, 400000, 300000, 40001
   106  func TestAsPathAs4Trans2(t *testing.T) {
   107  	as1 := []uint16{65000, 4000}
   108  	param1 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as1)
   109  	as2 := []uint16{10, 20, 30}
   110  	param2 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as2)
   111  	as3 := []uint16{bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   112  	param3 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as3)
   113  	params := []bgp.AsPathParamInterface{param1, param2, param3}
   114  	aspath := bgp.NewPathAttributeAsPath(params)
   115  
   116  	as4 := []uint32{400000, 300000, 40001}
   117  	param4s := []*bgp.As4PathParam{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)}
   118  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   119  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   120  	UpdatePathAttrs4ByteAs(msg)
   121  	assert.Equal(t, len(msg.PathAttributes), 1)
   122  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 3)
   123  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 2)
   124  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   125  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
   126  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS), 3)
   127  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[0], uint32(10))
   128  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[1], uint32(20))
   129  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[2], uint32(30))
   130  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS), 3)
   131  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[0], uint32(400000))
   132  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[1], uint32(300000))
   133  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[2], uint32(40001))
   134  }
   135  
   136  // before:
   137  //  as-path  : 65000, 4000, {10, 20, 30}, 23456, 23456, 40001
   138  //  as4-path : 3000, 400000, 300000, 40001
   139  // expected result:
   140  //  as-path  : 65000, 4000, 3000, 400000, 300000, 40001
   141  func TestAsPathAs4Trans3(t *testing.T) {
   142  	as1 := []uint16{65000, 4000}
   143  	param1 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as1)
   144  	as2 := []uint16{10, 20, 30}
   145  	param2 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as2)
   146  	as3 := []uint16{bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   147  	param3 := bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as3)
   148  	params := []bgp.AsPathParamInterface{param1, param2, param3}
   149  	aspath := bgp.NewPathAttributeAsPath(params)
   150  
   151  	as4 := []uint32{3000, 400000, 300000, 40001}
   152  	param4s := []*bgp.As4PathParam{bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)}
   153  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   154  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   155  	UpdatePathAttrs4ByteAs(msg)
   156  	assert.Equal(t, len(msg.PathAttributes), 1)
   157  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
   158  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 6)
   159  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   160  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
   161  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(3000))
   162  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(400000))
   163  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(300000))
   164  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[5], uint32(40001))
   165  }
   166  
   167  // before:
   168  //  as-path  : 65000, 4000, 23456, 23456, 40001
   169  //  as4-path : 400000, 300000, 40001, {10, 20, 30}
   170  // expected result:
   171  //  as-path  : 65000, 400000, 300000, 40001, {10, 20, 30}
   172  func TestAsPathAs4Trans4(t *testing.T) {
   173  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   174  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
   175  	aspath := bgp.NewPathAttributeAsPath(params)
   176  
   177  	as4 := []uint32{400000, 300000, 40001}
   178  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)
   179  	as5 := []uint32{10, 20, 30}
   180  	as4param2 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as5)
   181  	param4s := []*bgp.As4PathParam{as4param1, as4param2}
   182  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   183  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   184  	UpdatePathAttrs4ByteAs(msg)
   185  	assert.Equal(t, len(msg.PathAttributes), 1)
   186  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 2)
   187  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 4)
   188  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   189  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(400000))
   190  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(300000))
   191  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(40001))
   192  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS), 3)
   193  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[0], uint32(10))
   194  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[1], uint32(20))
   195  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[2], uint32(30))
   196  }
   197  
   198  // before:
   199  //  as-path  : 65000, 4000, 23456, 23456, 40001
   200  //  as4-path : {10, 20, 30} 400000, 300000, 40001
   201  // expected result:
   202  //  as-path  : 65000, {10, 20, 30}, 400000, 300000, 40001
   203  func TestAsPathAs4Trans5(t *testing.T) {
   204  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   205  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
   206  	aspath := bgp.NewPathAttributeAsPath(params)
   207  
   208  	as4 := []uint32{400000, 300000, 40001}
   209  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)
   210  	as5 := []uint32{10, 20, 30}
   211  	as4param2 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SET, as5)
   212  	param4s := []*bgp.As4PathParam{as4param2, as4param1}
   213  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   214  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   215  	UpdatePathAttrs4ByteAs(msg)
   216  	assert.Equal(t, len(msg.PathAttributes), 1)
   217  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 3)
   218  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 1)
   219  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   220  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS), 3)
   221  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[0], uint32(10))
   222  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[1], uint32(20))
   223  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[1].(*bgp.As4PathParam).AS[2], uint32(30))
   224  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS), 3)
   225  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[0], uint32(400000))
   226  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[1], uint32(300000))
   227  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[2].(*bgp.As4PathParam).AS[2], uint32(40001))
   228  }
   229  
   230  // before:
   231  //  as-path  : 65000, 4000, 23456, 23456, 40001
   232  //  as4-path : 100000, 65000, 4000, 400000, 300000, 40001
   233  // expected result:
   234  //  as-path  : 65000, 4000, 23456, 23456, 40001
   235  func TestAsPathAs4TransInvalid1(t *testing.T) {
   236  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   237  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
   238  	aspath := bgp.NewPathAttributeAsPath(params)
   239  
   240  	as4 := []uint32{100000, 65000, 4000, 400000, 300000, 40001}
   241  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)
   242  	param4s := []*bgp.As4PathParam{as4param1}
   243  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   244  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   245  	UpdatePathAttrs4ByteAs(msg)
   246  	assert.Equal(t, len(msg.PathAttributes), 1)
   247  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
   248  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5)
   249  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   250  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
   251  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS))
   252  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(bgp.AS_TRANS))
   253  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001))
   254  }
   255  
   256  // before:
   257  //  as-path  : 65000, 4000, 23456, 23456, 40001
   258  //  as4-path : 300000, 40001
   259  // expected result:
   260  //  as-path  : 65000, 4000, 23456, 300000, 40001
   261  func TestAsPathAs4TransInvalid2(t *testing.T) {
   262  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   263  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
   264  	aspath := bgp.NewPathAttributeAsPath(params)
   265  
   266  	as4 := []uint32{300000, 40001}
   267  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)
   268  	param4s := []*bgp.As4PathParam{as4param1}
   269  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   270  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   271  	UpdatePathAttrs4ByteAs(msg)
   272  	assert.Equal(t, len(msg.PathAttributes), 1)
   273  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
   274  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5)
   275  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   276  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
   277  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS))
   278  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(300000))
   279  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001))
   280  }
   281  
   282  // before:
   283  //  as-path  : 65000, 4000, 23456, 23456, 40001
   284  //  as4-path : nil
   285  // expected result:
   286  //  as-path  : 65000, 4000, 23456, 23456, 40001
   287  func TestAsPathAs4TransInvalid3(t *testing.T) {
   288  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   289  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
   290  	aspath := bgp.NewPathAttributeAsPath(params)
   291  
   292  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath}, nil).Body.(*bgp.BGPUpdate)
   293  	UpdatePathAttrs4ByteAs(msg)
   294  	assert.Equal(t, len(msg.PathAttributes), 1)
   295  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
   296  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5)
   297  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   298  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
   299  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS))
   300  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(bgp.AS_TRANS))
   301  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001))
   302  }
   303  
   304  // before:
   305  //  as-path  : 65000, 4000, 23456, 23456, 40001
   306  //  as4-path : empty
   307  // expected result:
   308  //  as-path  : 65000, 4000, 23456, 23456, 40001
   309  func TestAsPathAs4TransInvalid4(t *testing.T) {
   310  	as := []uint16{65000, 4000, bgp.AS_TRANS, bgp.AS_TRANS, 40001}
   311  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as)}
   312  	aspath := bgp.NewPathAttributeAsPath(params)
   313  
   314  	as4 := []uint32{}
   315  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as4)
   316  	param4s := []*bgp.As4PathParam{as4param1}
   317  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   318  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   319  	UpdatePathAttrs4ByteAs(msg)
   320  	assert.Equal(t, len(msg.PathAttributes), 1)
   321  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value), 1)
   322  	assert.Equal(t, len(msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS), 5)
   323  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[0], uint32(65000))
   324  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[1], uint32(4000))
   325  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[2], uint32(bgp.AS_TRANS))
   326  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[3], uint32(bgp.AS_TRANS))
   327  	assert.Equal(t, msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value[0].(*bgp.As4PathParam).AS[4], uint32(40001))
   328  }
   329  
   330  func TestASPathAs4TransMultipleParams(t *testing.T) {
   331  	as1 := []uint16{17676, 2914, 174, 50607}
   332  	as2 := []uint16{bgp.AS_TRANS, bgp.AS_TRANS}
   333  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as1), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as2)}
   334  	aspath := bgp.NewPathAttributeAsPath(params)
   335  
   336  	as41 := []uint32{2914, 174, 50607}
   337  	as42 := []uint32{198035, 198035}
   338  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as41)
   339  	as4param2 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as42)
   340  	param4s := []*bgp.As4PathParam{as4param1, as4param2}
   341  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   342  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   343  	UpdatePathAttrs4ByteAs(msg)
   344  	for _, param := range msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value {
   345  		p := param.(*bgp.As4PathParam)
   346  		assert.Equal(t, p.Num, uint8(len(p.AS)))
   347  	}
   348  }
   349  
   350  func TestASPathAs4TransMultipleLargeParams(t *testing.T) {
   351  	as1 := make([]uint16, 0, 255)
   352  	for i := 0; i < 255-5; i++ {
   353  		as1 = append(as1, uint16(i+1))
   354  	}
   355  	as1 = append(as1, []uint16{17676, 2914, 174, 50607}...)
   356  	as2 := []uint16{bgp.AS_TRANS, bgp.AS_TRANS}
   357  	params := []bgp.AsPathParamInterface{bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as1), bgp.NewAsPathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as2)}
   358  	aspath := bgp.NewPathAttributeAsPath(params)
   359  
   360  	as41 := []uint32{2914, 174, 50607}
   361  	as42 := []uint32{198035, 198035}
   362  	as4param1 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as41)
   363  	as4param2 := bgp.NewAs4PathParam(bgp.BGP_ASPATH_ATTR_TYPE_SEQ, as42)
   364  	param4s := []*bgp.As4PathParam{as4param1, as4param2}
   365  	as4path := bgp.NewPathAttributeAs4Path(param4s)
   366  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{aspath, as4path}, nil).Body.(*bgp.BGPUpdate)
   367  	UpdatePathAttrs4ByteAs(msg)
   368  	for _, param := range msg.PathAttributes[0].(*bgp.PathAttributeAsPath).Value {
   369  		p := param.(*bgp.As4PathParam)
   370  		assert.Equal(t, p.Num, uint8(len(p.AS)))
   371  	}
   372  }
   373  
   374  func TestAggregator4BytesASes(t *testing.T) {
   375  	getAggr := func(msg *bgp.BGPUpdate) *bgp.PathAttributeAggregator {
   376  		for _, attr := range msg.PathAttributes {
   377  			switch attr.(type) {
   378  			case *bgp.PathAttributeAggregator:
   379  				return attr.(*bgp.PathAttributeAggregator)
   380  			}
   381  		}
   382  		return nil
   383  	}
   384  
   385  	getAggr4 := func(msg *bgp.BGPUpdate) *bgp.PathAttributeAs4Aggregator {
   386  		for _, attr := range msg.PathAttributes {
   387  			switch attr.(type) {
   388  			case *bgp.PathAttributeAs4Aggregator:
   389  				return attr.(*bgp.PathAttributeAs4Aggregator)
   390  			}
   391  		}
   392  		return nil
   393  	}
   394  
   395  	addr := "192.168.0.1"
   396  	as4 := uint32(100000)
   397  	as := uint32(1000)
   398  	msg := bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(as4, addr)}, nil).Body.(*bgp.BGPUpdate)
   399  
   400  	// 4byte capable to 4byte capable for 4 bytes AS
   401  	assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil)
   402  	assert.Equal(t, getAggr(msg).Value.AS, as4)
   403  	assert.Equal(t, getAggr(msg).Value.Address.String(), addr)
   404  
   405  	// 4byte capable to 2byte capable for 4 bytes AS
   406  	UpdatePathAggregator2ByteAs(msg)
   407  	assert.Equal(t, getAggr(msg).Value.AS, uint32(bgp.AS_TRANS))
   408  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16)
   409  	assert.Equal(t, getAggr4(msg).Value.AS, as4)
   410  	assert.Equal(t, getAggr4(msg).Value.Address.String(), addr)
   411  
   412  	msg = bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(uint16(bgp.AS_TRANS), addr), bgp.NewPathAttributeAs4Aggregator(as4, addr)}, nil).Body.(*bgp.BGPUpdate)
   413  	assert.Equal(t, getAggr(msg).Value.AS, uint32(bgp.AS_TRANS))
   414  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16)
   415  
   416  	// non 4byte capable to 4byte capable for 4 bytes AS
   417  	assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil)
   418  	assert.Equal(t, getAggr(msg).Value.AS, as4)
   419  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32)
   420  	assert.Equal(t, getAggr(msg).Value.Address.String(), addr)
   421  	assert.Equal(t, getAggr4(msg), (*bgp.PathAttributeAs4Aggregator)(nil))
   422  
   423  	// non 4byte capable to non 4byte capable for 4 bytes AS
   424  	UpdatePathAggregator2ByteAs(msg)
   425  	assert.Equal(t, getAggr(msg).Value.AS, uint32(bgp.AS_TRANS))
   426  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16)
   427  	assert.Equal(t, getAggr4(msg).Value.AS, as4)
   428  	assert.Equal(t, getAggr4(msg).Value.Address.String(), addr)
   429  
   430  	msg = bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(uint32(as), addr)}, nil).Body.(*bgp.BGPUpdate)
   431  	// 4byte capable to 4byte capable for 2 bytes AS
   432  	assert.Equal(t, getAggr(msg).Value.AS, as)
   433  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32)
   434  	assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil)
   435  	assert.Equal(t, getAggr(msg).Value.AS, as)
   436  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32)
   437  
   438  	// 4byte capable to non 4byte capable for 2 bytes AS
   439  	UpdatePathAggregator2ByteAs(msg)
   440  	assert.Equal(t, getAggr4(msg), (*bgp.PathAttributeAs4Aggregator)(nil))
   441  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16)
   442  	assert.Equal(t, getAggr(msg).Value.AS, as)
   443  
   444  	msg = bgp.NewBGPUpdateMessage(nil, []bgp.PathAttributeInterface{bgp.NewPathAttributeAggregator(uint16(as), addr)}, nil).Body.(*bgp.BGPUpdate)
   445  	// non 4byte capable to 4byte capable for 2 bytes AS
   446  	assert.Equal(t, getAggr(msg).Value.AS, as)
   447  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16)
   448  	assert.Equal(t, UpdatePathAggregator4ByteAs(msg), nil)
   449  
   450  	assert.Equal(t, getAggr(msg).Value.AS, as)
   451  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint32)
   452  
   453  	// non 4byte capable to non 4byte capable for 2 bytes AS
   454  	UpdatePathAggregator2ByteAs(msg)
   455  	assert.Equal(t, getAggr(msg).Value.AS, as)
   456  	assert.Equal(t, getAggr(msg).Value.Askind, reflect.Uint16)
   457  	assert.Equal(t, getAggr4(msg), (*bgp.PathAttributeAs4Aggregator)(nil))
   458  }
   459  
   460  func TestBMP(t *testing.T) {
   461  	aspath1 := []bgp.AsPathParamInterface{
   462  		bgp.NewAs4PathParam(2, []uint32{1000000}),
   463  		bgp.NewAs4PathParam(1, []uint32{1000001, 1002}),
   464  		bgp.NewAs4PathParam(2, []uint32{1003, 100004}),
   465  	}
   466  	mp_nlri := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(100,
   467  		"fe80:1234:1234:5667:8967:af12:8912:1023")}
   468  
   469  	p := []bgp.PathAttributeInterface{
   470  		bgp.NewPathAttributeOrigin(3),
   471  		bgp.NewPathAttributeAsPath(aspath1),
   472  		bgp.NewPathAttributeMpUnreachNLRI(mp_nlri),
   473  	}
   474  	w := []*bgp.IPAddrPrefix{}
   475  	n := []*bgp.IPAddrPrefix{}
   476  
   477  	msg := bgp.NewBGPUpdateMessage(w, p, n)
   478  	pList := ProcessMessage(msg, peerR1(), time.Now())
   479  	CreateUpdateMsgFromPaths(pList)
   480  }
   481  
   482  func unreachIndex(msgs []*bgp.BGPMessage) int {
   483  	for i := range msgs {
   484  		for _, a := range msgs[i].Body.(*bgp.BGPUpdate).PathAttributes {
   485  			if a.GetType() == bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI {
   486  				return i
   487  			}
   488  		}
   489  	}
   490  	// should not be here
   491  	return -1
   492  }
   493  
   494  func TestMixedMPReachMPUnreach(t *testing.T) {
   495  	aspath1 := []bgp.AsPathParamInterface{
   496  		bgp.NewAs4PathParam(2, []uint32{100}),
   497  	}
   498  	nlri1 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(32, "2222::")}
   499  	nlri2 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(32, "1111::")}
   500  
   501  	p := []bgp.PathAttributeInterface{
   502  		bgp.NewPathAttributeOrigin(0),
   503  		bgp.NewPathAttributeAsPath(aspath1),
   504  		bgp.NewPathAttributeMpReachNLRI("1::1", nlri1),
   505  		bgp.NewPathAttributeMpUnreachNLRI(nlri2),
   506  	}
   507  	msg := bgp.NewBGPUpdateMessage(nil, p, nil)
   508  	pList := ProcessMessage(msg, peerR1(), time.Now())
   509  	assert.Equal(t, len(pList), 2)
   510  	assert.Equal(t, pList[0].IsWithdraw, false)
   511  	assert.Equal(t, pList[1].IsWithdraw, true)
   512  	msgs := CreateUpdateMsgFromPaths(pList)
   513  	assert.Equal(t, len(msgs), 2)
   514  
   515  	uIndex := unreachIndex(msgs)
   516  	rIndex := 0
   517  	if uIndex == 0 {
   518  		rIndex = 1
   519  	}
   520  	assert.Equal(t, len(msgs[uIndex].Body.(*bgp.BGPUpdate).PathAttributes), 1)
   521  	assert.Equal(t, len(msgs[rIndex].Body.(*bgp.BGPUpdate).PathAttributes), 3)
   522  }
   523  
   524  func TestMixedNLRIAndMPUnreach(t *testing.T) {
   525  	aspath1 := []bgp.AsPathParamInterface{
   526  		bgp.NewAs4PathParam(2, []uint32{100}),
   527  	}
   528  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.0.0.0")}
   529  	nlri2 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(32, "1111::")}
   530  
   531  	p := []bgp.PathAttributeInterface{
   532  		bgp.NewPathAttributeOrigin(0),
   533  		bgp.NewPathAttributeAsPath(aspath1),
   534  		bgp.NewPathAttributeNextHop("1.1.1.1"),
   535  		bgp.NewPathAttributeMpUnreachNLRI(nlri2),
   536  	}
   537  	msg := bgp.NewBGPUpdateMessage(nil, p, nlri1)
   538  	pList := ProcessMessage(msg, peerR1(), time.Now())
   539  
   540  	assert.Equal(t, len(pList), 2)
   541  	assert.Equal(t, pList[0].IsWithdraw, false)
   542  	assert.Equal(t, pList[1].IsWithdraw, true)
   543  	msgs := CreateUpdateMsgFromPaths(pList)
   544  	assert.Equal(t, len(msgs), 2)
   545  
   546  	uIndex := unreachIndex(msgs)
   547  	rIndex := 0
   548  	if uIndex == 0 {
   549  		rIndex = 1
   550  	}
   551  	assert.Equal(t, len(msgs[uIndex].Body.(*bgp.BGPUpdate).PathAttributes), 1)
   552  	assert.Equal(t, len(msgs[rIndex].Body.(*bgp.BGPUpdate).PathAttributes), 3)
   553  }
   554  
   555  func TestMergeV4NLRIs(t *testing.T) {
   556  	aspath1 := []bgp.AsPathParamInterface{
   557  		bgp.NewAs4PathParam(2, []uint32{100}),
   558  	}
   559  	attrs := []bgp.PathAttributeInterface{
   560  		bgp.NewPathAttributeOrigin(0),
   561  		bgp.NewPathAttributeAsPath(aspath1),
   562  		bgp.NewPathAttributeNextHop("1.1.1.1"),
   563  	}
   564  
   565  	nr := 1024
   566  	paths := make([]*Path, 0, nr)
   567  	addrs := make([]string, 0, nr)
   568  	for i := 0; i < nr; i++ {
   569  		addrs = append(addrs, fmt.Sprintf("1.1.%d.%d", i>>8&0xff, i&0xff))
   570  		nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(32, addrs[i])}
   571  		msg := bgp.NewBGPUpdateMessage(nil, attrs, nlri)
   572  		paths = append(paths, ProcessMessage(msg, peerR1(), time.Now())...)
   573  	}
   574  	msgs := CreateUpdateMsgFromPaths(paths)
   575  	assert.Equal(t, len(msgs), 2)
   576  
   577  	l := make([]*bgp.IPAddrPrefix, 0, nr)
   578  	for _, msg := range msgs {
   579  		u := msg.Body.(*bgp.BGPUpdate)
   580  		assert.Equal(t, len(u.PathAttributes), 3)
   581  		l = append(l, u.NLRI...)
   582  	}
   583  
   584  	assert.Equal(t, len(l), nr)
   585  	for i, addr := range addrs {
   586  		assert.Equal(t, addr, l[i].Prefix.String())
   587  	}
   588  	for _, msg := range msgs {
   589  		d, _ := msg.Serialize()
   590  		assert.True(t, len(d) < bgp.BGP_MAX_MESSAGE_LENGTH)
   591  	}
   592  }
   593  
   594  func TestNotMergeV4NLRIs(t *testing.T) {
   595  	paths := make([]*Path, 0, 2)
   596  
   597  	aspath1 := []bgp.AsPathParamInterface{
   598  		bgp.NewAs4PathParam(2, []uint32{100}),
   599  	}
   600  	attrs1 := []bgp.PathAttributeInterface{
   601  		bgp.NewPathAttributeOrigin(0),
   602  		bgp.NewPathAttributeAsPath(aspath1),
   603  		bgp.NewPathAttributeNextHop("1.1.1.1"),
   604  	}
   605  	nlri1 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(32, "1.1.1.1")}
   606  	paths = append(paths, ProcessMessage(bgp.NewBGPUpdateMessage(nil, attrs1, nlri1), peerR1(), time.Now())...)
   607  
   608  	attrs2 := []bgp.PathAttributeInterface{
   609  		bgp.NewPathAttributeOrigin(0),
   610  		bgp.NewPathAttributeAsPath(aspath1),
   611  		bgp.NewPathAttributeNextHop("2.2.2.2"),
   612  	}
   613  	nlri2 := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(32, "2.2.2.2")}
   614  	paths = append(paths, ProcessMessage(bgp.NewBGPUpdateMessage(nil, attrs2, nlri2), peerR1(), time.Now())...)
   615  
   616  	assert.NotEmpty(t, paths[0].GetHash(), paths[1].GetHash())
   617  
   618  	msgs := CreateUpdateMsgFromPaths(paths)
   619  	assert.Equal(t, len(msgs), 2)
   620  
   621  	paths[1].SetHash(paths[0].GetHash())
   622  	msgs = CreateUpdateMsgFromPaths(paths)
   623  	assert.Equal(t, len(msgs), 2)
   624  }
   625  
   626  func TestMergeV4Withdraw(t *testing.T) {
   627  	nr := 1024
   628  	paths := make([]*Path, 0, nr)
   629  	addrs := make([]string, 0, nr)
   630  	for i := 0; i < nr; i++ {
   631  		addrs = append(addrs, fmt.Sprintf("1.1.%d.%d", i>>8&0xff, i&0xff))
   632  		nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(32, addrs[i])}
   633  		// use different attribute for each nlri
   634  		aspath1 := []bgp.AsPathParamInterface{
   635  			bgp.NewAs4PathParam(2, []uint32{uint32(i)}),
   636  		}
   637  		attrs := []bgp.PathAttributeInterface{
   638  			bgp.NewPathAttributeOrigin(0),
   639  			bgp.NewPathAttributeAsPath(aspath1),
   640  			bgp.NewPathAttributeNextHop("1.1.1.1"),
   641  		}
   642  		msg := bgp.NewBGPUpdateMessage(nlri, attrs, nil)
   643  		paths = append(paths, ProcessMessage(msg, peerR1(), time.Now())...)
   644  	}
   645  	msgs := CreateUpdateMsgFromPaths(paths)
   646  	assert.Equal(t, len(msgs), 2)
   647  
   648  	l := make([]*bgp.IPAddrPrefix, 0, nr)
   649  	for _, msg := range msgs {
   650  		u := msg.Body.(*bgp.BGPUpdate)
   651  		assert.Equal(t, len(u.PathAttributes), 0)
   652  		l = append(l, u.WithdrawnRoutes...)
   653  	}
   654  	assert.Equal(t, len(l), nr)
   655  	for i, addr := range addrs {
   656  		assert.Equal(t, addr, l[i].Prefix.String())
   657  	}
   658  
   659  	for _, msg := range msgs {
   660  		d, _ := msg.Serialize()
   661  		assert.True(t, len(d) < bgp.BGP_MAX_MESSAGE_LENGTH)
   662  	}
   663  }