Trivial: Clean up some typos.
[vpp.git] / src / vnet / lisp-cp / lisp_cli.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vnet/lisp-cp/control.h>
17 #include <vnet/lisp-gpe/lisp_gpe.h>
18
19 static clib_error_t *
20 lisp_show_adjacencies_command_fn (vlib_main_t * vm,
21                                   unformat_input_t * input,
22                                   vlib_cli_command_t * cmd)
23 {
24   lisp_adjacency_t *adjs, *adj;
25   vlib_cli_output (vm, "%s %40s\n", "leid", "reid");
26   unformat_input_t _line_input, *line_input = &_line_input;
27   u32 vni = ~0;
28   clib_error_t *error = NULL;
29
30   /* Get a line of input. */
31   if (!unformat_user (input, unformat_line_input, line_input))
32     return 0;
33
34   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
35     {
36       if (unformat (line_input, "vni %d", &vni))
37         ;
38       else
39         {
40           vlib_cli_output (vm, "parse error: '%U'",
41                            format_unformat_error, line_input);
42           goto done;
43         }
44     }
45
46   if (~0 == vni)
47     {
48       vlib_cli_output (vm, "error: no vni specified!");
49       goto done;
50     }
51
52   adjs = vnet_lisp_adjacencies_get_by_vni (vni);
53
54   vec_foreach (adj, adjs)
55   {
56     vlib_cli_output (vm, "%U %40U\n", format_gid_address, &adj->leid,
57                      format_gid_address, &adj->reid);
58   }
59   vec_free (adjs);
60
61 done:
62   unformat_free (line_input);
63
64   return error;
65 }
66
67 /* *INDENT-OFF* */
68 VLIB_CLI_COMMAND (lisp_show_adjacencies_command) = {
69     .path = "show lisp adjacencies",
70     .short_help = "show lisp adjacencies",
71     .function = lisp_show_adjacencies_command_fn,
72 };
73 /* *INDENT-ON* */
74
75 static clib_error_t *
76 lisp_add_del_map_server_command_fn (vlib_main_t * vm,
77                                     unformat_input_t * input,
78                                     vlib_cli_command_t * cmd)
79 {
80   int rv = 0;
81   u8 is_add = 1, ip_set = 0;
82   ip_address_t ip;
83   unformat_input_t _line_input, *line_input = &_line_input;
84   clib_error_t *error = NULL;
85
86   /* Get a line of input. */
87   if (!unformat_user (input, unformat_line_input, line_input))
88     return 0;
89
90   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
91     {
92       if (unformat (line_input, "add"))
93         is_add = 1;
94       else if (unformat (line_input, "del"))
95         is_add = 0;
96       else if (unformat (line_input, "%U", unformat_ip_address, &ip))
97         ip_set = 1;
98       else
99         {
100           vlib_cli_output (vm, "parse error: '%U'",
101                            format_unformat_error, line_input);
102           goto done;
103         }
104     }
105
106   if (!ip_set)
107     {
108       vlib_cli_output (vm, "map-server ip address not set!");
109       goto done;
110     }
111
112   rv = vnet_lisp_add_del_map_server (&ip, is_add);
113   if (!rv)
114     vlib_cli_output (vm, "failed to %s map-server!",
115                      is_add ? "add" : "delete");
116
117 done:
118   unformat_free (line_input);
119
120   return error;
121 }
122
123 /* *INDENT-OFF* */
124 VLIB_CLI_COMMAND (lisp_add_del_map_server_command) = {
125     .path = "lisp map-server",
126     .short_help = "lisp map-server add|del <ip>",
127     .function = lisp_add_del_map_server_command_fn,
128 };
129 /* *INDENT-ON* */
130
131
132 static clib_error_t *
133 lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
134                                    vlib_cli_command_t * cmd)
135 {
136   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
137   unformat_input_t _line_input, *line_input = &_line_input;
138   u8 is_add = 1;
139   gid_address_t eid;
140   gid_address_t *eids = 0;
141   clib_error_t *error = 0;
142   u8 *locator_set_name = 0;
143   u32 locator_set_index = 0, map_index = 0;
144   uword *p;
145   vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
146   int rv = 0;
147   u32 vni = 0;
148   u8 *key = 0;
149   u32 key_id = 0;
150
151   memset (&eid, 0, sizeof (eid));
152   memset (a, 0, sizeof (*a));
153
154   /* Get a line of input. */
155   if (!unformat_user (input, unformat_line_input, line_input))
156     return 0;
157
158   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
159     {
160       if (unformat (line_input, "add"))
161         is_add = 1;
162       else if (unformat (line_input, "del"))
163         is_add = 0;
164       else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
165         ;
166       else if (unformat (line_input, "vni %d", &vni))
167         gid_address_vni (&eid) = vni;
168       else if (unformat (line_input, "secret-key %_%v%_", &key))
169         ;
170       else if (unformat (line_input, "key-id %U", unformat_hmac_key_id,
171                          &key_id))
172         ;
173       else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
174         {
175           vec_terminate_c_string (locator_set_name);
176           p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
177           if (!p)
178             {
179               error = clib_error_return (0, "locator-set %s doesn't exist",
180                                          locator_set_name);
181               goto done;
182             }
183           locator_set_index = p[0];
184         }
185       else
186         {
187           error = unformat_parse_error (line_input);
188           goto done;
189         }
190     }
191   /* XXX treat batch configuration */
192
193   if (GID_ADDR_SRC_DST == gid_address_type (&eid))
194     {
195       error =
196         clib_error_return (0, "src/dst is not supported for local EIDs!");
197       goto done;
198     }
199
200   if (key && (0 == key_id))
201     {
202       vlib_cli_output (vm, "invalid key_id!");
203       goto done;;
204     }
205
206   gid_address_copy (&a->eid, &eid);
207   a->is_add = is_add;
208   a->locator_set_index = locator_set_index;
209   a->local = 1;
210   a->key = key;
211   a->key_id = key_id;
212
213   rv = vnet_lisp_add_del_local_mapping (a, &map_index);
214   if (0 != rv)
215     {
216       error = clib_error_return (0, "failed to %s local mapping!",
217                                  is_add ? "add" : "delete");
218     }
219 done:
220   vec_free (eids);
221   if (locator_set_name)
222     vec_free (locator_set_name);
223   gid_address_free (&a->eid);
224   vec_free (a->key);
225   unformat_free (line_input);
226
227   return error;
228 }
229
230 /* *INDENT-OFF* */
231 VLIB_CLI_COMMAND (lisp_add_del_local_eid_command) = {
232     .path = "lisp eid-table",
233     .short_help = "lisp eid-table add/del [vni <vni>] eid <eid> "
234       "locator-set <locator-set> [key <secret-key> key-id sha1|sha256 ]",
235     .function = lisp_add_del_local_eid_command_fn,
236 };
237 /* *INDENT-ON* */
238
239 static clib_error_t *
240 lisp_eid_table_map_command_fn (vlib_main_t * vm,
241                                unformat_input_t * input,
242                                vlib_cli_command_t * cmd)
243 {
244   u8 is_add = 1, is_l2 = 0;
245   u32 vni = 0, dp_id = 0;
246   unformat_input_t _line_input, *line_input = &_line_input;
247   clib_error_t *error = NULL;
248
249   /* Get a line of input. */
250   if (!unformat_user (input, unformat_line_input, line_input))
251     return 0;
252
253   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
254     {
255       if (unformat (line_input, "del"))
256         is_add = 0;
257       else if (unformat (line_input, "vni %d", &vni))
258         ;
259       else if (unformat (line_input, "vrf %d", &dp_id))
260         ;
261       else if (unformat (line_input, "bd %d", &dp_id))
262         is_l2 = 1;
263       else
264         {
265           error = unformat_parse_error (line_input);
266           goto done;
267         }
268     }
269   vnet_lisp_eid_table_map (vni, dp_id, is_l2, is_add);
270
271 done:
272   unformat_free (line_input);
273
274   return error;
275 }
276
277 /* *INDENT-OFF* */
278 VLIB_CLI_COMMAND (lisp_eid_table_map_command) = {
279     .path = "lisp eid-table map",
280     .short_help = "lisp eid-table map [del] vni <vni> vrf <vrf> | bd <bdi>",
281     .function = lisp_eid_table_map_command_fn,
282 };
283 /* *INDENT-ON* */
284
285 /**
286  * Handler for add/del remote mapping CLI.
287  *
288  * @param vm vlib context
289  * @param input input from user
290  * @param cmd cmd
291  * @return pointer to clib error structure
292  */
293 static clib_error_t *
294 lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
295                                         unformat_input_t * input,
296                                         vlib_cli_command_t * cmd)
297 {
298   clib_error_t *error = 0;
299   unformat_input_t _line_input, *line_input = &_line_input;
300   u8 is_add = 1, del_all = 0;
301   locator_t rloc, *rlocs = 0, *curr_rloc = 0;
302   gid_address_t eid;
303   u8 eid_set = 0;
304   u32 vni, action = ~0, p, w;
305   int rv;
306
307   /* Get a line of input. */
308   if (!unformat_user (input, unformat_line_input, line_input))
309     return 0;
310
311   memset (&eid, 0, sizeof (eid));
312   memset (&rloc, 0, sizeof (rloc));
313
314   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
315     {
316       if (unformat (line_input, "del-all"))
317         del_all = 1;
318       else if (unformat (line_input, "del"))
319         is_add = 0;
320       else if (unformat (line_input, "add"))
321         ;
322       else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
323         eid_set = 1;
324       else if (unformat (line_input, "vni %u", &vni))
325         {
326           gid_address_vni (&eid) = vni;
327         }
328       else if (unformat (line_input, "p %d w %d", &p, &w))
329         {
330           if (!curr_rloc)
331             {
332               clib_warning
333                 ("No RLOC configured for setting priority/weight!");
334               goto done;
335             }
336           curr_rloc->priority = p;
337           curr_rloc->weight = w;
338         }
339       else if (unformat (line_input, "rloc %U", unformat_ip_address,
340                          &gid_address_ip (&rloc.address)))
341         {
342           /* since rloc is stored in ip prefix we need to set prefix length */
343           ip_prefix_t *pref = &gid_address_ippref (&rloc.address);
344
345           u8 version = gid_address_ip_version (&rloc.address);
346           ip_prefix_len (pref) = ip_address_max_len (version);
347
348           vec_add1 (rlocs, rloc);
349           curr_rloc = &rlocs[vec_len (rlocs) - 1];
350         }
351       else if (unformat (line_input, "action %U",
352                          unformat_negative_mapping_action, &action))
353         ;
354       else
355         {
356           clib_warning ("parse error");
357           goto done;
358         }
359     }
360
361   if (!eid_set)
362     {
363       clib_warning ("missing eid!");
364       goto done;
365     }
366
367   if (!del_all)
368     {
369       if (is_add && (~0 == action) && 0 == vec_len (rlocs))
370         {
371           clib_warning ("no action set for negative map-reply!");
372           goto done;
373         }
374     }
375   else
376     {
377       vnet_lisp_clear_all_remote_adjacencies ();
378       goto done;
379     }
380
381   /* TODO build src/dst with seid */
382
383   /* if it's a delete, clean forwarding */
384   if (!is_add)
385     {
386       vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
387       memset (a, 0, sizeof (a[0]));
388       gid_address_copy (&a->reid, &eid);
389       if (vnet_lisp_add_del_adjacency (a))
390         {
391           clib_warning ("failed to delete adjacency!");
392           goto done;
393         }
394     }
395
396   /* add as static remote mapping, i.e., not authoritative and infinite
397    * ttl */
398   if (is_add)
399     {
400       vnet_lisp_add_del_mapping_args_t _map_args, *map_args = &_map_args;
401       memset (map_args, 0, sizeof (map_args[0]));
402       gid_address_copy (&map_args->eid, &eid);
403       map_args->action = action;
404       map_args->is_static = 1;
405       map_args->authoritative = 0;
406       map_args->ttl = ~0;
407       rv = vnet_lisp_add_mapping (map_args, rlocs, NULL, NULL);
408     }
409   else
410     rv = vnet_lisp_del_mapping (&eid, NULL);
411
412   if (rv)
413     clib_warning ("failed to %s remote mapping!", is_add ? "add" : "delete");
414
415 done:
416   vec_free (rlocs);
417   unformat_free (line_input);
418   return error;
419 }
420
421 VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) =
422 {
423 .path = "lisp remote-mapping",.short_help =
424     "lisp remote-mapping add|del [del-all] vni <vni> "
425     "eid <est-eid> [action <no-action|natively-forward|"
426     "send-map-request|drop>] rloc <dst-locator> p <prio> w <weight> "
427     "[rloc <dst-locator> ... ]",.function =
428     lisp_add_del_remote_mapping_command_fn,};
429
430 /**
431  * Handler for add/del adjacency CLI.
432  */
433 static clib_error_t *
434 lisp_add_del_adjacency_command_fn (vlib_main_t * vm, unformat_input_t * input,
435                                    vlib_cli_command_t * cmd)
436 {
437   clib_error_t *error = 0;
438   unformat_input_t _line_input, *line_input = &_line_input;
439   vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
440   u8 is_add = 1;
441   ip_prefix_t *reid_ippref, *leid_ippref;
442   gid_address_t leid, reid;
443   u8 *dmac = gid_address_mac (&reid);
444   u8 *smac = gid_address_mac (&leid);
445   u8 reid_set = 0, leid_set = 0;
446   u32 vni;
447
448   /* Get a line of input. */
449   if (!unformat_user (input, unformat_line_input, line_input))
450     return 0;
451
452   memset (&reid, 0, sizeof (reid));
453   memset (&leid, 0, sizeof (leid));
454
455   leid_ippref = &gid_address_ippref (&leid);
456   reid_ippref = &gid_address_ippref (&reid);
457
458   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
459     {
460       if (unformat (line_input, "del"))
461         is_add = 0;
462       else if (unformat (line_input, "add"))
463         ;
464       else if (unformat (line_input, "reid %U",
465                          unformat_ip_prefix, reid_ippref))
466         {
467           gid_address_type (&reid) = GID_ADDR_IP_PREFIX;
468           reid_set = 1;
469         }
470       else if (unformat (line_input, "reid %U", unformat_mac_address, dmac))
471         {
472           gid_address_type (&reid) = GID_ADDR_MAC;
473           reid_set = 1;
474         }
475       else if (unformat (line_input, "vni %u", &vni))
476         {
477           gid_address_vni (&leid) = vni;
478           gid_address_vni (&reid) = vni;
479         }
480       else if (unformat (line_input, "leid %U",
481                          unformat_ip_prefix, leid_ippref))
482         {
483           gid_address_type (&leid) = GID_ADDR_IP_PREFIX;
484           leid_set = 1;
485         }
486       else if (unformat (line_input, "leid %U", unformat_mac_address, smac))
487         {
488           gid_address_type (&leid) = GID_ADDR_MAC;
489           leid_set = 1;
490         }
491       else
492         {
493           clib_warning ("parse error");
494           goto done;
495         }
496     }
497
498   if (!reid_set || !leid_set)
499     {
500       clib_warning ("missing remote or local eid!");
501       goto done;
502     }
503
504   if ((gid_address_type (&leid) != gid_address_type (&reid))
505       || (gid_address_type (&reid) == GID_ADDR_IP_PREFIX
506           && ip_prefix_version (reid_ippref)
507           != ip_prefix_version (leid_ippref)))
508     {
509       clib_warning ("remote and local EIDs are of different types!");
510       goto done;
511     }
512
513   memset (a, 0, sizeof (a[0]));
514   gid_address_copy (&a->leid, &leid);
515   gid_address_copy (&a->reid, &reid);
516   a->is_add = is_add;
517
518   if (vnet_lisp_add_del_adjacency (a))
519     clib_warning ("failed to %s adjacency!", is_add ? "add" : "delete");
520
521 done:
522   unformat_free (line_input);
523   return error;
524 }
525
526 /* *INDENT-OFF* */
527 VLIB_CLI_COMMAND (lisp_add_del_adjacency_command) = {
528     .path = "lisp adjacency",
529     .short_help = "lisp adjacency add|del vni <vni> reid <remote-eid> "
530       "leid <local-eid>",
531     .function = lisp_add_del_adjacency_command_fn,
532 };
533 /* *INDENT-ON* */
534
535
536 static clib_error_t *
537 lisp_map_request_mode_command_fn (vlib_main_t * vm,
538                                   unformat_input_t * input,
539                                   vlib_cli_command_t * cmd)
540 {
541   unformat_input_t _i, *i = &_i;
542   map_request_mode_t mr_mode = _MR_MODE_MAX;
543   clib_error_t *error = NULL;
544
545   /* Get a line of input. */
546   if (!unformat_user (input, unformat_line_input, i))
547     return 0;
548
549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
550     {
551       if (unformat (i, "dst-only"))
552         mr_mode = MR_MODE_DST_ONLY;
553       else if (unformat (i, "src-dst"))
554         mr_mode = MR_MODE_SRC_DST;
555       else
556         {
557           clib_warning ("parse error '%U'", format_unformat_error, i);
558           goto done;
559         }
560     }
561
562   if (_MR_MODE_MAX == mr_mode)
563     {
564       clib_warning ("No LISP map request mode entered!");
565       goto done;
566     }
567
568   vnet_lisp_set_map_request_mode (mr_mode);
569
570 done:
571   unformat_free (i);
572
573   return error;
574 }
575
576 /* *INDENT-OFF* */
577 VLIB_CLI_COMMAND (lisp_map_request_mode_command) = {
578     .path = "lisp map-request mode",
579     .short_help = "lisp map-request mode dst-only|src-dst",
580     .function = lisp_map_request_mode_command_fn,
581 };
582 /* *INDENT-ON* */
583
584
585 static u8 *
586 format_lisp_map_request_mode (u8 * s, va_list * args)
587 {
588   u32 mode = va_arg (*args, u32);
589
590   switch (mode)
591     {
592     case 0:
593       return format (0, "dst-only");
594     case 1:
595       return format (0, "src-dst");
596     }
597   return 0;
598 }
599
600 static clib_error_t *
601 lisp_show_map_request_mode_command_fn (vlib_main_t * vm,
602                                        unformat_input_t * input,
603                                        vlib_cli_command_t * cmd)
604 {
605   vlib_cli_output (vm, "map-request mode: %U", format_lisp_map_request_mode,
606                    vnet_lisp_get_map_request_mode ());
607   return 0;
608 }
609
610 /* *INDENT-OFF* */
611 VLIB_CLI_COMMAND (lisp_show_map_request_mode_command) = {
612     .path = "show lisp map-request mode",
613     .short_help = "show lisp map-request mode",
614     .function = lisp_show_map_request_mode_command_fn,
615 };
616 /* *INDENT-ON* */
617
618 static clib_error_t *
619 lisp_show_map_resolvers_command_fn (vlib_main_t * vm,
620                                     unformat_input_t * input,
621                                     vlib_cli_command_t * cmd)
622 {
623   lisp_msmr_t *mr;
624   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
625
626   vec_foreach (mr, lcm->map_resolvers)
627   {
628     vlib_cli_output (vm, "%U", format_ip_address, &mr->address);
629   }
630   return 0;
631 }
632
633 /* *INDENT-OFF* */
634 VLIB_CLI_COMMAND (lisp_show_map_resolvers_command) = {
635     .path = "show lisp map-resolvers",
636     .short_help = "show lisp map-resolvers",
637     .function = lisp_show_map_resolvers_command_fn,
638 };
639 /* *INDENT-ON* */
640
641
642 static clib_error_t *
643 lisp_pitr_set_locator_set_command_fn (vlib_main_t * vm,
644                                       unformat_input_t * input,
645                                       vlib_cli_command_t * cmd)
646 {
647   u8 locator_name_set = 0;
648   u8 *locator_set_name = 0;
649   u8 is_add = 1;
650   unformat_input_t _line_input, *line_input = &_line_input;
651   clib_error_t *error = 0;
652   int rv = 0;
653
654   /* Get a line of input. */
655   if (!unformat_user (input, unformat_line_input, line_input))
656     return 0;
657
658   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
659     {
660       if (unformat (line_input, "ls %_%v%_", &locator_set_name))
661         locator_name_set = 1;
662       else if (unformat (line_input, "disable"))
663         is_add = 0;
664       else
665         {
666           error = clib_error_return (0, "parse error");
667           goto done;
668         }
669     }
670
671   if (!locator_name_set)
672     {
673       clib_warning ("No locator set specified!");
674       goto done;
675     }
676   vec_terminate_c_string (locator_set_name);
677   rv = vnet_lisp_pitr_set_locator_set (locator_set_name, is_add);
678   if (0 != rv)
679     {
680       error = clib_error_return (0, "failed to %s pitr!",
681                                  is_add ? "add" : "delete");
682     }
683
684 done:
685   if (locator_set_name)
686     vec_free (locator_set_name);
687   unformat_free (line_input);
688
689   return error;
690 }
691
692 /* *INDENT-OFF* */
693 VLIB_CLI_COMMAND (lisp_pitr_set_locator_set_command) = {
694     .path = "lisp pitr",
695     .short_help = "lisp pitr [disable] ls <locator-set-name>",
696     .function = lisp_pitr_set_locator_set_command_fn,
697 };
698 /* *INDENT-ON* */
699
700 static clib_error_t *
701 lisp_show_pitr_command_fn (vlib_main_t * vm,
702                            unformat_input_t * input, vlib_cli_command_t * cmd)
703 {
704   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
705   mapping_t *m;
706   locator_set_t *ls;
707   u8 *tmp_str = 0;
708   u8 status = lcm->flags & LISP_FLAG_PITR_MODE;
709
710   vlib_cli_output (vm, "%=20s%=16s", "pitr", status ? "locator-set" : "");
711
712   if (!status)
713     {
714       vlib_cli_output (vm, "%=20s", "disable");
715       return 0;
716     }
717
718   if (~0 == lcm->pitr_map_index)
719     {
720       tmp_str = format (0, "N/A");
721     }
722   else
723     {
724       m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
725       if (~0 != m->locator_set_index)
726         {
727           ls =
728             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
729           tmp_str = format (0, "%s", ls->name);
730         }
731       else
732         {
733           tmp_str = format (0, "N/A");
734         }
735     }
736   vec_add1 (tmp_str, 0);
737
738   vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
739
740   vec_free (tmp_str);
741
742   return 0;
743 }
744
745 /* *INDENT-OFF* */
746 VLIB_CLI_COMMAND (lisp_show_pitr_command) = {
747     .path = "show lisp pitr",
748     .short_help = "Show pitr",
749     .function = lisp_show_pitr_command_fn,
750 };
751 /* *INDENT-ON* */
752
753 static u8 *
754 format_eid_entry (u8 * s, va_list * args)
755 {
756   vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
757   lisp_cp_main_t *lcm = va_arg (*args, lisp_cp_main_t *);
758   mapping_t *mapit = va_arg (*args, mapping_t *);
759   locator_set_t *ls = va_arg (*args, locator_set_t *);
760   gid_address_t *gid = &mapit->eid;
761   u32 ttl = mapit->ttl;
762   u8 aut = mapit->authoritative;
763   u32 *loc_index;
764   u8 first_line = 1;
765   u8 *loc;
766
767   u8 *type = ls->local ? format (0, "local(%s)", ls->name)
768     : format (0, "remote");
769
770   if (vec_len (ls->locator_indices) == 0)
771     {
772       s = format (s, "%-35U%-30s%-20u%-u", format_gid_address, gid,
773                   type, ttl, aut);
774     }
775   else
776     {
777       vec_foreach (loc_index, ls->locator_indices)
778       {
779         locator_t *l = pool_elt_at_index (lcm->locator_pool, loc_index[0]);
780         if (l->local)
781           loc = format (0, "%U", format_vnet_sw_if_index_name, vnm,
782                         l->sw_if_index);
783         else
784           loc = format (0, "%U", format_ip_address,
785                         &gid_address_ip (&l->address));
786
787         if (first_line)
788           {
789             s = format (s, "%-35U%-20s%-30v%-20u%-u\n", format_gid_address,
790                         gid, type, loc, ttl, aut);
791             first_line = 0;
792           }
793         else
794           s = format (s, "%55s%v\n", "", loc);
795       }
796     }
797   return s;
798 }
799
800 static clib_error_t *
801 lisp_show_eid_table_command_fn (vlib_main_t * vm,
802                                 unformat_input_t * input,
803                                 vlib_cli_command_t * cmd)
804 {
805   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
806   mapping_t *mapit;
807   unformat_input_t _line_input, *line_input = &_line_input;
808   u32 mi;
809   gid_address_t eid;
810   u8 print_all = 1;
811   u8 filter = 0;
812   clib_error_t *error = NULL;
813
814   memset (&eid, 0, sizeof (eid));
815
816   /* Get a line of input. */
817   if (!unformat_user (input, unformat_line_input, line_input))
818     return 0;
819
820   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
821     {
822       if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
823         print_all = 0;
824       else if (unformat (line_input, "local"))
825         filter = 1;
826       else if (unformat (line_input, "remote"))
827         filter = 2;
828       else
829         {
830           error = clib_error_return (0, "parse error: '%U'",
831                                      format_unformat_error, line_input);
832           goto done;
833         }
834     }
835
836   vlib_cli_output (vm, "%-35s%-20s%-30s%-20s%-s",
837                    "EID", "type", "locators", "ttl", "authoritative");
838
839   if (print_all)
840     {
841       /* *INDENT-OFF* */
842       pool_foreach (mapit, lcm->mapping_pool,
843       ({
844         if (mapit->pitr_set)
845           continue;
846
847         locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool,
848                                                 mapit->locator_set_index);
849         if (filter && !((1 == filter && ls->local) ||
850           (2 == filter && !ls->local)))
851           {
852             continue;
853           }
854         vlib_cli_output (vm, "%U", format_eid_entry, lcm->vnet_main,
855                          lcm, mapit, ls);
856       }));
857       /* *INDENT-ON* */
858     }
859   else
860     {
861       mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &eid);
862       if ((u32) ~ 0 == mi)
863         goto done;
864
865       mapit = pool_elt_at_index (lcm->mapping_pool, mi);
866       locator_set_t *ls = pool_elt_at_index (lcm->locator_set_pool,
867                                              mapit->locator_set_index);
868
869       if (filter && !((1 == filter && ls->local) ||
870                       (2 == filter && !ls->local)))
871         {
872           goto done;
873         }
874
875       vlib_cli_output (vm, "%U,", format_eid_entry, lcm->vnet_main,
876                        lcm, mapit, ls);
877     }
878
879 done:
880   unformat_free (line_input);
881
882   return error;
883 }
884
885 /* *INDENT-OFF* */
886 VLIB_CLI_COMMAND (lisp_cp_show_eid_table_command) = {
887     .path = "show lisp eid-table",
888     .short_help = "Shows EID table",
889     .function = lisp_show_eid_table_command_fn,
890 };
891 /* *INDENT-ON* */
892
893
894 static clib_error_t *
895 lisp_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input,
896                                 vlib_cli_command_t * cmd)
897 {
898   unformat_input_t _line_input, *line_input = &_line_input;
899   u8 is_enabled = 0;
900   u8 is_set = 0;
901   clib_error_t *error = NULL;
902
903   /* Get a line of input. */
904   if (!unformat_user (input, unformat_line_input, line_input))
905     return clib_error_return (0, "expected enable | disable");
906
907   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
908     {
909       if (unformat (line_input, "enable"))
910         {
911           is_set = 1;
912           is_enabled = 1;
913         }
914       else if (unformat (line_input, "disable"))
915         is_set = 1;
916       else
917         {
918           error = clib_error_return (0, "parse error: '%U'",
919                                      format_unformat_error, line_input);
920           goto done;
921         }
922     }
923
924   if (!is_set)
925     {
926       error = clib_error_return (0, "state not set");
927       goto done;
928     }
929
930   vnet_lisp_enable_disable (is_enabled);
931
932 done:
933   unformat_free (line_input);
934
935   return error;
936 }
937
938 /* *INDENT-OFF* */
939 VLIB_CLI_COMMAND (lisp_cp_enable_disable_command) = {
940     .path = "lisp",
941     .short_help = "lisp [enable|disable]",
942     .function = lisp_enable_disable_command_fn,
943 };
944 /* *INDENT-ON* */
945
946 static clib_error_t *
947 lisp_map_register_enable_disable_command_fn (vlib_main_t * vm,
948                                              unformat_input_t * input,
949                                              vlib_cli_command_t * cmd)
950 {
951   unformat_input_t _line_input, *line_input = &_line_input;
952   u8 is_enabled = 0;
953   u8 is_set = 0;
954   clib_error_t *error = NULL;
955
956   /* Get a line of input. */
957   if (!unformat_user (input, unformat_line_input, line_input))
958     return clib_error_return (0, "expected enable | disable");
959
960   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
961     {
962       if (unformat (line_input, "enable"))
963         {
964           is_set = 1;
965           is_enabled = 1;
966         }
967       else if (unformat (line_input, "disable"))
968         is_set = 1;
969       else
970         {
971           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
972                            line_input);
973           goto done;
974         }
975     }
976
977   if (!is_set)
978     {
979       vlib_cli_output (vm, "state not set!");
980       goto done;
981     }
982
983   vnet_lisp_map_register_enable_disable (is_enabled);
984
985 done:
986   unformat_free (line_input);
987
988   return error;
989 }
990
991 /* *INDENT-OFF* */
992 VLIB_CLI_COMMAND (lisp_map_register_enable_disable_command) = {
993     .path = "lisp map-register",
994     .short_help = "lisp map-register [enable|disable]",
995     .function = lisp_map_register_enable_disable_command_fn,
996 };
997 /* *INDENT-ON* */
998
999 static clib_error_t *
1000 lisp_rloc_probe_enable_disable_command_fn (vlib_main_t * vm,
1001                                            unformat_input_t * input,
1002                                            vlib_cli_command_t * cmd)
1003 {
1004   unformat_input_t _line_input, *line_input = &_line_input;
1005   u8 is_enabled = 0;
1006   u8 is_set = 0;
1007   clib_error_t *error = NULL;
1008
1009   /* Get a line of input. */
1010   if (!unformat_user (input, unformat_line_input, line_input))
1011     return clib_error_return (0, "expected enable | disable");
1012
1013   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1014     {
1015       if (unformat (line_input, "enable"))
1016         {
1017           is_set = 1;
1018           is_enabled = 1;
1019         }
1020       else if (unformat (line_input, "disable"))
1021         is_set = 1;
1022       else
1023         {
1024           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1025                            line_input);
1026           goto done;
1027         }
1028     }
1029
1030   if (!is_set)
1031     {
1032       vlib_cli_output (vm, "state not set!");
1033       goto done;
1034     }
1035
1036   vnet_lisp_rloc_probe_enable_disable (is_enabled);
1037
1038 done:
1039   unformat_free (line_input);
1040
1041   return error;
1042 }
1043
1044 /* *INDENT-OFF* */
1045 VLIB_CLI_COMMAND (lisp_rloc_probe_enable_disable_command) = {
1046     .path = "lisp rloc-probe",
1047     .short_help = "lisp rloc-probe [enable|disable]",
1048     .function = lisp_rloc_probe_enable_disable_command_fn,
1049 };
1050 /* *INDENT-ON* */
1051
1052 static u8 *
1053 format_lisp_status (u8 * s, va_list * args)
1054 {
1055   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1056   return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
1057 }
1058
1059 static clib_error_t *
1060 lisp_show_status_command_fn (vlib_main_t * vm, unformat_input_t * input,
1061                              vlib_cli_command_t * cmd)
1062 {
1063   u8 *msg = 0;
1064   msg = format (msg, "feature: %U\ngpe: %U\n",
1065                 format_lisp_status, format_vnet_lisp_gpe_status);
1066   vlib_cli_output (vm, "%v", msg);
1067   vec_free (msg);
1068   return 0;
1069 }
1070
1071 /* *INDENT-OFF* */
1072 VLIB_CLI_COMMAND (lisp_show_status_command) = {
1073     .path = "show lisp status",
1074     .short_help = "show lisp status",
1075     .function = lisp_show_status_command_fn,
1076 };
1077 /* *INDENT-ON* */
1078
1079 static clib_error_t *
1080 lisp_show_eid_table_map_command_fn (vlib_main_t * vm,
1081                                     unformat_input_t * input,
1082                                     vlib_cli_command_t * cmd)
1083 {
1084   hash_pair_t *p;
1085   unformat_input_t _line_input, *line_input = &_line_input;
1086   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1087   uword *vni_table = 0;
1088   u8 is_l2 = 0;
1089   clib_error_t *error = NULL;
1090
1091   /* Get a line of input. */
1092   if (!unformat_user (input, unformat_line_input, line_input))
1093     return 0;
1094
1095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1096     {
1097       if (unformat (line_input, "l2"))
1098         {
1099           vni_table = lcm->bd_id_by_vni;
1100           is_l2 = 1;
1101         }
1102       else if (unformat (line_input, "l3"))
1103         {
1104           vni_table = lcm->table_id_by_vni;
1105           is_l2 = 0;
1106         }
1107       else
1108         {
1109           error = clib_error_return (0, "parse error: '%U'",
1110                                      format_unformat_error, line_input);
1111           goto done;
1112         }
1113     }
1114
1115   if (!vni_table)
1116     {
1117       vlib_cli_output (vm, "Error: expected l2|l3 param!\n");
1118       goto done;
1119     }
1120
1121   vlib_cli_output (vm, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
1122
1123   /* *INDENT-OFF* */
1124   hash_foreach_pair (p, vni_table,
1125   ({
1126     vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
1127   }));
1128   /* *INDENT-ON* */
1129
1130 done:
1131   unformat_free (line_input);
1132
1133   return error;
1134 }
1135
1136 /* *INDENT-OFF* */
1137 VLIB_CLI_COMMAND (lisp_show_eid_table_map_command) = {
1138     .path = "show lisp eid-table map",
1139     .short_help = "show lisp eid-table l2|l3",
1140     .function = lisp_show_eid_table_map_command_fn,
1141 };
1142 /* *INDENT-ON* */
1143
1144
1145 static clib_error_t *
1146 lisp_add_del_locator_set_command_fn (vlib_main_t * vm,
1147                                      unformat_input_t * input,
1148                                      vlib_cli_command_t * cmd)
1149 {
1150   lisp_gpe_main_t *lgm = &lisp_gpe_main;
1151   vnet_main_t *vnm = lgm->vnet_main;
1152   unformat_input_t _line_input, *line_input = &_line_input;
1153   u8 is_add = 1;
1154   clib_error_t *error = 0;
1155   u8 *locator_set_name = 0;
1156   locator_t locator, *locators = 0;
1157   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
1158   u32 ls_index = 0;
1159   int rv = 0;
1160
1161   memset (&locator, 0, sizeof (locator));
1162   memset (a, 0, sizeof (a[0]));
1163
1164   /* Get a line of input. */
1165   if (!unformat_user (input, unformat_line_input, line_input))
1166     return 0;
1167
1168   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1169     {
1170       if (unformat (line_input, "add %_%v%_", &locator_set_name))
1171         is_add = 1;
1172       else if (unformat (line_input, "del %_%v%_", &locator_set_name))
1173         is_add = 0;
1174       else if (unformat (line_input, "iface %U p %d w %d",
1175                          unformat_vnet_sw_interface, vnm,
1176                          &locator.sw_if_index, &locator.priority,
1177                          &locator.weight))
1178         {
1179           locator.local = 1;
1180           vec_add1 (locators, locator);
1181         }
1182       else
1183         {
1184           error = unformat_parse_error (line_input);
1185           goto done;
1186         }
1187     }
1188
1189   a->name = locator_set_name;
1190   a->locators = locators;
1191   a->is_add = is_add;
1192   a->local = 1;
1193
1194   rv = vnet_lisp_add_del_locator_set (a, &ls_index);
1195   if (0 != rv)
1196     {
1197       error = clib_error_return (0, "failed to %s locator-set!",
1198                                  is_add ? "add" : "delete");
1199     }
1200
1201 done:
1202   vec_free (locators);
1203   if (locator_set_name)
1204     vec_free (locator_set_name);
1205   unformat_free (line_input);
1206
1207   return error;
1208 }
1209
1210 /* *INDENT-OFF* */
1211 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_set_command) = {
1212     .path = "lisp locator-set",
1213     .short_help = "lisp locator-set add/del <name> [iface <iface-name> "
1214         "p <priority> w <weight>]",
1215     .function = lisp_add_del_locator_set_command_fn,
1216 };
1217 /* *INDENT-ON* */
1218
1219 static clib_error_t *
1220 lisp_add_del_locator_in_set_command_fn (vlib_main_t * vm,
1221                                         unformat_input_t * input,
1222                                         vlib_cli_command_t * cmd)
1223 {
1224   lisp_gpe_main_t *lgm = &lisp_gpe_main;
1225   vnet_main_t *vnm = lgm->vnet_main;
1226   unformat_input_t _line_input, *line_input = &_line_input;
1227   u8 is_add = 1;
1228   clib_error_t *error = 0;
1229   u8 *locator_set_name = 0;
1230   u8 locator_set_name_set = 0;
1231   locator_t locator, *locators = 0;
1232   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
1233   u32 ls_index = 0;
1234
1235   memset (&locator, 0, sizeof (locator));
1236   memset (a, 0, sizeof (a[0]));
1237
1238   /* Get a line of input. */
1239   if (!unformat_user (input, unformat_line_input, line_input))
1240     return 0;
1241
1242   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1243     {
1244       if (unformat (line_input, "add"))
1245         is_add = 1;
1246       else if (unformat (line_input, "del"))
1247         is_add = 0;
1248       else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
1249         locator_set_name_set = 1;
1250       else if (unformat (line_input, "iface %U p %d w %d",
1251                          unformat_vnet_sw_interface, vnm,
1252                          &locator.sw_if_index, &locator.priority,
1253                          &locator.weight))
1254         {
1255           locator.local = 1;
1256           vec_add1 (locators, locator);
1257         }
1258       else
1259         {
1260           error = unformat_parse_error (line_input);
1261           goto done;
1262         }
1263     }
1264
1265   if (!locator_set_name_set)
1266     {
1267       error = clib_error_return (0, "locator_set name not set!");
1268       goto done;
1269     }
1270
1271   a->name = locator_set_name;
1272   a->locators = locators;
1273   a->is_add = is_add;
1274   a->local = 1;
1275
1276   vnet_lisp_add_del_locator (a, 0, &ls_index);
1277
1278 done:
1279   vec_free (locators);
1280   vec_free (locator_set_name);
1281   unformat_free (line_input);
1282
1283   return error;
1284 }
1285
1286 /* *INDENT-OFF* */
1287 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_in_set_command) = {
1288     .path = "lisp locator",
1289     .short_help = "lisp locator add/del locator-set <name> iface <iface-name> "
1290                   "p <priority> w <weight>",
1291     .function = lisp_add_del_locator_in_set_command_fn,
1292 };
1293 /* *INDENT-ON* */
1294
1295 static clib_error_t *
1296 lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm,
1297                                       unformat_input_t * input,
1298                                       vlib_cli_command_t * cmd)
1299 {
1300   locator_set_t *lsit;
1301   locator_t *loc;
1302   u32 *locit;
1303   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1304
1305   vlib_cli_output (vm, "%s%=16s%=16s%=16s", "Locator-set", "Locator",
1306                    "Priority", "Weight");
1307
1308   /* *INDENT-OFF* */
1309   pool_foreach (lsit, lcm->locator_set_pool,
1310   ({
1311     u8 * msg = 0;
1312     int next_line = 0;
1313     if (lsit->local)
1314       {
1315         msg = format (msg, "%v", lsit->name);
1316       }
1317     else
1318       {
1319         msg = format (msg, "<%s-%d>", "remote", lsit - lcm->locator_set_pool);
1320       }
1321     vec_foreach (locit, lsit->locator_indices)
1322       {
1323         if (next_line)
1324           {
1325             msg = format (msg, "%16s", " ");
1326           }
1327         loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1328         if (loc->local)
1329           msg = format (msg, "%16d%16d%16d\n", loc->sw_if_index, loc->priority,
1330                         loc->weight);
1331         else
1332           msg = format (msg, "%16U%16d%16d\n", format_ip_address,
1333                         &gid_address_ip(&loc->address), loc->priority,
1334                         loc->weight);
1335         next_line = 1;
1336       }
1337     vlib_cli_output (vm, "%v", msg);
1338     vec_free (msg);
1339   }));
1340   /* *INDENT-ON* */
1341   return 0;
1342 }
1343
1344 /* *INDENT-OFF* */
1345 VLIB_CLI_COMMAND (lisp_cp_show_locator_sets_command) = {
1346     .path = "show lisp locator-set",
1347     .short_help = "Shows locator-sets",
1348     .function = lisp_cp_show_locator_sets_command_fn,
1349 };
1350 /* *INDENT-ON* */
1351
1352
1353 static clib_error_t *
1354 lisp_add_del_map_resolver_command_fn (vlib_main_t * vm,
1355                                       unformat_input_t * input,
1356                                       vlib_cli_command_t * cmd)
1357 {
1358   unformat_input_t _line_input, *line_input = &_line_input;
1359   u8 is_add = 1, addr_set = 0;
1360   ip_address_t ip_addr;
1361   clib_error_t *error = 0;
1362   int rv = 0;
1363   vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
1364
1365   /* Get a line of input. */
1366   if (!unformat_user (input, unformat_line_input, line_input))
1367     return 0;
1368
1369   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1370     {
1371       if (unformat (line_input, "add"))
1372         is_add = 1;
1373       else if (unformat (line_input, "del"))
1374         is_add = 0;
1375       else if (unformat (line_input, "%U", unformat_ip_address, &ip_addr))
1376         addr_set = 1;
1377       else
1378         {
1379           error = unformat_parse_error (line_input);
1380           goto done;
1381         }
1382     }
1383
1384   if (!addr_set)
1385     {
1386       error = clib_error_return (0, "Map-resolver address must be set!");
1387       goto done;
1388     }
1389
1390   a->is_add = is_add;
1391   a->address = ip_addr;
1392   rv = vnet_lisp_add_del_map_resolver (a);
1393   if (0 != rv)
1394     {
1395       error = clib_error_return (0, "failed to %s map-resolver!",
1396                                  is_add ? "add" : "delete");
1397     }
1398
1399 done:
1400   unformat_free (line_input);
1401
1402   return error;
1403 }
1404
1405 /* *INDENT-OFF* */
1406 VLIB_CLI_COMMAND (lisp_add_del_map_resolver_command) = {
1407     .path = "lisp map-resolver",
1408     .short_help = "lisp map-resolver add/del <ip_address>",
1409     .function = lisp_add_del_map_resolver_command_fn,
1410 };
1411 /* *INDENT-ON* */
1412
1413
1414 static clib_error_t *
1415 lisp_add_del_mreq_itr_rlocs_command_fn (vlib_main_t * vm,
1416                                         unformat_input_t * input,
1417                                         vlib_cli_command_t * cmd)
1418 {
1419   unformat_input_t _line_input, *line_input = &_line_input;
1420   u8 is_add = 1;
1421   u8 *locator_set_name = 0;
1422   clib_error_t *error = 0;
1423   int rv = 0;
1424   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
1425
1426   /* Get a line of input. */
1427   if (!unformat_user (input, unformat_line_input, line_input))
1428     return 0;
1429
1430   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1431     {
1432       if (unformat (line_input, "del"))
1433         is_add = 0;
1434       else if (unformat (line_input, "add %_%v%_", &locator_set_name))
1435         is_add = 1;
1436       else
1437         {
1438           error = unformat_parse_error (line_input);
1439           goto done;
1440         }
1441     }
1442
1443   vec_terminate_c_string (locator_set_name);
1444   a->is_add = is_add;
1445   a->locator_set_name = locator_set_name;
1446   rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
1447   if (0 != rv)
1448     {
1449       error = clib_error_return (0, "failed to %s map-request itr-rlocs!",
1450                                  is_add ? "add" : "delete");
1451     }
1452
1453 done:
1454   vec_free (locator_set_name);
1455   unformat_free (line_input);
1456
1457   return error;
1458 }
1459
1460 /* *INDENT-OFF* */
1461 VLIB_CLI_COMMAND (lisp_add_del_map_request_command) = {
1462     .path = "lisp map-request itr-rlocs",
1463     .short_help = "lisp map-request itr-rlocs add/del <locator_set_name>",
1464     .function = lisp_add_del_mreq_itr_rlocs_command_fn,
1465 };
1466 /* *INDENT-ON* */
1467
1468 static clib_error_t *
1469 lisp_show_mreq_itr_rlocs_command_fn (vlib_main_t * vm,
1470                                      unformat_input_t * input,
1471                                      vlib_cli_command_t * cmd)
1472 {
1473   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1474   locator_set_t *loc_set;
1475
1476   vlib_cli_output (vm, "%=20s", "itr-rlocs");
1477
1478   if (~0 == lcm->mreq_itr_rlocs)
1479     {
1480       return 0;
1481     }
1482
1483   loc_set = pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
1484
1485   vlib_cli_output (vm, "%=20s", loc_set->name);
1486
1487   return 0;
1488 }
1489
1490 /* *INDENT-OFF* */
1491 VLIB_CLI_COMMAND (lisp_show_map_request_command) = {
1492     .path = "show lisp map-request itr-rlocs",
1493     .short_help = "Shows map-request itr-rlocs",
1494     .function = lisp_show_mreq_itr_rlocs_command_fn,
1495 };
1496 /* *INDENT-ON* */
1497
1498 static clib_error_t *
1499 lisp_use_petr_set_locator_set_command_fn (vlib_main_t * vm,
1500                                           unformat_input_t * input,
1501                                           vlib_cli_command_t * cmd)
1502 {
1503   u8 is_add = 1, ip_set = 0;
1504   unformat_input_t _line_input, *line_input = &_line_input;
1505   clib_error_t *error = 0;
1506   ip_address_t ip;
1507
1508   /* Get a line of input. */
1509   if (!unformat_user (input, unformat_line_input, line_input))
1510     return 0;
1511
1512   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1513     {
1514       if (unformat (line_input, "%U", unformat_ip_address, &ip))
1515         ip_set = 1;
1516       else if (unformat (line_input, "disable"))
1517         is_add = 0;
1518       else
1519         {
1520           error = clib_error_return (0, "parse error");
1521           goto done;
1522         }
1523     }
1524
1525   if (!ip_set)
1526     {
1527       clib_warning ("No petr IP specified!");
1528       goto done;
1529     }
1530
1531   if (vnet_lisp_use_petr (&ip, is_add))
1532     {
1533       error = clib_error_return (0, "failed to %s petr!",
1534                                  is_add ? "add" : "delete");
1535     }
1536
1537 done:
1538   unformat_free (line_input);
1539
1540   return error;
1541 }
1542
1543 /* *INDENT-OFF* */
1544 VLIB_CLI_COMMAND (lisp_use_petr_set_locator_set_command) = {
1545     .path = "lisp use-petr",
1546     .short_help = "lisp use-petr [disable] <petr-ip>",
1547     .function = lisp_use_petr_set_locator_set_command_fn,
1548 };
1549
1550 static clib_error_t *
1551 lisp_show_petr_command_fn (vlib_main_t * vm,
1552                            unformat_input_t * input, vlib_cli_command_t * cmd)
1553 {
1554   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1555   mapping_t *m;
1556   locator_set_t *ls;
1557   locator_t *loc;
1558   u8 *tmp_str = 0;
1559   u8 use_petr = lcm->flags & LISP_FLAG_USE_PETR;
1560   vlib_cli_output (vm, "%=20s%=16s", "petr", use_petr ? "ip" : "");
1561
1562   if (!use_petr)
1563     {
1564       vlib_cli_output (vm, "%=20s", "disable");
1565       return 0;
1566     }
1567
1568   if (~0 == lcm->petr_map_index)
1569     {
1570       tmp_str = format (0, "N/A");
1571     }
1572   else
1573     {
1574       m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
1575       if (~0 != m->locator_set_index)
1576         {
1577           ls = pool_elt_at_index(lcm->locator_set_pool, m->locator_set_index);
1578           loc = pool_elt_at_index (lcm->locator_pool, ls->locator_indices[0]);
1579           tmp_str = format (0, "%U", format_ip_address, &loc->address);
1580         }
1581       else
1582         {
1583           tmp_str = format (0, "N/A");
1584         }
1585     }
1586   vec_add1 (tmp_str, 0);
1587
1588   vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
1589
1590   vec_free (tmp_str);
1591
1592   return 0;
1593 }
1594
1595 /* *INDENT-OFF* */
1596 VLIB_CLI_COMMAND (lisp_show_petr_command) = {
1597     .path = "show lisp petr",
1598     .short_help = "Show petr",
1599     .function = lisp_show_petr_command_fn,
1600 };
1601 /* *INDENT-ON* */
1602
1603 /*
1604  * fd.io coding-style-patch-verification: ON
1605  *
1606  * Local Variables:
1607  * eval: (c-set-style "gnu")
1608  * End:
1609  */