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