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