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  }