diff options
author | Artur Makutunowicz <arma@linkedin.com> | 2019-01-17 10:28:23 -0800 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2019-01-26 12:40:45 +0900 |
commit | 192480fc7127ce0f266407cecceb00703807bbca (patch) | |
tree | 7f45576e8a12259db5d3a257180db38849abc932 /pkg/packet/bgp/bgp_test.go | |
parent | 526bd67f5de4cf361aaab2d10456e5113899ca54 (diff) |
Add experimental BGP-LS feature
Diffstat (limited to 'pkg/packet/bgp/bgp_test.go')
-rw-r--r-- | pkg/packet/bgp/bgp_test.go | 1932 |
1 files changed, 1932 insertions, 0 deletions
diff --git a/pkg/packet/bgp/bgp_test.go b/pkg/packet/bgp/bgp_test.go index 6a2d5f12..43bf73a0 100644 --- a/pkg/packet/bgp/bgp_test.go +++ b/pkg/packet/bgp/bgp_test.go @@ -1203,3 +1203,1935 @@ func Test_PathAttributeNextHop(t *testing.T) { f("192.0.2.1") f("2001:db8::68") } + +func Test_LsTLVDecode(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + t LsTLVType + l uint16 + v []byte + err bool + }{ + {[]byte{0x01, 0x09, 0x00, 0x1, 0xef}, LS_TLV_IP_REACH_INFO, 5, []byte{0xef}, false}, + {[]byte{0x01, 0x09, 0x00, 0x0}, LS_TLV_IP_REACH_INFO, 4, []byte{}, false}, + {[]byte{0x01, 0x09, 0x01, 0xff}, LS_TLV_IP_REACH_INFO, 0, []byte{}, true}, + {[]byte{0x01, 0x09, 0x01}, LS_TLV_L2_BUNDLE_MEMBER_TLV, 1, []byte{}, true}, + } + + for _, test := range tests { + tlv := &LsTLV{} + + got, err := tlv.DecodeFromBytes(test.in) + if test.err { + assert.Error(err) + continue + } else { + assert.NoError(err) + } + assert.Equal(tlv.Len(), int(test.l)) + assert.Equal(got, test.v) + } +} + +func Test_LsTLVSerialize(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + tlv LsTLV + val []byte + want []byte + err bool + }{ + {LsTLV{Type: LS_TLV_SID_LABEL_TLV, Length: 2}, []byte{0x11, 0x22}, []byte{0x04, 0x89, 0x00, 0x02, 0x11, 0x22}, false}, + {LsTLV{Type: LS_TLV_SID_LABEL_TLV, Length: 2}, []byte{0x11}, nil, true}, + {LsTLV{Type: LS_TLV_IGP_FLAGS, Length: 0}, []byte{}, []byte{0x04, 0x80, 0x00, 0x00}, false}, + } + + for _, test := range tests { + got, err := test.tlv.Serialize(test.val) + if test.err { + assert.Error(err) + } else { + assert.NoError(err) + } + + assert.Equal(got, test.want) + } +} + +func Test_LsTLVLinkID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x01, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02}, `{"type":258,"local_link_id":1,"remote_link_id":2}`, true, false}, + {[]byte{0x01, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0xFF}, `{"type":258,"local_link_id":1,"remote_link_id":2}`, false, false}, + {[]byte{0x01, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVLinkID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVIPv4InterfaceAddr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x01, 0x03, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01}, `{"type":259,"ipv4_interface_address":"1.1.1.1"}`, true, false}, + {[]byte{0x01, 0x03, 0x00, 0x04, 0x0a, 0x0a, 0x0a, 0x0a, 0x12}, `{"type":259,"ipv4_interface_address":"10.10.10.10"}`, false, false}, + {[]byte{0x01, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIPv4InterfaceAddr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVIPv4NeighborAddr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x01, 0x04, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01}, `{"type":260,"ipv4_neighbor_address":"1.1.1.1"}`, true, false}, + {[]byte{0x01, 0x04, 0x00, 0x04, 0x0a, 0x0a, 0x0a, 0x0a, 0x12}, `{"type":260,"ipv4_neighbor_address":"10.10.10.10"}`, false, false}, + {[]byte{0x01, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIPv4NeighborAddr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVIPv6InterfaceAddr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x01, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, `{"type":261,"ipv6_interface_address":"2001:db8::beef"}`, true, false}, + {[]byte{0x01, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, 0xFF}, `{"type":261,"ipv6_interface_address":"2001:db8::beef"}`, false, false}, + {[]byte{0x01, 0x05, 0x00, 0x10, 0xfe, 0x80, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, "", false, true}, + {[]byte{0x01, 0x05, 0x00, 0x03, 0x00, 0x00, 0x00}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIPv6InterfaceAddr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVIPv6NeighborAddr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x01, 0x06, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, `{"type":262,"ipv6_neighbor_address":"2001:db8::beef"}`, true, false}, + {[]byte{0x01, 0x06, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, 0xFF}, `{"type":262,"ipv6_neighbor_address":"2001:db8::beef"}`, false, false}, + {[]byte{0x01, 0x06, 0x00, 0x10, 0xfe, 0x81, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, "", false, true}, + {[]byte{0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIPv6NeighborAddr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVNodeFlagBits(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x00, 0x00, 0x01, 0xFF}, `{"type":1024,"node_flags":"{Node Flags: XXVRBETO}"}`, false}, + {[]byte{0x04, 0x00, 0x00, 0x01, 0x80}, `{"type":1024,"node_flags":"{Node Flags: *******O}"}`, false}, + {[]byte{0x04, 0x00, 0x00, 0x01, 0x80, 0xAA}, `{"type":1024,"node_flags":"{Node Flags: *******O}"}`, false}, + {[]byte{0x04, 0x00, 0x00, 0x02, 0x80, 0x44}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVNodeFlagBits{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVNodeName(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x02, 0x00, 0x03, 0x72, 0x74, 0x72}, `{"type":1026,"node_name":"rtr"}`, false}, + {[]byte{0x04, 0x02, 0x00, 0x03, 0x72, 0x74, 0x72, 0x00}, `{"type":1026,"node_name":"rtr"}`, false}, + {[]byte{0x04, 0x02, 0x00, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVNodeName{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVIsisArea(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x03, 0x00, 0x03, 0x72, 0x74, 0x72}, `{"type":1027,"isis_area_id":"[114 116 114]"}`, false}, + {[]byte{0x04, 0x03, 0x00, 0x03, 0x72, 0x74, 0x72, 0x44}, `{"type":1027,"isis_area_id":"[114 116 114]"}`, false}, + {[]byte{0x04, 0x03, 0x00, 0x00}, "", true}, + {[]byte{0x04, 0x03, 0x00, 0x0E, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVIsisArea{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVLocalIPv4RouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x04, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01}, `{"type":1028,"node_local_router_id_ipv4":"1.1.1.1"}`, false}, + {[]byte{0x04, 0x04, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01, 0x12}, `{"type":1028,"node_local_router_id_ipv4":"1.1.1.1"}`, false}, + {[]byte{0x04, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVLocalIPv4RouterID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVRemoteIPv4RouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x06, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02}, `{"type":1030,"node_remote_router_id_ipv4":"2.2.2.2"}`, false}, + {[]byte{0x04, 0x06, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x44}, `{"type":1030,"node_remote_router_id_ipv4":"2.2.2.2"}`, false}, + {[]byte{0x04, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVRemoteIPv4RouterID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVLocalIPv6RouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, `{"type":1029,"node_local_router_id_ipv6":"2001:db8::beef"}`, false}, + {[]byte{0x04, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, 0xFF}, `{"type":1029,"node_local_router_id_ipv6":"2001:db8::beef"}`, false}, + {[]byte{0x04, 0x05, 0x00, 0x01, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVLocalIPv6RouterID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVRemoteIPv6RouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x07, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, `{"type":1031,"node_remote_router_id_ipv6":"2001:db8::beef"}`, false}, + {[]byte{0x04, 0x07, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, 0xFF}, `{"type":1031,"node_remote_router_id_ipv6":"2001:db8::beef"}`, false}, + {[]byte{0x04, 0x07, 0x00, 0x01, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVRemoteIPv6RouterID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVOpaqueNodeAttr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x01, 0x00, 0x03, 0x01, 0x02, 0x03}, `{"type":1025,"node_opaque_attribute":"[1 2 3]"}`, false}, + {[]byte{0x04, 0x01, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04}, `{"type":1025,"node_opaque_attribute":"[1 2 3]"}`, false}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVOpaqueNodeAttr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVAutonomousSystem(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07}, `{"type":512,"asn":117901063}`, false}, + {[]byte{0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, 0xFF}, `{"type":512,"asn":117901063}`, false}, + {[]byte{0x02, 0x00, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVAutonomousSystem{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVBgpLsID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07}, `{"type":513,"bgp_ls_id":117901063}`, false}, + {[]byte{0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, 0xFF}, `{"type":513,"bgp_ls_id":117901063}`, false}, + {[]byte{0x02, 0x01, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVBgpLsID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVIgpRouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}, `{"type":515,"igp_router_id":"[1 2 3 4 5 6]"}`, false}, + {[]byte{0x02, 0x03, 0x00, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}, `{"type":515,"igp_router_id":"[1 2 3 4 5 6 7]"}`, false}, + {[]byte{0x02, 0x03, 0x00, 0x08, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, `{"type":515,"igp_router_id":"[1 2 3 4 5 6 7 8]"}`, false}, + {[]byte{0x02, 0x03, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVIgpRouterID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVOspfAreaID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07}, `{"type":514,"ospf_area_id":117901063}`, false}, + {[]byte{0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, 0xFF}, `{"type":514,"ospf_area_id":117901063}`, false}, + {[]byte{0x02, 0x02, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVOspfAreaID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVOspfRouteType(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x01, 0x08, 0x00, 0x01, 0x06}, `{"type":264,"ospf_route_type":"NSSA2"}`, false}, + {[]byte{0x01, 0x08, 0x00, 0x01, 0x01, 0xFF}, `{"type":264,"ospf_route_type":"INTRA-AREA"}`, false}, + {[]byte{0x01, 0x08, 0x00, 0x02, 0x01, 0x01}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVOspfRouteType{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVIPReachability(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x01, 0x09, 0x00, 0x02, 0x08, 0x0a}, `{"type":265,"prefix_length":8,"prefix":"[10]"}`, true, false}, + {[]byte{0x01, 0x09, 0x00, 0x03, 0x10, 0x0a, 0x0b, 0xFF}, `{"type":265,"prefix_length":16,"prefix":"[10 11]"}`, false, false}, + {[]byte{0x01, 0x09, 0x00, 0x02, 0x08}, ``, false, true}, + {[]byte{0x01, 0x09, 0x00, 0x01, 0x01}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIPReachability{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVIPReachabilityToIPNet(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + tlv LsTLVIPReachability + ipv6 bool + want net.IPNet + }{ + { + tlv: LsTLVIPReachability{ + PrefixLength: 8, + Prefix: []byte{0x0a}, + }, + ipv6: false, + want: net.IPNet{ + IP: net.IPv4(10, 0, 0, 0), + Mask: net.CIDRMask(8, 32), + }, + }, + { + tlv: LsTLVIPReachability{ + PrefixLength: 4, + Prefix: []byte{0xaa}, + }, + ipv6: false, + want: net.IPNet{ + IP: net.IPv4(160, 0, 0, 0), + Mask: net.CIDRMask(4, 32), + }, + }, + { + tlv: LsTLVIPReachability{ + PrefixLength: 31, + Prefix: []byte{0x0a, 0x0a, 0x0a, 0xfe}, + }, + ipv6: false, + want: net.IPNet{ + IP: net.IPv4(10, 10, 10, 254), + Mask: net.CIDRMask(31, 32), + }, + }, + { + tlv: LsTLVIPReachability{ + PrefixLength: 16, + Prefix: []byte{0x20, 0x01}, + }, + ipv6: true, + want: net.IPNet{ + IP: net.ParseIP("2001::"), + Mask: net.CIDRMask(16, 128), + }, + }, + { + tlv: LsTLVIPReachability{ + PrefixLength: 24, + Prefix: []byte{0x20, 0x01, 0x0d}, + }, + ipv6: true, + want: net.IPNet{ + IP: net.ParseIP("2001:d00::"), + Mask: net.CIDRMask(24, 128), + }, + }, + } + + for _, test := range tests { + got := test.tlv.ToIPNet(test.ipv6) + assert.Equal(test.want.IP.String(), got.IP.String()) + assert.Equal(test.want.Mask.String(), got.Mask.String()) + } +} + +func Test_LsTLVAdminGroup(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x40, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07}, `{"type":1088,"admin_group":"07070707"}`, false}, + {[]byte{0x04, 0x40, 0x00, 0x04, 0xAE, 0xAE, 0xAE, 0xAE, 0xFF}, `{"type":1088,"admin_group":"aeaeaeae"}`, false}, + {[]byte{0x04, 0x40, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVAdminGroup{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVMaxLinkBw(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x41, 0x00, 0x04, 0x43, 0xA4, 0xB2, 0x00}, `{"type":1089,"max_link_bw":329.39062}`, false}, + {[]byte{0x04, 0x41, 0x00, 0x04, 0x43, 0xA4, 0xB2, 0x00, 0xFF}, `{"type":1089,"max_link_bw":329.39062}`, false}, + {[]byte{0x04, 0x41, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0x04, 0x41, 0x00, 0x04, 0x7f, 0x80, 0x00, 0x00}, "", true}, // +Inf + {[]byte{0x04, 0x41, 0x00, 0x04, 0xff, 0x80, 0x00, 0x00}, "", true}, // -Inf + {[]byte{0x04, 0x41, 0x00, 0x04, 0xff, 0xbf, 0xff, 0xff}, "", true}, // NaN + {[]byte{0x04, 0x41, 0x00, 0x04, 0xc2, 0xc8, 0x00, 0x00}, "", true}, // -100 + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVMaxLinkBw{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVMaxReservableLinkBw(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x42, 0x00, 0x04, 0x43, 0xA4, 0xB2, 0x00}, `{"type":1090,"max_reservable_link_bw":329.39062}`, false}, + {[]byte{0x04, 0x42, 0x00, 0x04, 0x43, 0xA4, 0xB2, 0x00, 0xFF}, `{"type":1090,"max_reservable_link_bw":329.39062}`, false}, + {[]byte{0x04, 0x42, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0x04, 0x42, 0x00, 0x04, 0x7f, 0x80, 0x00, 0x00}, "", true}, // +Inf + {[]byte{0x04, 0x42, 0x00, 0x04, 0xff, 0x80, 0x00, 0x00}, "", true}, // -Inf + {[]byte{0x04, 0x42, 0x00, 0x04, 0xff, 0xbf, 0xff, 0xff}, "", true}, // NaN + {[]byte{0x04, 0x42, 0x00, 0x04, 0xc2, 0xc8, 0x00, 0x00}, "", true}, // -100 + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVMaxReservableLinkBw{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVUnreservedBw(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x43, 0x00, 0x20, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB3, 0x00}, + `{"type":1091,"unreserved_bw":[329.39062,329.39062,329.39062,329.39062,329.39062,329.39062,329.39062,329.39844]}`, false}, + {[]byte{0x04, 0x43, 0x00, 0x20, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, 0xff}, + `{"type":1091,"unreserved_bw":[329.39062,329.39062,329.39062,329.39062,329.39062,329.39062,329.39062,329.39062]}`, false}, + {[]byte{0x04, 0x43, 0x00, 0x20, + 0x7f, 0x80, 0x00, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB3, 0x00}, + "", true}, + {[]byte{0x04, 0x43, 0x00, 0x20, + 0xff, 0x80, 0x00, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB3, 0x00}, + "", true}, + {[]byte{0x04, 0x43, 0x00, 0x20, + 0x43, 0xA4, 0xB3, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0xff, 0xbf, 0xff, 0xff, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB3, 0x00}, + "", true}, + {[]byte{0x04, 0x43, 0x00, 0x20, + 0x43, 0xA4, 0xB3, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB3, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0x43, 0xA4, 0xB2, 0x00, + 0xc2, 0xc8, 0x00, 0x00}, + "", true}, + {[]byte{0x04, 0x43, 0x00, 0x03, 0x07, 0x07, 0x07}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVUnreservedBw{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVTEDefaultMetric(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x04, 0x44, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07}, `{"type":1092,"te_default_metric":117901063}`, true, false}, + {[]byte{0x04, 0x44, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, 0xFF}, `{"type":1092,"te_default_metric":117901063}`, false, false}, + {[]byte{0x04, 0x44, 0x00, 0x03, 0x07, 0x07, 0x07}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVTEDefaultMetric{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + got, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, got) + } + } +} + +func Test_LsTLVIGPMetric(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x04, 0x47, 0x00, 0x01, 0x01}, `{"type":1095,"igp_metric":1}`, true, false}, + {[]byte{0x04, 0x47, 0x00, 0x01, 0x3F}, `{"type":1095,"igp_metric":63}`, true, false}, + {[]byte{0x04, 0x47, 0x00, 0x01, 0xFF}, `{"type":1095,"igp_metric":63}`, false, false}, + {[]byte{0x04, 0x47, 0x00, 0x02, 0x00, 0x01}, `{"type":1095,"igp_metric":1}`, true, false}, + {[]byte{0x04, 0x47, 0x00, 0x02, 0xff, 0xff}, `{"type":1095,"igp_metric":65535}`, true, false}, + {[]byte{0x04, 0x47, 0x00, 0x03, 0x00, 0x00, 0x01}, `{"type":1095,"igp_metric":1}`, true, false}, + {[]byte{0x04, 0x47, 0x00, 0x03, 0xff, 0xff, 0xff}, `{"type":1095,"igp_metric":16777215}`, true, false}, + {[]byte{0x04, 0x47, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIGPMetric{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + got, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, got) + } + } +} + +func Test_LsTLVNLinkName(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x4a, 0x00, 0x03, 0x72, 0x74, 0x72}, `{"type":1098,"link_name":"rtr"}`, false}, + {[]byte{0x04, 0x4a, 0x00, 0x03, 0x72, 0x74, 0x72, 0x00}, `{"type":1098,"link_name":"rtr"}`, false}, + {[]byte{0x04, 0x4a, 0x00, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVLinkName{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVSrAlgorithm(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x0b, 0x00, 0x03, 0x01, 0x02, 0x03}, `{"type":1035,"sr_algorithm":"[1 2 3]"}`, false}, + {[]byte{0x04, 0x0b, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04}, `{"type":1035,"sr_algorithm":"[1 2 3]"}`, false}, + {[]byte{0x04, 0x0b, 0x00, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVSrAlgorithm{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVSrCapabilities(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + { + []byte{ + 0x04, 0x0a, 0x00, 0x0c, // type 1034, length 12 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + }, + `{"type":1034,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":100500}}]}`, + true, + false, + }, + { + []byte{ + 0x04, 0x0a, 0x00, 0x0d, // type 1034, length 13 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + }, + `{"type":1034,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":71005001}}]}`, + true, + false, + }, + { + []byte{ + 0x04, 0x0a, 0x00, 0x17, // type 1034, length 23 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + 0x0f, 0x42, 0x40, // range: 1000000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + }, + `{"type":1034,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":71005001}},{"Range":1000000,"FirstLabel":{"type":1161,"sid_label":100500}}]}`, + true, + false, + }, + { + []byte{ + 0x04, 0x0a, 0x00, 0x17, // type 1034, length 23 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + 0x0f, 0x42, 0x40, // range: 1000000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + 0xff, 0xff, 0xff, // some random bytes - should be ignored + }, + `{"type":1034,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":71005001}},{"Range":1000000,"FirstLabel":{"type":1161,"sid_label":100500}}]}`, + false, + false, + }, + { + []byte{ + 0x04, 0x0a, 0x00, 0xcc, // type 1034, length 204 (corrupted) + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + }, + "", + false, + true, + }, + { + []byte{ + 0x04, 0x0a, 0x00, 0x11, // type 1034, length 23 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + 0x0f, 0x42, 0x40, // range: 1000000 + 0x04, // No SID/Label sub-TLV + }, + "", + false, + true, + }, + } + + for _, test := range tests { + tlv := LsTLVSrCapabilities{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVLocalBlock(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + { + []byte{ + 0x04, 0x0c, 0x00, 0x0c, // type 1036, length 12 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + }, + `{"type":1036,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":100500}}]}`, + true, + false, + }, + { + []byte{ + 0x04, 0x0c, 0x00, 0x0d, // type 1036, length 13 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + }, + `{"type":1036,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":71005001}}]}`, + true, + false, + }, + { + []byte{ + 0x04, 0x0c, 0x00, 0x17, // type 1036, length 23 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + 0x0f, 0x42, 0x40, // range: 1000000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + }, + `{"type":1036,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":71005001}},{"Range":1000000,"FirstLabel":{"type":1161,"sid_label":100500}}]}`, + true, + false, + }, + { + []byte{ + 0x04, 0x0c, 0x00, 0x17, // type 1036, length 23 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + 0x0f, 0x42, 0x40, // range: 1000000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + 0xff, 0xff, 0xff, // some random bytes - should be ignored + }, + `{"type":1036,"flags":0,"ranges":[{"Range":35000,"FirstLabel":{"type":1161,"sid_label":71005001}},{"Range":1000000,"FirstLabel":{"type":1161,"sid_label":100500}}]}`, + false, + false, + }, + { + []byte{ + 0x04, 0x0c, 0x00, 0xcc, // type 1036, length 204 (corrupted) + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // SID/Label TLV, SID: 100500 + }, + "", + false, + true, + }, + { + []byte{ + 0x04, 0x0c, 0x00, 0x11, // type 1036, length 23 + 0x00, 0x00, // flags and reserved + 0x00, 0x88, 0xb8, // range: 35000 + 0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49, // SID/Label TLV, SID: 71005001 + 0x0f, 0x42, 0x40, // range: 1000000 + 0x04, // No SID/Label sub-TLV + }, + "", + false, + true, + }, + } + + for _, test := range tests { + tlv := LsTLVSrLocalBlock{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVAdjacencySID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x04, 0x4b, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x01, 0x88, 0x94}, `{"type":1099,"adjacency_sid":100500}`, true, false}, + {[]byte{0x04, 0x4b, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff}, `{"type":1099,"adjacency_sid":1048575}`, false, false}, + {[]byte{0x04, 0x4b, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x04, 0x3B, 0x73, 0x49}, `{"type":1099,"adjacency_sid":71005001}`, true, false}, + {[]byte{0x04, 0x4b, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x07, 0x04, 0x3B, 0x73, 0x49, 0x05, 0x06, 0x07}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVAdjacencySID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVSIDLabel(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94}, `{"type":1161,"sid_label":100500}`, true, false}, + {[]byte{0x04, 0x89, 0x00, 0x03, 0x0f, 0xff, 0xff}, `{"type":1161,"sid_label":1048575}`, true, false}, + {[]byte{0x04, 0x89, 0x00, 0x03, 0xff, 0xff, 0xff}, `{"type":1161,"sid_label":1048575}`, false, false}, + {[]byte{0x04, 0x89, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49}, `{"type":1161,"sid_label":71005001}`, false, false}, + {[]byte{0x04, 0x89, 0x00, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x04, 0x04, 0x3B, 0x73, 0x49}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVSIDLabel{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVPrefixSID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x04, 0x86, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x01, 0x88, 0x94}, `{"type":1158,"prefix_sid":100500}`, true, false}, + {[]byte{0x04, 0x86, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff}, `{"type":1158,"prefix_sid":1048575}`, false, false}, + {[]byte{0x04, 0x86, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x04, 0x3B, 0x73, 0x49}, `{"type":1158,"prefix_sid":71005001}`, true, false}, + {[]byte{0x04, 0x86, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x07, 0x04, 0x3B, 0x73, 0x49, 0x05, 0x06, 0x07}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVPrefixSID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + + if test.serialize { + s, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, s) + } + } +} + +func Test_LsTLVSourceRouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x93, 0x00, 0x04, 0x0a, 0x0a, 0x0a, 0x0a}, `{"type":1171,"source_router_id":"10.10.10.10"}`, false}, + {[]byte{0x04, 0x93, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF}, `{"type":1171,"source_router_id":"2001:db8::beef"}`, false}, + {[]byte{0x04, 0x93, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, 0xFF}, `{"type":1171,"source_router_id":"2001:db8::beef"}`, false}, + {[]byte{0x04, 0x93, 0x00, 0x01, 0x00}, "", true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVSourceRouterID{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVOpaqueLinkAttr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x49, 0x00, 0x03, 0x01, 0x02, 0x03}, `{"type":1097,"link_opaque_attribute":"[1 2 3]"}`, false}, + {[]byte{0x04, 0x49, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04}, `{"type":1097,"link_opaque_attribute":"[1 2 3]"}`, false}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVOpaqueLinkAttr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_LsTLVIGPFlags(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + serialize bool + err bool + }{ + {[]byte{0x04, 0x80, 0x00, 0x01, 0xFF}, `{"type":1152,"igp_flags":"{IGP Flags: XXXXPLND}"}`, true, false}, + {[]byte{0x04, 0x80, 0x00, 0x01, 0x80}, `{"type":1152,"igp_flags":"{IGP Flags: *******D}"}`, true, false}, + {[]byte{0x04, 0x80, 0x00, 0x01, 0x80, 0xAA}, `{"type":1152,"igp_flags":"{IGP Flags: *******D}"}`, false, false}, + {[]byte{0x04, 0x80, 0x00, 0x02, 0x80, 0x44}, "", false, true}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", false, true}, + } + + for _, test := range tests { + tlv := LsTLVIGPFlags{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + if test.serialize { + got, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, got) + } + } + } +} + +func Test_LsTLVOpaquePrefixAttr(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + want string + err bool + }{ + {[]byte{0x04, 0x85, 0x00, 0x03, 0x01, 0x02, 0x03}, `{"type":1157,"prefix_opaque_attribute":"[1 2 3]"}`, false}, + {[]byte{0x04, 0x85, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04}, `{"type":1157,"prefix_opaque_attribute":"[1 2 3]"}`, false}, + {[]byte{0xfe, 0xfe, 0x00, 0x00}, "", true}, + } + + for _, test := range tests { + tlv := LsTLVOpaquePrefixAttr{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + continue + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + } + + got, err := tlv.MarshalJSON() + assert.NoError(err) + assert.Equal(got, []byte(test.want)) + } +} + +func Test_parseIGPRouterID(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + str string + pseudo bool + }{ + {[]byte{1, 2, 3, 4}, "1.2.3.4", false}, + {[]byte{1, 2, 3, 4, 5, 255}, "0102.0304.05ff", false}, + {[]byte{1, 2, 3, 4, 5, 255, 0}, "0102.0304.05ff-00", true}, + {[]byte{1, 2, 3, 4, 5, 6, 7, 8}, "1.2.3.4:5.6.7.8", true}, + } + + for _, test := range tests { + str, pseudo := parseIGPRouterID(test.in) + assert.Equal(test.str, str) + assert.Equal(test.pseudo, pseudo) + } +} + +func Test_LsNodeDescriptor(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + str string + err bool + serialize bool + }{ + {[]byte{ + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "{ASN: 117901063, BGP LS ID: 117901063, OSPF AREA: 117901063, IGP ROUTER ID: 0102.0304.0506}", + false, true}, + {[]byte{ + 0x01, 0x01, 0x00, 0x22, // Remote Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "{ASN: 117901063, BGP LS ID: 117901063, OSPF AREA: 117901063, IGP ROUTER ID: 0102.0304.0506}", + false, true}, + {[]byte{ + 0x01, 0x00, 0x00, 0x21, // Truncated Length + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "", true, false}, + {[]byte{ + 0x01, 0x00, 0x00, 0x22, // Missing mandatory TLV + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + }, "", true, false}, + {[]byte{ + 0x01, 0x00, 0x00, 0x22, // Incorrect TLV order + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "", true, false}, + {[]byte{ + 0x01, 0x00, 0x00, 0x26, // Unexpected TLV + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0xfe, 0x01, 0x00, 0x00, // Unsupported + }, "{ASN: 117901063, BGP LS ID: 117901063, OSPF AREA: 117901063, IGP ROUTER ID: 0102.0304.0506}", + false, false}, + {[]byte{ + 0x01, 0x00, 0x00, 0x0a, // Missing optional TLVs + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "{ASN: 0, BGP LS ID: 0, OSPF AREA: 0, IGP ROUTER ID: 0102.0304.0506}", false, true}, + } + + for _, test := range tests { + tlv := LsTLVNodeDescriptor{} + if test.err { + assert.Error(tlv.DecodeFromBytes(test.in)) + } else { + assert.NoError(tlv.DecodeFromBytes(test.in)) + assert.Equal(test.str, tlv.String()) + if test.serialize { + got, err := tlv.Serialize() + assert.NoError(err) + assert.Equal(test.in, got) + } + } + } +} + +func Test_LsAddrPrefix(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + str string + err bool + serialize bool + }{ + {[]byte{ + 0x00, 0x01, 0x00, 0x2f, // Node NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "NLRI { NODE { AS:117901063 BGP-LS ID:117901063 0102.0304.0506 ISIS-L2:0 } }", false, true}, + {[]byte{ + 0x00, 0x01, 0x00, 0x2e, // Node NLRI, truncated length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, // TLV IGP Router ID: 0102.0304.05 + }, "", true, false}, + {[]byte{ + 0x00, 0x01, 0x00, 0x2f, // Node NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x01, 0x00, 0x22, // Remote Node Desc (unexpected) + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + }, "", true, false}, + {[]byte{ + 0x00, 0x01, 0x00, 0x2d, // Node NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + // Mandatory TLV missing + }, "", true, false}, + {[]byte{ + 0x00, 0x02, 0x00, 0x65, // Link NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x01, 0x00, 0x22, // Remote Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, // TLV IGP Router ID: 0605.0403.0201 + 0x01, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, // LinkID TLV, Local: 1, Remote: 2 + }, "NLRI { LINK { LOCAL_NODE: 0102.0304.0506 REMOTE_NODE: 0605.0403.0201 LINK: 1->2} }", false, true}, + {[]byte{ + 0x00, 0x02, 0x00, 0x69, // Link NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x01, 0x00, 0x22, // Remote Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, // TLV IGP Router ID: 0605.0403.0201 + 0x01, 0x03, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01, // IPv4 Interface Addr TLV: 1.1.1.1 + 0x01, 0x04, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, // IPv4 Neighbor Addr TLV: 2.2.2.2 + }, "NLRI { LINK { LOCAL_NODE: 0102.0304.0506 REMOTE_NODE: 0605.0403.0201 LINK: 1.1.1.1->2.2.2.2} }", false, true}, + {[]byte{ + 0x00, 0x02, 0x00, 0x81, // Link NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x01, 0x00, 0x22, // Remote Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, // TLV IGP Router ID: 0605.0403.0201 + 0x01, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, // IPv6 Interface Addr TLV: 2001:db8::beef + 0x01, 0x06, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, // IPv6 Interface Addr TLV: 2001:db8::dead + }, "NLRI { LINK { LOCAL_NODE: 0102.0304.0506 REMOTE_NODE: 0605.0403.0201 LINK: 2001:db8::beef->2001:db8::dead} }", false, true}, + {[]byte{ + 0x00, 0x02, 0x00, 0x59, // Link NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x01, 0x00, 0x22, // Remote Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, // TLV IGP Router ID: 0605.0403.0201 + }, "NLRI { LINK { LOCAL_NODE: 0102.0304.0506 REMOTE_NODE: 0605.0403.0201 LINK: UNKNOWN} }", false, true}, + {[]byte{ + 0x00, 0x02, 0x00, 0x33, // Link NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + // Missing mandatory TLV + }, "", true, false}, + {[]byte{ + 0x00, 0x03, 0x00, 0x35, // Prefix IPv4 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x09, 0x00, 0x02, 0x08, 0x0a, // IP ReachabilityInfo TLV, 10.0.0.0/8 + }, "NLRI { PREFIXv4 { LOCAL_NODE: 0102.0304.0506 PREFIX: [10.0.0.0/8] } }", false, true}, + {[]byte{ + 0x00, 0x03, 0x00, 0x43, // Prefix IPv4 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x09, 0x00, 0x02, 0x08, 0x0a, // IP ReachabilityInfo TLV, 10.0.0.0/8 + 0x01, 0x09, 0x00, 0x05, 0x1f, 0xc0, 0xa8, 0x07, 0xfe, // IP ReachabilityInfo TLV, 192.168.7.254/31 + 0x01, 0x08, 0x00, 0x01, 0x06, // OSPF Route Type TLV (NSSA2) + }, "NLRI { PREFIXv4 { LOCAL_NODE: 0102.0304.0506 PREFIX: [10.0.0.0/8 192.168.7.254/31] OSPF_ROUTE_TYPE:NSSA2 } }", false, true}, + {[]byte{ + 0x00, 0x03, 0x00, 0x35, // Prefix IPv4 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x09, 0x00, 0x02, 0x08, 0x0a, // IP ReachabilityInfo TLV, 10.0.0.0/8 + }, "NLRI { PREFIXv4 { LOCAL_NODE: 0102.0304.0506 PREFIX: [10.0.0.0/8] } }", false, true}, + {[]byte{ + 0x00, 0x03, 0x00, 0x2f, // Prefix IPv4 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + // Missing mandatory TLV (IP Reachability info) + }, "", true, false}, + {[]byte{ + 0x00, 0x03, 0x00, 0x39, // Prefix IPv4 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + // IPv6 IP Reachability info in v4 prefix + 0x01, 0x09, 0x00, 0x06, 0x40, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + }, "", true, false}, + {[]byte{ + 0x00, 0x04, 0x00, 0x35, // Prefix IPv6 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x09, 0x00, 0x02, 0x08, 0x0a, // IP ReachabilityInfo TLV, 10.0.0.0/8 + }, "NLRI { PREFIXv6 { LOCAL_NODE: 0102.0304.0506 PREFIX: [a00::/8] } }", false, true}, + {[]byte{ + 0x00, 0x04, 0x00, 0x43, // Prefix IPv6 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x09, 0x00, 0x02, 0x08, 0x0a, // IP ReachabilityInfo TLV, 10.0.0.0/8 + 0x01, 0x09, 0x00, 0x05, 0x1f, 0xc0, 0xa8, 0x07, 0xfe, // IP ReachabilityInfo TLV, 192.168.7.254/31 + 0x01, 0x08, 0x00, 0x01, 0x06, // OSPF Route Type TLV (NSSA2) + }, "NLRI { PREFIXv6 { LOCAL_NODE: 0102.0304.0506 PREFIX: [a00::/8 c0a8:7fe::/31] OSPF_ROUTE_TYPE:NSSA2 } }", false, true}, + {[]byte{ + 0x00, 0x04, 0x00, 0x35, // Prefix IPv6 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + 0x01, 0x09, 0x00, 0x02, 0x08, 0x0a, // IP ReachabilityInfo TLV, 10.0.0.0/8 + }, "NLRI { PREFIXv6 { LOCAL_NODE: 0102.0304.0506 PREFIX: [a00::/8] } }", false, true}, + {[]byte{ + 0x00, 0x04, 0x00, 0x2f, // Prefix IPv6 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + // Missing mandatory TLV (IP Reachability info) + }, "", true, false}, + {[]byte{ + 0x00, 0x04, 0x00, 0x39, // Prefix IPv6 NLRI, correct length + 0x02, // Protocol ISIS Level 2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ID + 0x01, 0x00, 0x00, 0x22, // Local Node Desc + 0x02, 0x00, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV ASN: 117901063 + 0x02, 0x01, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV BGP LS ID: 117901063 + 0x02, 0x02, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TLV OSPF Area ID: 117901063 + 0x02, 0x03, 0x00, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // TLV IGP Router ID: 0102.0304.0506 + // IPv6 IP Reachability info in v4 prefix + 0x01, 0x09, 0x00, 0x06, 0x40, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, + }, "", true, false}, + } + + for _, test := range tests { + nlri := LsAddrPrefix{} + if test.err { + assert.Error(nlri.DecodeFromBytes(test.in)) + } else { + assert.NoError(nlri.DecodeFromBytes(test.in)) + assert.Equal(test.str, nlri.String()) + if test.serialize { + got, err := nlri.Serialize() + assert.NoError(err) + assert.Equal(test.in, got) + } + } + } +} + +func Test_PathAttributeLs(t *testing.T) { + assert := assert.New(t) + + var tests = []struct { + in []byte + str string + json string + serialize bool + err bool + }{ + {[]byte{ + // LS Attribute with all Node-related TLVs. + 0x80, 0x29, 0x62, // Optional attribute, BGP_ATTR_TYPE_LS, correct length + 0x04, 0x00, 0x00, 0x01, 0xFF, // Node flags (all set) + 0x04, 0x01, 0x00, 0x03, 0x01, 0x02, 0x03, // Opaque Node Attr [1 2 3] + 0x04, 0x02, 0x00, 0x03, 0x72, 0x74, 0x72, // Node name: "rtr" + 0x04, 0x03, 0x00, 0x03, 0x72, 0x74, 0x72, // ISIS area: [114 116 114] + 0x04, 0x04, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01, // Local RouterID 1.1.1.1 + 0x04, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, // Local Router ID 2001:db8::beef + 0x04, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x88, 0xb8, 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // Capabilities: Range 35000, first label: 100500 + 0x04, 0x0b, 0x00, 0x03, 0x01, 0x02, 0x03, // SR ALgorithm [1 2 3] + 0x04, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x88, 0xb8, 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // Local block: Range 35000, first label: 100500 + 0xde, 0xad, 0x00, 0x01, 0xFF, // Unknown TLV + }, + "{LsAttributes: {Node Flags: XXVRBETO} {Opaque attribute: [1 2 3]} {Node Name: rtr} {ISIS Area ID: [114 116 114]} {Local RouterID IPv4: 1.1.1.1} {Local RouterID IPv6: 2001:db8::beef} {SR Capabilities: Flags:0 SRGB Ranges: 100500:135500 } {SR Algorithms: [1 2 3]} {SR LocalBlock: Flags:0 SRGB Ranges: 100500:135500 } }", + `{"type":41,"flags":128,"node":{"flags":{"overload":true,"attached":true,"external":true,"abr":true,"router":true,"v6":true},"opaque":"AQID","name":"rtr","isis_area":"cnRy","local_router_id_ipv4":"1.1.1.1","local_router_id_ipv6":"2001:db8::beef","sr_capabilities":{"ipv4_supported":false,"ipv6_supported":false,"ranges":[{"begin":100500,"end":135500}]},"sr_algorithms":"AQID","sr_local_block":{"ranges":[{"begin":100500,"end":135500}]}},"link":{"local_router_id_ipv4":"1.1.1.1","local_router_id_ipv6":"2001:db8::beef"},"prefix":{}}`, + false, false}, + {[]byte{ + // LS Attribute with all Node-related TLVs. + 0x80, 0x29, 0x5d, // Optional attribute, BGP_ATTR_TYPE_LS, correct length + 0x04, 0x00, 0x00, 0x01, 0xFF, // Node flags (all set) + 0x04, 0x01, 0x00, 0x03, 0x01, 0x02, 0x03, // Opaque Node Attr [1 2 3] + 0x04, 0x02, 0x00, 0x03, 0x72, 0x74, 0x72, // Node name: "rtr" + 0x04, 0x03, 0x00, 0x03, 0x72, 0x74, 0x72, // ISIS area: [114 116 114] + 0x04, 0x04, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01, // Local RouterID 1.1.1.1 + 0x04, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, // Local Router ID 2001:db8::beef + 0x04, 0x0a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x88, 0xb8, 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // Capabilities: Range 35000, first label: 100500 + 0x04, 0x0b, 0x00, 0x03, 0x01, 0x02, 0x03, // SR Algorithm [1 2 3] + 0x04, 0x0c, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x88, 0xb8, 0x04, 0x89, 0x00, 0x03, 0x01, 0x88, 0x94, // Local block: Range 35000, first label: 100500 + }, + "{LsAttributes: {Node Flags: XXVRBETO} {Opaque attribute: [1 2 3]} {Node Name: rtr} {ISIS Area ID: [114 116 114]} {Local RouterID IPv4: 1.1.1.1} {Local RouterID IPv6: 2001:db8::beef} {SR Capabilities: Flags:0 SRGB Ranges: 100500:135500 } {SR Algorithms: [1 2 3]} {SR LocalBlock: Flags:0 SRGB Ranges: 100500:135500 } }", + `{"type":41,"flags":128,"node":{"flags":{"overload":true,"attached":true,"external":true,"abr":true,"router":true,"v6":true},"opaque":"AQID","name":"rtr","isis_area":"cnRy","local_router_id_ipv4":"1.1.1.1","local_router_id_ipv6":"2001:db8::beef","sr_capabilities":{"ipv4_supported":false,"ipv6_supported":false,"ranges":[{"begin":100500,"end":135500}]},"sr_algorithms":"AQID","sr_local_block":{"ranges":[{"begin":100500,"end":135500}]}},"link":{"local_router_id_ipv4":"1.1.1.1","local_router_id_ipv6":"2001:db8::beef"},"prefix":{}}`, + true, false}, + {[]byte{ + // LS Attribute with truncated length + 0x80, 0x29, 0x04, // Optional attribute, BGP_ATTR_TYPE_LS, truncated length + 0x04, 0x00, 0x00, 0x01, 0xFF, // Node flags (all set) + }, "", "", false, true}, + {[]byte{ + // LS Attribute with all Link-related TLVs. + 0x80, 0x29, 0x9a, // Optional attribute, BGP_ATTR_TYPE_LS, correct length + 0x04, 0x04, 0x00, 0x04, 0x01, 0x01, 0x01, 0x01, // Local RouterID 1.1.1.1 + 0x04, 0x05, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xEF, // Local Router ID 2001:db8::beef + 0x04, 0x06, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, // Local RouterID 2.2.2.2 + 0x04, 0x07, 0x00, 0x10, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xAD, // Local Router ID 2001:db8::dead + 0x04, 0x40, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // Admin Group 0x07070707 + 0x04, 0x41, 0x00, 0x04, 0x43, 0xA4, 0xB2, 0x00, // Max Link Bandwidth 329.39062 + 0x04, 0x42, 0x00, 0x04, 0x43, 0xA4, 0xB2, 0x00, // Max Reservable Bandwidth 329.39062 + 0x04, 0x43, 0x00, 0x20, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, 0x43, 0xA4, 0xB2, 0x00, // Unreserved Bandwidth 329.39062 + 0x04, 0x44, 0x00, 0x04, 0x07, 0x07, 0x07, 0x07, // TE Default Metric: 117901063 + 0x04, 0x47, 0x00, 0x01, 0x01, // IGP Metric 1 + 0x04, 0x49, 0x00, 0x03, 0x01, 0x02, 0x03, // Opaque Link Attr: [1 2 3] + 0x04, 0x4a, 0x00, 0x03, 0x72, 0x74, 0x72, // Link Name: "rtr" + 0x04, 0x4b, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x01, 0x88, 0x94, // Adjacency SID: 100500 + }, + "{LsAttributes: {Local RouterID IPv4: 1.1.1.1} {Local RouterID IPv6: 2001:db8::beef} {Remote RouterID IPv4: 2.2.2.2} {Remote RouterID IPv6: 2001:db8::dead} {Admin Group: 07070707} {Max Link BW: 329.39062} {Max Reservable Link BW: 329.39062} {Unreserved BW: [329.39062 329.39062 329.39062 329.39062 329.39062 329.39062 329.39062 329.39062]} {TE Default metric: 117901063} {IGP metric: 1} {Opaque link attribute: [1 2 3]} {Link Name: rtr} {Adjacency SID: 100500} }", + `{"type":41,"flags":128,"node":{"local_router_id_ipv4":"1.1.1.1","local_router_id_ipv6":"2001:db8::beef"},"link":{"name":"rtr","local_router_id_ipv4":"1.1.1.1","local_router_id_ipv6":"2001:db8::beef","remote_router_id_ipv4":"2.2.2.2","remote_router_id_ipv6":"2001:db8::dead","admin_group":117901063,"default_te_metric":117901063,"igp_metric":1,"opaque":"AQID","bandwidth":329.39062,"reservable_bandwidth":329.39062,"unreserved_bandwidth":[329.39062,329.39062,329.39062,329.39062,329.39062,329.39062,329.39062,329.39062],"adjacency_sid":100500},"prefix":{}}`, + true, false}, + {[]byte{ + // LS Attribute with all Link-related TLVs. + 0x80, 0x29, 0x17, // Optional attribute, BGP_ATTR_TYPE_LS, correct length + 0x04, 0x80, 0x00, 0x01, 0xFF, // IGP Flags: PLND + 0x04, 0x85, 0x00, 0x03, 0x01, 0x02, 0x03, // Opaque prefix: [1 2 3] + 0x04, 0x86, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00, 0x01, 0x88, 0x94, // Prefix SID: 100500 + }, + "{LsAttributes: {IGP Flags: XXXXPLND} {Prefix opaque attribute: [1 2 3]} {Prefix SID: 100500} }", + `{"type":41,"flags":128,"node":{},"link":{},"prefix":{"igp_flags":{"down":true,"no_unicast":true,"local_address":true,"propagate_nssa":true},"opaque":"AQID","sr_prefix_sid":100500}}`, + true, false}, + } + + for _, test := range tests { + attr := PathAttributeLs{} + if test.err { + assert.Error(attr.DecodeFromBytes(test.in)) + } else { + assert.NoError(attr.DecodeFromBytes(test.in)) + got, err := attr.MarshalJSON() + assert.NoError(err) + assert.Equal(test.json, string(got)) + assert.Equal(test.str, attr.String()) + + if test.serialize { + got, err := attr.Serialize() + assert.NoError(err) + assert.Equal(test.in, got) + } + } + } +} |