1 // Copyright (c) 2020 Cisco and/or its affiliates.
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:
7 // http://www.apache.org/licenses/LICENSE-2.0
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 implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
23 "github.com/lunixbochs/struc"
25 "git.fd.io/govpp.git/api"
26 "git.fd.io/govpp.git/codec"
27 "git.fd.io/govpp.git/examples/binapi/fib_types"
28 "git.fd.io/govpp.git/examples/binapi/interface_types"
29 "git.fd.io/govpp.git/examples/binapi/interfaces"
30 "git.fd.io/govpp.git/examples/binapi/ip"
31 "git.fd.io/govpp.git/examples/binapi/ip_types"
32 "git.fd.io/govpp.git/examples/binapi/sr"
35 /*func TestNewCodecEncodeDecode(t *testing.T) {
44 AliasArray: MacAddress{0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
45 BaseArray: []uint32{0x00, 0x00, 0x00, 0x00},
46 Enum: IF_STATUS_API_FLAG_LINK_UP,
53 Slice: []byte{10, 20, 30, 40, 0, 0, 0},
54 String: "abcdefghikl",
56 VariableSlice: []SliceType{
57 {Proto: IP_API_PROTO_AH},
58 {Proto: IP_API_PROTO_ESP},
62 Un: AddressUnionIP4(IP4Address{1, 2, 3, 4}),
67 for _, test := range tests {
68 t.Run(test.name, func(t *testing.T) {
69 data, err := test.msg.Marshal()
71 t.Fatalf("expected nil error, got: %v", err)
75 if err := m2.Unmarshal(data); err != nil {
76 t.Fatalf("expected nil error, got: %v", err)
79 t.Logf("Data:\nOLD: %+v\nNEW: %+v", m, &m2)
81 if !reflect.DeepEqual(m, &m2) {
82 t.Fatalf("newData differs from oldData")
88 func NewTestAllMsg() *TestAllMsg {
92 AliasArray: MacAddress{0x11, 0x22, 0x33, 0x44, 0x55, 0x66},
93 BaseArray: []uint32{0x00, 0x00, 0x00, 0x00},
94 Enum: IF_STATUS_API_FLAG_LINK_UP,
101 Slice: []byte{10, 20, 30, 40, 0, 0, 0},
102 String: "abcdefghikl",
104 VariableSlice: []SliceType{
105 {Proto: IP_API_PROTO_AH},
106 {Proto: IP_API_PROTO_ESP},
110 Un: AddressUnionIP4(IP4Address{1, 2, 3, 4}),
115 func TestNewCodecEncodeDecode_(t *testing.T) {
118 data, err := m.Marshal(nil)
120 t.Fatalf("expected nil error, got: %v", err)
124 if err := m2.Unmarshal(data); err != nil {
125 t.Fatalf("expected nil error, got: %v", err)
128 t.Logf("Data:\nOLD: %+v\nNEW: %+v", m, &m2)
130 if !reflect.DeepEqual(m, &m2) {
131 t.Fatalf("newData differs from oldData")
137 func TestNewCodecEncodeDecode3(t *testing.T) {
139 data, err := m.Marshal(nil)
141 t.Fatalf("expected nil error, got: %v", err)
145 if err := m2.Unmarshal(data); err != nil {
146 t.Fatalf("expected nil error, got: %v", err)
149 t.Logf("Data:\nOLD: %+v\nNEW: %+v", m, &m2)
151 if !reflect.DeepEqual(m, &m2) {
152 t.Fatalf("newData differs from oldData")
155 func TestNewCodecEncodeDecode4(t *testing.T) {
156 m := &interfaces.SwInterfaceSetRxMode{
157 Mode: interface_types.RX_MODE_API_POLLING,
163 b := make([]byte, 2+m.Size())
165 data, err := m.Marshal(b[2:])
167 t.Fatalf("expected nil error, got: %v", err)
170 t.Logf("ENCODED DATA(%d): % 03x", len(data), data)
172 var m2 interfaces.SwInterfaceSetRxMode
173 if err := m2.Unmarshal(b[2:]); err != nil {
174 t.Fatalf("expected nil error, got: %v", err)
177 t.Logf("Data:\nOLD: %+v\nNEW: %+v", m, &m2)
179 if !reflect.DeepEqual(m, &m2) {
180 t.Fatalf("newData differs from oldData")
183 func TestNewCodecEncodeDecode2(t *testing.T) {
184 m := &sr.SrPoliciesDetails{
185 Bsid: sr.IP6Address{00, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
190 SidLists: []sr.Srv6SidList{
194 Sids: [16]sr.IP6Address{
196 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
202 b := make([]byte, 0, m.Size())
203 data, err := m.Marshal(b)
205 t.Fatalf("expected nil error, got: %v", err)
208 t.Logf("ENCODED DATA(%d): % 03x", len(data), data)
210 var m2 sr.SrPoliciesDetails
211 if err := m2.Unmarshal(data); err != nil {
212 t.Fatalf("expected nil error, got: %v", err)
215 t.Logf("Data:\nOLD: %+v\nNEW: %+v", m, &m2)
217 if !reflect.DeepEqual(m, &m2) {
218 t.Fatalf("newData differs from oldData")
222 func TestNewCodecEncode(t *testing.T) {
223 //m := NewIPRouteLookupReply()
224 m := &sr.SrPoliciesDetails{
225 Bsid: sr.IP6Address{00, 11, 22, 33, 44, 55, 66, 77, 88, 99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
230 SidLists: []sr.Srv6SidList{
234 Sids: [16]sr.IP6Address{
236 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},
243 t.Logf("size: %d", size)
246 var oldData, newData []byte
249 oldData, err = c.Marshal(m)
251 t.Fatalf("expected nil error, got: %v", err)
255 newData, err = m.Marshal(nil)
257 t.Fatalf("expected nil error, got: %v", err)
260 t.Logf("Data:\nOLD[%d]: % 03x\nNEW[%d]: % 03x", len(oldData), oldData, len(newData), newData)
262 if !bytes.Equal(oldData, newData) {
263 t.Fatalf("newData differs from oldData")
267 func TestNewCodecDecode(t *testing.T) {
268 /*m := &ip.IPRouteLookupReply{}
270 t.Logf("size: %d", size)*/
272 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
273 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00,
276 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00,
277 0x00, 0x00, 0x08, 0x09, 0x0a, 0x00, 0x00, 0x00,
278 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
279 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
282 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x09, 0x00,
283 0x00, 0x00, 0x08, 0x07, 0x06, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 var oldData, newData ip.IPRouteLookupReply
303 err = c.Unmarshal(data, &oldData)
305 t.Errorf("expected nil error, got: %v", err)
309 err = newData.Unmarshal(data)
311 t.Errorf("expected nil error, got: %v", err)
314 t.Logf("Data:\nOLD: %+v\nNEW: %+v", oldData, newData)
316 if !reflect.DeepEqual(oldData, newData) {
317 t.Fatalf("newData differs from oldData")
321 func NewIPRouteLookupReply() *ip.IPRouteLookupReply {
322 return &ip.IPRouteLookupReply{
328 Address: ip_types.Address{
329 Af: fib_types.ADDRESS_IP6,
330 Un: ip_types.AddressUnion{},
346 Address: ip.AddressUnion{},
349 ClassifyTableIndex: 2,
352 LabelStack: [16]ip.FibMplsLabel{
371 Address: ip.AddressUnion{},
374 ClassifyTableIndex: 2,
377 LabelStack: [16]ip.FibMplsLabel{
397 func TestSize(t *testing.T) {
399 size := binary.Size(*m)
400 t.Logf("size: %v", size)
403 func (m *TestAllMsg) Marshal(b []byte) ([]byte, error) {
404 order := binary.BigEndian
405 tmp := make([]byte, 143)
408 tmp[pos] = boolToUint(m.Bool)
414 order.PutUint16(tmp[pos:pos+2], m.Uint16)
417 order.PutUint32(tmp[pos:pos+4], m.Uint32)
420 tmp[pos] = byte(m.Int8)
423 order.PutUint16(tmp[pos:pos+2], uint16(m.Int16))
426 order.PutUint32(tmp[pos:pos+4], uint32(m.Int32))
429 order.PutUint32(tmp[pos:pos+4], uint32(m.AliasUint32))
432 copy(tmp[pos:pos+6], m.AliasArray[:])
435 order.PutUint32(tmp[pos:pos+4], uint32(m.Enum))
438 for i := 0; i < 4; i++ {
440 if i < len(m.BaseArray) {
443 order.PutUint32(tmp[pos:pos+4], uint32(x))
447 copy(tmp[pos:pos+7], m.Slice)
450 copy(tmp[pos:pos+64], m.String)
453 order.PutUint32(tmp[pos:pos+4], uint32(len(m.VlaStr)) /*m.SizeOf*/)
456 copy(tmp[pos:pos+len(m.VlaStr)], m.VlaStr[:])
459 order.PutUint32(tmp[pos:pos+4], uint32(len(m.VariableSlice)) /*m.SizeOf*/)
462 for i := range m.VariableSlice {
463 tmp[pos+i*1] = uint8(m.VariableSlice[i].Proto)
464 //copy(tmp[102+i:103+i], []byte{byte(m.VariableSlice[i].Proto)})
466 pos += len(m.VariableSlice) * 1
468 tmp[pos] = uint8(m.TypeUnion.Af)
471 copy(tmp[pos:pos+16], m.TypeUnion.Un.XXX_UnionData[:])
476 /*_, err := buf.Write(tmp)
480 return buf.Bytes(), nil*/
483 func (m *TestAllMsg) Unmarshal(tmp []byte) error {
484 order := binary.BigEndian
486 //tmp := make([]byte, 143)
489 m.Bool = tmp[pos] != 0
496 //order.PutUint16(tmp[pos:pos+2], m.Uint16)
497 m.Uint16 = order.Uint16(tmp[pos : pos+2])
500 //order.PutUint32(tmp[pos:pos+4], m.Uint32)
501 m.Uint32 = order.Uint32(tmp[pos : pos+4])
504 //tmp[pos] = byte(m.Int8)
505 m.Int8 = int8(tmp[pos])
508 //order.PutUint16(tmp[pos:pos+2], uint16(m.Int16))
509 m.Int16 = int16(order.Uint16(tmp[pos : pos+2]))
512 //order.PutUint32(tmp[pos:pos+4], uint32(m.Int32))
513 m.Int32 = int32(order.Uint32(tmp[pos : pos+4]))
516 //order.PutUint32(tmp[pos:pos+4], uint32(m.AliasUint32))
517 m.AliasUint32 = InterfaceIndex(order.Uint32(tmp[pos : pos+4]))
520 //copy(tmp[pos:pos+6], m.AliasArray[:])
521 copy(m.AliasArray[:], tmp[pos:pos+6])
524 //order.PutUint32(tmp[pos:pos+4], uint32(m.Enum))
525 m.Enum = IfStatusFlags(order.Uint32(tmp[pos : pos+4]))
528 m.BaseArray = make([]uint32, 4)
529 for i := 0; i < 4; i++ {
531 if i < len(m.BaseArray) {
534 order.PutUint32(tmp[pos:pos+4], uint32(x))*/
535 m.BaseArray[i] = order.Uint32(tmp[pos : pos+4])
539 m.Slice = make([]byte, 7)
540 copy(m.Slice[:7], tmp[pos:pos+7])
541 //copy(tmp[pos:pos+7], m.Slice)
544 i := bytes.Index(tmp[pos:pos+64], []byte{0x00})
545 m.String = string(tmp[pos : pos+i])
546 //copy(tmp[pos:pos+64], m.String)
549 //order.PutUint32(tmp[pos:pos+4], uint32(len(m.VlaStr)) /*m.SizeOf*/)
550 VlaStrLen := int(order.Uint32(tmp[pos : pos+4]))
553 m.VlaStr = string(tmp[pos : pos+VlaStrLen])
554 //copy(m.VlaStr[pos:pos+VlaStrLen], tmp[pos:pos+64])
557 m.SizeOf = uint32(order.Uint32(tmp[pos : pos+4]))
560 /*order.PutUint32(tmp[pos:pos+4], uint32(len(m.VariableSlice)))
561 m.VariableSlice = IfStatusFlags(order.Uint32(tmp[pos : pos+4]))
564 m.VariableSlice = make([]SliceType, m.SizeOf)
565 for i := range m.VariableSlice {
566 //tmp[pos+i*1] = uint8(m.VariableSlice[i].Proto)
567 m.VariableSlice[i].Proto = IPProto(tmp[pos+i*1])
568 //copy(tmp[102+i:103+i], []byte{byte(m.VariableSlice[i].Proto)})
570 pos += len(m.VariableSlice) * 1
572 //tmp[pos] = uint8(m.TypeUnion.Af)
573 m.TypeUnion.Af = AddressFamily(tmp[pos])
576 //copy(tmp[pos:pos+16], m.TypeUnion.Un.XXX_UnionData[:])
577 copy(m.TypeUnion.Un.XXX_UnionData[:], tmp[pos:pos+16])
581 /*_, err := buf.Write(tmp)
585 return buf.Bytes(), nil*/
588 func boolToUint(b bool) uint8 {
595 // SwInterfaceDetails represents VPP binary API message 'sw_interface_details'.
596 type TestAllMsg struct {
604 AliasUint32 InterfaceIndex
605 AliasArray MacAddress
607 BaseArray []uint32 `struc:"[4]uint32"`
608 Slice []byte `struc:"[7]byte"`
609 String string `struc:"[64]byte"`
610 XXX_VlaStrLen uint32 `struc:"sizeof=VlaStr"`
612 SizeOf uint32 `struc:"sizeof=VariableSlice"`
613 VariableSlice []SliceType
617 type InterfaceIndex uint32
618 type MacAddress [6]uint8
619 type IfStatusFlags uint32
622 IF_STATUS_API_FLAG_ADMIN_UP IfStatusFlags = 1
623 IF_STATUS_API_FLAG_LINK_UP IfStatusFlags = 2
626 // Address represents VPP binary API type 'address'.
627 type Address struct {
632 // AddressFamily represents VPP binary API enum 'address_family'.
633 type AddressFamily uint8
636 ADDRESS_IP4 AddressFamily = 0
637 ADDRESS_IP6 AddressFamily = 1
640 // AddressUnion represents VPP binary API union 'address_union'.
641 type AddressUnion struct {
642 XXX_UnionData [16]byte
645 func (*AddressUnion) GetTypeName() string { return "address_union" }
647 func AddressUnionIP4(a IP4Address) (u AddressUnion) {
651 func (u *AddressUnion) SetIP4(a IP4Address) {
652 var b = new(bytes.Buffer)
653 if err := struc.Pack(b, &a); err != nil {
656 copy(u.XXX_UnionData[:], b.Bytes())
658 func (u *AddressUnion) GetIP4() (a IP4Address) {
659 var b = bytes.NewReader(u.XXX_UnionData[:])
664 func AddressUnionIP6(a IP6Address) (u AddressUnion) {
668 func (u *AddressUnion) SetIP6(a IP6Address) {
669 var b = new(bytes.Buffer)
670 if err := struc.Pack(b, &a); err != nil {
673 copy(u.XXX_UnionData[:], b.Bytes())
675 func (u *AddressUnion) GetIP6() (a IP6Address) {
676 var b = bytes.NewReader(u.XXX_UnionData[:])
681 // IP4Address represents VPP binary API alias 'ip4_address'.
682 type IP4Address [4]uint8
684 // IP6Address represents VPP binary API alias 'ip6_address'.
685 type IP6Address [16]uint8
687 type SliceType struct {
694 IP_API_PROTO_HOPOPT IPProto = 0
695 IP_API_PROTO_ICMP IPProto = 1
696 IP_API_PROTO_IGMP IPProto = 2
697 IP_API_PROTO_TCP IPProto = 6
698 IP_API_PROTO_UDP IPProto = 17
699 IP_API_PROTO_GRE IPProto = 47
700 IP_API_PROTO_ESP IPProto = 50
701 IP_API_PROTO_AH IPProto = 51
702 IP_API_PROTO_ICMP6 IPProto = 58
703 IP_API_PROTO_EIGRP IPProto = 88
704 IP_API_PROTO_OSPF IPProto = 89
705 IP_API_PROTO_SCTP IPProto = 132
706 IP_API_PROTO_RESERVED IPProto = 255
709 func (m *TestAllMsg) Reset() { *m = TestAllMsg{} }
710 func (*TestAllMsg) GetMessageName() string { return "sw_interface_details" }
711 func (*TestAllMsg) GetCrcString() string { return "17b69fa2" }
712 func (*TestAllMsg) GetMessageType() api.MessageType { return api.ReplyMessage }