lisp: Move to plugin
[vpp.git] / src / plugins / lisp / lisp-cp / lisp_cp_test.c
1 /*
2  * Copyright (c) 2015 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 <vat/vat.h>
17 #include <vlibapi/api.h>
18 #include <vlibmemory/api.h>
19 #include <vppinfra/error.h>
20
21 #include <vnet/ip/ip_format_fns.h>
22 #include <vnet/ethernet/ethernet_format_fns.h>
23 #include <lisp/lisp-cp/lisp_types.h>
24
25 /* define message IDs */
26 #include <lisp/lisp-cp/lisp.api_enum.h>
27 #include <lisp/lisp-cp/lisp.api_types.h>
28 #include <vpp/api/vpe.api_types.h>
29
30 typedef struct
31 {
32   /* API message ID base */
33   u16 msg_id_base;
34   vat_main_t *vat_main;
35   u32 ping_id;
36 } lisp_test_main_t;
37
38 lisp_test_main_t lisp_test_main;
39
40 #define __plugin_msg_base lisp_test_main.msg_id_base
41 #include <vlibapi/vat_helper_macros.h>
42
43 /* Macro to finish up custom dump fns */
44 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
45 #define FINISH                                  \
46     vec_add1 (s, 0);                            \
47     vl_print (handle, (char *)s);               \
48     vec_free (s);                               \
49     return handle;
50
51 typedef struct
52 {
53   u32 spi;
54   u8 si;
55 } __attribute__ ((__packed__)) lisp_nsh_api_t;
56
57 #define LISP_PING(_lm, mp_ping)                                         \
58   if (!(_lm)->ping_id)                                                  \
59     (_lm)->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC)); \
60   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));          \
61   mp_ping->_vl_msg_id = htons ((_lm)->ping_id);                         \
62   mp_ping->client_index = vam->my_client_index;                         \
63   fformat (vam->ofp, "Sending ping id=%d\n", (_lm)->ping_id);           \
64   vam->result_ready = 0;                                                \
65
66 uword
67 unformat_nsh_address (unformat_input_t * input, va_list * args)
68 {
69   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
70   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
71 }
72
73 static u8 *
74 format_nsh_address_vat (u8 * s, va_list * args)
75 {
76   nsh_t *a = va_arg (*args, nsh_t *);
77   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
78 }
79
80 static u8 *
81 format_lisp_flat_eid (u8 * s, va_list * args)
82 {
83   vl_api_eid_t *eid = va_arg (*args, vl_api_eid_t *);
84
85   switch (eid->type)
86     {
87     case EID_TYPE_API_PREFIX:
88       if (eid->address.prefix.address.af)
89         return format (s, "%U/%d", format_ip6_address,
90                        eid->address.prefix.address.un.ip6,
91                        eid->address.prefix.len);
92       return format (s, "%U/%d", format_ip4_address,
93                      eid->address.prefix.address.un.ip4,
94                      eid->address.prefix.len);
95     case EID_TYPE_API_MAC:
96       return format (s, "%U", format_ethernet_address, eid->address.mac);
97     case EID_TYPE_API_NSH:
98       return format (s, "%U", format_nsh_address_vat, eid->address.nsh);
99     }
100   return 0;
101 }
102
103 static u8 *
104 format_lisp_eid_vat (u8 * s, va_list * args)
105 {
106   vl_api_eid_t *deid = va_arg (*args, vl_api_eid_t *);
107   vl_api_eid_t *seid = va_arg (*args, vl_api_eid_t *);
108   u8 is_src_dst = (u8) va_arg (*args, int);
109
110   if (is_src_dst)
111     s = format (s, "%U|", format_lisp_flat_eid, seid);
112
113   s = format (s, "%U", format_lisp_flat_eid, deid);
114
115   return s;
116 }
117
118
119
120 /* *INDENT-OFF* */
121 /** Used for parsing LISP eids */
122 typedef struct lisp_eid_vat_t_
123 {
124   union {
125     ip46_address_t ip;
126     mac_address_t mac;
127     lisp_nsh_api_t nsh;
128   } addr;
129   /**< prefix length if IP */
130   u32 len;
131   /**< type of eid */
132   u8 type;
133 } __clib_packed lisp_eid_vat_t;
134 /* *INDENT-ON* */
135
136 static uword
137 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
138 {
139   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
140
141   clib_memset (a, 0, sizeof (a[0]));
142
143   if (unformat (input, "%U/%d", unformat_ip46_address, a->addr.ip, &a->len))
144     {
145       a->type = 0;              /* ip prefix type */
146     }
147   else if (unformat (input, "%U", unformat_ethernet_address, &a->addr.mac))
148     {
149       a->type = 1;              /* mac type */
150     }
151   else if (unformat (input, "%U", unformat_nsh_address, a->addr.nsh))
152     {
153       a->type = 2;              /* NSH type */
154       a->addr.nsh.spi = clib_host_to_net_u32 (a->addr.nsh.spi);
155     }
156   else
157     {
158       return 0;
159     }
160
161   if (a->type == 0)
162     {
163       if (ip46_address_is_ip4 (&a->addr.ip))
164         return a->len > 32 ? 1 : 0;
165       else
166         return a->len > 128 ? 1 : 0;
167     }
168
169   return 1;
170 }
171
172 static void
173 lisp_eid_put_vat (vl_api_eid_t * eid, const lisp_eid_vat_t * vat_eid)
174 {
175   eid->type = vat_eid->type;
176   switch (eid->type)
177     {
178     case EID_TYPE_API_PREFIX:
179       if (ip46_address_is_ip4 (&vat_eid->addr.ip))
180         {
181           clib_memcpy (&eid->address.prefix.address.un.ip4,
182                        &vat_eid->addr.ip.ip4, 4);
183           eid->address.prefix.address.af = ADDRESS_IP4;
184           eid->address.prefix.len = vat_eid->len;
185         }
186       else
187         {
188           clib_memcpy (&eid->address.prefix.address.un.ip6,
189                        &vat_eid->addr.ip.ip6, 16);
190           eid->address.prefix.address.af = ADDRESS_IP6;
191           eid->address.prefix.len = vat_eid->len;
192         }
193       return;
194     case EID_TYPE_API_MAC:
195       clib_memcpy (&eid->address.mac, &vat_eid->addr.mac,
196                    sizeof (eid->address.mac));
197       return;
198     case EID_TYPE_API_NSH:
199       clib_memcpy (&eid->address.nsh, &vat_eid->addr.nsh,
200                    sizeof (eid->address.nsh));
201       return;
202     default:
203       ASSERT (0);
204       return;
205     }
206 }
207
208 static int
209 api_lisp_add_del_locator_set (vat_main_t * vam)
210 {
211   unformat_input_t *input = vam->input;
212   vl_api_lisp_add_del_locator_set_t *mp;
213   u8 is_add = 1;
214   u8 *locator_set_name = NULL;
215   u8 locator_set_name_set = 0;
216   vl_api_local_locator_t locator, *locators = 0;
217   u32 sw_if_index, priority, weight;
218   u32 data_len = 0;
219
220   int ret;
221   /* Parse args required to build the message */
222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
223     {
224       if (unformat (input, "del"))
225         {
226           is_add = 0;
227         }
228       else if (unformat (input, "locator-set %s", &locator_set_name))
229         {
230           locator_set_name_set = 1;
231         }
232       else if (unformat (input, "sw_if_index %u p %u w %u",
233                          &sw_if_index, &priority, &weight))
234         {
235           locator.sw_if_index = htonl (sw_if_index);
236           locator.priority = priority;
237           locator.weight = weight;
238           vec_add1 (locators, locator);
239         }
240       else
241         if (unformat
242             (input, "iface %U p %u w %u", unformat_sw_if_index, vam,
243              &sw_if_index, &priority, &weight))
244         {
245           locator.sw_if_index = htonl (sw_if_index);
246           locator.priority = priority;
247           locator.weight = weight;
248           vec_add1 (locators, locator);
249         }
250       else
251         break;
252     }
253
254   if (locator_set_name_set == 0)
255     {
256       errmsg ("missing locator-set name");
257       vec_free (locators);
258       return -99;
259     }
260
261   if (vec_len (locator_set_name) > 64)
262     {
263       errmsg ("locator-set name too long");
264       vec_free (locator_set_name);
265       vec_free (locators);
266       return -99;
267     }
268   vec_add1 (locator_set_name, 0);
269
270   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
271
272   /* Construct the API message */
273   M2 (LISP_ADD_DEL_LOCATOR_SET, mp, data_len);
274
275   mp->is_add = is_add;
276   clib_memcpy (mp->locator_set_name, locator_set_name,
277                vec_len (locator_set_name));
278   vec_free (locator_set_name);
279
280   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
281   if (locators)
282     clib_memcpy (mp->locators, locators, data_len);
283   vec_free (locators);
284
285   /* send it... */
286   S (mp);
287
288   /* Wait for a reply... */
289   W (ret);
290   return ret;
291 }
292
293 static int
294 api_lisp_add_del_locator (vat_main_t * vam)
295 {
296   unformat_input_t *input = vam->input;
297   vl_api_lisp_add_del_locator_t *mp;
298   u32 tmp_if_index = ~0;
299   u32 sw_if_index = ~0;
300   u8 sw_if_index_set = 0;
301   u8 sw_if_index_if_name_set = 0;
302   u32 priority = ~0;
303   u8 priority_set = 0;
304   u32 weight = ~0;
305   u8 weight_set = 0;
306   u8 is_add = 1;
307   u8 *locator_set_name = NULL;
308   u8 locator_set_name_set = 0;
309   int ret;
310
311   /* Parse args required to build the message */
312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
313     {
314       if (unformat (input, "del"))
315         {
316           is_add = 0;
317         }
318       else if (unformat (input, "locator-set %s", &locator_set_name))
319         {
320           locator_set_name_set = 1;
321         }
322       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
323                          &tmp_if_index))
324         {
325           sw_if_index_if_name_set = 1;
326           sw_if_index = tmp_if_index;
327         }
328       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
329         {
330           sw_if_index_set = 1;
331           sw_if_index = tmp_if_index;
332         }
333       else if (unformat (input, "p %d", &priority))
334         {
335           priority_set = 1;
336         }
337       else if (unformat (input, "w %d", &weight))
338         {
339           weight_set = 1;
340         }
341       else
342         break;
343     }
344
345   if (locator_set_name_set == 0)
346     {
347       errmsg ("missing locator-set name");
348       return -99;
349     }
350
351   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
352     {
353       errmsg ("missing sw_if_index");
354       vec_free (locator_set_name);
355       return -99;
356     }
357
358   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
359     {
360       errmsg ("cannot use both params interface name and sw_if_index");
361       vec_free (locator_set_name);
362       return -99;
363     }
364
365   if (priority_set == 0)
366     {
367       errmsg ("missing locator-set priority");
368       vec_free (locator_set_name);
369       return -99;
370     }
371
372   if (weight_set == 0)
373     {
374       errmsg ("missing locator-set weight");
375       vec_free (locator_set_name);
376       return -99;
377     }
378
379   if (vec_len (locator_set_name) > 64)
380     {
381       errmsg ("locator-set name too long");
382       vec_free (locator_set_name);
383       return -99;
384     }
385   vec_add1 (locator_set_name, 0);
386
387   /* Construct the API message */
388   M (LISP_ADD_DEL_LOCATOR, mp);
389
390   mp->is_add = is_add;
391   mp->sw_if_index = ntohl (sw_if_index);
392   mp->priority = priority;
393   mp->weight = weight;
394   clib_memcpy (mp->locator_set_name, locator_set_name,
395                vec_len (locator_set_name));
396   vec_free (locator_set_name);
397
398   /* send it... */
399   S (mp);
400
401   /* Wait for a reply... */
402   W (ret);
403   return ret;
404 }
405
406 static int
407 api_lisp_add_del_local_eid (vat_main_t * vam)
408 {
409   unformat_input_t *input = vam->input;
410   vl_api_lisp_add_del_local_eid_t *mp;
411   u8 is_add = 1;
412   u8 eid_set = 0;
413   lisp_eid_vat_t _eid, *eid = &_eid;
414   u8 *locator_set_name = 0;
415   u8 locator_set_name_set = 0;
416   u32 vni = 0;
417   u16 key_id = 0;
418   u8 *key = 0;
419   int ret;
420
421   /* Parse args required to build the message */
422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
423     {
424       if (unformat (input, "del"))
425         {
426           is_add = 0;
427         }
428       else if (unformat (input, "vni %d", &vni))
429         {
430           ;
431         }
432       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
433         {
434           eid_set = 1;
435         }
436       else if (unformat (input, "locator-set %s", &locator_set_name))
437         {
438           locator_set_name_set = 1;
439         }
440       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
441         ;
442       else if (unformat (input, "secret-key %_%v%_", &key))
443         ;
444       else
445         break;
446     }
447
448   if (locator_set_name_set == 0)
449     {
450       errmsg ("missing locator-set name");
451       return -99;
452     }
453
454   if (0 == eid_set)
455     {
456       errmsg ("EID address not set!");
457       vec_free (locator_set_name);
458       return -99;
459     }
460
461   if (key && (0 == key_id))
462     {
463       errmsg ("invalid key_id!");
464       return -99;
465     }
466
467   if (vec_len (key) > 64)
468     {
469       errmsg ("key too long");
470       vec_free (key);
471       return -99;
472     }
473
474   if (vec_len (locator_set_name) > 64)
475     {
476       errmsg ("locator-set name too long");
477       vec_free (locator_set_name);
478       return -99;
479     }
480   vec_add1 (locator_set_name, 0);
481
482   /* Construct the API message */
483   M (LISP_ADD_DEL_LOCAL_EID, mp);
484
485   mp->is_add = is_add;
486   lisp_eid_put_vat (&mp->eid, eid);
487   mp->vni = clib_host_to_net_u32 (vni);
488   mp->key.id = key_id;
489   clib_memcpy (mp->locator_set_name, locator_set_name,
490                vec_len (locator_set_name));
491   clib_memcpy (mp->key.key, key, vec_len (key));
492
493   vec_free (locator_set_name);
494   vec_free (key);
495
496   /* send it... */
497   S (mp);
498
499   /* Wait for a reply... */
500   W (ret);
501   return ret;
502 }
503
504 static int
505 api_lisp_add_del_map_server (vat_main_t * vam)
506 {
507   unformat_input_t *input = vam->input;
508   vl_api_lisp_add_del_map_server_t *mp;
509   u8 is_add = 1;
510   u8 ipv4_set = 0;
511   u8 ipv6_set = 0;
512   ip4_address_t ipv4;
513   ip6_address_t ipv6;
514   int ret;
515
516   /* Parse args required to build the message */
517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
518     {
519       if (unformat (input, "del"))
520         {
521           is_add = 0;
522         }
523       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
524         {
525           ipv4_set = 1;
526         }
527       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
528         {
529           ipv6_set = 1;
530         }
531       else
532         break;
533     }
534
535   if (ipv4_set && ipv6_set)
536     {
537       errmsg ("both eid v4 and v6 addresses set");
538       return -99;
539     }
540
541   if (!ipv4_set && !ipv6_set)
542     {
543       errmsg ("eid addresses not set");
544       return -99;
545     }
546
547   /* Construct the API message */
548   M (LISP_ADD_DEL_MAP_SERVER, mp);
549
550   mp->is_add = is_add;
551   if (ipv6_set)
552     {
553       mp->ip_address.af = 1;
554       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
555     }
556   else
557     {
558       mp->ip_address.af = 0;
559       clib_memcpy (mp->ip_address.un.ip4, &ipv4, sizeof (ipv4));
560     }
561
562   /* send it... */
563   S (mp);
564
565   /* Wait for a reply... */
566   W (ret);
567   return ret;
568 }
569
570 static int
571 api_lisp_add_del_map_resolver (vat_main_t * vam)
572 {
573   unformat_input_t *input = vam->input;
574   vl_api_lisp_add_del_map_resolver_t *mp;
575   u8 is_add = 1;
576   u8 ipv4_set = 0;
577   u8 ipv6_set = 0;
578   ip4_address_t ipv4;
579   ip6_address_t ipv6;
580   int ret;
581
582   /* Parse args required to build the message */
583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
584     {
585       if (unformat (input, "del"))
586         {
587           is_add = 0;
588         }
589       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
590         {
591           ipv4_set = 1;
592         }
593       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
594         {
595           ipv6_set = 1;
596         }
597       else
598         break;
599     }
600
601   if (ipv4_set && ipv6_set)
602     {
603       errmsg ("both eid v4 and v6 addresses set");
604       return -99;
605     }
606
607   if (!ipv4_set && !ipv6_set)
608     {
609       errmsg ("eid addresses not set");
610       return -99;
611     }
612
613   /* Construct the API message */
614   M (LISP_ADD_DEL_MAP_RESOLVER, mp);
615
616   mp->is_add = is_add;
617   if (ipv6_set)
618     {
619       mp->ip_address.af = 1;
620       clib_memcpy (mp->ip_address.un.ip6, &ipv6, sizeof (ipv6));
621     }
622   else
623     {
624       mp->ip_address.af = 0;
625       clib_memcpy (mp->ip_address.un.ip6, &ipv4, sizeof (ipv4));
626     }
627
628   /* send it... */
629   S (mp);
630
631   /* Wait for a reply... */
632   W (ret);
633   return ret;
634 }
635
636 static int
637 api_lisp_enable_disable (vat_main_t * vam)
638 {
639   unformat_input_t *input = vam->input;
640   vl_api_lisp_enable_disable_t *mp;
641   u8 is_set = 0;
642   u8 is_enable = 0;
643   int ret;
644
645   /* Parse args required to build the message */
646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
647     {
648       if (unformat (input, "enable"))
649         {
650           is_set = 1;
651           is_enable = 1;
652         }
653       else if (unformat (input, "disable"))
654         {
655           is_set = 1;
656         }
657       else
658         break;
659     }
660
661   if (!is_set)
662     {
663       errmsg ("Value not set");
664       return -99;
665     }
666
667   /* Construct the API message */
668   M (LISP_ENABLE_DISABLE, mp);
669
670   mp->is_enable = is_enable;
671
672   /* send it... */
673   S (mp);
674
675   /* Wait for a reply... */
676   W (ret);
677   return ret;
678 }
679
680 /**
681  * Enable/disable LISP proxy ITR.
682  *
683  * @param vam vpp API test context
684  * @return return code
685  */
686 static int
687 api_lisp_pitr_set_locator_set (vat_main_t * vam)
688 {
689   u8 ls_name_set = 0;
690   unformat_input_t *input = vam->input;
691   vl_api_lisp_pitr_set_locator_set_t *mp;
692   u8 is_add = 1;
693   u8 *ls_name = 0;
694   int ret;
695
696   /* Parse args required to build the message */
697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
698     {
699       if (unformat (input, "del"))
700         is_add = 0;
701       else if (unformat (input, "locator-set %s", &ls_name))
702         ls_name_set = 1;
703       else
704         {
705           errmsg ("parse error '%U'", format_unformat_error, input);
706           return -99;
707         }
708     }
709
710   if (!ls_name_set)
711     {
712       errmsg ("locator-set name not set!");
713       return -99;
714     }
715
716   M (LISP_PITR_SET_LOCATOR_SET, mp);
717
718   mp->is_add = is_add;
719   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
720   vec_free (ls_name);
721
722   /* send */
723   S (mp);
724
725   /* wait for reply */
726   W (ret);
727   return ret;
728 }
729
730 static int
731 api_lisp_use_petr (vat_main_t * vam)
732 {
733   unformat_input_t *input = vam->input;
734   vl_api_lisp_use_petr_t *mp;
735   u8 is_add = 0;
736   ip_address_t ip;
737   int ret;
738
739   clib_memset (&ip, 0, sizeof (ip));
740
741   /* Parse args required to build the message */
742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
743     {
744       if (unformat (input, "disable"))
745         is_add = 0;
746       else
747         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
748         {
749           is_add = 1;
750           ip_addr_version (&ip) = AF_IP4;
751         }
752       else
753         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
754         {
755           is_add = 1;
756           ip_addr_version (&ip) = AF_IP6;
757         }
758       else
759         {
760           errmsg ("parse error '%U'", format_unformat_error, input);
761           return -99;
762         }
763     }
764
765   M (LISP_USE_PETR, mp);
766
767   mp->is_add = is_add;
768   if (is_add)
769     {
770       mp->ip_address.af = ip_addr_version (&ip) == AF_IP4 ? 0 : 1;
771       if (mp->ip_address.af)
772         clib_memcpy (mp->ip_address.un.ip6, &ip, 16);
773       else
774         clib_memcpy (mp->ip_address.un.ip4, &ip, 4);
775     }
776
777   /* send */
778   S (mp);
779
780   /* wait for reply */
781   W (ret);
782   return ret;
783 }
784
785 static void
786   vl_api_show_lisp_use_petr_reply_t_handler
787   (vl_api_show_lisp_use_petr_reply_t * mp)
788 {
789   vat_main_t *vam = &vat_main;
790   i32 retval = ntohl (mp->retval);
791
792   if (0 <= retval)
793     {
794       print (vam->ofp, "%s\n", mp->is_petr_enable ? "enabled" : "disabled");
795       if (mp->is_petr_enable)
796         {
797           print (vam->ofp, "Proxy-ETR address; %U",
798                  mp->ip_address.af ? format_ip6_address : format_ip4_address,
799                  mp->ip_address.un);
800         }
801     }
802
803   vam->retval = retval;
804   vam->result_ready = 1;
805 }
806
807 static int
808 api_show_lisp_use_petr (vat_main_t * vam)
809 {
810   vl_api_show_lisp_use_petr_t *mp;
811   int ret;
812
813   if (!vam->json_output)
814     {
815       print (vam->ofp, "%=20s", "Proxy-ETR status:");
816     }
817
818   M (SHOW_LISP_USE_PETR, mp);
819   /* send it... */
820   S (mp);
821
822   /* Wait for a reply... */
823   W (ret);
824   return ret;
825 }
826
827 static void
828   vl_api_show_lisp_rloc_probe_state_reply_t_handler
829   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   int retval = clib_net_to_host_u32 (mp->retval);
833
834   if (retval)
835     goto end;
836
837   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
838 end:
839   vam->retval = retval;
840   vam->result_ready = 1;
841 }
842
843 static int
844 api_show_lisp_map_register_state (vat_main_t * vam)
845 {
846   vl_api_show_lisp_map_register_state_t *mp;
847   int ret;
848
849   M (SHOW_LISP_MAP_REGISTER_STATE, mp);
850
851   /* send */
852   S (mp);
853
854   /* wait for reply */
855   W (ret);
856   return ret;
857 }
858
859 static int
860 api_show_lisp_rloc_probe_state (vat_main_t * vam)
861 {
862   vl_api_show_lisp_rloc_probe_state_t *mp;
863   int ret;
864
865   M (SHOW_LISP_RLOC_PROBE_STATE, mp);
866
867   /* send */
868   S (mp);
869
870   /* wait for reply */
871   W (ret);
872   return ret;
873 }
874
875 static int
876 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
877 {
878   unformat_input_t *input = vam->input;
879   vl_api_lisp_rloc_probe_enable_disable_t *mp;
880   u8 is_set = 0;
881   u8 is_enable = 0;
882   int ret;
883
884   /* Parse args required to build the message */
885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
886     {
887       if (unformat (input, "enable"))
888         {
889           is_set = 1;
890           is_enable = 1;
891         }
892       else if (unformat (input, "disable"))
893         is_set = 1;
894       else
895         break;
896     }
897
898   if (!is_set)
899     {
900       errmsg ("Value not set");
901       return -99;
902     }
903
904   /* Construct the API message */
905   M (LISP_RLOC_PROBE_ENABLE_DISABLE, mp);
906
907   mp->is_enable = is_enable;
908
909   /* send it... */
910   S (mp);
911
912   /* Wait for a reply... */
913   W (ret);
914   return ret;
915 }
916
917 static int
918 api_lisp_map_register_enable_disable (vat_main_t * vam)
919 {
920   unformat_input_t *input = vam->input;
921   vl_api_lisp_map_register_enable_disable_t *mp;
922   u8 is_set = 0;
923   u8 is_enable = 0;
924   int ret;
925
926   /* Parse args required to build the message */
927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
928     {
929       if (unformat (input, "enable"))
930         {
931           is_set = 1;
932           is_enable = 1;
933         }
934       else if (unformat (input, "disable"))
935         is_set = 1;
936       else
937         break;
938     }
939
940   if (!is_set)
941     {
942       errmsg ("Value not set");
943       return -99;
944     }
945
946   /* Construct the API message */
947   M (LISP_MAP_REGISTER_ENABLE_DISABLE, mp);
948
949   mp->is_enable = is_enable;
950
951   /* send it... */
952   S (mp);
953
954   /* Wait for a reply... */
955   W (ret);
956   return ret;
957 }
958
959 static void
960   vl_api_show_lisp_map_request_mode_reply_t_handler
961   (vl_api_show_lisp_map_request_mode_reply_t * mp)
962 {
963   vat_main_t *vam = &vat_main;
964   i32 retval = ntohl (mp->retval);
965
966   if (0 <= retval)
967     {
968       print (vam->ofp, "map_request_mode: %s",
969              mp->is_src_dst ? "src-dst" : "dst-only");
970     }
971
972   vam->retval = retval;
973   vam->result_ready = 1;
974 }
975
976 static void
977   vl_api_show_lisp_map_register_state_reply_t_handler
978   (vl_api_show_lisp_map_register_state_reply_t * mp)
979 {
980   vat_main_t *vam = &vat_main;
981   int retval = clib_net_to_host_u32 (mp->retval);
982
983   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
984
985   vam->retval = retval;
986   vam->result_ready = 1;
987 }
988
989 static void
990 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
991 {
992   vat_main_t *vam = &vat_main;
993   u8 *s = 0;
994
995   if (mp->local)
996     {
997       s = format (s, "%=16d%=16d%=16d",
998                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
999     }
1000   else
1001     {
1002       s = format (s, "%=16U%=16d%=16d",
1003                   format_ip46_address,
1004                   mp->ip_address, mp->priority, mp->weight);
1005     }
1006
1007   print (vam->ofp, "%v", s);
1008   vec_free (s);
1009 }
1010
1011 static void
1012 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
1013                                            mp)
1014 {
1015   vat_main_t *vam = &vat_main;
1016   u8 *ls_name = 0;
1017
1018   ls_name = format (0, "%s", mp->ls_name);
1019
1020   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
1021          ls_name);
1022   vec_free (ls_name);
1023 }
1024
1025 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1026   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1027 {
1028   vat_main_t *vam = &vat_main;
1029   i32 retval = ntohl (mp->retval);
1030   if (vam->async_mode)
1031     {
1032       vam->async_errors += (retval < 0);
1033     }
1034   else
1035     {
1036       vam->retval = retval;
1037       vam->result_ready = 1;
1038     }
1039 }
1040
1041
1042 static void
1043 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
1044 {
1045   vat_main_t *vam = &vat_main;
1046   u8 *s = 0, *eid = 0;
1047
1048   if (~0 == mp->locator_set_index)
1049     s = format (0, "action: %d", mp->action);
1050   else
1051     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
1052
1053   eid = format (0, "%U", format_lisp_eid_vat,
1054                 &mp->deid, &mp->seid, mp->is_src_dst);
1055   vec_add1 (eid, 0);
1056
1057   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
1058          clib_net_to_host_u32 (mp->vni),
1059          eid,
1060          mp->is_local ? "local" : "remote",
1061          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
1062          clib_net_to_host_u16 (mp->key.id), mp->key.key);
1063
1064   vec_free (s);
1065   vec_free (eid);
1066 }
1067
1068 static void
1069   vl_api_lisp_eid_table_map_details_t_handler
1070   (vl_api_lisp_eid_table_map_details_t * mp)
1071 {
1072   vat_main_t *vam = &vat_main;
1073
1074   u8 *line = format (0, "%=10d%=10d",
1075                      clib_net_to_host_u32 (mp->vni),
1076                      clib_net_to_host_u32 (mp->dp_table));
1077   print (vam->ofp, "%v", line);
1078   vec_free (line);
1079 }
1080
1081 static void
1082   vl_api_lisp_eid_table_vni_details_t_handler
1083   (vl_api_lisp_eid_table_vni_details_t * mp)
1084 {
1085   vat_main_t *vam = &vat_main;
1086
1087   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
1088   print (vam->ofp, "%v", line);
1089   vec_free (line);
1090 }
1091
1092 static void
1093   vl_api_lisp_adjacencies_get_reply_t_handler
1094   (vl_api_lisp_adjacencies_get_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   u32 i, n;
1098   int retval = clib_net_to_host_u32 (mp->retval);
1099   vl_api_lisp_adjacency_t *a;
1100
1101   if (retval)
1102     goto end;
1103
1104   n = clib_net_to_host_u32 (mp->count);
1105
1106   for (i = 0; i < n; i++)
1107     {
1108       a = &mp->adjacencies[i];
1109       print (vam->ofp, "%U %40U",
1110              format_lisp_flat_eid, a->leid, format_lisp_flat_eid, a->reid);
1111     }
1112
1113 end:
1114   vam->retval = retval;
1115   vam->result_ready = 1;
1116 }
1117
1118 static void
1119 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t *
1120                                           mp)
1121 {
1122   vat_main_t *vam = &vat_main;
1123
1124   print (vam->ofp, "%=20U",
1125          mp->ip_address.af ? format_ip6_address : format_ip4_address,
1126          mp->ip_address.un);
1127 }
1128
1129 static void
1130 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
1131                                             * mp)
1132 {
1133   vat_main_t *vam = &vat_main;
1134
1135   print (vam->ofp, "%=20U",
1136          mp->ip_address.af ? format_ip6_address : format_ip4_address,
1137          mp->ip_address.un);
1138 }
1139
1140 static void
1141 vl_api_show_lisp_status_reply_t_handler (vl_api_show_lisp_status_reply_t * mp)
1142 {
1143   vat_main_t *vam = &vat_main;
1144   i32 retval = ntohl (mp->retval);
1145
1146   if (0 <= retval)
1147     {
1148       print (vam->ofp, "feature: %s\ngpe: %s",
1149              mp->is_lisp_enabled ? "enabled" : "disabled",
1150              mp->is_gpe_enabled ? "enabled" : "disabled");
1151     }
1152
1153   vam->retval = retval;
1154   vam->result_ready = 1;
1155 }
1156
1157 static void
1158   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
1159   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
1160 {
1161   vat_main_t *vam = &vat_main;
1162   i32 retval = ntohl (mp->retval);
1163
1164   if (retval >= 0)
1165     {
1166       print (vam->ofp, "%=20s", mp->locator_set_name);
1167     }
1168
1169   vam->retval = retval;
1170   vam->result_ready = 1;
1171 }
1172
1173 static void
1174 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
1175 {
1176   vat_main_t *vam = &vat_main;
1177   i32 retval = ntohl (mp->retval);
1178
1179   if (0 <= retval)
1180     {
1181       print (vam->ofp, "%-20s%-16s",
1182              mp->is_enabled ? "enabled" : "disabled",
1183              mp->is_enabled ? (char *) mp->locator_set_name : "");
1184     }
1185
1186   vam->retval = retval;
1187   vam->result_ready = 1;
1188 }
1189
1190 uword
1191 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
1192 {
1193   u32 *key_id = va_arg (*args, u32 *);
1194   u8 *s = 0;
1195
1196   if (unformat (input, "%s", &s))
1197     {
1198       if (!strcmp ((char *) s, "sha1"))
1199         key_id[0] = HMAC_SHA_1_96;
1200       else if (!strcmp ((char *) s, "sha256"))
1201         key_id[0] = HMAC_SHA_256_128;
1202       else
1203         {
1204           clib_warning ("invalid key_id: '%s'", s);
1205           key_id[0] = HMAC_NO_KEY;
1206         }
1207     }
1208   else
1209     return 0;
1210
1211   vec_free (s);
1212   return 1;
1213 }
1214
1215
1216
1217 static int
1218 api_show_lisp_map_request_mode (vat_main_t * vam)
1219 {
1220   vl_api_show_lisp_map_request_mode_t *mp;
1221   int ret;
1222
1223   M (SHOW_LISP_MAP_REQUEST_MODE, mp);
1224
1225   /* send */
1226   S (mp);
1227
1228   /* wait for reply */
1229   W (ret);
1230   return ret;
1231 }
1232
1233 static int
1234 api_lisp_map_request_mode (vat_main_t * vam)
1235 {
1236   unformat_input_t *input = vam->input;
1237   vl_api_lisp_map_request_mode_t *mp;
1238   u8 mode = 0;
1239   int ret;
1240
1241   /* Parse args required to build the message */
1242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1243     {
1244       if (unformat (input, "dst-only"))
1245         mode = 0;
1246       else if (unformat (input, "src-dst"))
1247         mode = 1;
1248       else
1249         {
1250           errmsg ("parse error '%U'", format_unformat_error, input);
1251           return -99;
1252         }
1253     }
1254
1255   M (LISP_MAP_REQUEST_MODE, mp);
1256
1257   mp->is_src_dst = mode == 1;
1258
1259   /* send */
1260   S (mp);
1261
1262   /* wait for reply */
1263   W (ret);
1264   return ret;
1265 }
1266
1267 static int
1268 api_show_lisp_pitr (vat_main_t * vam)
1269 {
1270   vl_api_show_lisp_pitr_t *mp;
1271   int ret;
1272
1273   if (!vam->json_output)
1274     {
1275       print (vam->ofp, "%=20s", "lisp status:");
1276     }
1277
1278   M (SHOW_LISP_PITR, mp);
1279   /* send it... */
1280   S (mp);
1281
1282   /* Wait for a reply... */
1283   W (ret);
1284   return ret;
1285 }
1286
1287 /**
1288  * Add/delete mapping between vni and vrf
1289  */
1290 static int
1291 api_lisp_eid_table_add_del_map (vat_main_t * vam)
1292 {
1293   unformat_input_t *input = vam->input;
1294   vl_api_lisp_eid_table_add_del_map_t *mp;
1295   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
1296   u32 vni, vrf, bd_index;
1297   int ret;
1298
1299   /* Parse args required to build the message */
1300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1301     {
1302       if (unformat (input, "del"))
1303         is_add = 0;
1304       else if (unformat (input, "vrf %d", &vrf))
1305         vrf_set = 1;
1306       else if (unformat (input, "bd_index %d", &bd_index))
1307         bd_index_set = 1;
1308       else if (unformat (input, "vni %d", &vni))
1309         vni_set = 1;
1310       else
1311         break;
1312     }
1313
1314   if (!vni_set || (!vrf_set && !bd_index_set))
1315     {
1316       errmsg ("missing arguments!");
1317       return -99;
1318     }
1319
1320   if (vrf_set && bd_index_set)
1321     {
1322       errmsg ("error: both vrf and bd entered!");
1323       return -99;
1324     }
1325
1326   M (LISP_EID_TABLE_ADD_DEL_MAP, mp);
1327
1328   mp->is_add = is_add;
1329   mp->vni = htonl (vni);
1330   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
1331   mp->is_l2 = bd_index_set;
1332
1333   /* send */
1334   S (mp);
1335
1336   /* wait for reply */
1337   W (ret);
1338   return ret;
1339 }
1340
1341 /**
1342  * Add/del remote mapping to/from LISP control plane
1343  *
1344  * @param vam vpp API test context
1345  * @return return code
1346  */
1347 static int
1348 api_lisp_add_del_remote_mapping (vat_main_t * vam)
1349 {
1350   unformat_input_t *input = vam->input;
1351   vl_api_lisp_add_del_remote_mapping_t *mp;
1352   u32 vni = 0;
1353   lisp_eid_vat_t _eid, *eid = &_eid;
1354   lisp_eid_vat_t _seid, *seid = &_seid;
1355   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
1356   u32 action = ~0, p, w, data_len;
1357   ip4_address_t rloc4;
1358   ip6_address_t rloc6;
1359   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
1360   int ret;
1361
1362   clib_memset (&rloc, 0, sizeof (rloc));
1363
1364   /* Parse args required to build the message */
1365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1366     {
1367       if (unformat (input, "del-all"))
1368         {
1369           del_all = 1;
1370         }
1371       else if (unformat (input, "del"))
1372         {
1373           is_add = 0;
1374         }
1375       else if (unformat (input, "add"))
1376         {
1377           is_add = 1;
1378         }
1379       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
1380         {
1381           eid_set = 1;
1382         }
1383       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
1384         {
1385           seid_set = 1;
1386         }
1387       else if (unformat (input, "vni %d", &vni))
1388         {
1389           ;
1390         }
1391       else if (unformat (input, "p %d w %d", &p, &w))
1392         {
1393           if (!curr_rloc)
1394             {
1395               errmsg ("No RLOC configured for setting priority/weight!");
1396               return -99;
1397             }
1398           curr_rloc->priority = p;
1399           curr_rloc->weight = w;
1400         }
1401       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
1402         {
1403           rloc.ip_address.af = 0;
1404           clib_memcpy (&rloc.ip_address.un.ip6, &rloc6, sizeof (rloc6));
1405           vec_add1 (rlocs, rloc);
1406           curr_rloc = &rlocs[vec_len (rlocs) - 1];
1407         }
1408       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
1409         {
1410           rloc.ip_address.af = 1;
1411           clib_memcpy (&rloc.ip_address.un.ip4, &rloc4, sizeof (rloc4));
1412           vec_add1 (rlocs, rloc);
1413           curr_rloc = &rlocs[vec_len (rlocs) - 1];
1414         }
1415       else if (unformat (input, "action %U",
1416                          unformat_negative_mapping_action, &action))
1417         {
1418           ;
1419         }
1420       else
1421         {
1422           clib_warning ("parse error '%U'", format_unformat_error, input);
1423           return -99;
1424         }
1425     }
1426
1427   if (0 == eid_set)
1428     {
1429       errmsg ("missing params!");
1430       return -99;
1431     }
1432
1433   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
1434     {
1435       errmsg ("no action set for negative map-reply!");
1436       return -99;
1437     }
1438
1439   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
1440
1441   M2 (LISP_ADD_DEL_REMOTE_MAPPING, mp, data_len);
1442   mp->is_add = is_add;
1443   mp->vni = htonl (vni);
1444   mp->action = (u8) action;
1445   mp->is_src_dst = seid_set;
1446   mp->del_all = del_all;
1447   lisp_eid_put_vat (&mp->deid, eid);
1448   lisp_eid_put_vat (&mp->seid, seid);
1449
1450   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
1451   clib_memcpy (mp->rlocs, rlocs, data_len);
1452   vec_free (rlocs);
1453
1454   /* send it... */
1455   S (mp);
1456
1457   /* Wait for a reply... */
1458   W (ret);
1459   return ret;
1460 }
1461
1462 /**
1463  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
1464  * forwarding entries in data-plane accordingly.
1465  *
1466  * @param vam vpp API test context
1467  * @return return code
1468  */
1469 static int
1470 api_lisp_add_del_adjacency (vat_main_t * vam)
1471 {
1472   unformat_input_t *input = vam->input;
1473   vl_api_lisp_add_del_adjacency_t *mp;
1474   u32 vni = 0;
1475   u8 is_add = 1;
1476   int ret;
1477   lisp_eid_vat_t leid, reid;
1478
1479   leid.type = reid.type = (u8) ~ 0;
1480
1481   /* Parse args required to build the message */
1482   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1483     {
1484       if (unformat (input, "del"))
1485         {
1486           is_add = 0;
1487         }
1488       else if (unformat (input, "add"))
1489         {
1490           is_add = 1;
1491         }
1492       else if (unformat (input, "reid %U/%d", unformat_ip46_address,
1493                          &reid.addr.ip, &reid.len))
1494         {
1495           reid.type = 0;        /* ipv4 */
1496         }
1497       else if (unformat (input, "reid %U", unformat_ethernet_address,
1498                          &reid.addr.mac))
1499         {
1500           reid.type = 1;        /* mac */
1501         }
1502       else if (unformat (input, "leid %U/%d", unformat_ip46_address,
1503                          &leid.addr.ip, &leid.len))
1504         {
1505           leid.type = 0;        /* ipv4 */
1506         }
1507       else if (unformat (input, "leid %U", unformat_ethernet_address,
1508                          &leid.addr.mac))
1509         {
1510           leid.type = 1;        /* mac */
1511         }
1512       else if (unformat (input, "vni %d", &vni))
1513         {
1514           ;
1515         }
1516       else
1517         {
1518           errmsg ("parse error '%U'", format_unformat_error, input);
1519           return -99;
1520         }
1521     }
1522
1523   if ((u8) ~ 0 == reid.type)
1524     {
1525       errmsg ("missing params!");
1526       return -99;
1527     }
1528
1529   if (leid.type != reid.type)
1530     {
1531       errmsg ("remote and local EIDs are of different types!");
1532       return -99;
1533     }
1534
1535   M (LISP_ADD_DEL_ADJACENCY, mp);
1536   mp->is_add = is_add;
1537   mp->vni = htonl (vni);
1538   lisp_eid_put_vat (&mp->leid, &leid);
1539   lisp_eid_put_vat (&mp->reid, &reid);
1540
1541   /* send it... */
1542   S (mp);
1543
1544   /* Wait for a reply... */
1545   W (ret);
1546   return ret;
1547 }
1548
1549 /**
1550  * Add/del map request itr rlocs from LISP control plane and updates
1551  *
1552  * @param vam vpp API test context
1553  * @return return code
1554  */
1555 static int
1556 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
1557 {
1558   unformat_input_t *input = vam->input;
1559   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
1560   u8 *locator_set_name = 0;
1561   u8 locator_set_name_set = 0;
1562   u8 is_add = 1;
1563   int ret;
1564
1565   /* Parse args required to build the message */
1566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1567     {
1568       if (unformat (input, "del"))
1569         {
1570           is_add = 0;
1571         }
1572       else if (unformat (input, "%_%v%_", &locator_set_name))
1573         {
1574           locator_set_name_set = 1;
1575         }
1576       else
1577         {
1578           clib_warning ("parse error '%U'", format_unformat_error, input);
1579           return -99;
1580         }
1581     }
1582
1583   if (is_add && !locator_set_name_set)
1584     {
1585       errmsg ("itr-rloc is not set!");
1586       return -99;
1587     }
1588
1589   if (is_add && vec_len (locator_set_name) > 64)
1590     {
1591       errmsg ("itr-rloc locator-set name too long");
1592       vec_free (locator_set_name);
1593       return -99;
1594     }
1595
1596   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
1597   mp->is_add = is_add;
1598   if (is_add)
1599     {
1600       clib_memcpy (mp->locator_set_name, locator_set_name,
1601                    vec_len (locator_set_name));
1602     }
1603   else
1604     {
1605       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
1606     }
1607   vec_free (locator_set_name);
1608
1609   /* send it... */
1610   S (mp);
1611
1612   /* Wait for a reply... */
1613   W (ret);
1614   return ret;
1615 }
1616
1617 static int
1618 api_lisp_locator_dump (vat_main_t * vam)
1619 {
1620   unformat_input_t *input = vam->input;
1621   vl_api_lisp_locator_dump_t *mp;
1622   vl_api_control_ping_t *mp_ping;
1623   u8 is_index_set = 0, is_name_set = 0;
1624   u8 *ls_name = 0;
1625   u32 ls_index = ~0;
1626   int ret;
1627
1628   /* Parse args required to build the message */
1629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1630     {
1631       if (unformat (input, "ls_name %_%v%_", &ls_name))
1632         {
1633           is_name_set = 1;
1634         }
1635       else if (unformat (input, "ls_index %d", &ls_index))
1636         {
1637           is_index_set = 1;
1638         }
1639       else
1640         {
1641           errmsg ("parse error '%U'", format_unformat_error, input);
1642           return -99;
1643         }
1644     }
1645
1646   if (!is_index_set && !is_name_set)
1647     {
1648       errmsg ("error: expected lisp of index or name!");
1649       return -99;
1650     }
1651
1652   if (is_index_set && is_name_set)
1653     {
1654       errmsg ("error: only lisp param expected!");
1655       return -99;
1656     }
1657
1658   if (vec_len (ls_name) > 62)
1659     {
1660       errmsg ("error: locator set name too long!");
1661       return -99;
1662     }
1663
1664   if (!vam->json_output)
1665     {
1666       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
1667     }
1668
1669   M (LISP_LOCATOR_DUMP, mp);
1670   mp->is_index_set = is_index_set;
1671
1672   if (is_index_set)
1673     mp->ls_index = clib_host_to_net_u32 (ls_index);
1674   else
1675     {
1676       vec_add1 (ls_name, 0);
1677       strncpy ((char *) mp->ls_name, (char *) ls_name,
1678                sizeof (mp->ls_name) - 1);
1679     }
1680
1681   /* send it... */
1682   S (mp);
1683
1684   /* Use a control ping for synchronization */
1685   if (!lisp_test_main.ping_id)
1686     lisp_test_main.ping_id =
1687       vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC));
1688   mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
1689   mp_ping->_vl_msg_id = htons (lisp_test_main.ping_id);
1690   mp_ping->client_index = vam->my_client_index;
1691
1692   fformat (vam->ofp, "Sending ping id=%d\n", lisp_test_main.ping_id);
1693
1694   vam->result_ready = 0;
1695   S (mp_ping);
1696
1697   /* Wait for a reply... */
1698   W (ret);
1699   return ret;
1700 }
1701
1702 static int
1703 api_lisp_locator_set_dump (vat_main_t * vam)
1704 {
1705   vl_api_lisp_locator_set_dump_t *mp;
1706   vl_api_control_ping_t *mp_ping;
1707   unformat_input_t *input = vam->input;
1708   u8 filter = 0;
1709   int ret;
1710
1711   /* Parse args required to build the message */
1712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1713     {
1714       if (unformat (input, "local"))
1715         {
1716           filter = 1;
1717         }
1718       else if (unformat (input, "remote"))
1719         {
1720           filter = 2;
1721         }
1722       else
1723         {
1724           errmsg ("parse error '%U'", format_unformat_error, input);
1725           return -99;
1726         }
1727     }
1728
1729   if (!vam->json_output)
1730     {
1731       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
1732     }
1733
1734   M (LISP_LOCATOR_SET_DUMP, mp);
1735
1736   mp->filter = filter;
1737
1738   /* send it... */
1739   S (mp);
1740
1741   /* Use a control ping for synchronization */
1742   LISP_PING (&lisp_test_main, mp_ping);
1743   S (mp_ping);
1744
1745   /* Wait for a reply... */
1746   W (ret);
1747   return ret;
1748 }
1749
1750 static int
1751 api_lisp_eid_table_map_dump (vat_main_t * vam)
1752 {
1753   u8 is_l2 = 0;
1754   u8 mode_set = 0;
1755   unformat_input_t *input = vam->input;
1756   vl_api_lisp_eid_table_map_dump_t *mp;
1757   vl_api_control_ping_t *mp_ping;
1758   int ret;
1759
1760   /* Parse args required to build the message */
1761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1762     {
1763       if (unformat (input, "l2"))
1764         {
1765           is_l2 = 1;
1766           mode_set = 1;
1767         }
1768       else if (unformat (input, "l3"))
1769         {
1770           is_l2 = 0;
1771           mode_set = 1;
1772         }
1773       else
1774         {
1775           errmsg ("parse error '%U'", format_unformat_error, input);
1776           return -99;
1777         }
1778     }
1779
1780   if (!mode_set)
1781     {
1782       errmsg ("expected lisp of 'l2' or 'l3' parameter!");
1783       return -99;
1784     }
1785
1786   if (!vam->json_output)
1787     {
1788       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
1789     }
1790
1791   M (LISP_EID_TABLE_MAP_DUMP, mp);
1792   mp->is_l2 = is_l2;
1793
1794   /* send it... */
1795   S (mp);
1796
1797   /* Use a control ping for synchronization */
1798   LISP_PING (&lisp_test_main, mp_ping);
1799   S (mp_ping);
1800
1801   /* Wait for a reply... */
1802   W (ret);
1803   return ret;
1804 }
1805
1806 static int
1807 api_lisp_eid_table_vni_dump (vat_main_t * vam)
1808 {
1809   vl_api_lisp_eid_table_vni_dump_t *mp;
1810   vl_api_control_ping_t *mp_ping;
1811   int ret;
1812
1813   if (!vam->json_output)
1814     {
1815       print (vam->ofp, "VNI");
1816     }
1817
1818   M (LISP_EID_TABLE_VNI_DUMP, mp);
1819
1820   /* send it... */
1821   S (mp);
1822
1823   /* Use a control ping for synchronization */
1824   LISP_PING (&lisp_test_main, mp_ping);
1825   S (mp_ping);
1826
1827   /* Wait for a reply... */
1828   W (ret);
1829   return ret;
1830 }
1831
1832 static int
1833 api_lisp_eid_table_dump (vat_main_t * vam)
1834 {
1835   unformat_input_t *i = vam->input;
1836   vl_api_lisp_eid_table_dump_t *mp;
1837   vl_api_control_ping_t *mp_ping;
1838   u8 filter = 0;
1839   int ret;
1840   u32 vni, t = 0;
1841   lisp_eid_vat_t eid;
1842   u8 eid_set = 0;
1843
1844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1845     {
1846       if (unformat
1847           (i, "eid %U/%d", unformat_ip46_address, &eid.addr.ip, &eid.len))
1848         {
1849           eid_set = 1;
1850           eid.type = 0;
1851         }
1852       else
1853         if (unformat (i, "eid %U", unformat_ethernet_address, &eid.addr.mac))
1854         {
1855           eid_set = 1;
1856           eid.type = 1;
1857         }
1858       else if (unformat (i, "eid %U", unformat_nsh_address, &eid.addr.nsh))
1859         {
1860           eid_set = 1;
1861           eid.type = 2;
1862         }
1863       else if (unformat (i, "vni %d", &t))
1864         {
1865           vni = t;
1866         }
1867       else if (unformat (i, "local"))
1868         {
1869           filter = 1;
1870         }
1871       else if (unformat (i, "remote"))
1872         {
1873           filter = 2;
1874         }
1875       else
1876         {
1877           errmsg ("parse error '%U'", format_unformat_error, i);
1878           return -99;
1879         }
1880     }
1881
1882   if (!vam->json_output)
1883     {
1884       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
1885              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
1886     }
1887
1888   M (LISP_EID_TABLE_DUMP, mp);
1889
1890   mp->filter = filter;
1891   if (eid_set)
1892     {
1893       mp->eid_set = 1;
1894       mp->vni = htonl (vni);
1895       lisp_eid_put_vat (&mp->eid, &eid);
1896     }
1897
1898   /* send it... */
1899   S (mp);
1900
1901   /* Use a control ping for synchronization */
1902   LISP_PING (&lisp_test_main, mp_ping);
1903   S (mp_ping);
1904
1905   /* Wait for a reply... */
1906   W (ret);
1907   return ret;
1908 }
1909
1910
1911 static int
1912 api_lisp_adjacencies_get (vat_main_t * vam)
1913 {
1914   unformat_input_t *i = vam->input;
1915   vl_api_lisp_adjacencies_get_t *mp;
1916   u8 vni_set = 0;
1917   u32 vni = ~0;
1918   int ret;
1919
1920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1921     {
1922       if (unformat (i, "vni %d", &vni))
1923         {
1924           vni_set = 1;
1925         }
1926       else
1927         {
1928           errmsg ("parse error '%U'", format_unformat_error, i);
1929           return -99;
1930         }
1931     }
1932
1933   if (!vni_set)
1934     {
1935       errmsg ("vni not set!");
1936       return -99;
1937     }
1938
1939   if (!vam->json_output)
1940     {
1941       print (vam->ofp, "%s %40s", "leid", "reid");
1942     }
1943
1944   M (LISP_ADJACENCIES_GET, mp);
1945   mp->vni = clib_host_to_net_u32 (vni);
1946
1947   /* send it... */
1948   S (mp);
1949
1950   /* Wait for a reply... */
1951   W (ret);
1952   return ret;
1953 }
1954
1955 static int
1956 api_lisp_map_server_dump (vat_main_t * vam)
1957 {
1958   vl_api_lisp_map_server_dump_t *mp;
1959   vl_api_control_ping_t *mp_ping;
1960   int ret;
1961
1962   if (!vam->json_output)
1963     {
1964       print (vam->ofp, "%=20s", "Map server");
1965     }
1966
1967   M (LISP_MAP_SERVER_DUMP, mp);
1968   /* send it... */
1969   S (mp);
1970
1971   /* Use a control ping for synchronization */
1972   LISP_PING (&lisp_test_main, mp_ping);
1973   S (mp_ping);
1974
1975   /* Wait for a reply... */
1976   W (ret);
1977   return ret;
1978 }
1979
1980 static int
1981 api_lisp_map_resolver_dump (vat_main_t * vam)
1982 {
1983   vl_api_lisp_map_resolver_dump_t *mp;
1984   vl_api_control_ping_t *mp_ping;
1985   int ret;
1986
1987   if (!vam->json_output)
1988     {
1989       print (vam->ofp, "%=20s", "Map resolver");
1990     }
1991
1992   M (LISP_MAP_RESOLVER_DUMP, mp);
1993   /* send it... */
1994   S (mp);
1995
1996   /* Use a control ping for synchronization */
1997   LISP_PING (&lisp_test_main, mp_ping);
1998   S (mp_ping);
1999
2000   /* Wait for a reply... */
2001   W (ret);
2002   return ret;
2003 }
2004
2005 static int
2006 api_show_lisp_status (vat_main_t * vam)
2007 {
2008   vl_api_show_lisp_status_t *mp;
2009   int ret;
2010
2011   if (!vam->json_output)
2012     {
2013       print (vam->ofp, "%-20s%-16s", "LISP status", "locator-set");
2014     }
2015
2016   M (SHOW_LISP_STATUS, mp);
2017   /* send it... */
2018   S (mp);
2019   /* Wait for a reply... */
2020   W (ret);
2021   return ret;
2022 }
2023
2024 static int
2025 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
2026 {
2027   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
2028   int ret;
2029
2030   if (!vam->json_output)
2031     {
2032       print (vam->ofp, "%=20s", "itr-rlocs:");
2033     }
2034
2035   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, mp);
2036   /* send it... */
2037   S (mp);
2038   /* Wait for a reply... */
2039   W (ret);
2040   return ret;
2041 }
2042
2043 #define vat_plugin_register vat_plugin_register_cp
2044 #include <lisp/lisp-cp/lisp.api_test.c>
2045
2046 /*
2047  * fd.io coding-style-patch-verification: ON
2048  *
2049  * Local Variables:
2050  * eval: (c-set-style "gnu")
2051  * End:
2052  */