github.com/osrg/gobgp@v2.0.0+incompatible/internal/pkg/zebra/zapi_test.go (about) 1 // Copyright (C) 2014, 2015 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 zebra 17 18 import ( 19 "encoding/binary" 20 "net" 21 "syscall" 22 "testing" 23 24 "github.com/stretchr/testify/require" 25 26 "github.com/stretchr/testify/assert" 27 ) 28 29 func Test_Header(t *testing.T) { 30 assert := assert.New(t) 31 32 //DecodeFromBytes 33 buf := make([]byte, 6) 34 binary.BigEndian.PutUint16(buf[0:], 10) 35 buf[2] = HEADER_MARKER 36 buf[3] = 2 37 binary.BigEndian.PutUint16(buf[4:], uint16(IPV4_ROUTE_ADD)) 38 h := &Header{} 39 err := h.DecodeFromBytes(buf) 40 assert.Equal(nil, err) 41 42 //Serialize 43 buf, err = h.Serialize() 44 assert.Equal(nil, err) 45 h2 := &Header{} 46 err = h2.DecodeFromBytes(buf) 47 assert.Equal(nil, err) 48 assert.Equal(h, h2) 49 50 // header_size mismatch 51 buf = make([]byte, HeaderSize(2)-1) 52 binary.BigEndian.PutUint16(buf[0:], 10) 53 buf[2] = 0xff 54 buf[3] = 0x02 55 h3 := &Header{} 56 err = h3.DecodeFromBytes(buf) 57 assert.NotEqual(nil, err) 58 } 59 60 func Test_InterfaceUpdateBody(t *testing.T) { 61 assert := assert.New(t) 62 63 //DecodeFromBytes 64 buf := make([]byte, INTERFACE_NAMSIZ+49) 65 pos := INTERFACE_NAMSIZ 66 binary.BigEndian.PutUint32(buf[pos:], 1) 67 pos += 4 68 buf[pos] = byte(INTERFACE_ACTIVE) 69 pos += 1 70 binary.BigEndian.PutUint64(buf[pos:], 1) 71 pos += 8 // flags 72 binary.BigEndian.PutUint32(buf[pos:], 1) 73 pos += 4 // metric 74 binary.BigEndian.PutUint32(buf[pos:], 1500) 75 pos += 4 // MTU 76 binary.BigEndian.PutUint32(buf[pos:], 1500) 77 pos += 4 // MTU6 78 binary.BigEndian.PutUint32(buf[pos:], 200) 79 pos += 4 // bandwidth 80 binary.BigEndian.PutUint32(buf[pos:], 6) 81 pos += 4 // hwaddr_len 82 mac, _ := net.ParseMAC("01:23:45:67:89:ab") 83 copy(buf[pos:pos+6], []byte(mac)) 84 pos += 4 85 b := &InterfaceUpdateBody{} 86 err := b.DecodeFromBytes(buf, 2) 87 assert.Equal(nil, err) 88 assert.Equal("01:23:45:67:89:ab", b.HardwareAddr.String()) 89 90 buf = make([]byte, INTERFACE_NAMSIZ+28) 91 b = &InterfaceUpdateBody{} 92 err = b.DecodeFromBytes(buf, 2) 93 assert.NotEqual(nil, err) 94 } 95 96 func Test_InterfaceAddressUpdateBody(t *testing.T) { 97 assert := assert.New(t) 98 99 //DecodeFromBytes 100 buf := make([]byte, 15) 101 pos := 0 102 binary.BigEndian.PutUint32(buf[pos:], 0) // index 103 pos += 4 104 buf[pos] = 0x01 // flags 105 pos += 1 106 buf[pos] = 0x2 // family 107 pos += 1 108 ip := net.ParseIP("192.168.100.1").To4() // prefix 109 copy(buf[pos:pos+4], []byte(ip)) 110 pos += 4 111 buf[pos] = byte(24) // prefix len 112 pos += 1 113 dst := net.ParseIP("192.168.100.255").To4() // destination 114 copy(buf[pos:pos+4], []byte(dst)) 115 116 b := &InterfaceAddressUpdateBody{} 117 err := b.DecodeFromBytes(buf, 2) 118 require.NoError(t, err) 119 120 assert.Equal(uint32(0), b.Index) 121 assert.Equal(INTERFACE_ADDRESS_FLAG(1), b.Flags) 122 assert.Equal("192.168.100.1", b.Prefix.String()) 123 assert.Equal(uint8(24), b.Length) 124 assert.Equal("192.168.100.255", b.Destination.String()) 125 126 // af invalid 127 buf[5] = 0x4 128 pos += 1 129 b = &InterfaceAddressUpdateBody{} 130 err = b.DecodeFromBytes(buf, 2) 131 assert.NotEqual(nil, err) 132 } 133 134 func Test_RouterIDUpdateBody(t *testing.T) { 135 assert := assert.New(t) 136 137 //DecodeFromBytes 138 buf := make([]byte, 6) 139 pos := 0 140 buf[pos] = 0x2 141 pos += 1 142 ip := net.ParseIP("192.168.100.1").To4() 143 copy(buf[pos:pos+4], []byte(ip)) 144 pos += 4 145 buf[pos] = byte(32) 146 147 b := &RouterIDUpdateBody{} 148 err := b.DecodeFromBytes(buf, 2) 149 assert.Equal(nil, err) 150 assert.Equal("192.168.100.1", b.Prefix.String()) 151 assert.Equal(uint8(32), b.Length) 152 153 // af invalid 154 buf[0] = 0x4 155 pos += 1 156 b = &RouterIDUpdateBody{} 157 err = b.DecodeFromBytes(buf, 2) 158 assert.NotEqual(nil, err) 159 } 160 161 func Test_IPRouteBody_IPv4(t *testing.T) { 162 assert := assert.New(t) 163 164 //DecodeFromBytes IPV4_ROUTE 165 buf := make([]byte, 26) 166 buf[0] = byte(ROUTE_CONNECT) 167 buf[1] = byte(FLAG_SELECTED) 168 buf[2] = byte(MESSAGE_NEXTHOP | MESSAGE_IFINDEX | MESSAGE_DISTANCE | MESSAGE_METRIC | MESSAGE_MTU) 169 buf[3] = 24 170 ip := net.ParseIP("192.168.100.0").To4() 171 copy(buf[4:7], []byte(ip)) 172 173 buf[7] = 1 174 nexthop := net.ParseIP("0.0.0.0").To4() 175 copy(buf[8:12], []byte(nexthop)) 176 177 buf[12] = 1 178 binary.BigEndian.PutUint32(buf[13:], 1) 179 buf[17] = 0 // distance 180 binary.BigEndian.PutUint32(buf[18:], 1) 181 binary.BigEndian.PutUint32(buf[22:], 1) 182 r := &IPRouteBody{Api: IPV4_ROUTE_ADD} 183 err := r.DecodeFromBytes(buf, 2) 184 185 assert.Equal(nil, err) 186 assert.Equal("192.168.100.0", r.Prefix.Prefix.String()) 187 assert.Equal(uint8(0x18), r.Prefix.PrefixLen) 188 assert.Equal(MESSAGE_NEXTHOP|MESSAGE_IFINDEX|MESSAGE_DISTANCE|MESSAGE_METRIC|MESSAGE_MTU, r.Message) 189 assert.Equal("0.0.0.0", r.Nexthops[0].Gate.String()) 190 assert.Equal(uint32(1), r.Nexthops[1].Ifindex) 191 assert.Equal(uint8(0), r.Distance) 192 assert.Equal(uint32(1), r.Metric) 193 assert.Equal(uint32(1), r.Mtu) 194 195 //Serialize 196 buf, err = r.Serialize(2) 197 assert.Equal(nil, err) 198 assert.Equal([]byte{0x2, 0x10, 0x1f}, buf[0:3]) 199 assert.Equal([]byte{0x0, 0x1}, buf[3:5]) 200 assert.Equal(byte(24), buf[5]) 201 ip = net.ParseIP("192.168.100.0").To4() 202 assert.Equal([]byte(ip)[0:3], buf[6:9]) 203 assert.Equal(byte(2), buf[9]) 204 assert.Equal(byte(NEXTHOP_TYPE_IPV4), buf[10]) 205 assert.Equal(byte(NEXTHOP_TYPE_IFINDEX), buf[15]) 206 assert.Equal(byte(0x0), buf[20]) 207 208 bi := make([]byte, 4) 209 binary.BigEndian.PutUint32(bi, 1) 210 assert.Equal(bi, buf[21:25]) 211 assert.Equal(bi, buf[25:]) 212 213 // length invalid 214 buf = make([]byte, 18) 215 buf[0] = byte(ROUTE_CONNECT) 216 buf[1] = byte(FLAG_SELECTED) 217 buf[2] = byte(MESSAGE_NEXTHOP | MESSAGE_IFINDEX | MESSAGE_DISTANCE | MESSAGE_METRIC) 218 buf[3] = 24 219 ip = net.ParseIP("192.168.100.0").To4() 220 copy(buf[4:7], []byte(ip)) 221 buf[7] = 1 222 nexthop = net.ParseIP("0.0.0.0").To4() 223 copy(buf[8:12], []byte(nexthop)) 224 buf[12] = 1 225 binary.BigEndian.PutUint32(buf[13:], 1) 226 227 r = &IPRouteBody{Api: IPV4_ROUTE_ADD} 228 err = r.DecodeFromBytes(buf, 2) 229 assert.Equal("MESSAGE_METRIC message length invalid pos:16 rest:16", err.Error()) 230 231 // no nexthop 232 buf = make([]byte, 12) 233 buf[0] = byte(ROUTE_CONNECT) 234 buf[1] = byte(FLAG_SELECTED) 235 buf[2] = byte(MESSAGE_DISTANCE | MESSAGE_METRIC) 236 buf[3] = 24 237 ip = net.ParseIP("192.168.100.0").To4() 238 copy(buf[4:7], []byte(ip)) 239 buf[7] = 1 240 binary.BigEndian.PutUint32(buf[8:], 0) 241 r = &IPRouteBody{Api: IPV4_ROUTE_ADD} 242 err = r.DecodeFromBytes(buf, 2) 243 assert.Equal(nil, err) 244 245 } 246 247 func Test_IPRouteBody_IPv6(t *testing.T) { 248 assert := assert.New(t) 249 250 //DecodeFromBytes IPV6_ROUTE 251 buf := make([]byte, 43) 252 buf[0] = byte(ROUTE_CONNECT) 253 buf[1] = byte(FLAG_SELECTED) 254 buf[2] = byte(MESSAGE_NEXTHOP | MESSAGE_IFINDEX | MESSAGE_DISTANCE | MESSAGE_METRIC | MESSAGE_MTU) 255 buf[3] = 64 256 ip := net.ParseIP("2001:db8:0:f101::").To16() 257 copy(buf[4:12], []byte(ip)) 258 259 buf[12] = 1 260 nexthop := net.ParseIP("::").To16() 261 copy(buf[13:29], []byte(nexthop)) 262 // ifindex 263 buf[29] = 1 264 binary.BigEndian.PutUint32(buf[30:], 1) 265 266 buf[34] = 0 // distance 267 binary.BigEndian.PutUint32(buf[35:], 1) 268 binary.BigEndian.PutUint32(buf[39:], 1) 269 r := &IPRouteBody{Api: IPV6_ROUTE_ADD} 270 err := r.DecodeFromBytes(buf, 2) 271 272 assert.Equal(nil, err) 273 assert.Equal("2001:db8:0:f101::", r.Prefix.Prefix.String()) 274 assert.Equal(uint8(64), r.Prefix.PrefixLen) 275 assert.Equal(MESSAGE_NEXTHOP|MESSAGE_IFINDEX|MESSAGE_DISTANCE|MESSAGE_METRIC|MESSAGE_MTU, r.Message) 276 assert.Equal("::", r.Nexthops[0].Gate.String()) 277 assert.Equal(uint32(1), r.Nexthops[1].Ifindex) 278 assert.Equal(uint8(0), r.Distance) 279 assert.Equal(uint32(1), r.Metric) 280 assert.Equal(uint32(1), r.Mtu) 281 282 //Serialize 283 buf, err = r.Serialize(2) 284 assert.Equal(nil, err) 285 assert.Equal([]byte{0x2, 0x10, 0x1f}, buf[0:3]) 286 assert.Equal([]byte{0x0, 0x1}, buf[3:5]) 287 assert.Equal(byte(64), buf[5]) 288 ip = net.ParseIP("2001:db8:0:f101::").To16() 289 assert.Equal([]byte(ip)[0:8], buf[6:14]) 290 assert.Equal(byte(2), buf[14]) 291 assert.Equal(byte(NEXTHOP_TYPE_IPV6), buf[15]) 292 ip = net.ParseIP("::").To16() 293 assert.Equal([]byte(ip), buf[16:32]) 294 assert.Equal(byte(NEXTHOP_TYPE_IFINDEX), buf[32]) 295 bi := make([]byte, 4) 296 binary.BigEndian.PutUint32(bi, 1) 297 assert.Equal(bi, buf[33:37]) 298 299 //distance 300 assert.Equal(byte(0), buf[37]) 301 bi = make([]byte, 4) 302 binary.BigEndian.PutUint32(bi, 1) 303 assert.Equal(bi, buf[38:42]) 304 assert.Equal(bi, buf[42:]) 305 306 // length invalid 307 buf = make([]byte, 50) 308 buf[0] = byte(ROUTE_CONNECT) 309 buf[1] = byte(FLAG_SELECTED) 310 buf[2] = byte(MESSAGE_NEXTHOP | MESSAGE_IFINDEX | MESSAGE_DISTANCE | MESSAGE_METRIC) 311 buf[3] = 24 312 ip = net.ParseIP("2001:db8:0:f101::").To4() 313 copy(buf[4:12], []byte(ip)) 314 buf[13] = 1 315 nexthop = net.ParseIP("::").To16() 316 copy(buf[14:30], []byte(nexthop)) 317 buf[31] = 1 318 binary.BigEndian.PutUint32(buf[32:], 1) 319 320 r = &IPRouteBody{Api: IPV6_ROUTE_ADD} 321 err = r.DecodeFromBytes(buf, 2) 322 assert.Equal("message length invalid", err.Error()) 323 324 // no nexthop 325 buf = make([]byte, 11) 326 buf[0] = byte(ROUTE_CONNECT) 327 buf[1] = byte(FLAG_SELECTED) 328 buf[2] = byte(MESSAGE_DISTANCE | MESSAGE_METRIC) 329 buf[3] = 16 330 ip = net.ParseIP("2501::").To16() 331 copy(buf[4:6], []byte(ip)) 332 buf[6] = 1 333 binary.BigEndian.PutUint32(buf[7:], 0) 334 r = &IPRouteBody{Api: IPV6_ROUTE_ADD} 335 err = r.DecodeFromBytes(buf, 2) 336 assert.Equal(nil, err) 337 } 338 339 func Test_NexthopLookupBody(t *testing.T) { 340 assert := assert.New(t) 341 342 //ipv4 343 //DecodeFromBytes 344 pos := 0 345 buf := make([]byte, 18) 346 ip := net.ParseIP("192.168.50.0").To4() 347 copy(buf[0:4], []byte(ip)) 348 pos += 4 349 binary.BigEndian.PutUint32(buf[pos:], 10) 350 pos += 4 351 buf[pos] = byte(1) 352 pos += 1 353 buf[pos] = byte(4) 354 pos += 1 355 ip = net.ParseIP("172.16.1.101").To4() 356 copy(buf[pos:pos+4], []byte(ip)) 357 pos += 4 358 binary.BigEndian.PutUint32(buf[pos:], 3) 359 360 b := &NexthopLookupBody{Api: IPV4_NEXTHOP_LOOKUP} 361 err := b.DecodeFromBytes(buf, 2) 362 assert.Equal(nil, err) 363 assert.Equal("192.168.50.0", b.Addr.String()) 364 assert.Equal(uint32(10), b.Metric) 365 assert.Equal(uint32(3), b.Nexthops[0].Ifindex) 366 assert.Equal(NEXTHOP_TYPE(4), b.Nexthops[0].Type) 367 assert.Equal("172.16.1.101", b.Nexthops[0].Gate.String()) 368 369 //Serialize 370 buf, err = b.Serialize(2) 371 ip = net.ParseIP("192.168.50.0").To4() 372 assert.Equal(nil, err) 373 assert.Equal([]byte(ip)[0:4], buf[0:4]) 374 375 // length invalid 376 buf = make([]byte, 3) 377 b = &NexthopLookupBody{Api: IPV4_NEXTHOP_LOOKUP} 378 err = b.DecodeFromBytes(buf, 2) 379 assert.NotEqual(nil, err) 380 381 //ipv6 382 //DecodeFromBytes 383 pos = 0 384 buf = make([]byte, 46) 385 ip = net.ParseIP("2001:db8:0:f101::").To16() 386 copy(buf[0:16], []byte(ip)) 387 pos += 16 388 binary.BigEndian.PutUint32(buf[pos:], 10) 389 pos += 4 390 buf[pos] = byte(1) 391 pos += 1 392 buf[pos] = byte(7) 393 pos += 1 394 ip = net.ParseIP("2001:db8:0:1111::1").To16() 395 copy(buf[pos:pos+16], []byte(ip)) 396 pos += 16 397 binary.BigEndian.PutUint32(buf[pos:], 3) 398 399 b = &NexthopLookupBody{Api: IPV6_NEXTHOP_LOOKUP} 400 err = b.DecodeFromBytes(buf, 2) 401 assert.Equal(nil, err) 402 assert.Equal("2001:db8:0:f101::", b.Addr.String()) 403 assert.Equal(uint32(10), b.Metric) 404 assert.Equal(uint32(3), b.Nexthops[0].Ifindex) 405 assert.Equal(NEXTHOP_TYPE(7), b.Nexthops[0].Type) 406 assert.Equal("2001:db8:0:1111::1", b.Nexthops[0].Gate.String()) 407 408 //Serialize 409 buf, err = b.Serialize(2) 410 ip = net.ParseIP("2001:db8:0:f101::").To16() 411 assert.Equal(nil, err) 412 assert.Equal([]byte(ip)[0:16], buf[0:16]) 413 414 // length invalid 415 buf = make([]byte, 15) 416 b = &NexthopLookupBody{Api: IPV6_NEXTHOP_LOOKUP} 417 err = b.DecodeFromBytes(buf, 2) 418 assert.NotEqual(nil, err) 419 } 420 421 func Test_ImportLookupBody(t *testing.T) { 422 assert := assert.New(t) 423 424 //DecodeFromBytes 425 pos := 0 426 buf := make([]byte, 18) 427 ip := net.ParseIP("192.168.50.0").To4() 428 copy(buf[0:4], []byte(ip)) 429 pos += 4 430 binary.BigEndian.PutUint32(buf[pos:], 10) 431 pos += 4 432 buf[pos] = byte(1) 433 pos += 1 434 buf[pos] = byte(4) 435 pos += 1 436 ip = net.ParseIP("172.16.1.101").To4() 437 copy(buf[pos:pos+4], []byte(ip)) 438 pos += 4 439 binary.BigEndian.PutUint32(buf[pos:], 3) 440 441 b := &ImportLookupBody{Api: IPV4_IMPORT_LOOKUP} 442 err := b.DecodeFromBytes(buf, 2) 443 assert.Equal(nil, err) 444 assert.Equal("192.168.50.0", b.Addr.String()) 445 assert.Equal(uint32(10), b.Metric) 446 assert.Equal(uint32(3), b.Nexthops[0].Ifindex) 447 assert.Equal(NEXTHOP_TYPE(4), b.Nexthops[0].Type) 448 assert.Equal("172.16.1.101", b.Nexthops[0].Gate.String()) 449 450 //Serialize 451 b.PrefixLength = uint8(24) 452 buf, err = b.Serialize(2) 453 ip = net.ParseIP("192.168.50.0").To4() 454 assert.Equal(nil, err) 455 assert.Equal(uint8(24), buf[0]) 456 assert.Equal([]byte(ip)[0:4], buf[1:5]) 457 458 // length invalid 459 buf = make([]byte, 3) 460 b = &ImportLookupBody{Api: IPV4_IMPORT_LOOKUP} 461 err = b.DecodeFromBytes(buf, 2) 462 assert.NotEqual(nil, err) 463 } 464 465 func Test_NexthopRegisterBody(t *testing.T) { 466 assert := assert.New(t) 467 468 // Input binary 469 bufIn := []byte{ 470 0x01, 0x00, 0x02, 0x20, // connected(1 byte)=1, afi(2 bytes)=AF_INET, prefix_len(1 byte)=32 471 0xc0, 0xa8, 0x01, 0x01, // prefix(4 bytes)="192.168.1.1" 472 0x00, 0x00, 0x0a, 0x80, // connected(1 byte)=0, afi(2 bytes)=AF_INET6, prefix_len(1 byte)=128 473 0x20, 0x01, 0x0d, 0xb8, // prefix(16 bytes)="2001:db8:1:1::1" 474 0x00, 0x01, 0x00, 0x01, 475 0x00, 0x00, 0x00, 0x00, 476 0x00, 0x00, 0x00, 0x01, 477 } 478 binary.BigEndian.PutUint16(bufIn[1:], syscall.AF_INET) 479 binary.BigEndian.PutUint16(bufIn[9:], syscall.AF_INET6) 480 481 // Test DecodeFromBytes() 482 b := &NexthopRegisterBody{Api: NEXTHOP_REGISTER} 483 err := b.DecodeFromBytes(bufIn, 3) 484 assert.Nil(err) 485 486 // Test decoded values 487 assert.Equal(uint8(1), b.Nexthops[0].Connected) 488 assert.Equal(uint16(syscall.AF_INET), b.Nexthops[0].Family) 489 assert.Equal(net.ParseIP("192.168.1.1").To4(), b.Nexthops[0].Prefix) 490 assert.Equal(uint8(0), b.Nexthops[1].Connected) 491 assert.Equal(uint16(syscall.AF_INET6), b.Nexthops[1].Family) 492 assert.Equal(net.ParseIP("2001:db8:1:1::1").To16(), b.Nexthops[1].Prefix) 493 494 // Test Serialize() 495 bufOut, err := b.Serialize(3) 496 assert.Nil(err) 497 498 // Test serialised value 499 assert.Equal(bufIn, bufOut) 500 } 501 502 func Test_NexthopUpdateBody(t *testing.T) { 503 assert := assert.New(t) 504 505 // Input binary 506 bufIn := []byte{ 507 0x00, 0x02, 0x20, // afi(2 bytes)=AF_INET, prefix_len(1 byte)=32 508 0xc0, 0xa8, 0x01, 0x01, // prefix(4 bytes)="192.168.1.1" 509 0x00, 0x00, 0x00, 0x01, // metric(4 bytes)=1 510 0x01, // nexthops(1 byte)=1 511 0x04, // nexthop_type(1 byte)=NEXTHOP_IPV4_IFINDEX 512 0xc0, 0xa8, 0x01, 0x01, // nexthop_ip(4 bytes)="192.168.0.1" 513 0x00, 0x00, 0x00, 0x02, // nexthop_ifindex(4 byte)=2 514 } 515 516 // Test DecodeFromBytes() 517 b := &NexthopUpdateBody{Api: NEXTHOP_UPDATE} 518 err := b.DecodeFromBytes(bufIn, 2) 519 assert.Nil(err) 520 521 // Test decoded values 522 assert.Equal(uint8(syscall.AF_INET), b.Prefix.Family) 523 assert.Equal(net.ParseIP("192.168.1.1").To4(), b.Prefix.Prefix) 524 assert.Equal(uint32(1), b.Metric) 525 nexthop := Nexthop{ 526 Type: NEXTHOP_TYPE(NEXTHOP_TYPE_IPV4_IFINDEX), 527 Gate: net.ParseIP("192.168.1.1").To4(), 528 Ifindex: uint32(2), 529 } 530 assert.Equal(1, len(b.Nexthops)) 531 assert.Equal(nexthop, b.Nexthops[0]) 532 }