lisp: Move to plugin
[vpp.git] / src / plugins / lisp / lisp-cp / one_cli.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <lisp/lisp-cp/control.h>
17 #include <lisp/lisp-gpe/lisp_gpe.h>
18
19 static clib_error_t *
20 lisp_show_adjacencies_command_fn (vlib_main_t * vm,
21                                   unformat_input_t * input,
22                                   vlib_cli_command_t * cmd)
23 {
24   lisp_adjacency_t *adjs, *adj;
25   vlib_cli_output (vm, "%s %40s\n", "leid", "reid");
26   unformat_input_t _line_input, *line_input = &_line_input;
27   u32 vni = ~0;
28
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           unformat_free (line_input);
42           return 0;
43         }
44     }
45   unformat_free (line_input);
46
47   if (~0 == vni)
48     {
49       vlib_cli_output (vm, "error: no vni specified!");
50       return 0;
51     }
52
53   adjs = vnet_lisp_adjacencies_get_by_vni (vni);
54
55   vec_foreach (adj, adjs)
56   {
57     vlib_cli_output (vm, "%U %40U\n", format_gid_address, &adj->leid,
58                      format_gid_address, &adj->reid);
59   }
60   vec_free (adjs);
61
62   return 0;
63 }
64
65 /* *INDENT-OFF* */
66 VLIB_CLI_COMMAND (one_show_adjacencies_command) = {
67     .path = "show one adjacencies",
68     .short_help = "show one adjacencies",
69     .function = lisp_show_adjacencies_command_fn,
70 };
71 /* *INDENT-ON* */
72
73 static clib_error_t *
74 lisp_add_del_map_server_command_fn (vlib_main_t * vm,
75                                     unformat_input_t * input,
76                                     vlib_cli_command_t * cmd)
77 {
78   int rv = 0;
79   u8 is_add = 1, ip_set = 0;
80   ip_address_t ip;
81   unformat_input_t _line_input, *line_input = &_line_input;
82
83   /* Get a line of input. */
84   if (!unformat_user (input, unformat_line_input, line_input))
85     return 0;
86
87   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
88     {
89       if (unformat (line_input, "add"))
90         is_add = 1;
91       else if (unformat (line_input, "del"))
92         is_add = 0;
93       else if (unformat (line_input, "%U", unformat_ip_address, &ip))
94         ip_set = 1;
95       else
96         {
97           vlib_cli_output (vm, "parse error: '%U'",
98                            format_unformat_error, line_input);
99           unformat_free (line_input);
100           return 0;
101         }
102     }
103   unformat_free (line_input);
104
105   if (!ip_set)
106     {
107       vlib_cli_output (vm, "map-server ip address not set!");
108       return 0;
109     }
110
111   rv = vnet_lisp_add_del_map_server (&ip, is_add);
112   if (!rv)
113     vlib_cli_output (vm, "failed to %s map-server!",
114                      is_add ? "add" : "delete");
115
116   return 0;
117 }
118
119 /* *INDENT-OFF* */
120 VLIB_CLI_COMMAND (one_add_del_map_server_command) = {
121     .path = "one map-server",
122     .short_help = "one map-server add|del <ip>",
123     .function = lisp_add_del_map_server_command_fn,
124 };
125 /* *INDENT-ON* */
126
127
128 static clib_error_t *
129 lisp_add_del_local_eid_command_fn (vlib_main_t * vm, unformat_input_t * input,
130                                    vlib_cli_command_t * cmd)
131 {
132   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
133   unformat_input_t _line_input, *line_input = &_line_input;
134   u8 is_add = 1;
135   gid_address_t eid;
136   gid_address_t *eids = 0;
137   clib_error_t *error = 0;
138   u8 *locator_set_name = 0;
139   u32 locator_set_index = 0, map_index = 0;
140   uword *p;
141   vnet_lisp_add_del_mapping_args_t _a, *a = &_a;
142   int rv = 0;
143   u32 vni = 0;
144   u8 *key = 0;
145   u32 key_id = 0;
146
147   clib_memset (&eid, 0, sizeof (eid));
148   clib_memset (a, 0, sizeof (*a));
149
150   /* Get a line of input. */
151   if (!unformat_user (input, unformat_line_input, line_input))
152     return 0;
153
154   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
155     {
156       if (unformat (line_input, "add"))
157         is_add = 1;
158       else if (unformat (line_input, "del"))
159         is_add = 0;
160       else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
161         ;
162       else if (unformat (line_input, "vni %d", &vni))
163         gid_address_vni (&eid) = vni;
164       else if (unformat (line_input, "secret-key %_%v%_", &key))
165         ;
166       else if (unformat (line_input, "key-id %U", unformat_hmac_key_id,
167                          &key_id))
168         ;
169       else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
170         {
171           vec_terminate_c_string (locator_set_name);
172           p = hash_get_mem (lcm->locator_set_index_by_name, locator_set_name);
173           if (!p)
174             {
175               error = clib_error_return (0, "locator-set %s doesn't exist",
176                                          locator_set_name);
177               goto done;
178             }
179           locator_set_index = p[0];
180         }
181       else if (unformat (line_input, "authoritative"))
182         a->authoritative = 1;
183       else
184         {
185           error = unformat_parse_error (line_input);
186           goto done;
187         }
188     }
189   /* XXX treat batch configuration */
190
191   if (GID_ADDR_SRC_DST == gid_address_type (&eid))
192     {
193       error =
194         clib_error_return (0, "src/dst is not supported for local EIDs!");
195       goto done;
196     }
197
198   if (key && (0 == key_id))
199     {
200       vlib_cli_output (vm, "invalid key_id!");
201       goto done;
202     }
203
204   gid_address_copy (&a->eid, &eid);
205   a->is_add = is_add;
206   a->locator_set_index = locator_set_index;
207   a->local = 1;
208   a->key = key;
209   a->key_id = key_id;
210
211   rv = vnet_lisp_add_del_local_mapping (a, &map_index);
212   if (0 != rv)
213     {
214       error = clib_error_return (0, "failed to %s local mapping!",
215                                  is_add ? "add" : "delete");
216     }
217 done:
218   vec_free (eids);
219   if (locator_set_name)
220     vec_free (locator_set_name);
221   gid_address_free (&a->eid);
222   vec_free (a->key);
223   unformat_free (line_input);
224   return error;
225 }
226
227 /* *INDENT-OFF* */
228 VLIB_CLI_COMMAND (one_add_del_local_eid_command) = {
229     .path = "one eid-table",
230     .short_help = "one eid-table add/del [vni <vni>] eid <eid> "
231       "locator-set <locator-set> [key <secret-key> key-id sha1|sha256 ]",
232     .function = lisp_add_del_local_eid_command_fn,
233 };
234 /* *INDENT-ON* */
235
236 static clib_error_t *
237 lisp_eid_table_map_command_fn (vlib_main_t * vm,
238                                unformat_input_t * input,
239                                vlib_cli_command_t * cmd)
240 {
241   u8 is_add = 1, is_l2 = 0;
242   u32 vni = 0, dp_id = 0;
243   unformat_input_t _line_input, *line_input = &_line_input;
244   clib_error_t *error = NULL;
245
246   /* Get a line of input. */
247   if (!unformat_user (input, unformat_line_input, line_input))
248     return 0;
249
250   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
251     {
252       if (unformat (line_input, "del"))
253         is_add = 0;
254       else if (unformat (line_input, "vni %d", &vni))
255         ;
256       else if (unformat (line_input, "vrf %d", &dp_id))
257         ;
258       else if (unformat (line_input, "bd %d", &dp_id))
259         is_l2 = 1;
260       else
261         {
262           error = unformat_parse_error (line_input);
263           goto done;
264         }
265     }
266   vnet_lisp_eid_table_map (vni, dp_id, is_l2, is_add);
267
268 done:
269   unformat_free (line_input);
270
271   return error;
272 }
273
274 /* *INDENT-OFF* */
275 VLIB_CLI_COMMAND (one_eid_table_map_command) = {
276     .path = "one eid-table map",
277     .short_help = "one eid-table map [del] vni <vni> vrf <vrf> | bd <bdi>",
278     .function = lisp_eid_table_map_command_fn,
279 };
280 /* *INDENT-ON* */
281
282 static clib_error_t *
283 lisp_add_del_ndp_entry_command_fn (vlib_main_t * vm,
284                                    unformat_input_t * input,
285                                    vlib_cli_command_t * cmd)
286 {
287   unformat_input_t _line_input, *line_input = &_line_input;
288   clib_error_t *error = NULL;
289   int rc = 0;
290   u8 hw_addr[6], bd = 0;
291   ip6_address_t ip6;
292   u32 hw_addr_set = 0, ip_set = 0, is_add = 1;
293   gid_address_t _g, *g = &_g;
294
295   clib_memset (&ip6, 0, sizeof (ip6));
296   clib_memset (hw_addr, 0, sizeof (hw_addr));
297   clib_memset (g, 0, sizeof (*g));
298
299   if (!unformat_user (input, unformat_line_input, line_input))
300     return 0;
301
302   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
303     {
304       if (unformat (line_input, "mac %U", unformat_mac_address, hw_addr))
305         hw_addr_set = 1;
306       else if (unformat (line_input, "ip %U", unformat_ip6_address, &ip6))
307         ip_set = 1;
308       else if (unformat (line_input, "del"))
309         is_add = 0;
310       else if (unformat (line_input, "bd %d", &bd))
311         ;
312       else
313         {
314           error = clib_error_return (0, "parse error");
315           goto done;
316         }
317     }
318
319   if (!ip_set || (!hw_addr_set && is_add))
320     {
321       vlib_cli_output (vm, "expected IP and MAC addresses!");
322       return 0;
323     }
324
325   /* build GID address */
326   ip_address_set (&gid_address_arp_ndp_ip (g), &ip6, AF_IP6);
327   gid_address_ndp_bd (g) = bd;
328   gid_address_type (g) = GID_ADDR_NDP;
329   rc = vnet_lisp_add_del_l2_arp_ndp_entry (g, hw_addr, is_add);
330   if (rc)
331     clib_warning ("Failed to %s ndp entry!", is_add ? "add" : "delete");
332
333 done:
334   unformat_free (line_input);
335   return error;
336 }
337
338 /* *INDENT-OFF* */
339 VLIB_CLI_COMMAND (one_add_del_ndp_entry_command) = {
340     .path = "one ndp",
341     .short_help = "one ndp [del] bd <bd> mac <mac> ip <ipv6>",
342     .function = lisp_add_del_ndp_entry_command_fn,
343 };
344 /* *INDENT-ON* */
345
346 static clib_error_t *
347 lisp_add_del_l2_arp_entry_command_fn (vlib_main_t * vm,
348                                       unformat_input_t * input,
349                                       vlib_cli_command_t * cmd)
350 {
351   unformat_input_t _line_input, *line_input = &_line_input;
352   clib_error_t *error = NULL;
353   int rc = 0;
354   u8 hw_addr[6], bd = 0;
355   ip4_address_t ip4;
356   u32 hw_addr_set = 0, ip_set = 0, is_add = 1;
357   gid_address_t _arp, *arp = &_arp;
358
359   clib_memset (&ip4, 0, sizeof (ip4));
360   clib_memset (hw_addr, 0, sizeof (hw_addr));
361   clib_memset (arp, 0, sizeof (*arp));
362
363   if (!unformat_user (input, unformat_line_input, line_input))
364     return 0;
365
366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
367     {
368       if (unformat (line_input, "mac %U", unformat_mac_address, hw_addr))
369         hw_addr_set = 1;
370       else if (unformat (line_input, "ip %U", unformat_ip4_address, &ip4))
371         ip_set = 1;
372       else if (unformat (line_input, "del"))
373         is_add = 0;
374       else if (unformat (line_input, "bd %d", &bd))
375         ;
376       else
377         {
378           error = clib_error_return (0, "parse error");
379           goto done;
380         }
381     }
382
383   if (!ip_set || (!hw_addr_set && is_add))
384     {
385       vlib_cli_output (vm, "expected IP and MAC addresses!");
386       return 0;
387     }
388
389   /* build GID address */
390   gid_address_arp_ip4 (arp) = ip4;
391   gid_address_arp_bd (arp) = bd;
392   gid_address_type (arp) = GID_ADDR_ARP;
393   rc = vnet_lisp_add_del_l2_arp_ndp_entry (arp, hw_addr, is_add);
394   if (rc)
395     clib_warning ("Failed to %s l2 arp entry!", is_add ? "add" : "delete");
396
397 done:
398   unformat_free (line_input);
399   return error;
400 }
401
402 /* *INDENT-OFF* */
403 VLIB_CLI_COMMAND (one_add_del_l2_arp_entry_command) = {
404     .path = "one l2 arp",
405     .short_help = "one l2 arp [del] bd <bd> mac <mac> ip <ipv4>",
406     .function = lisp_add_del_l2_arp_entry_command_fn,
407 };
408 /* *INDENT-ON* */
409
410 static clib_error_t *
411 lisp_show_l2_arp_entries_command_fn (vlib_main_t * vm,
412                                      unformat_input_t * input,
413                                      vlib_cli_command_t * cmd)
414 {
415   u32 *ht = vnet_lisp_l2_arp_bds_get ();
416   lisp_api_l2_arp_entry_t *entries, *e;
417   hash_pair_t *p;
418
419   /* *INDENT-OFF* */
420   hash_foreach_pair (p, ht,
421   ({
422     entries = vnet_lisp_l2_arp_entries_get_by_bd (p->key);
423     vlib_cli_output (vm, "Table: %d", p->key);
424
425     vec_foreach (e, entries)
426       {
427         vlib_cli_output (vm, "\t%U -> %U", format_ip4_address, &e->ip4,
428                          format_mac_address, e->mac);
429       }
430     vec_free (entries);
431   }));
432   /* *INDENT-ON* */
433
434   hash_free (ht);
435   return 0;
436 }
437
438 /* *INDENT-OFF* */
439 VLIB_CLI_COMMAND (one_show_l2_arp_entries_command) = {
440     .path = "show one l2 arp entries",
441     .short_help = "Show ONE L2 ARP entries",
442     .function = lisp_show_l2_arp_entries_command_fn,
443 };
444 /* *INDENT-ON* */
445
446 static clib_error_t *
447 lisp_show_ndp_entries_command_fn (vlib_main_t * vm,
448                                   unformat_input_t * input,
449                                   vlib_cli_command_t * cmd)
450 {
451   u32 *ht = vnet_lisp_ndp_bds_get ();
452   lisp_api_ndp_entry_t *entries, *e;
453   hash_pair_t *p;
454
455   /* *INDENT-OFF* */
456   hash_foreach_pair (p, ht,
457   ({
458     entries = vnet_lisp_ndp_entries_get_by_bd (p->key);
459     vlib_cli_output (vm, "Table: %d", p->key);
460
461     vec_foreach (e, entries)
462       {
463         vlib_cli_output (vm, "\t%U -> %U", format_ip6_address, &e->ip6,
464                          format_mac_address, e->mac);
465       }
466     vec_free (entries);
467   }));
468   /* *INDENT-ON* */
469
470   hash_free (ht);
471   return 0;
472 }
473
474 /* *INDENT-OFF* */
475 VLIB_CLI_COMMAND (one_show_ndp_entries_command) = {
476     .path = "show one ndp entries",
477     .short_help = "Show ONE NDP entries",
478     .function = lisp_show_ndp_entries_command_fn,
479 };
480 /* *INDENT-ON* */
481
482 /**
483  * Handler for add/del remote mapping CLI.
484  *
485  * @param vm vlib context
486  * @param input input from user
487  * @param cmd cmd
488  * @return pointer to clib error structure
489  */
490 static clib_error_t *
491 lisp_add_del_remote_mapping_command_fn (vlib_main_t * vm,
492                                         unformat_input_t * input,
493                                         vlib_cli_command_t * cmd)
494 {
495   clib_error_t *error = 0;
496   unformat_input_t _line_input, *line_input = &_line_input;
497   u8 is_add = 1, del_all = 0;
498   locator_t rloc, *rlocs = 0, *curr_rloc = 0;
499   gid_address_t eid;
500   u8 eid_set = 0;
501   u32 vni, action = ~0, p, w;
502   int rv;
503
504   /* Get a line of input. */
505   if (!unformat_user (input, unformat_line_input, line_input))
506     return 0;
507
508   clib_memset (&eid, 0, sizeof (eid));
509   clib_memset (&rloc, 0, sizeof (rloc));
510
511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
512     {
513       if (unformat (line_input, "del-all"))
514         del_all = 1;
515       else if (unformat (line_input, "del"))
516         is_add = 0;
517       else if (unformat (line_input, "add"))
518         ;
519       else if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
520         eid_set = 1;
521       else if (unformat (line_input, "vni %u", &vni))
522         {
523           gid_address_vni (&eid) = vni;
524         }
525       else if (unformat (line_input, "p %d w %d", &p, &w))
526         {
527           if (!curr_rloc)
528             {
529               clib_warning
530                 ("No RLOC configured for setting priority/weight!");
531               goto done;
532             }
533           curr_rloc->priority = p;
534           curr_rloc->weight = w;
535         }
536       else if (unformat (line_input, "rloc %U", unformat_ip_address,
537                          &gid_address_ip (&rloc.address)))
538         {
539           /* since rloc is stored in ip prefix we need to set prefix length */
540           ip_prefix_t *pref = &gid_address_ippref (&rloc.address);
541
542           u8 version = gid_address_ip_version (&rloc.address);
543           ip_prefix_len (pref) = ip_address_max_len (version);
544
545           vec_add1 (rlocs, rloc);
546           curr_rloc = &rlocs[vec_len (rlocs) - 1];
547         }
548       else if (unformat (line_input, "action %U",
549                          unformat_negative_mapping_action, &action))
550         ;
551       else
552         {
553           clib_warning ("parse error");
554           goto done;
555         }
556     }
557
558   if (!del_all && !eid_set)
559     {
560       clib_warning ("missing eid!");
561       goto done;
562     }
563
564   if (!del_all)
565     {
566       if (is_add && (~0 == action) && 0 == vec_len (rlocs))
567         {
568           clib_warning ("no action set for negative map-reply!");
569           goto done;
570         }
571     }
572   else
573     {
574       vnet_lisp_clear_all_remote_adjacencies ();
575       goto done;
576     }
577
578   /* if it's a delete, clean forwarding */
579   if (!is_add)
580     {
581       vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
582       clib_memset (a, 0, sizeof (a[0]));
583       gid_address_copy (&a->reid, &eid);
584       if (vnet_lisp_add_del_adjacency (a))
585         {
586           clib_warning ("failed to delete adjacency!");
587           goto done;
588         }
589     }
590
591   /* add as static remote mapping, i.e., not authoritative and infinite
592    * ttl */
593   if (is_add)
594     {
595       vnet_lisp_add_del_mapping_args_t _map_args, *map_args = &_map_args;
596       clib_memset (map_args, 0, sizeof (map_args[0]));
597       gid_address_copy (&map_args->eid, &eid);
598       map_args->action = action;
599       map_args->is_static = 1;
600       map_args->authoritative = 0;
601       map_args->ttl = ~0;
602       rv = vnet_lisp_add_mapping (map_args, rlocs, NULL, NULL);
603     }
604   else
605     rv = vnet_lisp_del_mapping (&eid, NULL);
606
607   if (rv)
608     clib_warning ("failed to %s remote mapping!", is_add ? "add" : "delete");
609
610 done:
611   vec_free (rlocs);
612   unformat_free (line_input);
613   return error;
614 }
615
616 /* *INDENT-OFF* */
617 VLIB_CLI_COMMAND (one_add_del_remote_mapping_command) = {
618   .path = "one remote-mapping",
619   .short_help =
620     "one remote-mapping add|del [del-all] vni <vni> "
621     "eid <est-eid> [action <no-action|natively-forward|"
622     "send-map-request|drop>] rloc <dst-locator> p <prio> w <weight> "
623     "[rloc <dst-locator> ... ]",
624   .function = lisp_add_del_remote_mapping_command_fn,
625 };
626 /* *INDENT-ON* */
627
628 /**
629  * Handler for add/del adjacency CLI.
630  */
631 static clib_error_t *
632 lisp_add_del_adjacency_command_fn (vlib_main_t * vm, unformat_input_t * input,
633                                    vlib_cli_command_t * cmd)
634 {
635   clib_error_t *error = 0;
636   unformat_input_t _line_input, *line_input = &_line_input;
637   vnet_lisp_add_del_adjacency_args_t _a, *a = &_a;
638   u8 is_add = 1;
639   ip_prefix_t *reid_ippref, *leid_ippref;
640   gid_address_t leid, reid;
641   u8 *dmac = gid_address_mac (&reid);
642   u8 *smac = gid_address_mac (&leid);
643   u8 reid_set = 0, leid_set = 0;
644   u32 vni;
645
646   /* Get a line of input. */
647   if (!unformat_user (input, unformat_line_input, line_input))
648     return 0;
649
650   clib_memset (&reid, 0, sizeof (reid));
651   clib_memset (&leid, 0, sizeof (leid));
652
653   leid_ippref = &gid_address_ippref (&leid);
654   reid_ippref = &gid_address_ippref (&reid);
655
656   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
657     {
658       if (unformat (line_input, "del"))
659         is_add = 0;
660       else if (unformat (line_input, "add"))
661         ;
662       else if (unformat (line_input, "reid %U",
663                          unformat_ip_prefix, reid_ippref))
664         {
665           gid_address_type (&reid) = GID_ADDR_IP_PREFIX;
666           reid_set = 1;
667         }
668       else if (unformat (line_input, "reid %U", unformat_mac_address, dmac))
669         {
670           gid_address_type (&reid) = GID_ADDR_MAC;
671           reid_set = 1;
672         }
673       else if (unformat (line_input, "vni %u", &vni))
674         {
675           gid_address_vni (&leid) = vni;
676           gid_address_vni (&reid) = vni;
677         }
678       else if (unformat (line_input, "leid %U",
679                          unformat_ip_prefix, leid_ippref))
680         {
681           gid_address_type (&leid) = GID_ADDR_IP_PREFIX;
682           leid_set = 1;
683         }
684       else if (unformat (line_input, "leid %U", unformat_mac_address, smac))
685         {
686           gid_address_type (&leid) = GID_ADDR_MAC;
687           leid_set = 1;
688         }
689       else
690         {
691           clib_warning ("parse error");
692           goto done;
693         }
694     }
695
696   if (!reid_set || !leid_set)
697     {
698       clib_warning ("missing remote or local eid!");
699       goto done;
700     }
701
702   if ((gid_address_type (&leid) != gid_address_type (&reid))
703       || (gid_address_type (&reid) == GID_ADDR_IP_PREFIX
704           && ip_prefix_version (reid_ippref)
705           != ip_prefix_version (leid_ippref)))
706     {
707       clib_warning ("remote and local EIDs are of different types!");
708       goto done;
709     }
710
711   clib_memset (a, 0, sizeof (a[0]));
712   gid_address_copy (&a->leid, &leid);
713   gid_address_copy (&a->reid, &reid);
714   a->is_add = is_add;
715
716   if (vnet_lisp_add_del_adjacency (a))
717     clib_warning ("failed to %s adjacency!", is_add ? "add" : "delete");
718
719 done:
720   unformat_free (line_input);
721   return error;
722 }
723
724 /* *INDENT-OFF* */
725 VLIB_CLI_COMMAND (one_add_del_adjacency_command) = {
726     .path = "one adjacency",
727     .short_help = "one adjacency add|del vni <vni> reid <remote-eid> "
728       "leid <local-eid>",
729     .function = lisp_add_del_adjacency_command_fn,
730 };
731 /* *INDENT-ON* */
732
733
734 static clib_error_t *
735 lisp_map_request_mode_command_fn (vlib_main_t * vm,
736                                   unformat_input_t * input,
737                                   vlib_cli_command_t * cmd)
738 {
739   unformat_input_t _i, *i = &_i;
740   map_request_mode_t mr_mode = _MR_MODE_MAX;
741
742   /* Get a line of input. */
743   if (!unformat_user (input, unformat_line_input, i))
744     return 0;
745
746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
747     {
748       if (unformat (i, "dst-only"))
749         mr_mode = MR_MODE_DST_ONLY;
750       else if (unformat (i, "src-dst"))
751         mr_mode = MR_MODE_SRC_DST;
752       else
753         {
754           clib_warning ("parse error '%U'", format_unformat_error, i);
755           goto done;
756         }
757     }
758
759   if (_MR_MODE_MAX == mr_mode)
760     {
761       clib_warning ("No map request mode entered!");
762       goto done;
763     }
764
765   vnet_lisp_set_map_request_mode (mr_mode);
766
767 done:
768   unformat_free (i);
769
770   return 0;
771 }
772
773 /* *INDENT-OFF* */
774 VLIB_CLI_COMMAND (one_map_request_mode_command) = {
775     .path = "one map-request mode",
776     .short_help = "one map-request mode dst-only|src-dst",
777     .function = lisp_map_request_mode_command_fn,
778 };
779 /* *INDENT-ON* */
780
781
782 static u8 *
783 format_lisp_map_request_mode (u8 * s, va_list * args)
784 {
785   u32 mode = va_arg (*args, u32);
786
787   switch (mode)
788     {
789     case 0:
790       return format (0, "dst-only");
791     case 1:
792       return format (0, "src-dst");
793     }
794   return 0;
795 }
796
797 static clib_error_t *
798 lisp_show_map_request_mode_command_fn (vlib_main_t * vm,
799                                        unformat_input_t * input,
800                                        vlib_cli_command_t * cmd)
801 {
802   vlib_cli_output (vm, "map-request mode: %U", format_lisp_map_request_mode,
803                    vnet_lisp_get_map_request_mode ());
804   return 0;
805 }
806
807 /* *INDENT-OFF* */
808 VLIB_CLI_COMMAND (one_show_map_request_mode_command) = {
809     .path = "show one map-request mode",
810     .short_help = "show one map-request mode",
811     .function = lisp_show_map_request_mode_command_fn,
812 };
813 /* *INDENT-ON* */
814
815 static clib_error_t *
816 lisp_show_map_resolvers_command_fn (vlib_main_t * vm,
817                                     unformat_input_t * input,
818                                     vlib_cli_command_t * cmd)
819 {
820   lisp_msmr_t *mr;
821   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
822
823   vec_foreach (mr, lcm->map_resolvers)
824   {
825     vlib_cli_output (vm, "%U", format_ip_address, &mr->address);
826   }
827   return 0;
828 }
829
830 /* *INDENT-OFF* */
831 VLIB_CLI_COMMAND (one_show_map_resolvers_command) = {
832     .path = "show one map-resolvers",
833     .short_help = "show one map-resolvers",
834     .function = lisp_show_map_resolvers_command_fn,
835 };
836 /* *INDENT-ON* */
837
838 static clib_error_t *
839 lisp_nsh_set_locator_set_command_fn (vlib_main_t * vm,
840                                      unformat_input_t * input,
841                                      vlib_cli_command_t * cmd)
842 {
843   u8 locator_name_set = 0;
844   u8 *locator_set_name = 0;
845   u8 is_add = 1;
846   unformat_input_t _line_input, *line_input = &_line_input;
847   clib_error_t *error = 0;
848   int rv = 0;
849
850   /* Get a line of input. */
851   if (!unformat_user (input, unformat_line_input, line_input))
852     return 0;
853
854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
855     {
856       if (unformat (line_input, "ls %_%v%_", &locator_set_name))
857         locator_name_set = 1;
858       else if (unformat (line_input, "disable"))
859         is_add = 0;
860       else
861         {
862           error = clib_error_return (0, "parse error");
863           goto done;
864         }
865     }
866
867   if (!locator_name_set)
868     {
869       clib_warning ("No locator set specified!");
870       goto done;
871     }
872
873   vec_terminate_c_string (locator_set_name);
874   rv = vnet_lisp_nsh_set_locator_set (locator_set_name, is_add);
875   if (0 != rv)
876     {
877       error = clib_error_return (0, "failed to %s NSH mapping!",
878                                  is_add ? "add" : "delete");
879     }
880
881 done:
882   vec_free (locator_set_name);
883   unformat_free (line_input);
884   return error;
885 }
886
887 /* *INDENT-OFF* */
888 VLIB_CLI_COMMAND (one_nsh_set_locator_set_command) = {
889     .path = "one nsh-mapping",
890     .short_help = "one nsh-mapping [del] ls <locator-set-name>",
891     .function = lisp_nsh_set_locator_set_command_fn,
892 };
893 /* *INDENT-ON* */
894
895 static clib_error_t *
896 lisp_map_register_fallback_threshold_show_command_fn (vlib_main_t * vm,
897                                                       unformat_input_t *
898                                                       input,
899                                                       vlib_cli_command_t *
900                                                       cmd)
901 {
902   u32 val = vnet_lisp_map_register_fallback_threshold_get ();
903   vlib_cli_output (vm, "map register fallback threshold value: %d", val);
904   return 0;
905 }
906
907 /* *INDENT-OFF* */
908 VLIB_CLI_COMMAND (one_map_register_fallback_threshold_show_command) = {
909     .path = "show one map-register fallback-threshold",
910     .short_help = "show one map-register fallback-threshold",
911     .function = lisp_map_register_fallback_threshold_show_command_fn,
912 };
913
914 /* *INDENT-ON* */
915
916 static clib_error_t *
917 lisp_map_register_fallback_threshold_command_fn (vlib_main_t * vm,
918                                                  unformat_input_t * input,
919                                                  vlib_cli_command_t * cmd)
920 {
921   unformat_input_t _line_input, *line_input = &_line_input;
922   clib_error_t *error = 0;
923   u32 val = 0;
924   int rv = 0;
925
926   /* Get a line of input. */
927   if (!unformat_user (input, unformat_line_input, line_input))
928     return 0;
929
930   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
931     {
932       if (unformat (line_input, "%d", &val))
933         ;
934       else
935         {
936           error = clib_error_return (0, "parse error");
937           goto done;
938         }
939     }
940
941   rv = vnet_lisp_map_register_fallback_threshold_set (val);
942   if (rv)
943     {
944       error = clib_error_return (0, "setting fallback threshold failed!");
945     }
946
947 done:
948   unformat_free (line_input);
949   return error;
950 }
951
952 /* *INDENT-OFF* */
953 VLIB_CLI_COMMAND (one_map_register_fallback_threshold_command) = {
954     .path = "one map-register fallback-threshold",
955     .short_help = "one map-register fallback-threshold <count>",
956     .function = lisp_map_register_fallback_threshold_command_fn,
957 };
958 /* *INDENT-ON* */
959
960 static clib_error_t *
961 lisp_pitr_set_locator_set_command_fn (vlib_main_t * vm,
962                                       unformat_input_t * input,
963                                       vlib_cli_command_t * cmd)
964 {
965   u8 locator_name_set = 0;
966   u8 *locator_set_name = 0;
967   u8 is_add = 1;
968   unformat_input_t _line_input, *line_input = &_line_input;
969   clib_error_t *error = 0;
970   int rv = 0;
971
972   /* Get a line of input. */
973   if (!unformat_user (input, unformat_line_input, line_input))
974     return 0;
975
976   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
977     {
978       if (unformat (line_input, "ls %_%v%_", &locator_set_name))
979         locator_name_set = 1;
980       else if (unformat (line_input, "disable"))
981         is_add = 0;
982       else
983         {
984           error = clib_error_return (0, "parse error");
985           goto done;
986         }
987     }
988
989   if (!locator_name_set)
990     {
991       clib_warning ("No locator set specified!");
992       goto done;
993     }
994   vec_terminate_c_string (locator_set_name);
995   rv = vnet_lisp_pitr_set_locator_set (locator_set_name, is_add);
996   if (0 != rv)
997     {
998       error = clib_error_return (0, "failed to %s pitr!",
999                                  is_add ? "add" : "delete");
1000     }
1001
1002 done:
1003   if (locator_set_name)
1004     vec_free (locator_set_name);
1005   unformat_free (line_input);
1006   return error;
1007 }
1008
1009 /* *INDENT-OFF* */
1010 VLIB_CLI_COMMAND (one_pitr_set_locator_set_command) = {
1011     .path = "one pitr",
1012     .short_help = "one pitr [disable] ls <locator-set-name>",
1013     .function = lisp_pitr_set_locator_set_command_fn,
1014 };
1015 /* *INDENT-ON* */
1016
1017 static clib_error_t *
1018 lisp_show_pitr_command_fn (vlib_main_t * vm,
1019                            unformat_input_t * input, vlib_cli_command_t * cmd)
1020 {
1021   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1022   mapping_t *m;
1023   locator_set_t *ls;
1024   u8 *tmp_str = 0;
1025   u8 status = lcm->flags & LISP_FLAG_PITR_MODE;
1026
1027   vlib_cli_output (vm, "%=20s%=16s", "pitr", status ? "locator-set" : "");
1028
1029   if (!status)
1030     {
1031       vlib_cli_output (vm, "%=20s", "disable");
1032       return 0;
1033     }
1034
1035   if (~0 == lcm->pitr_map_index)
1036     {
1037       tmp_str = format (0, "N/A");
1038     }
1039   else
1040     {
1041       m = pool_elt_at_index (lcm->mapping_pool, lcm->pitr_map_index);
1042       if (~0 != m->locator_set_index)
1043         {
1044           ls =
1045             pool_elt_at_index (lcm->locator_set_pool, m->locator_set_index);
1046           tmp_str = format (0, "%s", ls->name);
1047         }
1048       else
1049         {
1050           tmp_str = format (0, "N/A");
1051         }
1052     }
1053   vec_add1 (tmp_str, 0);
1054
1055   vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
1056
1057   vec_free (tmp_str);
1058
1059   return 0;
1060 }
1061
1062 /* *INDENT-OFF* */
1063 VLIB_CLI_COMMAND (one_show_pitr_command) = {
1064     .path = "show one pitr",
1065     .short_help = "Show pitr",
1066     .function = lisp_show_pitr_command_fn,
1067 };
1068 /* *INDENT-ON* */
1069
1070 static u8 *
1071 format_eid_entry (u8 * s, va_list * args)
1072 {
1073   vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
1074   lisp_cp_main_t *lcm = va_arg (*args, lisp_cp_main_t *);
1075   mapping_t *mapit = va_arg (*args, mapping_t *);
1076   locator_set_t *ls = va_arg (*args, locator_set_t *);
1077   gid_address_t *gid = &mapit->eid;
1078   u32 ttl = mapit->ttl;
1079   u8 aut = mapit->authoritative;
1080   u32 *loc_index;
1081   u8 first_line = 1;
1082   u8 *loc;
1083
1084   u8 *type = ls->local ? format (0, "local(%s)", ls->name)
1085     : format (0, "remote");
1086
1087   if (vec_len (ls->locator_indices) == 0)
1088     {
1089       s = format (s, "%-35U%-20saction:%-30U%-20u%-u", format_gid_address,
1090                   gid, type, format_negative_mapping_action, mapit->action,
1091                   ttl, aut);
1092     }
1093   else
1094     {
1095       vec_foreach (loc_index, ls->locator_indices)
1096       {
1097         locator_t *l = pool_elt_at_index (lcm->locator_pool, loc_index[0]);
1098         if (l->local)
1099           loc = format (0, "%U", format_vnet_sw_if_index_name, vnm,
1100                         l->sw_if_index);
1101         else
1102           loc = format (0, "%U", format_ip_address,
1103                         &gid_address_ip (&l->address));
1104
1105         if (first_line)
1106           {
1107             s = format (s, "%-35U%-20s%-30v%-20u%-u\n", format_gid_address,
1108                         gid, type, loc, ttl, aut);
1109             first_line = 0;
1110           }
1111         else
1112           s = format (s, "%55s%v\n", "", loc);
1113       }
1114     }
1115   return s;
1116 }
1117
1118 static clib_error_t *
1119 lisp_show_eid_table_command_fn (vlib_main_t * vm,
1120                                 unformat_input_t * input,
1121                                 vlib_cli_command_t * cmd)
1122 {
1123   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1124   mapping_t *mapit;
1125   unformat_input_t _line_input, *line_input = &_line_input;
1126   u32 mi;
1127   gid_address_t eid;
1128   u8 print_all = 1;
1129   u8 filter = 0;
1130   clib_error_t *error = NULL;
1131
1132   clib_memset (&eid, 0, sizeof (eid));
1133
1134   /* Get a line of input. */
1135   if (!unformat_user (input, unformat_line_input, line_input))
1136     return 0;
1137
1138   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1139     {
1140       if (unformat (line_input, "eid %U", unformat_gid_address, &eid))
1141         print_all = 0;
1142       else if (unformat (line_input, "local"))
1143         filter = 1;
1144       else if (unformat (line_input, "remote"))
1145         filter = 2;
1146       else
1147         {
1148           error = clib_error_return (0, "parse error: '%U'",
1149                                      format_unformat_error, line_input);
1150           goto done;
1151         }
1152     }
1153
1154   vlib_cli_output (vm, "%-35s%-20s%-30s%-20s%-s",
1155                    "EID", "type", "locators", "ttl", "authoritative");
1156
1157   if (print_all)
1158     {
1159       /* *INDENT-OFF* */
1160       pool_foreach (mapit, lcm->mapping_pool,
1161       ({
1162         if (mapit->pitr_set || mapit->nsh_set)
1163           continue;
1164
1165         locator_set_t * ls = pool_elt_at_index (lcm->locator_set_pool,
1166                                                 mapit->locator_set_index);
1167         if (filter && !((1 == filter && ls->local) ||
1168           (2 == filter && !ls->local)))
1169           {
1170             continue;
1171           }
1172         vlib_cli_output (vm, "%U", format_eid_entry, lcm->vnet_main,
1173                          lcm, mapit, ls);
1174       }));
1175       /* *INDENT-ON* */
1176     }
1177   else
1178     {
1179       mi = gid_dictionary_lookup (&lcm->mapping_index_by_gid, &eid);
1180       if ((u32) ~ 0 == mi)
1181         goto done;
1182
1183       mapit = pool_elt_at_index (lcm->mapping_pool, mi);
1184       locator_set_t *ls = pool_elt_at_index (lcm->locator_set_pool,
1185                                              mapit->locator_set_index);
1186
1187       if (filter && !((1 == filter && ls->local) ||
1188                       (2 == filter && !ls->local)))
1189         {
1190           goto done;
1191         }
1192
1193       vlib_cli_output (vm, "%U,", format_eid_entry, lcm->vnet_main,
1194                        lcm, mapit, ls);
1195     }
1196
1197 done:
1198   unformat_free (line_input);
1199
1200   return error;
1201 }
1202
1203 /* *INDENT-OFF* */
1204 VLIB_CLI_COMMAND (one_cp_show_eid_table_command) = {
1205     .path = "show one eid-table",
1206     .short_help = "show one eid-table [local|remote|eid <eid>]",
1207     .function = lisp_show_eid_table_command_fn,
1208 };
1209 /* *INDENT-ON* */
1210
1211 static clib_error_t *
1212 lisp_enable_disable_pitr_mode_command_fn (vlib_main_t * vm,
1213                                           unformat_input_t * input,
1214                                           vlib_cli_command_t * cmd)
1215 {
1216   unformat_input_t _line_input, *line_input = &_line_input;
1217   u8 is_enabled = 0;
1218   u8 is_set = 0;
1219   clib_error_t *error = NULL;
1220
1221   /* Get a line of input. */
1222   if (!unformat_user (input, unformat_line_input, line_input))
1223     return clib_error_return (0, "expected enable | disable");
1224
1225   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1226     {
1227       if (unformat (line_input, "enable"))
1228         {
1229           is_set = 1;
1230           is_enabled = 1;
1231         }
1232       else if (unformat (line_input, "disable"))
1233         is_set = 1;
1234       else
1235         {
1236           error = clib_error_return (0, "parse error: '%U'",
1237                                      format_unformat_error, line_input);
1238           goto done;
1239         }
1240     }
1241
1242   if (!is_set)
1243     {
1244       error = clib_error_return (0, "state not set");
1245       goto done;
1246     }
1247
1248   vnet_lisp_enable_disable_pitr_mode (is_enabled);
1249
1250 done:
1251   unformat_free (line_input);
1252
1253   return error;
1254 }
1255
1256 /* *INDENT-OFF* */
1257 VLIB_CLI_COMMAND (one_cp_enable_disable_pitr_mode_command) = {
1258     .path = "one pitr mode",
1259     .short_help = "one pitr mode [enable|disable]",
1260     .function = lisp_enable_disable_pitr_mode_command_fn,
1261 };
1262 /* *INDENT-ON* */
1263
1264
1265 static clib_error_t *
1266 lisp_enable_disable_petr_mode_command_fn (vlib_main_t * vm,
1267                                           unformat_input_t * input,
1268                                           vlib_cli_command_t * cmd)
1269 {
1270   unformat_input_t _line_input, *line_input = &_line_input;
1271   u8 is_enabled = 0;
1272   u8 is_set = 0;
1273   clib_error_t *error = NULL;
1274
1275   /* Get a line of input. */
1276   if (!unformat_user (input, unformat_line_input, line_input))
1277     return clib_error_return (0, "expected enable | disable");
1278
1279   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1280     {
1281       if (unformat (line_input, "enable"))
1282         {
1283           is_set = 1;
1284           is_enabled = 1;
1285         }
1286       else if (unformat (line_input, "disable"))
1287         is_set = 1;
1288       else
1289         {
1290           error = clib_error_return (0, "parse error: '%U'",
1291                                      format_unformat_error, line_input);
1292           goto done;
1293         }
1294     }
1295
1296   if (!is_set)
1297     {
1298       error = clib_error_return (0, "state not set");
1299       goto done;
1300     }
1301
1302   vnet_lisp_enable_disable_petr_mode (is_enabled);
1303
1304 done:
1305   unformat_free (line_input);
1306
1307   return error;
1308 }
1309
1310 /* *INDENT-OFF* */
1311 VLIB_CLI_COMMAND (one_cp_enable_disable_petr_mode_command) = {
1312     .path = "one petr mode",
1313     .short_help = "one petr mode [enable|disable]",
1314     .function = lisp_enable_disable_petr_mode_command_fn,
1315 };
1316 /* *INDENT-ON* */
1317
1318 static clib_error_t *
1319 lisp_enable_disable_xtr_mode_command_fn (vlib_main_t * vm,
1320                                          unformat_input_t * input,
1321                                          vlib_cli_command_t * cmd)
1322 {
1323   unformat_input_t _line_input, *line_input = &_line_input;
1324   u8 is_enabled = 0;
1325   u8 is_set = 0;
1326   clib_error_t *error = NULL;
1327
1328   /* Get a line of input. */
1329   if (!unformat_user (input, unformat_line_input, line_input))
1330     return clib_error_return (0, "expected enable | disable");
1331
1332   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1333     {
1334       if (unformat (line_input, "enable"))
1335         {
1336           is_set = 1;
1337           is_enabled = 1;
1338         }
1339       else if (unformat (line_input, "disable"))
1340         is_set = 1;
1341       else
1342         {
1343           error = clib_error_return (0, "parse error: '%U'",
1344                                      format_unformat_error, line_input);
1345           goto done;
1346         }
1347     }
1348
1349   if (!is_set)
1350     {
1351       error = clib_error_return (0, "state not set");
1352       goto done;
1353     }
1354
1355   vnet_lisp_enable_disable_xtr_mode (is_enabled);
1356
1357 done:
1358   unformat_free (line_input);
1359
1360   return error;
1361 }
1362
1363 /* *INDENT-OFF* */
1364 VLIB_CLI_COMMAND (one_cp_enable_disable_xtr_mode_command) = {
1365     .path = "one xtr mode",
1366     .short_help = "one xtr mode [enable|disable]",
1367     .function = lisp_enable_disable_xtr_mode_command_fn,
1368 };
1369 /* *INDENT-ON* */
1370
1371 static clib_error_t *
1372 one_enable_command_fn (vlib_main_t * vm, unformat_input_t * input,
1373                        vlib_cli_command_t * cmd)
1374 {
1375   if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1376     return clib_error_return (0, "parse error: '%U'", format_unformat_error,
1377                               input);
1378
1379   vnet_lisp_enable_disable (1);
1380
1381   return 0;
1382 }
1383
1384 /* *INDENT-OFF* */
1385 VLIB_CLI_COMMAND (one_cp_enable_command) = {
1386     .path = "one enable",
1387     .short_help = "one enable",
1388     .function = one_enable_command_fn,
1389 };
1390 /* *INDENT-ON* */
1391
1392 static clib_error_t *
1393 one_disable_command_fn (vlib_main_t * vm, unformat_input_t * input,
1394                         vlib_cli_command_t * cmd)
1395 {
1396   if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1397     return clib_error_return (0, "parse error: '%U'", format_unformat_error,
1398                               input);
1399
1400   vnet_lisp_enable_disable (0);
1401
1402   return 0;
1403 }
1404
1405 /* *INDENT-OFF* */
1406 VLIB_CLI_COMMAND (one_cp_disable_command) = {
1407     .path = "one disable",
1408     .short_help = "one disable",
1409     .function = one_disable_command_fn,
1410 };
1411 /* *INDENT-ON* */
1412
1413 static clib_error_t *
1414 lisp_map_register_set_ttl_command_fn (vlib_main_t * vm,
1415                                       unformat_input_t * input,
1416                                       vlib_cli_command_t * cmd)
1417 {
1418   unformat_input_t _line_input, *line_input = &_line_input;
1419   u32 ttl = 0;
1420   u8 is_set = 0;
1421   clib_error_t *error = NULL;
1422
1423   /* Get a line of input. */
1424   if (!unformat_user (input, unformat_line_input, line_input))
1425     return clib_error_return (0, "expected enable | disable");
1426
1427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1428     {
1429       if (unformat (line_input, "%u", &ttl))
1430         is_set = 1;
1431       else
1432         {
1433           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1434                            line_input);
1435           goto done;
1436         }
1437     }
1438
1439   if (!is_set)
1440     {
1441       vlib_cli_output (vm, "expected integer value for TTL!");
1442       goto done;
1443     }
1444
1445   vnet_lisp_map_register_set_ttl (ttl);
1446
1447 done:
1448   unformat_free (line_input);
1449   return error;
1450 }
1451
1452 /* *INDENT-OFF* */
1453 VLIB_CLI_COMMAND (one_map_register_set_ttl_command) = {
1454     .path = "one map-register ttl",
1455     .short_help = "one map-register ttl",
1456     .function = lisp_map_register_set_ttl_command_fn,
1457 };
1458 /* *INDENT-ON* */
1459
1460 static clib_error_t *
1461 lisp_map_register_show_ttl_command_fn (vlib_main_t * vm,
1462                                        unformat_input_t * input,
1463                                        vlib_cli_command_t * cmd)
1464 {
1465   u32 ttl = vnet_lisp_map_register_get_ttl ();
1466
1467   vlib_cli_output (vm, "map-register TTL: %u", ttl);
1468   return 0;
1469 }
1470
1471 /* *INDENT-OFF* */
1472 VLIB_CLI_COMMAND (one_map_register_show_ttl_command) = {
1473     .path = "show one map-register ttl",
1474     .short_help = "show one map-register ttl",
1475     .function = lisp_map_register_show_ttl_command_fn,
1476 };
1477
1478 /* *INDENT-ON* */
1479
1480 static clib_error_t *
1481 lisp_map_register_enable_disable_command_fn (vlib_main_t * vm,
1482                                              unformat_input_t * input,
1483                                              vlib_cli_command_t * cmd)
1484 {
1485   unformat_input_t _line_input, *line_input = &_line_input;
1486   u8 is_enabled = 0;
1487   u8 is_set = 0;
1488   clib_error_t *error = NULL;
1489
1490   /* Get a line of input. */
1491   if (!unformat_user (input, unformat_line_input, line_input))
1492     return clib_error_return (0, "expected enable | disable");
1493
1494   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1495     {
1496       if (unformat (line_input, "enable"))
1497         {
1498           is_set = 1;
1499           is_enabled = 1;
1500         }
1501       else if (unformat (line_input, "disable"))
1502         is_set = 1;
1503       else
1504         {
1505           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1506                            line_input);
1507           goto done;
1508         }
1509     }
1510
1511   if (!is_set)
1512     {
1513       vlib_cli_output (vm, "state not set!");
1514       goto done;
1515     }
1516
1517   vnet_lisp_map_register_enable_disable (is_enabled);
1518
1519 done:
1520   unformat_free (line_input);
1521
1522   return error;
1523 }
1524
1525 /* *INDENT-OFF* */
1526 VLIB_CLI_COMMAND (one_map_register_enable_disable_command) = {
1527     .path = "one map-register",
1528     .short_help = "one map-register [enable|disable]",
1529     .function = lisp_map_register_enable_disable_command_fn,
1530 };
1531 /* *INDENT-ON* */
1532
1533 static clib_error_t *
1534 lisp_rloc_probe_enable_disable_command_fn (vlib_main_t * vm,
1535                                            unformat_input_t * input,
1536                                            vlib_cli_command_t * cmd)
1537 {
1538   unformat_input_t _line_input, *line_input = &_line_input;
1539   u8 is_enabled = 0;
1540   u8 is_set = 0;
1541   clib_error_t *error = NULL;
1542
1543   /* Get a line of input. */
1544   if (!unformat_user (input, unformat_line_input, line_input))
1545     return clib_error_return (0, "expected enable | disable");
1546
1547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1548     {
1549       if (unformat (line_input, "enable"))
1550         {
1551           is_set = 1;
1552           is_enabled = 1;
1553         }
1554       else if (unformat (line_input, "disable"))
1555         is_set = 1;
1556       else
1557         {
1558           vlib_cli_output (vm, "parse error: '%U'", format_unformat_error,
1559                            line_input);
1560           goto done;
1561         }
1562     }
1563
1564   if (!is_set)
1565     {
1566       vlib_cli_output (vm, "state not set!");
1567       goto done;
1568     }
1569
1570   vnet_lisp_rloc_probe_enable_disable (is_enabled);
1571
1572 done:
1573   unformat_free (line_input);
1574
1575   return error;
1576 }
1577
1578 /* *INDENT-OFF* */
1579 VLIB_CLI_COMMAND (one_rloc_probe_enable_disable_command) = {
1580     .path = "one rloc-probe",
1581     .short_help = "one rloc-probe [enable|disable]",
1582     .function = lisp_rloc_probe_enable_disable_command_fn,
1583 };
1584 /* *INDENT-ON* */
1585
1586 static u8 *
1587 format_lisp_status (u8 * s, va_list * args)
1588 {
1589   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1590   return format (s, "%s", lcm->is_enabled ? "enabled" : "disabled");
1591 }
1592
1593 static clib_error_t *
1594 lisp_show_status_command_fn (vlib_main_t * vm, unformat_input_t * input,
1595                              vlib_cli_command_t * cmd)
1596 {
1597   u8 *msg = 0;
1598   msg = format (msg, "feature: %U\ngpe: %U\n",
1599                 format_lisp_status, format_vnet_lisp_gpe_status);
1600   vlib_cli_output (vm, "%v", msg);
1601   vec_free (msg);
1602   return 0;
1603 }
1604
1605 /* *INDENT-OFF* */
1606 VLIB_CLI_COMMAND (one_show_status_command) = {
1607     .path = "show one status",
1608     .short_help = "show one status",
1609     .function = lisp_show_status_command_fn,
1610 };
1611 /* *INDENT-ON* */
1612
1613 static clib_error_t *
1614 lisp_show_eid_table_map_command_fn (vlib_main_t * vm,
1615                                     unformat_input_t * input,
1616                                     vlib_cli_command_t * cmd)
1617 {
1618   hash_pair_t *p;
1619   unformat_input_t _line_input, *line_input = &_line_input;
1620   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1621   uword *vni_table = 0;
1622   u8 is_l2 = 0;
1623   clib_error_t *error = NULL;
1624
1625   /* Get a line of input. */
1626   if (!unformat_user (input, unformat_line_input, line_input))
1627     return 0;
1628
1629   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1630     {
1631       if (unformat (line_input, "l2"))
1632         {
1633           vni_table = lcm->bd_id_by_vni;
1634           is_l2 = 1;
1635         }
1636       else if (unformat (line_input, "l3"))
1637         {
1638           vni_table = lcm->table_id_by_vni;
1639           is_l2 = 0;
1640         }
1641       else
1642         {
1643           error = clib_error_return (0, "parse error: '%U'",
1644                                      format_unformat_error, line_input);
1645           goto done;
1646         }
1647     }
1648
1649   if (!vni_table)
1650     {
1651       vlib_cli_output (vm, "Error: expected l2|l3 param!\n");
1652       goto done;
1653     }
1654
1655   vlib_cli_output (vm, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
1656
1657   /* *INDENT-OFF* */
1658   hash_foreach_pair (p, vni_table,
1659   ({
1660     vlib_cli_output (vm, "%=10d%=10d", p->key, p->value[0]);
1661   }));
1662   /* *INDENT-ON* */
1663
1664 done:
1665   unformat_free (line_input);
1666
1667   return error;
1668 }
1669
1670 /* *INDENT-OFF* */
1671 VLIB_CLI_COMMAND (one_show_eid_table_map_command) = {
1672     .path = "show one eid-table map",
1673     .short_help = "show one eid-table map l2|l3",
1674     .function = lisp_show_eid_table_map_command_fn,
1675 };
1676 /* *INDENT-ON* */
1677
1678
1679 static clib_error_t *
1680 lisp_add_del_locator_set_command_fn (vlib_main_t * vm,
1681                                      unformat_input_t * input,
1682                                      vlib_cli_command_t * cmd)
1683 {
1684   lisp_gpe_main_t *lgm = &lisp_gpe_main;
1685   vnet_main_t *vnm = lgm->vnet_main;
1686   unformat_input_t _line_input, *line_input = &_line_input;
1687   u8 is_add = 1;
1688   clib_error_t *error = 0;
1689   u8 *locator_set_name = 0;
1690   locator_t locator, *locators = 0;
1691   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
1692   u32 ls_index = 0;
1693   int rv = 0;
1694
1695   clib_memset (&locator, 0, sizeof (locator));
1696   clib_memset (a, 0, sizeof (a[0]));
1697
1698   /* Get a line of input. */
1699   if (!unformat_user (input, unformat_line_input, line_input))
1700     return 0;
1701
1702   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1703     {
1704       if (unformat (line_input, "add %_%v%_", &locator_set_name))
1705         is_add = 1;
1706       else if (unformat (line_input, "del %_%v%_", &locator_set_name))
1707         is_add = 0;
1708       else if (unformat (line_input, "iface %U p %d w %d",
1709                          unformat_vnet_sw_interface, vnm,
1710                          &locator.sw_if_index, &locator.priority,
1711                          &locator.weight))
1712         {
1713           locator.local = 1;
1714           locator.state = 1;
1715           vec_add1 (locators, locator);
1716         }
1717       else
1718         {
1719           error = unformat_parse_error (line_input);
1720           goto done;
1721         }
1722     }
1723
1724   vec_terminate_c_string (locator_set_name);
1725   a->name = locator_set_name;
1726   a->locators = locators;
1727   a->is_add = is_add;
1728   a->local = 1;
1729
1730   rv = vnet_lisp_add_del_locator_set (a, &ls_index);
1731   if (0 != rv)
1732     {
1733       error = clib_error_return (0, "failed to %s locator-set!",
1734                                  is_add ? "add" : "delete");
1735     }
1736
1737 done:
1738   vec_free (locators);
1739   if (locator_set_name)
1740     vec_free (locator_set_name);
1741   unformat_free (line_input);
1742   return error;
1743 }
1744
1745 /* *INDENT-OFF* */
1746 VLIB_CLI_COMMAND (one_cp_add_del_locator_set_command) = {
1747     .path = "one locator-set",
1748     .short_help = "one locator-set add/del <name> [iface <iface-name> "
1749         "p <priority> w <weight>]",
1750     .function = lisp_add_del_locator_set_command_fn,
1751 };
1752 /* *INDENT-ON* */
1753
1754 static clib_error_t *
1755 lisp_add_del_locator_in_set_command_fn (vlib_main_t * vm,
1756                                         unformat_input_t * input,
1757                                         vlib_cli_command_t * cmd)
1758 {
1759   lisp_gpe_main_t *lgm = &lisp_gpe_main;
1760   vnet_main_t *vnm = lgm->vnet_main;
1761   unformat_input_t _line_input, *line_input = &_line_input;
1762   u8 is_add = 1;
1763   clib_error_t *error = 0;
1764   u8 *locator_set_name = 0;
1765   u8 locator_set_name_set = 0;
1766   locator_t locator, *locators = 0;
1767   vnet_lisp_add_del_locator_set_args_t _a, *a = &_a;
1768   u32 ls_index = 0;
1769
1770   clib_memset (&locator, 0, sizeof (locator));
1771   clib_memset (a, 0, sizeof (a[0]));
1772
1773   /* Get a line of input. */
1774   if (!unformat_user (input, unformat_line_input, line_input))
1775     return 0;
1776
1777   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1778     {
1779       if (unformat (line_input, "add"))
1780         is_add = 1;
1781       else if (unformat (line_input, "del"))
1782         is_add = 0;
1783       else if (unformat (line_input, "locator-set %_%v%_", &locator_set_name))
1784         locator_set_name_set = 1;
1785       else if (unformat (line_input, "iface %U p %d w %d",
1786                          unformat_vnet_sw_interface, vnm,
1787                          &locator.sw_if_index, &locator.priority,
1788                          &locator.weight))
1789         {
1790           locator.local = 1;
1791           vec_add1 (locators, locator);
1792         }
1793       else
1794         {
1795           error = unformat_parse_error (line_input);
1796           goto done;
1797         }
1798     }
1799
1800   if (!locator_set_name_set)
1801     {
1802       error = clib_error_return (0, "locator_set name not set!");
1803       goto done;
1804     }
1805
1806   vec_terminate_c_string (locator_set_name);
1807   a->name = locator_set_name;
1808   a->locators = locators;
1809   a->is_add = is_add;
1810   a->local = 1;
1811
1812   vnet_lisp_add_del_locator (a, 0, &ls_index);
1813
1814 done:
1815   vec_free (locators);
1816   vec_free (locator_set_name);
1817   unformat_free (line_input);
1818   return error;
1819 }
1820
1821 /* *INDENT-OFF* */
1822 VLIB_CLI_COMMAND (one_cp_add_del_locator_in_set_command) = {
1823     .path = "one locator",
1824     .short_help = "one locator add/del locator-set <name> iface <iface-name> "
1825                   "p <priority> w <weight>",
1826     .function = lisp_add_del_locator_in_set_command_fn,
1827 };
1828 /* *INDENT-ON* */
1829
1830 static clib_error_t *
1831 lisp_cp_show_locator_sets_command_fn (vlib_main_t * vm,
1832                                       unformat_input_t * input,
1833                                       vlib_cli_command_t * cmd)
1834 {
1835   locator_set_t *lsit;
1836   locator_t *loc;
1837   u32 *locit;
1838   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
1839
1840   vlib_cli_output (vm, "%s%=16s%=16s%=16s", "Locator-set", "Locator",
1841                    "Priority", "Weight");
1842
1843   /* *INDENT-OFF* */
1844   pool_foreach (lsit, lcm->locator_set_pool,
1845   ({
1846     u8 * msg = 0;
1847     int next_line = 0;
1848     if (lsit->local)
1849       {
1850         msg = format (msg, "%s", lsit->name);
1851       }
1852     else
1853       {
1854         msg = format (msg, "<%s-%d>", "remote", lsit - lcm->locator_set_pool);
1855       }
1856     vec_foreach (locit, lsit->locator_indices)
1857       {
1858         if (next_line)
1859           {
1860             msg = format (msg, "%16s", " ");
1861           }
1862         loc = pool_elt_at_index (lcm->locator_pool, locit[0]);
1863         if (loc->local)
1864           msg = format (msg, "%16d%16d%16d\n", loc->sw_if_index, loc->priority,
1865                         loc->weight);
1866         else
1867           msg = format (msg, "%16U%16d%16d\n", format_ip_address,
1868                         &gid_address_ip(&loc->address), loc->priority,
1869                         loc->weight);
1870         next_line = 1;
1871       }
1872     vlib_cli_output (vm, "%v", msg);
1873     vec_free (msg);
1874   }));
1875   /* *INDENT-ON* */
1876   return 0;
1877 }
1878
1879 /* *INDENT-OFF* */
1880 VLIB_CLI_COMMAND (one_cp_show_locator_sets_command) = {
1881     .path = "show one locator-set",
1882     .short_help = "Shows locator-sets",
1883     .function = lisp_cp_show_locator_sets_command_fn,
1884 };
1885 /* *INDENT-ON* */
1886
1887
1888 static clib_error_t *
1889 lisp_add_del_map_resolver_command_fn (vlib_main_t * vm,
1890                                       unformat_input_t * input,
1891                                       vlib_cli_command_t * cmd)
1892 {
1893   unformat_input_t _line_input, *line_input = &_line_input;
1894   u8 is_add = 1, addr_set = 0;
1895   ip_address_t ip_addr;
1896   clib_error_t *error = 0;
1897   int rv = 0;
1898   vnet_lisp_add_del_map_resolver_args_t _a, *a = &_a;
1899
1900   /* Get a line of input. */
1901   if (!unformat_user (input, unformat_line_input, line_input))
1902     return 0;
1903
1904   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1905     {
1906       if (unformat (line_input, "add"))
1907         is_add = 1;
1908       else if (unformat (line_input, "del"))
1909         is_add = 0;
1910       else if (unformat (line_input, "%U", unformat_ip_address, &ip_addr))
1911         addr_set = 1;
1912       else
1913         {
1914           error = unformat_parse_error (line_input);
1915           goto done;
1916         }
1917     }
1918
1919   if (!addr_set)
1920     {
1921       error = clib_error_return (0, "Map-resolver address must be set!");
1922       goto done;
1923     }
1924
1925   a->is_add = is_add;
1926   a->address = ip_addr;
1927   rv = vnet_lisp_add_del_map_resolver (a);
1928   if (0 != rv)
1929     {
1930       error = clib_error_return (0, "failed to %s map-resolver!",
1931                                  is_add ? "add" : "delete");
1932     }
1933
1934 done:
1935   unformat_free (line_input);
1936   return error;
1937 }
1938
1939 /* *INDENT-OFF* */
1940 VLIB_CLI_COMMAND (one_add_del_map_resolver_command) = {
1941     .path = "one map-resolver",
1942     .short_help = "one map-resolver add/del <ip_address>",
1943     .function = lisp_add_del_map_resolver_command_fn,
1944 };
1945 /* *INDENT-ON* */
1946
1947
1948 static clib_error_t *
1949 lisp_add_del_mreq_itr_rlocs_command_fn (vlib_main_t * vm,
1950                                         unformat_input_t * input,
1951                                         vlib_cli_command_t * cmd)
1952 {
1953   unformat_input_t _line_input, *line_input = &_line_input;
1954   u8 is_add = 1;
1955   u8 *locator_set_name = 0;
1956   clib_error_t *error = 0;
1957   int rv = 0;
1958   vnet_lisp_add_del_mreq_itr_rloc_args_t _a, *a = &_a;
1959
1960   /* Get a line of input. */
1961   if (!unformat_user (input, unformat_line_input, line_input))
1962     return 0;
1963
1964   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1965     {
1966       if (unformat (line_input, "del"))
1967         is_add = 0;
1968       else if (unformat (line_input, "add %_%v%_", &locator_set_name))
1969         is_add = 1;
1970       else
1971         {
1972           error = unformat_parse_error (line_input);
1973           goto done;
1974         }
1975     }
1976
1977   vec_terminate_c_string (locator_set_name);
1978   a->is_add = is_add;
1979   a->locator_set_name = locator_set_name;
1980   rv = vnet_lisp_add_del_mreq_itr_rlocs (a);
1981   if (0 != rv)
1982     {
1983       error = clib_error_return (0, "failed to %s map-request itr-rlocs!",
1984                                  is_add ? "add" : "delete");
1985     }
1986
1987 done:
1988   vec_free (locator_set_name);
1989   unformat_free (line_input);
1990   return error;
1991
1992 }
1993
1994 /* *INDENT-OFF* */
1995 VLIB_CLI_COMMAND (one_add_del_map_request_command) = {
1996     .path = "one map-request itr-rlocs",
1997     .short_help = "one map-request itr-rlocs add/del <locator_set_name>",
1998     .function = lisp_add_del_mreq_itr_rlocs_command_fn,
1999 };
2000 /* *INDENT-ON* */
2001
2002 static clib_error_t *
2003 lisp_show_mreq_itr_rlocs_command_fn (vlib_main_t * vm,
2004                                      unformat_input_t * input,
2005                                      vlib_cli_command_t * cmd)
2006 {
2007   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
2008   locator_set_t *loc_set;
2009
2010   vlib_cli_output (vm, "%=20s", "itr-rlocs");
2011
2012   if (~0 == lcm->mreq_itr_rlocs)
2013     {
2014       return 0;
2015     }
2016
2017   loc_set = pool_elt_at_index (lcm->locator_set_pool, lcm->mreq_itr_rlocs);
2018
2019   vlib_cli_output (vm, "%=20s", loc_set->name);
2020
2021   return 0;
2022 }
2023
2024 /* *INDENT-OFF* */
2025 VLIB_CLI_COMMAND (one_show_map_request_command) = {
2026     .path = "show one map-request itr-rlocs",
2027     .short_help = "Shows map-request itr-rlocs",
2028     .function = lisp_show_mreq_itr_rlocs_command_fn,
2029 };
2030 /* *INDENT-ON* */
2031
2032 static clib_error_t *
2033 lisp_use_petr_set_locator_set_command_fn (vlib_main_t * vm,
2034                                           unformat_input_t * input,
2035                                           vlib_cli_command_t * cmd)
2036 {
2037   u8 is_add = 1, ip_set = 0;
2038   unformat_input_t _line_input, *line_input = &_line_input;
2039   clib_error_t *error = 0;
2040   ip_address_t ip;
2041
2042   /* Get a line of input. */
2043   if (!unformat_user (input, unformat_line_input, line_input))
2044     return 0;
2045
2046   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2047     {
2048       if (unformat (line_input, "%U", unformat_ip_address, &ip))
2049         ip_set = 1;
2050       else if (unformat (line_input, "disable"))
2051         is_add = 0;
2052       else
2053         {
2054           error = clib_error_return (0, "parse error");
2055           goto done;
2056         }
2057     }
2058
2059   if (!ip_set)
2060     {
2061       clib_warning ("No petr IP specified!");
2062       goto done;
2063     }
2064
2065   if (vnet_lisp_use_petr (&ip, is_add))
2066     {
2067       error = clib_error_return (0, "failed to %s petr!",
2068                                  is_add ? "add" : "delete");
2069     }
2070
2071 done:
2072   unformat_free (line_input);
2073   return error;
2074 }
2075
2076 /* *INDENT-OFF* */
2077 VLIB_CLI_COMMAND (one_use_petr_set_locator_set_command) = {
2078     .path = "one use-petr",
2079     .short_help = "one use-petr [disable] <petr-ip>",
2080     .function = lisp_use_petr_set_locator_set_command_fn,
2081 };
2082
2083 static clib_error_t *
2084 lisp_show_petr_command_fn (vlib_main_t * vm,
2085                            unformat_input_t * input, vlib_cli_command_t * cmd)
2086 {
2087   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
2088   mapping_t *m;
2089   locator_set_t *ls;
2090   locator_t *loc;
2091   u8 *tmp_str = 0;
2092   u8 use_petr = lcm->flags & LISP_FLAG_USE_PETR;
2093   vlib_cli_output (vm, "%=20s%=16s", "petr", use_petr ? "ip" : "");
2094
2095   if (!use_petr)
2096     {
2097       vlib_cli_output (vm, "%=20s", "disable");
2098       return 0;
2099     }
2100
2101   if (~0 == lcm->petr_map_index)
2102     {
2103       tmp_str = format (0, "N/A");
2104     }
2105   else
2106     {
2107       m = pool_elt_at_index (lcm->mapping_pool, lcm->petr_map_index);
2108       if (~0 != m->locator_set_index)
2109         {
2110           ls = pool_elt_at_index(lcm->locator_set_pool, m->locator_set_index);
2111           loc = pool_elt_at_index (lcm->locator_pool, ls->locator_indices[0]);
2112           tmp_str = format (0, "%U", format_ip_address, &loc->address);
2113         }
2114       else
2115         {
2116           tmp_str = format (0, "N/A");
2117         }
2118     }
2119   vec_add1 (tmp_str, 0);
2120
2121   vlib_cli_output (vm, "%=20s%=16s", "enable", tmp_str);
2122
2123   vec_free (tmp_str);
2124
2125   return 0;
2126 }
2127
2128 /* *INDENT-OFF* */
2129 VLIB_CLI_COMMAND (one_show_petr_command) = {
2130     .path = "show one petr",
2131     .short_help = "Show petr",
2132     .function = lisp_show_petr_command_fn,
2133 };
2134 /* *INDENT-ON* */
2135
2136 static clib_error_t *
2137 lisp_show_map_servers_command_fn (vlib_main_t * vm,
2138                                   unformat_input_t * input,
2139                                   vlib_cli_command_t * cmd)
2140 {
2141   lisp_msmr_t *ms;
2142   lisp_cp_main_t *lcm = vnet_lisp_cp_get_main ();
2143
2144   vec_foreach (ms, lcm->map_servers)
2145   {
2146     vlib_cli_output (vm, "%U", format_ip_address, &ms->address);
2147   }
2148   return 0;
2149 }
2150
2151 /* *INDENT-OFF* */
2152 VLIB_CLI_COMMAND (one_show_map_servers_command) = {
2153     .path = "show one map-servers",
2154     .short_help = "show one map servers",
2155     .function = lisp_show_map_servers_command_fn,
2156 };
2157 /* *INDENT-ON* */
2158
2159 static clib_error_t *
2160 lisp_show_map_register_state_command_fn (vlib_main_t * vm,
2161                                          unformat_input_t * input,
2162                                          vlib_cli_command_t * cmd)
2163 {
2164   u8 *msg = 0;
2165   u8 is_enabled = vnet_lisp_map_register_state_get ();
2166
2167   msg = format (msg, "%s\n", is_enabled ? "enabled" : "disabled");
2168   vlib_cli_output (vm, "%v", msg);
2169   vec_free (msg);
2170   return 0;
2171 }
2172
2173 /* *INDENT-OFF* */
2174 VLIB_CLI_COMMAND (one_show_map_register_state_command) = {
2175     .path = "show one map-register state",
2176     .short_help = "show one map-register state",
2177     .function = lisp_show_map_register_state_command_fn,
2178 };
2179 /* *INDENT-ON* */
2180
2181 static clib_error_t *
2182 lisp_show_rloc_probe_state_command_fn (vlib_main_t * vm,
2183                                        unformat_input_t * input,
2184                                        vlib_cli_command_t * cmd)
2185 {
2186   u8 *msg = 0;
2187   u8 is_enabled = vnet_lisp_rloc_probe_state_get ();
2188
2189   msg = format (msg, "%s\n", is_enabled ? "enabled" : "disabled");
2190   vlib_cli_output (vm, "%v", msg);
2191   vec_free (msg);
2192   return 0;
2193 }
2194
2195 /* *INDENT-OFF* */
2196 VLIB_CLI_COMMAND (one_show_rloc_probe_state_command) = {
2197     .path = "show one rloc state",
2198     .short_help = "show one RLOC state",
2199     .function = lisp_show_rloc_probe_state_command_fn,
2200 };
2201 /* *INDENT-ON* */
2202
2203 static clib_error_t *
2204 lisp_show_stats_command_fn (vlib_main_t * vm,
2205                             unformat_input_t * input,
2206                             vlib_cli_command_t * cmd)
2207 {
2208   u8 is_enabled = vnet_lisp_stats_enable_disable_state ();
2209   vlib_cli_output (vm, "%s\n", is_enabled ? "enabled" : "disabled");
2210   return 0;
2211 }
2212
2213 /* *INDENT-OFF* */
2214 VLIB_CLI_COMMAND (one_show_stats_command) = {
2215     .path = "show one statistics status",
2216     .short_help = "show ONE statistics enable/disable status",
2217     .function = lisp_show_stats_command_fn,
2218 };
2219 /* *INDENT-ON* */
2220
2221 static clib_error_t *
2222 lisp_show_stats_details_command_fn (vlib_main_t * vm,
2223                                     unformat_input_t * input,
2224                                     vlib_cli_command_t * cmd)
2225 {
2226   lisp_api_stats_t *stat, *stats = vnet_lisp_get_stats ();
2227
2228   if (vec_len (stats) > 0)
2229     vlib_cli_output (vm,
2230                      "[src-EID, dst-EID] [loc-rloc, rmt-rloc] count bytes\n");
2231   else
2232     vlib_cli_output (vm, "No statistics found.\n");
2233
2234   vec_foreach (stat, stats)
2235   {
2236     vlib_cli_output (vm, "[%U, %U] [%U, %U] %7u %7u\n",
2237                      format_fid_address, &stat->seid,
2238                      format_fid_address, &stat->deid,
2239                      format_ip_address, &stat->loc_rloc,
2240                      format_ip_address, &stat->rmt_rloc,
2241                      stat->counters.packets, stat->counters.bytes);
2242   }
2243   vec_free (stats);
2244   return 0;
2245 }
2246
2247 /* *INDENT-OFF* */
2248 VLIB_CLI_COMMAND (one_show_stats_details_command) = {
2249     .path = "show one statistics details",
2250     .short_help = "show ONE statistics",
2251     .function = lisp_show_stats_details_command_fn,
2252 };
2253 /* *INDENT-ON* */
2254
2255 static clib_error_t *
2256 lisp_stats_enable_disable_command_fn (vlib_main_t * vm,
2257                                       unformat_input_t * input,
2258                                       vlib_cli_command_t * cmd)
2259 {
2260   unformat_input_t _line_input, *line_input = &_line_input;
2261   u8 enable = 0;
2262
2263   /* Get a line of input. */
2264   if (!unformat_user (input, unformat_line_input, line_input))
2265     return clib_error_return (0, "expected enable | disable");
2266
2267   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2268     {
2269       if (unformat (line_input, "enable"))
2270         enable = 1;
2271       else if (unformat (line_input, "disable"))
2272         enable = 0;
2273       else
2274         {
2275           clib_warning ("Error: expected enable/disable!");
2276           goto done;
2277         }
2278     }
2279   vnet_lisp_stats_enable_disable (enable);
2280 done:
2281   unformat_free (line_input);
2282   return 0;
2283 }
2284
2285 /* *INDENT-OFF* */
2286 VLIB_CLI_COMMAND (one_stats_enable_disable_command) = {
2287     .path = "one statistics",
2288     .short_help = "enable/disable ONE statistics collecting",
2289     .function = lisp_stats_enable_disable_command_fn,
2290 };
2291 /* *INDENT-ON* */
2292
2293 static clib_error_t *
2294 lisp_stats_flush_command_fn (vlib_main_t * vm,
2295                              unformat_input_t * input,
2296                              vlib_cli_command_t * cmd)
2297 {
2298   vnet_lisp_flush_stats ();
2299   return 0;
2300 }
2301
2302 /* *INDENT-OFF* */
2303 VLIB_CLI_COMMAND (one_stats_flush_command) = {
2304     .path = "one statistics flush",
2305     .short_help = "Flush ONE statistics",
2306     .function = lisp_stats_flush_command_fn,
2307 };
2308 /* *INDENT-ON* */
2309
2310 static clib_error_t *
2311 lisp_show_one_modes_command_fn (vlib_main_t * vm,
2312                                 unformat_input_t * input,
2313                                 vlib_cli_command_t * cmd)
2314 {
2315   u8 pitr_mode = vnet_lisp_get_pitr_mode ();
2316   u8 petr_mode = vnet_lisp_get_petr_mode ();
2317   u8 xtr_mode = vnet_lisp_get_xtr_mode ();
2318
2319   vlib_cli_output (vm, "xTR: %s\n", xtr_mode ? "enabled" : "disabled");
2320   vlib_cli_output (vm, "P-ITR: %s\n", pitr_mode ? "enabled" : "disabled");
2321   vlib_cli_output (vm, "P-ETR: %s\n", petr_mode ? "enabled" : "disabled");
2322
2323   return 0;
2324 }
2325
2326 /* *INDENT-OFF* */
2327 VLIB_CLI_COMMAND (one_cp_show_one_modes_modes_command) = {
2328     .path = "show one modes",
2329     .short_help = "show one modes",
2330     .function = lisp_show_one_modes_command_fn,
2331 };
2332 /* *INDENT-ON* */
2333
2334 /*
2335  * fd.io coding-style-patch-verification: ON
2336  *
2337  * Local Variables:
2338  * eval: (c-set-style "gnu")
2339  * End:
2340  */