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