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