vxlan-gbp: Mark APIs as in-progress
[vpp.git] / src / plugins / lisp / 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 <lisp/lisp-cp/control.h>
17 #include <lisp/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   clib_memset (&eid, 0, sizeof (eid));
152   clib_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   clib_memset (&eid, 0, sizeof (eid));
312   clib_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       clib_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       clib_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 /* *INDENT-OFF* */
422 VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) = {
423     .path = "lisp remote-mapping",
424     .short_help = "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> "
427                   "w <weight> [rloc <dst-locator> ... ]",
428     .function = lisp_add_del_remote_mapping_command_fn,
429 };
430 /* *INDENT-ON* */
431
432 /**
433  * Handler for add/del adjacency CLI.
434  */
435 static clib_error_t *
436 lisp_add_del_adjacency_command_fn (vlib_main_t * vm, unformat_input_t * input,
437                                    vlib_cli_command_t * cmd)
438 {
439   clib_error_t *error = 0;
440   unformat_input_t _line_input, *line_input = &_line_input;
441   vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
442   u8 is_add = 1;
443   ip_prefix_t *reid_ippref, *leid_ippref;
444   gid_address_t leid, reid;
445   u8 *dmac = gid_address_mac (&reid);
446   u8 *smac = gid_address_mac (&leid);
447   u8 reid_set = 0, leid_set = 0;
448   u32 vni;
449
450   /* Get a line of input. */
451   if (!unformat_user (input, unformat_line_input, line_input))
452     return 0;
453
454   clib_memset (&reid, 0, sizeof (reid));
455   clib_memset (&leid, 0, sizeof (leid));
456
457   leid_ippref = &gid_address_ippref (&leid);
458   reid_ippref = &gid_address_ippref (&reid);
459
460   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
461     {
462       if (unformat (line_input, "del"))
463         is_add = 0;
464       else if (unformat (line_input, "add"))
465         ;
466       else if (unformat (line_input, "reid %U",
467                          unformat_ip_prefix, reid_ippref))
468         {
469           gid_address_type (&reid) = GID_ADDR_IP_PREFIX;
470           reid_set = 1;
471         }
472       else if (unformat (line_input, "reid %U", unformat_mac_address, dmac))
473         {
474           gid_address_type (&reid) = GID_ADDR_MAC;
475           reid_set = 1;
476         }
477       else if (unformat (line_input, "vni %u", &vni))
478         {
479           gid_address_vni (&leid) = vni;
480           gid_address_vni (&reid) = vni;
481         }
482       else if (unformat (line_input, "leid %U",
483                          unformat_ip_prefix, leid_ippref))
484         {
485           gid_address_type (&leid) = GID_ADDR_IP_PREFIX;
486           leid_set = 1;
487         }
488       else if (unformat (line_input, "leid %U", unformat_mac_address, smac))
489         {
490           gid_address_type (&leid) = GID_ADDR_MAC;
491           leid_set = 1;
492         }
493       else
494         {
495           clib_warning ("parse error");
496           goto done;
497         }
498     }
499
500   if (!reid_set || !leid_set)
501     {
502       clib_warning ("missing remote or local eid!");
503       goto done;
504     }
505
506   if ((gid_address_type (&leid) != gid_address_type (&reid))
507       || (gid_address_type (&reid) == GID_ADDR_IP_PREFIX
508           && ip_prefix_version (reid_ippref)
509           != ip_prefix_version (leid_ippref)))
510     {
511       clib_warning ("remote and local EIDs are of different types!");
512       goto done;
513     }
514
515   clib_memset (a, 0, sizeof (a[0]));
516   gid_address_copy (&a->leid, &leid);
517   gid_address_copy (&a->reid, &reid);
518   a->is_add = is_add;
519
520   if (vnet_lisp_add_del_adjacency (a))
521     clib_warning ("failed to %s adjacency!", is_add ? "add" : "delete");
522
523 done:
524   unformat_free (line_input);
525   return error;
526 }
527
528 /* *INDENT-OFF* */
529 VLIB_CLI_COMMAND (lisp_add_del_adjacency_command) = {
530     .path = "lisp adjacency",
531     .short_help = "lisp adjacency add|del vni <vni> reid <remote-eid> "
532       "leid <local-eid>",
533     .function = lisp_add_del_adjacency_command_fn,
534 };
535 /* *INDENT-ON* */
536
537
538 static clib_error_t *
539 lisp_map_request_mode_command_fn (vlib_main_t * vm,
540                                   unformat_input_t * input,
541                                   vlib_cli_command_t * cmd)
542 {
543   unformat_input_t _i, *i = &_i;
544   map_request_mode_t mr_mode = _MR_MODE_MAX;
545   clib_error_t *error = NULL;
546
547   /* Get a line of input. */
548   if (!unformat_user (input, unformat_line_input, i))
549     return 0;
550
551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
552     {
553       if (unformat (i, "dst-only"))
554         mr_mode = MR_MODE_DST_ONLY;
555       else if (unformat (i, "src-dst"))
556         mr_mode = MR_MODE_SRC_DST;
557       else
558         {
559           clib_warning ("parse error '%U'", format_unformat_error, i);
560           goto done;
561         }
562     }
563
564   if (_MR_MODE_MAX == mr_mode)
565     {
566       clib_warning ("No LISP map request mode entered!");
567       goto done;
568     }
569
570   vnet_lisp_set_map_request_mode (mr_mode);
571
572 done:
573   unformat_free (i);
574
575   return error;
576 }
577
578 /* *INDENT-OFF* */
579 VLIB_CLI_COMMAND (lisp_map_request_mode_command) = {
580     .path = "lisp map-request mode",
581     .short_help = "lisp map-request mode dst-only|src-dst",
582     .function = lisp_map_request_mode_command_fn,
583 };
584 /* *INDENT-ON* */
585
586
587 static u8 *
588 format_lisp_map_request_mode (u8 * s, va_list * args)
589 {
590   u32 mode = va_arg (*args, u32);
591
592   switch (mode)
593     {
594     case 0:
595       return format (0, "dst-only");
596     case 1:
597       return format (0, "src-dst");
598     }
599   return 0;
600 }
601
602 static clib_error_t *
603 lisp_show_map_request_mode_command_fn (vlib_main_t * vm,
604                                        unformat_input_t * input,
605                                        vlib_cli_command_t * cmd)
606 {
607   vlib_cli_output (vm, "map-request mode: %U", format_lisp_map_request_mode,
608                    vnet_lisp_get_map_request_mode ());
609   return 0;
610 }
611
612 /* *INDENT-OFF* */
613 VLIB_CLI_COMMAND (lisp_show_map_request_mode_command) = {
614     .path = "show lisp map-request mode",
615     .short_help = "show lisp map-request mode",
616     .function = lisp_show_map_request_mode_command_fn,
617 };
618 /* *INDENT-ON* */
619
620 static clib_error_t *
621 lisp_show_map_resolvers_command_fn (vlib_main_t * vm,
622                                     unformat_input_t * input,
623                                     vlib_cli_command_t * cmd)
624 {
625   lisp_msmr_t *mr;
626   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
627
628   vec_foreach (mr, lcm->map_resolvers)
629   {
630     vlib_cli_output (vm, "%U", format_ip_address, &mr->address);
631   }
632   return 0;
633 }
634
635 /* *INDENT-OFF* */
636 VLIB_CLI_COMMAND (lisp_show_map_resolvers_command) = {
637     .path = "show lisp map-resolvers",
638     .short_help = "show lisp map-resolvers",
639     .function = lisp_show_map_resolvers_command_fn,
640 };
641 /* *INDENT-ON* */
642
643
644 static clib_error_t *
645 lisp_pitr_set_locator_set_command_fn (vlib_main_t * vm,
646                                       unformat_input_t * input,
647                                       vlib_cli_command_t * cmd)
648 {
649   u8 locator_name_set = 0;
650   u8 *locator_set_name = 0;
651   u8 is_add = 1;
652   unformat_input_t _line_input, *line_input = &_line_input;
653   clib_error_t *error = 0;
654   int rv = 0;
655
656   /* Get a line of input. */
657   if (!unformat_user (input, unformat_line_input, line_input))
658     return 0;
659
660   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
661     {
662       if (unformat (line_input, "ls %_%v%_", &locator_set_name))
663         locator_name_set = 1;
664       else if (unformat (line_input, "disable"))
665         is_add = 0;
666       else
667         {
668           error = clib_error_return (0, "parse error");
669           goto done;
670         }
671     }
672
673   if (!locator_name_set)
674     {
675       clib_warning ("No locator set specified!");
676       goto done;
677     }
678   vec_terminate_c_string (locator_set_name);
679   rv = vnet_lisp_pitr_set_locator_set (locator_set_name, is_add);
680   if (0 != rv)
681     {
682       error = clib_error_return (0, "failed to %s pitr!",
683                                  is_add ? "add" : "delete");
684     }
685
686 done:
687   if (locator_set_name)
688     vec_free (locator_set_name);
689   unformat_free (line_input);
690
691   return error;
692 }
693
694 /* *INDENT-OFF* */
695 VLIB_CLI_COMMAND (lisp_pitr_set_locator_set_command) = {
696     .path = "lisp pitr",
697     .short_help = "lisp pitr [disable] ls <locator-set-name>",
698     .function = lisp_pitr_set_locator_set_command_fn,
699 };
700 /* *INDENT-ON* */
701
702 static clib_error_t *
703 lisp_show_pitr_command_fn (vlib_main_t * vm,
704                            unformat_input_t * input, vlib_cli_command_t * cmd)
705 {
706   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
707   mapping_t *m;
708   locator_set_t *ls;
709   u8 *tmp_str = 0;
710   u8 status = lcm->flags & LISP_FLAG_PITR_MODE;
711
712   vlib_cli_output (vm, "%=20s%=16s", "pitr", status ? "locator-set" : "");
713
714   if (!status)
715     {
716       vlib_cli_output (vm, "%=20s", "disable");
717       return 0;
718     }
719
720   if (~0 == lcm->pitr_map_index)
721     {
722       tmp_str = format (0, "N/A");
723     }
724   else
725     {
726       m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
727       if (~0 != m->locator_set_index)
728         {
729           ls =
730             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
731           tmp_str = format (0, "%s", ls->name);
732         }
733       else
734         {
735           tmp_str = format (0, "N/A");
736         }
737     }
738   vec_add1 (tmp_str, 0);
739
740   vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
741
742   vec_free (tmp_str);
743
744   return 0;
745 }
746
747 /* *INDENT-OFF* */
748 VLIB_CLI_COMMAND (lisp_show_pitr_command) = {
749     .path = "show lisp pitr",
750     .short_help = "Show pitr",
751     .function = lisp_show_pitr_command_fn,
752 };
753 /* *INDENT-ON* */
754
755 static u8 *
756 format_eid_entry (u8 * s, va_list * args)
757 {
758   vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
759   lisp_cp_main_t *lcm = va_arg (*args, lisp_cp_main_t *);
760   mapping_t *mapit = va_arg (*args, mapping_t *);
761   locator_set_t *ls = va_arg (*args, locator_set_t *);
762   gid_address_t *gid = &mapit->eid;
763   u32 ttl = mapit->ttl;
764   u8 aut = mapit->authoritative;
765   u32 *loc_index;
766   u8 first_line = 1;
767   u8 *loc;
768
769   u8 *type = ls->local ? format (0, "local(%s)", ls->name)
770     : format (0, "remote");
771
772   if (vec_len (ls->locator_indices) == 0)
773     {
774       s = format (s, "%-35U%-30s%-20u%-u", format_gid_address, gid,
775                   type, ttl, aut);
776     }
777   else
778     {
779       vec_foreach (loc_index, ls->locator_indices)
780       {
781         locator_t *l = pool_elt_at_index (lcm->locator_pool, loc_index[0]);
782         if (l->local)
783           loc = format (0, "%U", format_vnet_sw_if_index_name, vnm,
784                         l->sw_if_index);
785         else
786           loc = format (0, "%U", format_ip_address,
787                         &gid_address_ip (&l->address));
788
789         if (first_line)
790           {
791             s = format (s, "%-35U%-20s%-30v%-20u%-u\n", format_gid_address,
792                         gid, type, loc, ttl, aut);
793             first_line = 0;
794           }
795         else
796           s = format (s, "%55s%v\n", "", loc);
797       }
798     }
799   return s;
800 }
801
802 static clib_error_t *
803 lisp_show_eid_table_command_fn (vlib_main_t * vm,
804                                 unformat_input_t * input,
805                                 vlib_cli_command_t * cmd)
806 {
807   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
808   mapping_t *mapit;
809   unformat_input_t _line_input, *line_input = &_line_input;
810   u32 mi;
811   gid_address_t eid;
812   u8 print_all = 1;
813   u8 filter = 0;
814   clib_error_t *error = NULL;
815
816   clib_memset (&eid, 0, sizeof (eid));
817
818   /* Get a line of input. */
819   if (!unformat_user (input, unformat_line_input, line_input))
820     return 0;
821
822   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
823     {
824       if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
825         print_all = 0;
826       else if (unformat (line_input, "local"))
827         filter = 1;
828       else if (unformat (line_input, "remote"))
829         filter = 2;
830       else
831         {
832           error = clib_error_return (0, "parse error: '%U'",
833                                      format_unformat_error, line_input);
834           goto done;
835         }
836     }
837
838   vlib_cli_output (vm, "%-35s%-20s%-30s%-20s%-s",
839                    "EID", "type", "locators", "ttl", "authoritative");
840
841   if (print_all)
842     {
843       /* *INDENT-OFF* */
844       pool_foreach (mapit, lcm->mapping_pool,
845       ({
846         if (mapit->pitr_set)
847           continue;
848
849         locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool,
850                                                 mapit->locator_set_index);
851         if (filter && !((1 == filter && ls->local) ||
852           (2 == filter && !ls->local)))
853           {
854             continue;
855           }
856         vlib_cli_output (vm, "%U", format_eid_entry, lcm->vnet_main,
857                          lcm, mapit, ls);
858       }));
859       /* *INDENT-ON* */
860     }
861   else
862     {
863       mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &eid);
864       if ((u32) ~ 0 == mi)
865         goto done;
866
867       mapit = pool_elt_at_index (lcm->mapping_pool, mi);
868       locator_set_t *ls = pool_elt_at_index (lcm->locator_set_pool,
869                                              mapit->locator_set_index);
870
871       if (filter && !((1 == filter && ls->local) ||
872                       (2 == filter && !ls->local)))
873         {
874           goto done;
875         }
876
877       vlib_cli_output (vm, "%U,", format_eid_entry, lcm->vnet_main,
878                        lcm, mapit, ls);
879     }
880
881 done:
882   unformat_free (line_input);
883
884   return error;
885 }
886
887 /* *INDENT-OFF* */
888 VLIB_CLI_COMMAND (lisp_cp_show_eid_table_command) = {
889     .path = "show lisp eid-table",
890     .short_help = "show lisp eid-table [local|remote|eid <eid>]",
891     .function = lisp_show_eid_table_command_fn,
892 };
893 /* *INDENT-ON* */
894
895
896 static clib_error_t *
897 lisp_enable_command_fn (vlib_main_t * vm, unformat_input_t * input,
898                         vlib_cli_command_t * cmd)
899 {
900   if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
901     return clib_error_return (0, "parse error: '%U'", format_unformat_error,
902                               input);
903
904   vnet_lisp_enable_disable (1);
905
906   return 0;
907 }
908
909 /* *INDENT-OFF* */
910 VLIB_CLI_COMMAND (lisp_cp_enable_command) = {
911     .path = "lisp enable",
912     .short_help = "lisp enable",
913     .function = lisp_enable_command_fn,
914 };
915 /* *INDENT-ON* */
916
917 static clib_error_t *
918 lisp_disable_command_fn (vlib_main_t * vm, unformat_input_t * input,
919                          vlib_cli_command_t * cmd)
920 {
921   if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
922     return clib_error_return (0, "parse error: '%U'", format_unformat_error,
923                               input);
924
925   vnet_lisp_enable_disable (0);
926
927   return 0;
928 }
929
930 /* *INDENT-OFF* */
931 VLIB_CLI_COMMAND (lisp_cp_disable_command) = {
932     .path = "lisp disable",
933     .short_help = "lisp disable",
934     .function = lisp_disable_command_fn,
935 };
936 /* *INDENT-ON* */
937
938 static clib_error_t *
939 lisp_map_register_enable_disable_command_fn (vlib_main_t * vm,
940                                              unformat_input_t * input,
941                                              vlib_cli_command_t * cmd)
942 {
943   unformat_input_t _line_input, *line_input = &_line_input;
944   u8 is_enabled = 0;
945   u8 is_set = 0;
946   clib_error_t *error = NULL;
947
948   /* Get a line of input. */
949   if (!unformat_user (input, unformat_line_input, line_input))
950     return clib_error_return (0, "expected enable | disable");
951
952   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
953     {
954       if (unformat (line_input, "enable"))
955         {
956           is_set = 1;
957           is_enabled = 1;
958         }
959       else if (unformat (line_input, "disable"))
960         is_set = 1;
961       else
962         {
963           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
964                            line_input);
965           goto done;
966         }
967     }
968
969   if (!is_set)
970     {
971       vlib_cli_output (vm, "state not set!");
972       goto done;
973     }
974
975   vnet_lisp_map_register_enable_disable (is_enabled);
976
977 done:
978   unformat_free (line_input);
979
980   return error;
981 }
982
983 /* *INDENT-OFF* */
984 VLIB_CLI_COMMAND (lisp_map_register_enable_disable_command) = {
985     .path = "lisp map-register",
986     .short_help = "lisp map-register [enable|disable]",
987     .function = lisp_map_register_enable_disable_command_fn,
988 };
989 /* *INDENT-ON* */
990
991 static clib_error_t *
992 lisp_rloc_probe_enable_disable_command_fn (vlib_main_t * vm,
993                                            unformat_input_t * input,
994                                            vlib_cli_command_t * cmd)
995 {
996   unformat_input_t _line_input, *line_input = &_line_input;
997   u8 is_enabled = 0;
998   u8 is_set = 0;
999   clib_error_t *error = NULL;
1000
1001   /* Get a line of input. */
1002   if (!unformat_user (input, unformat_line_input, line_input))
1003     return clib_error_return (0, "expected enable | disable");
1004
1005   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1006     {
1007       if (unformat (line_input, "enable"))
1008         {
1009           is_set = 1;
1010           is_enabled = 1;
1011         }
1012       else if (unformat (line_input, "disable"))
1013         is_set = 1;
1014       else
1015         {
1016           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1017                            line_input);
1018           goto done;
1019         }
1020     }
1021
1022   if (!is_set)
1023     {
1024       vlib_cli_output (vm, "state not set!");
1025       goto done;
1026     }
1027
1028   vnet_lisp_rloc_probe_enable_disable (is_enabled);
1029
1030 done:
1031   unformat_free (line_input);
1032
1033   return error;
1034 }
1035
1036 /* *INDENT-OFF* */
1037 VLIB_CLI_COMMAND (lisp_rloc_probe_enable_disable_command) = {
1038     .path = "lisp rloc-probe",
1039     .short_help = "lisp rloc-probe [enable|disable]",
1040     .function = lisp_rloc_probe_enable_disable_command_fn,
1041 };
1042 /* *INDENT-ON* */
1043
1044 static u8 *
1045 format_lisp_status (u8 * s, va_list * args)
1046 {
1047   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1048   return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
1049 }
1050
1051 static clib_error_t *
1052 lisp_show_status_command_fn (vlib_main_t * vm, unformat_input_t * input,
1053                              vlib_cli_command_t * cmd)
1054 {
1055   u8 *msg = 0;
1056   msg = format (msg, "feature: %U\ngpe: %U\n",
1057                 format_lisp_status, format_vnet_lisp_gpe_status);
1058   vlib_cli_output (vm, "%v", msg);
1059   vec_free (msg);
1060   return 0;
1061 }
1062
1063 /* *INDENT-OFF* */
1064 VLIB_CLI_COMMAND (lisp_show_status_command) = {
1065     .path = "show lisp status",
1066     .short_help = "show lisp status",
1067     .function = lisp_show_status_command_fn,
1068 };
1069 /* *INDENT-ON* */
1070
1071 static clib_error_t *
1072 lisp_show_eid_table_map_command_fn (vlib_main_t * vm,
1073                                     unformat_input_t * input,
1074                                     vlib_cli_command_t * cmd)
1075 {
1076   hash_pair_t *p;
1077   unformat_input_t _line_input, *line_input = &_line_input;
1078   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1079   uword *vni_table = 0;
1080   u8 is_l2 = 0;
1081   clib_error_t *error = NULL;
1082
1083   /* Get a line of input. */
1084   if (!unformat_user (input, unformat_line_input, line_input))
1085     return 0;
1086
1087   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1088     {
1089       if (unformat (line_input, "l2"))
1090         {
1091           vni_table = lcm->bd_id_by_vni;
1092           is_l2 = 1;
1093         }
1094       else if (unformat (line_input, "l3"))
1095         {
1096           vni_table = lcm->table_id_by_vni;
1097           is_l2 = 0;
1098         }
1099       else
1100         {
1101           error = clib_error_return (0, "parse error: '%U'",
1102                                      format_unformat_error, line_input);
1103           goto done;
1104         }
1105     }
1106
1107   if (!vni_table)
1108     {
1109       vlib_cli_output (vm, "Error: expected l2|l3 param!\n");
1110       goto done;
1111     }
1112
1113   vlib_cli_output (vm, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
1114
1115   /* *INDENT-OFF* */
1116   hash_foreach_pair (p, vni_table,
1117   ({
1118     vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
1119   }));
1120   /* *INDENT-ON* */
1121
1122 done:
1123   unformat_free (line_input);
1124
1125   return error;
1126 }
1127
1128 /* *INDENT-OFF* */
1129 VLIB_CLI_COMMAND (lisp_show_eid_table_map_command) = {
1130     .path = "show lisp eid-table map",
1131     .short_help = "show lisp eid-table map l2|l3",
1132     .function = lisp_show_eid_table_map_command_fn,
1133 };
1134 /* *INDENT-ON* */
1135
1136
1137 static clib_error_t *
1138 lisp_add_del_locator_set_command_fn (vlib_main_t * vm,
1139                                      unformat_input_t * input,
1140                                      vlib_cli_command_t * cmd)
1141 {
1142   lisp_gpe_main_t *lgm = &lisp_gpe_main;
1143   vnet_main_t *vnm = lgm->vnet_main;
1144   unformat_input_t _line_input, *line_input = &_line_input;
1145   u8 is_add = 1;
1146   clib_error_t *error = 0;
1147   u8 *locator_set_name = 0;
1148   locator_t locator, *locators = 0;
1149   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
1150   u32 ls_index = 0;
1151   int rv = 0;
1152
1153   clib_memset (&locator, 0, sizeof (locator));
1154   clib_memset (a, 0, sizeof (a[0]));
1155
1156   /* Get a line of input. */
1157   if (!unformat_user (input, unformat_line_input, line_input))
1158     return clib_error_return (0, "missing parameters");
1159
1160   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1161     {
1162       if (unformat (line_input, "add %_%v%_", &locator_set_name))
1163         is_add = 1;
1164       else if (unformat (line_input, "del %_%v%_", &locator_set_name))
1165         is_add = 0;
1166       else if (unformat (line_input, "iface %U p %d w %d",
1167                          unformat_vnet_sw_interface, vnm,
1168                          &locator.sw_if_index, &locator.priority,
1169                          &locator.weight))
1170         {
1171           locator.local = 1;
1172           locator.state = 1;
1173           vec_add1 (locators, locator);
1174         }
1175       else
1176         {
1177           error = unformat_parse_error (line_input);
1178           goto done;
1179         }
1180     }
1181
1182   vec_terminate_c_string (locator_set_name);
1183   a->name = locator_set_name;
1184   a->locators = locators;
1185   a->is_add = is_add;
1186   a->local = 1;
1187
1188   rv = vnet_lisp_add_del_locator_set (a, &ls_index);
1189   if (0 != rv)
1190     {
1191       error = clib_error_return (0, "failed to %s locator-set!",
1192                                  is_add ? "add" : "delete");
1193     }
1194
1195 done:
1196   vec_free (locators);
1197   if (locator_set_name)
1198     vec_free (locator_set_name);
1199   unformat_free (line_input);
1200
1201   return error;
1202 }
1203
1204 /* *INDENT-OFF* */
1205 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_set_command) = {
1206     .path = "lisp locator-set",
1207     .short_help = "lisp locator-set add/del <name> [iface <iface-name> "
1208         "p <priority> w <weight>]",
1209     .function = lisp_add_del_locator_set_command_fn,
1210 };
1211 /* *INDENT-ON* */
1212
1213 static clib_error_t *
1214 lisp_add_del_locator_in_set_command_fn (vlib_main_t * vm,
1215                                         unformat_input_t * input,
1216                                         vlib_cli_command_t * cmd)
1217 {
1218   lisp_gpe_main_t *lgm = &lisp_gpe_main;
1219   vnet_main_t *vnm = lgm->vnet_main;
1220   unformat_input_t _line_input, *line_input = &_line_input;
1221   u8 is_add = 1;
1222   clib_error_t *error = 0;
1223   u8 *locator_set_name = 0;
1224   u8 locator_set_name_set = 0;
1225   locator_t locator, *locators = 0;
1226   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
1227   u32 ls_index = 0;
1228
1229   clib_memset (&locator, 0, sizeof (locator));
1230   clib_memset (a, 0, sizeof (a[0]));
1231
1232   /* Get a line of input. */
1233   if (!unformat_user (input, unformat_line_input, line_input))
1234     return 0;
1235
1236   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1237     {
1238       if (unformat (line_input, "add"))
1239         is_add = 1;
1240       else if (unformat (line_input, "del"))
1241         is_add = 0;
1242       else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
1243         locator_set_name_set = 1;
1244       else if (unformat (line_input, "iface %U p %d w %d",
1245                          unformat_vnet_sw_interface, vnm,
1246                          &locator.sw_if_index, &locator.priority,
1247                          &locator.weight))
1248         {
1249           locator.local = 1;
1250           vec_add1 (locators, locator);
1251         }
1252       else
1253         {
1254           error = unformat_parse_error (line_input);
1255           goto done;
1256         }
1257     }
1258
1259   if (!locator_set_name_set)
1260     {
1261       error = clib_error_return (0, "locator_set name not set!");
1262       goto done;
1263     }
1264
1265   a->name = locator_set_name;
1266   a->locators = locators;
1267   a->is_add = is_add;
1268   a->local = 1;
1269
1270   vnet_lisp_add_del_locator (a, 0, &ls_index);
1271
1272 done:
1273   vec_free (locators);
1274   vec_free (locator_set_name);
1275   unformat_free (line_input);
1276
1277   return error;
1278 }
1279
1280 /* *INDENT-OFF* */
1281 VLIB_CLI_COMMAND (lisp_cp_add_del_locator_in_set_command) = {
1282     .path = "lisp locator",
1283     .short_help = "lisp locator add/del locator-set <name> iface <iface-name> "
1284                   "p <priority> w <weight>",
1285     .function = lisp_add_del_locator_in_set_command_fn,
1286 };
1287 /* *INDENT-ON* */
1288
1289 static clib_error_t *
1290 lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm,
1291                                       unformat_input_t * input,
1292                                       vlib_cli_command_t * cmd)
1293 {
1294   locator_set_t *lsit;
1295   locator_t *loc;
1296   u32 *locit;
1297   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1298
1299   vlib_cli_output (vm, "%s%=16s%=16s%=16s", "Locator-set", "Locator",
1300                    "Priority", "Weight");
1301
1302   /* *INDENT-OFF* */
1303   pool_foreach (lsit, lcm->locator_set_pool,
1304   ({
1305     u8 * msg = 0;
1306     int next_line = 0;
1307     if (lsit->local)
1308       {
1309         msg = format (msg, "%v", lsit->name);
1310       }
1311     else
1312       {
1313         msg = format (msg, "<%s-%d>", "remote", lsit - lcm->locator_set_pool);
1314       }
1315     vec_foreach (locit, lsit->locator_indices)
1316       {
1317         if (next_line)
1318           {
1319             msg = format (msg, "%16s", " ");
1320           }
1321         loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1322         if (loc->local)
1323           msg = format (msg, "%16d%16d%16d\n", loc->sw_if_index, loc->priority,
1324                         loc->weight);
1325         else
1326           msg = format (msg, "%16U%16d%16d\n", format_ip_address,
1327                         &gid_address_ip(&loc->address), loc->priority,
1328                         loc->weight);
1329         next_line = 1;
1330       }
1331     vlib_cli_output (vm, "%v", msg);
1332     vec_free (msg);
1333   }));
1334   /* *INDENT-ON* */
1335   return 0;
1336 }
1337
1338 /* *INDENT-OFF* */
1339 VLIB_CLI_COMMAND (lisp_cp_show_locator_sets_command) = {
1340     .path = "show lisp locator-set",
1341     .short_help = "Shows locator-sets",
1342     .function = lisp_cp_show_locator_sets_command_fn,
1343 };
1344 /* *INDENT-ON* */
1345
1346
1347 static clib_error_t *
1348 lisp_add_del_map_resolver_command_fn (vlib_main_t * vm,
1349                                       unformat_input_t * input,
1350                                       vlib_cli_command_t * cmd)
1351 {
1352   unformat_input_t _line_input, *line_input = &_line_input;
1353   u8 is_add = 1, addr_set = 0;
1354   ip_address_t ip_addr;
1355   clib_error_t *error = 0;
1356   int rv = 0;
1357   vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
1358
1359   /* Get a line of input. */
1360   if (!unformat_user (input, unformat_line_input, line_input))
1361     return 0;
1362
1363   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1364     {
1365       if (unformat (line_input, "add"))
1366         is_add = 1;
1367       else if (unformat (line_input, "del"))
1368         is_add = 0;
1369       else if (unformat (line_input, "%U", unformat_ip_address, &ip_addr))
1370         addr_set = 1;
1371       else
1372         {
1373           error = unformat_parse_error (line_input);
1374           goto done;
1375         }
1376     }
1377
1378   if (!addr_set)
1379     {
1380       error = clib_error_return (0, "Map-resolver address must be set!");
1381       goto done;
1382     }
1383
1384   a->is_add = is_add;
1385   a->address = ip_addr;
1386   rv = vnet_lisp_add_del_map_resolver (a);
1387   if (0 != rv)
1388     {
1389       error = clib_error_return (0, "failed to %s map-resolver!",
1390                                  is_add ? "add" : "delete");
1391     }
1392
1393 done:
1394   unformat_free (line_input);
1395
1396   return error;
1397 }
1398
1399 /* *INDENT-OFF* */
1400 VLIB_CLI_COMMAND (lisp_add_del_map_resolver_command) = {
1401     .path = "lisp map-resolver",
1402     .short_help = "lisp map-resolver add/del <ip_address>",
1403     .function = lisp_add_del_map_resolver_command_fn,
1404 };
1405 /* *INDENT-ON* */
1406
1407
1408 static clib_error_t *
1409 lisp_add_del_mreq_itr_rlocs_command_fn (vlib_main_t * vm,
1410                                         unformat_input_t * input,
1411                                         vlib_cli_command_t * cmd)
1412 {
1413   unformat_input_t _line_input, *line_input = &_line_input;
1414   u8 is_add = 1;
1415   u8 *locator_set_name = 0;
1416   clib_error_t *error = 0;
1417   int rv = 0;
1418   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
1419
1420   /* Get a line of input. */
1421   if (!unformat_user (input, unformat_line_input, line_input))
1422     return 0;
1423
1424   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1425     {
1426       if (unformat (line_input, "del"))
1427         is_add = 0;
1428       else if (unformat (line_input, "add %_%v%_", &locator_set_name))
1429         is_add = 1;
1430       else
1431         {
1432           error = unformat_parse_error (line_input);
1433           goto done;
1434         }
1435     }
1436
1437   vec_terminate_c_string (locator_set_name);
1438   a->is_add = is_add;
1439   a->locator_set_name = locator_set_name;
1440   rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
1441   if (0 != rv)
1442     {
1443       error = clib_error_return (0, "failed to %s map-request itr-rlocs!",
1444                                  is_add ? "add" : "delete");
1445     }
1446
1447 done:
1448   vec_free (locator_set_name);
1449   unformat_free (line_input);
1450
1451   return error;
1452 }
1453
1454 /* *INDENT-OFF* */
1455 VLIB_CLI_COMMAND (lisp_add_del_map_request_command) = {
1456     .path = "lisp map-request itr-rlocs",
1457     .short_help = "lisp map-request itr-rlocs add/del <locator_set_name>",
1458     .function = lisp_add_del_mreq_itr_rlocs_command_fn,
1459 };
1460 /* *INDENT-ON* */
1461
1462 static clib_error_t *
1463 lisp_show_mreq_itr_rlocs_command_fn (vlib_main_t * vm,
1464                                      unformat_input_t * input,
1465                                      vlib_cli_command_t * cmd)
1466 {
1467   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1468   locator_set_t *loc_set;
1469
1470   vlib_cli_output (vm, "%=20s", "itr-rlocs");
1471
1472   if (~0 == lcm->mreq_itr_rlocs)
1473     {
1474       return 0;
1475     }
1476
1477   loc_set = pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
1478
1479   vlib_cli_output (vm, "%=20s", loc_set->name);
1480
1481   return 0;
1482 }
1483
1484 /* *INDENT-OFF* */
1485 VLIB_CLI_COMMAND (lisp_show_map_request_command) = {
1486     .path = "show lisp map-request itr-rlocs",
1487     .short_help = "Shows map-request itr-rlocs",
1488     .function = lisp_show_mreq_itr_rlocs_command_fn,
1489 };
1490 /* *INDENT-ON* */
1491
1492 static clib_error_t *
1493 lisp_use_petr_set_locator_set_command_fn (vlib_main_t * vm,
1494                                           unformat_input_t * input,
1495                                           vlib_cli_command_t * cmd)
1496 {
1497   u8 is_add = 1, ip_set = 0;
1498   unformat_input_t _line_input, *line_input = &_line_input;
1499   clib_error_t *error = 0;
1500   ip_address_t ip;
1501
1502   /* Get a line of input. */
1503   if (!unformat_user (input, unformat_line_input, line_input))
1504     return 0;
1505
1506   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1507     {
1508       if (unformat (line_input, "%U", unformat_ip_address, &ip))
1509         ip_set = 1;
1510       else if (unformat (line_input, "disable"))
1511         is_add = 0;
1512       else
1513         {
1514           error = clib_error_return (0, "parse error");
1515           goto done;
1516         }
1517     }
1518
1519   if (!ip_set)
1520     {
1521       clib_warning ("No petr IP specified!");
1522       goto done;
1523     }
1524
1525   if (vnet_lisp_use_petr (&ip, is_add))
1526     {
1527       error = clib_error_return (0, "failed to %s petr!",
1528                                  is_add ? "add" : "delete");
1529     }
1530
1531 done:
1532   unformat_free (line_input);
1533
1534   return error;
1535 }
1536
1537 /* *INDENT-OFF* */
1538 VLIB_CLI_COMMAND (lisp_use_petr_set_locator_set_command) = {
1539     .path = "lisp use-petr",
1540     .short_help = "lisp use-petr [disable] <petr-ip>",
1541     .function = lisp_use_petr_set_locator_set_command_fn,
1542 };
1543
1544 static clib_error_t *
1545 lisp_show_petr_command_fn (vlib_main_t * vm,
1546                            unformat_input_t * input, vlib_cli_command_t * cmd)
1547 {
1548   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1549   mapping_t *m;
1550   locator_set_t *ls;
1551   locator_t *loc;
1552   u8 *tmp_str = 0;
1553   u8 use_petr = lcm->flags & LISP_FLAG_USE_PETR;
1554   vlib_cli_output (vm, "%=20s%=16s", "petr", use_petr ? "ip" : "");
1555
1556   if (!use_petr)
1557     {
1558       vlib_cli_output (vm, "%=20s", "disable");
1559       return 0;
1560     }
1561
1562   if (~0 == lcm->petr_map_index)
1563     {
1564       tmp_str = format (0, "N/A");
1565     }
1566   else
1567     {
1568       m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
1569       if (~0 != m->locator_set_index)
1570         {
1571           ls = pool_elt_at_index(lcm->locator_set_pool, m->locator_set_index);
1572           loc = pool_elt_at_index (lcm->locator_pool, ls->locator_indices[0]);
1573           tmp_str = format (0, "%U", format_ip_address, &loc->address);
1574         }
1575       else
1576         {
1577           tmp_str = format (0, "N/A");
1578         }
1579     }
1580   vec_add1 (tmp_str, 0);
1581
1582   vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
1583
1584   vec_free (tmp_str);
1585
1586   return 0;
1587 }
1588
1589 /* *INDENT-OFF* */
1590 VLIB_CLI_COMMAND (lisp_show_petr_command) = {
1591     .path = "show lisp petr",
1592     .short_help = "Show petr",
1593     .function = lisp_show_petr_command_fn,
1594 };
1595 /* *INDENT-ON* */
1596
1597 /*
1598  * fd.io coding-style-patch-verification: ON
1599  *
1600  * Local Variables:
1601  * eval: (c-set-style "gnu")
1602  * End:
1603  */