misc: remove GNU Indent directives
[vpp.git] / src / plugins / lisp / test / lisp_cp_test.c
1 /*
2  * Copyright (c) 2019 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:
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 implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/vnet.h>
17 #include <vppinfra/error.h>
18 #include <lisp/lisp-cp/lisp_cp_messages.h>
19 #include <lisp/lisp-cp/control.h>
20 #include <lisp/lisp-cp/lisp_msg_serdes.h>
21 #include <vlibapi/api.h>
22 #include <lisp/lisp-cp/packets.h>
23
24 #define _assert(e)                                      \
25   error = CLIB_ERROR_ASSERT (e);                        \
26   if (error)                                            \
27     {                                                   \
28       fformat(stderr, "FAIL: line %d \n\n", __LINE__);  \
29       goto done;                                        \
30     }
31
32 static void
33 print_chunk (u8 * b, int *offset, int c, char *des)
34 {
35   int i, n = offset[0] + c;;
36   for (i = offset[0]; i < n; i++)
37     {
38       printf ("0x%02x, ", b[i]);
39     }
40   printf (" // %s\n", des);
41   *offset += c;
42 }
43
44 void
45 print_map_request (map_request_hdr_t * h)
46 {
47 #define pchunk(_count, _desc) \
48   print_chunk((u8 *)h, &offset, _count, _desc)
49
50   int offset = 0;
51
52   pchunk (4, "data");
53   pchunk (8, "Nonce");
54   pchunk (2, "Source-EID-AFI");
55   pchunk (4, "Source EID Address");
56   pchunk (2, "ITR-RLOC-AFI 1");
57   pchunk (4, "ITR-RLOC Address 1");
58   pchunk (2, "ITR-RLOC-AFI 2");
59   pchunk (16, "ITR-RLOC Address 2");
60   pchunk (1, "REC: reserved");
61   pchunk (1, "REC: EID mask-len");
62   pchunk (2, "REC: EID-prefix-AFI");
63   pchunk (4, "REC: EID-prefix");
64   printf ("\n");
65 }
66
67 static clib_error_t *
68 test_lisp_msg_push_ecm ()
69 {
70   vlib_main_t *vm = vlib_get_main ();
71   clib_error_t *error = 0;
72   gid_address_t la, ra;
73   vlib_buffer_t *b = 0;
74   u32 buff_len = 900;
75   int lp = 0x15, rp = 0x14;
76
77   b = clib_mem_alloc (buff_len);
78   clib_memset ((u8 *) b, 0, buff_len);
79   b->current_length = buff_len;
80   b->current_data = sizeof (udp_header_t) + sizeof (ip4_header_t) +
81     sizeof (ecm_hdr_t) + 1;
82
83   la.type = GID_ADDR_IP_PREFIX;
84   la.ippref.addr.ip.ip4.as_u32 = 0xa1b2c3d4;
85   la.ippref.addr.version = AF_IP4;
86
87   ra.type = GID_ADDR_IP_PREFIX;
88   ra.ippref.addr.ip.ip4.as_u32 = 0x90817263;
89   ra.ippref.addr.version = AF_IP4;
90
91   ecm_hdr_t *lh = lisp_msg_push_ecm (vm, b, lp, rp, &la, &ra);
92
93   u8 expected_ecm_hdr[] = {
94     0x80, 0x00, 0x00, 0x00
95   };
96   _assert (0 == memcmp (expected_ecm_hdr, lh, sizeof (expected_ecm_hdr)));
97
98   ip4_header_t *ih = (ip4_header_t *) (lh + 1);
99   /* clear ip checksum */
100   clib_memset ((u8 *) ih + 10, 0, 2);
101
102   u8 expected_ip4_hdr[] = {
103     0x45,                   /* version; IHL */
104     0x00,                   /* services */
105     0x03, 0xa0,             /* total length */
106     0x00, 0x00,             /* identification */
107     0x40, 0x00,             /* flags; fragment offset*/
108     0xff,                   /* TTL */
109     0x11,                   /* protocol */
110     0x00, 0x00,             /* header checksum */
111     0xd4, 0xc3, 0xb2, 0xa1, /* src IP */
112     0x63, 0x72, 0x81, 0x90, /* dst IP */
113   };
114
115   _assert (0 == memcmp (ih, expected_ip4_hdr, sizeof (expected_ip4_hdr)));
116
117   udp_header_t *uh = (udp_header_t *) (ih + 1);
118   /* clear udp checksum */
119   clib_memset ((u8 *) uh + 6, 0, 2);
120
121   u8 expected_udp_hdr[] = {
122     0x00, 0x15, /* src port */
123     0x00, 0x14, /* dst port */
124     0x03, 0x8c, /* length */
125     0x00, 0x00, /* checksum */
126   };
127
128   _assert (0 == memcmp (uh, expected_udp_hdr, sizeof (expected_udp_hdr)));
129
130 done:
131   clib_mem_free (b);
132   return error;
133 }
134
135 static clib_error_t *
136 test_lisp_msg_parse_mapping_record ()
137 {
138   clib_error_t *error = 0;
139   locator_t probed;
140   locator_t *locs = 0;
141   vlib_buffer_t *b = 0;
142   gid_address_t eid;
143   u32 buff_len = 500;
144
145   b = clib_mem_alloc (buff_len);
146   clib_memset ((u8 *) b, 0, buff_len);
147
148   u8 map_reply_records[] = {
149     /* 1. record */
150     0x01, 0x02, 0x03, 0x04, /* record TTL */
151     0x01,                   /* locator count */
152     0x00, 0x00, 0x00,       /* eid-mask-len; ... */
153     0x00, 0x00,             /* reserved; map-version num */
154     0x00, 0x01,             /* EID-Prefix-AFI */
155     0x33, 0x44, 0x55, 0x66, /* eid-prefix */
156     /* loc */
157     0x0a,                   /* prority */
158     0x0b,                   /* weight */
159     0x0c,                   /* m-prority */
160     0x0d,                   /* m-weight */
161     0x00, 0x00,             /* unused flags */
162     0x00, 0x01,             /* Loc-AFI */
163     0xaa, 0xbb, 0xcc, 0xdd, /* Loator */
164   };
165
166   b->current_length = buff_len;
167   clib_memcpy (b->data, map_reply_records, sizeof (map_reply_records));
168
169   lisp_msg_parse_mapping_record (b, &eid, &locs, &probed);
170   _assert (vec_len (locs) == 1);
171   _assert (eid.ippref.addr.ip.ip4.as_u32 == 0x66554433);
172   _assert (locs[0].local == 0);
173   _assert (locs[0].address.ippref.addr.ip.ip4.as_u32 == 0xddccbbaa);
174   _assert (locs[0].address.type == GID_ADDR_IP_PREFIX);
175   _assert (locs[0].priority == 0xa);
176   _assert (locs[0].weight == 0xb);
177   _assert (locs[0].mpriority == 0xc);
178   _assert (locs[0].mweight == 0xd);
179
180 done:
181   clib_mem_free (b);
182   if (locs)
183     vec_free (locs);
184   return error;
185 }
186
187 static map_request_hdr_t *
188 build_map_request (lisp_cp_main_t * lcm, vlib_buffer_t * b,
189                    gid_address_t * rlocs)
190 {
191   gid_address_t _seid, *seid = &_seid;
192   gid_address_t _deid, *deid = &_deid;
193   u8 is_smr_invoked = 1;
194   u8 rloc_probe_set = 0;
195   u64 nonce = 0;
196   map_request_hdr_t *h = 0;
197   clib_memset (deid, 0, sizeof (deid[0]));
198   clib_memset (seid, 0, sizeof (seid[0]));
199
200   gid_address_type (seid) = GID_ADDR_IP_PREFIX;
201   ip_address_t *ip_addr = &gid_address_ip (seid);
202   ip_addr_v4 (ip_addr).as_u32 = 0x12345678;
203   seid->ippref.addr.version = AF_IP4;
204
205   gid_address_type (deid) = GID_ADDR_IP_PREFIX;
206   ip_address_t *ip_addr2 = &gid_address_ip (deid);
207   ip_addr_v4 (ip_addr2).as_u32 = 0x9abcdef0;
208   deid->ippref.addr.version = AF_IP4;
209   gid_address_ippref_len (deid) = 24;
210
211   h = lisp_msg_put_mreq (lcm, b, seid, deid, rlocs,
212                          is_smr_invoked, rloc_probe_set, &nonce);
213   vec_free (rlocs);
214   return h;
215 }
216
217 static void
218 generate_rlocs (gid_address_t ** rlocs, u32 * count)
219 {
220   gid_address_t gid_addr_data, *gid_addr = &gid_addr_data;
221   clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
222   ip_address_t *addr = &gid_address_ip (gid_addr);
223
224   gid_address_type (gid_addr) = GID_ADDR_IP_PREFIX;
225
226   ip_addr_version (addr) = AF_IP4;
227   ip_addr_v4 (addr).data_u32 = 0x10203040;
228   vec_add1 (rlocs[0], gid_addr[0]);
229
230   ip_addr_v6 (addr).as_u32[0] = 0xffeeddcc;
231   ip_addr_v6 (addr).as_u32[1] = 0xbbaa9988;
232   ip_addr_v6 (addr).as_u32[2] = 0x77665544;
233   ip_addr_v6 (addr).as_u32[3] = 0x33221100;
234   ip_addr_version (addr) = AF_IP6;
235   vec_add1 (rlocs[0], gid_addr[0]);
236 }
237
238 static clib_error_t *
239 test_lisp_msg_parse ()
240 {
241   gid_address_t eid;
242   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
243   map_request_hdr_t *h;
244   gid_address_t gid;
245   clib_error_t *error = 0;
246   vlib_buffer_t *b;
247   gid_address_t *rlocs_decode = 0, *rlocs = 0;
248   u32 rloc_count_parse = 0;
249
250   u8 *data = clib_mem_alloc (500);
251   clib_memset (data, 0, 500);
252   b = (vlib_buffer_t *) data;
253
254   generate_rlocs (&rlocs_decode, &rloc_count_parse);
255   h = build_map_request (lcm, b, rlocs_decode);
256
257   vlib_buffer_pull (b, sizeof (*h));
258   u32 len = lisp_msg_parse_addr (b, &gid);
259   _assert (len == 2 + 4
260            /* Source-EID-AFI field lenght + IPv4 address length */ );
261   _assert (gid.ippref.addr.ip.ip4.as_u32 == 0x12345678);
262   _assert (gid.ippref.addr.version == AF_IP4);
263
264   u8 rloc_count = MREQ_ITR_RLOC_COUNT (h) + 1;
265   lisp_msg_parse_itr_rlocs (b, &rlocs, rloc_count);
266
267   _assert (vec_len (rlocs) == 2);
268   _assert (rlocs[0].ippref.addr.ip.ip4.as_u32 == 0x10203040);
269   _assert (rlocs[0].ippref.addr.version == AF_IP4);
270
271   _assert (rlocs[1].ippref.addr.ip.ip6.as_u32[0] == 0xffeeddcc);
272   _assert (rlocs[1].ippref.addr.ip.ip6.as_u32[1] == 0xbbaa9988);
273   _assert (rlocs[1].ippref.addr.ip.ip6.as_u32[2] == 0x77665544);
274   _assert (rlocs[1].ippref.addr.ip.ip6.as_u32[3] == 0x33221100);
275   _assert (rlocs[1].ippref.addr.version == AF_IP6);
276
277   lisp_msg_parse_eid_rec (b, &eid);
278   _assert (eid.ippref.addr.ip.ip4.as_u32 == 0x9abcdef0);
279   _assert (eid.ippref.addr.version == AF_IP4);
280   _assert (eid.ippref.len == 24);
281
282 done:
283   clib_mem_free (data);
284   if (rlocs)
285     vec_free (rlocs);
286   return error;
287 }
288
289 static clib_error_t *
290 test_lisp_msg_put_mreq_with_lcaf ()
291 {
292   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
293   clib_error_t *error = 0;
294   map_request_hdr_t *h = 0;
295   gid_address_t *rlocs = 0;
296
297   ip_prefix_t ippref;
298   ip_prefix_version (&ippref) = AF_IP4;
299   ip4_address_t *ip = &ip_prefix_v4 (&ippref);
300   ip->as_u32 = 0x11223344;
301   ippref.len = 32;
302
303   gid_address_t g = {
304     .type = GID_ADDR_IP_PREFIX,
305     .ippref = ippref,
306     .vni = 0x90919293,
307     .vni_mask = 0x17
308   };
309   vec_add1 (rlocs, g);
310
311   u8 *data = clib_mem_alloc (500);
312   clib_memset (data, 0, 500);
313
314   h = build_map_request (lcm, (vlib_buffer_t *) data, rlocs);
315
316   /* clear Nonce to simplify comparison */
317   clib_memset ((u8 *) h + 4, 0, 8);
318
319   u8 expected_data[] =
320     {
321       0x10, 0x40, 0x00, 0x01, /* type; flags; IRC; REC count */
322       0x00, 0x00, 0x00, 0x00,
323       0x00, 0x00, 0x00, 0x00, /* nonce */
324       0x00, 0x01,             /* Source-EID-AFI */
325       0x78, 0x56, 0x34, 0x12, /* Source EID Address */
326
327       /* RLOCs */
328       0x40, 0x03,             /* AFI = LCAF*/
329       /* LCAF header*/
330       0x00, 0x00,             /* reserved1, flags */
331       0x02,                   /* type = Instance ID */
332       0x17,                   /* IID mask-len */
333       0x00, 0x0a,             /* lenght */
334       0x90, 0x91, 0x92, 0x93, /* IID / VNI */
335
336       0x00, 0x01,             /* AFI = ipv4 */
337       0x44, 0x33, 0x22, 0x11, /* ITR-RLOC Address 1 */
338
339       /* record */
340       0x00,                   /* reserved */
341       0x18,                   /* EID mask-len */
342       0x00, 0x01,             /* EID-prefix-AFI */
343       0xf0, 0xde, 0xbc, 0x9a, /* EID-prefix */
344     };
345
346   _assert (0 == memcmp (expected_data, (u8 *) h, sizeof (expected_data)));
347 done:
348   clib_mem_free (data);
349   return error;
350 }
351
352 static clib_error_t *
353 test_lisp_msg_put_mreq ()
354 {
355   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
356   clib_error_t *error = 0;
357   map_request_hdr_t *h;
358   gid_address_t *rlocs = 0;
359   u32 rloc_count = 0;
360
361   u8 *data = clib_mem_alloc (500);
362   clib_memset (data, 0, 500);
363
364   generate_rlocs (&rlocs, &rloc_count);
365   h = build_map_request (lcm, (vlib_buffer_t *) data, rlocs);
366
367   /* clear Nonce to simplify comparison */
368   clib_memset ((u8 *) h + 4, 0, 8);
369
370   print_map_request (h);
371
372   u8 expected_data[50] = {
373     0x10, 0x40, 0x01, 0x01, /* type; flags; IRC; REC count */
374     0x00, 0x00, 0x00, 0x00,
375     0x00, 0x00, 0x00, 0x00, /* nonce */
376     0x00, 0x01,             /* Source-EID-AFI */
377     0x78, 0x56, 0x34, 0x12, /* Source EID Address */
378
379     /* RLOCs */
380     0x00, 0x01,             /* ITR-RLOC-AFI 1 */
381     0x40, 0x30, 0x20, 0x10, /* ITR-RLOC Address 1 */
382     0x00, 0x02,             /* ITR-RLOC-AFI 2 */
383     0xcc, 0xdd, 0xee, 0xff,
384     0x88, 0x99, 0xaa, 0xbb,
385     0x44, 0x55, 0x66, 0x77,
386     0x00, 0x11, 0x22, 0x33, /* ITR-RLOC Address 2 */
387
388     /* record */
389     0x00,                   /* reserved */
390     0x18,                   /* EID mask-len */
391     0x00, 0x01,             /* EID-prefix-AFI */
392     0xf0, 0xde, 0xbc, 0x9a, /* EID-prefix */
393   };
394
395   _assert (0 == memcmp (expected_data, (u8 *) h, sizeof (expected_data)));
396
397 done:
398   clib_mem_free (data);
399   return error;
400 }
401
402 /* generate a vector of eid records */
403 static mapping_t *
404 build_test_map_records ()
405 {
406   mapping_t *records = 0;
407
408   mapping_t r = {
409     .ttl = MAP_REGISTER_DEFAULT_TTL,
410     .eid = {
411       .type = GID_ADDR_MAC,
412       .mac = {1, 2, 3, 4, 5, 6},
413       .vni = 0x0
414     }
415   };
416
417   locator_t loc = {
418     .weight = 1,
419     .priority = 2,
420     .local = 1,
421     .address = {
422       .type = GID_ADDR_IP_PREFIX,
423       .ippref = {
424         .addr = {
425           .ip.ip4.as_u32 = 0x99887766,
426           .version = AF_IP4
427         }
428       }
429     }
430   };
431
432   vec_add1 (r.locators, loc);
433   vec_add1 (records, r);
434
435   return records;
436 }
437
438 static void
439 free_test_map_records (mapping_t * maps)
440 {
441   mapping_t *map;
442   vec_foreach (map, maps)
443   {
444     vec_free (map->locators);
445   }
446   vec_free (maps);
447 }
448
449 static clib_error_t *
450 test_lisp_map_register ()
451 {
452   vlib_buffer_t *b;
453   clib_error_t *error = 0;
454   u64 nonce;
455   u32 msg_len = 0;
456   mapping_t *records = build_test_map_records ();
457
458   u8 *data = clib_mem_alloc (500);
459   clib_memset (data, 0, 500);
460   b = (vlib_buffer_t *) data;
461
462   lisp_msg_put_map_register (b, records, 1 /* want map notify */ ,
463                              20 /* length of HMAC_SHA_1_96 */ ,
464                              &nonce, &msg_len);
465   free_test_map_records (records);
466
467   /* clear Nonce to simplify comparison */
468   clib_memset ((u8 *) b->data + 4, 0, 8);
469
470   /* clear authentication data */
471   clib_memset ((u8 *) b->data + 16, 0, 20);
472
473   u8 expected_data[] = {
474     0x30, 0x00, 0x01, 0x01, /* type; rsvd; want notify; REC count */
475     0x00, 0x00, 0x00, 0x00,
476     0x00, 0x00, 0x00, 0x00, /* nonce */
477     0x00, 0x00, 0x00, 0x00, /* key id, auth data length:
478                               both are zeroes because those are set in another
479                               function (see auth_data_len_by_key_id())*/
480     0x00, 0x00, 0x00, 0x00,
481     0x00, 0x00, 0x00, 0x00,
482     0x00, 0x00, 0x00, 0x00,
483     0x00, 0x00, 0x00, 0x00,
484     0x00, 0x00, 0x00, 0x00, /* auth data */
485
486     /* first record */
487     /* 0x00, 0x00, 0x03, 0x84, */ /* default ttl (15 minues) */
488     0x00, 0x01, 0x51, 0x80, /* default ttl (24h = 86400s) */
489     0x01, 0x00, 0x00, 0x00, /* loc count, eid len, ACT, A */
490     0x00, 0x00, 0x40, 0x05, /* rsvd, map ver num, AFI = MAC */
491     0x01, 0x02, 0x03, 0x04,
492     0x05, 0x06,             /* MAC EID */
493
494     /* locator 1 */
495     0x02, 0x01, 0x00, 0x00, /* prio, weight, mprio, mweight */
496     0x00, 0x04, 0x00, 0x01, /* flags, AFI = ipv4 */
497     0x66, 0x77, 0x88, 0x99, /* ipv4 locator address */
498   };
499
500   _assert (0 == memcmp (expected_data, b->data, sizeof (expected_data)));
501 done:
502   clib_mem_free (data);
503   return error;
504 }
505
506 static vlib_buffer_t *
507 create_buffer (u8 * data, u32 data_len)
508 {
509   vlib_buffer_t *b;
510
511   u8 *buf_data = clib_mem_alloc (500);
512   clib_memset (buf_data, 0, 500);
513   b = (vlib_buffer_t *) buf_data;
514
515   u8 *p = vlib_buffer_put_uninit (b, data_len);
516   clib_memcpy (p, data, data_len);
517
518   return b;
519 }
520
521 static clib_error_t *
522 test_lisp_parse_map_reply ()
523 {
524   clib_error_t *error = 0;
525
526   u8 map_reply_data[] =
527     {
528       0x00, 0x00, 0x00, 0x01, /* type; rsvd; mapping count */
529       0x00, 0x00, 0x00, 0x00,
530     };
531
532   vlib_buffer_t *b = create_buffer (map_reply_data, sizeof (map_reply_data));
533   map_records_arg_t *mrecs = parse_map_reply (b);
534   _assert (0 == mrecs);
535   clib_mem_free (b);
536
537   u8 map_reply_data2[] =
538     {
539       0x00, 0x00, 0x00, 0x01, /* type; rsvd */
540       0x00, 0x00, 0x00, 0x00,
541       0x00, 0x00, 0x00, 0x00, /* nonce */
542
543       /* 1. record  - incomplete */
544       0x01, 0x02, 0x03, 0x04, /* record TTL */
545       0x01,                   /* locator count */
546     };
547
548   b = create_buffer (map_reply_data2, sizeof (map_reply_data2));
549   mrecs = parse_map_reply (b);
550   _assert (0 == mrecs);
551 done:
552   clib_mem_free (b);
553   return error;
554 }
555
556 static clib_error_t *
557 test_lisp_parse_lcaf ()
558 {
559   int i;
560   clib_error_t *error = 0;
561   gid_address_t eid;
562   locator_t *locs = 0;
563   locator_t probed;
564   vlib_buffer_t *b = 0;
565   u32 buff_len = 500;
566
567   b = clib_mem_alloc (buff_len);
568   clib_memset ((u8 *) b, 0, buff_len);
569
570   u8 map_reply_records[] =
571     {
572       /* 1. record */
573       0x01, 0x02, 0x03, 0x04, /* record TTL */
574       0x03,                   /* locator count */
575       0x00, 0x00, 0x00,       /* eid-mask-len; ... */
576       0x00, 0x00,             /* reserved; map-version num */
577       0x00, 0x01,             /* EID-Prefix-AFI */
578       0x33, 0x44, 0x55, 0x66, /* eid-prefix */
579
580       /* 1st locator */
581       0x0a,                   /* prority */
582       0x0b,                   /* weight */
583       0x0c,                   /* m-prority */
584       0x0d,                   /* m-weight */
585       0x00, 0x00,             /* unused flags */
586       0x40, 0x03,             /* Loc-AFI = LCAF*/
587
588       /* LCAF header*/
589       0x00, 0x00,             /* reserved1, flags */
590       0x02,                   /* type = Instance ID */
591       0x18,                   /* IID mask-len */
592       0x00, 0x0a,             /* lenght */
593       /* LCAF Instance ID */
594       0x00, 0x00, 0x00, 0x09, /* iid */
595       0x00, 0x01,             /* AFI = ipv4 */
596       0x10, 0xbb, 0xcc, 0xdd, /* ipv4 loator address */
597
598       /* 2nd locator */
599       0x07,                   /* prority */
600       0x06,                   /* weight */
601       0x05,                   /* m-prority */
602       0x04,                   /* m-weight */
603       0x00, 0x00,             /* unused flags */
604       0x40, 0x03,             /* Loc-AFI = LCAF*/
605
606       /* LCAF header*/
607       0x00, 0x00,             /* reserved1, flags */
608       0x02,                   /* type = Instance ID */
609       0x18,                   /* IID mask-len */
610       0x00, 0x16,             /* iid length + next AFI lenght */
611       /* LCAF Instance ID */
612       0x22, 0x44, 0x66, 0x88, /* iid */
613       0x00, 0x02,             /* AFI = ipv6 */
614       0xcc, 0xdd, 0xee, 0xff,
615       0x88, 0x99, 0xaa, 0xbb,
616       0x44, 0x55, 0x66, 0x77,
617       0x00, 0x11, 0x22, 0x33, /* ipv6 locator address */
618
619       /* 3rd locator */
620       0x0a,                   /* prority */
621       0x0b,                   /* weight */
622       0x0c,                   /* m-prority */
623       0x0d,                   /* m-weight */
624       0x00, 0x00,             /* unused flags */
625       0x00, 0x01,             /* Loc-AFI */
626       0xaa, 0xbb, 0xcc, 0xdd, /* Loator */
627     };
628
629   b->current_length = buff_len;
630   memcpy (b->data, map_reply_records, sizeof (map_reply_records));
631
632   lisp_msg_parse_mapping_record (b, &eid, &locs, &probed);
633   _assert (vec_len (locs) == 3);
634   _assert (eid.ippref.addr.ip.ip4.as_u32 == 0x66554433);
635
636   /* check 1st locator - an LCAF with ipv4 */
637   _assert (locs[0].local == 0);
638   _assert (locs[0].priority == 0xa);
639   _assert (locs[0].weight == 0xb);
640   _assert (locs[0].mpriority == 0xc);
641   _assert (locs[0].mweight == 0xd);
642
643   _assert (gid_address_type (&locs[0].address) == GID_ADDR_IP_PREFIX);
644   _assert (gid_address_vni (&locs[0].address) == 0x09);
645   ip_prefix_t *ip_pref = &gid_address_ippref (&locs[0].address);
646   _assert (AF_IP4 == ip_prefix_version (ip_pref));
647
648   /* 2nd locator - LCAF entry with ipv6 address */
649   _assert (locs[1].local == 0);
650   _assert (locs[1].priority == 0x7);
651   _assert (locs[1].weight == 0x6);
652   _assert (locs[1].mpriority == 0x5);
653   _assert (locs[1].mweight == 0x4);
654
655   _assert (gid_address_type (&locs[1].address) == GID_ADDR_IP_PREFIX);
656   _assert (0x22446688 == gid_address_vni (&locs[1].address));
657   ip_pref = &gid_address_ippref (&locs[1].address);
658   _assert (AF_IP6 == ip_prefix_version (ip_pref));
659
660   /* 3rd locator - simple ipv4 address */
661   _assert (gid_address_type (&locs[2].address) == GID_ADDR_IP_PREFIX);
662 done:
663   clib_mem_free (b);
664
665   for (i = 0; i < 3; i++)
666     locator_free (&locs[i]);
667   vec_free (locs);
668   return error;
669 }
670
671 #define foreach_test_case                 \
672   _(lisp_msg_put_mreq)                    \
673   _(lisp_msg_put_mreq_with_lcaf)          \
674   _(lisp_msg_push_ecm)                    \
675   _(lisp_msg_parse)                       \
676   _(lisp_msg_parse_mapping_record)        \
677   _(lisp_parse_map_reply)                 \
678   _(lisp_parse_lcaf)                      \
679   _(lisp_map_register)
680
681 static int
682 lisp_cp_serdes_tests (vlib_main_t * vm, unformat_input_t * input)
683 {
684   clib_error_t *error;
685
686 #define _(_test_name)                                   \
687   error = test_ ## _test_name ();                       \
688   if (error)                                            \
689     {                                                   \
690       fformat (stderr, "FAIL: test_" #_test_name "\n"); \
691       return -1;                                        \
692     }                                                   \
693   else                                                  \
694       fformat (stderr, "PASS: test_" #_test_name "\n"); \
695
696   foreach_test_case
697 #undef _
698     return 0;
699 }
700
701 static clib_error_t *
702 test_locator_type (void)
703 {
704   clib_error_t *error = 0;
705   gid_address_t _gid_addr, *gid = &_gid_addr;
706   ip_prefix_t *ippref;
707   gid_address_type (gid) = GID_ADDR_IP_PREFIX;
708   gid_address_ippref_len (gid) = 24;
709   ippref = &gid_address_ippref (gid);
710   ip_prefix_version (ippref) = AF_IP4;
711   ip_prefix_len (ippref) = 0;
712   ip4_address_t *ip4 = &ip_prefix_v4 (ippref);
713   ip4->as_u32 = 0x20304050;
714
715   /* local locator */
716   locator_t loc1, loc2 = {
717     .local = 1,
718     .state = 2,
719     .sw_if_index = 8,
720     .priority = 3,
721     .weight = 100,
722     .mpriority = 4,
723     .mweight = 101
724   };
725   locator_copy (&loc1, &loc2);
726   _assert (0 == locator_cmp (&loc1, &loc2));
727
728   /* remote locator */
729   loc2.local = 0;
730
731   ip_prefix_t nested_ippref;
732   ip_prefix_version (&nested_ippref) = AF_IP4;
733   ip_prefix_len (&nested_ippref) = 0;
734   ip4 = &ip_prefix_v4 (&nested_ippref);
735   ip4->as_u32 = 0x33882299;
736   gid_address_t nested_gid = {
737     .type = GID_ADDR_IP_PREFIX,
738     .ippref = nested_ippref
739   };
740
741   lcaf_t lcaf = {
742     .type = LCAF_INSTANCE_ID,
743     .uni = {
744             .vni_mask_len = 5,
745             .vni = 0xa1b2c3d4,
746             .gid_addr = &nested_gid}
747   };
748   gid_address_type (gid) = GID_ADDR_LCAF;
749   gid_address_lcaf (gid) = lcaf;
750
751   loc2.address = gid[0];
752   locator_copy (&loc1, &loc2);
753
754   _assert (0 == locator_cmp (&loc1, &loc2));
755
756 done:
757   locator_free (&loc1);
758   return error;
759 }
760
761 static clib_error_t *
762 test_gid_parse_ip_pref ()
763 {
764   clib_error_t *error = 0;
765   gid_address_t _gid_addr, *gid_addr = &_gid_addr;
766   gid_address_t _gid_addr_copy, *copy = &_gid_addr_copy;
767
768   u8 data[] =
769     {
770       0x00, 0x01,             /* AFI = IPv4 */
771       0x10, 0xbb, 0xcc, 0xdd, /* ipv4 address */
772     };
773
774   u32 len = gid_address_parse (data, gid_addr);
775   _assert (6 == len);
776   gid_address_copy (copy, gid_addr);
777   _assert (0 == gid_address_cmp (copy, gid_addr));
778 done:
779   return error;
780 }
781
782 static clib_error_t *
783 test_gid_parse_mac ()
784 {
785   clib_error_t *error = 0;
786   gid_address_t _gid, *gid = &_gid;
787   gid_address_t _gid_copy, *gid_copy = &_gid_copy;
788
789   u8 data[] =
790     {
791       0x40, 0x05,             /* AFI = MAC address */
792       0x10, 0xbb, 0xcc, 0xdd, /* MAC */
793       0x77, 0x99,
794     };
795
796   u32 len = gid_address_parse (data, gid);
797   _assert (8 == len);
798   _assert (GID_ADDR_MAC == gid_address_type (gid));
799   gid_address_copy (gid_copy, gid);
800   _assert (0 == gid_address_cmp (gid_copy, gid));
801 done:
802   return error;
803 }
804
805 static clib_error_t *
806 test_gid_write_nsh (void)
807 {
808   clib_error_t *error = 0;
809
810   u8 *b = clib_mem_alloc (500);
811   clib_memset (b, 0, 500);
812
813   gid_address_t g = {
814     .vni = 0,
815     .nsh.spi = 0x112233,
816     .nsh.si = 0x42,
817     .type = GID_ADDR_NSH,
818   };
819
820   u16 len = gid_address_put (b, &g);
821
822   u8 expected[] =
823     {
824       0x40, 0x03, 0x00, 0x00, /* AFI = LCAF*/
825       0x11, 0x00, 0x00, 0x04, /* type = SPI LCAF, length = 4 */
826
827       /* Service Path ID, Service index */
828       0x11, 0x22, 0x33, 0x42, /* SPI, SI */
829     };
830
831   _assert (sizeof (expected) == len);
832   _assert (0 == memcmp (expected, b, len));
833 done:
834   clib_mem_free (b);
835   return error;
836 }
837
838 static clib_error_t *
839 test_gid_parse_nsh ()
840 {
841   clib_error_t *error = 0;
842   gid_address_t _gid_addr, *gid_addr = &_gid_addr;
843   gid_address_t _gid_addr_copy, *copy = &_gid_addr_copy;
844
845   clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
846   clib_memset (copy, 0, sizeof (copy[0]));
847
848   u8 data[] =
849     {
850       0x40, 0x03, 0x00, 0x00, /* AFI = LCAF*/
851       0x11, 0x00, 0x00, 0x04, /* type = SPI LCAF, length = 4 */
852
853       /* Service Path ID, Service index */
854       0x55, 0x99, 0x42, 0x09, /* SPI, SI */
855     };
856
857   u32 len = gid_address_parse (data, gid_addr);
858   _assert (sizeof (data) == len);
859   gid_address_copy (copy, gid_addr);
860   _assert (0 == gid_address_cmp (gid_addr, copy));
861   _assert (GID_ADDR_NSH == gid_address_type (copy));
862   _assert (0 == gid_address_vni (copy));
863   _assert (gid_address_nsh_spi (copy) == 0x559942);
864   _assert (gid_address_nsh_si (copy) == 0x09);
865
866 done:
867   gid_address_free (copy);
868   gid_address_free (gid_addr);
869   return error;
870 }
871
872 static clib_error_t *
873 test_gid_parse_lcaf ()
874 {
875   clib_error_t *error = 0;
876   gid_address_t _gid_addr, *gid_addr = &_gid_addr;
877   gid_address_t _gid_addr_copy, *gid_addr_copy = &_gid_addr_copy;
878
879   clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
880   clib_memset (gid_addr_copy, 0, sizeof (gid_addr_copy[0]));
881
882   u8 data[] =
883     {
884       0x40, 0x03,             /* AFI = LCAF*/
885
886       /* LCAF header*/
887       0x00, 0x00,             /* reserved1, flags */
888       0x02,                   /* type = Instance ID */
889       0x18,                   /* IID mask-len */
890       0x00, 0x0a,             /* iid length + next AFI lenght */
891       /* LCAF Instance ID */
892       0x00, 0x00, 0x00, 0x09, /* iid */
893       0x00, 0x01,             /* AFI = ipv4 */
894       0x10, 0xbb, 0xcc, 0xdd, /* ipv4 address */
895     };
896
897   u32 len = gid_address_parse (data, gid_addr);
898   _assert (18 == len);
899   gid_address_copy (gid_addr_copy, gid_addr);
900   _assert (0 == gid_address_cmp (gid_addr_copy, gid_addr));
901   _assert (GID_ADDR_IP_PREFIX == gid_address_type (gid_addr));
902   _assert (9 == gid_address_vni (gid_addr));
903   _assert (0x18 == gid_address_vni_mask (gid_addr));
904   _assert (0xddccbb10 == gid_addr->ippref.addr.ip.ip4.as_u32);
905
906 done:
907   gid_address_free (gid_addr);
908   gid_address_free (gid_addr_copy);
909   return error;
910 }
911
912 /* recursive LCAFs are not supported */
913 #if 0
914 static clib_error_t *
915 test_gid_parse_lcaf_complex ()
916 {
917   clib_error_t *error = 0;
918   gid_address_t _gid_addr, *gid_addr = &_gid_addr;
919   gid_address_t _gid_addr_copy, *gid_addr_copy = &_gid_addr_copy;
920
921   clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
922   clib_memset (gid_addr_copy, 0, sizeof (gid_addr_copy[0]));
923
924   u8 data[] = {
925     0x40, 0x03,                 /* AFI = LCAF */
926
927     /* LCAF header */
928     0x00, 0x00,                 /* reserved1, flags */
929     0x02,                       /* type = Instance ID */
930     0x18,                       /* IID mask-len */
931     0x00, 0x0a,                 /* iid length + next AFI lenght */
932     /* LCAF Instance ID */
933     0x00, 0x00, 0x00, 0x0b,     /* iid */
934
935     0x40, 0x03,                 /* AFI = LCAF */
936     /* LCAF header */
937     0x00, 0x00,                 /* reserved1, flags */
938     0x02,                       /* type = Instance ID */
939     0x17,                       /* IID mask-len */
940     0x00, 0x0a,                 /* iid length + next AFI lenght */
941     /* LCAF Instance ID */
942     0x00, 0x00, 0x00, 0x0c,     /* iid */
943
944     0x40, 0x03,                 /* AFI = LCAF */
945     /* LCAF header */
946     0x00, 0x00,                 /* reserved1, flags */
947     0x02,                       /* type = Instance ID */
948     0x16,                       /* IID mask-len */
949     0x00, 0x16,                 /* iid length + next AFI lenght */
950     /* LCAF Instance ID */
951     0x00, 0x00, 0x00, 0x0d,     /* iid */
952
953     0x00, 0x02,                 /* AFI = IPv6 */
954
955     0x10, 0xbb, 0xcc, 0xdd,
956     0x10, 0xbb, 0xcc, 0xdd,
957     0x10, 0xbb, 0xcc, 0xdd,
958     0x10, 0xbb, 0xcc, 0xdd,     /* ipv6 address */
959   };
960
961   u32 len = gid_address_parse (data, gid_addr);
962   _assert (54 == len);
963   _assert (gid_addr->type == GID_ADDR_LCAF);
964   gid_address_copy (gid_addr_copy, gid_addr);
965   _assert (0 == gid_address_cmp (gid_addr_copy, gid_addr));
966   _assert (gid_addr_copy->type == GID_ADDR_LCAF);
967
968   lcaf_t *lcaf = &gid_address_lcaf (gid_addr_copy);
969   _assert (lcaf->type == LCAF_INSTANCE_ID);
970   vni_t *v = (vni_t *) lcaf;
971   _assert (v->vni == 0x0b);
972   _assert (v->vni_mask_len == 0x18);
973
974   gid_address_t *tmp = vni_gid (v);
975   _assert (gid_address_type (tmp) == GID_ADDR_LCAF);
976   lcaf = &gid_address_lcaf (tmp);
977   _assert (lcaf->type == LCAF_INSTANCE_ID);
978
979   v = (vni_t *) lcaf;
980   _assert (v->vni == 0x0c);
981   _assert (v->vni_mask_len == 0x17);
982
983   tmp = vni_gid (v);
984   _assert (gid_address_type (tmp) == GID_ADDR_LCAF);
985   lcaf = &gid_address_lcaf (tmp);
986
987   _assert (lcaf->type == LCAF_INSTANCE_ID);
988   v = (vni_t *) lcaf;
989   _assert (v->vni == 0x0d);
990   _assert (v->vni_mask_len == 0x16);
991
992   tmp = vni_gid (v);
993   _assert (gid_address_type (tmp) == GID_ADDR_IP_PREFIX);
994
995   ip_prefix_t *ip_pref = &gid_address_ippref (tmp);
996   ip6_address_t *ip6 = &ip_prefix_v6 (ip_pref);
997   _assert (ip6->as_u32[0] == 0xddccbb10);
998   _assert (ip6->as_u32[1] == 0xddccbb10);
999   _assert (ip6->as_u32[2] == 0xddccbb10);
1000   _assert (ip6->as_u32[3] == 0xddccbb10);
1001   _assert (ip_prefix_version (ip_pref) == AF_IP6);
1002
1003 done:
1004   gid_address_free (gid_addr);
1005   gid_address_free (gid_addr_copy);
1006   return error;
1007 }
1008 #endif
1009
1010 static clib_error_t *
1011 test_write_mac_in_lcaf (void)
1012 {
1013   clib_error_t *error = 0;
1014
1015   u8 *b = clib_mem_alloc (500);
1016   clib_memset (b, 0, 500);
1017
1018   gid_address_t g = {
1019     .mac = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6},
1020     .vni = 0x01020304,
1021     .vni_mask = 0x10,
1022     .type = GID_ADDR_MAC,
1023   };
1024
1025   u16 len = gid_address_put (b, &g);
1026
1027   u8 expected[] =
1028     {
1029       0x40, 0x03,             /* AFI = LCAF */
1030       0x00,                   /* reserved1 */
1031       0x00,                   /* flags */
1032       0x02,                   /* LCAF type = Instance ID */
1033       0x10,                   /* IID/IID mask len */
1034       0x00, 0x0c,             /* length */
1035       0x01, 0x02, 0x03, 0x04, /* Instance ID / VNI */
1036
1037       0x40, 0x05,             /* AFI = MAC */
1038       0x01, 0x02, 0x03, 0x04,
1039       0x05, 0x06              /* MAC */
1040     };
1041
1042   _assert (sizeof (expected) == len);
1043   _assert (0 == memcmp (expected, b, len));
1044 done:
1045   clib_mem_free (b);
1046   return error;
1047 }
1048
1049 static clib_error_t *
1050 test_mac_address_write (void)
1051 {
1052   clib_error_t *error = 0;
1053
1054   u8 *b = clib_mem_alloc (500);
1055   clib_memset (b, 0, 500);
1056
1057   gid_address_t g = {
1058     .mac = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6},
1059     .type = GID_ADDR_MAC,
1060   };
1061
1062   u16 len = gid_address_put (b, &g);
1063   _assert (8 == len);
1064
1065   u8 expected[] =
1066     {
1067       0x40, 0x05,             /* AFI = MAC */
1068       0x01, 0x02, 0x03, 0x04,
1069       0x05, 0x06              /* MAC */
1070     };
1071
1072   _assert (0 == memcmp (expected, b, len));
1073 done:
1074   clib_mem_free (b);
1075   return error;
1076 }
1077
1078 static clib_error_t *
1079 test_src_dst_with_vni_serdes (void)
1080 {
1081   clib_error_t *error = 0;
1082   u8 *b = clib_mem_alloc (500);
1083   clib_memset (b, 0, 500);
1084
1085   fid_address_t src =
1086     {
1087       .type = FID_ADDR_IP_PREF,
1088       .ippref =
1089         {
1090           .len = 24,
1091           .addr =
1092             {
1093               .version = AF_IP4,
1094               .ip.ip4.data = { 0x1, 0x2, 0x3, 0x0 }
1095             }
1096         }
1097     };
1098
1099   fid_address_t dst =
1100     {
1101       .type = FID_ADDR_IP_PREF,
1102       .ippref =
1103         {
1104           .len = 16,
1105           .addr =
1106             {
1107               .version = AF_IP4,
1108               .ip.ip4.data = { 0x9, 0x8, 0x0, 0x0 }
1109             }
1110         }
1111     };
1112
1113   source_dest_t sd =
1114     {
1115       .src = src,
1116       .dst = dst
1117     };
1118
1119   gid_address_t g =
1120     {
1121       .sd = sd,
1122       .type = GID_ADDR_SRC_DST,
1123       .vni = 0x12345678,
1124       .vni_mask = 0x9
1125     };
1126
1127
1128   u16 size_to_put = gid_address_size_to_put (&g);
1129   _assert (36 == size_to_put);
1130   _assert (0 == gid_address_len (&g));
1131
1132   u16 write_len = gid_address_put (b, &g);
1133   _assert (size_to_put == write_len);
1134
1135   u8 expected_data[] =
1136     {
1137       0x40, 0x03, 0x00, 0x00,  /* AFI = LCAF, reserved1, flags */
1138       0x02, 0x09, 0x00, 0x1c,  /* LCAF type = IID, IID mask-len, length */
1139       0x12, 0x34, 0x56, 0x78,  /* reserved; source-ML, Dest-ML */
1140
1141       0x40, 0x03, 0x00, 0x00,  /* AFI = LCAF, reserved1, flags */
1142       0x0c, 0x00, 0x00, 0x10,  /* LCAF type = source/dest key, rsvd, length */
1143       0x00, 0x00, 0x18, 0x10,  /* reserved; source-ML, Dest-ML */
1144
1145       0x00, 0x01,              /* AFI = ip4 */
1146       0x01, 0x02, 0x03, 0x00,  /* source */
1147
1148       0x00, 0x01,              /* AFI = ip4 */
1149       0x09, 0x08, 0x00, 0x00,  /* destination */
1150     };
1151
1152   _assert (0 == memcmp (expected_data, b, sizeof (expected_data)));
1153
1154   gid_address_t p;
1155   clib_memset (&p, 0, sizeof (p));
1156   _assert (write_len == gid_address_parse (b, &p));
1157   _assert (0 == gid_address_cmp (&g, &p));
1158 done:
1159   clib_mem_free (b);
1160   return error;
1161 }
1162
1163 static clib_error_t *
1164 test_src_dst_deser_bad_afi (void)
1165 {
1166   clib_error_t *error = 0;
1167
1168   u8 expected_data[] =
1169     {
1170       0x40, 0x03, 0x00, 0x00,  /* AFI = LCAF, reserved1, flags */
1171       0x0c, 0x00, 0x00, 0x14,  /* LCAF type = source/dest key, rsvd, length */
1172       0x00, 0x00, 0x00, 0x00,  /* reserved; source-ML, Dest-ML */
1173
1174       0xde, 0xad,              /* AFI = bad value */
1175       0x11, 0x22, 0x33, 0x44,
1176       0x55, 0x66,              /* source */
1177
1178       0x40, 0x05,              /* AFI = MAC */
1179       0x10, 0x21, 0x32, 0x43,
1180       0x54, 0x65,              /* destination */
1181     };
1182
1183   gid_address_t p;
1184   _assert (~0 == gid_address_parse (expected_data, &p));
1185 done:
1186   return error;
1187 }
1188
1189 static clib_error_t *
1190 test_src_dst_serdes (void)
1191 {
1192   clib_error_t *error = 0;
1193
1194   u8 *b = clib_mem_alloc (500);
1195   clib_memset (b, 0, 500);
1196
1197   fid_address_t src = {
1198     .type = FID_ADDR_MAC,
1199     .mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
1200   };
1201
1202   fid_address_t dst = {
1203     .type = FID_ADDR_MAC,
1204     .mac = {0x10, 0x21, 0x32, 0x43, 0x54, 0x65}
1205   };
1206
1207   source_dest_t sd = {
1208     .src = src,
1209     .dst = dst
1210   };
1211
1212   gid_address_t g = {
1213     .sd = sd,
1214     .type = GID_ADDR_SRC_DST,
1215     .vni = 0x0,
1216     .vni_mask = 0x0
1217   };
1218
1219   u16 size_to_put = gid_address_size_to_put (&g);
1220   _assert (28 == size_to_put);
1221   _assert (0 == gid_address_len (&g));
1222
1223   u16 write_len = gid_address_put (b, &g);
1224   _assert (size_to_put == write_len);
1225
1226   u8 expected_data[] =
1227     {
1228       0x40, 0x03, 0x00, 0x00,  /* AFI = LCAF, reserved1, flags */
1229       0x0c, 0x00, 0x00, 0x14,  /* LCAF type = source/dest key, rsvd, length */
1230       0x00, 0x00, 0x00, 0x00,  /* reserved; source-ML, Dest-ML */
1231
1232       0x40, 0x05,              /* AFI = MAC */
1233       0x11, 0x22, 0x33, 0x44,
1234       0x55, 0x66,              /* source */
1235
1236       0x40, 0x05,              /* AFI = MAC */
1237       0x10, 0x21, 0x32, 0x43,
1238       0x54, 0x65,              /* destination */
1239     };
1240
1241   _assert (0 == memcmp (expected_data, b, sizeof (expected_data)));
1242
1243   gid_address_t p;
1244   clib_memset (&p, 0, sizeof (p));
1245   _assert (write_len == gid_address_parse (b, &p));
1246   _assert (0 == gid_address_cmp (&g, &p));
1247 done:
1248   clib_mem_free (b);
1249   return error;
1250 }
1251
1252 static clib_error_t *
1253 test_gid_address_write (void)
1254 {
1255   clib_error_t *error = 0;
1256   ip_prefix_t ippref_data, *ippref = &ippref_data;
1257
1258   u8 *b = clib_mem_alloc (500);
1259   clib_memset (b, 0, 500);
1260
1261   ip_prefix_version (ippref) = AF_IP4;
1262   ip_prefix_len (ippref) = 9;
1263   ip4_address_t *ip4 = &ip_prefix_v4 (ippref);
1264   ip4->as_u32 = 0xaabbccdd;
1265
1266   gid_address_t g = {
1267     .ippref = ippref[0],
1268     .type = GID_ADDR_IP_PREFIX,
1269     .vni = 0x01020304,
1270     .vni_mask = 0x18
1271   };
1272
1273   _assert (18 == gid_address_size_to_put (&g));
1274   _assert (gid_address_len (&g) == 9);
1275
1276   u16 write_len = gid_address_put (b, &g);
1277   _assert (18 == write_len);
1278
1279   u8 expected_gid_data[] =
1280     {
1281       0x40, 0x03,             /* AFI = LCAF */
1282       0x00,                   /* reserved1 */
1283       0x00,                   /* flags */
1284       0x02,                   /* LCAF type = Instance ID */
1285       0x18,                   /* IID/VNI mask len */
1286       0x00, 0x0a,             /* length */
1287       0x01, 0x02, 0x03, 0x04, /* Instance ID / VNI */
1288
1289       0x00, 0x01,             /* AFI = IPv4 */
1290       0xdd, 0xcc, 0xbb, 0xaa, /* ipv4 addr */
1291     };
1292
1293   _assert (0 == memcmp (expected_gid_data, b, sizeof (expected_gid_data)));
1294 done:
1295   clib_mem_free (b);
1296   return error;
1297 }
1298
1299 #undef foreach_test_case
1300
1301 #define foreach_test_case                 \
1302   _(locator_type)                         \
1303   _(gid_parse_ip_pref)                    \
1304   _(gid_parse_mac)                        \
1305   _(gid_parse_lcaf)                       \
1306   _(gid_parse_nsh)                        \
1307   _(gid_write_nsh)                        \
1308   _(mac_address_write)                    \
1309   _(gid_address_write)                    \
1310   _(src_dst_serdes)                       \
1311   _(write_mac_in_lcaf)                    \
1312   _(src_dst_deser_bad_afi)                \
1313   _(src_dst_with_vni_serdes)
1314
1315 static int
1316 lisp_cp_types_tests (vlib_main_t * vm, unformat_input_t * input)
1317 {
1318   clib_error_t *error;
1319
1320 #define _(_test_name)                                   \
1321   error = test_ ## _test_name ();                       \
1322   if (error)                                            \
1323     {                                                   \
1324       fformat (stderr, "FAIL: test_" #_test_name "\n"); \
1325       return -1;                                        \
1326     }                                                   \
1327   else                                                  \
1328       fformat (stderr, "PASS: test_" #_test_name "\n"); \
1329
1330   foreach_test_case
1331 #undef _
1332     return 0;
1333 }
1334
1335 #undef _assert
1336
1337 static clib_error_t *
1338 lisp_cp_test (vlib_main_t * vm, unformat_input_t * input,
1339               vlib_cli_command_t * cmd_arg)
1340 {
1341   int res = 0;
1342
1343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1344     {
1345       if (unformat (input, "serdes"))
1346         {
1347           res = lisp_cp_serdes_tests (vm, input);
1348         }
1349       if (unformat (input, "types"))
1350         {
1351           res = lisp_cp_types_tests (vm, input);
1352         }
1353       else if (unformat (input, "all"))
1354         {
1355           if ((res = lisp_cp_serdes_tests (vm, input)))
1356             goto done;
1357           if ((res = lisp_cp_types_tests (vm, input)))
1358             goto done;
1359         }
1360       else
1361         break;
1362     }
1363
1364 done:
1365   if (res)
1366     return clib_error_return (0, "rbtree unit test failed");
1367   return 0;
1368 }
1369
1370 VLIB_CLI_COMMAND (lisp_cp_command, static) =
1371 {
1372   .path = "test lisp cp",
1373   .short_help = "lisp cp internal unit tests",
1374   .function = lisp_cp_test,
1375 };
1376
1377 #include <vlib/unix/plugin.h>
1378 #include <vpp/app/version.h>
1379
1380 VLIB_PLUGIN_REGISTER () = {
1381     .version = VPP_BUILD_VER,
1382     .description = "Test Locator ID Separation Protocol (LISP)",
1383     .default_disabled = 1,
1384 };
1385
1386 /*
1387  * fd.io coding-style-patch-verification: ON
1388  *
1389  * Local Variables:
1390  * eval: (c-set-style "gnu")
1391  * End:
1392  */