github.com/osrg/gobgp/v3@v3.30.0/internal/pkg/table/table_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 "testing" 20 "time" 21 22 "github.com/osrg/gobgp/v3/pkg/packet/bgp" 23 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestLookupLonger(t *testing.T) { 28 tbl := NewTable(logger, bgp.RF_IPv4_UC) 29 30 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(23, "11.0.0.0"), 0)) 31 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(24, "11.0.0.0"), 0)) 32 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(32, "11.0.0.4"), 0)) 33 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(32, "11.0.0.129"), 0)) 34 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(28, "11.0.0.144"), 0)) 35 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(29, "11.0.0.144"), 0)) 36 tbl.setDestination(NewDestination(bgp.NewIPAddrPrefix(32, "11.0.0.145"), 0)) 37 38 r, _ := tbl.GetLongerPrefixDestinations("11.0.0.128/25") 39 assert.Equal(t, len(r), 4) 40 r, _ = tbl.GetLongerPrefixDestinations("11.0.0.0/24") 41 assert.Equal(t, len(r), 6) 42 } 43 44 func TestTableDeleteDest(t *testing.T) { 45 peerT := TableCreatePeer() 46 pathT := TableCreatePath(peerT) 47 ipv4t := NewTable(logger, bgp.RF_IPv4_UC) 48 for _, path := range pathT { 49 dest := NewDestination(path.GetNlri(), 0) 50 ipv4t.setDestination(dest) 51 } 52 dest := NewDestination(pathT[0].GetNlri(), 0) 53 ipv4t.setDestination(dest) 54 ipv4t.deleteDest(dest) 55 gdest := ipv4t.GetDestination(pathT[0].GetNlri()) 56 assert.Nil(t, gdest) 57 } 58 59 func TestTableGetRouteFamily(t *testing.T) { 60 ipv4t := NewTable(logger, bgp.RF_IPv4_UC) 61 rf := ipv4t.GetRoutefamily() 62 assert.Equal(t, rf, bgp.RF_IPv4_UC) 63 } 64 65 func TestTableSetDestinations(t *testing.T) { 66 peerT := TableCreatePeer() 67 pathT := TableCreatePath(peerT) 68 ipv4t := NewTable(logger, bgp.RF_IPv4_UC) 69 destinations := make(map[string]*Destination) 70 for _, path := range pathT { 71 tableKey := ipv4t.tableKey(path.GetNlri()) 72 dest := NewDestination(path.GetNlri(), 0) 73 destinations[tableKey] = dest 74 } 75 ipv4t.setDestinations(destinations) 76 ds := ipv4t.GetDestinations() 77 assert.Equal(t, ds, destinations) 78 } 79 func TestTableGetDestinations(t *testing.T) { 80 peerT := DestCreatePeer() 81 pathT := DestCreatePath(peerT) 82 ipv4t := NewTable(logger, bgp.RF_IPv4_UC) 83 destinations := make(map[string]*Destination) 84 for _, path := range pathT { 85 tableKey := ipv4t.tableKey(path.GetNlri()) 86 dest := NewDestination(path.GetNlri(), 0) 87 destinations[tableKey] = dest 88 } 89 ipv4t.setDestinations(destinations) 90 ds := ipv4t.GetDestinations() 91 assert.Equal(t, ds, destinations) 92 } 93 94 func TestTableKey(t *testing.T) { 95 tb := NewTable(logger, bgp.RF_IPv4_UC) 96 n1, _ := bgp.NewPrefixFromRouteFamily(bgp.AFI_IP, bgp.SAFI_UNICAST, "0.0.0.0/0") 97 d1 := NewDestination(n1, 0) 98 n2, _ := bgp.NewPrefixFromRouteFamily(bgp.AFI_IP, bgp.SAFI_UNICAST, "0.0.0.0/1") 99 d2 := NewDestination(n2, 0) 100 assert.Equal(t, len(tb.tableKey(d1.GetNlri())), 5) 101 tb.setDestination(d1) 102 tb.setDestination(d2) 103 assert.Equal(t, len(tb.GetDestinations()), 2) 104 } 105 106 func TestTableSelectMalformedIPv4UCPrefixes(t *testing.T) { 107 table := NewTable(logger, bgp.RF_IPv4_UC) 108 assert.Equal(t, 0, len(table.GetDestinations())) 109 110 tests := []struct { 111 name string 112 prefix string 113 option LookupOption 114 found int 115 }{ 116 { 117 name: "Malformed IPv4 Address", 118 prefix: "2.2.2.2.2", 119 option: LOOKUP_EXACT, 120 found: 0, 121 }, 122 { 123 name: "exact match with RD and prefix that does not exist", 124 prefix: "foo", 125 option: LOOKUP_EXACT, 126 found: 0, 127 }, 128 } 129 130 for _, tt := range tests { 131 t.Run(tt.name, func(t *testing.T) { 132 filteredTable, _ := table.Select( 133 TableSelectOption{ 134 LookupPrefixes: []*LookupPrefix{{ 135 Prefix: tt.prefix, 136 LookupOption: tt.option, 137 }}, 138 }, 139 ) 140 assert.Equal(t, tt.found, len(filteredTable.GetDestinations())) 141 }) 142 } 143 } 144 145 func TestTableSelectMalformedIPv6UCPrefixes(t *testing.T) { 146 table := NewTable(logger, bgp.RF_IPv6_UC) 147 assert.Equal(t, 0, len(table.GetDestinations())) 148 149 tests := []struct { 150 name string 151 prefix string 152 option LookupOption 153 found int 154 }{ 155 { 156 name: "Malformed IPv6 Address: 3343:faba:3903:128::::/63", 157 prefix: "3343:faba:3903:128::::/63", 158 option: LOOKUP_EXACT, 159 found: 0, 160 }, 161 { 162 name: "Malformed IPv6 Address: foo", 163 prefix: "foo", 164 option: LOOKUP_EXACT, 165 found: 0, 166 }, 167 } 168 169 for _, tt := range tests { 170 t.Run(tt.name, func(t *testing.T) { 171 filteredTable, _ := table.Select( 172 TableSelectOption{ 173 LookupPrefixes: []*LookupPrefix{{ 174 Prefix: tt.prefix, 175 LookupOption: tt.option, 176 }}, 177 }, 178 ) 179 assert.Equal(t, tt.found, len(filteredTable.GetDestinations())) 180 }) 181 } 182 } 183 184 func TestTableSelectVPNv4(t *testing.T) { 185 prefixes := []string{ 186 "100:100:2.2.2.0/25", 187 "100:100:2.2.2.2/32", 188 "200:100:2.2.2.2/32", 189 "300:100:2.2.2.2/32", 190 "100:100:2.2.2.3/32", 191 "100:100:2.2.2.4/32", 192 "1.1.1.1:1:2.2.2.5/32", 193 "8732:1:2.2.2.5/32", 194 "8732:1:3.3.3.3/32", 195 } 196 197 table := NewTable(logger, bgp.RF_IPv4_VPN) 198 for _, prefix := range prefixes { 199 nlri, _ := bgp.NewPrefixFromRouteFamily(bgp.AFI_IP, bgp.SAFI_MPLS_VPN, prefix) 200 201 destination := NewDestination(nlri, 0, NewPath(nil, nlri, false, nil, time.Now(), false)) 202 table.setDestination(destination) 203 } 204 assert.Equal(t, 9, len(table.GetDestinations())) 205 206 tests := []struct { 207 name string 208 prefix string 209 RD string 210 option LookupOption 211 found int 212 }{ 213 { 214 name: "exact match with RD that does not exist", 215 prefix: "2.2.2.2/32", 216 RD: "500:500", 217 option: LOOKUP_EXACT, 218 found: 0, 219 }, 220 { 221 name: "exact match with RD and prefix that does not exist", 222 prefix: "4.4.4.4/32", 223 RD: "100:100", 224 option: LOOKUP_EXACT, 225 found: 0, 226 }, 227 { 228 name: "exact match with RD", 229 prefix: "2.2.2.0/25", 230 RD: "100:100", 231 option: LOOKUP_EXACT, 232 found: 1, 233 }, 234 { 235 name: "longer match with RD", 236 prefix: "2.2.2.0/25", 237 RD: "100:100", 238 option: LOOKUP_LONGER, 239 found: 4, 240 }, 241 { 242 name: "shorter match with RD", 243 prefix: "2.2.2.2/32", 244 RD: "100:100", 245 option: LOOKUP_SHORTER, 246 found: 2, 247 }, 248 { 249 name: "exact match without RD for prefix that does not exist", 250 prefix: "4.4.4.4/32", 251 option: LOOKUP_EXACT, 252 found: 0, 253 }, 254 { 255 name: "exact match without RD", 256 prefix: "2.2.2.2/32", 257 option: LOOKUP_EXACT, 258 found: 3, 259 }, 260 { 261 name: "longer match without RD", 262 prefix: "2.2.2.0/24", 263 option: LOOKUP_LONGER, 264 found: 8, 265 }, 266 { 267 name: "shorter match without RD", 268 prefix: "2.2.2.2/32", 269 option: LOOKUP_SHORTER, 270 found: 4, 271 }, 272 } 273 274 for _, tt := range tests { 275 t.Run(tt.name, func(t *testing.T) { 276 filteredTable, _ := table.Select( 277 TableSelectOption{ 278 LookupPrefixes: []*LookupPrefix{{ 279 Prefix: tt.prefix, 280 RD: tt.RD, 281 LookupOption: tt.option, 282 }}, 283 }, 284 ) 285 assert.Equal(t, tt.found, len(filteredTable.GetDestinations())) 286 }) 287 } 288 } 289 290 func TestTableSelectVPNv6(t *testing.T) { 291 prefixes := []string{ 292 "100:100:100::/32", 293 "100:100:100::/64", 294 "100:100:100:1::/64", 295 "100:100:100:2::/64", 296 "200:100:100:2::/64", 297 "300:100:100:2::/64", 298 "100:100:100:3:1::/48", 299 "100:100:100:3:1:2::/64", 300 "100:100:100:2:3:4:5:6::/96", 301 } 302 303 table := NewTable(logger, bgp.RF_IPv6_VPN) 304 for _, prefix := range prefixes { 305 nlri, _ := bgp.NewPrefixFromRouteFamily(bgp.AFI_IP6, bgp.SAFI_MPLS_VPN, prefix) 306 307 destination := NewDestination(nlri, 0, NewPath(nil, nlri, false, nil, time.Now(), false)) 308 table.setDestination(destination) 309 } 310 assert.Equal(t, 9, len(table.GetDestinations())) 311 312 tests := []struct { 313 name string 314 prefix string 315 RD string 316 option LookupOption 317 found int 318 }{ 319 { 320 name: "exact match with RD that does not exist", 321 prefix: "100::/32", 322 RD: "500:500", 323 option: LOOKUP_EXACT, 324 found: 0, 325 }, 326 { 327 name: "exact match with RD and prefix that does not exist", 328 prefix: "200::/32", 329 RD: "100:100", 330 option: LOOKUP_EXACT, 331 found: 0, 332 }, 333 { 334 name: "exact match with RD", 335 prefix: "100:2::/64", 336 RD: "100:100", 337 option: LOOKUP_EXACT, 338 found: 1, 339 }, 340 { 341 name: "longer match with RD", 342 prefix: "100::/16", 343 RD: "100:100", 344 option: LOOKUP_LONGER, 345 found: 7, 346 }, 347 { 348 name: "shorter match with RD", 349 prefix: "100::/96", 350 RD: "100:100", 351 option: LOOKUP_SHORTER, 352 found: 2, 353 }, 354 { 355 name: "exact match without RD for prefix that does not exist", 356 prefix: "100:5::/64", 357 option: LOOKUP_EXACT, 358 found: 0, 359 }, 360 { 361 name: "exact match without RD", 362 prefix: "100:2::/64", 363 option: LOOKUP_EXACT, 364 found: 3, 365 }, 366 { 367 name: "longer match without RD", 368 prefix: "100:3::/32", 369 option: LOOKUP_LONGER, 370 found: 2, 371 }, 372 { 373 name: "shorter match without RD", 374 prefix: "100:2::/96", 375 option: LOOKUP_SHORTER, 376 found: 3, 377 }, 378 } 379 380 for _, tt := range tests { 381 t.Run(tt.name, func(t *testing.T) { 382 filteredTable, _ := table.Select( 383 TableSelectOption{ 384 LookupPrefixes: []*LookupPrefix{{ 385 Prefix: tt.prefix, 386 RD: tt.RD, 387 LookupOption: tt.option, 388 }}, 389 }, 390 ) 391 assert.Equal(t, tt.found, len(filteredTable.GetDestinations())) 392 }) 393 } 394 } 395 396 func TableCreatePeer() []*PeerInfo { 397 peerT1 := &PeerInfo{AS: 65000} 398 peerT2 := &PeerInfo{AS: 65001} 399 peerT3 := &PeerInfo{AS: 65002} 400 peerT := []*PeerInfo{peerT1, peerT2, peerT3} 401 return peerT 402 } 403 404 func TableCreatePath(peerT []*PeerInfo) []*Path { 405 bgpMsgT1 := updateMsgT1() 406 bgpMsgT2 := updateMsgT2() 407 bgpMsgT3 := updateMsgT3() 408 pathT := make([]*Path, 3) 409 for i, msg := range []*bgp.BGPMessage{bgpMsgT1, bgpMsgT2, bgpMsgT3} { 410 updateMsgT := msg.Body.(*bgp.BGPUpdate) 411 nlriList := updateMsgT.NLRI 412 pathAttributes := updateMsgT.PathAttributes 413 nlri_info := nlriList[0] 414 pathT[i] = NewPath(peerT[i], nlri_info, false, pathAttributes, time.Now(), false) 415 } 416 return pathT 417 } 418 419 func updateMsgT1() *bgp.BGPMessage { 420 421 origin := bgp.NewPathAttributeOrigin(0) 422 aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65000})} 423 aspath := bgp.NewPathAttributeAsPath(aspathParam) 424 nexthop := bgp.NewPathAttributeNextHop("192.168.50.1") 425 med := bgp.NewPathAttributeMultiExitDisc(0) 426 427 pathAttributes := []bgp.PathAttributeInterface{ 428 origin, 429 aspath, 430 nexthop, 431 med, 432 } 433 434 nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.10.0")} 435 return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) 436 } 437 438 func updateMsgT2() *bgp.BGPMessage { 439 440 origin := bgp.NewPathAttributeOrigin(0) 441 aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65100})} 442 aspath := bgp.NewPathAttributeAsPath(aspathParam) 443 nexthop := bgp.NewPathAttributeNextHop("192.168.100.1") 444 med := bgp.NewPathAttributeMultiExitDisc(100) 445 446 pathAttributes := []bgp.PathAttributeInterface{ 447 origin, 448 aspath, 449 nexthop, 450 med, 451 } 452 453 nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "20.20.20.0")} 454 return bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) 455 } 456 457 func updateMsgT3() *bgp.BGPMessage { 458 origin := bgp.NewPathAttributeOrigin(0) 459 aspathParam := []bgp.AsPathParamInterface{bgp.NewAsPathParam(2, []uint16{65100})} 460 aspath := bgp.NewPathAttributeAsPath(aspathParam) 461 nexthop := bgp.NewPathAttributeNextHop("192.168.150.1") 462 med := bgp.NewPathAttributeMultiExitDisc(100) 463 464 pathAttributes := []bgp.PathAttributeInterface{ 465 origin, 466 aspath, 467 nexthop, 468 med, 469 } 470 471 nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "30.30.30.0")} 472 w1 := bgp.NewIPAddrPrefix(23, "40.40.40.0") 473 withdrawnRoutes := []*bgp.IPAddrPrefix{w1} 474 return bgp.NewBGPUpdateMessage(withdrawnRoutes, pathAttributes, nlri) 475 }