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