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:
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.
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>
25 error = CLIB_ERROR_ASSERT (e); \
28 fformat(stderr, "FAIL: line %d \n\n", __LINE__); \
33 print_chunk (u8 * b, int *offset, int c, char *des)
35 int i, n = offset[0] + c;;
36 for (i = offset[0]; i < n; i++)
38 printf ("0x%02x, ", b[i]);
40 printf (" // %s\n", des);
45 print_map_request (map_request_hdr_t * h)
47 #define pchunk(_count, _desc) \
48 print_chunk((u8 *)h, &offset, _count, _desc)
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");
68 test_lisp_msg_push_ecm ()
70 vlib_main_t *vm = vlib_get_main ();
71 clib_error_t *error = 0;
75 int lp = 0x15, rp = 0x14;
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;
83 la.type = GID_ADDR_IP_PREFIX;
84 la.ippref.addr.ip.ip4.as_u32 = 0xa1b2c3d4;
85 la.ippref.addr.version = AF_IP4;
87 ra.type = GID_ADDR_IP_PREFIX;
88 ra.ippref.addr.ip.ip4.as_u32 = 0x90817263;
89 ra.ippref.addr.version = AF_IP4;
91 ecm_hdr_t *lh = lisp_msg_push_ecm (vm, b, lp, rp, &la, &ra);
93 u8 expected_ecm_hdr[] = {
94 0x80, 0x00, 0x00, 0x00
96 _assert (0 == memcmp (expected_ecm_hdr, lh, sizeof (expected_ecm_hdr)));
98 ip4_header_t *ih = (ip4_header_t *) (lh + 1);
99 /* clear ip checksum */
100 clib_memset ((u8 *) ih + 10, 0, 2);
102 u8 expected_ip4_hdr[] = {
103 0x45, /* version; IHL */
105 0x03, 0xa0, /* total length */
106 0x00, 0x00, /* identification */
107 0x40, 0x00, /* flags; fragment offset*/
110 0x00, 0x00, /* header checksum */
111 0xd4, 0xc3, 0xb2, 0xa1, /* src IP */
112 0x63, 0x72, 0x81, 0x90, /* dst IP */
115 _assert (0 == memcmp (ih, expected_ip4_hdr, sizeof (expected_ip4_hdr)));
117 udp_header_t *uh = (udp_header_t *) (ih + 1);
118 /* clear udp checksum */
119 clib_memset ((u8 *) uh + 6, 0, 2);
121 u8 expected_udp_hdr[] = {
122 0x00, 0x15, /* src port */
123 0x00, 0x14, /* dst port */
124 0x03, 0x8c, /* length */
125 0x00, 0x00, /* checksum */
128 _assert (0 == memcmp (uh, expected_udp_hdr, sizeof (expected_udp_hdr)));
135 static clib_error_t *
136 test_lisp_msg_parse_mapping_record ()
138 clib_error_t *error = 0;
141 vlib_buffer_t *b = 0;
145 b = clib_mem_alloc (buff_len);
146 clib_memset ((u8 *) b, 0, buff_len);
148 u8 map_reply_records[] = {
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 */
159 0x0c, /* m-prority */
161 0x00, 0x00, /* unused flags */
162 0x00, 0x01, /* Loc-AFI */
163 0xaa, 0xbb, 0xcc, 0xdd, /* Loator */
166 b->current_length = buff_len;
167 clib_memcpy (b->data, map_reply_records, sizeof (map_reply_records));
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);
187 static map_request_hdr_t *
188 build_map_request (lisp_cp_main_t * lcm, vlib_buffer_t * b,
189 gid_address_t * rlocs)
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;
196 map_request_hdr_t *h = 0;
197 clib_memset (deid, 0, sizeof (deid[0]));
198 clib_memset (seid, 0, sizeof (seid[0]));
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;
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;
211 h = lisp_msg_put_mreq (lcm, b, seid, deid, rlocs,
212 is_smr_invoked, rloc_probe_set, &nonce);
218 generate_rlocs (gid_address_t ** rlocs, u32 * count)
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);
224 gid_address_type (gid_addr) = GID_ADDR_IP_PREFIX;
226 ip_addr_version (addr) = AF_IP4;
227 ip_addr_v4 (addr).data_u32 = 0x10203040;
228 vec_add1 (rlocs[0], gid_addr[0]);
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]);
238 static clib_error_t *
239 test_lisp_msg_parse ()
242 lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
243 map_request_hdr_t *h;
245 clib_error_t *error = 0;
247 gid_address_t *rlocs_decode = 0, *rlocs = 0;
248 u32 rloc_count_parse = 0;
250 u8 *data = clib_mem_alloc (500);
251 clib_memset (data, 0, 500);
252 b = (vlib_buffer_t *) data;
254 generate_rlocs (&rlocs_decode, &rloc_count_parse);
255 h = build_map_request (lcm, b, rlocs_decode);
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);
264 u8 rloc_count = MREQ_ITR_RLOC_COUNT (h) + 1;
265 lisp_msg_parse_itr_rlocs (b, &rlocs, rloc_count);
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);
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);
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);
283 clib_mem_free (data);
289 static clib_error_t *
290 test_lisp_msg_put_mreq_with_lcaf ()
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;
298 ip_prefix_version (&ippref) = AF_IP4;
299 ip4_address_t *ip = &ip_prefix_v4 (&ippref);
300 ip->as_u32 = 0x11223344;
304 .type = GID_ADDR_IP_PREFIX,
311 u8 *data = clib_mem_alloc (500);
312 clib_memset (data, 0, 500);
314 h = build_map_request (lcm, (vlib_buffer_t *) data, rlocs);
316 /* clear Nonce to simplify comparison */
317 clib_memset ((u8 *) h + 4, 0, 8);
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 */
328 0x40, 0x03, /* AFI = LCAF*/
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 */
336 0x00, 0x01, /* AFI = ipv4 */
337 0x44, 0x33, 0x22, 0x11, /* ITR-RLOC Address 1 */
341 0x18, /* EID mask-len */
342 0x00, 0x01, /* EID-prefix-AFI */
343 0xf0, 0xde, 0xbc, 0x9a, /* EID-prefix */
346 _assert (0 == memcmp (expected_data, (u8 *) h, sizeof (expected_data)));
348 clib_mem_free (data);
352 static clib_error_t *
353 test_lisp_msg_put_mreq ()
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;
361 u8 *data = clib_mem_alloc (500);
362 clib_memset (data, 0, 500);
364 generate_rlocs (&rlocs, &rloc_count);
365 h = build_map_request (lcm, (vlib_buffer_t *) data, rlocs);
367 /* clear Nonce to simplify comparison */
368 clib_memset ((u8 *) h + 4, 0, 8);
370 print_map_request (h);
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 */
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 */
390 0x18, /* EID mask-len */
391 0x00, 0x01, /* EID-prefix-AFI */
392 0xf0, 0xde, 0xbc, 0x9a, /* EID-prefix */
395 _assert (0 == memcmp (expected_data, (u8 *) h, sizeof (expected_data)));
398 clib_mem_free (data);
402 /* generate a vector of eid records */
404 build_test_map_records ()
406 mapping_t *records = 0;
409 .ttl = MAP_REGISTER_DEFAULT_TTL,
411 .type = GID_ADDR_MAC,
412 .mac = {1, 2, 3, 4, 5, 6},
422 .type = GID_ADDR_IP_PREFIX,
425 .ip.ip4.as_u32 = 0x99887766,
432 vec_add1 (r.locators, loc);
433 vec_add1 (records, r);
439 free_test_map_records (mapping_t * maps)
442 vec_foreach (map, maps)
444 vec_free (map->locators);
449 static clib_error_t *
450 test_lisp_map_register ()
453 clib_error_t *error = 0;
456 mapping_t *records = build_test_map_records ();
458 u8 *data = clib_mem_alloc (500);
459 clib_memset (data, 0, 500);
460 b = (vlib_buffer_t *) data;
462 lisp_msg_put_map_register (b, records, 1 /* want map notify */ ,
463 20 /* length of HMAC_SHA_1_96 */ ,
465 free_test_map_records (records);
467 /* clear Nonce to simplify comparison */
468 clib_memset ((u8 *) b->data + 4, 0, 8);
470 /* clear authentication data */
471 clib_memset ((u8 *) b->data + 16, 0, 20);
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 */
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 */
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 */
500 _assert (0 == memcmp (expected_data, b->data, sizeof (expected_data)));
502 clib_mem_free (data);
506 static vlib_buffer_t *
507 create_buffer (u8 * data, u32 data_len)
511 u8 *buf_data = clib_mem_alloc (500);
512 clib_memset (buf_data, 0, 500);
513 b = (vlib_buffer_t *) buf_data;
515 u8 *p = vlib_buffer_put_uninit (b, data_len);
516 clib_memcpy (p, data, data_len);
521 static clib_error_t *
522 test_lisp_parse_map_reply ()
524 clib_error_t *error = 0;
526 u8 map_reply_data[] =
528 0x00, 0x00, 0x00, 0x01, /* type; rsvd; mapping count */
529 0x00, 0x00, 0x00, 0x00,
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);
537 u8 map_reply_data2[] =
539 0x00, 0x00, 0x00, 0x01, /* type; rsvd */
540 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, /* nonce */
543 /* 1. record - incomplete */
544 0x01, 0x02, 0x03, 0x04, /* record TTL */
545 0x01, /* locator count */
548 b = create_buffer (map_reply_data2, sizeof (map_reply_data2));
549 mrecs = parse_map_reply (b);
550 _assert (0 == mrecs);
556 static clib_error_t *
557 test_lisp_parse_lcaf ()
560 clib_error_t *error = 0;
564 vlib_buffer_t *b = 0;
567 b = clib_mem_alloc (buff_len);
568 clib_memset ((u8 *) b, 0, buff_len);
570 u8 map_reply_records[] =
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 */
583 0x0c, /* m-prority */
585 0x00, 0x00, /* unused flags */
586 0x40, 0x03, /* Loc-AFI = LCAF*/
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 */
601 0x05, /* m-prority */
603 0x00, 0x00, /* unused flags */
604 0x40, 0x03, /* Loc-AFI = LCAF*/
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 */
622 0x0c, /* m-prority */
624 0x00, 0x00, /* unused flags */
625 0x00, 0x01, /* Loc-AFI */
626 0xaa, 0xbb, 0xcc, 0xdd, /* Loator */
629 b->current_length = buff_len;
630 memcpy (b->data, map_reply_records, sizeof (map_reply_records));
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);
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);
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));
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);
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));
660 /* 3rd locator - simple ipv4 address */
661 _assert (gid_address_type (&locs[2].address) == GID_ADDR_IP_PREFIX);
665 for (i = 0; i < 3; i++)
666 locator_free (&locs[i]);
671 #define foreach_test_case \
672 _(lisp_msg_put_mreq) \
673 _(lisp_msg_put_mreq_with_lcaf) \
674 _(lisp_msg_push_ecm) \
676 _(lisp_msg_parse_mapping_record) \
677 _(lisp_parse_map_reply) \
682 lisp_cp_serdes_tests (vlib_main_t * vm, unformat_input_t * input)
686 #define _(_test_name) \
687 error = test_ ## _test_name (); \
690 fformat (stderr, "FAIL: test_" #_test_name "\n"); \
694 fformat (stderr, "PASS: test_" #_test_name "\n"); \
701 static clib_error_t *
702 test_locator_type (void)
704 clib_error_t *error = 0;
705 gid_address_t _gid_addr, *gid = &_gid_addr;
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;
716 locator_t loc1, loc2 = {
725 locator_copy (&loc1, &loc2);
726 _assert (0 == locator_cmp (&loc1, &loc2));
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
742 .type = LCAF_INSTANCE_ID,
746 .gid_addr = &nested_gid}
748 gid_address_type (gid) = GID_ADDR_LCAF;
749 gid_address_lcaf (gid) = lcaf;
751 loc2.address = gid[0];
752 locator_copy (&loc1, &loc2);
754 _assert (0 == locator_cmp (&loc1, &loc2));
757 locator_free (&loc1);
761 static clib_error_t *
762 test_gid_parse_ip_pref ()
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;
770 0x00, 0x01, /* AFI = IPv4 */
771 0x10, 0xbb, 0xcc, 0xdd, /* ipv4 address */
774 u32 len = gid_address_parse (data, gid_addr);
776 gid_address_copy (copy, gid_addr);
777 _assert (0 == gid_address_cmp (copy, gid_addr));
782 static clib_error_t *
783 test_gid_parse_mac ()
785 clib_error_t *error = 0;
786 gid_address_t _gid, *gid = &_gid;
787 gid_address_t _gid_copy, *gid_copy = &_gid_copy;
791 0x40, 0x05, /* AFI = MAC address */
792 0x10, 0xbb, 0xcc, 0xdd, /* MAC */
796 u32 len = gid_address_parse (data, gid);
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));
805 static clib_error_t *
806 test_gid_write_nsh (void)
808 clib_error_t *error = 0;
810 u8 *b = clib_mem_alloc (500);
811 clib_memset (b, 0, 500);
817 .type = GID_ADDR_NSH,
820 u16 len = gid_address_put (b, &g);
824 0x40, 0x03, 0x00, 0x00, /* AFI = LCAF*/
825 0x11, 0x00, 0x00, 0x04, /* type = SPI LCAF, length = 4 */
827 /* Service Path ID, Service index */
828 0x11, 0x22, 0x33, 0x42, /* SPI, SI */
831 _assert (sizeof (expected) == len);
832 _assert (0 == memcmp (expected, b, len));
838 static clib_error_t *
839 test_gid_parse_nsh ()
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;
845 clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
846 clib_memset (copy, 0, sizeof (copy[0]));
850 0x40, 0x03, 0x00, 0x00, /* AFI = LCAF*/
851 0x11, 0x00, 0x00, 0x04, /* type = SPI LCAF, length = 4 */
853 /* Service Path ID, Service index */
854 0x55, 0x99, 0x42, 0x09, /* SPI, SI */
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);
867 gid_address_free (copy);
868 gid_address_free (gid_addr);
872 static clib_error_t *
873 test_gid_parse_lcaf ()
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;
879 clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
880 clib_memset (gid_addr_copy, 0, sizeof (gid_addr_copy[0]));
884 0x40, 0x03, /* AFI = LCAF*/
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 */
897 u32 len = gid_address_parse (data, gid_addr);
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);
907 gid_address_free (gid_addr);
908 gid_address_free (gid_addr_copy);
912 /* recursive LCAFs are not supported */
914 static clib_error_t *
915 test_gid_parse_lcaf_complex ()
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;
921 clib_memset (gid_addr, 0, sizeof (gid_addr[0]));
922 clib_memset (gid_addr_copy, 0, sizeof (gid_addr_copy[0]));
925 0x40, 0x03, /* AFI = LCAF */
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 */
935 0x40, 0x03, /* AFI = LCAF */
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 */
944 0x40, 0x03, /* AFI = LCAF */
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 */
953 0x00, 0x02, /* AFI = IPv6 */
955 0x10, 0xbb, 0xcc, 0xdd,
956 0x10, 0xbb, 0xcc, 0xdd,
957 0x10, 0xbb, 0xcc, 0xdd,
958 0x10, 0xbb, 0xcc, 0xdd, /* ipv6 address */
961 u32 len = gid_address_parse (data, gid_addr);
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);
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);
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);
980 _assert (v->vni == 0x0c);
981 _assert (v->vni_mask_len == 0x17);
984 _assert (gid_address_type (tmp) == GID_ADDR_LCAF);
985 lcaf = &gid_address_lcaf (tmp);
987 _assert (lcaf->type == LCAF_INSTANCE_ID);
989 _assert (v->vni == 0x0d);
990 _assert (v->vni_mask_len == 0x16);
993 _assert (gid_address_type (tmp) == GID_ADDR_IP_PREFIX);
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);
1004 gid_address_free (gid_addr);
1005 gid_address_free (gid_addr_copy);
1010 static clib_error_t *
1011 test_write_mac_in_lcaf (void)
1013 clib_error_t *error = 0;
1015 u8 *b = clib_mem_alloc (500);
1016 clib_memset (b, 0, 500);
1019 .mac = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6},
1022 .type = GID_ADDR_MAC,
1025 u16 len = gid_address_put (b, &g);
1029 0x40, 0x03, /* AFI = LCAF */
1030 0x00, /* reserved1 */
1032 0x02, /* LCAF type = Instance ID */
1033 0x10, /* IID/IID mask len */
1034 0x00, 0x0c, /* length */
1035 0x01, 0x02, 0x03, 0x04, /* Instance ID / VNI */
1037 0x40, 0x05, /* AFI = MAC */
1038 0x01, 0x02, 0x03, 0x04,
1039 0x05, 0x06 /* MAC */
1042 _assert (sizeof (expected) == len);
1043 _assert (0 == memcmp (expected, b, len));
1049 static clib_error_t *
1050 test_mac_address_write (void)
1052 clib_error_t *error = 0;
1054 u8 *b = clib_mem_alloc (500);
1055 clib_memset (b, 0, 500);
1058 .mac = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6},
1059 .type = GID_ADDR_MAC,
1062 u16 len = gid_address_put (b, &g);
1067 0x40, 0x05, /* AFI = MAC */
1068 0x01, 0x02, 0x03, 0x04,
1069 0x05, 0x06 /* MAC */
1072 _assert (0 == memcmp (expected, b, len));
1078 static clib_error_t *
1079 test_src_dst_with_vni_serdes (void)
1081 clib_error_t *error = 0;
1082 u8 *b = clib_mem_alloc (500);
1083 clib_memset (b, 0, 500);
1087 .type = FID_ADDR_IP_PREF,
1094 .ip.ip4.data = { 0x1, 0x2, 0x3, 0x0 }
1101 .type = FID_ADDR_IP_PREF,
1108 .ip.ip4.data = { 0x9, 0x8, 0x0, 0x0 }
1122 .type = GID_ADDR_SRC_DST,
1128 u16 size_to_put = gid_address_size_to_put (&g);
1129 _assert (36 == size_to_put);
1130 _assert (0 == gid_address_len (&g));
1132 u16 write_len = gid_address_put (b, &g);
1133 _assert (size_to_put == write_len);
1135 u8 expected_data[] =
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 */
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 */
1145 0x00, 0x01, /* AFI = ip4 */
1146 0x01, 0x02, 0x03, 0x00, /* source */
1148 0x00, 0x01, /* AFI = ip4 */
1149 0x09, 0x08, 0x00, 0x00, /* destination */
1152 _assert (0 == memcmp (expected_data, b, sizeof (expected_data)));
1155 clib_memset (&p, 0, sizeof (p));
1156 _assert (write_len == gid_address_parse (b, &p));
1157 _assert (0 == gid_address_cmp (&g, &p));
1163 static clib_error_t *
1164 test_src_dst_deser_bad_afi (void)
1166 clib_error_t *error = 0;
1168 u8 expected_data[] =
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 */
1174 0xde, 0xad, /* AFI = bad value */
1175 0x11, 0x22, 0x33, 0x44,
1176 0x55, 0x66, /* source */
1178 0x40, 0x05, /* AFI = MAC */
1179 0x10, 0x21, 0x32, 0x43,
1180 0x54, 0x65, /* destination */
1184 _assert (~0 == gid_address_parse (expected_data, &p));
1189 static clib_error_t *
1190 test_src_dst_serdes (void)
1192 clib_error_t *error = 0;
1194 u8 *b = clib_mem_alloc (500);
1195 clib_memset (b, 0, 500);
1197 fid_address_t src = {
1198 .type = FID_ADDR_MAC,
1199 .mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}
1202 fid_address_t dst = {
1203 .type = FID_ADDR_MAC,
1204 .mac = {0x10, 0x21, 0x32, 0x43, 0x54, 0x65}
1207 source_dest_t sd = {
1214 .type = GID_ADDR_SRC_DST,
1219 u16 size_to_put = gid_address_size_to_put (&g);
1220 _assert (28 == size_to_put);
1221 _assert (0 == gid_address_len (&g));
1223 u16 write_len = gid_address_put (b, &g);
1224 _assert (size_to_put == write_len);
1226 u8 expected_data[] =
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 */
1232 0x40, 0x05, /* AFI = MAC */
1233 0x11, 0x22, 0x33, 0x44,
1234 0x55, 0x66, /* source */
1236 0x40, 0x05, /* AFI = MAC */
1237 0x10, 0x21, 0x32, 0x43,
1238 0x54, 0x65, /* destination */
1241 _assert (0 == memcmp (expected_data, b, sizeof (expected_data)));
1244 clib_memset (&p, 0, sizeof (p));
1245 _assert (write_len == gid_address_parse (b, &p));
1246 _assert (0 == gid_address_cmp (&g, &p));
1252 static clib_error_t *
1253 test_gid_address_write (void)
1255 clib_error_t *error = 0;
1256 ip_prefix_t ippref_data, *ippref = &ippref_data;
1258 u8 *b = clib_mem_alloc (500);
1259 clib_memset (b, 0, 500);
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;
1267 .ippref = ippref[0],
1268 .type = GID_ADDR_IP_PREFIX,
1273 _assert (18 == gid_address_size_to_put (&g));
1274 _assert (gid_address_len (&g) == 9);
1276 u16 write_len = gid_address_put (b, &g);
1277 _assert (18 == write_len);
1279 u8 expected_gid_data[] =
1281 0x40, 0x03, /* AFI = LCAF */
1282 0x00, /* reserved1 */
1284 0x02, /* LCAF type = Instance ID */
1285 0x18, /* IID/VNI mask len */
1286 0x00, 0x0a, /* length */
1287 0x01, 0x02, 0x03, 0x04, /* Instance ID / VNI */
1289 0x00, 0x01, /* AFI = IPv4 */
1290 0xdd, 0xcc, 0xbb, 0xaa, /* ipv4 addr */
1293 _assert (0 == memcmp (expected_gid_data, b, sizeof (expected_gid_data)));
1299 #undef foreach_test_case
1301 #define foreach_test_case \
1303 _(gid_parse_ip_pref) \
1308 _(mac_address_write) \
1309 _(gid_address_write) \
1311 _(write_mac_in_lcaf) \
1312 _(src_dst_deser_bad_afi) \
1313 _(src_dst_with_vni_serdes)
1316 lisp_cp_types_tests (vlib_main_t * vm, unformat_input_t * input)
1318 clib_error_t *error;
1320 #define _(_test_name) \
1321 error = test_ ## _test_name (); \
1324 fformat (stderr, "FAIL: test_" #_test_name "\n"); \
1328 fformat (stderr, "PASS: test_" #_test_name "\n"); \
1337 static clib_error_t *
1338 lisp_cp_test (vlib_main_t * vm, unformat_input_t * input,
1339 vlib_cli_command_t * cmd_arg)
1343 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1345 if (unformat (input, "serdes"))
1347 res = lisp_cp_serdes_tests (vm, input);
1349 if (unformat (input, "types"))
1351 res = lisp_cp_types_tests (vm, input);
1353 else if (unformat (input, "all"))
1355 if ((res = lisp_cp_serdes_tests (vm, input)))
1357 if ((res = lisp_cp_types_tests (vm, input)))
1366 return clib_error_return (0, "rbtree unit test failed");
1370 VLIB_CLI_COMMAND (lisp_cp_command, static) =
1372 .path = "test lisp cp",
1373 .short_help = "lisp cp internal unit tests",
1374 .function = lisp_cp_test,
1377 #include <vlib/unix/plugin.h>
1378 #include <vpp/app/version.h>
1380 VLIB_PLUGIN_REGISTER () = {
1381 .version = VPP_BUILD_VER,
1382 .description = "Test Locator ID Separation Protocol (LISP)",
1383 .default_disabled = 1,
1387 * fd.io coding-style-patch-verification: ON
1390 * eval: (c-set-style "gnu")