LISP statistics
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/l2/l2_input.h>
26 #include <vnet/l2tp/l2tp.h>
27 #include <vnet/vxlan/vxlan.h>
28 #include <vnet/gre/gre.h>
29 #include <vnet/vxlan-gpe/vxlan_gpe.h>
30 #include <vnet/lisp-gpe/lisp_gpe.h>
31
32 #include <vpp/api/vpe_msg_enum.h>
33 #include <vnet/l2/l2_classify.h>
34 #include <vnet/l2/l2_vtr.h>
35 #include <vnet/classify/input_acl.h>
36 #include <vnet/classify/policer_classify.h>
37 #include <vnet/classify/flow_classify.h>
38 #include <vnet/mpls/mpls.h>
39 #include <vnet/ipsec/ipsec.h>
40 #include <vnet/ipsec/ikev2.h>
41 #include <inttypes.h>
42 #include <vnet/map/map.h>
43 #include <vnet/cop/cop.h>
44 #include <vnet/ip/ip6_hop_by_hop.h>
45 #include <vnet/ip/ip_source_and_port_range_check.h>
46 #include <vnet/policer/xlate.h>
47 #include <vnet/span/span.h>
48 #include <vnet/policer/policer.h>
49 #include <vnet/policer/police.h>
50 #include <vnet/mfib/mfib_types.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp/api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp/api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp/api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 #define __plugin_msg_base 0
74 #include <vlibapi/vat_helper_macros.h>
75
76 f64
77 vat_time_now (vat_main_t * vam)
78 {
79 #if VPP_API_TEST_BUILTIN
80   return vlib_time_now (vam->vlib_main);
81 #else
82   return clib_time_now (&vam->clib_time);
83 #endif
84 }
85
86 void
87 errmsg (char *fmt, ...)
88 {
89   vat_main_t *vam = &vat_main;
90   va_list va;
91   u8 *s;
92
93   va_start (va, fmt);
94   s = va_format (0, fmt, &va);
95   va_end (va);
96
97   vec_add1 (s, 0);
98
99 #if VPP_API_TEST_BUILTIN
100   vlib_cli_output (vam->vlib_main, (char *) s);
101 #else
102   {
103     if (vam->ifp != stdin)
104       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
105                vam->input_line_number);
106     fformat (vam->ofp, (char *) s);
107     fflush (vam->ofp);
108   }
109 #endif
110
111   vec_free (s);
112 }
113
114 #if VPP_API_TEST_BUILTIN == 0
115 static uword
116 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
117 {
118   vat_main_t *vam = va_arg (*args, vat_main_t *);
119   u32 *result = va_arg (*args, u32 *);
120   u8 *if_name;
121   uword *p;
122
123   if (!unformat (input, "%s", &if_name))
124     return 0;
125
126   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
127   if (p == 0)
128     return 0;
129   *result = p[0];
130   return 1;
131 }
132
133 /* Parse an IP4 address %d.%d.%d.%d. */
134 uword
135 unformat_ip4_address (unformat_input_t * input, va_list * args)
136 {
137   u8 *result = va_arg (*args, u8 *);
138   unsigned a[4];
139
140   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
141     return 0;
142
143   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
144     return 0;
145
146   result[0] = a[0];
147   result[1] = a[1];
148   result[2] = a[2];
149   result[3] = a[3];
150
151   return 1;
152 }
153
154 uword
155 unformat_ethernet_address (unformat_input_t * input, va_list * args)
156 {
157   u8 *result = va_arg (*args, u8 *);
158   u32 i, a[6];
159
160   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
161                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
162     return 0;
163
164   /* Check range. */
165   for (i = 0; i < 6; i++)
166     if (a[i] >= (1 << 8))
167       return 0;
168
169   for (i = 0; i < 6; i++)
170     result[i] = a[i];
171
172   return 1;
173 }
174
175 /* Returns ethernet type as an int in host byte order. */
176 uword
177 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
178                                         va_list * args)
179 {
180   u16 *result = va_arg (*args, u16 *);
181   int type;
182
183   /* Numeric type. */
184   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
185     {
186       if (type >= (1 << 16))
187         return 0;
188       *result = type;
189       return 1;
190     }
191   return 0;
192 }
193
194 /* Parse an IP6 address. */
195 uword
196 unformat_ip6_address (unformat_input_t * input, va_list * args)
197 {
198   ip6_address_t *result = va_arg (*args, ip6_address_t *);
199   u16 hex_quads[8];
200   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
201   uword c, n_colon, double_colon_index;
202
203   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
204   double_colon_index = ARRAY_LEN (hex_quads);
205   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
206     {
207       hex_digit = 16;
208       if (c >= '0' && c <= '9')
209         hex_digit = c - '0';
210       else if (c >= 'a' && c <= 'f')
211         hex_digit = c + 10 - 'a';
212       else if (c >= 'A' && c <= 'F')
213         hex_digit = c + 10 - 'A';
214       else if (c == ':' && n_colon < 2)
215         n_colon++;
216       else
217         {
218           unformat_put_input (input);
219           break;
220         }
221
222       /* Too many hex quads. */
223       if (n_hex_quads >= ARRAY_LEN (hex_quads))
224         return 0;
225
226       if (hex_digit < 16)
227         {
228           hex_quad = (hex_quad << 4) | hex_digit;
229
230           /* Hex quad must fit in 16 bits. */
231           if (n_hex_digits >= 4)
232             return 0;
233
234           n_colon = 0;
235           n_hex_digits++;
236         }
237
238       /* Save position of :: */
239       if (n_colon == 2)
240         {
241           /* More than one :: ? */
242           if (double_colon_index < ARRAY_LEN (hex_quads))
243             return 0;
244           double_colon_index = n_hex_quads;
245         }
246
247       if (n_colon > 0 && n_hex_digits > 0)
248         {
249           hex_quads[n_hex_quads++] = hex_quad;
250           hex_quad = 0;
251           n_hex_digits = 0;
252         }
253     }
254
255   if (n_hex_digits > 0)
256     hex_quads[n_hex_quads++] = hex_quad;
257
258   {
259     word i;
260
261     /* Expand :: to appropriate number of zero hex quads. */
262     if (double_colon_index < ARRAY_LEN (hex_quads))
263       {
264         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
265
266         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
267           hex_quads[n_zero + i] = hex_quads[i];
268
269         for (i = 0; i < n_zero; i++)
270           hex_quads[double_colon_index + i] = 0;
271
272         n_hex_quads = ARRAY_LEN (hex_quads);
273       }
274
275     /* Too few hex quads given. */
276     if (n_hex_quads < ARRAY_LEN (hex_quads))
277       return 0;
278
279     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
280       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
281
282     return 1;
283   }
284 }
285
286 uword
287 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
288 {
289   u32 *r = va_arg (*args, u32 *);
290
291   if (0);
292 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
293   foreach_ipsec_policy_action
294 #undef _
295     else
296     return 0;
297   return 1;
298 }
299
300 uword
301 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
302 {
303   u32 *r = va_arg (*args, u32 *);
304
305   if (0);
306 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
307   foreach_ipsec_crypto_alg
308 #undef _
309     else
310     return 0;
311   return 1;
312 }
313
314 u8 *
315 format_ipsec_crypto_alg (u8 * s, va_list * args)
316 {
317   u32 i = va_arg (*args, u32);
318   u8 *t = 0;
319
320   switch (i)
321     {
322 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
323       foreach_ipsec_crypto_alg
324 #undef _
325     default:
326       return format (s, "unknown");
327     }
328   return format (s, "%s", t);
329 }
330
331 uword
332 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
333 {
334   u32 *r = va_arg (*args, u32 *);
335
336   if (0);
337 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
338   foreach_ipsec_integ_alg
339 #undef _
340     else
341     return 0;
342   return 1;
343 }
344
345 u8 *
346 format_ipsec_integ_alg (u8 * s, va_list * args)
347 {
348   u32 i = va_arg (*args, u32);
349   u8 *t = 0;
350
351   switch (i)
352     {
353 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
354       foreach_ipsec_integ_alg
355 #undef _
356     default:
357       return format (s, "unknown");
358     }
359   return format (s, "%s", t);
360 }
361
362 uword
363 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
364 {
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
369   foreach_ikev2_auth_method
370 #undef _
371     else
372     return 0;
373   return 1;
374 }
375
376 uword
377 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
378 {
379   u32 *r = va_arg (*args, u32 *);
380
381   if (0);
382 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
383   foreach_ikev2_id_type
384 #undef _
385     else
386     return 0;
387   return 1;
388 }
389 #else /* VPP_API_TEST_BUILTIN == 1 */
390 static uword
391 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
392 {
393   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
394   vnet_main_t *vnm = vnet_get_main ();
395   u32 *result = va_arg (*args, u32 *);
396   u32 sw_if_index;
397
398   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
399     return 0;
400
401   *result = sw_if_index;
402   return 1;
403 }
404 #endif /* VPP_API_TEST_BUILTIN */
405
406 static uword
407 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
408 {
409   u8 *r = va_arg (*args, u8 *);
410
411   if (unformat (input, "kbps"))
412     *r = SSE2_QOS_RATE_KBPS;
413   else if (unformat (input, "pps"))
414     *r = SSE2_QOS_RATE_PPS;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_round_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "closest"))
426     *r = SSE2_QOS_ROUND_TO_CLOSEST;
427   else if (unformat (input, "up"))
428     *r = SSE2_QOS_ROUND_TO_UP;
429   else if (unformat (input, "down"))
430     *r = SSE2_QOS_ROUND_TO_DOWN;
431   else
432     return 0;
433   return 1;
434 }
435
436 static uword
437 unformat_policer_type (unformat_input_t * input, va_list * args)
438 {
439   u8 *r = va_arg (*args, u8 *);
440
441   if (unformat (input, "1r2c"))
442     *r = SSE2_QOS_POLICER_TYPE_1R2C;
443   else if (unformat (input, "1r3c"))
444     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
445   else if (unformat (input, "2r3c-2698"))
446     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
447   else if (unformat (input, "2r3c-4115"))
448     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
449   else if (unformat (input, "2r3c-mef5cf1"))
450     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
451   else
452     return 0;
453   return 1;
454 }
455
456 static uword
457 unformat_dscp (unformat_input_t * input, va_list * va)
458 {
459   u8 *r = va_arg (*va, u8 *);
460
461   if (0);
462 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
463   foreach_vnet_dscp
464 #undef _
465     else
466     return 0;
467   return 1;
468 }
469
470 static uword
471 unformat_policer_action_type (unformat_input_t * input, va_list * va)
472 {
473   sse2_qos_pol_action_params_st *a
474     = va_arg (*va, sse2_qos_pol_action_params_st *);
475
476   if (unformat (input, "drop"))
477     a->action_type = SSE2_QOS_ACTION_DROP;
478   else if (unformat (input, "transmit"))
479     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
480   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
481     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
482   else
483     return 0;
484   return 1;
485 }
486
487 static uword
488 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
489 {
490   u32 *r = va_arg (*va, u32 *);
491   u32 tid;
492
493   if (unformat (input, "ip4"))
494     tid = POLICER_CLASSIFY_TABLE_IP4;
495   else if (unformat (input, "ip6"))
496     tid = POLICER_CLASSIFY_TABLE_IP6;
497   else if (unformat (input, "l2"))
498     tid = POLICER_CLASSIFY_TABLE_L2;
499   else
500     return 0;
501
502   *r = tid;
503   return 1;
504 }
505
506 static uword
507 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
508 {
509   u32 *r = va_arg (*va, u32 *);
510   u32 tid;
511
512   if (unformat (input, "ip4"))
513     tid = FLOW_CLASSIFY_TABLE_IP4;
514   else if (unformat (input, "ip6"))
515     tid = FLOW_CLASSIFY_TABLE_IP6;
516   else
517     return 0;
518
519   *r = tid;
520   return 1;
521 }
522
523 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
524 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
525 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
526 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
527
528 #if (VPP_API_TEST_BUILTIN==0)
529 uword
530 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
531 {
532   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
533   mfib_itf_attribute_t attr;
534
535   old = *iflags;
536   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
537   {
538     if (unformat (input, mfib_itf_flag_long_names[attr]))
539       *iflags |= (1 << attr);
540   }
541   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
542   {
543     if (unformat (input, mfib_itf_flag_names[attr]))
544       *iflags |= (1 << attr);
545   }
546
547   return (old == *iflags ? 0 : 1);
548 }
549
550 uword
551 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
552 {
553   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
554   mfib_entry_attribute_t attr;
555
556   old = *eflags;
557   FOR_EACH_MFIB_ATTRIBUTE (attr)
558   {
559     if (unformat (input, mfib_flag_long_names[attr]))
560       *eflags |= (1 << attr);
561   }
562   FOR_EACH_MFIB_ATTRIBUTE (attr)
563   {
564     if (unformat (input, mfib_flag_names[attr]))
565       *eflags |= (1 << attr);
566   }
567
568   return (old == *eflags ? 0 : 1);
569 }
570
571 u8 *
572 format_ip4_address (u8 * s, va_list * args)
573 {
574   u8 *a = va_arg (*args, u8 *);
575   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
576 }
577
578 u8 *
579 format_ip6_address (u8 * s, va_list * args)
580 {
581   ip6_address_t *a = va_arg (*args, ip6_address_t *);
582   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
583
584   i_max_n_zero = ARRAY_LEN (a->as_u16);
585   max_n_zeros = 0;
586   i_first_zero = i_max_n_zero;
587   n_zeros = 0;
588   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
589     {
590       u32 is_zero = a->as_u16[i] == 0;
591       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
592         {
593           i_first_zero = i;
594           n_zeros = 0;
595         }
596       n_zeros += is_zero;
597       if ((!is_zero && n_zeros > max_n_zeros)
598           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
599         {
600           i_max_n_zero = i_first_zero;
601           max_n_zeros = n_zeros;
602           i_first_zero = ARRAY_LEN (a->as_u16);
603           n_zeros = 0;
604         }
605     }
606
607   last_double_colon = 0;
608   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
609     {
610       if (i == i_max_n_zero && max_n_zeros > 1)
611         {
612           s = format (s, "::");
613           i += max_n_zeros - 1;
614           last_double_colon = 1;
615         }
616       else
617         {
618           s = format (s, "%s%x",
619                       (last_double_colon || i == 0) ? "" : ":",
620                       clib_net_to_host_u16 (a->as_u16[i]));
621           last_double_colon = 0;
622         }
623     }
624
625   return s;
626 }
627
628 /* Format an IP46 address. */
629 u8 *
630 format_ip46_address (u8 * s, va_list * args)
631 {
632   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
633   ip46_type_t type = va_arg (*args, ip46_type_t);
634   int is_ip4 = 1;
635
636   switch (type)
637     {
638     case IP46_TYPE_ANY:
639       is_ip4 = ip46_address_is_ip4 (ip46);
640       break;
641     case IP46_TYPE_IP4:
642       is_ip4 = 1;
643       break;
644     case IP46_TYPE_IP6:
645       is_ip4 = 0;
646       break;
647     }
648
649   return is_ip4 ?
650     format (s, "%U", format_ip4_address, &ip46->ip4) :
651     format (s, "%U", format_ip6_address, &ip46->ip6);
652 }
653
654 u8 *
655 format_ethernet_address (u8 * s, va_list * args)
656 {
657   u8 *a = va_arg (*args, u8 *);
658
659   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
660                  a[0], a[1], a[2], a[3], a[4], a[5]);
661 }
662 #endif
663
664 static void
665 increment_v4_address (ip4_address_t * a)
666 {
667   u32 v;
668
669   v = ntohl (a->as_u32) + 1;
670   a->as_u32 = ntohl (v);
671 }
672
673 static void
674 increment_v6_address (ip6_address_t * a)
675 {
676   u64 v0, v1;
677
678   v0 = clib_net_to_host_u64 (a->as_u64[0]);
679   v1 = clib_net_to_host_u64 (a->as_u64[1]);
680
681   v1 += 1;
682   if (v1 == 0)
683     v0 += 1;
684   a->as_u64[0] = clib_net_to_host_u64 (v0);
685   a->as_u64[1] = clib_net_to_host_u64 (v1);
686 }
687
688 static void
689 increment_mac_address (u64 * mac)
690 {
691   u64 tmp = *mac;
692
693   tmp = clib_net_to_host_u64 (tmp);
694   tmp += 1 << 16;               /* skip unused (least significant) octets */
695   tmp = clib_host_to_net_u64 (tmp);
696   *mac = tmp;
697 }
698
699 static void vl_api_create_loopback_reply_t_handler
700   (vl_api_create_loopback_reply_t * mp)
701 {
702   vat_main_t *vam = &vat_main;
703   i32 retval = ntohl (mp->retval);
704
705   vam->retval = retval;
706   vam->regenerate_interface_table = 1;
707   vam->sw_if_index = ntohl (mp->sw_if_index);
708   vam->result_ready = 1;
709 }
710
711 static void vl_api_create_loopback_reply_t_handler_json
712   (vl_api_create_loopback_reply_t * mp)
713 {
714   vat_main_t *vam = &vat_main;
715   vat_json_node_t node;
716
717   vat_json_init_object (&node);
718   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
719   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
720
721   vat_json_print (vam->ofp, &node);
722   vat_json_free (&node);
723   vam->retval = ntohl (mp->retval);
724   vam->result_ready = 1;
725 }
726
727 static void vl_api_create_loopback_instance_reply_t_handler
728   (vl_api_create_loopback_instance_reply_t * mp)
729 {
730   vat_main_t *vam = &vat_main;
731   i32 retval = ntohl (mp->retval);
732
733   vam->retval = retval;
734   vam->regenerate_interface_table = 1;
735   vam->sw_if_index = ntohl (mp->sw_if_index);
736   vam->result_ready = 1;
737 }
738
739 static void vl_api_create_loopback_instance_reply_t_handler_json
740   (vl_api_create_loopback_instance_reply_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   vat_json_node_t node;
744
745   vat_json_init_object (&node);
746   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
747   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
748
749   vat_json_print (vam->ofp, &node);
750   vat_json_free (&node);
751   vam->retval = ntohl (mp->retval);
752   vam->result_ready = 1;
753 }
754
755 static void vl_api_af_packet_create_reply_t_handler
756   (vl_api_af_packet_create_reply_t * mp)
757 {
758   vat_main_t *vam = &vat_main;
759   i32 retval = ntohl (mp->retval);
760
761   vam->retval = retval;
762   vam->regenerate_interface_table = 1;
763   vam->sw_if_index = ntohl (mp->sw_if_index);
764   vam->result_ready = 1;
765 }
766
767 static void vl_api_af_packet_create_reply_t_handler_json
768   (vl_api_af_packet_create_reply_t * mp)
769 {
770   vat_main_t *vam = &vat_main;
771   vat_json_node_t node;
772
773   vat_json_init_object (&node);
774   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
775   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
776
777   vat_json_print (vam->ofp, &node);
778   vat_json_free (&node);
779
780   vam->retval = ntohl (mp->retval);
781   vam->result_ready = 1;
782 }
783
784 static void vl_api_create_vlan_subif_reply_t_handler
785   (vl_api_create_vlan_subif_reply_t * mp)
786 {
787   vat_main_t *vam = &vat_main;
788   i32 retval = ntohl (mp->retval);
789
790   vam->retval = retval;
791   vam->regenerate_interface_table = 1;
792   vam->sw_if_index = ntohl (mp->sw_if_index);
793   vam->result_ready = 1;
794 }
795
796 static void vl_api_create_vlan_subif_reply_t_handler_json
797   (vl_api_create_vlan_subif_reply_t * mp)
798 {
799   vat_main_t *vam = &vat_main;
800   vat_json_node_t node;
801
802   vat_json_init_object (&node);
803   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
804   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
805
806   vat_json_print (vam->ofp, &node);
807   vat_json_free (&node);
808
809   vam->retval = ntohl (mp->retval);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_subif_reply_t_handler
814   (vl_api_create_subif_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   i32 retval = ntohl (mp->retval);
818
819   vam->retval = retval;
820   vam->regenerate_interface_table = 1;
821   vam->sw_if_index = ntohl (mp->sw_if_index);
822   vam->result_ready = 1;
823 }
824
825 static void vl_api_create_subif_reply_t_handler_json
826   (vl_api_create_subif_reply_t * mp)
827 {
828   vat_main_t *vam = &vat_main;
829   vat_json_node_t node;
830
831   vat_json_init_object (&node);
832   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
833   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
834
835   vat_json_print (vam->ofp, &node);
836   vat_json_free (&node);
837
838   vam->retval = ntohl (mp->retval);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_interface_name_renumber_reply_t_handler
843   (vl_api_interface_name_renumber_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   i32 retval = ntohl (mp->retval);
847
848   vam->retval = retval;
849   vam->regenerate_interface_table = 1;
850   vam->result_ready = 1;
851 }
852
853 static void vl_api_interface_name_renumber_reply_t_handler_json
854   (vl_api_interface_name_renumber_reply_t * mp)
855 {
856   vat_main_t *vam = &vat_main;
857   vat_json_node_t node;
858
859   vat_json_init_object (&node);
860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
861
862   vat_json_print (vam->ofp, &node);
863   vat_json_free (&node);
864
865   vam->retval = ntohl (mp->retval);
866   vam->result_ready = 1;
867 }
868
869 /*
870  * Special-case: build the interface table, maintain
871  * the next loopback sw_if_index vbl.
872  */
873 static void vl_api_sw_interface_details_t_handler
874   (vl_api_sw_interface_details_t * mp)
875 {
876   vat_main_t *vam = &vat_main;
877   u8 *s = format (0, "%s%c", mp->interface_name, 0);
878
879   hash_set_mem (vam->sw_if_index_by_interface_name, s,
880                 ntohl (mp->sw_if_index));
881
882   /* In sub interface case, fill the sub interface table entry */
883   if (mp->sw_if_index != mp->sup_sw_if_index)
884     {
885       sw_interface_subif_t *sub = NULL;
886
887       vec_add2 (vam->sw_if_subif_table, sub, 1);
888
889       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
890       strncpy ((char *) sub->interface_name, (char *) s,
891                vec_len (sub->interface_name));
892       sub->sw_if_index = ntohl (mp->sw_if_index);
893       sub->sub_id = ntohl (mp->sub_id);
894
895       sub->sub_dot1ad = mp->sub_dot1ad;
896       sub->sub_number_of_tags = mp->sub_number_of_tags;
897       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
898       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
899       sub->sub_exact_match = mp->sub_exact_match;
900       sub->sub_default = mp->sub_default;
901       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
902       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
903
904       /* vlan tag rewrite */
905       sub->vtr_op = ntohl (mp->vtr_op);
906       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
907       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
908       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
909     }
910 }
911
912 static void vl_api_sw_interface_details_t_handler_json
913   (vl_api_sw_interface_details_t * mp)
914 {
915   vat_main_t *vam = &vat_main;
916   vat_json_node_t *node = NULL;
917
918   if (VAT_JSON_ARRAY != vam->json_tree.type)
919     {
920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
921       vat_json_init_array (&vam->json_tree);
922     }
923   node = vat_json_array_add (&vam->json_tree);
924
925   vat_json_init_object (node);
926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
927   vat_json_object_add_uint (node, "sup_sw_if_index",
928                             ntohl (mp->sup_sw_if_index));
929   vat_json_object_add_uint (node, "l2_address_length",
930                             ntohl (mp->l2_address_length));
931   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
932                              sizeof (mp->l2_address));
933   vat_json_object_add_string_copy (node, "interface_name",
934                                    mp->interface_name);
935   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
936   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
937   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
938   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
939   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
940   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
941   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
942   vat_json_object_add_uint (node, "sub_number_of_tags",
943                             mp->sub_number_of_tags);
944   vat_json_object_add_uint (node, "sub_outer_vlan_id",
945                             ntohs (mp->sub_outer_vlan_id));
946   vat_json_object_add_uint (node, "sub_inner_vlan_id",
947                             ntohs (mp->sub_inner_vlan_id));
948   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
949   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
950   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
951                             mp->sub_outer_vlan_id_any);
952   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
953                             mp->sub_inner_vlan_id_any);
954   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
955   vat_json_object_add_uint (node, "vtr_push_dot1q",
956                             ntohl (mp->vtr_push_dot1q));
957   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
958   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
959   if (mp->sub_dot1ah)
960     {
961       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
962                                        format (0, "%U",
963                                                format_ethernet_address,
964                                                &mp->b_dmac));
965       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
966                                        format (0, "%U",
967                                                format_ethernet_address,
968                                                &mp->b_smac));
969       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
970       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
971     }
972 }
973
974 #if VPP_API_TEST_BUILTIN == 0
975 static void vl_api_sw_interface_set_flags_t_handler
976   (vl_api_sw_interface_set_flags_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   if (vam->interface_event_display)
980     errmsg ("interface flags: sw_if_index %d %s %s",
981             ntohl (mp->sw_if_index),
982             mp->admin_up_down ? "admin-up" : "admin-down",
983             mp->link_up_down ? "link-up" : "link-down");
984 }
985 #endif
986
987 static void vl_api_sw_interface_set_flags_t_handler_json
988   (vl_api_sw_interface_set_flags_t * mp)
989 {
990   /* JSON output not supported */
991 }
992
993 static void
994 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
995 {
996   vat_main_t *vam = &vat_main;
997   i32 retval = ntohl (mp->retval);
998
999   vam->retval = retval;
1000   vam->shmem_result = (u8 *) mp->reply_in_shmem;
1001   vam->result_ready = 1;
1002 }
1003
1004 static void
1005 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   vat_json_node_t node;
1009   api_main_t *am = &api_main;
1010   void *oldheap;
1011   u8 *reply;
1012
1013   vat_json_init_object (&node);
1014   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1015   vat_json_object_add_uint (&node, "reply_in_shmem",
1016                             ntohl (mp->reply_in_shmem));
1017   /* Toss the shared-memory original... */
1018   pthread_mutex_lock (&am->vlib_rp->mutex);
1019   oldheap = svm_push_data_heap (am->vlib_rp);
1020
1021   reply = (u8 *) (mp->reply_in_shmem);
1022   vec_free (reply);
1023
1024   svm_pop_heap (oldheap);
1025   pthread_mutex_unlock (&am->vlib_rp->mutex);
1026
1027   vat_json_print (vam->ofp, &node);
1028   vat_json_free (&node);
1029
1030   vam->retval = ntohl (mp->retval);
1031   vam->result_ready = 1;
1032 }
1033
1034 static void
1035 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1036 {
1037   vat_main_t *vam = &vat_main;
1038   i32 retval = ntohl (mp->retval);
1039
1040   vam->retval = retval;
1041   vam->cmd_reply = mp->reply;
1042   vam->result_ready = 1;
1043 }
1044
1045 static void
1046 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_classify_add_del_table_reply_t_handler
1063   (vl_api_classify_add_del_table_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0 &&
1075           ((mp->new_table_index != 0xFFFFFFFF) ||
1076            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1077            (mp->match_n_vectors != 0xFFFFFFFF)))
1078         /*
1079          * Note: this is just barely thread-safe, depends on
1080          * the main thread spinning waiting for an answer...
1081          */
1082         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1083                 ntohl (mp->new_table_index),
1084                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1085       vam->result_ready = 1;
1086     }
1087 }
1088
1089 static void vl_api_classify_add_del_table_reply_t_handler_json
1090   (vl_api_classify_add_del_table_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_uint (&node, "new_table_index",
1098                             ntohl (mp->new_table_index));
1099   vat_json_object_add_uint (&node, "skip_n_vectors",
1100                             ntohl (mp->skip_n_vectors));
1101   vat_json_object_add_uint (&node, "match_n_vectors",
1102                             ntohl (mp->match_n_vectors));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111 static void vl_api_get_node_index_reply_t_handler
1112   (vl_api_get_node_index_reply_t * mp)
1113 {
1114   vat_main_t *vam = &vat_main;
1115   i32 retval = ntohl (mp->retval);
1116   if (vam->async_mode)
1117     {
1118       vam->async_errors += (retval < 0);
1119     }
1120   else
1121     {
1122       vam->retval = retval;
1123       if (retval == 0)
1124         errmsg ("node index %d", ntohl (mp->node_index));
1125       vam->result_ready = 1;
1126     }
1127 }
1128
1129 static void vl_api_get_node_index_reply_t_handler_json
1130   (vl_api_get_node_index_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1138
1139   vat_json_print (vam->ofp, &node);
1140   vat_json_free (&node);
1141
1142   vam->retval = ntohl (mp->retval);
1143   vam->result_ready = 1;
1144 }
1145
1146 static void vl_api_get_next_index_reply_t_handler
1147   (vl_api_get_next_index_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   i32 retval = ntohl (mp->retval);
1151   if (vam->async_mode)
1152     {
1153       vam->async_errors += (retval < 0);
1154     }
1155   else
1156     {
1157       vam->retval = retval;
1158       if (retval == 0)
1159         errmsg ("next node index %d", ntohl (mp->next_index));
1160       vam->result_ready = 1;
1161     }
1162 }
1163
1164 static void vl_api_get_next_index_reply_t_handler_json
1165   (vl_api_get_next_index_reply_t * mp)
1166 {
1167   vat_main_t *vam = &vat_main;
1168   vat_json_node_t node;
1169
1170   vat_json_init_object (&node);
1171   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1172   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1173
1174   vat_json_print (vam->ofp, &node);
1175   vat_json_free (&node);
1176
1177   vam->retval = ntohl (mp->retval);
1178   vam->result_ready = 1;
1179 }
1180
1181 static void vl_api_add_node_next_reply_t_handler
1182   (vl_api_add_node_next_reply_t * mp)
1183 {
1184   vat_main_t *vam = &vat_main;
1185   i32 retval = ntohl (mp->retval);
1186   if (vam->async_mode)
1187     {
1188       vam->async_errors += (retval < 0);
1189     }
1190   else
1191     {
1192       vam->retval = retval;
1193       if (retval == 0)
1194         errmsg ("next index %d", ntohl (mp->next_index));
1195       vam->result_ready = 1;
1196     }
1197 }
1198
1199 static void vl_api_add_node_next_reply_t_handler_json
1200   (vl_api_add_node_next_reply_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t node;
1204
1205   vat_json_init_object (&node);
1206   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1207   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1208
1209   vat_json_print (vam->ofp, &node);
1210   vat_json_free (&node);
1211
1212   vam->retval = ntohl (mp->retval);
1213   vam->result_ready = 1;
1214 }
1215
1216 static void vl_api_show_version_reply_t_handler
1217   (vl_api_show_version_reply_t * mp)
1218 {
1219   vat_main_t *vam = &vat_main;
1220   i32 retval = ntohl (mp->retval);
1221
1222   if (retval >= 0)
1223     {
1224       errmsg ("        program: %s", mp->program);
1225       errmsg ("        version: %s", mp->version);
1226       errmsg ("     build date: %s", mp->build_date);
1227       errmsg ("build directory: %s", mp->build_directory);
1228     }
1229   vam->retval = retval;
1230   vam->result_ready = 1;
1231 }
1232
1233 static void vl_api_show_version_reply_t_handler_json
1234   (vl_api_show_version_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_string_copy (&node, "program", mp->program);
1242   vat_json_object_add_string_copy (&node, "version", mp->version);
1243   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1244   vat_json_object_add_string_copy (&node, "build_directory",
1245                                    mp->build_directory);
1246
1247   vat_json_print (vam->ofp, &node);
1248   vat_json_free (&node);
1249
1250   vam->retval = ntohl (mp->retval);
1251   vam->result_ready = 1;
1252 }
1253
1254 static void
1255 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1256 {
1257   u32 sw_if_index = ntohl (mp->sw_if_index);
1258   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1259           mp->mac_ip ? "mac/ip binding" : "address resolution",
1260           format_ip4_address, &mp->address,
1261           format_ethernet_address, mp->new_mac, sw_if_index);
1262 }
1263
1264 static void
1265 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1266 {
1267   /* JSON output not supported */
1268 }
1269
1270 static void
1271 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1272 {
1273   u32 sw_if_index = ntohl (mp->sw_if_index);
1274   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1275           mp->mac_ip ? "mac/ip binding" : "address resolution",
1276           format_ip6_address, mp->address,
1277           format_ethernet_address, mp->new_mac, sw_if_index);
1278 }
1279
1280 static void
1281 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1282 {
1283   /* JSON output not supported */
1284 }
1285
1286 /*
1287  * Special-case: build the bridge domain table, maintain
1288  * the next bd id vbl.
1289  */
1290 static void vl_api_bridge_domain_details_t_handler
1291   (vl_api_bridge_domain_details_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1295
1296   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1297          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1298
1299   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1300          ntohl (mp->bd_id), mp->learn, mp->forward,
1301          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1302
1303   if (n_sw_ifs)
1304     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1305 }
1306
1307 static void vl_api_bridge_domain_details_t_handler_json
1308   (vl_api_bridge_domain_details_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   vat_json_node_t *node, *array = NULL;
1312
1313   if (VAT_JSON_ARRAY != vam->json_tree.type)
1314     {
1315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1316       vat_json_init_array (&vam->json_tree);
1317     }
1318   node = vat_json_array_add (&vam->json_tree);
1319
1320   vat_json_init_object (node);
1321   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1322   vat_json_object_add_uint (node, "flood", mp->flood);
1323   vat_json_object_add_uint (node, "forward", mp->forward);
1324   vat_json_object_add_uint (node, "learn", mp->learn);
1325   vat_json_object_add_uint (node, "bvi_sw_if_index",
1326                             ntohl (mp->bvi_sw_if_index));
1327   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1328   array = vat_json_object_add (node, "sw_if");
1329   vat_json_init_array (array);
1330 }
1331
1332 /*
1333  * Special-case: build the bridge domain sw if table.
1334  */
1335 static void vl_api_bridge_domain_sw_if_details_t_handler
1336   (vl_api_bridge_domain_sw_if_details_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   hash_pair_t *p;
1340   u8 *sw_if_name = 0;
1341   u32 sw_if_index;
1342
1343   sw_if_index = ntohl (mp->sw_if_index);
1344   /* *INDENT-OFF* */
1345   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1346   ({
1347     if ((u32) p->value[0] == sw_if_index)
1348       {
1349         sw_if_name = (u8 *)(p->key);
1350         break;
1351       }
1352   }));
1353   /* *INDENT-ON* */
1354
1355   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1356          mp->shg, sw_if_name ? (char *) sw_if_name :
1357          "sw_if_index not found!");
1358 }
1359
1360 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1361   (vl_api_bridge_domain_sw_if_details_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   vat_json_node_t *node = NULL;
1365   uword last_index = 0;
1366
1367   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1368   ASSERT (vec_len (vam->json_tree.array) >= 1);
1369   last_index = vec_len (vam->json_tree.array) - 1;
1370   node = &vam->json_tree.array[last_index];
1371   node = vat_json_object_get_element (node, "sw_if");
1372   ASSERT (NULL != node);
1373   node = vat_json_array_add (node);
1374
1375   vat_json_init_object (node);
1376   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1377   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1378   vat_json_object_add_uint (node, "shg", mp->shg);
1379 }
1380
1381 static void vl_api_control_ping_reply_t_handler
1382   (vl_api_control_ping_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->result_ready = 1;
1394     }
1395 }
1396
1397 static void vl_api_control_ping_reply_t_handler_json
1398   (vl_api_control_ping_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402
1403   if (VAT_JSON_NONE != vam->json_tree.type)
1404     {
1405       vat_json_print (vam->ofp, &vam->json_tree);
1406       vat_json_free (&vam->json_tree);
1407       vam->json_tree.type = VAT_JSON_NONE;
1408     }
1409   else
1410     {
1411       /* just print [] */
1412       vat_json_init_array (&vam->json_tree);
1413       vat_json_print (vam->ofp, &vam->json_tree);
1414       vam->json_tree.type = VAT_JSON_NONE;
1415     }
1416
1417   vam->retval = retval;
1418   vam->result_ready = 1;
1419 }
1420
1421 static void
1422 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   i32 retval = ntohl (mp->retval);
1426   if (vam->async_mode)
1427     {
1428       vam->async_errors += (retval < 0);
1429     }
1430   else
1431     {
1432       vam->retval = retval;
1433       vam->result_ready = 1;
1434     }
1435 }
1436
1437 static void vl_api_l2_flags_reply_t_handler_json
1438   (vl_api_l2_flags_reply_t * mp)
1439 {
1440   vat_main_t *vam = &vat_main;
1441   vat_json_node_t node;
1442
1443   vat_json_init_object (&node);
1444   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1445   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1446                             ntohl (mp->resulting_feature_bitmap));
1447
1448   vat_json_print (vam->ofp, &node);
1449   vat_json_free (&node);
1450
1451   vam->retval = ntohl (mp->retval);
1452   vam->result_ready = 1;
1453 }
1454
1455 static void vl_api_bridge_flags_reply_t_handler
1456   (vl_api_bridge_flags_reply_t * mp)
1457 {
1458   vat_main_t *vam = &vat_main;
1459   i32 retval = ntohl (mp->retval);
1460   if (vam->async_mode)
1461     {
1462       vam->async_errors += (retval < 0);
1463     }
1464   else
1465     {
1466       vam->retval = retval;
1467       vam->result_ready = 1;
1468     }
1469 }
1470
1471 static void vl_api_bridge_flags_reply_t_handler_json
1472   (vl_api_bridge_flags_reply_t * mp)
1473 {
1474   vat_main_t *vam = &vat_main;
1475   vat_json_node_t node;
1476
1477   vat_json_init_object (&node);
1478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1479   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1480                             ntohl (mp->resulting_feature_bitmap));
1481
1482   vat_json_print (vam->ofp, &node);
1483   vat_json_free (&node);
1484
1485   vam->retval = ntohl (mp->retval);
1486   vam->result_ready = 1;
1487 }
1488
1489 static void vl_api_tap_connect_reply_t_handler
1490   (vl_api_tap_connect_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   i32 retval = ntohl (mp->retval);
1494   if (vam->async_mode)
1495     {
1496       vam->async_errors += (retval < 0);
1497     }
1498   else
1499     {
1500       vam->retval = retval;
1501       vam->sw_if_index = ntohl (mp->sw_if_index);
1502       vam->result_ready = 1;
1503     }
1504
1505 }
1506
1507 static void vl_api_tap_connect_reply_t_handler_json
1508   (vl_api_tap_connect_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   vat_json_node_t node;
1512
1513   vat_json_init_object (&node);
1514   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1515   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522
1523 }
1524
1525 static void
1526 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1527 {
1528   vat_main_t *vam = &vat_main;
1529   i32 retval = ntohl (mp->retval);
1530   if (vam->async_mode)
1531     {
1532       vam->async_errors += (retval < 0);
1533     }
1534   else
1535     {
1536       vam->retval = retval;
1537       vam->sw_if_index = ntohl (mp->sw_if_index);
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_tap_modify_reply_t_handler_json
1543   (vl_api_tap_modify_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1551
1552   vat_json_print (vam->ofp, &node);
1553   vat_json_free (&node);
1554
1555   vam->retval = ntohl (mp->retval);
1556   vam->result_ready = 1;
1557 }
1558
1559 static void
1560 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_tap_delete_reply_t_handler_json
1576   (vl_api_tap_delete_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583
1584   vat_json_print (vam->ofp, &node);
1585   vat_json_free (&node);
1586
1587   vam->retval = ntohl (mp->retval);
1588   vam->result_ready = 1;
1589 }
1590
1591 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1592   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605 }
1606
1607 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1608   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   vat_json_node_t node;
1612
1613   vat_json_init_object (&node);
1614   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1615   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1616                             ntohl (mp->sw_if_index));
1617
1618   vat_json_print (vam->ofp, &node);
1619   vat_json_free (&node);
1620
1621   vam->retval = ntohl (mp->retval);
1622   vam->result_ready = 1;
1623 }
1624
1625 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1626   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1627 {
1628   vat_main_t *vam = &vat_main;
1629   i32 retval = ntohl (mp->retval);
1630   if (vam->async_mode)
1631     {
1632       vam->async_errors += (retval < 0);
1633     }
1634   else
1635     {
1636       vam->retval = retval;
1637       vam->sw_if_index = ntohl (mp->sw_if_index);
1638       vam->result_ready = 1;
1639     }
1640 }
1641
1642 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1643   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1644 {
1645   vat_main_t *vam = &vat_main;
1646   vat_json_node_t node;
1647
1648   vat_json_init_object (&node);
1649   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1650   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1651
1652   vat_json_print (vam->ofp, &node);
1653   vat_json_free (&node);
1654
1655   vam->retval = ntohl (mp->retval);
1656   vam->result_ready = 1;
1657 }
1658
1659
1660 static void vl_api_one_add_del_locator_set_reply_t_handler
1661   (vl_api_one_add_del_locator_set_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->result_ready = 1;
1673     }
1674 }
1675
1676 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1677   (vl_api_one_add_del_locator_set_reply_t * mp)
1678 {
1679   vat_main_t *vam = &vat_main;
1680   vat_json_node_t node;
1681
1682   vat_json_init_object (&node);
1683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1684   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1685
1686   vat_json_print (vam->ofp, &node);
1687   vat_json_free (&node);
1688
1689   vam->retval = ntohl (mp->retval);
1690   vam->result_ready = 1;
1691 }
1692
1693 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1694   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1695 {
1696   vat_main_t *vam = &vat_main;
1697   i32 retval = ntohl (mp->retval);
1698   if (vam->async_mode)
1699     {
1700       vam->async_errors += (retval < 0);
1701     }
1702   else
1703     {
1704       vam->retval = retval;
1705       vam->sw_if_index = ntohl (mp->sw_if_index);
1706       vam->result_ready = 1;
1707     }
1708 }
1709
1710 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1711   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t node;
1715
1716   vat_json_init_object (&node);
1717   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1718   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1719
1720   vat_json_print (vam->ofp, &node);
1721   vat_json_free (&node);
1722
1723   vam->retval = ntohl (mp->retval);
1724   vam->result_ready = 1;
1725 }
1726
1727 static void vl_api_gre_add_del_tunnel_reply_t_handler
1728   (vl_api_gre_add_del_tunnel_reply_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   i32 retval = ntohl (mp->retval);
1732   if (vam->async_mode)
1733     {
1734       vam->async_errors += (retval < 0);
1735     }
1736   else
1737     {
1738       vam->retval = retval;
1739       vam->sw_if_index = ntohl (mp->sw_if_index);
1740       vam->result_ready = 1;
1741     }
1742 }
1743
1744 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1745   (vl_api_gre_add_del_tunnel_reply_t * mp)
1746 {
1747   vat_main_t *vam = &vat_main;
1748   vat_json_node_t node;
1749
1750   vat_json_init_object (&node);
1751   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1752   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1753
1754   vat_json_print (vam->ofp, &node);
1755   vat_json_free (&node);
1756
1757   vam->retval = ntohl (mp->retval);
1758   vam->result_ready = 1;
1759 }
1760
1761 static void vl_api_create_vhost_user_if_reply_t_handler
1762   (vl_api_create_vhost_user_if_reply_t * mp)
1763 {
1764   vat_main_t *vam = &vat_main;
1765   i32 retval = ntohl (mp->retval);
1766   if (vam->async_mode)
1767     {
1768       vam->async_errors += (retval < 0);
1769     }
1770   else
1771     {
1772       vam->retval = retval;
1773       vam->sw_if_index = ntohl (mp->sw_if_index);
1774       vam->result_ready = 1;
1775     }
1776 }
1777
1778 static void vl_api_create_vhost_user_if_reply_t_handler_json
1779   (vl_api_create_vhost_user_if_reply_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782   vat_json_node_t node;
1783
1784   vat_json_init_object (&node);
1785   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1786   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1787
1788   vat_json_print (vam->ofp, &node);
1789   vat_json_free (&node);
1790
1791   vam->retval = ntohl (mp->retval);
1792   vam->result_ready = 1;
1793 }
1794
1795 static void vl_api_ip_address_details_t_handler
1796   (vl_api_ip_address_details_t * mp)
1797 {
1798   vat_main_t *vam = &vat_main;
1799   static ip_address_details_t empty_ip_address_details = { {0} };
1800   ip_address_details_t *address = NULL;
1801   ip_details_t *current_ip_details = NULL;
1802   ip_details_t *details = NULL;
1803
1804   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1805
1806   if (!details || vam->current_sw_if_index >= vec_len (details)
1807       || !details[vam->current_sw_if_index].present)
1808     {
1809       errmsg ("ip address details arrived but not stored");
1810       errmsg ("ip_dump should be called first");
1811       return;
1812     }
1813
1814   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1815
1816 #define addresses (current_ip_details->addr)
1817
1818   vec_validate_init_empty (addresses, vec_len (addresses),
1819                            empty_ip_address_details);
1820
1821   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1822
1823   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1824   address->prefix_length = mp->prefix_length;
1825 #undef addresses
1826 }
1827
1828 static void vl_api_ip_address_details_t_handler_json
1829   (vl_api_ip_address_details_t * mp)
1830 {
1831   vat_main_t *vam = &vat_main;
1832   vat_json_node_t *node = NULL;
1833   struct in6_addr ip6;
1834   struct in_addr ip4;
1835
1836   if (VAT_JSON_ARRAY != vam->json_tree.type)
1837     {
1838       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1839       vat_json_init_array (&vam->json_tree);
1840     }
1841   node = vat_json_array_add (&vam->json_tree);
1842
1843   vat_json_init_object (node);
1844   if (vam->is_ipv6)
1845     {
1846       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1847       vat_json_object_add_ip6 (node, "ip", ip6);
1848     }
1849   else
1850     {
1851       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1852       vat_json_object_add_ip4 (node, "ip", ip4);
1853     }
1854   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1855 }
1856
1857 static void
1858 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   static ip_details_t empty_ip_details = { 0 };
1862   ip_details_t *ip = NULL;
1863   u32 sw_if_index = ~0;
1864
1865   sw_if_index = ntohl (mp->sw_if_index);
1866
1867   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1868                            sw_if_index, empty_ip_details);
1869
1870   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1871                          sw_if_index);
1872
1873   ip->present = 1;
1874 }
1875
1876 static void
1877 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1878 {
1879   vat_main_t *vam = &vat_main;
1880
1881   if (VAT_JSON_ARRAY != vam->json_tree.type)
1882     {
1883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1884       vat_json_init_array (&vam->json_tree);
1885     }
1886   vat_json_array_add_uint (&vam->json_tree,
1887                            clib_net_to_host_u32 (mp->sw_if_index));
1888 }
1889
1890 static void vl_api_map_domain_details_t_handler_json
1891   (vl_api_map_domain_details_t * mp)
1892 {
1893   vat_json_node_t *node = NULL;
1894   vat_main_t *vam = &vat_main;
1895   struct in6_addr ip6;
1896   struct in_addr ip4;
1897
1898   if (VAT_JSON_ARRAY != vam->json_tree.type)
1899     {
1900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1901       vat_json_init_array (&vam->json_tree);
1902     }
1903
1904   node = vat_json_array_add (&vam->json_tree);
1905   vat_json_init_object (node);
1906
1907   vat_json_object_add_uint (node, "domain_index",
1908                             clib_net_to_host_u32 (mp->domain_index));
1909   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1910   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1911   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1912   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1913   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1914   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1915   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1916   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1917   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1918   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1919   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1920   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1921   vat_json_object_add_uint (node, "flags", mp->flags);
1922   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1923   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1924 }
1925
1926 static void vl_api_map_domain_details_t_handler
1927   (vl_api_map_domain_details_t * mp)
1928 {
1929   vat_main_t *vam = &vat_main;
1930
1931   if (mp->is_translation)
1932     {
1933       print (vam->ofp,
1934              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1935              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1936              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1937              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1938              clib_net_to_host_u32 (mp->domain_index));
1939     }
1940   else
1941     {
1942       print (vam->ofp,
1943              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1944              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1945              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1946              format_ip6_address, mp->ip6_src,
1947              clib_net_to_host_u32 (mp->domain_index));
1948     }
1949   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1950          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1951          mp->is_translation ? "map-t" : "");
1952 }
1953
1954 static void vl_api_map_rule_details_t_handler_json
1955   (vl_api_map_rule_details_t * mp)
1956 {
1957   struct in6_addr ip6;
1958   vat_json_node_t *node = NULL;
1959   vat_main_t *vam = &vat_main;
1960
1961   if (VAT_JSON_ARRAY != vam->json_tree.type)
1962     {
1963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1964       vat_json_init_array (&vam->json_tree);
1965     }
1966
1967   node = vat_json_array_add (&vam->json_tree);
1968   vat_json_init_object (node);
1969
1970   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1971   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1972   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1973 }
1974
1975 static void
1976 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1980          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1981 }
1982
1983 static void
1984 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1985 {
1986   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1987           "router_addr %U host_mac %U",
1988           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1989           format_ip4_address, &mp->host_address,
1990           format_ip4_address, &mp->router_address,
1991           format_ethernet_address, mp->host_mac);
1992 }
1993
1994 static void vl_api_dhcp_compl_event_t_handler_json
1995   (vl_api_dhcp_compl_event_t * mp)
1996 {
1997   /* JSON output not supported */
1998 }
1999
2000 static void
2001 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2002                               u32 counter)
2003 {
2004   vat_main_t *vam = &vat_main;
2005   static u64 default_counter = 0;
2006
2007   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2008                            NULL);
2009   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2010                            sw_if_index, default_counter);
2011   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2012 }
2013
2014 static void
2015 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2016                                 interface_counter_t counter)
2017 {
2018   vat_main_t *vam = &vat_main;
2019   static interface_counter_t default_counter = { 0, };
2020
2021   vec_validate_init_empty (vam->combined_interface_counters,
2022                            vnet_counter_type, NULL);
2023   vec_validate_init_empty (vam->combined_interface_counters
2024                            [vnet_counter_type], sw_if_index, default_counter);
2025   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2026 }
2027
2028 static void vl_api_vnet_interface_counters_t_handler
2029   (vl_api_vnet_interface_counters_t * mp)
2030 {
2031   /* not supported */
2032 }
2033
2034 static void vl_api_vnet_interface_counters_t_handler_json
2035   (vl_api_vnet_interface_counters_t * mp)
2036 {
2037   interface_counter_t counter;
2038   vlib_counter_t *v;
2039   u64 *v_packets;
2040   u64 packets;
2041   u32 count;
2042   u32 first_sw_if_index;
2043   int i;
2044
2045   count = ntohl (mp->count);
2046   first_sw_if_index = ntohl (mp->first_sw_if_index);
2047
2048   if (!mp->is_combined)
2049     {
2050       v_packets = (u64 *) & mp->data;
2051       for (i = 0; i < count; i++)
2052         {
2053           packets =
2054             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2055           set_simple_interface_counter (mp->vnet_counter_type,
2056                                         first_sw_if_index + i, packets);
2057           v_packets++;
2058         }
2059     }
2060   else
2061     {
2062       v = (vlib_counter_t *) & mp->data;
2063       for (i = 0; i < count; i++)
2064         {
2065           counter.packets =
2066             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2067           counter.bytes =
2068             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2069           set_combined_interface_counter (mp->vnet_counter_type,
2070                                           first_sw_if_index + i, counter);
2071           v++;
2072         }
2073     }
2074 }
2075
2076 static u32
2077 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2078 {
2079   vat_main_t *vam = &vat_main;
2080   u32 i;
2081
2082   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2083     {
2084       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2085         {
2086           return i;
2087         }
2088     }
2089   return ~0;
2090 }
2091
2092 static u32
2093 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2094 {
2095   vat_main_t *vam = &vat_main;
2096   u32 i;
2097
2098   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2099     {
2100       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2101         {
2102           return i;
2103         }
2104     }
2105   return ~0;
2106 }
2107
2108 static void vl_api_vnet_ip4_fib_counters_t_handler
2109   (vl_api_vnet_ip4_fib_counters_t * mp)
2110 {
2111   /* not supported */
2112 }
2113
2114 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2115   (vl_api_vnet_ip4_fib_counters_t * mp)
2116 {
2117   vat_main_t *vam = &vat_main;
2118   vl_api_ip4_fib_counter_t *v;
2119   ip4_fib_counter_t *counter;
2120   struct in_addr ip4;
2121   u32 vrf_id;
2122   u32 vrf_index;
2123   u32 count;
2124   int i;
2125
2126   vrf_id = ntohl (mp->vrf_id);
2127   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2128   if (~0 == vrf_index)
2129     {
2130       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2131       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2132       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2133       vec_validate (vam->ip4_fib_counters, vrf_index);
2134       vam->ip4_fib_counters[vrf_index] = NULL;
2135     }
2136
2137   vec_free (vam->ip4_fib_counters[vrf_index]);
2138   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2139   count = ntohl (mp->count);
2140   for (i = 0; i < count; i++)
2141     {
2142       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2143       counter = &vam->ip4_fib_counters[vrf_index][i];
2144       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2145       counter->address = ip4;
2146       counter->address_length = v->address_length;
2147       counter->packets = clib_net_to_host_u64 (v->packets);
2148       counter->bytes = clib_net_to_host_u64 (v->bytes);
2149       v++;
2150     }
2151 }
2152
2153 static void vl_api_vnet_ip4_nbr_counters_t_handler
2154   (vl_api_vnet_ip4_nbr_counters_t * mp)
2155 {
2156   /* not supported */
2157 }
2158
2159 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2160   (vl_api_vnet_ip4_nbr_counters_t * mp)
2161 {
2162   vat_main_t *vam = &vat_main;
2163   vl_api_ip4_nbr_counter_t *v;
2164   ip4_nbr_counter_t *counter;
2165   u32 sw_if_index;
2166   u32 count;
2167   int i;
2168
2169   sw_if_index = ntohl (mp->sw_if_index);
2170   count = ntohl (mp->count);
2171   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2172
2173   if (mp->begin)
2174     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2175
2176   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2177   for (i = 0; i < count; i++)
2178     {
2179       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2180       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2181       counter->address.s_addr = v->address;
2182       counter->packets = clib_net_to_host_u64 (v->packets);
2183       counter->bytes = clib_net_to_host_u64 (v->bytes);
2184       counter->linkt = v->link_type;
2185       v++;
2186     }
2187 }
2188
2189 static void vl_api_vnet_ip6_fib_counters_t_handler
2190   (vl_api_vnet_ip6_fib_counters_t * mp)
2191 {
2192   /* not supported */
2193 }
2194
2195 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2196   (vl_api_vnet_ip6_fib_counters_t * mp)
2197 {
2198   vat_main_t *vam = &vat_main;
2199   vl_api_ip6_fib_counter_t *v;
2200   ip6_fib_counter_t *counter;
2201   struct in6_addr ip6;
2202   u32 vrf_id;
2203   u32 vrf_index;
2204   u32 count;
2205   int i;
2206
2207   vrf_id = ntohl (mp->vrf_id);
2208   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2209   if (~0 == vrf_index)
2210     {
2211       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2212       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2213       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2214       vec_validate (vam->ip6_fib_counters, vrf_index);
2215       vam->ip6_fib_counters[vrf_index] = NULL;
2216     }
2217
2218   vec_free (vam->ip6_fib_counters[vrf_index]);
2219   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2220   count = ntohl (mp->count);
2221   for (i = 0; i < count; i++)
2222     {
2223       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2224       counter = &vam->ip6_fib_counters[vrf_index][i];
2225       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2226       counter->address = ip6;
2227       counter->address_length = v->address_length;
2228       counter->packets = clib_net_to_host_u64 (v->packets);
2229       counter->bytes = clib_net_to_host_u64 (v->bytes);
2230       v++;
2231     }
2232 }
2233
2234 static void vl_api_vnet_ip6_nbr_counters_t_handler
2235   (vl_api_vnet_ip6_nbr_counters_t * mp)
2236 {
2237   /* not supported */
2238 }
2239
2240 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2241   (vl_api_vnet_ip6_nbr_counters_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vl_api_ip6_nbr_counter_t *v;
2245   ip6_nbr_counter_t *counter;
2246   struct in6_addr ip6;
2247   u32 sw_if_index;
2248   u32 count;
2249   int i;
2250
2251   sw_if_index = ntohl (mp->sw_if_index);
2252   count = ntohl (mp->count);
2253   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2254
2255   if (mp->begin)
2256     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2257
2258   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2259   for (i = 0; i < count; i++)
2260     {
2261       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2262       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2263       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2264       counter->address = ip6;
2265       counter->packets = clib_net_to_host_u64 (v->packets);
2266       counter->bytes = clib_net_to_host_u64 (v->bytes);
2267       v++;
2268     }
2269 }
2270
2271 static void vl_api_get_first_msg_id_reply_t_handler
2272   (vl_api_get_first_msg_id_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   i32 retval = ntohl (mp->retval);
2276
2277   if (vam->async_mode)
2278     {
2279       vam->async_errors += (retval < 0);
2280     }
2281   else
2282     {
2283       vam->retval = retval;
2284       vam->result_ready = 1;
2285     }
2286   if (retval >= 0)
2287     {
2288       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2289     }
2290 }
2291
2292 static void vl_api_get_first_msg_id_reply_t_handler_json
2293   (vl_api_get_first_msg_id_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297
2298   vat_json_init_object (&node);
2299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2300   vat_json_object_add_uint (&node, "first_msg_id",
2301                             (uint) ntohs (mp->first_msg_id));
2302
2303   vat_json_print (vam->ofp, &node);
2304   vat_json_free (&node);
2305
2306   vam->retval = ntohl (mp->retval);
2307   vam->result_ready = 1;
2308 }
2309
2310 static void vl_api_get_node_graph_reply_t_handler
2311   (vl_api_get_node_graph_reply_t * mp)
2312 {
2313   vat_main_t *vam = &vat_main;
2314   api_main_t *am = &api_main;
2315   i32 retval = ntohl (mp->retval);
2316   u8 *pvt_copy, *reply;
2317   void *oldheap;
2318   vlib_node_t *node;
2319   int i;
2320
2321   if (vam->async_mode)
2322     {
2323       vam->async_errors += (retval < 0);
2324     }
2325   else
2326     {
2327       vam->retval = retval;
2328       vam->result_ready = 1;
2329     }
2330
2331   /* "Should never happen..." */
2332   if (retval != 0)
2333     return;
2334
2335   reply = (u8 *) (mp->reply_in_shmem);
2336   pvt_copy = vec_dup (reply);
2337
2338   /* Toss the shared-memory original... */
2339   pthread_mutex_lock (&am->vlib_rp->mutex);
2340   oldheap = svm_push_data_heap (am->vlib_rp);
2341
2342   vec_free (reply);
2343
2344   svm_pop_heap (oldheap);
2345   pthread_mutex_unlock (&am->vlib_rp->mutex);
2346
2347   if (vam->graph_nodes)
2348     {
2349       hash_free (vam->graph_node_index_by_name);
2350
2351       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2352         {
2353           node = vam->graph_nodes[i];
2354           vec_free (node->name);
2355           vec_free (node->next_nodes);
2356           vec_free (node);
2357         }
2358       vec_free (vam->graph_nodes);
2359     }
2360
2361   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2362   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2363   vec_free (pvt_copy);
2364
2365   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2366     {
2367       node = vam->graph_nodes[i];
2368       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2369     }
2370 }
2371
2372 static void vl_api_get_node_graph_reply_t_handler_json
2373   (vl_api_get_node_graph_reply_t * mp)
2374 {
2375   vat_main_t *vam = &vat_main;
2376   api_main_t *am = &api_main;
2377   void *oldheap;
2378   vat_json_node_t node;
2379   u8 *reply;
2380
2381   /* $$$$ make this real? */
2382   vat_json_init_object (&node);
2383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2384   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2385
2386   reply = (u8 *) (mp->reply_in_shmem);
2387
2388   /* Toss the shared-memory original... */
2389   pthread_mutex_lock (&am->vlib_rp->mutex);
2390   oldheap = svm_push_data_heap (am->vlib_rp);
2391
2392   vec_free (reply);
2393
2394   svm_pop_heap (oldheap);
2395   pthread_mutex_unlock (&am->vlib_rp->mutex);
2396
2397   vat_json_print (vam->ofp, &node);
2398   vat_json_free (&node);
2399
2400   vam->retval = ntohl (mp->retval);
2401   vam->result_ready = 1;
2402 }
2403
2404 static void
2405 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2406 {
2407   vat_main_t *vam = &vat_main;
2408   u8 *s = 0;
2409
2410   if (mp->local)
2411     {
2412       s = format (s, "%=16d%=16d%=16d",
2413                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2414     }
2415   else
2416     {
2417       s = format (s, "%=16U%=16d%=16d",
2418                   mp->is_ipv6 ? format_ip6_address :
2419                   format_ip4_address,
2420                   mp->ip_address, mp->priority, mp->weight);
2421     }
2422
2423   print (vam->ofp, "%v", s);
2424   vec_free (s);
2425 }
2426
2427 static void
2428 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431   vat_json_node_t *node = NULL;
2432   struct in6_addr ip6;
2433   struct in_addr ip4;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442
2443   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2444   vat_json_object_add_uint (node, "priority", mp->priority);
2445   vat_json_object_add_uint (node, "weight", mp->weight);
2446
2447   if (mp->local)
2448     vat_json_object_add_uint (node, "sw_if_index",
2449                               clib_net_to_host_u32 (mp->sw_if_index));
2450   else
2451     {
2452       if (mp->is_ipv6)
2453         {
2454           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2455           vat_json_object_add_ip6 (node, "address", ip6);
2456         }
2457       else
2458         {
2459           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2460           vat_json_object_add_ip4 (node, "address", ip4);
2461         }
2462     }
2463 }
2464
2465 static void
2466 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2467                                           mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   u8 *ls_name = 0;
2471
2472   ls_name = format (0, "%s", mp->ls_name);
2473
2474   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2475          ls_name);
2476   vec_free (ls_name);
2477 }
2478
2479 static void
2480   vl_api_one_locator_set_details_t_handler_json
2481   (vl_api_one_locator_set_details_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   vat_json_node_t *node = 0;
2485   u8 *ls_name = 0;
2486
2487   ls_name = format (0, "%s", mp->ls_name);
2488   vec_add1 (ls_name, 0);
2489
2490   if (VAT_JSON_ARRAY != vam->json_tree.type)
2491     {
2492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2493       vat_json_init_array (&vam->json_tree);
2494     }
2495   node = vat_json_array_add (&vam->json_tree);
2496
2497   vat_json_init_object (node);
2498   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2499   vat_json_object_add_uint (node, "ls_index",
2500                             clib_net_to_host_u32 (mp->ls_index));
2501   vec_free (ls_name);
2502 }
2503
2504 static u8 *
2505 format_lisp_flat_eid (u8 * s, va_list * args)
2506 {
2507   u32 type = va_arg (*args, u32);
2508   u8 *eid = va_arg (*args, u8 *);
2509   u32 eid_len = va_arg (*args, u32);
2510
2511   switch (type)
2512     {
2513     case 0:
2514       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2515     case 1:
2516       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2517     case 2:
2518       return format (s, "%U", format_ethernet_address, eid);
2519     }
2520   return 0;
2521 }
2522
2523 static u8 *
2524 format_lisp_eid_vat (u8 * s, va_list * args)
2525 {
2526   u32 type = va_arg (*args, u32);
2527   u8 *eid = va_arg (*args, u8 *);
2528   u32 eid_len = va_arg (*args, u32);
2529   u8 *seid = va_arg (*args, u8 *);
2530   u32 seid_len = va_arg (*args, u32);
2531   u32 is_src_dst = va_arg (*args, u32);
2532
2533   if (is_src_dst)
2534     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2535
2536   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2537
2538   return s;
2539 }
2540
2541 static void
2542 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2543 {
2544   vat_main_t *vam = &vat_main;
2545   u8 *s = 0, *eid = 0;
2546
2547   if (~0 == mp->locator_set_index)
2548     s = format (0, "action: %d", mp->action);
2549   else
2550     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2551
2552   eid = format (0, "%U", format_lisp_eid_vat,
2553                 mp->eid_type,
2554                 mp->eid,
2555                 mp->eid_prefix_len,
2556                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2557   vec_add1 (eid, 0);
2558
2559   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2560          clib_net_to_host_u32 (mp->vni),
2561          eid,
2562          mp->is_local ? "local" : "remote",
2563          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2564          clib_net_to_host_u16 (mp->key_id), mp->key);
2565
2566   vec_free (s);
2567   vec_free (eid);
2568 }
2569
2570 static void
2571 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2572                                              * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   vat_json_node_t *node = 0;
2576   u8 *eid = 0;
2577
2578   if (VAT_JSON_ARRAY != vam->json_tree.type)
2579     {
2580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2581       vat_json_init_array (&vam->json_tree);
2582     }
2583   node = vat_json_array_add (&vam->json_tree);
2584
2585   vat_json_init_object (node);
2586   if (~0 == mp->locator_set_index)
2587     vat_json_object_add_uint (node, "action", mp->action);
2588   else
2589     vat_json_object_add_uint (node, "locator_set_index",
2590                               clib_net_to_host_u32 (mp->locator_set_index));
2591
2592   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2593   eid = format (0, "%U", format_lisp_eid_vat,
2594                 mp->eid_type,
2595                 mp->eid,
2596                 mp->eid_prefix_len,
2597                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2598   vec_add1 (eid, 0);
2599   vat_json_object_add_string_copy (node, "eid", eid);
2600   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2601   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2602   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2603
2604   if (mp->key_id)
2605     {
2606       vat_json_object_add_uint (node, "key_id",
2607                                 clib_net_to_host_u16 (mp->key_id));
2608       vat_json_object_add_string_copy (node, "key", mp->key);
2609     }
2610   vec_free (eid);
2611 }
2612
2613 static void
2614 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617   u8 *seid = 0, *deid = 0;
2618   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2619
2620   deid = format (0, "%U", format_lisp_eid_vat,
2621                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2622
2623   seid = format (0, "%U", format_lisp_eid_vat,
2624                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2625
2626   vec_add1 (deid, 0);
2627   vec_add1 (seid, 0);
2628
2629   if (mp->is_ip4)
2630     format_ip_address_fcn = format_ip4_address;
2631   else
2632     format_ip_address_fcn = format_ip6_address;
2633
2634
2635   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
2636          clib_net_to_host_u32 (mp->vni),
2637          seid, deid,
2638          format_ip_address_fcn, mp->lloc,
2639          format_ip_address_fcn, mp->rloc,
2640          clib_net_to_host_u32 (mp->pkt_count),
2641          clib_net_to_host_u32 (mp->bytes));
2642
2643   vec_free (deid);
2644   vec_free (seid);
2645 }
2646
2647 static void
2648 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
2649 {
2650   struct in6_addr ip6;
2651   struct in_addr ip4;
2652   vat_main_t *vam = &vat_main;
2653   vat_json_node_t *node = 0;
2654   u8 *deid = 0, *seid = 0;
2655
2656   if (VAT_JSON_ARRAY != vam->json_tree.type)
2657     {
2658       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2659       vat_json_init_array (&vam->json_tree);
2660     }
2661   node = vat_json_array_add (&vam->json_tree);
2662
2663   vat_json_init_object (node);
2664   deid = format (0, "%U", format_lisp_eid_vat,
2665                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
2666
2667   seid = format (0, "%U", format_lisp_eid_vat,
2668                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
2669
2670   vec_add1 (deid, 0);
2671   vec_add1 (seid, 0);
2672
2673   vat_json_object_add_string_copy (node, "seid", seid);
2674   vat_json_object_add_string_copy (node, "deid", deid);
2675   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2676
2677   if (mp->is_ip4)
2678     {
2679       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
2680       vat_json_object_add_ip4 (node, "lloc", ip4);
2681       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
2682       vat_json_object_add_ip4 (node, "rloc", ip4);
2683     }
2684   else
2685     {
2686       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
2687       vat_json_object_add_ip6 (node, "lloc", ip6);
2688       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
2689       vat_json_object_add_ip6 (node, "rloc", ip6);
2690     }
2691   vat_json_object_add_uint (node, "pkt_count",
2692                             clib_net_to_host_u32 (mp->pkt_count));
2693   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
2694
2695   vec_free (deid);
2696   vec_free (seid);
2697 }
2698
2699 static void
2700   vl_api_one_eid_table_map_details_t_handler
2701   (vl_api_one_eid_table_map_details_t * mp)
2702 {
2703   vat_main_t *vam = &vat_main;
2704
2705   u8 *line = format (0, "%=10d%=10d",
2706                      clib_net_to_host_u32 (mp->vni),
2707                      clib_net_to_host_u32 (mp->dp_table));
2708   print (vam->ofp, "%v", line);
2709   vec_free (line);
2710 }
2711
2712 static void
2713   vl_api_one_eid_table_map_details_t_handler_json
2714   (vl_api_one_eid_table_map_details_t * mp)
2715 {
2716   vat_main_t *vam = &vat_main;
2717   vat_json_node_t *node = NULL;
2718
2719   if (VAT_JSON_ARRAY != vam->json_tree.type)
2720     {
2721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2722       vat_json_init_array (&vam->json_tree);
2723     }
2724   node = vat_json_array_add (&vam->json_tree);
2725   vat_json_init_object (node);
2726   vat_json_object_add_uint (node, "dp_table",
2727                             clib_net_to_host_u32 (mp->dp_table));
2728   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2729 }
2730
2731 static void
2732   vl_api_one_eid_table_vni_details_t_handler
2733   (vl_api_one_eid_table_vni_details_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736
2737   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2738   print (vam->ofp, "%v", line);
2739   vec_free (line);
2740 }
2741
2742 static void
2743   vl_api_one_eid_table_vni_details_t_handler_json
2744   (vl_api_one_eid_table_vni_details_t * mp)
2745 {
2746   vat_main_t *vam = &vat_main;
2747   vat_json_node_t *node = NULL;
2748
2749   if (VAT_JSON_ARRAY != vam->json_tree.type)
2750     {
2751       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2752       vat_json_init_array (&vam->json_tree);
2753     }
2754   node = vat_json_array_add (&vam->json_tree);
2755   vat_json_init_object (node);
2756   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2757 }
2758
2759 static void
2760   vl_api_show_one_map_register_state_reply_t_handler
2761   (vl_api_show_one_map_register_state_reply_t * mp)
2762 {
2763   vat_main_t *vam = &vat_main;
2764   int retval = clib_net_to_host_u32 (mp->retval);
2765
2766   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2767
2768   vam->retval = retval;
2769   vam->result_ready = 1;
2770 }
2771
2772 static void
2773   vl_api_show_one_map_register_state_reply_t_handler_json
2774   (vl_api_show_one_map_register_state_reply_t * mp)
2775 {
2776   vat_main_t *vam = &vat_main;
2777   vat_json_node_t _node, *node = &_node;
2778   int retval = clib_net_to_host_u32 (mp->retval);
2779
2780   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2781
2782   vat_json_init_object (node);
2783   vat_json_object_add_string_copy (node, "state", s);
2784
2785   vat_json_print (vam->ofp, node);
2786   vat_json_free (node);
2787
2788   vam->retval = retval;
2789   vam->result_ready = 1;
2790   vec_free (s);
2791 }
2792
2793 static void
2794   vl_api_show_one_rloc_probe_state_reply_t_handler
2795   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2796 {
2797   vat_main_t *vam = &vat_main;
2798   int retval = clib_net_to_host_u32 (mp->retval);
2799
2800   if (retval)
2801     goto end;
2802
2803   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2804 end:
2805   vam->retval = retval;
2806   vam->result_ready = 1;
2807 }
2808
2809 static void
2810   vl_api_show_one_rloc_probe_state_reply_t_handler_json
2811   (vl_api_show_one_rloc_probe_state_reply_t * mp)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   vat_json_node_t _node, *node = &_node;
2815   int retval = clib_net_to_host_u32 (mp->retval);
2816
2817   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2818   vat_json_init_object (node);
2819   vat_json_object_add_string_copy (node, "state", s);
2820
2821   vat_json_print (vam->ofp, node);
2822   vat_json_free (node);
2823
2824   vam->retval = retval;
2825   vam->result_ready = 1;
2826   vec_free (s);
2827 }
2828
2829 static void
2830   vl_api_show_one_stats_enable_disable_reply_t_handler
2831   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2832 {
2833   vat_main_t *vam = &vat_main;
2834   int retval = clib_net_to_host_u32 (mp->retval);
2835
2836   if (retval)
2837     goto end;
2838
2839   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
2840 end:
2841   vam->retval = retval;
2842   vam->result_ready = 1;
2843 }
2844
2845 static void
2846   vl_api_show_one_stats_enable_disable_reply_t_handler_json
2847   (vl_api_show_one_stats_enable_disable_reply_t * mp)
2848 {
2849   vat_main_t *vam = &vat_main;
2850   vat_json_node_t _node, *node = &_node;
2851   int retval = clib_net_to_host_u32 (mp->retval);
2852
2853   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
2854   vat_json_init_object (node);
2855   vat_json_object_add_string_copy (node, "state", s);
2856
2857   vat_json_print (vam->ofp, node);
2858   vat_json_free (node);
2859
2860   vam->retval = retval;
2861   vam->result_ready = 1;
2862   vec_free (s);
2863 }
2864
2865 static void
2866 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
2867 {
2868   e->dp_table = clib_net_to_host_u32 (e->dp_table);
2869   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
2870 }
2871
2872 static void
2873   gpe_fwd_entries_get_reply_t_net_to_host
2874   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2875 {
2876   u32 i;
2877
2878   mp->count = clib_net_to_host_u32 (mp->count);
2879   for (i = 0; i < mp->count; i++)
2880     {
2881       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
2882     }
2883 }
2884
2885 static u8 *
2886 format_gpe_encap_mode (u8 * s, va_list * args)
2887 {
2888   u32 mode = va_arg (*args, u32);
2889
2890   switch (mode)
2891     {
2892     case 0:
2893       return format (s, "lisp");
2894     case 1:
2895       return format (s, "vxlan");
2896     }
2897   return 0;
2898 }
2899
2900 static void
2901   vl_api_gpe_get_encap_mode_reply_t_handler
2902   (vl_api_gpe_get_encap_mode_reply_t * mp)
2903 {
2904   vat_main_t *vam = &vat_main;
2905
2906   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
2907   vam->retval = ntohl (mp->retval);
2908   vam->result_ready = 1;
2909 }
2910
2911 static void
2912   vl_api_gpe_get_encap_mode_reply_t_handler_json
2913   (vl_api_gpe_get_encap_mode_reply_t * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916   vat_json_node_t node;
2917
2918   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
2919   vec_add1 (encap_mode, 0);
2920
2921   vat_json_init_object (&node);
2922   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
2923
2924   vec_free (encap_mode);
2925   vat_json_print (vam->ofp, &node);
2926   vat_json_free (&node);
2927
2928   vam->retval = ntohl (mp->retval);
2929   vam->result_ready = 1;
2930 }
2931
2932 static void
2933   vl_api_gpe_fwd_entry_path_details_t_handler
2934   (vl_api_gpe_fwd_entry_path_details_t * mp)
2935 {
2936   vat_main_t *vam = &vat_main;
2937   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
2938
2939   if (mp->lcl_loc.is_ip4)
2940     format_ip_address_fcn = format_ip4_address;
2941   else
2942     format_ip_address_fcn = format_ip6_address;
2943
2944   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
2945          format_ip_address_fcn, &mp->lcl_loc,
2946          format_ip_address_fcn, &mp->rmt_loc);
2947 }
2948
2949 static void
2950 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
2951 {
2952   struct in6_addr ip6;
2953   struct in_addr ip4;
2954
2955   if (loc->is_ip4)
2956     {
2957       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
2958       vat_json_object_add_ip4 (n, "address", ip4);
2959     }
2960   else
2961     {
2962       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
2963       vat_json_object_add_ip6 (n, "address", ip6);
2964     }
2965   vat_json_object_add_uint (n, "weight", loc->weight);
2966 }
2967
2968 static void
2969   vl_api_gpe_fwd_entry_path_details_t_handler_json
2970   (vl_api_gpe_fwd_entry_path_details_t * mp)
2971 {
2972   vat_main_t *vam = &vat_main;
2973   vat_json_node_t *node = NULL;
2974   vat_json_node_t *loc_node;
2975
2976   if (VAT_JSON_ARRAY != vam->json_tree.type)
2977     {
2978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2979       vat_json_init_array (&vam->json_tree);
2980     }
2981   node = vat_json_array_add (&vam->json_tree);
2982   vat_json_init_object (node);
2983
2984   loc_node = vat_json_object_add (node, "local_locator");
2985   vat_json_init_object (loc_node);
2986   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
2987
2988   loc_node = vat_json_object_add (node, "remote_locator");
2989   vat_json_init_object (loc_node);
2990   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
2991 }
2992
2993 static void
2994   vl_api_gpe_fwd_entries_get_reply_t_handler
2995   (vl_api_gpe_fwd_entries_get_reply_t * mp)
2996 {
2997   vat_main_t *vam = &vat_main;
2998   u32 i;
2999   int retval = clib_net_to_host_u32 (mp->retval);
3000   vl_api_gpe_fwd_entry_t *e;
3001
3002   if (retval)
3003     goto end;
3004
3005   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3006
3007   for (i = 0; i < mp->count; i++)
3008     {
3009       e = &mp->entries[i];
3010       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3011              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3012              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3013     }
3014
3015 end:
3016   vam->retval = retval;
3017   vam->result_ready = 1;
3018 }
3019
3020 static void
3021   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3022   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3023 {
3024   u8 *s = 0;
3025   vat_main_t *vam = &vat_main;
3026   vat_json_node_t *e = 0, root;
3027   u32 i;
3028   int retval = clib_net_to_host_u32 (mp->retval);
3029   vl_api_gpe_fwd_entry_t *fwd;
3030
3031   if (retval)
3032     goto end;
3033
3034   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3035   vat_json_init_array (&root);
3036
3037   for (i = 0; i < mp->count; i++)
3038     {
3039       e = vat_json_array_add (&root);
3040       fwd = &mp->entries[i];
3041
3042       vat_json_init_object (e);
3043       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3044       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3045
3046       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3047                   fwd->leid_prefix_len);
3048       vec_add1 (s, 0);
3049       vat_json_object_add_string_copy (e, "leid", s);
3050       vec_free (s);
3051
3052       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3053                   fwd->reid_prefix_len);
3054       vec_add1 (s, 0);
3055       vat_json_object_add_string_copy (e, "reid", s);
3056       vec_free (s);
3057     }
3058
3059   vat_json_print (vam->ofp, &root);
3060   vat_json_free (&root);
3061
3062 end:
3063   vam->retval = retval;
3064   vam->result_ready = 1;
3065 }
3066
3067 static void
3068   vl_api_one_adjacencies_get_reply_t_handler
3069   (vl_api_one_adjacencies_get_reply_t * mp)
3070 {
3071   vat_main_t *vam = &vat_main;
3072   u32 i, n;
3073   int retval = clib_net_to_host_u32 (mp->retval);
3074   vl_api_one_adjacency_t *a;
3075
3076   if (retval)
3077     goto end;
3078
3079   n = clib_net_to_host_u32 (mp->count);
3080
3081   for (i = 0; i < n; i++)
3082     {
3083       a = &mp->adjacencies[i];
3084       print (vam->ofp, "%U %40U",
3085              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3086              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3087     }
3088
3089 end:
3090   vam->retval = retval;
3091   vam->result_ready = 1;
3092 }
3093
3094 static void
3095   vl_api_one_adjacencies_get_reply_t_handler_json
3096   (vl_api_one_adjacencies_get_reply_t * mp)
3097 {
3098   u8 *s = 0;
3099   vat_main_t *vam = &vat_main;
3100   vat_json_node_t *e = 0, root;
3101   u32 i, n;
3102   int retval = clib_net_to_host_u32 (mp->retval);
3103   vl_api_one_adjacency_t *a;
3104
3105   if (retval)
3106     goto end;
3107
3108   n = clib_net_to_host_u32 (mp->count);
3109   vat_json_init_array (&root);
3110
3111   for (i = 0; i < n; i++)
3112     {
3113       e = vat_json_array_add (&root);
3114       a = &mp->adjacencies[i];
3115
3116       vat_json_init_object (e);
3117       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3118                   a->leid_prefix_len);
3119       vec_add1 (s, 0);
3120       vat_json_object_add_string_copy (e, "leid", s);
3121       vec_free (s);
3122
3123       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3124                   a->reid_prefix_len);
3125       vec_add1 (s, 0);
3126       vat_json_object_add_string_copy (e, "reid", s);
3127       vec_free (s);
3128     }
3129
3130   vat_json_print (vam->ofp, &root);
3131   vat_json_free (&root);
3132
3133 end:
3134   vam->retval = retval;
3135   vam->result_ready = 1;
3136 }
3137
3138 static void
3139 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3140 {
3141   vat_main_t *vam = &vat_main;
3142
3143   print (vam->ofp, "%=20U",
3144          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3145          mp->ip_address);
3146 }
3147
3148 static void
3149   vl_api_one_map_server_details_t_handler_json
3150   (vl_api_one_map_server_details_t * mp)
3151 {
3152   vat_main_t *vam = &vat_main;
3153   vat_json_node_t *node = NULL;
3154   struct in6_addr ip6;
3155   struct in_addr ip4;
3156
3157   if (VAT_JSON_ARRAY != vam->json_tree.type)
3158     {
3159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3160       vat_json_init_array (&vam->json_tree);
3161     }
3162   node = vat_json_array_add (&vam->json_tree);
3163
3164   vat_json_init_object (node);
3165   if (mp->is_ipv6)
3166     {
3167       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3168       vat_json_object_add_ip6 (node, "map-server", ip6);
3169     }
3170   else
3171     {
3172       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3173       vat_json_object_add_ip4 (node, "map-server", ip4);
3174     }
3175 }
3176
3177 static void
3178 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3179                                            * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182
3183   print (vam->ofp, "%=20U",
3184          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3185          mp->ip_address);
3186 }
3187
3188 static void
3189   vl_api_one_map_resolver_details_t_handler_json
3190   (vl_api_one_map_resolver_details_t * mp)
3191 {
3192   vat_main_t *vam = &vat_main;
3193   vat_json_node_t *node = NULL;
3194   struct in6_addr ip6;
3195   struct in_addr ip4;
3196
3197   if (VAT_JSON_ARRAY != vam->json_tree.type)
3198     {
3199       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3200       vat_json_init_array (&vam->json_tree);
3201     }
3202   node = vat_json_array_add (&vam->json_tree);
3203
3204   vat_json_init_object (node);
3205   if (mp->is_ipv6)
3206     {
3207       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3208       vat_json_object_add_ip6 (node, "map resolver", ip6);
3209     }
3210   else
3211     {
3212       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3213       vat_json_object_add_ip4 (node, "map resolver", ip4);
3214     }
3215 }
3216
3217 static void
3218 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3219 {
3220   vat_main_t *vam = &vat_main;
3221   i32 retval = ntohl (mp->retval);
3222
3223   if (0 <= retval)
3224     {
3225       print (vam->ofp, "feature: %s\ngpe: %s",
3226              mp->feature_status ? "enabled" : "disabled",
3227              mp->gpe_status ? "enabled" : "disabled");
3228     }
3229
3230   vam->retval = retval;
3231   vam->result_ready = 1;
3232 }
3233
3234 static void
3235   vl_api_show_one_status_reply_t_handler_json
3236   (vl_api_show_one_status_reply_t * mp)
3237 {
3238   vat_main_t *vam = &vat_main;
3239   vat_json_node_t node;
3240   u8 *gpe_status = NULL;
3241   u8 *feature_status = NULL;
3242
3243   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
3244   feature_status = format (0, "%s",
3245                            mp->feature_status ? "enabled" : "disabled");
3246   vec_add1 (gpe_status, 0);
3247   vec_add1 (feature_status, 0);
3248
3249   vat_json_init_object (&node);
3250   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
3251   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
3252
3253   vec_free (gpe_status);
3254   vec_free (feature_status);
3255
3256   vat_json_print (vam->ofp, &node);
3257   vat_json_free (&node);
3258
3259   vam->retval = ntohl (mp->retval);
3260   vam->result_ready = 1;
3261 }
3262
3263 static void
3264   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
3265   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268   i32 retval = ntohl (mp->retval);
3269
3270   if (retval >= 0)
3271     {
3272       print (vam->ofp, "%=20s", mp->locator_set_name);
3273     }
3274
3275   vam->retval = retval;
3276   vam->result_ready = 1;
3277 }
3278
3279 static void
3280   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
3281   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
3282 {
3283   vat_main_t *vam = &vat_main;
3284   vat_json_node_t *node = NULL;
3285
3286   if (VAT_JSON_ARRAY != vam->json_tree.type)
3287     {
3288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3289       vat_json_init_array (&vam->json_tree);
3290     }
3291   node = vat_json_array_add (&vam->json_tree);
3292
3293   vat_json_init_object (node);
3294   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
3295
3296   vat_json_print (vam->ofp, node);
3297   vat_json_free (node);
3298
3299   vam->retval = ntohl (mp->retval);
3300   vam->result_ready = 1;
3301 }
3302
3303 static u8 *
3304 format_lisp_map_request_mode (u8 * s, va_list * args)
3305 {
3306   u32 mode = va_arg (*args, u32);
3307
3308   switch (mode)
3309     {
3310     case 0:
3311       return format (0, "dst-only");
3312     case 1:
3313       return format (0, "src-dst");
3314     }
3315   return 0;
3316 }
3317
3318 static void
3319   vl_api_show_one_map_request_mode_reply_t_handler
3320   (vl_api_show_one_map_request_mode_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   i32 retval = ntohl (mp->retval);
3324
3325   if (0 <= retval)
3326     {
3327       u32 mode = mp->mode;
3328       print (vam->ofp, "map_request_mode: %U",
3329              format_lisp_map_request_mode, mode);
3330     }
3331
3332   vam->retval = retval;
3333   vam->result_ready = 1;
3334 }
3335
3336 static void
3337   vl_api_show_one_map_request_mode_reply_t_handler_json
3338   (vl_api_show_one_map_request_mode_reply_t * mp)
3339 {
3340   vat_main_t *vam = &vat_main;
3341   vat_json_node_t node;
3342   u8 *s = 0;
3343   u32 mode;
3344
3345   mode = mp->mode;
3346   s = format (0, "%U", format_lisp_map_request_mode, mode);
3347   vec_add1 (s, 0);
3348
3349   vat_json_init_object (&node);
3350   vat_json_object_add_string_copy (&node, "map_request_mode", s);
3351   vat_json_print (vam->ofp, &node);
3352   vat_json_free (&node);
3353
3354   vec_free (s);
3355   vam->retval = ntohl (mp->retval);
3356   vam->result_ready = 1;
3357 }
3358
3359 static void
3360   vl_api_show_one_use_petr_reply_t_handler
3361   (vl_api_show_one_use_petr_reply_t * mp)
3362 {
3363   vat_main_t *vam = &vat_main;
3364   i32 retval = ntohl (mp->retval);
3365
3366   if (0 <= retval)
3367     {
3368       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
3369       if (mp->status)
3370         {
3371           print (vam->ofp, "Proxy-ETR address; %U",
3372                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
3373                  mp->address);
3374         }
3375     }
3376
3377   vam->retval = retval;
3378   vam->result_ready = 1;
3379 }
3380
3381 static void
3382   vl_api_show_one_use_petr_reply_t_handler_json
3383   (vl_api_show_one_use_petr_reply_t * mp)
3384 {
3385   vat_main_t *vam = &vat_main;
3386   vat_json_node_t node;
3387   u8 *status = 0;
3388   struct in_addr ip4;
3389   struct in6_addr ip6;
3390
3391   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3392   vec_add1 (status, 0);
3393
3394   vat_json_init_object (&node);
3395   vat_json_object_add_string_copy (&node, "status", status);
3396   if (mp->status)
3397     {
3398       if (mp->is_ip4)
3399         {
3400           clib_memcpy (&ip6, mp->address, sizeof (ip6));
3401           vat_json_object_add_ip6 (&node, "address", ip6);
3402         }
3403       else
3404         {
3405           clib_memcpy (&ip4, mp->address, sizeof (ip4));
3406           vat_json_object_add_ip4 (&node, "address", ip4);
3407         }
3408     }
3409
3410   vec_free (status);
3411
3412   vat_json_print (vam->ofp, &node);
3413   vat_json_free (&node);
3414
3415   vam->retval = ntohl (mp->retval);
3416   vam->result_ready = 1;
3417 }
3418
3419 static void
3420 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
3421 {
3422   vat_main_t *vam = &vat_main;
3423   i32 retval = ntohl (mp->retval);
3424
3425   if (0 <= retval)
3426     {
3427       print (vam->ofp, "%-20s%-16s",
3428              mp->status ? "enabled" : "disabled",
3429              mp->status ? (char *) mp->locator_set_name : "");
3430     }
3431
3432   vam->retval = retval;
3433   vam->result_ready = 1;
3434 }
3435
3436 static void
3437 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
3438 {
3439   vat_main_t *vam = &vat_main;
3440   vat_json_node_t node;
3441   u8 *status = 0;
3442
3443   status = format (0, "%s", mp->status ? "enabled" : "disabled");
3444   vec_add1 (status, 0);
3445
3446   vat_json_init_object (&node);
3447   vat_json_object_add_string_copy (&node, "status", status);
3448   if (mp->status)
3449     {
3450       vat_json_object_add_string_copy (&node, "locator_set",
3451                                        mp->locator_set_name);
3452     }
3453
3454   vec_free (status);
3455
3456   vat_json_print (vam->ofp, &node);
3457   vat_json_free (&node);
3458
3459   vam->retval = ntohl (mp->retval);
3460   vam->result_ready = 1;
3461 }
3462
3463 static u8 *
3464 format_policer_type (u8 * s, va_list * va)
3465 {
3466   u32 i = va_arg (*va, u32);
3467
3468   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
3469     s = format (s, "1r2c");
3470   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
3471     s = format (s, "1r3c");
3472   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
3473     s = format (s, "2r3c-2698");
3474   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
3475     s = format (s, "2r3c-4115");
3476   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
3477     s = format (s, "2r3c-mef5cf1");
3478   else
3479     s = format (s, "ILLEGAL");
3480   return s;
3481 }
3482
3483 static u8 *
3484 format_policer_rate_type (u8 * s, va_list * va)
3485 {
3486   u32 i = va_arg (*va, u32);
3487
3488   if (i == SSE2_QOS_RATE_KBPS)
3489     s = format (s, "kbps");
3490   else if (i == SSE2_QOS_RATE_PPS)
3491     s = format (s, "pps");
3492   else
3493     s = format (s, "ILLEGAL");
3494   return s;
3495 }
3496
3497 static u8 *
3498 format_policer_round_type (u8 * s, va_list * va)
3499 {
3500   u32 i = va_arg (*va, u32);
3501
3502   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3503     s = format (s, "closest");
3504   else if (i == SSE2_QOS_ROUND_TO_UP)
3505     s = format (s, "up");
3506   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3507     s = format (s, "down");
3508   else
3509     s = format (s, "ILLEGAL");
3510   return s;
3511 }
3512
3513 static u8 *
3514 format_policer_action_type (u8 * s, va_list * va)
3515 {
3516   u32 i = va_arg (*va, u32);
3517
3518   if (i == SSE2_QOS_ACTION_DROP)
3519     s = format (s, "drop");
3520   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3521     s = format (s, "transmit");
3522   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3523     s = format (s, "mark-and-transmit");
3524   else
3525     s = format (s, "ILLEGAL");
3526   return s;
3527 }
3528
3529 static u8 *
3530 format_dscp (u8 * s, va_list * va)
3531 {
3532   u32 i = va_arg (*va, u32);
3533   char *t = 0;
3534
3535   switch (i)
3536     {
3537 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3538       foreach_vnet_dscp
3539 #undef _
3540     default:
3541       return format (s, "ILLEGAL");
3542     }
3543   s = format (s, "%s", t);
3544   return s;
3545 }
3546
3547 static void
3548 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3549 {
3550   vat_main_t *vam = &vat_main;
3551   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3552
3553   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3554     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3555   else
3556     conform_dscp_str = format (0, "");
3557
3558   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3559     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3560   else
3561     exceed_dscp_str = format (0, "");
3562
3563   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3564     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3565   else
3566     violate_dscp_str = format (0, "");
3567
3568   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3569          "rate type %U, round type %U, %s rate, %s color-aware, "
3570          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3571          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3572          "conform action %U%s, exceed action %U%s, violate action %U%s",
3573          mp->name,
3574          format_policer_type, mp->type,
3575          ntohl (mp->cir),
3576          ntohl (mp->eir),
3577          clib_net_to_host_u64 (mp->cb),
3578          clib_net_to_host_u64 (mp->eb),
3579          format_policer_rate_type, mp->rate_type,
3580          format_policer_round_type, mp->round_type,
3581          mp->single_rate ? "single" : "dual",
3582          mp->color_aware ? "is" : "not",
3583          ntohl (mp->cir_tokens_per_period),
3584          ntohl (mp->pir_tokens_per_period),
3585          ntohl (mp->scale),
3586          ntohl (mp->current_limit),
3587          ntohl (mp->current_bucket),
3588          ntohl (mp->extended_limit),
3589          ntohl (mp->extended_bucket),
3590          clib_net_to_host_u64 (mp->last_update_time),
3591          format_policer_action_type, mp->conform_action_type,
3592          conform_dscp_str,
3593          format_policer_action_type, mp->exceed_action_type,
3594          exceed_dscp_str,
3595          format_policer_action_type, mp->violate_action_type,
3596          violate_dscp_str);
3597
3598   vec_free (conform_dscp_str);
3599   vec_free (exceed_dscp_str);
3600   vec_free (violate_dscp_str);
3601 }
3602
3603 static void vl_api_policer_details_t_handler_json
3604   (vl_api_policer_details_t * mp)
3605 {
3606   vat_main_t *vam = &vat_main;
3607   vat_json_node_t *node;
3608   u8 *rate_type_str, *round_type_str, *type_str;
3609   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3610
3611   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3612   round_type_str =
3613     format (0, "%U", format_policer_round_type, mp->round_type);
3614   type_str = format (0, "%U", format_policer_type, mp->type);
3615   conform_action_str = format (0, "%U", format_policer_action_type,
3616                                mp->conform_action_type);
3617   exceed_action_str = format (0, "%U", format_policer_action_type,
3618                               mp->exceed_action_type);
3619   violate_action_str = format (0, "%U", format_policer_action_type,
3620                                mp->violate_action_type);
3621
3622   if (VAT_JSON_ARRAY != vam->json_tree.type)
3623     {
3624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3625       vat_json_init_array (&vam->json_tree);
3626     }
3627   node = vat_json_array_add (&vam->json_tree);
3628
3629   vat_json_init_object (node);
3630   vat_json_object_add_string_copy (node, "name", mp->name);
3631   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3632   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3633   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3634   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3635   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3636   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3637   vat_json_object_add_string_copy (node, "type", type_str);
3638   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3639   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3640   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3641   vat_json_object_add_uint (node, "cir_tokens_per_period",
3642                             ntohl (mp->cir_tokens_per_period));
3643   vat_json_object_add_uint (node, "eir_tokens_per_period",
3644                             ntohl (mp->pir_tokens_per_period));
3645   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3646   vat_json_object_add_uint (node, "current_bucket",
3647                             ntohl (mp->current_bucket));
3648   vat_json_object_add_uint (node, "extended_limit",
3649                             ntohl (mp->extended_limit));
3650   vat_json_object_add_uint (node, "extended_bucket",
3651                             ntohl (mp->extended_bucket));
3652   vat_json_object_add_uint (node, "last_update_time",
3653                             ntohl (mp->last_update_time));
3654   vat_json_object_add_string_copy (node, "conform_action",
3655                                    conform_action_str);
3656   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3657     {
3658       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3659       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3660       vec_free (dscp_str);
3661     }
3662   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3663   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3664     {
3665       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3666       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3667       vec_free (dscp_str);
3668     }
3669   vat_json_object_add_string_copy (node, "violate_action",
3670                                    violate_action_str);
3671   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3672     {
3673       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3674       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3675       vec_free (dscp_str);
3676     }
3677
3678   vec_free (rate_type_str);
3679   vec_free (round_type_str);
3680   vec_free (type_str);
3681   vec_free (conform_action_str);
3682   vec_free (exceed_action_str);
3683   vec_free (violate_action_str);
3684 }
3685
3686 static void
3687 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3688                                            mp)
3689 {
3690   vat_main_t *vam = &vat_main;
3691   int i, count = ntohl (mp->count);
3692
3693   if (count > 0)
3694     print (vam->ofp, "classify table ids (%d) : ", count);
3695   for (i = 0; i < count; i++)
3696     {
3697       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3698       print (vam->ofp, (i < count - 1) ? "," : "");
3699     }
3700   vam->retval = ntohl (mp->retval);
3701   vam->result_ready = 1;
3702 }
3703
3704 static void
3705   vl_api_classify_table_ids_reply_t_handler_json
3706   (vl_api_classify_table_ids_reply_t * mp)
3707 {
3708   vat_main_t *vam = &vat_main;
3709   int i, count = ntohl (mp->count);
3710
3711   if (count > 0)
3712     {
3713       vat_json_node_t node;
3714
3715       vat_json_init_object (&node);
3716       for (i = 0; i < count; i++)
3717         {
3718           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3719         }
3720       vat_json_print (vam->ofp, &node);
3721       vat_json_free (&node);
3722     }
3723   vam->retval = ntohl (mp->retval);
3724   vam->result_ready = 1;
3725 }
3726
3727 static void
3728   vl_api_classify_table_by_interface_reply_t_handler
3729   (vl_api_classify_table_by_interface_reply_t * mp)
3730 {
3731   vat_main_t *vam = &vat_main;
3732   u32 table_id;
3733
3734   table_id = ntohl (mp->l2_table_id);
3735   if (table_id != ~0)
3736     print (vam->ofp, "l2 table id : %d", table_id);
3737   else
3738     print (vam->ofp, "l2 table id : No input ACL tables configured");
3739   table_id = ntohl (mp->ip4_table_id);
3740   if (table_id != ~0)
3741     print (vam->ofp, "ip4 table id : %d", table_id);
3742   else
3743     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3744   table_id = ntohl (mp->ip6_table_id);
3745   if (table_id != ~0)
3746     print (vam->ofp, "ip6 table id : %d", table_id);
3747   else
3748     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3749   vam->retval = ntohl (mp->retval);
3750   vam->result_ready = 1;
3751 }
3752
3753 static void
3754   vl_api_classify_table_by_interface_reply_t_handler_json
3755   (vl_api_classify_table_by_interface_reply_t * mp)
3756 {
3757   vat_main_t *vam = &vat_main;
3758   vat_json_node_t node;
3759
3760   vat_json_init_object (&node);
3761
3762   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3763   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3764   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3765
3766   vat_json_print (vam->ofp, &node);
3767   vat_json_free (&node);
3768
3769   vam->retval = ntohl (mp->retval);
3770   vam->result_ready = 1;
3771 }
3772
3773 static void vl_api_policer_add_del_reply_t_handler
3774   (vl_api_policer_add_del_reply_t * mp)
3775 {
3776   vat_main_t *vam = &vat_main;
3777   i32 retval = ntohl (mp->retval);
3778   if (vam->async_mode)
3779     {
3780       vam->async_errors += (retval < 0);
3781     }
3782   else
3783     {
3784       vam->retval = retval;
3785       vam->result_ready = 1;
3786       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3787         /*
3788          * Note: this is just barely thread-safe, depends on
3789          * the main thread spinning waiting for an answer...
3790          */
3791         errmsg ("policer index %d", ntohl (mp->policer_index));
3792     }
3793 }
3794
3795 static void vl_api_policer_add_del_reply_t_handler_json
3796   (vl_api_policer_add_del_reply_t * mp)
3797 {
3798   vat_main_t *vam = &vat_main;
3799   vat_json_node_t node;
3800
3801   vat_json_init_object (&node);
3802   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3803   vat_json_object_add_uint (&node, "policer_index",
3804                             ntohl (mp->policer_index));
3805
3806   vat_json_print (vam->ofp, &node);
3807   vat_json_free (&node);
3808
3809   vam->retval = ntohl (mp->retval);
3810   vam->result_ready = 1;
3811 }
3812
3813 /* Format hex dump. */
3814 u8 *
3815 format_hex_bytes (u8 * s, va_list * va)
3816 {
3817   u8 *bytes = va_arg (*va, u8 *);
3818   int n_bytes = va_arg (*va, int);
3819   uword i;
3820
3821   /* Print short or long form depending on byte count. */
3822   uword short_form = n_bytes <= 32;
3823   uword indent = format_get_indent (s);
3824
3825   if (n_bytes == 0)
3826     return s;
3827
3828   for (i = 0; i < n_bytes; i++)
3829     {
3830       if (!short_form && (i % 32) == 0)
3831         s = format (s, "%08x: ", i);
3832       s = format (s, "%02x", bytes[i]);
3833       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3834         s = format (s, "\n%U", format_white_space, indent);
3835     }
3836
3837   return s;
3838 }
3839
3840 static void
3841 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3842                                             * mp)
3843 {
3844   vat_main_t *vam = &vat_main;
3845   i32 retval = ntohl (mp->retval);
3846   if (retval == 0)
3847     {
3848       print (vam->ofp, "classify table info :");
3849       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3850              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3851              ntohl (mp->miss_next_index));
3852       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3853              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3854              ntohl (mp->match_n_vectors));
3855       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3856              ntohl (mp->mask_length));
3857     }
3858   vam->retval = retval;
3859   vam->result_ready = 1;
3860 }
3861
3862 static void
3863   vl_api_classify_table_info_reply_t_handler_json
3864   (vl_api_classify_table_info_reply_t * mp)
3865 {
3866   vat_main_t *vam = &vat_main;
3867   vat_json_node_t node;
3868
3869   i32 retval = ntohl (mp->retval);
3870   if (retval == 0)
3871     {
3872       vat_json_init_object (&node);
3873
3874       vat_json_object_add_int (&node, "sessions",
3875                                ntohl (mp->active_sessions));
3876       vat_json_object_add_int (&node, "nexttbl",
3877                                ntohl (mp->next_table_index));
3878       vat_json_object_add_int (&node, "nextnode",
3879                                ntohl (mp->miss_next_index));
3880       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3881       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3882       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3883       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3884                       ntohl (mp->mask_length), 0);
3885       vat_json_object_add_string_copy (&node, "mask", s);
3886
3887       vat_json_print (vam->ofp, &node);
3888       vat_json_free (&node);
3889     }
3890   vam->retval = ntohl (mp->retval);
3891   vam->result_ready = 1;
3892 }
3893
3894 static void
3895 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3896                                            mp)
3897 {
3898   vat_main_t *vam = &vat_main;
3899
3900   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3901          ntohl (mp->hit_next_index), ntohl (mp->advance),
3902          ntohl (mp->opaque_index));
3903   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3904          ntohl (mp->match_length));
3905 }
3906
3907 static void
3908   vl_api_classify_session_details_t_handler_json
3909   (vl_api_classify_session_details_t * mp)
3910 {
3911   vat_main_t *vam = &vat_main;
3912   vat_json_node_t *node = NULL;
3913
3914   if (VAT_JSON_ARRAY != vam->json_tree.type)
3915     {
3916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3917       vat_json_init_array (&vam->json_tree);
3918     }
3919   node = vat_json_array_add (&vam->json_tree);
3920
3921   vat_json_init_object (node);
3922   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3923   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3924   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3925   u8 *s =
3926     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3927             0);
3928   vat_json_object_add_string_copy (node, "match", s);
3929 }
3930
3931 static void vl_api_pg_create_interface_reply_t_handler
3932   (vl_api_pg_create_interface_reply_t * mp)
3933 {
3934   vat_main_t *vam = &vat_main;
3935
3936   vam->retval = ntohl (mp->retval);
3937   vam->result_ready = 1;
3938 }
3939
3940 static void vl_api_pg_create_interface_reply_t_handler_json
3941   (vl_api_pg_create_interface_reply_t * mp)
3942 {
3943   vat_main_t *vam = &vat_main;
3944   vat_json_node_t node;
3945
3946   i32 retval = ntohl (mp->retval);
3947   if (retval == 0)
3948     {
3949       vat_json_init_object (&node);
3950
3951       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3952
3953       vat_json_print (vam->ofp, &node);
3954       vat_json_free (&node);
3955     }
3956   vam->retval = ntohl (mp->retval);
3957   vam->result_ready = 1;
3958 }
3959
3960 static void vl_api_policer_classify_details_t_handler
3961   (vl_api_policer_classify_details_t * mp)
3962 {
3963   vat_main_t *vam = &vat_main;
3964
3965   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3966          ntohl (mp->table_index));
3967 }
3968
3969 static void vl_api_policer_classify_details_t_handler_json
3970   (vl_api_policer_classify_details_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   vat_json_node_t *node;
3974
3975   if (VAT_JSON_ARRAY != vam->json_tree.type)
3976     {
3977       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3978       vat_json_init_array (&vam->json_tree);
3979     }
3980   node = vat_json_array_add (&vam->json_tree);
3981
3982   vat_json_init_object (node);
3983   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3984   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3985 }
3986
3987 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3988   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3989 {
3990   vat_main_t *vam = &vat_main;
3991   i32 retval = ntohl (mp->retval);
3992   if (vam->async_mode)
3993     {
3994       vam->async_errors += (retval < 0);
3995     }
3996   else
3997     {
3998       vam->retval = retval;
3999       vam->sw_if_index = ntohl (mp->sw_if_index);
4000       vam->result_ready = 1;
4001     }
4002 }
4003
4004 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4005   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4006 {
4007   vat_main_t *vam = &vat_main;
4008   vat_json_node_t node;
4009
4010   vat_json_init_object (&node);
4011   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4012   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4013
4014   vat_json_print (vam->ofp, &node);
4015   vat_json_free (&node);
4016
4017   vam->retval = ntohl (mp->retval);
4018   vam->result_ready = 1;
4019 }
4020
4021 static void vl_api_flow_classify_details_t_handler
4022   (vl_api_flow_classify_details_t * mp)
4023 {
4024   vat_main_t *vam = &vat_main;
4025
4026   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4027          ntohl (mp->table_index));
4028 }
4029
4030 static void vl_api_flow_classify_details_t_handler_json
4031   (vl_api_flow_classify_details_t * mp)
4032 {
4033   vat_main_t *vam = &vat_main;
4034   vat_json_node_t *node;
4035
4036   if (VAT_JSON_ARRAY != vam->json_tree.type)
4037     {
4038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4039       vat_json_init_array (&vam->json_tree);
4040     }
4041   node = vat_json_array_add (&vam->json_tree);
4042
4043   vat_json_init_object (node);
4044   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4045   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4046 }
4047
4048
4049
4050 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4051 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4052 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4053 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4054 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4055 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4056 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4057 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4058 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4059 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4060
4061 /*
4062  * Generate boilerplate reply handlers, which
4063  * dig the return value out of the xxx_reply_t API message,
4064  * stick it into vam->retval, and set vam->result_ready
4065  *
4066  * Could also do this by pointing N message decode slots at
4067  * a single function, but that could break in subtle ways.
4068  */
4069
4070 #define foreach_standard_reply_retval_handler           \
4071 _(sw_interface_set_flags_reply)                         \
4072 _(sw_interface_add_del_address_reply)                   \
4073 _(sw_interface_set_table_reply)                         \
4074 _(sw_interface_set_mpls_enable_reply)                   \
4075 _(sw_interface_set_vpath_reply)                         \
4076 _(sw_interface_set_vxlan_bypass_reply)                  \
4077 _(sw_interface_set_l2_bridge_reply)                     \
4078 _(bridge_domain_add_del_reply)                          \
4079 _(sw_interface_set_l2_xconnect_reply)                   \
4080 _(l2fib_add_del_reply)                                  \
4081 _(ip_add_del_route_reply)                               \
4082 _(ip_mroute_add_del_reply)                              \
4083 _(mpls_route_add_del_reply)                             \
4084 _(mpls_ip_bind_unbind_reply)                            \
4085 _(proxy_arp_add_del_reply)                              \
4086 _(proxy_arp_intfc_enable_disable_reply)                 \
4087 _(sw_interface_set_unnumbered_reply)                    \
4088 _(ip_neighbor_add_del_reply)                            \
4089 _(reset_vrf_reply)                                      \
4090 _(oam_add_del_reply)                                    \
4091 _(reset_fib_reply)                                      \
4092 _(dhcp_proxy_config_reply)                              \
4093 _(dhcp_proxy_set_vss_reply)                             \
4094 _(dhcp_client_config_reply)                             \
4095 _(set_ip_flow_hash_reply)                               \
4096 _(sw_interface_ip6_enable_disable_reply)                \
4097 _(sw_interface_ip6_set_link_local_address_reply)        \
4098 _(ip6nd_proxy_add_del_reply)                            \
4099 _(sw_interface_ip6nd_ra_prefix_reply)                   \
4100 _(sw_interface_ip6nd_ra_config_reply)                   \
4101 _(set_arp_neighbor_limit_reply)                         \
4102 _(l2_patch_add_del_reply)                               \
4103 _(sr_policy_add_reply)                                  \
4104 _(sr_policy_mod_reply)                                  \
4105 _(sr_policy_del_reply)                                  \
4106 _(sr_localsid_add_del_reply)                            \
4107 _(sr_steering_add_del_reply)                            \
4108 _(classify_add_del_session_reply)                       \
4109 _(classify_set_interface_ip_table_reply)                \
4110 _(classify_set_interface_l2_tables_reply)               \
4111 _(l2tpv3_set_tunnel_cookies_reply)                      \
4112 _(l2tpv3_interface_enable_disable_reply)                \
4113 _(l2tpv3_set_lookup_key_reply)                          \
4114 _(l2_fib_clear_table_reply)                             \
4115 _(l2_interface_efp_filter_reply)                        \
4116 _(l2_interface_vlan_tag_rewrite_reply)                  \
4117 _(modify_vhost_user_if_reply)                           \
4118 _(delete_vhost_user_if_reply)                           \
4119 _(want_ip4_arp_events_reply)                            \
4120 _(want_ip6_nd_events_reply)                             \
4121 _(input_acl_set_interface_reply)                        \
4122 _(ipsec_spd_add_del_reply)                              \
4123 _(ipsec_interface_add_del_spd_reply)                    \
4124 _(ipsec_spd_add_del_entry_reply)                        \
4125 _(ipsec_sad_add_del_entry_reply)                        \
4126 _(ipsec_sa_set_key_reply)                               \
4127 _(ikev2_profile_add_del_reply)                          \
4128 _(ikev2_profile_set_auth_reply)                         \
4129 _(ikev2_profile_set_id_reply)                           \
4130 _(ikev2_profile_set_ts_reply)                           \
4131 _(ikev2_set_local_key_reply)                            \
4132 _(ikev2_set_responder_reply)                            \
4133 _(ikev2_set_ike_transforms_reply)                       \
4134 _(ikev2_set_esp_transforms_reply)                       \
4135 _(ikev2_set_sa_lifetime_reply)                          \
4136 _(ikev2_initiate_sa_init_reply)                         \
4137 _(ikev2_initiate_del_ike_sa_reply)                      \
4138 _(ikev2_initiate_del_child_sa_reply)                    \
4139 _(ikev2_initiate_rekey_child_sa_reply)                  \
4140 _(delete_loopback_reply)                                \
4141 _(bd_ip_mac_add_del_reply)                              \
4142 _(map_del_domain_reply)                                 \
4143 _(map_add_del_rule_reply)                               \
4144 _(want_interface_events_reply)                          \
4145 _(want_stats_reply)                                     \
4146 _(cop_interface_enable_disable_reply)                   \
4147 _(cop_whitelist_enable_disable_reply)                   \
4148 _(sw_interface_clear_stats_reply)                       \
4149 _(ioam_enable_reply)                              \
4150 _(ioam_disable_reply)                              \
4151 _(one_add_del_locator_reply)                            \
4152 _(one_add_del_local_eid_reply)                          \
4153 _(one_add_del_remote_mapping_reply)                     \
4154 _(one_add_del_adjacency_reply)                          \
4155 _(one_add_del_map_resolver_reply)                       \
4156 _(one_add_del_map_server_reply)                         \
4157 _(one_enable_disable_reply)                             \
4158 _(one_rloc_probe_enable_disable_reply)                  \
4159 _(one_map_register_enable_disable_reply)                \
4160 _(one_pitr_set_locator_set_reply)                       \
4161 _(one_map_request_mode_reply)                           \
4162 _(one_add_del_map_request_itr_rlocs_reply)              \
4163 _(one_eid_table_add_del_map_reply)                      \
4164 _(one_use_petr_reply)                                   \
4165 _(one_stats_enable_disable_reply)                       \
4166 _(gpe_add_del_fwd_entry_reply)                          \
4167 _(gpe_enable_disable_reply)                             \
4168 _(gpe_set_encap_mode_reply)                             \
4169 _(gpe_add_del_iface_reply)                              \
4170 _(vxlan_gpe_add_del_tunnel_reply)                       \
4171 _(af_packet_delete_reply)                               \
4172 _(policer_classify_set_interface_reply)                 \
4173 _(netmap_create_reply)                                  \
4174 _(netmap_delete_reply)                                  \
4175 _(set_ipfix_exporter_reply)                             \
4176 _(set_ipfix_classify_stream_reply)                      \
4177 _(ipfix_classify_table_add_del_reply)                   \
4178 _(flow_classify_set_interface_reply)                    \
4179 _(sw_interface_span_enable_disable_reply)               \
4180 _(pg_capture_reply)                                     \
4181 _(pg_enable_disable_reply)                              \
4182 _(ip_source_and_port_range_check_add_del_reply)         \
4183 _(ip_source_and_port_range_check_interface_add_del_reply)\
4184 _(delete_subif_reply)                                   \
4185 _(l2_interface_pbb_tag_rewrite_reply)                   \
4186 _(punt_reply)                                           \
4187 _(feature_enable_disable_reply)                         \
4188 _(sw_interface_tag_add_del_reply)                       \
4189 _(sw_interface_set_mtu_reply)
4190
4191 #define _(n)                                    \
4192     static void vl_api_##n##_t_handler          \
4193     (vl_api_##n##_t * mp)                       \
4194     {                                           \
4195         vat_main_t * vam = &vat_main;           \
4196         i32 retval = ntohl(mp->retval);         \
4197         if (vam->async_mode) {                  \
4198             vam->async_errors += (retval < 0);  \
4199         } else {                                \
4200             vam->retval = retval;               \
4201             vam->result_ready = 1;              \
4202         }                                       \
4203     }
4204 foreach_standard_reply_retval_handler;
4205 #undef _
4206
4207 #define _(n)                                    \
4208     static void vl_api_##n##_t_handler_json     \
4209     (vl_api_##n##_t * mp)                       \
4210     {                                           \
4211         vat_main_t * vam = &vat_main;           \
4212         vat_json_node_t node;                   \
4213         vat_json_init_object(&node);            \
4214         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
4215         vat_json_print(vam->ofp, &node);        \
4216         vam->retval = ntohl(mp->retval);        \
4217         vam->result_ready = 1;                  \
4218     }
4219 foreach_standard_reply_retval_handler;
4220 #undef _
4221
4222 /*
4223  * Table of message reply handlers, must include boilerplate handlers
4224  * we just generated
4225  */
4226
4227 #define foreach_vpe_api_reply_msg                                       \
4228 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
4229 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
4230 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
4231 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
4232 _(CONTROL_PING_REPLY, control_ping_reply)                               \
4233 _(CLI_REPLY, cli_reply)                                                 \
4234 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
4235 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
4236   sw_interface_add_del_address_reply)                                   \
4237 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
4238 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
4239 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
4240 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
4241 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
4242   sw_interface_set_l2_xconnect_reply)                                   \
4243 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
4244   sw_interface_set_l2_bridge_reply)                                     \
4245 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
4246 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
4247 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
4248 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
4249 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
4250 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
4251 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
4252 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
4253 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
4254 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
4255 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
4256 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
4257 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
4258 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
4259 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
4260 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
4261   proxy_arp_intfc_enable_disable_reply)                                 \
4262 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
4263 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
4264   sw_interface_set_unnumbered_reply)                                    \
4265 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
4266 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
4267 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
4268 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
4269 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
4270 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
4271 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
4272 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
4273 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
4274 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
4275 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
4276 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
4277   sw_interface_ip6_enable_disable_reply)                                \
4278 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
4279   sw_interface_ip6_set_link_local_address_reply)                        \
4280 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
4281 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
4282 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
4283   sw_interface_ip6nd_ra_prefix_reply)                                   \
4284 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
4285   sw_interface_ip6nd_ra_config_reply)                                   \
4286 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
4287 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
4288 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
4289 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
4290 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
4291 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
4292 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
4293 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
4294 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
4295 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
4296 classify_set_interface_ip_table_reply)                                  \
4297 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
4298   classify_set_interface_l2_tables_reply)                               \
4299 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
4300 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
4301 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
4302 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
4303 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
4304   l2tpv3_interface_enable_disable_reply)                                \
4305 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
4306 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
4307 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
4308 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
4309 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
4310 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
4311 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
4312 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
4313 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
4314 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
4315 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
4316 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
4317 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
4318 _(SHOW_VERSION_REPLY, show_version_reply)                               \
4319 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
4320 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
4321 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
4322 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
4323 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
4324 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
4325 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
4326 _(IP6_ND_EVENT, ip6_nd_event)                                           \
4327 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
4328 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
4329 _(IP_DETAILS, ip_details)                                               \
4330 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
4331 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
4332 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
4333 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
4334 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
4335 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
4336 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
4337 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
4338 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
4339 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
4340 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
4341 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
4342 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
4343 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
4344 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
4345 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
4346 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
4347 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
4348 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
4349 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
4350 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
4351 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
4352 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
4353 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
4354 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
4355 _(MAP_RULE_DETAILS, map_rule_details)                                   \
4356 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
4357 _(WANT_STATS_REPLY, want_stats_reply)                                   \
4358 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
4359 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
4360 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
4361 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
4362 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
4363 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
4364 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
4365 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
4366 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
4367 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
4368 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
4369 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
4370 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
4371 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
4372 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
4373 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
4374   one_map_register_enable_disable_reply)                                \
4375 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
4376   one_rloc_probe_enable_disable_reply)                                  \
4377 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
4378 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
4379 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
4380 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
4381 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
4382 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
4383 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
4384 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
4385 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
4386 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
4387 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
4388 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
4389 _(ONE_STATS_DETAILS, one_stats_details)                                 \
4390 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
4391 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
4392   show_one_stats_enable_disable_reply)                                  \
4393 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
4394 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
4395 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
4396 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
4397 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
4398 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
4399 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
4400   gpe_fwd_entry_path_details)                                           \
4401 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
4402 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
4403   one_add_del_map_request_itr_rlocs_reply)                              \
4404 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
4405   one_get_map_request_itr_rlocs_reply)                                  \
4406 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
4407 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
4408 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
4409 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
4410 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
4411   show_one_map_register_state_reply)                                    \
4412 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
4413 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
4414 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
4415 _(POLICER_DETAILS, policer_details)                                     \
4416 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
4417 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
4418 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
4419 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
4420 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
4421 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
4422 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
4423 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
4424 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
4425 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
4426 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
4427 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
4428 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
4429 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
4430 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
4431 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
4432 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
4433 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
4434 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
4435 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
4436 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
4437 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
4438 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
4439 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
4440 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
4441  ip_source_and_port_range_check_add_del_reply)                          \
4442 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
4443  ip_source_and_port_range_check_interface_add_del_reply)                \
4444 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
4445 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
4446 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
4447 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
4448 _(PUNT_REPLY, punt_reply)                                               \
4449 _(IP_FIB_DETAILS, ip_fib_details)                                       \
4450 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
4451 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
4452 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
4453 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
4454 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
4455 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
4456 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
4457
4458 #define foreach_standalone_reply_msg                                    \
4459 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
4460 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
4461 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
4462 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
4463 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
4464 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)
4465
4466 typedef struct
4467 {
4468   u8 *name;
4469   u32 value;
4470 } name_sort_t;
4471
4472
4473 #define STR_VTR_OP_CASE(op)     \
4474     case L2_VTR_ ## op:         \
4475         return "" # op;
4476
4477 static const char *
4478 str_vtr_op (u32 vtr_op)
4479 {
4480   switch (vtr_op)
4481     {
4482       STR_VTR_OP_CASE (DISABLED);
4483       STR_VTR_OP_CASE (PUSH_1);
4484       STR_VTR_OP_CASE (PUSH_2);
4485       STR_VTR_OP_CASE (POP_1);
4486       STR_VTR_OP_CASE (POP_2);
4487       STR_VTR_OP_CASE (TRANSLATE_1_1);
4488       STR_VTR_OP_CASE (TRANSLATE_1_2);
4489       STR_VTR_OP_CASE (TRANSLATE_2_1);
4490       STR_VTR_OP_CASE (TRANSLATE_2_2);
4491     }
4492
4493   return "UNKNOWN";
4494 }
4495
4496 static int
4497 dump_sub_interface_table (vat_main_t * vam)
4498 {
4499   const sw_interface_subif_t *sub = NULL;
4500
4501   if (vam->json_output)
4502     {
4503       clib_warning
4504         ("JSON output supported only for VPE API calls and dump_stats_table");
4505       return -99;
4506     }
4507
4508   print (vam->ofp,
4509          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4510          "Interface", "sw_if_index",
4511          "sub id", "dot1ad", "tags", "outer id",
4512          "inner id", "exact", "default", "outer any", "inner any");
4513
4514   vec_foreach (sub, vam->sw_if_subif_table)
4515   {
4516     print (vam->ofp,
4517            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4518            sub->interface_name,
4519            sub->sw_if_index,
4520            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4521            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4522            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4523            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4524     if (sub->vtr_op != L2_VTR_DISABLED)
4525       {
4526         print (vam->ofp,
4527                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4528                "tag1: %d tag2: %d ]",
4529                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4530                sub->vtr_tag1, sub->vtr_tag2);
4531       }
4532   }
4533
4534   return 0;
4535 }
4536
4537 static int
4538 name_sort_cmp (void *a1, void *a2)
4539 {
4540   name_sort_t *n1 = a1;
4541   name_sort_t *n2 = a2;
4542
4543   return strcmp ((char *) n1->name, (char *) n2->name);
4544 }
4545
4546 static int
4547 dump_interface_table (vat_main_t * vam)
4548 {
4549   hash_pair_t *p;
4550   name_sort_t *nses = 0, *ns;
4551
4552   if (vam->json_output)
4553     {
4554       clib_warning
4555         ("JSON output supported only for VPE API calls and dump_stats_table");
4556       return -99;
4557     }
4558
4559   /* *INDENT-OFF* */
4560   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4561   ({
4562     vec_add2 (nses, ns, 1);
4563     ns->name = (u8 *)(p->key);
4564     ns->value = (u32) p->value[0];
4565   }));
4566   /* *INDENT-ON* */
4567
4568   vec_sort_with_function (nses, name_sort_cmp);
4569
4570   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4571   vec_foreach (ns, nses)
4572   {
4573     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4574   }
4575   vec_free (nses);
4576   return 0;
4577 }
4578
4579 static int
4580 dump_ip_table (vat_main_t * vam, int is_ipv6)
4581 {
4582   const ip_details_t *det = NULL;
4583   const ip_address_details_t *address = NULL;
4584   u32 i = ~0;
4585
4586   print (vam->ofp, "%-12s", "sw_if_index");
4587
4588   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4589   {
4590     i++;
4591     if (!det->present)
4592       {
4593         continue;
4594       }
4595     print (vam->ofp, "%-12d", i);
4596     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4597     if (!det->addr)
4598       {
4599         continue;
4600       }
4601     vec_foreach (address, det->addr)
4602     {
4603       print (vam->ofp,
4604              "            %-30U%-13d",
4605              is_ipv6 ? format_ip6_address : format_ip4_address,
4606              address->ip, address->prefix_length);
4607     }
4608   }
4609
4610   return 0;
4611 }
4612
4613 static int
4614 dump_ipv4_table (vat_main_t * vam)
4615 {
4616   if (vam->json_output)
4617     {
4618       clib_warning
4619         ("JSON output supported only for VPE API calls and dump_stats_table");
4620       return -99;
4621     }
4622
4623   return dump_ip_table (vam, 0);
4624 }
4625
4626 static int
4627 dump_ipv6_table (vat_main_t * vam)
4628 {
4629   if (vam->json_output)
4630     {
4631       clib_warning
4632         ("JSON output supported only for VPE API calls and dump_stats_table");
4633       return -99;
4634     }
4635
4636   return dump_ip_table (vam, 1);
4637 }
4638
4639 static char *
4640 counter_type_to_str (u8 counter_type, u8 is_combined)
4641 {
4642   if (!is_combined)
4643     {
4644       switch (counter_type)
4645         {
4646         case VNET_INTERFACE_COUNTER_DROP:
4647           return "drop";
4648         case VNET_INTERFACE_COUNTER_PUNT:
4649           return "punt";
4650         case VNET_INTERFACE_COUNTER_IP4:
4651           return "ip4";
4652         case VNET_INTERFACE_COUNTER_IP6:
4653           return "ip6";
4654         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4655           return "rx-no-buf";
4656         case VNET_INTERFACE_COUNTER_RX_MISS:
4657           return "rx-miss";
4658         case VNET_INTERFACE_COUNTER_RX_ERROR:
4659           return "rx-error";
4660         case VNET_INTERFACE_COUNTER_TX_ERROR:
4661           return "tx-error";
4662         default:
4663           return "INVALID-COUNTER-TYPE";
4664         }
4665     }
4666   else
4667     {
4668       switch (counter_type)
4669         {
4670         case VNET_INTERFACE_COUNTER_RX:
4671           return "rx";
4672         case VNET_INTERFACE_COUNTER_TX:
4673           return "tx";
4674         default:
4675           return "INVALID-COUNTER-TYPE";
4676         }
4677     }
4678 }
4679
4680 static int
4681 dump_stats_table (vat_main_t * vam)
4682 {
4683   vat_json_node_t node;
4684   vat_json_node_t *msg_array;
4685   vat_json_node_t *msg;
4686   vat_json_node_t *counter_array;
4687   vat_json_node_t *counter;
4688   interface_counter_t c;
4689   u64 packets;
4690   ip4_fib_counter_t *c4;
4691   ip6_fib_counter_t *c6;
4692   ip4_nbr_counter_t *n4;
4693   ip6_nbr_counter_t *n6;
4694   int i, j;
4695
4696   if (!vam->json_output)
4697     {
4698       clib_warning ("dump_stats_table supported only in JSON format");
4699       return -99;
4700     }
4701
4702   vat_json_init_object (&node);
4703
4704   /* interface counters */
4705   msg_array = vat_json_object_add (&node, "interface_counters");
4706   vat_json_init_array (msg_array);
4707   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4708     {
4709       msg = vat_json_array_add (msg_array);
4710       vat_json_init_object (msg);
4711       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4712                                        (u8 *) counter_type_to_str (i, 0));
4713       vat_json_object_add_int (msg, "is_combined", 0);
4714       counter_array = vat_json_object_add (msg, "data");
4715       vat_json_init_array (counter_array);
4716       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4717         {
4718           packets = vam->simple_interface_counters[i][j];
4719           vat_json_array_add_uint (counter_array, packets);
4720         }
4721     }
4722   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4723     {
4724       msg = vat_json_array_add (msg_array);
4725       vat_json_init_object (msg);
4726       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4727                                        (u8 *) counter_type_to_str (i, 1));
4728       vat_json_object_add_int (msg, "is_combined", 1);
4729       counter_array = vat_json_object_add (msg, "data");
4730       vat_json_init_array (counter_array);
4731       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4732         {
4733           c = vam->combined_interface_counters[i][j];
4734           counter = vat_json_array_add (counter_array);
4735           vat_json_init_object (counter);
4736           vat_json_object_add_uint (counter, "packets", c.packets);
4737           vat_json_object_add_uint (counter, "bytes", c.bytes);
4738         }
4739     }
4740
4741   /* ip4 fib counters */
4742   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4743   vat_json_init_array (msg_array);
4744   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4745     {
4746       msg = vat_json_array_add (msg_array);
4747       vat_json_init_object (msg);
4748       vat_json_object_add_uint (msg, "vrf_id",
4749                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4750       counter_array = vat_json_object_add (msg, "c");
4751       vat_json_init_array (counter_array);
4752       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4753         {
4754           counter = vat_json_array_add (counter_array);
4755           vat_json_init_object (counter);
4756           c4 = &vam->ip4_fib_counters[i][j];
4757           vat_json_object_add_ip4 (counter, "address", c4->address);
4758           vat_json_object_add_uint (counter, "address_length",
4759                                     c4->address_length);
4760           vat_json_object_add_uint (counter, "packets", c4->packets);
4761           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4762         }
4763     }
4764
4765   /* ip6 fib counters */
4766   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4767   vat_json_init_array (msg_array);
4768   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4769     {
4770       msg = vat_json_array_add (msg_array);
4771       vat_json_init_object (msg);
4772       vat_json_object_add_uint (msg, "vrf_id",
4773                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4774       counter_array = vat_json_object_add (msg, "c");
4775       vat_json_init_array (counter_array);
4776       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4777         {
4778           counter = vat_json_array_add (counter_array);
4779           vat_json_init_object (counter);
4780           c6 = &vam->ip6_fib_counters[i][j];
4781           vat_json_object_add_ip6 (counter, "address", c6->address);
4782           vat_json_object_add_uint (counter, "address_length",
4783                                     c6->address_length);
4784           vat_json_object_add_uint (counter, "packets", c6->packets);
4785           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4786         }
4787     }
4788
4789   /* ip4 nbr counters */
4790   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4791   vat_json_init_array (msg_array);
4792   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4793     {
4794       msg = vat_json_array_add (msg_array);
4795       vat_json_init_object (msg);
4796       vat_json_object_add_uint (msg, "sw_if_index", i);
4797       counter_array = vat_json_object_add (msg, "c");
4798       vat_json_init_array (counter_array);
4799       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4800         {
4801           counter = vat_json_array_add (counter_array);
4802           vat_json_init_object (counter);
4803           n4 = &vam->ip4_nbr_counters[i][j];
4804           vat_json_object_add_ip4 (counter, "address", n4->address);
4805           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4806           vat_json_object_add_uint (counter, "packets", n4->packets);
4807           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4808         }
4809     }
4810
4811   /* ip6 nbr counters */
4812   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4813   vat_json_init_array (msg_array);
4814   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4815     {
4816       msg = vat_json_array_add (msg_array);
4817       vat_json_init_object (msg);
4818       vat_json_object_add_uint (msg, "sw_if_index", i);
4819       counter_array = vat_json_object_add (msg, "c");
4820       vat_json_init_array (counter_array);
4821       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4822         {
4823           counter = vat_json_array_add (counter_array);
4824           vat_json_init_object (counter);
4825           n6 = &vam->ip6_nbr_counters[i][j];
4826           vat_json_object_add_ip6 (counter, "address", n6->address);
4827           vat_json_object_add_uint (counter, "packets", n6->packets);
4828           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4829         }
4830     }
4831
4832   vat_json_print (vam->ofp, &node);
4833   vat_json_free (&node);
4834
4835   return 0;
4836 }
4837
4838 int
4839 exec (vat_main_t * vam)
4840 {
4841   api_main_t *am = &api_main;
4842   vl_api_cli_request_t *mp;
4843   f64 timeout;
4844   void *oldheap;
4845   u8 *cmd = 0;
4846   unformat_input_t *i = vam->input;
4847
4848   if (vec_len (i->buffer) == 0)
4849     return -1;
4850
4851   if (vam->exec_mode == 0 && unformat (i, "mode"))
4852     {
4853       vam->exec_mode = 1;
4854       return 0;
4855     }
4856   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4857     {
4858       vam->exec_mode = 0;
4859       return 0;
4860     }
4861
4862
4863   M (CLI_REQUEST, mp);
4864
4865   /*
4866    * Copy cmd into shared memory.
4867    * In order for the CLI command to work, it
4868    * must be a vector ending in \n, not a C-string ending
4869    * in \n\0.
4870    */
4871   pthread_mutex_lock (&am->vlib_rp->mutex);
4872   oldheap = svm_push_data_heap (am->vlib_rp);
4873
4874   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4875   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4876
4877   svm_pop_heap (oldheap);
4878   pthread_mutex_unlock (&am->vlib_rp->mutex);
4879
4880   mp->cmd_in_shmem = (u64) cmd;
4881   S (mp);
4882   timeout = vat_time_now (vam) + 10.0;
4883
4884   while (vat_time_now (vam) < timeout)
4885     {
4886       if (vam->result_ready == 1)
4887         {
4888           u8 *free_me;
4889           if (vam->shmem_result != NULL)
4890             print (vam->ofp, "%s", vam->shmem_result);
4891           pthread_mutex_lock (&am->vlib_rp->mutex);
4892           oldheap = svm_push_data_heap (am->vlib_rp);
4893
4894           free_me = (u8 *) vam->shmem_result;
4895           vec_free (free_me);
4896
4897           svm_pop_heap (oldheap);
4898           pthread_mutex_unlock (&am->vlib_rp->mutex);
4899           return 0;
4900         }
4901     }
4902   return -99;
4903 }
4904
4905 /*
4906  * Future replacement of exec() that passes CLI buffers directly in
4907  * the API messages instead of an additional shared memory area.
4908  */
4909 static int
4910 exec_inband (vat_main_t * vam)
4911 {
4912   vl_api_cli_inband_t *mp;
4913   unformat_input_t *i = vam->input;
4914   int ret;
4915
4916   if (vec_len (i->buffer) == 0)
4917     return -1;
4918
4919   if (vam->exec_mode == 0 && unformat (i, "mode"))
4920     {
4921       vam->exec_mode = 1;
4922       return 0;
4923     }
4924   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4925     {
4926       vam->exec_mode = 0;
4927       return 0;
4928     }
4929
4930   /*
4931    * In order for the CLI command to work, it
4932    * must be a vector ending in \n, not a C-string ending
4933    * in \n\0.
4934    */
4935   u32 len = vec_len (vam->input->buffer);
4936   M2 (CLI_INBAND, mp, len);
4937   clib_memcpy (mp->cmd, vam->input->buffer, len);
4938   mp->length = htonl (len);
4939
4940   S (mp);
4941   W2 (ret, print (vam->ofp, "%s", vam->cmd_reply));
4942   return ret;
4943 }
4944
4945 static int
4946 api_create_loopback (vat_main_t * vam)
4947 {
4948   unformat_input_t *i = vam->input;
4949   vl_api_create_loopback_t *mp;
4950   vl_api_create_loopback_instance_t *mp_lbi;
4951   u8 mac_address[6];
4952   u8 mac_set = 0;
4953   u8 is_specified = 0;
4954   u32 user_instance = 0;
4955   int ret;
4956
4957   memset (mac_address, 0, sizeof (mac_address));
4958
4959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4960     {
4961       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4962         mac_set = 1;
4963       if (unformat (i, "instance %d", &user_instance))
4964         is_specified = 1;
4965       else
4966         break;
4967     }
4968
4969   if (is_specified)
4970     {
4971       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
4972       mp_lbi->is_specified = is_specified;
4973       if (is_specified)
4974         mp_lbi->user_instance = htonl (user_instance);
4975       if (mac_set)
4976         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
4977       S (mp_lbi);
4978     }
4979   else
4980     {
4981       /* Construct the API message */
4982       M (CREATE_LOOPBACK, mp);
4983       if (mac_set)
4984         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4985       S (mp);
4986     }
4987
4988   W (ret);
4989   return ret;
4990 }
4991
4992 static int
4993 api_delete_loopback (vat_main_t * vam)
4994 {
4995   unformat_input_t *i = vam->input;
4996   vl_api_delete_loopback_t *mp;
4997   u32 sw_if_index = ~0;
4998   int ret;
4999
5000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5001     {
5002       if (unformat (i, "sw_if_index %d", &sw_if_index))
5003         ;
5004       else
5005         break;
5006     }
5007
5008   if (sw_if_index == ~0)
5009     {
5010       errmsg ("missing sw_if_index");
5011       return -99;
5012     }
5013
5014   /* Construct the API message */
5015   M (DELETE_LOOPBACK, mp);
5016   mp->sw_if_index = ntohl (sw_if_index);
5017
5018   S (mp);
5019   W (ret);
5020   return ret;
5021 }
5022
5023 static int
5024 api_want_stats (vat_main_t * vam)
5025 {
5026   unformat_input_t *i = vam->input;
5027   vl_api_want_stats_t *mp;
5028   int enable = -1;
5029   int ret;
5030
5031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5032     {
5033       if (unformat (i, "enable"))
5034         enable = 1;
5035       else if (unformat (i, "disable"))
5036         enable = 0;
5037       else
5038         break;
5039     }
5040
5041   if (enable == -1)
5042     {
5043       errmsg ("missing enable|disable");
5044       return -99;
5045     }
5046
5047   M (WANT_STATS, mp);
5048   mp->enable_disable = enable;
5049
5050   S (mp);
5051   W (ret);
5052   return ret;
5053 }
5054
5055 static int
5056 api_want_interface_events (vat_main_t * vam)
5057 {
5058   unformat_input_t *i = vam->input;
5059   vl_api_want_interface_events_t *mp;
5060   int enable = -1;
5061   int ret;
5062
5063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5064     {
5065       if (unformat (i, "enable"))
5066         enable = 1;
5067       else if (unformat (i, "disable"))
5068         enable = 0;
5069       else
5070         break;
5071     }
5072
5073   if (enable == -1)
5074     {
5075       errmsg ("missing enable|disable");
5076       return -99;
5077     }
5078
5079   M (WANT_INTERFACE_EVENTS, mp);
5080   mp->enable_disable = enable;
5081
5082   vam->interface_event_display = enable;
5083
5084   S (mp);
5085   W (ret);
5086   return ret;
5087 }
5088
5089
5090 /* Note: non-static, called once to set up the initial intfc table */
5091 int
5092 api_sw_interface_dump (vat_main_t * vam)
5093 {
5094   vl_api_sw_interface_dump_t *mp;
5095   vl_api_control_ping_t *mp_ping;
5096   hash_pair_t *p;
5097   name_sort_t *nses = 0, *ns;
5098   sw_interface_subif_t *sub = NULL;
5099   int ret;
5100
5101   /* Toss the old name table */
5102   /* *INDENT-OFF* */
5103   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5104   ({
5105     vec_add2 (nses, ns, 1);
5106     ns->name = (u8 *)(p->key);
5107     ns->value = (u32) p->value[0];
5108   }));
5109   /* *INDENT-ON* */
5110
5111   hash_free (vam->sw_if_index_by_interface_name);
5112
5113   vec_foreach (ns, nses) vec_free (ns->name);
5114
5115   vec_free (nses);
5116
5117   vec_foreach (sub, vam->sw_if_subif_table)
5118   {
5119     vec_free (sub->interface_name);
5120   }
5121   vec_free (vam->sw_if_subif_table);
5122
5123   /* recreate the interface name hash table */
5124   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5125
5126   /* Get list of ethernets */
5127   M (SW_INTERFACE_DUMP, mp);
5128   mp->name_filter_valid = 1;
5129   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
5130   S (mp);
5131
5132   /* and local / loopback interfaces */
5133   M (SW_INTERFACE_DUMP, mp);
5134   mp->name_filter_valid = 1;
5135   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
5136   S (mp);
5137
5138   /* and packet-generator interfaces */
5139   M (SW_INTERFACE_DUMP, mp);
5140   mp->name_filter_valid = 1;
5141   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
5142   S (mp);
5143
5144   /* and vxlan-gpe tunnel interfaces */
5145   M (SW_INTERFACE_DUMP, mp);
5146   mp->name_filter_valid = 1;
5147   strncpy ((char *) mp->name_filter, "vxlan_gpe",
5148            sizeof (mp->name_filter) - 1);
5149   S (mp);
5150
5151   /* and vxlan tunnel interfaces */
5152   M (SW_INTERFACE_DUMP, mp);
5153   mp->name_filter_valid = 1;
5154   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
5155   S (mp);
5156
5157   /* and host (af_packet) interfaces */
5158   M (SW_INTERFACE_DUMP, mp);
5159   mp->name_filter_valid = 1;
5160   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
5161   S (mp);
5162
5163   /* and l2tpv3 tunnel interfaces */
5164   M (SW_INTERFACE_DUMP, mp);
5165   mp->name_filter_valid = 1;
5166   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
5167            sizeof (mp->name_filter) - 1);
5168   S (mp);
5169
5170   /* and GRE tunnel interfaces */
5171   M (SW_INTERFACE_DUMP, mp);
5172   mp->name_filter_valid = 1;
5173   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
5174   S (mp);
5175
5176   /* and LISP-GPE interfaces */
5177   M (SW_INTERFACE_DUMP, mp);
5178   mp->name_filter_valid = 1;
5179   strncpy ((char *) mp->name_filter, "lisp_gpe",
5180            sizeof (mp->name_filter) - 1);
5181   S (mp);
5182
5183   /* and IPSEC tunnel interfaces */
5184   M (SW_INTERFACE_DUMP, mp);
5185   mp->name_filter_valid = 1;
5186   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
5187   S (mp);
5188
5189   /* Use a control ping for synchronization */
5190   M (CONTROL_PING, mp_ping);
5191   S (mp_ping);
5192
5193   W (ret);
5194   return ret;
5195 }
5196
5197 static int
5198 api_sw_interface_set_flags (vat_main_t * vam)
5199 {
5200   unformat_input_t *i = vam->input;
5201   vl_api_sw_interface_set_flags_t *mp;
5202   u32 sw_if_index;
5203   u8 sw_if_index_set = 0;
5204   u8 admin_up = 0, link_up = 0;
5205   int ret;
5206
5207   /* Parse args required to build the message */
5208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5209     {
5210       if (unformat (i, "admin-up"))
5211         admin_up = 1;
5212       else if (unformat (i, "admin-down"))
5213         admin_up = 0;
5214       else if (unformat (i, "link-up"))
5215         link_up = 1;
5216       else if (unformat (i, "link-down"))
5217         link_up = 0;
5218       else
5219         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5220         sw_if_index_set = 1;
5221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5222         sw_if_index_set = 1;
5223       else
5224         break;
5225     }
5226
5227   if (sw_if_index_set == 0)
5228     {
5229       errmsg ("missing interface name or sw_if_index");
5230       return -99;
5231     }
5232
5233   /* Construct the API message */
5234   M (SW_INTERFACE_SET_FLAGS, mp);
5235   mp->sw_if_index = ntohl (sw_if_index);
5236   mp->admin_up_down = admin_up;
5237   mp->link_up_down = link_up;
5238
5239   /* send it... */
5240   S (mp);
5241
5242   /* Wait for a reply, return the good/bad news... */
5243   W (ret);
5244   return ret;
5245 }
5246
5247 static int
5248 api_sw_interface_clear_stats (vat_main_t * vam)
5249 {
5250   unformat_input_t *i = vam->input;
5251   vl_api_sw_interface_clear_stats_t *mp;
5252   u32 sw_if_index;
5253   u8 sw_if_index_set = 0;
5254   int ret;
5255
5256   /* Parse args required to build the message */
5257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5258     {
5259       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5260         sw_if_index_set = 1;
5261       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5262         sw_if_index_set = 1;
5263       else
5264         break;
5265     }
5266
5267   /* Construct the API message */
5268   M (SW_INTERFACE_CLEAR_STATS, mp);
5269
5270   if (sw_if_index_set == 1)
5271     mp->sw_if_index = ntohl (sw_if_index);
5272   else
5273     mp->sw_if_index = ~0;
5274
5275   /* send it... */
5276   S (mp);
5277
5278   /* Wait for a reply, return the good/bad news... */
5279   W (ret);
5280   return ret;
5281 }
5282
5283 static int
5284 api_sw_interface_add_del_address (vat_main_t * vam)
5285 {
5286   unformat_input_t *i = vam->input;
5287   vl_api_sw_interface_add_del_address_t *mp;
5288   u32 sw_if_index;
5289   u8 sw_if_index_set = 0;
5290   u8 is_add = 1, del_all = 0;
5291   u32 address_length = 0;
5292   u8 v4_address_set = 0;
5293   u8 v6_address_set = 0;
5294   ip4_address_t v4address;
5295   ip6_address_t v6address;
5296   int ret;
5297
5298   /* Parse args required to build the message */
5299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5300     {
5301       if (unformat (i, "del-all"))
5302         del_all = 1;
5303       else if (unformat (i, "del"))
5304         is_add = 0;
5305       else
5306         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5307         sw_if_index_set = 1;
5308       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5309         sw_if_index_set = 1;
5310       else if (unformat (i, "%U/%d",
5311                          unformat_ip4_address, &v4address, &address_length))
5312         v4_address_set = 1;
5313       else if (unformat (i, "%U/%d",
5314                          unformat_ip6_address, &v6address, &address_length))
5315         v6_address_set = 1;
5316       else
5317         break;
5318     }
5319
5320   if (sw_if_index_set == 0)
5321     {
5322       errmsg ("missing interface name or sw_if_index");
5323       return -99;
5324     }
5325   if (v4_address_set && v6_address_set)
5326     {
5327       errmsg ("both v4 and v6 addresses set");
5328       return -99;
5329     }
5330   if (!v4_address_set && !v6_address_set && !del_all)
5331     {
5332       errmsg ("no addresses set");
5333       return -99;
5334     }
5335
5336   /* Construct the API message */
5337   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
5338
5339   mp->sw_if_index = ntohl (sw_if_index);
5340   mp->is_add = is_add;
5341   mp->del_all = del_all;
5342   if (v6_address_set)
5343     {
5344       mp->is_ipv6 = 1;
5345       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5346     }
5347   else
5348     {
5349       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5350     }
5351   mp->address_length = address_length;
5352
5353   /* send it... */
5354   S (mp);
5355
5356   /* Wait for a reply, return good/bad news  */
5357   W (ret);
5358   return ret;
5359 }
5360
5361 static int
5362 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5363 {
5364   unformat_input_t *i = vam->input;
5365   vl_api_sw_interface_set_mpls_enable_t *mp;
5366   u32 sw_if_index;
5367   u8 sw_if_index_set = 0;
5368   u8 enable = 1;
5369   int ret;
5370
5371   /* Parse args required to build the message */
5372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5373     {
5374       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5375         sw_if_index_set = 1;
5376       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5377         sw_if_index_set = 1;
5378       else if (unformat (i, "disable"))
5379         enable = 0;
5380       else if (unformat (i, "dis"))
5381         enable = 0;
5382       else
5383         break;
5384     }
5385
5386   if (sw_if_index_set == 0)
5387     {
5388       errmsg ("missing interface name or sw_if_index");
5389       return -99;
5390     }
5391
5392   /* Construct the API message */
5393   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
5394
5395   mp->sw_if_index = ntohl (sw_if_index);
5396   mp->enable = enable;
5397
5398   /* send it... */
5399   S (mp);
5400
5401   /* Wait for a reply... */
5402   W (ret);
5403   return ret;
5404 }
5405
5406 static int
5407 api_sw_interface_set_table (vat_main_t * vam)
5408 {
5409   unformat_input_t *i = vam->input;
5410   vl_api_sw_interface_set_table_t *mp;
5411   u32 sw_if_index, vrf_id = 0;
5412   u8 sw_if_index_set = 0;
5413   u8 is_ipv6 = 0;
5414   int ret;
5415
5416   /* Parse args required to build the message */
5417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5418     {
5419       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5420         sw_if_index_set = 1;
5421       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5422         sw_if_index_set = 1;
5423       else if (unformat (i, "vrf %d", &vrf_id))
5424         ;
5425       else if (unformat (i, "ipv6"))
5426         is_ipv6 = 1;
5427       else
5428         break;
5429     }
5430
5431   if (sw_if_index_set == 0)
5432     {
5433       errmsg ("missing interface name or sw_if_index");
5434       return -99;
5435     }
5436
5437   /* Construct the API message */
5438   M (SW_INTERFACE_SET_TABLE, mp);
5439
5440   mp->sw_if_index = ntohl (sw_if_index);
5441   mp->is_ipv6 = is_ipv6;
5442   mp->vrf_id = ntohl (vrf_id);
5443
5444   /* send it... */
5445   S (mp);
5446
5447   /* Wait for a reply... */
5448   W (ret);
5449   return ret;
5450 }
5451
5452 static void vl_api_sw_interface_get_table_reply_t_handler
5453   (vl_api_sw_interface_get_table_reply_t * mp)
5454 {
5455   vat_main_t *vam = &vat_main;
5456
5457   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5458
5459   vam->retval = ntohl (mp->retval);
5460   vam->result_ready = 1;
5461
5462 }
5463
5464 static void vl_api_sw_interface_get_table_reply_t_handler_json
5465   (vl_api_sw_interface_get_table_reply_t * mp)
5466 {
5467   vat_main_t *vam = &vat_main;
5468   vat_json_node_t node;
5469
5470   vat_json_init_object (&node);
5471   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5472   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5473
5474   vat_json_print (vam->ofp, &node);
5475   vat_json_free (&node);
5476
5477   vam->retval = ntohl (mp->retval);
5478   vam->result_ready = 1;
5479 }
5480
5481 static int
5482 api_sw_interface_get_table (vat_main_t * vam)
5483 {
5484   unformat_input_t *i = vam->input;
5485   vl_api_sw_interface_get_table_t *mp;
5486   u32 sw_if_index;
5487   u8 sw_if_index_set = 0;
5488   u8 is_ipv6 = 0;
5489   int ret;
5490
5491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5492     {
5493       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5494         sw_if_index_set = 1;
5495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5496         sw_if_index_set = 1;
5497       else if (unformat (i, "ipv6"))
5498         is_ipv6 = 1;
5499       else
5500         break;
5501     }
5502
5503   if (sw_if_index_set == 0)
5504     {
5505       errmsg ("missing interface name or sw_if_index");
5506       return -99;
5507     }
5508
5509   M (SW_INTERFACE_GET_TABLE, mp);
5510   mp->sw_if_index = htonl (sw_if_index);
5511   mp->is_ipv6 = is_ipv6;
5512
5513   S (mp);
5514   W (ret);
5515   return ret;
5516 }
5517
5518 static int
5519 api_sw_interface_set_vpath (vat_main_t * vam)
5520 {
5521   unformat_input_t *i = vam->input;
5522   vl_api_sw_interface_set_vpath_t *mp;
5523   u32 sw_if_index = 0;
5524   u8 sw_if_index_set = 0;
5525   u8 is_enable = 0;
5526   int ret;
5527
5528   /* Parse args required to build the message */
5529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5530     {
5531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5532         sw_if_index_set = 1;
5533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5534         sw_if_index_set = 1;
5535       else if (unformat (i, "enable"))
5536         is_enable = 1;
5537       else if (unformat (i, "disable"))
5538         is_enable = 0;
5539       else
5540         break;
5541     }
5542
5543   if (sw_if_index_set == 0)
5544     {
5545       errmsg ("missing interface name or sw_if_index");
5546       return -99;
5547     }
5548
5549   /* Construct the API message */
5550   M (SW_INTERFACE_SET_VPATH, mp);
5551
5552   mp->sw_if_index = ntohl (sw_if_index);
5553   mp->enable = is_enable;
5554
5555   /* send it... */
5556   S (mp);
5557
5558   /* Wait for a reply... */
5559   W (ret);
5560   return ret;
5561 }
5562
5563 static int
5564 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5565 {
5566   unformat_input_t *i = vam->input;
5567   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5568   u32 sw_if_index = 0;
5569   u8 sw_if_index_set = 0;
5570   u8 is_enable = 1;
5571   u8 is_ipv6 = 0;
5572   int ret;
5573
5574   /* Parse args required to build the message */
5575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5576     {
5577       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5578         sw_if_index_set = 1;
5579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5580         sw_if_index_set = 1;
5581       else if (unformat (i, "enable"))
5582         is_enable = 1;
5583       else if (unformat (i, "disable"))
5584         is_enable = 0;
5585       else if (unformat (i, "ip4"))
5586         is_ipv6 = 0;
5587       else if (unformat (i, "ip6"))
5588         is_ipv6 = 1;
5589       else
5590         break;
5591     }
5592
5593   if (sw_if_index_set == 0)
5594     {
5595       errmsg ("missing interface name or sw_if_index");
5596       return -99;
5597     }
5598
5599   /* Construct the API message */
5600   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
5601
5602   mp->sw_if_index = ntohl (sw_if_index);
5603   mp->enable = is_enable;
5604   mp->is_ipv6 = is_ipv6;
5605
5606   /* send it... */
5607   S (mp);
5608
5609   /* Wait for a reply... */
5610   W (ret);
5611   return ret;
5612 }
5613
5614 static int
5615 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5616 {
5617   unformat_input_t *i = vam->input;
5618   vl_api_sw_interface_set_l2_xconnect_t *mp;
5619   u32 rx_sw_if_index;
5620   u8 rx_sw_if_index_set = 0;
5621   u32 tx_sw_if_index;
5622   u8 tx_sw_if_index_set = 0;
5623   u8 enable = 1;
5624   int ret;
5625
5626   /* Parse args required to build the message */
5627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5628     {
5629       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5630         rx_sw_if_index_set = 1;
5631       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5632         tx_sw_if_index_set = 1;
5633       else if (unformat (i, "rx"))
5634         {
5635           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5636             {
5637               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5638                             &rx_sw_if_index))
5639                 rx_sw_if_index_set = 1;
5640             }
5641           else
5642             break;
5643         }
5644       else if (unformat (i, "tx"))
5645         {
5646           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5647             {
5648               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5649                             &tx_sw_if_index))
5650                 tx_sw_if_index_set = 1;
5651             }
5652           else
5653             break;
5654         }
5655       else if (unformat (i, "enable"))
5656         enable = 1;
5657       else if (unformat (i, "disable"))
5658         enable = 0;
5659       else
5660         break;
5661     }
5662
5663   if (rx_sw_if_index_set == 0)
5664     {
5665       errmsg ("missing rx interface name or rx_sw_if_index");
5666       return -99;
5667     }
5668
5669   if (enable && (tx_sw_if_index_set == 0))
5670     {
5671       errmsg ("missing tx interface name or tx_sw_if_index");
5672       return -99;
5673     }
5674
5675   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
5676
5677   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5678   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5679   mp->enable = enable;
5680
5681   S (mp);
5682   W (ret);
5683   return ret;
5684 }
5685
5686 static int
5687 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5688 {
5689   unformat_input_t *i = vam->input;
5690   vl_api_sw_interface_set_l2_bridge_t *mp;
5691   u32 rx_sw_if_index;
5692   u8 rx_sw_if_index_set = 0;
5693   u32 bd_id;
5694   u8 bd_id_set = 0;
5695   u8 bvi = 0;
5696   u32 shg = 0;
5697   u8 enable = 1;
5698   int ret;
5699
5700   /* Parse args required to build the message */
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5704         rx_sw_if_index_set = 1;
5705       else if (unformat (i, "bd_id %d", &bd_id))
5706         bd_id_set = 1;
5707       else
5708         if (unformat
5709             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5710         rx_sw_if_index_set = 1;
5711       else if (unformat (i, "shg %d", &shg))
5712         ;
5713       else if (unformat (i, "bvi"))
5714         bvi = 1;
5715       else if (unformat (i, "enable"))
5716         enable = 1;
5717       else if (unformat (i, "disable"))
5718         enable = 0;
5719       else
5720         break;
5721     }
5722
5723   if (rx_sw_if_index_set == 0)
5724     {
5725       errmsg ("missing rx interface name or sw_if_index");
5726       return -99;
5727     }
5728
5729   if (enable && (bd_id_set == 0))
5730     {
5731       errmsg ("missing bridge domain");
5732       return -99;
5733     }
5734
5735   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
5736
5737   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5738   mp->bd_id = ntohl (bd_id);
5739   mp->shg = (u8) shg;
5740   mp->bvi = bvi;
5741   mp->enable = enable;
5742
5743   S (mp);
5744   W (ret);
5745   return ret;
5746 }
5747
5748 static int
5749 api_bridge_domain_dump (vat_main_t * vam)
5750 {
5751   unformat_input_t *i = vam->input;
5752   vl_api_bridge_domain_dump_t *mp;
5753   vl_api_control_ping_t *mp_ping;
5754   u32 bd_id = ~0;
5755   int ret;
5756
5757   /* Parse args required to build the message */
5758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5759     {
5760       if (unformat (i, "bd_id %d", &bd_id))
5761         ;
5762       else
5763         break;
5764     }
5765
5766   M (BRIDGE_DOMAIN_DUMP, mp);
5767   mp->bd_id = ntohl (bd_id);
5768   S (mp);
5769
5770   /* Use a control ping for synchronization */
5771   M (CONTROL_PING, mp_ping);
5772   S (mp_ping);
5773
5774   W (ret);
5775   return ret;
5776 }
5777
5778 static int
5779 api_bridge_domain_add_del (vat_main_t * vam)
5780 {
5781   unformat_input_t *i = vam->input;
5782   vl_api_bridge_domain_add_del_t *mp;
5783   u32 bd_id = ~0;
5784   u8 is_add = 1;
5785   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5786   u32 mac_age = 0;
5787   int ret;
5788
5789   /* Parse args required to build the message */
5790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5791     {
5792       if (unformat (i, "bd_id %d", &bd_id))
5793         ;
5794       else if (unformat (i, "flood %d", &flood))
5795         ;
5796       else if (unformat (i, "uu-flood %d", &uu_flood))
5797         ;
5798       else if (unformat (i, "forward %d", &forward))
5799         ;
5800       else if (unformat (i, "learn %d", &learn))
5801         ;
5802       else if (unformat (i, "arp-term %d", &arp_term))
5803         ;
5804       else if (unformat (i, "mac-age %d", &mac_age))
5805         ;
5806       else if (unformat (i, "del"))
5807         {
5808           is_add = 0;
5809           flood = uu_flood = forward = learn = 0;
5810         }
5811       else
5812         break;
5813     }
5814
5815   if (bd_id == ~0)
5816     {
5817       errmsg ("missing bridge domain");
5818       return -99;
5819     }
5820
5821   if (mac_age > 255)
5822     {
5823       errmsg ("mac age must be less than 256 ");
5824       return -99;
5825     }
5826
5827   M (BRIDGE_DOMAIN_ADD_DEL, mp);
5828
5829   mp->bd_id = ntohl (bd_id);
5830   mp->flood = flood;
5831   mp->uu_flood = uu_flood;
5832   mp->forward = forward;
5833   mp->learn = learn;
5834   mp->arp_term = arp_term;
5835   mp->is_add = is_add;
5836   mp->mac_age = (u8) mac_age;
5837
5838   S (mp);
5839   W (ret);
5840   return ret;
5841 }
5842
5843 static int
5844 api_l2fib_add_del (vat_main_t * vam)
5845 {
5846   unformat_input_t *i = vam->input;
5847   vl_api_l2fib_add_del_t *mp;
5848   f64 timeout;
5849   u64 mac = 0;
5850   u8 mac_set = 0;
5851   u32 bd_id;
5852   u8 bd_id_set = 0;
5853   u32 sw_if_index = ~0;
5854   u8 sw_if_index_set = 0;
5855   u8 is_add = 1;
5856   u8 static_mac = 0;
5857   u8 filter_mac = 0;
5858   u8 bvi_mac = 0;
5859   int count = 1;
5860   f64 before = 0;
5861   int j;
5862
5863   /* Parse args required to build the message */
5864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5865     {
5866       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5867         mac_set = 1;
5868       else if (unformat (i, "bd_id %d", &bd_id))
5869         bd_id_set = 1;
5870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5871         sw_if_index_set = 1;
5872       else if (unformat (i, "sw_if"))
5873         {
5874           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5875             {
5876               if (unformat
5877                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5878                 sw_if_index_set = 1;
5879             }
5880           else
5881             break;
5882         }
5883       else if (unformat (i, "static"))
5884         static_mac = 1;
5885       else if (unformat (i, "filter"))
5886         {
5887           filter_mac = 1;
5888           static_mac = 1;
5889         }
5890       else if (unformat (i, "bvi"))
5891         {
5892           bvi_mac = 1;
5893           static_mac = 1;
5894         }
5895       else if (unformat (i, "del"))
5896         is_add = 0;
5897       else if (unformat (i, "count %d", &count))
5898         ;
5899       else
5900         break;
5901     }
5902
5903   if (mac_set == 0)
5904     {
5905       errmsg ("missing mac address");
5906       return -99;
5907     }
5908
5909   if (bd_id_set == 0)
5910     {
5911       errmsg ("missing bridge domain");
5912       return -99;
5913     }
5914
5915   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5916     {
5917       errmsg ("missing interface name or sw_if_index");
5918       return -99;
5919     }
5920
5921   if (count > 1)
5922     {
5923       /* Turn on async mode */
5924       vam->async_mode = 1;
5925       vam->async_errors = 0;
5926       before = vat_time_now (vam);
5927     }
5928
5929   for (j = 0; j < count; j++)
5930     {
5931       M (L2FIB_ADD_DEL, mp);
5932
5933       mp->mac = mac;
5934       mp->bd_id = ntohl (bd_id);
5935       mp->is_add = is_add;
5936
5937       if (is_add)
5938         {
5939           mp->sw_if_index = ntohl (sw_if_index);
5940           mp->static_mac = static_mac;
5941           mp->filter_mac = filter_mac;
5942           mp->bvi_mac = bvi_mac;
5943         }
5944       increment_mac_address (&mac);
5945       /* send it... */
5946       S (mp);
5947     }
5948
5949   if (count > 1)
5950     {
5951       vl_api_control_ping_t *mp_ping;
5952       f64 after;
5953
5954       /* Shut off async mode */
5955       vam->async_mode = 0;
5956
5957       M (CONTROL_PING, mp_ping);
5958       S (mp_ping);
5959
5960       timeout = vat_time_now (vam) + 1.0;
5961       while (vat_time_now (vam) < timeout)
5962         if (vam->result_ready == 1)
5963           goto out;
5964       vam->retval = -99;
5965
5966     out:
5967       if (vam->retval == -99)
5968         errmsg ("timeout");
5969
5970       if (vam->async_errors > 0)
5971         {
5972           errmsg ("%d asynchronous errors", vam->async_errors);
5973           vam->retval = -98;
5974         }
5975       vam->async_errors = 0;
5976       after = vat_time_now (vam);
5977
5978       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5979              count, after - before, count / (after - before));
5980     }
5981   else
5982     {
5983       int ret;
5984
5985       /* Wait for a reply... */
5986       W (ret);
5987       return ret;
5988     }
5989   /* Return the good/bad news */
5990   return (vam->retval);
5991 }
5992
5993 static int
5994 api_l2_flags (vat_main_t * vam)
5995 {
5996   unformat_input_t *i = vam->input;
5997   vl_api_l2_flags_t *mp;
5998   u32 sw_if_index;
5999   u32 feature_bitmap = 0;
6000   u8 sw_if_index_set = 0;
6001   int ret;
6002
6003   /* Parse args required to build the message */
6004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6005     {
6006       if (unformat (i, "sw_if_index %d", &sw_if_index))
6007         sw_if_index_set = 1;
6008       else if (unformat (i, "sw_if"))
6009         {
6010           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6011             {
6012               if (unformat
6013                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6014                 sw_if_index_set = 1;
6015             }
6016           else
6017             break;
6018         }
6019       else if (unformat (i, "learn"))
6020         feature_bitmap |= L2INPUT_FEAT_LEARN;
6021       else if (unformat (i, "forward"))
6022         feature_bitmap |= L2INPUT_FEAT_FWD;
6023       else if (unformat (i, "flood"))
6024         feature_bitmap |= L2INPUT_FEAT_FLOOD;
6025       else if (unformat (i, "uu-flood"))
6026         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
6027       else
6028         break;
6029     }
6030
6031   if (sw_if_index_set == 0)
6032     {
6033       errmsg ("missing interface name or sw_if_index");
6034       return -99;
6035     }
6036
6037   M (L2_FLAGS, mp);
6038
6039   mp->sw_if_index = ntohl (sw_if_index);
6040   mp->feature_bitmap = ntohl (feature_bitmap);
6041
6042   S (mp);
6043   W (ret);
6044   return ret;
6045 }
6046
6047 static int
6048 api_bridge_flags (vat_main_t * vam)
6049 {
6050   unformat_input_t *i = vam->input;
6051   vl_api_bridge_flags_t *mp;
6052   u32 bd_id;
6053   u8 bd_id_set = 0;
6054   u8 is_set = 1;
6055   u32 flags = 0;
6056   int ret;
6057
6058   /* Parse args required to build the message */
6059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6060     {
6061       if (unformat (i, "bd_id %d", &bd_id))
6062         bd_id_set = 1;
6063       else if (unformat (i, "learn"))
6064         flags |= L2_LEARN;
6065       else if (unformat (i, "forward"))
6066         flags |= L2_FWD;
6067       else if (unformat (i, "flood"))
6068         flags |= L2_FLOOD;
6069       else if (unformat (i, "uu-flood"))
6070         flags |= L2_UU_FLOOD;
6071       else if (unformat (i, "arp-term"))
6072         flags |= L2_ARP_TERM;
6073       else if (unformat (i, "off"))
6074         is_set = 0;
6075       else if (unformat (i, "disable"))
6076         is_set = 0;
6077       else
6078         break;
6079     }
6080
6081   if (bd_id_set == 0)
6082     {
6083       errmsg ("missing bridge domain");
6084       return -99;
6085     }
6086
6087   M (BRIDGE_FLAGS, mp);
6088
6089   mp->bd_id = ntohl (bd_id);
6090   mp->feature_bitmap = ntohl (flags);
6091   mp->is_set = is_set;
6092
6093   S (mp);
6094   W (ret);
6095   return ret;
6096 }
6097
6098 static int
6099 api_bd_ip_mac_add_del (vat_main_t * vam)
6100 {
6101   unformat_input_t *i = vam->input;
6102   vl_api_bd_ip_mac_add_del_t *mp;
6103   u32 bd_id;
6104   u8 is_ipv6 = 0;
6105   u8 is_add = 1;
6106   u8 bd_id_set = 0;
6107   u8 ip_set = 0;
6108   u8 mac_set = 0;
6109   ip4_address_t v4addr;
6110   ip6_address_t v6addr;
6111   u8 macaddr[6];
6112   int ret;
6113
6114
6115   /* Parse args required to build the message */
6116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6117     {
6118       if (unformat (i, "bd_id %d", &bd_id))
6119         {
6120           bd_id_set++;
6121         }
6122       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
6123         {
6124           ip_set++;
6125         }
6126       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
6127         {
6128           ip_set++;
6129           is_ipv6++;
6130         }
6131       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
6132         {
6133           mac_set++;
6134         }
6135       else if (unformat (i, "del"))
6136         is_add = 0;
6137       else
6138         break;
6139     }
6140
6141   if (bd_id_set == 0)
6142     {
6143       errmsg ("missing bridge domain");
6144       return -99;
6145     }
6146   else if (ip_set == 0)
6147     {
6148       errmsg ("missing IP address");
6149       return -99;
6150     }
6151   else if (mac_set == 0)
6152     {
6153       errmsg ("missing MAC address");
6154       return -99;
6155     }
6156
6157   M (BD_IP_MAC_ADD_DEL, mp);
6158
6159   mp->bd_id = ntohl (bd_id);
6160   mp->is_ipv6 = is_ipv6;
6161   mp->is_add = is_add;
6162   if (is_ipv6)
6163     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
6164   else
6165     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
6166   clib_memcpy (mp->mac_address, macaddr, 6);
6167   S (mp);
6168   W (ret);
6169   return ret;
6170 }
6171
6172 static int
6173 api_tap_connect (vat_main_t * vam)
6174 {
6175   unformat_input_t *i = vam->input;
6176   vl_api_tap_connect_t *mp;
6177   u8 mac_address[6];
6178   u8 random_mac = 1;
6179   u8 name_set = 0;
6180   u8 *tap_name;
6181   u8 *tag = 0;
6182   ip4_address_t ip4_address;
6183   u32 ip4_mask_width;
6184   int ip4_address_set = 0;
6185   ip6_address_t ip6_address;
6186   u32 ip6_mask_width;
6187   int ip6_address_set = 0;
6188   int ret;
6189
6190   memset (mac_address, 0, sizeof (mac_address));
6191
6192   /* Parse args required to build the message */
6193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6194     {
6195       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6196         {
6197           random_mac = 0;
6198         }
6199       else if (unformat (i, "random-mac"))
6200         random_mac = 1;
6201       else if (unformat (i, "tapname %s", &tap_name))
6202         name_set = 1;
6203       else if (unformat (i, "tag %s", &tag))
6204         ;
6205       else if (unformat (i, "address %U/%d",
6206                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
6207         ip4_address_set = 1;
6208       else if (unformat (i, "address %U/%d",
6209                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
6210         ip6_address_set = 1;
6211       else
6212         break;
6213     }
6214
6215   if (name_set == 0)
6216     {
6217       errmsg ("missing tap name");
6218       return -99;
6219     }
6220   if (vec_len (tap_name) > 63)
6221     {
6222       errmsg ("tap name too long");
6223       return -99;
6224     }
6225   vec_add1 (tap_name, 0);
6226
6227   if (vec_len (tag) > 63)
6228     {
6229       errmsg ("tag too long");
6230       return -99;
6231     }
6232
6233   /* Construct the API message */
6234   M (TAP_CONNECT, mp);
6235
6236   mp->use_random_mac = random_mac;
6237   clib_memcpy (mp->mac_address, mac_address, 6);
6238   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6239   if (tag)
6240     clib_memcpy (mp->tag, tag, vec_len (tag));
6241
6242   if (ip4_address_set)
6243     {
6244       mp->ip4_address_set = 1;
6245       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
6246       mp->ip4_mask_width = ip4_mask_width;
6247     }
6248   if (ip6_address_set)
6249     {
6250       mp->ip6_address_set = 1;
6251       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
6252       mp->ip6_mask_width = ip6_mask_width;
6253     }
6254
6255   vec_free (tap_name);
6256   vec_free (tag);
6257
6258   /* send it... */
6259   S (mp);
6260
6261   /* Wait for a reply... */
6262   W (ret);
6263   return ret;
6264 }
6265
6266 static int
6267 api_tap_modify (vat_main_t * vam)
6268 {
6269   unformat_input_t *i = vam->input;
6270   vl_api_tap_modify_t *mp;
6271   u8 mac_address[6];
6272   u8 random_mac = 1;
6273   u8 name_set = 0;
6274   u8 *tap_name;
6275   u32 sw_if_index = ~0;
6276   u8 sw_if_index_set = 0;
6277   int ret;
6278
6279   memset (mac_address, 0, sizeof (mac_address));
6280
6281   /* Parse args required to build the message */
6282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6283     {
6284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6285         sw_if_index_set = 1;
6286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6287         sw_if_index_set = 1;
6288       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6289         {
6290           random_mac = 0;
6291         }
6292       else if (unformat (i, "random-mac"))
6293         random_mac = 1;
6294       else if (unformat (i, "tapname %s", &tap_name))
6295         name_set = 1;
6296       else
6297         break;
6298     }
6299
6300   if (sw_if_index_set == 0)
6301     {
6302       errmsg ("missing vpp interface name");
6303       return -99;
6304     }
6305   if (name_set == 0)
6306     {
6307       errmsg ("missing tap name");
6308       return -99;
6309     }
6310   if (vec_len (tap_name) > 63)
6311     {
6312       errmsg ("tap name too long");
6313     }
6314   vec_add1 (tap_name, 0);
6315
6316   /* Construct the API message */
6317   M (TAP_MODIFY, mp);
6318
6319   mp->use_random_mac = random_mac;
6320   mp->sw_if_index = ntohl (sw_if_index);
6321   clib_memcpy (mp->mac_address, mac_address, 6);
6322   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6323   vec_free (tap_name);
6324
6325   /* send it... */
6326   S (mp);
6327
6328   /* Wait for a reply... */
6329   W (ret);
6330   return ret;
6331 }
6332
6333 static int
6334 api_tap_delete (vat_main_t * vam)
6335 {
6336   unformat_input_t *i = vam->input;
6337   vl_api_tap_delete_t *mp;
6338   u32 sw_if_index = ~0;
6339   u8 sw_if_index_set = 0;
6340   int ret;
6341
6342   /* Parse args required to build the message */
6343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6344     {
6345       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6348         sw_if_index_set = 1;
6349       else
6350         break;
6351     }
6352
6353   if (sw_if_index_set == 0)
6354     {
6355       errmsg ("missing vpp interface name");
6356       return -99;
6357     }
6358
6359   /* Construct the API message */
6360   M (TAP_DELETE, mp);
6361
6362   mp->sw_if_index = ntohl (sw_if_index);
6363
6364   /* send it... */
6365   S (mp);
6366
6367   /* Wait for a reply... */
6368   W (ret);
6369   return ret;
6370 }
6371
6372 static int
6373 api_ip_add_del_route (vat_main_t * vam)
6374 {
6375   unformat_input_t *i = vam->input;
6376   vl_api_ip_add_del_route_t *mp;
6377   u32 sw_if_index = ~0, vrf_id = 0;
6378   u8 is_ipv6 = 0;
6379   u8 is_local = 0, is_drop = 0;
6380   u8 is_unreach = 0, is_prohibit = 0;
6381   u8 create_vrf_if_needed = 0;
6382   u8 is_add = 1;
6383   u32 next_hop_weight = 1;
6384   u8 not_last = 0;
6385   u8 is_multipath = 0;
6386   u8 address_set = 0;
6387   u8 address_length_set = 0;
6388   u32 next_hop_table_id = 0;
6389   u32 resolve_attempts = 0;
6390   u32 dst_address_length = 0;
6391   u8 next_hop_set = 0;
6392   ip4_address_t v4_dst_address, v4_next_hop_address;
6393   ip6_address_t v6_dst_address, v6_next_hop_address;
6394   int count = 1;
6395   int j;
6396   f64 before = 0;
6397   u32 random_add_del = 0;
6398   u32 *random_vector = 0;
6399   uword *random_hash;
6400   u32 random_seed = 0xdeaddabe;
6401   u32 classify_table_index = ~0;
6402   u8 is_classify = 0;
6403   u8 resolve_host = 0, resolve_attached = 0;
6404   mpls_label_t *next_hop_out_label_stack = NULL;
6405   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6406   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6407
6408   /* Parse args required to build the message */
6409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6410     {
6411       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6412         ;
6413       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6414         ;
6415       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6416         {
6417           address_set = 1;
6418           is_ipv6 = 0;
6419         }
6420       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6421         {
6422           address_set = 1;
6423           is_ipv6 = 1;
6424         }
6425       else if (unformat (i, "/%d", &dst_address_length))
6426         {
6427           address_length_set = 1;
6428         }
6429
6430       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6431                                          &v4_next_hop_address))
6432         {
6433           next_hop_set = 1;
6434         }
6435       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6436                                          &v6_next_hop_address))
6437         {
6438           next_hop_set = 1;
6439         }
6440       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6441         ;
6442       else if (unformat (i, "weight %d", &next_hop_weight))
6443         ;
6444       else if (unformat (i, "drop"))
6445         {
6446           is_drop = 1;
6447         }
6448       else if (unformat (i, "null-send-unreach"))
6449         {
6450           is_unreach = 1;
6451         }
6452       else if (unformat (i, "null-send-prohibit"))
6453         {
6454           is_prohibit = 1;
6455         }
6456       else if (unformat (i, "local"))
6457         {
6458           is_local = 1;
6459         }
6460       else if (unformat (i, "classify %d", &classify_table_index))
6461         {
6462           is_classify = 1;
6463         }
6464       else if (unformat (i, "del"))
6465         is_add = 0;
6466       else if (unformat (i, "add"))
6467         is_add = 1;
6468       else if (unformat (i, "not-last"))
6469         not_last = 1;
6470       else if (unformat (i, "resolve-via-host"))
6471         resolve_host = 1;
6472       else if (unformat (i, "resolve-via-attached"))
6473         resolve_attached = 1;
6474       else if (unformat (i, "multipath"))
6475         is_multipath = 1;
6476       else if (unformat (i, "vrf %d", &vrf_id))
6477         ;
6478       else if (unformat (i, "create-vrf"))
6479         create_vrf_if_needed = 1;
6480       else if (unformat (i, "count %d", &count))
6481         ;
6482       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6483         ;
6484       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6485         ;
6486       else if (unformat (i, "out-label %d", &next_hop_out_label))
6487         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6488       else if (unformat (i, "via-label %d", &next_hop_via_label))
6489         ;
6490       else if (unformat (i, "random"))
6491         random_add_del = 1;
6492       else if (unformat (i, "seed %d", &random_seed))
6493         ;
6494       else
6495         {
6496           clib_warning ("parse error '%U'", format_unformat_error, i);
6497           return -99;
6498         }
6499     }
6500
6501   if (!next_hop_set && !is_drop && !is_local &&
6502       !is_classify && !is_unreach && !is_prohibit &&
6503       MPLS_LABEL_INVALID == next_hop_via_label)
6504     {
6505       errmsg
6506         ("next hop / local / drop / unreach / prohibit / classify not set");
6507       return -99;
6508     }
6509
6510   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6511     {
6512       errmsg ("next hop and next-hop via label set");
6513       return -99;
6514     }
6515   if (address_set == 0)
6516     {
6517       errmsg ("missing addresses");
6518       return -99;
6519     }
6520
6521   if (address_length_set == 0)
6522     {
6523       errmsg ("missing address length");
6524       return -99;
6525     }
6526
6527   /* Generate a pile of unique, random routes */
6528   if (random_add_del)
6529     {
6530       u32 this_random_address;
6531       random_hash = hash_create (count, sizeof (uword));
6532
6533       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6534       for (j = 0; j <= count; j++)
6535         {
6536           do
6537             {
6538               this_random_address = random_u32 (&random_seed);
6539               this_random_address =
6540                 clib_host_to_net_u32 (this_random_address);
6541             }
6542           while (hash_get (random_hash, this_random_address));
6543           vec_add1 (random_vector, this_random_address);
6544           hash_set (random_hash, this_random_address, 1);
6545         }
6546       hash_free (random_hash);
6547       v4_dst_address.as_u32 = random_vector[0];
6548     }
6549
6550   if (count > 1)
6551     {
6552       /* Turn on async mode */
6553       vam->async_mode = 1;
6554       vam->async_errors = 0;
6555       before = vat_time_now (vam);
6556     }
6557
6558   for (j = 0; j < count; j++)
6559     {
6560       /* Construct the API message */
6561       M2 (IP_ADD_DEL_ROUTE, mp,
6562           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6563
6564       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6565       mp->table_id = ntohl (vrf_id);
6566       mp->create_vrf_if_needed = create_vrf_if_needed;
6567
6568       mp->is_add = is_add;
6569       mp->is_drop = is_drop;
6570       mp->is_unreach = is_unreach;
6571       mp->is_prohibit = is_prohibit;
6572       mp->is_ipv6 = is_ipv6;
6573       mp->is_local = is_local;
6574       mp->is_classify = is_classify;
6575       mp->is_multipath = is_multipath;
6576       mp->is_resolve_host = resolve_host;
6577       mp->is_resolve_attached = resolve_attached;
6578       mp->not_last = not_last;
6579       mp->next_hop_weight = next_hop_weight;
6580       mp->dst_address_length = dst_address_length;
6581       mp->next_hop_table_id = ntohl (next_hop_table_id);
6582       mp->classify_table_index = ntohl (classify_table_index);
6583       mp->next_hop_via_label = ntohl (next_hop_via_label);
6584       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6585       if (0 != mp->next_hop_n_out_labels)
6586         {
6587           memcpy (mp->next_hop_out_label_stack,
6588                   next_hop_out_label_stack,
6589                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6590           vec_free (next_hop_out_label_stack);
6591         }
6592
6593       if (is_ipv6)
6594         {
6595           clib_memcpy (mp->dst_address, &v6_dst_address,
6596                        sizeof (v6_dst_address));
6597           if (next_hop_set)
6598             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6599                          sizeof (v6_next_hop_address));
6600           increment_v6_address (&v6_dst_address);
6601         }
6602       else
6603         {
6604           clib_memcpy (mp->dst_address, &v4_dst_address,
6605                        sizeof (v4_dst_address));
6606           if (next_hop_set)
6607             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6608                          sizeof (v4_next_hop_address));
6609           if (random_add_del)
6610             v4_dst_address.as_u32 = random_vector[j + 1];
6611           else
6612             increment_v4_address (&v4_dst_address);
6613         }
6614       /* send it... */
6615       S (mp);
6616       /* If we receive SIGTERM, stop now... */
6617       if (vam->do_exit)
6618         break;
6619     }
6620
6621   /* When testing multiple add/del ops, use a control-ping to sync */
6622   if (count > 1)
6623     {
6624       vl_api_control_ping_t *mp_ping;
6625       f64 after;
6626       f64 timeout;
6627
6628       /* Shut off async mode */
6629       vam->async_mode = 0;
6630
6631       M (CONTROL_PING, mp_ping);
6632       S (mp_ping);
6633
6634       timeout = vat_time_now (vam) + 1.0;
6635       while (vat_time_now (vam) < timeout)
6636         if (vam->result_ready == 1)
6637           goto out;
6638       vam->retval = -99;
6639
6640     out:
6641       if (vam->retval == -99)
6642         errmsg ("timeout");
6643
6644       if (vam->async_errors > 0)
6645         {
6646           errmsg ("%d asynchronous errors", vam->async_errors);
6647           vam->retval = -98;
6648         }
6649       vam->async_errors = 0;
6650       after = vat_time_now (vam);
6651
6652       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6653       if (j > 0)
6654         count = j;
6655
6656       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6657              count, after - before, count / (after - before));
6658     }
6659   else
6660     {
6661       int ret;
6662
6663       /* Wait for a reply... */
6664       W (ret);
6665       return ret;
6666     }
6667
6668   /* Return the good/bad news */
6669   return (vam->retval);
6670 }
6671
6672 static int
6673 api_ip_mroute_add_del (vat_main_t * vam)
6674 {
6675   unformat_input_t *i = vam->input;
6676   vl_api_ip_mroute_add_del_t *mp;
6677   u32 sw_if_index = ~0, vrf_id = 0;
6678   u8 is_ipv6 = 0;
6679   u8 is_local = 0;
6680   u8 create_vrf_if_needed = 0;
6681   u8 is_add = 1;
6682   u8 address_set = 0;
6683   u32 grp_address_length = 0;
6684   ip4_address_t v4_grp_address, v4_src_address;
6685   ip6_address_t v6_grp_address, v6_src_address;
6686   mfib_itf_flags_t iflags = 0;
6687   mfib_entry_flags_t eflags = 0;
6688   int ret;
6689
6690   /* Parse args required to build the message */
6691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6692     {
6693       if (unformat (i, "sw_if_index %d", &sw_if_index))
6694         ;
6695       else if (unformat (i, "%U %U",
6696                          unformat_ip4_address, &v4_src_address,
6697                          unformat_ip4_address, &v4_grp_address))
6698         {
6699           grp_address_length = 64;
6700           address_set = 1;
6701           is_ipv6 = 0;
6702         }
6703       else if (unformat (i, "%U %U",
6704                          unformat_ip6_address, &v6_src_address,
6705                          unformat_ip6_address, &v6_grp_address))
6706         {
6707           grp_address_length = 256;
6708           address_set = 1;
6709           is_ipv6 = 1;
6710         }
6711       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
6712         {
6713           memset (&v4_src_address, 0, sizeof (v4_src_address));
6714           grp_address_length = 32;
6715           address_set = 1;
6716           is_ipv6 = 0;
6717         }
6718       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
6719         {
6720           memset (&v6_src_address, 0, sizeof (v6_src_address));
6721           grp_address_length = 128;
6722           address_set = 1;
6723           is_ipv6 = 1;
6724         }
6725       else if (unformat (i, "/%d", &grp_address_length))
6726         ;
6727       else if (unformat (i, "local"))
6728         {
6729           is_local = 1;
6730         }
6731       else if (unformat (i, "del"))
6732         is_add = 0;
6733       else if (unformat (i, "add"))
6734         is_add = 1;
6735       else if (unformat (i, "vrf %d", &vrf_id))
6736         ;
6737       else if (unformat (i, "create-vrf"))
6738         create_vrf_if_needed = 1;
6739       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
6740         ;
6741       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6742         ;
6743       else
6744         {
6745           clib_warning ("parse error '%U'", format_unformat_error, i);
6746           return -99;
6747         }
6748     }
6749
6750   if (address_set == 0)
6751     {
6752       errmsg ("missing addresses\n");
6753       return -99;
6754     }
6755
6756   /* Construct the API message */
6757   M (IP_MROUTE_ADD_DEL, mp);
6758
6759   mp->next_hop_sw_if_index = ntohl (sw_if_index);
6760   mp->table_id = ntohl (vrf_id);
6761   mp->create_vrf_if_needed = create_vrf_if_needed;
6762
6763   mp->is_add = is_add;
6764   mp->is_ipv6 = is_ipv6;
6765   mp->is_local = is_local;
6766   mp->itf_flags = ntohl (iflags);
6767   mp->entry_flags = ntohl (eflags);
6768   mp->grp_address_length = grp_address_length;
6769   mp->grp_address_length = ntohs (mp->grp_address_length);
6770
6771   if (is_ipv6)
6772     {
6773       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
6774       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
6775     }
6776   else
6777     {
6778       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
6779       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
6780
6781     }
6782
6783   /* send it... */
6784   S (mp);
6785   /* Wait for a reply... */
6786   W (ret);
6787   return ret;
6788 }
6789
6790 static int
6791 api_mpls_route_add_del (vat_main_t * vam)
6792 {
6793   unformat_input_t *i = vam->input;
6794   vl_api_mpls_route_add_del_t *mp;
6795   u32 sw_if_index = ~0, table_id = 0;
6796   u8 create_table_if_needed = 0;
6797   u8 is_add = 1;
6798   u32 next_hop_weight = 1;
6799   u8 is_multipath = 0;
6800   u32 next_hop_table_id = 0;
6801   u8 next_hop_set = 0;
6802   ip4_address_t v4_next_hop_address = {
6803     .as_u32 = 0,
6804   };
6805   ip6_address_t v6_next_hop_address = { {0} };
6806   int count = 1;
6807   int j;
6808   f64 before = 0;
6809   u32 classify_table_index = ~0;
6810   u8 is_classify = 0;
6811   u8 resolve_host = 0, resolve_attached = 0;
6812   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6813   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6814   mpls_label_t *next_hop_out_label_stack = NULL;
6815   mpls_label_t local_label = MPLS_LABEL_INVALID;
6816   u8 is_eos = 0;
6817   u8 next_hop_proto_is_ip4 = 1;
6818
6819   /* Parse args required to build the message */
6820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6821     {
6822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6823         ;
6824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6825         ;
6826       else if (unformat (i, "%d", &local_label))
6827         ;
6828       else if (unformat (i, "eos"))
6829         is_eos = 1;
6830       else if (unformat (i, "non-eos"))
6831         is_eos = 0;
6832       else if (unformat (i, "via %U", unformat_ip4_address,
6833                          &v4_next_hop_address))
6834         {
6835           next_hop_set = 1;
6836           next_hop_proto_is_ip4 = 1;
6837         }
6838       else if (unformat (i, "via %U", unformat_ip6_address,
6839                          &v6_next_hop_address))
6840         {
6841           next_hop_set = 1;
6842           next_hop_proto_is_ip4 = 0;
6843         }
6844       else if (unformat (i, "weight %d", &next_hop_weight))
6845         ;
6846       else if (unformat (i, "create-table"))
6847         create_table_if_needed = 1;
6848       else if (unformat (i, "classify %d", &classify_table_index))
6849         {
6850           is_classify = 1;
6851         }
6852       else if (unformat (i, "del"))
6853         is_add = 0;
6854       else if (unformat (i, "add"))
6855         is_add = 1;
6856       else if (unformat (i, "resolve-via-host"))
6857         resolve_host = 1;
6858       else if (unformat (i, "resolve-via-attached"))
6859         resolve_attached = 1;
6860       else if (unformat (i, "multipath"))
6861         is_multipath = 1;
6862       else if (unformat (i, "count %d", &count))
6863         ;
6864       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6865         {
6866           next_hop_set = 1;
6867           next_hop_proto_is_ip4 = 1;
6868         }
6869       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6870         {
6871           next_hop_set = 1;
6872           next_hop_proto_is_ip4 = 0;
6873         }
6874       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6875         ;
6876       else if (unformat (i, "via-label %d", &next_hop_via_label))
6877         ;
6878       else if (unformat (i, "out-label %d", &next_hop_out_label))
6879         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6880       else
6881         {
6882           clib_warning ("parse error '%U'", format_unformat_error, i);
6883           return -99;
6884         }
6885     }
6886
6887   if (!next_hop_set && !is_classify)
6888     {
6889       errmsg ("next hop / classify not set");
6890       return -99;
6891     }
6892
6893   if (MPLS_LABEL_INVALID == local_label)
6894     {
6895       errmsg ("missing label");
6896       return -99;
6897     }
6898
6899   if (count > 1)
6900     {
6901       /* Turn on async mode */
6902       vam->async_mode = 1;
6903       vam->async_errors = 0;
6904       before = vat_time_now (vam);
6905     }
6906
6907   for (j = 0; j < count; j++)
6908     {
6909       /* Construct the API message */
6910       M2 (MPLS_ROUTE_ADD_DEL, mp,
6911           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6912
6913       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6914       mp->mr_table_id = ntohl (table_id);
6915       mp->mr_create_table_if_needed = create_table_if_needed;
6916
6917       mp->mr_is_add = is_add;
6918       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6919       mp->mr_is_classify = is_classify;
6920       mp->mr_is_multipath = is_multipath;
6921       mp->mr_is_resolve_host = resolve_host;
6922       mp->mr_is_resolve_attached = resolve_attached;
6923       mp->mr_next_hop_weight = next_hop_weight;
6924       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6925       mp->mr_classify_table_index = ntohl (classify_table_index);
6926       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6927       mp->mr_label = ntohl (local_label);
6928       mp->mr_eos = is_eos;
6929
6930       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6931       if (0 != mp->mr_next_hop_n_out_labels)
6932         {
6933           memcpy (mp->mr_next_hop_out_label_stack,
6934                   next_hop_out_label_stack,
6935                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6936           vec_free (next_hop_out_label_stack);
6937         }
6938
6939       if (next_hop_set)
6940         {
6941           if (next_hop_proto_is_ip4)
6942             {
6943               clib_memcpy (mp->mr_next_hop,
6944                            &v4_next_hop_address,
6945                            sizeof (v4_next_hop_address));
6946             }
6947           else
6948             {
6949               clib_memcpy (mp->mr_next_hop,
6950                            &v6_next_hop_address,
6951                            sizeof (v6_next_hop_address));
6952             }
6953         }
6954       local_label++;
6955
6956       /* send it... */
6957       S (mp);
6958       /* If we receive SIGTERM, stop now... */
6959       if (vam->do_exit)
6960         break;
6961     }
6962
6963   /* When testing multiple add/del ops, use a control-ping to sync */
6964   if (count > 1)
6965     {
6966       vl_api_control_ping_t *mp_ping;
6967       f64 after;
6968       f64 timeout;
6969
6970       /* Shut off async mode */
6971       vam->async_mode = 0;
6972
6973       M (CONTROL_PING, mp_ping);
6974       S (mp_ping);
6975
6976       timeout = vat_time_now (vam) + 1.0;
6977       while (vat_time_now (vam) < timeout)
6978         if (vam->result_ready == 1)
6979           goto out;
6980       vam->retval = -99;
6981
6982     out:
6983       if (vam->retval == -99)
6984         errmsg ("timeout");
6985
6986       if (vam->async_errors > 0)
6987         {
6988           errmsg ("%d asynchronous errors", vam->async_errors);
6989           vam->retval = -98;
6990         }
6991       vam->async_errors = 0;
6992       after = vat_time_now (vam);
6993
6994       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6995       if (j > 0)
6996         count = j;
6997
6998       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6999              count, after - before, count / (after - before));
7000     }
7001   else
7002     {
7003       int ret;
7004
7005       /* Wait for a reply... */
7006       W (ret);
7007       return ret;
7008     }
7009
7010   /* Return the good/bad news */
7011   return (vam->retval);
7012 }
7013
7014 static int
7015 api_mpls_ip_bind_unbind (vat_main_t * vam)
7016 {
7017   unformat_input_t *i = vam->input;
7018   vl_api_mpls_ip_bind_unbind_t *mp;
7019   u32 ip_table_id = 0;
7020   u8 create_table_if_needed = 0;
7021   u8 is_bind = 1;
7022   u8 is_ip4 = 1;
7023   ip4_address_t v4_address;
7024   ip6_address_t v6_address;
7025   u32 address_length;
7026   u8 address_set = 0;
7027   mpls_label_t local_label = MPLS_LABEL_INVALID;
7028   int ret;
7029
7030   /* Parse args required to build the message */
7031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7032     {
7033       if (unformat (i, "%U/%d", unformat_ip4_address,
7034                     &v4_address, &address_length))
7035         {
7036           is_ip4 = 1;
7037           address_set = 1;
7038         }
7039       else if (unformat (i, "%U/%d", unformat_ip6_address,
7040                          &v6_address, &address_length))
7041         {
7042           is_ip4 = 0;
7043           address_set = 1;
7044         }
7045       else if (unformat (i, "%d", &local_label))
7046         ;
7047       else if (unformat (i, "create-table"))
7048         create_table_if_needed = 1;
7049       else if (unformat (i, "table-id %d", &ip_table_id))
7050         ;
7051       else if (unformat (i, "unbind"))
7052         is_bind = 0;
7053       else if (unformat (i, "bind"))
7054         is_bind = 1;
7055       else
7056         {
7057           clib_warning ("parse error '%U'", format_unformat_error, i);
7058           return -99;
7059         }
7060     }
7061
7062   if (!address_set)
7063     {
7064       errmsg ("IP addres not set");
7065       return -99;
7066     }
7067
7068   if (MPLS_LABEL_INVALID == local_label)
7069     {
7070       errmsg ("missing label");
7071       return -99;
7072     }
7073
7074   /* Construct the API message */
7075   M (MPLS_IP_BIND_UNBIND, mp);
7076
7077   mp->mb_create_table_if_needed = create_table_if_needed;
7078   mp->mb_is_bind = is_bind;
7079   mp->mb_is_ip4 = is_ip4;
7080   mp->mb_ip_table_id = ntohl (ip_table_id);
7081   mp->mb_mpls_table_id = 0;
7082   mp->mb_label = ntohl (local_label);
7083   mp->mb_address_length = address_length;
7084
7085   if (is_ip4)
7086     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
7087   else
7088     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
7089
7090   /* send it... */
7091   S (mp);
7092
7093   /* Wait for a reply... */
7094   W (ret);
7095   return ret;
7096 }
7097
7098 static int
7099 api_proxy_arp_add_del (vat_main_t * vam)
7100 {
7101   unformat_input_t *i = vam->input;
7102   vl_api_proxy_arp_add_del_t *mp;
7103   u32 vrf_id = 0;
7104   u8 is_add = 1;
7105   ip4_address_t lo, hi;
7106   u8 range_set = 0;
7107   int ret;
7108
7109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7110     {
7111       if (unformat (i, "vrf %d", &vrf_id))
7112         ;
7113       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
7114                          unformat_ip4_address, &hi))
7115         range_set = 1;
7116       else if (unformat (i, "del"))
7117         is_add = 0;
7118       else
7119         {
7120           clib_warning ("parse error '%U'", format_unformat_error, i);
7121           return -99;
7122         }
7123     }
7124
7125   if (range_set == 0)
7126     {
7127       errmsg ("address range not set");
7128       return -99;
7129     }
7130
7131   M (PROXY_ARP_ADD_DEL, mp);
7132
7133   mp->vrf_id = ntohl (vrf_id);
7134   mp->is_add = is_add;
7135   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
7136   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
7137
7138   S (mp);
7139   W (ret);
7140   return ret;
7141 }
7142
7143 static int
7144 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
7145 {
7146   unformat_input_t *i = vam->input;
7147   vl_api_proxy_arp_intfc_enable_disable_t *mp;
7148   u32 sw_if_index;
7149   u8 enable = 1;
7150   u8 sw_if_index_set = 0;
7151   int ret;
7152
7153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7154     {
7155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7156         sw_if_index_set = 1;
7157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7158         sw_if_index_set = 1;
7159       else if (unformat (i, "enable"))
7160         enable = 1;
7161       else if (unformat (i, "disable"))
7162         enable = 0;
7163       else
7164         {
7165           clib_warning ("parse error '%U'", format_unformat_error, i);
7166           return -99;
7167         }
7168     }
7169
7170   if (sw_if_index_set == 0)
7171     {
7172       errmsg ("missing interface name or sw_if_index");
7173       return -99;
7174     }
7175
7176   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
7177
7178   mp->sw_if_index = ntohl (sw_if_index);
7179   mp->enable_disable = enable;
7180
7181   S (mp);
7182   W (ret);
7183   return ret;
7184 }
7185
7186 static int
7187 api_mpls_tunnel_add_del (vat_main_t * vam)
7188 {
7189   unformat_input_t *i = vam->input;
7190   vl_api_mpls_tunnel_add_del_t *mp;
7191
7192   u8 is_add = 1;
7193   u8 l2_only = 0;
7194   u32 sw_if_index = ~0;
7195   u32 next_hop_sw_if_index = ~0;
7196   u32 next_hop_proto_is_ip4 = 1;
7197
7198   u32 next_hop_table_id = 0;
7199   ip4_address_t v4_next_hop_address = {
7200     .as_u32 = 0,
7201   };
7202   ip6_address_t v6_next_hop_address = { {0} };
7203   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
7204   int ret;
7205
7206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7207     {
7208       if (unformat (i, "add"))
7209         is_add = 1;
7210       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
7211         is_add = 0;
7212       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
7213         ;
7214       else if (unformat (i, "via %U",
7215                          unformat_ip4_address, &v4_next_hop_address))
7216         {
7217           next_hop_proto_is_ip4 = 1;
7218         }
7219       else if (unformat (i, "via %U",
7220                          unformat_ip6_address, &v6_next_hop_address))
7221         {
7222           next_hop_proto_is_ip4 = 0;
7223         }
7224       else if (unformat (i, "l2-only"))
7225         l2_only = 1;
7226       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7227         ;
7228       else if (unformat (i, "out-label %d", &next_hop_out_label))
7229         vec_add1 (labels, ntohl (next_hop_out_label));
7230       else
7231         {
7232           clib_warning ("parse error '%U'", format_unformat_error, i);
7233           return -99;
7234         }
7235     }
7236
7237   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
7238
7239   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
7240   mp->mt_sw_if_index = ntohl (sw_if_index);
7241   mp->mt_is_add = is_add;
7242   mp->mt_l2_only = l2_only;
7243   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
7244   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
7245
7246   mp->mt_next_hop_n_out_labels = vec_len (labels);
7247
7248   if (0 != mp->mt_next_hop_n_out_labels)
7249     {
7250       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
7251                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
7252       vec_free (labels);
7253     }
7254
7255   if (next_hop_proto_is_ip4)
7256     {
7257       clib_memcpy (mp->mt_next_hop,
7258                    &v4_next_hop_address, sizeof (v4_next_hop_address));
7259     }
7260   else
7261     {
7262       clib_memcpy (mp->mt_next_hop,
7263                    &v6_next_hop_address, sizeof (v6_next_hop_address));
7264     }
7265
7266   S (mp);
7267   W (ret);
7268   return ret;
7269 }
7270
7271 static int
7272 api_sw_interface_set_unnumbered (vat_main_t * vam)
7273 {
7274   unformat_input_t *i = vam->input;
7275   vl_api_sw_interface_set_unnumbered_t *mp;
7276   u32 sw_if_index;
7277   u32 unnum_sw_index = ~0;
7278   u8 is_add = 1;
7279   u8 sw_if_index_set = 0;
7280   int ret;
7281
7282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7283     {
7284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7285         sw_if_index_set = 1;
7286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7287         sw_if_index_set = 1;
7288       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
7289         ;
7290       else if (unformat (i, "del"))
7291         is_add = 0;
7292       else
7293         {
7294           clib_warning ("parse error '%U'", format_unformat_error, i);
7295           return -99;
7296         }
7297     }
7298
7299   if (sw_if_index_set == 0)
7300     {
7301       errmsg ("missing interface name or sw_if_index");
7302       return -99;
7303     }
7304
7305   M (SW_INTERFACE_SET_UNNUMBERED, mp);
7306
7307   mp->sw_if_index = ntohl (sw_if_index);
7308   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
7309   mp->is_add = is_add;
7310
7311   S (mp);
7312   W (ret);
7313   return ret;
7314 }
7315
7316 static int
7317 api_ip_neighbor_add_del (vat_main_t * vam)
7318 {
7319   unformat_input_t *i = vam->input;
7320   vl_api_ip_neighbor_add_del_t *mp;
7321   u32 sw_if_index;
7322   u8 sw_if_index_set = 0;
7323   u8 is_add = 1;
7324   u8 is_static = 0;
7325   u8 is_no_fib_entry = 0;
7326   u8 mac_address[6];
7327   u8 mac_set = 0;
7328   u8 v4_address_set = 0;
7329   u8 v6_address_set = 0;
7330   ip4_address_t v4address;
7331   ip6_address_t v6address;
7332   int ret;
7333
7334   memset (mac_address, 0, sizeof (mac_address));
7335
7336   /* Parse args required to build the message */
7337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7338     {
7339       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7340         {
7341           mac_set = 1;
7342         }
7343       else if (unformat (i, "del"))
7344         is_add = 0;
7345       else
7346         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7347         sw_if_index_set = 1;
7348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7349         sw_if_index_set = 1;
7350       else if (unformat (i, "is_static"))
7351         is_static = 1;
7352       else if (unformat (i, "no-fib-entry"))
7353         is_no_fib_entry = 1;
7354       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
7355         v4_address_set = 1;
7356       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
7357         v6_address_set = 1;
7358       else
7359         {
7360           clib_warning ("parse error '%U'", format_unformat_error, i);
7361           return -99;
7362         }
7363     }
7364
7365   if (sw_if_index_set == 0)
7366     {
7367       errmsg ("missing interface name or sw_if_index");
7368       return -99;
7369     }
7370   if (v4_address_set && v6_address_set)
7371     {
7372       errmsg ("both v4 and v6 addresses set");
7373       return -99;
7374     }
7375   if (!v4_address_set && !v6_address_set)
7376     {
7377       errmsg ("no address set");
7378       return -99;
7379     }
7380
7381   /* Construct the API message */
7382   M (IP_NEIGHBOR_ADD_DEL, mp);
7383
7384   mp->sw_if_index = ntohl (sw_if_index);
7385   mp->is_add = is_add;
7386   mp->is_static = is_static;
7387   mp->is_no_adj_fib = is_no_fib_entry;
7388   if (mac_set)
7389     clib_memcpy (mp->mac_address, mac_address, 6);
7390   if (v6_address_set)
7391     {
7392       mp->is_ipv6 = 1;
7393       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
7394     }
7395   else
7396     {
7397       /* mp->is_ipv6 = 0; via memset in M macro above */
7398       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
7399     }
7400
7401   /* send it... */
7402   S (mp);
7403
7404   /* Wait for a reply, return good/bad news  */
7405   W (ret);
7406   return ret;
7407 }
7408
7409 static int
7410 api_reset_vrf (vat_main_t * vam)
7411 {
7412   unformat_input_t *i = vam->input;
7413   vl_api_reset_vrf_t *mp;
7414   u32 vrf_id = 0;
7415   u8 is_ipv6 = 0;
7416   u8 vrf_id_set = 0;
7417   int ret;
7418
7419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7420     {
7421       if (unformat (i, "vrf %d", &vrf_id))
7422         vrf_id_set = 1;
7423       else if (unformat (i, "ipv6"))
7424         is_ipv6 = 1;
7425       else
7426         {
7427           clib_warning ("parse error '%U'", format_unformat_error, i);
7428           return -99;
7429         }
7430     }
7431
7432   if (vrf_id_set == 0)
7433     {
7434       errmsg ("missing vrf id");
7435       return -99;
7436     }
7437
7438   M (RESET_VRF, mp);
7439
7440   mp->vrf_id = ntohl (vrf_id);
7441   mp->is_ipv6 = is_ipv6;
7442
7443   S (mp);
7444   W (ret);
7445   return ret;
7446 }
7447
7448 static int
7449 api_create_vlan_subif (vat_main_t * vam)
7450 {
7451   unformat_input_t *i = vam->input;
7452   vl_api_create_vlan_subif_t *mp;
7453   u32 sw_if_index;
7454   u8 sw_if_index_set = 0;
7455   u32 vlan_id;
7456   u8 vlan_id_set = 0;
7457   int ret;
7458
7459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7460     {
7461       if (unformat (i, "sw_if_index %d", &sw_if_index))
7462         sw_if_index_set = 1;
7463       else
7464         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7465         sw_if_index_set = 1;
7466       else if (unformat (i, "vlan %d", &vlan_id))
7467         vlan_id_set = 1;
7468       else
7469         {
7470           clib_warning ("parse error '%U'", format_unformat_error, i);
7471           return -99;
7472         }
7473     }
7474
7475   if (sw_if_index_set == 0)
7476     {
7477       errmsg ("missing interface name or sw_if_index");
7478       return -99;
7479     }
7480
7481   if (vlan_id_set == 0)
7482     {
7483       errmsg ("missing vlan_id");
7484       return -99;
7485     }
7486   M (CREATE_VLAN_SUBIF, mp);
7487
7488   mp->sw_if_index = ntohl (sw_if_index);
7489   mp->vlan_id = ntohl (vlan_id);
7490
7491   S (mp);
7492   W (ret);
7493   return ret;
7494 }
7495
7496 #define foreach_create_subif_bit                \
7497 _(no_tags)                                      \
7498 _(one_tag)                                      \
7499 _(two_tags)                                     \
7500 _(dot1ad)                                       \
7501 _(exact_match)                                  \
7502 _(default_sub)                                  \
7503 _(outer_vlan_id_any)                            \
7504 _(inner_vlan_id_any)
7505
7506 static int
7507 api_create_subif (vat_main_t * vam)
7508 {
7509   unformat_input_t *i = vam->input;
7510   vl_api_create_subif_t *mp;
7511   u32 sw_if_index;
7512   u8 sw_if_index_set = 0;
7513   u32 sub_id;
7514   u8 sub_id_set = 0;
7515   u32 no_tags = 0;
7516   u32 one_tag = 0;
7517   u32 two_tags = 0;
7518   u32 dot1ad = 0;
7519   u32 exact_match = 0;
7520   u32 default_sub = 0;
7521   u32 outer_vlan_id_any = 0;
7522   u32 inner_vlan_id_any = 0;
7523   u32 tmp;
7524   u16 outer_vlan_id = 0;
7525   u16 inner_vlan_id = 0;
7526   int ret;
7527
7528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7529     {
7530       if (unformat (i, "sw_if_index %d", &sw_if_index))
7531         sw_if_index_set = 1;
7532       else
7533         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7534         sw_if_index_set = 1;
7535       else if (unformat (i, "sub_id %d", &sub_id))
7536         sub_id_set = 1;
7537       else if (unformat (i, "outer_vlan_id %d", &tmp))
7538         outer_vlan_id = tmp;
7539       else if (unformat (i, "inner_vlan_id %d", &tmp))
7540         inner_vlan_id = tmp;
7541
7542 #define _(a) else if (unformat (i, #a)) a = 1 ;
7543       foreach_create_subif_bit
7544 #undef _
7545         else
7546         {
7547           clib_warning ("parse error '%U'", format_unformat_error, i);
7548           return -99;
7549         }
7550     }
7551
7552   if (sw_if_index_set == 0)
7553     {
7554       errmsg ("missing interface name or sw_if_index");
7555       return -99;
7556     }
7557
7558   if (sub_id_set == 0)
7559     {
7560       errmsg ("missing sub_id");
7561       return -99;
7562     }
7563   M (CREATE_SUBIF, mp);
7564
7565   mp->sw_if_index = ntohl (sw_if_index);
7566   mp->sub_id = ntohl (sub_id);
7567
7568 #define _(a) mp->a = a;
7569   foreach_create_subif_bit;
7570 #undef _
7571
7572   mp->outer_vlan_id = ntohs (outer_vlan_id);
7573   mp->inner_vlan_id = ntohs (inner_vlan_id);
7574
7575   S (mp);
7576   W (ret);
7577   return ret;
7578 }
7579
7580 static int
7581 api_oam_add_del (vat_main_t * vam)
7582 {
7583   unformat_input_t *i = vam->input;
7584   vl_api_oam_add_del_t *mp;
7585   u32 vrf_id = 0;
7586   u8 is_add = 1;
7587   ip4_address_t src, dst;
7588   u8 src_set = 0;
7589   u8 dst_set = 0;
7590   int ret;
7591
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "vrf %d", &vrf_id))
7595         ;
7596       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7597         src_set = 1;
7598       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7599         dst_set = 1;
7600       else if (unformat (i, "del"))
7601         is_add = 0;
7602       else
7603         {
7604           clib_warning ("parse error '%U'", format_unformat_error, i);
7605           return -99;
7606         }
7607     }
7608
7609   if (src_set == 0)
7610     {
7611       errmsg ("missing src addr");
7612       return -99;
7613     }
7614
7615   if (dst_set == 0)
7616     {
7617       errmsg ("missing dst addr");
7618       return -99;
7619     }
7620
7621   M (OAM_ADD_DEL, mp);
7622
7623   mp->vrf_id = ntohl (vrf_id);
7624   mp->is_add = is_add;
7625   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7626   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7627
7628   S (mp);
7629   W (ret);
7630   return ret;
7631 }
7632
7633 static int
7634 api_reset_fib (vat_main_t * vam)
7635 {
7636   unformat_input_t *i = vam->input;
7637   vl_api_reset_fib_t *mp;
7638   u32 vrf_id = 0;
7639   u8 is_ipv6 = 0;
7640   u8 vrf_id_set = 0;
7641
7642   int ret;
7643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7644     {
7645       if (unformat (i, "vrf %d", &vrf_id))
7646         vrf_id_set = 1;
7647       else if (unformat (i, "ipv6"))
7648         is_ipv6 = 1;
7649       else
7650         {
7651           clib_warning ("parse error '%U'", format_unformat_error, i);
7652           return -99;
7653         }
7654     }
7655
7656   if (vrf_id_set == 0)
7657     {
7658       errmsg ("missing vrf id");
7659       return -99;
7660     }
7661
7662   M (RESET_FIB, mp);
7663
7664   mp->vrf_id = ntohl (vrf_id);
7665   mp->is_ipv6 = is_ipv6;
7666
7667   S (mp);
7668   W (ret);
7669   return ret;
7670 }
7671
7672 static int
7673 api_dhcp_proxy_config (vat_main_t * vam)
7674 {
7675   unformat_input_t *i = vam->input;
7676   vl_api_dhcp_proxy_config_t *mp;
7677   u32 rx_vrf_id = 0;
7678   u32 server_vrf_id = 0;
7679   u8 is_add = 1;
7680   u8 v4_address_set = 0;
7681   u8 v6_address_set = 0;
7682   ip4_address_t v4address;
7683   ip6_address_t v6address;
7684   u8 v4_src_address_set = 0;
7685   u8 v6_src_address_set = 0;
7686   ip4_address_t v4srcaddress;
7687   ip6_address_t v6srcaddress;
7688   int ret;
7689
7690   /* Parse args required to build the message */
7691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7692     {
7693       if (unformat (i, "del"))
7694         is_add = 0;
7695       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7696         ;
7697       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7698         ;
7699       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7700         v4_address_set = 1;
7701       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7702         v6_address_set = 1;
7703       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7704         v4_src_address_set = 1;
7705       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7706         v6_src_address_set = 1;
7707       else
7708         break;
7709     }
7710
7711   if (v4_address_set && v6_address_set)
7712     {
7713       errmsg ("both v4 and v6 server addresses set");
7714       return -99;
7715     }
7716   if (!v4_address_set && !v6_address_set)
7717     {
7718       errmsg ("no server addresses set");
7719       return -99;
7720     }
7721
7722   if (v4_src_address_set && v6_src_address_set)
7723     {
7724       errmsg ("both v4 and v6  src addresses set");
7725       return -99;
7726     }
7727   if (!v4_src_address_set && !v6_src_address_set)
7728     {
7729       errmsg ("no src addresses set");
7730       return -99;
7731     }
7732
7733   if (!(v4_src_address_set && v4_address_set) &&
7734       !(v6_src_address_set && v6_address_set))
7735     {
7736       errmsg ("no matching server and src addresses set");
7737       return -99;
7738     }
7739
7740   /* Construct the API message */
7741   M (DHCP_PROXY_CONFIG, mp);
7742
7743   mp->is_add = is_add;
7744   mp->rx_vrf_id = ntohl (rx_vrf_id);
7745   mp->server_vrf_id = ntohl (server_vrf_id);
7746   if (v6_address_set)
7747     {
7748       mp->is_ipv6 = 1;
7749       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7750       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7751     }
7752   else
7753     {
7754       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7755       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7756     }
7757
7758   /* send it... */
7759   S (mp);
7760
7761   /* Wait for a reply, return good/bad news  */
7762   W (ret);
7763   return ret;
7764 }
7765
7766 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
7767 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
7768
7769 static void
7770 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
7771 {
7772   vat_main_t *vam = &vat_main;
7773   u32 i, count = mp->count;
7774   vl_api_dhcp_server_t *s;
7775
7776   if (mp->is_ipv6)
7777     print (vam->ofp,
7778            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7779            ntohl (mp->rx_vrf_id),
7780            format_ip6_address, mp->dhcp_src_address,
7781            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7782   else
7783     print (vam->ofp,
7784            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
7785            ntohl (mp->rx_vrf_id),
7786            format_ip4_address, mp->dhcp_src_address,
7787            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
7788
7789   for (i = 0; i < count; i++)
7790     {
7791       s = &mp->servers[i];
7792
7793       if (mp->is_ipv6)
7794         print (vam->ofp,
7795                " Server Table-ID %d, Server Address %U",
7796                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
7797       else
7798         print (vam->ofp,
7799                " Server Table-ID %d, Server Address %U",
7800                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
7801     }
7802 }
7803
7804 static void vl_api_dhcp_proxy_details_t_handler_json
7805   (vl_api_dhcp_proxy_details_t * mp)
7806 {
7807   vat_main_t *vam = &vat_main;
7808   vat_json_node_t *node = NULL;
7809   u32 i, count = mp->count;
7810   struct in_addr ip4;
7811   struct in6_addr ip6;
7812   vl_api_dhcp_server_t *s;
7813
7814   if (VAT_JSON_ARRAY != vam->json_tree.type)
7815     {
7816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7817       vat_json_init_array (&vam->json_tree);
7818     }
7819   node = vat_json_array_add (&vam->json_tree);
7820
7821   vat_json_init_object (node);
7822   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
7823   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
7824   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
7825
7826   if (mp->is_ipv6)
7827     {
7828       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
7829       vat_json_object_add_ip6 (node, "src_address", ip6);
7830     }
7831   else
7832     {
7833       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
7834       vat_json_object_add_ip4 (node, "src_address", ip4);
7835     }
7836
7837   for (i = 0; i < count; i++)
7838     {
7839       s = &mp->servers[i];
7840
7841       vat_json_object_add_uint (node, "server-table-id",
7842                                 ntohl (s->server_vrf_id));
7843
7844       if (mp->is_ipv6)
7845         {
7846           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
7847           vat_json_object_add_ip4 (node, "src_address", ip4);
7848         }
7849       else
7850         {
7851           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
7852           vat_json_object_add_ip6 (node, "server_address", ip6);
7853         }
7854     }
7855 }
7856
7857 static int
7858 api_dhcp_proxy_dump (vat_main_t * vam)
7859 {
7860   unformat_input_t *i = vam->input;
7861   vl_api_control_ping_t *mp_ping;
7862   vl_api_dhcp_proxy_dump_t *mp;
7863   u8 is_ipv6 = 0;
7864   int ret;
7865
7866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7867     {
7868       if (unformat (i, "ipv6"))
7869         is_ipv6 = 1;
7870       else
7871         {
7872           clib_warning ("parse error '%U'", format_unformat_error, i);
7873           return -99;
7874         }
7875     }
7876
7877   M (DHCP_PROXY_DUMP, mp);
7878
7879   mp->is_ip6 = is_ipv6;
7880   S (mp);
7881
7882   /* Use a control ping for synchronization */
7883   M (CONTROL_PING, mp_ping);
7884   S (mp_ping);
7885
7886   W (ret);
7887   return ret;
7888 }
7889
7890 static int
7891 api_dhcp_proxy_set_vss (vat_main_t * vam)
7892 {
7893   unformat_input_t *i = vam->input;
7894   vl_api_dhcp_proxy_set_vss_t *mp;
7895   u8 is_ipv6 = 0;
7896   u8 is_add = 1;
7897   u32 tbl_id;
7898   u8 tbl_id_set = 0;
7899   u32 oui;
7900   u8 oui_set = 0;
7901   u32 fib_id;
7902   u8 fib_id_set = 0;
7903   int ret;
7904
7905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7906     {
7907       if (unformat (i, "tbl_id %d", &tbl_id))
7908         tbl_id_set = 1;
7909       if (unformat (i, "fib_id %d", &fib_id))
7910         fib_id_set = 1;
7911       if (unformat (i, "oui %d", &oui))
7912         oui_set = 1;
7913       else if (unformat (i, "ipv6"))
7914         is_ipv6 = 1;
7915       else if (unformat (i, "del"))
7916         is_add = 0;
7917       else
7918         {
7919           clib_warning ("parse error '%U'", format_unformat_error, i);
7920           return -99;
7921         }
7922     }
7923
7924   if (tbl_id_set == 0)
7925     {
7926       errmsg ("missing tbl id");
7927       return -99;
7928     }
7929
7930   if (fib_id_set == 0)
7931     {
7932       errmsg ("missing fib id");
7933       return -99;
7934     }
7935   if (oui_set == 0)
7936     {
7937       errmsg ("missing oui");
7938       return -99;
7939     }
7940
7941   M (DHCP_PROXY_SET_VSS, mp);
7942   mp->tbl_id = ntohl (tbl_id);
7943   mp->fib_id = ntohl (fib_id);
7944   mp->oui = ntohl (oui);
7945   mp->is_ipv6 = is_ipv6;
7946   mp->is_add = is_add;
7947
7948   S (mp);
7949   W (ret);
7950   return ret;
7951 }
7952
7953 static int
7954 api_dhcp_client_config (vat_main_t * vam)
7955 {
7956   unformat_input_t *i = vam->input;
7957   vl_api_dhcp_client_config_t *mp;
7958   u32 sw_if_index;
7959   u8 sw_if_index_set = 0;
7960   u8 is_add = 1;
7961   u8 *hostname = 0;
7962   u8 disable_event = 0;
7963   int ret;
7964
7965   /* Parse args required to build the message */
7966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7967     {
7968       if (unformat (i, "del"))
7969         is_add = 0;
7970       else
7971         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7972         sw_if_index_set = 1;
7973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7974         sw_if_index_set = 1;
7975       else if (unformat (i, "hostname %s", &hostname))
7976         ;
7977       else if (unformat (i, "disable_event"))
7978         disable_event = 1;
7979       else
7980         break;
7981     }
7982
7983   if (sw_if_index_set == 0)
7984     {
7985       errmsg ("missing interface name or sw_if_index");
7986       return -99;
7987     }
7988
7989   if (vec_len (hostname) > 63)
7990     {
7991       errmsg ("hostname too long");
7992     }
7993   vec_add1 (hostname, 0);
7994
7995   /* Construct the API message */
7996   M (DHCP_CLIENT_CONFIG, mp);
7997
7998   mp->sw_if_index = ntohl (sw_if_index);
7999   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
8000   vec_free (hostname);
8001   mp->is_add = is_add;
8002   mp->want_dhcp_event = disable_event ? 0 : 1;
8003   mp->pid = getpid ();
8004
8005   /* send it... */
8006   S (mp);
8007
8008   /* Wait for a reply, return good/bad news  */
8009   W (ret);
8010   return ret;
8011 }
8012
8013 static int
8014 api_set_ip_flow_hash (vat_main_t * vam)
8015 {
8016   unformat_input_t *i = vam->input;
8017   vl_api_set_ip_flow_hash_t *mp;
8018   u32 vrf_id = 0;
8019   u8 is_ipv6 = 0;
8020   u8 vrf_id_set = 0;
8021   u8 src = 0;
8022   u8 dst = 0;
8023   u8 sport = 0;
8024   u8 dport = 0;
8025   u8 proto = 0;
8026   u8 reverse = 0;
8027   int ret;
8028
8029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8030     {
8031       if (unformat (i, "vrf %d", &vrf_id))
8032         vrf_id_set = 1;
8033       else if (unformat (i, "ipv6"))
8034         is_ipv6 = 1;
8035       else if (unformat (i, "src"))
8036         src = 1;
8037       else if (unformat (i, "dst"))
8038         dst = 1;
8039       else if (unformat (i, "sport"))
8040         sport = 1;
8041       else if (unformat (i, "dport"))
8042         dport = 1;
8043       else if (unformat (i, "proto"))
8044         proto = 1;
8045       else if (unformat (i, "reverse"))
8046         reverse = 1;
8047
8048       else
8049         {
8050           clib_warning ("parse error '%U'", format_unformat_error, i);
8051           return -99;
8052         }
8053     }
8054
8055   if (vrf_id_set == 0)
8056     {
8057       errmsg ("missing vrf id");
8058       return -99;
8059     }
8060
8061   M (SET_IP_FLOW_HASH, mp);
8062   mp->src = src;
8063   mp->dst = dst;
8064   mp->sport = sport;
8065   mp->dport = dport;
8066   mp->proto = proto;
8067   mp->reverse = reverse;
8068   mp->vrf_id = ntohl (vrf_id);
8069   mp->is_ipv6 = is_ipv6;
8070
8071   S (mp);
8072   W (ret);
8073   return ret;
8074 }
8075
8076 static int
8077 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
8078 {
8079   unformat_input_t *i = vam->input;
8080   vl_api_sw_interface_ip6_enable_disable_t *mp;
8081   u32 sw_if_index;
8082   u8 sw_if_index_set = 0;
8083   u8 enable = 0;
8084   int ret;
8085
8086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8087     {
8088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8089         sw_if_index_set = 1;
8090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8091         sw_if_index_set = 1;
8092       else if (unformat (i, "enable"))
8093         enable = 1;
8094       else if (unformat (i, "disable"))
8095         enable = 0;
8096       else
8097         {
8098           clib_warning ("parse error '%U'", format_unformat_error, i);
8099           return -99;
8100         }
8101     }
8102
8103   if (sw_if_index_set == 0)
8104     {
8105       errmsg ("missing interface name or sw_if_index");
8106       return -99;
8107     }
8108
8109   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
8110
8111   mp->sw_if_index = ntohl (sw_if_index);
8112   mp->enable = enable;
8113
8114   S (mp);
8115   W (ret);
8116   return ret;
8117 }
8118
8119 static int
8120 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
8121 {
8122   unformat_input_t *i = vam->input;
8123   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
8124   u32 sw_if_index;
8125   u8 sw_if_index_set = 0;
8126   u8 v6_address_set = 0;
8127   ip6_address_t v6address;
8128   int ret;
8129
8130   /* Parse args required to build the message */
8131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8132     {
8133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8134         sw_if_index_set = 1;
8135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8136         sw_if_index_set = 1;
8137       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8138         v6_address_set = 1;
8139       else
8140         break;
8141     }
8142
8143   if (sw_if_index_set == 0)
8144     {
8145       errmsg ("missing interface name or sw_if_index");
8146       return -99;
8147     }
8148   if (!v6_address_set)
8149     {
8150       errmsg ("no address set");
8151       return -99;
8152     }
8153
8154   /* Construct the API message */
8155   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
8156
8157   mp->sw_if_index = ntohl (sw_if_index);
8158   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8159
8160   /* send it... */
8161   S (mp);
8162
8163   /* Wait for a reply, return good/bad news  */
8164   W (ret);
8165   return ret;
8166 }
8167
8168 static int
8169 api_ip6nd_proxy_add_del (vat_main_t * vam)
8170 {
8171   unformat_input_t *i = vam->input;
8172   vl_api_ip6nd_proxy_add_del_t *mp;
8173   u32 sw_if_index = ~0;
8174   u8 v6_address_set = 0;
8175   ip6_address_t v6address;
8176   u8 is_del = 0;
8177   int ret;
8178
8179   /* Parse args required to build the message */
8180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8181     {
8182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8183         ;
8184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8185         ;
8186       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
8187         v6_address_set = 1;
8188       if (unformat (i, "del"))
8189         is_del = 1;
8190       else
8191         {
8192           clib_warning ("parse error '%U'", format_unformat_error, i);
8193           return -99;
8194         }
8195     }
8196
8197   if (sw_if_index == ~0)
8198     {
8199       errmsg ("missing interface name or sw_if_index");
8200       return -99;
8201     }
8202   if (!v6_address_set)
8203     {
8204       errmsg ("no address set");
8205       return -99;
8206     }
8207
8208   /* Construct the API message */
8209   M (IP6ND_PROXY_ADD_DEL, mp);
8210
8211   mp->is_del = is_del;
8212   mp->sw_if_index = ntohl (sw_if_index);
8213   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8214
8215   /* send it... */
8216   S (mp);
8217
8218   /* Wait for a reply, return good/bad news  */
8219   W (ret);
8220   return ret;
8221 }
8222
8223 static int
8224 api_ip6nd_proxy_dump (vat_main_t * vam)
8225 {
8226   vl_api_ip6nd_proxy_dump_t *mp;
8227   vl_api_control_ping_t *mp_ping;
8228   int ret;
8229
8230   M (IP6ND_PROXY_DUMP, mp);
8231
8232   S (mp);
8233
8234   /* Use a control ping for synchronization */
8235   M (CONTROL_PING, mp_ping);
8236   S (mp_ping);
8237
8238   W (ret);
8239   return ret;
8240 }
8241
8242 static void vl_api_ip6nd_proxy_details_t_handler
8243   (vl_api_ip6nd_proxy_details_t * mp)
8244 {
8245   vat_main_t *vam = &vat_main;
8246
8247   print (vam->ofp, "host %U sw_if_index %d",
8248          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
8249 }
8250
8251 static void vl_api_ip6nd_proxy_details_t_handler_json
8252   (vl_api_ip6nd_proxy_details_t * mp)
8253 {
8254   vat_main_t *vam = &vat_main;
8255   struct in6_addr ip6;
8256   vat_json_node_t *node = NULL;
8257
8258   if (VAT_JSON_ARRAY != vam->json_tree.type)
8259     {
8260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
8261       vat_json_init_array (&vam->json_tree);
8262     }
8263   node = vat_json_array_add (&vam->json_tree);
8264
8265   vat_json_init_object (node);
8266   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
8267
8268   clib_memcpy (&ip6, mp->address, sizeof (ip6));
8269   vat_json_object_add_ip6 (node, "host", ip6);
8270 }
8271
8272 static int
8273 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
8274 {
8275   unformat_input_t *i = vam->input;
8276   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
8277   u32 sw_if_index;
8278   u8 sw_if_index_set = 0;
8279   u32 address_length = 0;
8280   u8 v6_address_set = 0;
8281   ip6_address_t v6address;
8282   u8 use_default = 0;
8283   u8 no_advertise = 0;
8284   u8 off_link = 0;
8285   u8 no_autoconfig = 0;
8286   u8 no_onlink = 0;
8287   u8 is_no = 0;
8288   u32 val_lifetime = 0;
8289   u32 pref_lifetime = 0;
8290   int ret;
8291
8292   /* Parse args required to build the message */
8293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8294     {
8295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8296         sw_if_index_set = 1;
8297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8298         sw_if_index_set = 1;
8299       else if (unformat (i, "%U/%d",
8300                          unformat_ip6_address, &v6address, &address_length))
8301         v6_address_set = 1;
8302       else if (unformat (i, "val_life %d", &val_lifetime))
8303         ;
8304       else if (unformat (i, "pref_life %d", &pref_lifetime))
8305         ;
8306       else if (unformat (i, "def"))
8307         use_default = 1;
8308       else if (unformat (i, "noadv"))
8309         no_advertise = 1;
8310       else if (unformat (i, "offl"))
8311         off_link = 1;
8312       else if (unformat (i, "noauto"))
8313         no_autoconfig = 1;
8314       else if (unformat (i, "nolink"))
8315         no_onlink = 1;
8316       else if (unformat (i, "isno"))
8317         is_no = 1;
8318       else
8319         {
8320           clib_warning ("parse error '%U'", format_unformat_error, i);
8321           return -99;
8322         }
8323     }
8324
8325   if (sw_if_index_set == 0)
8326     {
8327       errmsg ("missing interface name or sw_if_index");
8328       return -99;
8329     }
8330   if (!v6_address_set)
8331     {
8332       errmsg ("no address set");
8333       return -99;
8334     }
8335
8336   /* Construct the API message */
8337   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
8338
8339   mp->sw_if_index = ntohl (sw_if_index);
8340   clib_memcpy (mp->address, &v6address, sizeof (v6address));
8341   mp->address_length = address_length;
8342   mp->use_default = use_default;
8343   mp->no_advertise = no_advertise;
8344   mp->off_link = off_link;
8345   mp->no_autoconfig = no_autoconfig;
8346   mp->no_onlink = no_onlink;
8347   mp->is_no = is_no;
8348   mp->val_lifetime = ntohl (val_lifetime);
8349   mp->pref_lifetime = ntohl (pref_lifetime);
8350
8351   /* send it... */
8352   S (mp);
8353
8354   /* Wait for a reply, return good/bad news  */
8355   W (ret);
8356   return ret;
8357 }
8358
8359 static int
8360 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
8361 {
8362   unformat_input_t *i = vam->input;
8363   vl_api_sw_interface_ip6nd_ra_config_t *mp;
8364   u32 sw_if_index;
8365   u8 sw_if_index_set = 0;
8366   u8 suppress = 0;
8367   u8 managed = 0;
8368   u8 other = 0;
8369   u8 ll_option = 0;
8370   u8 send_unicast = 0;
8371   u8 cease = 0;
8372   u8 is_no = 0;
8373   u8 default_router = 0;
8374   u32 max_interval = 0;
8375   u32 min_interval = 0;
8376   u32 lifetime = 0;
8377   u32 initial_count = 0;
8378   u32 initial_interval = 0;
8379   int ret;
8380
8381
8382   /* Parse args required to build the message */
8383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8384     {
8385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8386         sw_if_index_set = 1;
8387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8388         sw_if_index_set = 1;
8389       else if (unformat (i, "maxint %d", &max_interval))
8390         ;
8391       else if (unformat (i, "minint %d", &min_interval))
8392         ;
8393       else if (unformat (i, "life %d", &lifetime))
8394         ;
8395       else if (unformat (i, "count %d", &initial_count))
8396         ;
8397       else if (unformat (i, "interval %d", &initial_interval))
8398         ;
8399       else if (unformat (i, "suppress") || unformat (i, "surpress"))
8400         suppress = 1;
8401       else if (unformat (i, "managed"))
8402         managed = 1;
8403       else if (unformat (i, "other"))
8404         other = 1;
8405       else if (unformat (i, "ll"))
8406         ll_option = 1;
8407       else if (unformat (i, "send"))
8408         send_unicast = 1;
8409       else if (unformat (i, "cease"))
8410         cease = 1;
8411       else if (unformat (i, "isno"))
8412         is_no = 1;
8413       else if (unformat (i, "def"))
8414         default_router = 1;
8415       else
8416         {
8417           clib_warning ("parse error '%U'", format_unformat_error, i);
8418           return -99;
8419         }
8420     }
8421
8422   if (sw_if_index_set == 0)
8423     {
8424       errmsg ("missing interface name or sw_if_index");
8425       return -99;
8426     }
8427
8428   /* Construct the API message */
8429   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
8430
8431   mp->sw_if_index = ntohl (sw_if_index);
8432   mp->max_interval = ntohl (max_interval);
8433   mp->min_interval = ntohl (min_interval);
8434   mp->lifetime = ntohl (lifetime);
8435   mp->initial_count = ntohl (initial_count);
8436   mp->initial_interval = ntohl (initial_interval);
8437   mp->suppress = suppress;
8438   mp->managed = managed;
8439   mp->other = other;
8440   mp->ll_option = ll_option;
8441   mp->send_unicast = send_unicast;
8442   mp->cease = cease;
8443   mp->is_no = is_no;
8444   mp->default_router = default_router;
8445
8446   /* send it... */
8447   S (mp);
8448
8449   /* Wait for a reply, return good/bad news  */
8450   W (ret);
8451   return ret;
8452 }
8453
8454 static int
8455 api_set_arp_neighbor_limit (vat_main_t * vam)
8456 {
8457   unformat_input_t *i = vam->input;
8458   vl_api_set_arp_neighbor_limit_t *mp;
8459   u32 arp_nbr_limit;
8460   u8 limit_set = 0;
8461   u8 is_ipv6 = 0;
8462   int ret;
8463
8464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8465     {
8466       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
8467         limit_set = 1;
8468       else if (unformat (i, "ipv6"))
8469         is_ipv6 = 1;
8470       else
8471         {
8472           clib_warning ("parse error '%U'", format_unformat_error, i);
8473           return -99;
8474         }
8475     }
8476
8477   if (limit_set == 0)
8478     {
8479       errmsg ("missing limit value");
8480       return -99;
8481     }
8482
8483   M (SET_ARP_NEIGHBOR_LIMIT, mp);
8484
8485   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
8486   mp->is_ipv6 = is_ipv6;
8487
8488   S (mp);
8489   W (ret);
8490   return ret;
8491 }
8492
8493 static int
8494 api_l2_patch_add_del (vat_main_t * vam)
8495 {
8496   unformat_input_t *i = vam->input;
8497   vl_api_l2_patch_add_del_t *mp;
8498   u32 rx_sw_if_index;
8499   u8 rx_sw_if_index_set = 0;
8500   u32 tx_sw_if_index;
8501   u8 tx_sw_if_index_set = 0;
8502   u8 is_add = 1;
8503   int ret;
8504
8505   /* Parse args required to build the message */
8506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
8509         rx_sw_if_index_set = 1;
8510       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
8511         tx_sw_if_index_set = 1;
8512       else if (unformat (i, "rx"))
8513         {
8514           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8515             {
8516               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8517                             &rx_sw_if_index))
8518                 rx_sw_if_index_set = 1;
8519             }
8520           else
8521             break;
8522         }
8523       else if (unformat (i, "tx"))
8524         {
8525           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8526             {
8527               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8528                             &tx_sw_if_index))
8529                 tx_sw_if_index_set = 1;
8530             }
8531           else
8532             break;
8533         }
8534       else if (unformat (i, "del"))
8535         is_add = 0;
8536       else
8537         break;
8538     }
8539
8540   if (rx_sw_if_index_set == 0)
8541     {
8542       errmsg ("missing rx interface name or rx_sw_if_index");
8543       return -99;
8544     }
8545
8546   if (tx_sw_if_index_set == 0)
8547     {
8548       errmsg ("missing tx interface name or tx_sw_if_index");
8549       return -99;
8550     }
8551
8552   M (L2_PATCH_ADD_DEL, mp);
8553
8554   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8555   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8556   mp->is_add = is_add;
8557
8558   S (mp);
8559   W (ret);
8560   return ret;
8561 }
8562
8563 u8 is_del;
8564 u8 localsid_addr[16];
8565 u8 end_psp;
8566 u8 behavior;
8567 u32 sw_if_index;
8568 u32 vlan_index;
8569 u32 fib_table;
8570 u8 nh_addr[16];
8571
8572 static int
8573 api_sr_localsid_add_del (vat_main_t * vam)
8574 {
8575   unformat_input_t *i = vam->input;
8576   vl_api_sr_localsid_add_del_t *mp;
8577
8578   u8 is_del;
8579   ip6_address_t localsid;
8580   u8 end_psp = 0;
8581   u8 behavior = ~0;
8582   u32 sw_if_index;
8583   u32 fib_table = ~(u32) 0;
8584   ip6_address_t next_hop;
8585
8586   bool nexthop_set = 0;
8587
8588   int ret;
8589
8590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8591     {
8592       if (unformat (i, "del"))
8593         is_del = 1;
8594       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
8595       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
8596         nexthop_set = 1;
8597       else if (unformat (i, "behavior %u", &behavior));
8598       else if (unformat (i, "sw_if_index %u", &sw_if_index));
8599       else if (unformat (i, "fib-table %u", &fib_table));
8600       else if (unformat (i, "end.psp %u", &behavior));
8601       else
8602         break;
8603     }
8604
8605   M (SR_LOCALSID_ADD_DEL, mp);
8606
8607   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
8608   if (nexthop_set)
8609     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
8610   mp->behavior = behavior;
8611   mp->sw_if_index = ntohl (sw_if_index);
8612   mp->fib_table = ntohl (fib_table);
8613   mp->end_psp = end_psp;
8614   mp->is_del = is_del;
8615
8616   S (mp);
8617   W (ret);
8618   return ret;
8619 }
8620
8621 static int
8622 api_ioam_enable (vat_main_t * vam)
8623 {
8624   unformat_input_t *input = vam->input;
8625   vl_api_ioam_enable_t *mp;
8626   u32 id = 0;
8627   int has_trace_option = 0;
8628   int has_pot_option = 0;
8629   int has_seqno_option = 0;
8630   int has_analyse_option = 0;
8631   int ret;
8632
8633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8634     {
8635       if (unformat (input, "trace"))
8636         has_trace_option = 1;
8637       else if (unformat (input, "pot"))
8638         has_pot_option = 1;
8639       else if (unformat (input, "seqno"))
8640         has_seqno_option = 1;
8641       else if (unformat (input, "analyse"))
8642         has_analyse_option = 1;
8643       else
8644         break;
8645     }
8646   M (IOAM_ENABLE, mp);
8647   mp->id = htons (id);
8648   mp->seqno = has_seqno_option;
8649   mp->analyse = has_analyse_option;
8650   mp->pot_enable = has_pot_option;
8651   mp->trace_enable = has_trace_option;
8652
8653   S (mp);
8654   W (ret);
8655   return ret;
8656 }
8657
8658
8659 static int
8660 api_ioam_disable (vat_main_t * vam)
8661 {
8662   vl_api_ioam_disable_t *mp;
8663   int ret;
8664
8665   M (IOAM_DISABLE, mp);
8666   S (mp);
8667   W (ret);
8668   return ret;
8669 }
8670
8671 #define foreach_tcp_proto_field                 \
8672 _(src_port)                                     \
8673 _(dst_port)
8674
8675 #define foreach_udp_proto_field                 \
8676 _(src_port)                                     \
8677 _(dst_port)
8678
8679 #define foreach_ip4_proto_field                 \
8680 _(src_address)                                  \
8681 _(dst_address)                                  \
8682 _(tos)                                          \
8683 _(length)                                       \
8684 _(fragment_id)                                  \
8685 _(ttl)                                          \
8686 _(protocol)                                     \
8687 _(checksum)
8688
8689 typedef struct
8690 {
8691   u16 src_port, dst_port;
8692 } tcpudp_header_t;
8693
8694 #if VPP_API_TEST_BUILTIN == 0
8695 uword
8696 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8697 {
8698   u8 **maskp = va_arg (*args, u8 **);
8699   u8 *mask = 0;
8700   u8 found_something = 0;
8701   tcp_header_t *tcp;
8702
8703 #define _(a) u8 a=0;
8704   foreach_tcp_proto_field;
8705 #undef _
8706
8707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8708     {
8709       if (0);
8710 #define _(a) else if (unformat (input, #a)) a=1;
8711       foreach_tcp_proto_field
8712 #undef _
8713         else
8714         break;
8715     }
8716
8717 #define _(a) found_something += a;
8718   foreach_tcp_proto_field;
8719 #undef _
8720
8721   if (found_something == 0)
8722     return 0;
8723
8724   vec_validate (mask, sizeof (*tcp) - 1);
8725
8726   tcp = (tcp_header_t *) mask;
8727
8728 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8729   foreach_tcp_proto_field;
8730 #undef _
8731
8732   *maskp = mask;
8733   return 1;
8734 }
8735
8736 uword
8737 unformat_udp_mask (unformat_input_t * input, va_list * args)
8738 {
8739   u8 **maskp = va_arg (*args, u8 **);
8740   u8 *mask = 0;
8741   u8 found_something = 0;
8742   udp_header_t *udp;
8743
8744 #define _(a) u8 a=0;
8745   foreach_udp_proto_field;
8746 #undef _
8747
8748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8749     {
8750       if (0);
8751 #define _(a) else if (unformat (input, #a)) a=1;
8752       foreach_udp_proto_field
8753 #undef _
8754         else
8755         break;
8756     }
8757
8758 #define _(a) found_something += a;
8759   foreach_udp_proto_field;
8760 #undef _
8761
8762   if (found_something == 0)
8763     return 0;
8764
8765   vec_validate (mask, sizeof (*udp) - 1);
8766
8767   udp = (udp_header_t *) mask;
8768
8769 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8770   foreach_udp_proto_field;
8771 #undef _
8772
8773   *maskp = mask;
8774   return 1;
8775 }
8776
8777 uword
8778 unformat_l4_mask (unformat_input_t * input, va_list * args)
8779 {
8780   u8 **maskp = va_arg (*args, u8 **);
8781   u16 src_port = 0, dst_port = 0;
8782   tcpudp_header_t *tcpudp;
8783
8784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8785     {
8786       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8787         return 1;
8788       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8789         return 1;
8790       else if (unformat (input, "src_port"))
8791         src_port = 0xFFFF;
8792       else if (unformat (input, "dst_port"))
8793         dst_port = 0xFFFF;
8794       else
8795         return 0;
8796     }
8797
8798   if (!src_port && !dst_port)
8799     return 0;
8800
8801   u8 *mask = 0;
8802   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8803
8804   tcpudp = (tcpudp_header_t *) mask;
8805   tcpudp->src_port = src_port;
8806   tcpudp->dst_port = dst_port;
8807
8808   *maskp = mask;
8809
8810   return 1;
8811 }
8812
8813 uword
8814 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8815 {
8816   u8 **maskp = va_arg (*args, u8 **);
8817   u8 *mask = 0;
8818   u8 found_something = 0;
8819   ip4_header_t *ip;
8820
8821 #define _(a) u8 a=0;
8822   foreach_ip4_proto_field;
8823 #undef _
8824   u8 version = 0;
8825   u8 hdr_length = 0;
8826
8827
8828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8829     {
8830       if (unformat (input, "version"))
8831         version = 1;
8832       else if (unformat (input, "hdr_length"))
8833         hdr_length = 1;
8834       else if (unformat (input, "src"))
8835         src_address = 1;
8836       else if (unformat (input, "dst"))
8837         dst_address = 1;
8838       else if (unformat (input, "proto"))
8839         protocol = 1;
8840
8841 #define _(a) else if (unformat (input, #a)) a=1;
8842       foreach_ip4_proto_field
8843 #undef _
8844         else
8845         break;
8846     }
8847
8848 #define _(a) found_something += a;
8849   foreach_ip4_proto_field;
8850 #undef _
8851
8852   if (found_something == 0)
8853     return 0;
8854
8855   vec_validate (mask, sizeof (*ip) - 1);
8856
8857   ip = (ip4_header_t *) mask;
8858
8859 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8860   foreach_ip4_proto_field;
8861 #undef _
8862
8863   ip->ip_version_and_header_length = 0;
8864
8865   if (version)
8866     ip->ip_version_and_header_length |= 0xF0;
8867
8868   if (hdr_length)
8869     ip->ip_version_and_header_length |= 0x0F;
8870
8871   *maskp = mask;
8872   return 1;
8873 }
8874
8875 #define foreach_ip6_proto_field                 \
8876 _(src_address)                                  \
8877 _(dst_address)                                  \
8878 _(payload_length)                               \
8879 _(hop_limit)                                    \
8880 _(protocol)
8881
8882 uword
8883 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8884 {
8885   u8 **maskp = va_arg (*args, u8 **);
8886   u8 *mask = 0;
8887   u8 found_something = 0;
8888   ip6_header_t *ip;
8889   u32 ip_version_traffic_class_and_flow_label;
8890
8891 #define _(a) u8 a=0;
8892   foreach_ip6_proto_field;
8893 #undef _
8894   u8 version = 0;
8895   u8 traffic_class = 0;
8896   u8 flow_label = 0;
8897
8898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8899     {
8900       if (unformat (input, "version"))
8901         version = 1;
8902       else if (unformat (input, "traffic-class"))
8903         traffic_class = 1;
8904       else if (unformat (input, "flow-label"))
8905         flow_label = 1;
8906       else if (unformat (input, "src"))
8907         src_address = 1;
8908       else if (unformat (input, "dst"))
8909         dst_address = 1;
8910       else if (unformat (input, "proto"))
8911         protocol = 1;
8912
8913 #define _(a) else if (unformat (input, #a)) a=1;
8914       foreach_ip6_proto_field
8915 #undef _
8916         else
8917         break;
8918     }
8919
8920 #define _(a) found_something += a;
8921   foreach_ip6_proto_field;
8922 #undef _
8923
8924   if (found_something == 0)
8925     return 0;
8926
8927   vec_validate (mask, sizeof (*ip) - 1);
8928
8929   ip = (ip6_header_t *) mask;
8930
8931 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8932   foreach_ip6_proto_field;
8933 #undef _
8934
8935   ip_version_traffic_class_and_flow_label = 0;
8936
8937   if (version)
8938     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8939
8940   if (traffic_class)
8941     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8942
8943   if (flow_label)
8944     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8945
8946   ip->ip_version_traffic_class_and_flow_label =
8947     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8948
8949   *maskp = mask;
8950   return 1;
8951 }
8952
8953 uword
8954 unformat_l3_mask (unformat_input_t * input, va_list * args)
8955 {
8956   u8 **maskp = va_arg (*args, u8 **);
8957
8958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8959     {
8960       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8961         return 1;
8962       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8963         return 1;
8964       else
8965         break;
8966     }
8967   return 0;
8968 }
8969
8970 uword
8971 unformat_l2_mask (unformat_input_t * input, va_list * args)
8972 {
8973   u8 **maskp = va_arg (*args, u8 **);
8974   u8 *mask = 0;
8975   u8 src = 0;
8976   u8 dst = 0;
8977   u8 proto = 0;
8978   u8 tag1 = 0;
8979   u8 tag2 = 0;
8980   u8 ignore_tag1 = 0;
8981   u8 ignore_tag2 = 0;
8982   u8 cos1 = 0;
8983   u8 cos2 = 0;
8984   u8 dot1q = 0;
8985   u8 dot1ad = 0;
8986   int len = 14;
8987
8988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8989     {
8990       if (unformat (input, "src"))
8991         src = 1;
8992       else if (unformat (input, "dst"))
8993         dst = 1;
8994       else if (unformat (input, "proto"))
8995         proto = 1;
8996       else if (unformat (input, "tag1"))
8997         tag1 = 1;
8998       else if (unformat (input, "tag2"))
8999         tag2 = 1;
9000       else if (unformat (input, "ignore-tag1"))
9001         ignore_tag1 = 1;
9002       else if (unformat (input, "ignore-tag2"))
9003         ignore_tag2 = 1;
9004       else if (unformat (input, "cos1"))
9005         cos1 = 1;
9006       else if (unformat (input, "cos2"))
9007         cos2 = 1;
9008       else if (unformat (input, "dot1q"))
9009         dot1q = 1;
9010       else if (unformat (input, "dot1ad"))
9011         dot1ad = 1;
9012       else
9013         break;
9014     }
9015   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9016        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9017     return 0;
9018
9019   if (tag1 || ignore_tag1 || cos1 || dot1q)
9020     len = 18;
9021   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9022     len = 22;
9023
9024   vec_validate (mask, len - 1);
9025
9026   if (dst)
9027     memset (mask, 0xff, 6);
9028
9029   if (src)
9030     memset (mask + 6, 0xff, 6);
9031
9032   if (tag2 || dot1ad)
9033     {
9034       /* inner vlan tag */
9035       if (tag2)
9036         {
9037           mask[19] = 0xff;
9038           mask[18] = 0x0f;
9039         }
9040       if (cos2)
9041         mask[18] |= 0xe0;
9042       if (proto)
9043         mask[21] = mask[20] = 0xff;
9044       if (tag1)
9045         {
9046           mask[15] = 0xff;
9047           mask[14] = 0x0f;
9048         }
9049       if (cos1)
9050         mask[14] |= 0xe0;
9051       *maskp = mask;
9052       return 1;
9053     }
9054   if (tag1 | dot1q)
9055     {
9056       if (tag1)
9057         {
9058           mask[15] = 0xff;
9059           mask[14] = 0x0f;
9060         }
9061       if (cos1)
9062         mask[14] |= 0xe0;
9063       if (proto)
9064         mask[16] = mask[17] = 0xff;
9065
9066       *maskp = mask;
9067       return 1;
9068     }
9069   if (cos2)
9070     mask[18] |= 0xe0;
9071   if (cos1)
9072     mask[14] |= 0xe0;
9073   if (proto)
9074     mask[12] = mask[13] = 0xff;
9075
9076   *maskp = mask;
9077   return 1;
9078 }
9079
9080 uword
9081 unformat_classify_mask (unformat_input_t * input, va_list * args)
9082 {
9083   u8 **maskp = va_arg (*args, u8 **);
9084   u32 *skipp = va_arg (*args, u32 *);
9085   u32 *matchp = va_arg (*args, u32 *);
9086   u32 match;
9087   u8 *mask = 0;
9088   u8 *l2 = 0;
9089   u8 *l3 = 0;
9090   u8 *l4 = 0;
9091   int i;
9092
9093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9094     {
9095       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9096         ;
9097       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9098         ;
9099       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9100         ;
9101       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9102         ;
9103       else
9104         break;
9105     }
9106
9107   if (l4 && !l3)
9108     {
9109       vec_free (mask);
9110       vec_free (l2);
9111       vec_free (l4);
9112       return 0;
9113     }
9114
9115   if (mask || l2 || l3 || l4)
9116     {
9117       if (l2 || l3 || l4)
9118         {
9119           /* "With a free Ethernet header in every package" */
9120           if (l2 == 0)
9121             vec_validate (l2, 13);
9122           mask = l2;
9123           if (vec_len (l3))
9124             {
9125               vec_append (mask, l3);
9126               vec_free (l3);
9127             }
9128           if (vec_len (l4))
9129             {
9130               vec_append (mask, l4);
9131               vec_free (l4);
9132             }
9133         }
9134
9135       /* Scan forward looking for the first significant mask octet */
9136       for (i = 0; i < vec_len (mask); i++)
9137         if (mask[i])
9138           break;
9139
9140       /* compute (skip, match) params */
9141       *skipp = i / sizeof (u32x4);
9142       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9143
9144       /* Pad mask to an even multiple of the vector size */
9145       while (vec_len (mask) % sizeof (u32x4))
9146         vec_add1 (mask, 0);
9147
9148       match = vec_len (mask) / sizeof (u32x4);
9149
9150       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9151         {
9152           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9153           if (*tmp || *(tmp + 1))
9154             break;
9155           match--;
9156         }
9157       if (match == 0)
9158         clib_warning ("BUG: match 0");
9159
9160       _vec_len (mask) = match * sizeof (u32x4);
9161
9162       *matchp = match;
9163       *maskp = mask;
9164
9165       return 1;
9166     }
9167
9168   return 0;
9169 }
9170 #endif /* VPP_API_TEST_BUILTIN */
9171
9172 #define foreach_l2_next                         \
9173 _(drop, DROP)                                   \
9174 _(ethernet, ETHERNET_INPUT)                     \
9175 _(ip4, IP4_INPUT)                               \
9176 _(ip6, IP6_INPUT)
9177
9178 uword
9179 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9180 {
9181   u32 *miss_next_indexp = va_arg (*args, u32 *);
9182   u32 next_index = 0;
9183   u32 tmp;
9184
9185 #define _(n,N) \
9186   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9187   foreach_l2_next;
9188 #undef _
9189
9190   if (unformat (input, "%d", &tmp))
9191     {
9192       next_index = tmp;
9193       goto out;
9194     }
9195
9196   return 0;
9197
9198 out:
9199   *miss_next_indexp = next_index;
9200   return 1;
9201 }
9202
9203 #define foreach_ip_next                         \
9204 _(drop, DROP)                                   \
9205 _(local, LOCAL)                                 \
9206 _(rewrite, REWRITE)
9207
9208 uword
9209 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9210 {
9211   u32 *miss_next_indexp = va_arg (*args, u32 *);
9212   u32 next_index = 0;
9213   u32 tmp;
9214
9215 #define _(n,N) \
9216   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9217   foreach_ip_next;
9218 #undef _
9219
9220   if (unformat (input, "%d", &tmp))
9221     {
9222       next_index = tmp;
9223       goto out;
9224     }
9225
9226   return 0;
9227
9228 out:
9229   *miss_next_indexp = next_index;
9230   return 1;
9231 }
9232
9233 #define foreach_acl_next                        \
9234 _(deny, DENY)
9235
9236 uword
9237 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9238 {
9239   u32 *miss_next_indexp = va_arg (*args, u32 *);
9240   u32 next_index = 0;
9241   u32 tmp;
9242
9243 #define _(n,N) \
9244   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9245   foreach_acl_next;
9246 #undef _
9247
9248   if (unformat (input, "permit"))
9249     {
9250       next_index = ~0;
9251       goto out;
9252     }
9253   else if (unformat (input, "%d", &tmp))
9254     {
9255       next_index = tmp;
9256       goto out;
9257     }
9258
9259   return 0;
9260
9261 out:
9262   *miss_next_indexp = next_index;
9263   return 1;
9264 }
9265
9266 uword
9267 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9268 {
9269   u32 *r = va_arg (*args, u32 *);
9270
9271   if (unformat (input, "conform-color"))
9272     *r = POLICE_CONFORM;
9273   else if (unformat (input, "exceed-color"))
9274     *r = POLICE_EXCEED;
9275   else
9276     return 0;
9277
9278   return 1;
9279 }
9280
9281 static int
9282 api_classify_add_del_table (vat_main_t * vam)
9283 {
9284   unformat_input_t *i = vam->input;
9285   vl_api_classify_add_del_table_t *mp;
9286
9287   u32 nbuckets = 2;
9288   u32 skip = ~0;
9289   u32 match = ~0;
9290   int is_add = 1;
9291   int del_chain = 0;
9292   u32 table_index = ~0;
9293   u32 next_table_index = ~0;
9294   u32 miss_next_index = ~0;
9295   u32 memory_size = 32 << 20;
9296   u8 *mask = 0;
9297   u32 current_data_flag = 0;
9298   int current_data_offset = 0;
9299   int ret;
9300
9301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9302     {
9303       if (unformat (i, "del"))
9304         is_add = 0;
9305       else if (unformat (i, "del-chain"))
9306         {
9307           is_add = 0;
9308           del_chain = 1;
9309         }
9310       else if (unformat (i, "buckets %d", &nbuckets))
9311         ;
9312       else if (unformat (i, "memory_size %d", &memory_size))
9313         ;
9314       else if (unformat (i, "skip %d", &skip))
9315         ;
9316       else if (unformat (i, "match %d", &match))
9317         ;
9318       else if (unformat (i, "table %d", &table_index))
9319         ;
9320       else if (unformat (i, "mask %U", unformat_classify_mask,
9321                          &mask, &skip, &match))
9322         ;
9323       else if (unformat (i, "next-table %d", &next_table_index))
9324         ;
9325       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
9326                          &miss_next_index))
9327         ;
9328       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9329                          &miss_next_index))
9330         ;
9331       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
9332                          &miss_next_index))
9333         ;
9334       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9335         ;
9336       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9337         ;
9338       else
9339         break;
9340     }
9341
9342   if (is_add && mask == 0)
9343     {
9344       errmsg ("Mask required");
9345       return -99;
9346     }
9347
9348   if (is_add && skip == ~0)
9349     {
9350       errmsg ("skip count required");
9351       return -99;
9352     }
9353
9354   if (is_add && match == ~0)
9355     {
9356       errmsg ("match count required");
9357       return -99;
9358     }
9359
9360   if (!is_add && table_index == ~0)
9361     {
9362       errmsg ("table index required for delete");
9363       return -99;
9364     }
9365
9366   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
9367
9368   mp->is_add = is_add;
9369   mp->del_chain = del_chain;
9370   mp->table_index = ntohl (table_index);
9371   mp->nbuckets = ntohl (nbuckets);
9372   mp->memory_size = ntohl (memory_size);
9373   mp->skip_n_vectors = ntohl (skip);
9374   mp->match_n_vectors = ntohl (match);
9375   mp->next_table_index = ntohl (next_table_index);
9376   mp->miss_next_index = ntohl (miss_next_index);
9377   mp->current_data_flag = ntohl (current_data_flag);
9378   mp->current_data_offset = ntohl (current_data_offset);
9379   clib_memcpy (mp->mask, mask, vec_len (mask));
9380
9381   vec_free (mask);
9382
9383   S (mp);
9384   W (ret);
9385   return ret;
9386 }
9387
9388 #if VPP_API_TEST_BUILTIN == 0
9389 uword
9390 unformat_l4_match (unformat_input_t * input, va_list * args)
9391 {
9392   u8 **matchp = va_arg (*args, u8 **);
9393
9394   u8 *proto_header = 0;
9395   int src_port = 0;
9396   int dst_port = 0;
9397
9398   tcpudp_header_t h;
9399
9400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9401     {
9402       if (unformat (input, "src_port %d", &src_port))
9403         ;
9404       else if (unformat (input, "dst_port %d", &dst_port))
9405         ;
9406       else
9407         return 0;
9408     }
9409
9410   h.src_port = clib_host_to_net_u16 (src_port);
9411   h.dst_port = clib_host_to_net_u16 (dst_port);
9412   vec_validate (proto_header, sizeof (h) - 1);
9413   memcpy (proto_header, &h, sizeof (h));
9414
9415   *matchp = proto_header;
9416
9417   return 1;
9418 }
9419
9420 uword
9421 unformat_ip4_match (unformat_input_t * input, va_list * args)
9422 {
9423   u8 **matchp = va_arg (*args, u8 **);
9424   u8 *match = 0;
9425   ip4_header_t *ip;
9426   int version = 0;
9427   u32 version_val;
9428   int hdr_length = 0;
9429   u32 hdr_length_val;
9430   int src = 0, dst = 0;
9431   ip4_address_t src_val, dst_val;
9432   int proto = 0;
9433   u32 proto_val;
9434   int tos = 0;
9435   u32 tos_val;
9436   int length = 0;
9437   u32 length_val;
9438   int fragment_id = 0;
9439   u32 fragment_id_val;
9440   int ttl = 0;
9441   int ttl_val;
9442   int checksum = 0;
9443   u32 checksum_val;
9444
9445   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9446     {
9447       if (unformat (input, "version %d", &version_val))
9448         version = 1;
9449       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9450         hdr_length = 1;
9451       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9452         src = 1;
9453       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9454         dst = 1;
9455       else if (unformat (input, "proto %d", &proto_val))
9456         proto = 1;
9457       else if (unformat (input, "tos %d", &tos_val))
9458         tos = 1;
9459       else if (unformat (input, "length %d", &length_val))
9460         length = 1;
9461       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9462         fragment_id = 1;
9463       else if (unformat (input, "ttl %d", &ttl_val))
9464         ttl = 1;
9465       else if (unformat (input, "checksum %d", &checksum_val))
9466         checksum = 1;
9467       else
9468         break;
9469     }
9470
9471   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9472       + ttl + checksum == 0)
9473     return 0;
9474
9475   /*
9476    * Aligned because we use the real comparison functions
9477    */
9478   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9479
9480   ip = (ip4_header_t *) match;
9481
9482   /* These are realistically matched in practice */
9483   if (src)
9484     ip->src_address.as_u32 = src_val.as_u32;
9485
9486   if (dst)
9487     ip->dst_address.as_u32 = dst_val.as_u32;
9488
9489   if (proto)
9490     ip->protocol = proto_val;
9491
9492
9493   /* These are not, but they're included for completeness */
9494   if (version)
9495     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9496
9497   if (hdr_length)
9498     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9499
9500   if (tos)
9501     ip->tos = tos_val;
9502
9503   if (length)
9504     ip->length = clib_host_to_net_u16 (length_val);
9505
9506   if (ttl)
9507     ip->ttl = ttl_val;
9508
9509   if (checksum)
9510     ip->checksum = clib_host_to_net_u16 (checksum_val);
9511
9512   *matchp = match;
9513   return 1;
9514 }
9515
9516 uword
9517 unformat_ip6_match (unformat_input_t * input, va_list * args)
9518 {
9519   u8 **matchp = va_arg (*args, u8 **);
9520   u8 *match = 0;
9521   ip6_header_t *ip;
9522   int version = 0;
9523   u32 version_val;
9524   u8 traffic_class = 0;
9525   u32 traffic_class_val = 0;
9526   u8 flow_label = 0;
9527   u8 flow_label_val;
9528   int src = 0, dst = 0;
9529   ip6_address_t src_val, dst_val;
9530   int proto = 0;
9531   u32 proto_val;
9532   int payload_length = 0;
9533   u32 payload_length_val;
9534   int hop_limit = 0;
9535   int hop_limit_val;
9536   u32 ip_version_traffic_class_and_flow_label;
9537
9538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9539     {
9540       if (unformat (input, "version %d", &version_val))
9541         version = 1;
9542       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9543         traffic_class = 1;
9544       else if (unformat (input, "flow_label %d", &flow_label_val))
9545         flow_label = 1;
9546       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9547         src = 1;
9548       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9549         dst = 1;
9550       else if (unformat (input, "proto %d", &proto_val))
9551         proto = 1;
9552       else if (unformat (input, "payload_length %d", &payload_length_val))
9553         payload_length = 1;
9554       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9555         hop_limit = 1;
9556       else
9557         break;
9558     }
9559
9560   if (version + traffic_class + flow_label + src + dst + proto +
9561       payload_length + hop_limit == 0)
9562     return 0;
9563
9564   /*
9565    * Aligned because we use the real comparison functions
9566    */
9567   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9568
9569   ip = (ip6_header_t *) match;
9570
9571   if (src)
9572     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9573
9574   if (dst)
9575     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9576
9577   if (proto)
9578     ip->protocol = proto_val;
9579
9580   ip_version_traffic_class_and_flow_label = 0;
9581
9582   if (version)
9583     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9584
9585   if (traffic_class)
9586     ip_version_traffic_class_and_flow_label |=
9587       (traffic_class_val & 0xFF) << 20;
9588
9589   if (flow_label)
9590     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9591
9592   ip->ip_version_traffic_class_and_flow_label =
9593     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9594
9595   if (payload_length)
9596     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9597
9598   if (hop_limit)
9599     ip->hop_limit = hop_limit_val;
9600
9601   *matchp = match;
9602   return 1;
9603 }
9604
9605 uword
9606 unformat_l3_match (unformat_input_t * input, va_list * args)
9607 {
9608   u8 **matchp = va_arg (*args, u8 **);
9609
9610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9611     {
9612       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9613         return 1;
9614       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9615         return 1;
9616       else
9617         break;
9618     }
9619   return 0;
9620 }
9621
9622 uword
9623 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9624 {
9625   u8 *tagp = va_arg (*args, u8 *);
9626   u32 tag;
9627
9628   if (unformat (input, "%d", &tag))
9629     {
9630       tagp[0] = (tag >> 8) & 0x0F;
9631       tagp[1] = tag & 0xFF;
9632       return 1;
9633     }
9634
9635   return 0;
9636 }
9637
9638 uword
9639 unformat_l2_match (unformat_input_t * input, va_list * args)
9640 {
9641   u8 **matchp = va_arg (*args, u8 **);
9642   u8 *match = 0;
9643   u8 src = 0;
9644   u8 src_val[6];
9645   u8 dst = 0;
9646   u8 dst_val[6];
9647   u8 proto = 0;
9648   u16 proto_val;
9649   u8 tag1 = 0;
9650   u8 tag1_val[2];
9651   u8 tag2 = 0;
9652   u8 tag2_val[2];
9653   int len = 14;
9654   u8 ignore_tag1 = 0;
9655   u8 ignore_tag2 = 0;
9656   u8 cos1 = 0;
9657   u8 cos2 = 0;
9658   u32 cos1_val = 0;
9659   u32 cos2_val = 0;
9660
9661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9662     {
9663       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9664         src = 1;
9665       else
9666         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9667         dst = 1;
9668       else if (unformat (input, "proto %U",
9669                          unformat_ethernet_type_host_byte_order, &proto_val))
9670         proto = 1;
9671       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9672         tag1 = 1;
9673       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9674         tag2 = 1;
9675       else if (unformat (input, "ignore-tag1"))
9676         ignore_tag1 = 1;
9677       else if (unformat (input, "ignore-tag2"))
9678         ignore_tag2 = 1;
9679       else if (unformat (input, "cos1 %d", &cos1_val))
9680         cos1 = 1;
9681       else if (unformat (input, "cos2 %d", &cos2_val))
9682         cos2 = 1;
9683       else
9684         break;
9685     }
9686   if ((src + dst + proto + tag1 + tag2 +
9687        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9688     return 0;
9689
9690   if (tag1 || ignore_tag1 || cos1)
9691     len = 18;
9692   if (tag2 || ignore_tag2 || cos2)
9693     len = 22;
9694
9695   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9696
9697   if (dst)
9698     clib_memcpy (match, dst_val, 6);
9699
9700   if (src)
9701     clib_memcpy (match + 6, src_val, 6);
9702
9703   if (tag2)
9704     {
9705       /* inner vlan tag */
9706       match[19] = tag2_val[1];
9707       match[18] = tag2_val[0];
9708       if (cos2)
9709         match[18] |= (cos2_val & 0x7) << 5;
9710       if (proto)
9711         {
9712           match[21] = proto_val & 0xff;
9713           match[20] = proto_val >> 8;
9714         }
9715       if (tag1)
9716         {
9717           match[15] = tag1_val[1];
9718           match[14] = tag1_val[0];
9719         }
9720       if (cos1)
9721         match[14] |= (cos1_val & 0x7) << 5;
9722       *matchp = match;
9723       return 1;
9724     }
9725   if (tag1)
9726     {
9727       match[15] = tag1_val[1];
9728       match[14] = tag1_val[0];
9729       if (proto)
9730         {
9731           match[17] = proto_val & 0xff;
9732           match[16] = proto_val >> 8;
9733         }
9734       if (cos1)
9735         match[14] |= (cos1_val & 0x7) << 5;
9736
9737       *matchp = match;
9738       return 1;
9739     }
9740   if (cos2)
9741     match[18] |= (cos2_val & 0x7) << 5;
9742   if (cos1)
9743     match[14] |= (cos1_val & 0x7) << 5;
9744   if (proto)
9745     {
9746       match[13] = proto_val & 0xff;
9747       match[12] = proto_val >> 8;
9748     }
9749
9750   *matchp = match;
9751   return 1;
9752 }
9753 #endif
9754
9755 uword
9756 api_unformat_classify_match (unformat_input_t * input, va_list * args)
9757 {
9758   u8 **matchp = va_arg (*args, u8 **);
9759   u32 skip_n_vectors = va_arg (*args, u32);
9760   u32 match_n_vectors = va_arg (*args, u32);
9761
9762   u8 *match = 0;
9763   u8 *l2 = 0;
9764   u8 *l3 = 0;
9765   u8 *l4 = 0;
9766
9767   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9768     {
9769       if (unformat (input, "hex %U", unformat_hex_string, &match))
9770         ;
9771       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9772         ;
9773       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9774         ;
9775       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9776         ;
9777       else
9778         break;
9779     }
9780
9781   if (l4 && !l3)
9782     {
9783       vec_free (match);
9784       vec_free (l2);
9785       vec_free (l4);
9786       return 0;
9787     }
9788
9789   if (match || l2 || l3 || l4)
9790     {
9791       if (l2 || l3 || l4)
9792         {
9793           /* "Win a free Ethernet header in every packet" */
9794           if (l2 == 0)
9795             vec_validate_aligned (l2, 13, sizeof (u32x4));
9796           match = l2;
9797           if (vec_len (l3))
9798             {
9799               vec_append_aligned (match, l3, sizeof (u32x4));
9800               vec_free (l3);
9801             }
9802           if (vec_len (l4))
9803             {
9804               vec_append_aligned (match, l4, sizeof (u32x4));
9805               vec_free (l4);
9806             }
9807         }
9808
9809       /* Make sure the vector is big enough even if key is all 0's */
9810       vec_validate_aligned
9811         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9812          sizeof (u32x4));
9813
9814       /* Set size, include skipped vectors */
9815       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9816
9817       *matchp = match;
9818
9819       return 1;
9820     }
9821
9822   return 0;
9823 }
9824
9825 static int
9826 api_classify_add_del_session (vat_main_t * vam)
9827 {
9828   unformat_input_t *i = vam->input;
9829   vl_api_classify_add_del_session_t *mp;
9830   int is_add = 1;
9831   u32 table_index = ~0;
9832   u32 hit_next_index = ~0;
9833   u32 opaque_index = ~0;
9834   u8 *match = 0;
9835   i32 advance = 0;
9836   u32 skip_n_vectors = 0;
9837   u32 match_n_vectors = 0;
9838   u32 action = 0;
9839   u32 metadata = 0;
9840   int ret;
9841
9842   /*
9843    * Warning: you have to supply skip_n and match_n
9844    * because the API client cant simply look at the classify
9845    * table object.
9846    */
9847
9848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9849     {
9850       if (unformat (i, "del"))
9851         is_add = 0;
9852       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
9853                          &hit_next_index))
9854         ;
9855       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9856                          &hit_next_index))
9857         ;
9858       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
9859                          &hit_next_index))
9860         ;
9861       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9862         ;
9863       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9864         ;
9865       else if (unformat (i, "opaque-index %d", &opaque_index))
9866         ;
9867       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9868         ;
9869       else if (unformat (i, "match_n %d", &match_n_vectors))
9870         ;
9871       else if (unformat (i, "match %U", api_unformat_classify_match,
9872                          &match, skip_n_vectors, match_n_vectors))
9873         ;
9874       else if (unformat (i, "advance %d", &advance))
9875         ;
9876       else if (unformat (i, "table-index %d", &table_index))
9877         ;
9878       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9879         action = 1;
9880       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9881         action = 2;
9882       else if (unformat (i, "action %d", &action))
9883         ;
9884       else if (unformat (i, "metadata %d", &metadata))
9885         ;
9886       else
9887         break;
9888     }
9889
9890   if (table_index == ~0)
9891     {
9892       errmsg ("Table index required");
9893       return -99;
9894     }
9895
9896   if (is_add && match == 0)
9897     {
9898       errmsg ("Match value required");
9899       return -99;
9900     }
9901
9902   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
9903
9904   mp->is_add = is_add;
9905   mp->table_index = ntohl (table_index);
9906   mp->hit_next_index = ntohl (hit_next_index);
9907   mp->opaque_index = ntohl (opaque_index);
9908   mp->advance = ntohl (advance);
9909   mp->action = action;
9910   mp->metadata = ntohl (metadata);
9911   clib_memcpy (mp->match, match, vec_len (match));
9912   vec_free (match);
9913
9914   S (mp);
9915   W (ret);
9916   return ret;
9917 }
9918
9919 static int
9920 api_classify_set_interface_ip_table (vat_main_t * vam)
9921 {
9922   unformat_input_t *i = vam->input;
9923   vl_api_classify_set_interface_ip_table_t *mp;
9924   u32 sw_if_index;
9925   int sw_if_index_set;
9926   u32 table_index = ~0;
9927   u8 is_ipv6 = 0;
9928   int ret;
9929
9930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9931     {
9932       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9933         sw_if_index_set = 1;
9934       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9935         sw_if_index_set = 1;
9936       else if (unformat (i, "table %d", &table_index))
9937         ;
9938       else
9939         {
9940           clib_warning ("parse error '%U'", format_unformat_error, i);
9941           return -99;
9942         }
9943     }
9944
9945   if (sw_if_index_set == 0)
9946     {
9947       errmsg ("missing interface name or sw_if_index");
9948       return -99;
9949     }
9950
9951
9952   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
9953
9954   mp->sw_if_index = ntohl (sw_if_index);
9955   mp->table_index = ntohl (table_index);
9956   mp->is_ipv6 = is_ipv6;
9957
9958   S (mp);
9959   W (ret);
9960   return ret;
9961 }
9962
9963 static int
9964 api_classify_set_interface_l2_tables (vat_main_t * vam)
9965 {
9966   unformat_input_t *i = vam->input;
9967   vl_api_classify_set_interface_l2_tables_t *mp;
9968   u32 sw_if_index;
9969   int sw_if_index_set;
9970   u32 ip4_table_index = ~0;
9971   u32 ip6_table_index = ~0;
9972   u32 other_table_index = ~0;
9973   u32 is_input = 1;
9974   int ret;
9975
9976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9977     {
9978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9979         sw_if_index_set = 1;
9980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9981         sw_if_index_set = 1;
9982       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9983         ;
9984       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9985         ;
9986       else if (unformat (i, "other-table %d", &other_table_index))
9987         ;
9988       else if (unformat (i, "is-input %d", &is_input))
9989         ;
9990       else
9991         {
9992           clib_warning ("parse error '%U'", format_unformat_error, i);
9993           return -99;
9994         }
9995     }
9996
9997   if (sw_if_index_set == 0)
9998     {
9999       errmsg ("missing interface name or sw_if_index");
10000       return -99;
10001     }
10002
10003
10004   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10005
10006   mp->sw_if_index = ntohl (sw_if_index);
10007   mp->ip4_table_index = ntohl (ip4_table_index);
10008   mp->ip6_table_index = ntohl (ip6_table_index);
10009   mp->other_table_index = ntohl (other_table_index);
10010   mp->is_input = (u8) is_input;
10011
10012   S (mp);
10013   W (ret);
10014   return ret;
10015 }
10016
10017 static int
10018 api_set_ipfix_exporter (vat_main_t * vam)
10019 {
10020   unformat_input_t *i = vam->input;
10021   vl_api_set_ipfix_exporter_t *mp;
10022   ip4_address_t collector_address;
10023   u8 collector_address_set = 0;
10024   u32 collector_port = ~0;
10025   ip4_address_t src_address;
10026   u8 src_address_set = 0;
10027   u32 vrf_id = ~0;
10028   u32 path_mtu = ~0;
10029   u32 template_interval = ~0;
10030   u8 udp_checksum = 0;
10031   int ret;
10032
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "collector_address %U", unformat_ip4_address,
10036                     &collector_address))
10037         collector_address_set = 1;
10038       else if (unformat (i, "collector_port %d", &collector_port))
10039         ;
10040       else if (unformat (i, "src_address %U", unformat_ip4_address,
10041                          &src_address))
10042         src_address_set = 1;
10043       else if (unformat (i, "vrf_id %d", &vrf_id))
10044         ;
10045       else if (unformat (i, "path_mtu %d", &path_mtu))
10046         ;
10047       else if (unformat (i, "template_interval %d", &template_interval))
10048         ;
10049       else if (unformat (i, "udp_checksum"))
10050         udp_checksum = 1;
10051       else
10052         break;
10053     }
10054
10055   if (collector_address_set == 0)
10056     {
10057       errmsg ("collector_address required");
10058       return -99;
10059     }
10060
10061   if (src_address_set == 0)
10062     {
10063       errmsg ("src_address required");
10064       return -99;
10065     }
10066
10067   M (SET_IPFIX_EXPORTER, mp);
10068
10069   memcpy (mp->collector_address, collector_address.data,
10070           sizeof (collector_address.data));
10071   mp->collector_port = htons ((u16) collector_port);
10072   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
10073   mp->vrf_id = htonl (vrf_id);
10074   mp->path_mtu = htonl (path_mtu);
10075   mp->template_interval = htonl (template_interval);
10076   mp->udp_checksum = udp_checksum;
10077
10078   S (mp);
10079   W (ret);
10080   return ret;
10081 }
10082
10083 static int
10084 api_set_ipfix_classify_stream (vat_main_t * vam)
10085 {
10086   unformat_input_t *i = vam->input;
10087   vl_api_set_ipfix_classify_stream_t *mp;
10088   u32 domain_id = 0;
10089   u32 src_port = UDP_DST_PORT_ipfix;
10090   int ret;
10091
10092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10093     {
10094       if (unformat (i, "domain %d", &domain_id))
10095         ;
10096       else if (unformat (i, "src_port %d", &src_port))
10097         ;
10098       else
10099         {
10100           errmsg ("unknown input `%U'", format_unformat_error, i);
10101           return -99;
10102         }
10103     }
10104
10105   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10106
10107   mp->domain_id = htonl (domain_id);
10108   mp->src_port = htons ((u16) src_port);
10109
10110   S (mp);
10111   W (ret);
10112   return ret;
10113 }
10114
10115 static int
10116 api_ipfix_classify_table_add_del (vat_main_t * vam)
10117 {
10118   unformat_input_t *i = vam->input;
10119   vl_api_ipfix_classify_table_add_del_t *mp;
10120   int is_add = -1;
10121   u32 classify_table_index = ~0;
10122   u8 ip_version = 0;
10123   u8 transport_protocol = 255;
10124   int ret;
10125
10126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10127     {
10128       if (unformat (i, "add"))
10129         is_add = 1;
10130       else if (unformat (i, "del"))
10131         is_add = 0;
10132       else if (unformat (i, "table %d", &classify_table_index))
10133         ;
10134       else if (unformat (i, "ip4"))
10135         ip_version = 4;
10136       else if (unformat (i, "ip6"))
10137         ip_version = 6;
10138       else if (unformat (i, "tcp"))
10139         transport_protocol = 6;
10140       else if (unformat (i, "udp"))
10141         transport_protocol = 17;
10142       else
10143         {
10144           errmsg ("unknown input `%U'", format_unformat_error, i);
10145           return -99;
10146         }
10147     }
10148
10149   if (is_add == -1)
10150     {
10151       errmsg ("expecting: add|del");
10152       return -99;
10153     }
10154   if (classify_table_index == ~0)
10155     {
10156       errmsg ("classifier table not specified");
10157       return -99;
10158     }
10159   if (ip_version == 0)
10160     {
10161       errmsg ("IP version not specified");
10162       return -99;
10163     }
10164
10165   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10166
10167   mp->is_add = is_add;
10168   mp->table_id = htonl (classify_table_index);
10169   mp->ip_version = ip_version;
10170   mp->transport_protocol = transport_protocol;
10171
10172   S (mp);
10173   W (ret);
10174   return ret;
10175 }
10176
10177 static int
10178 api_get_node_index (vat_main_t * vam)
10179 {
10180   unformat_input_t *i = vam->input;
10181   vl_api_get_node_index_t *mp;
10182   u8 *name = 0;
10183   int ret;
10184
10185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10186     {
10187       if (unformat (i, "node %s", &name))
10188         ;
10189       else
10190         break;
10191     }
10192   if (name == 0)
10193     {
10194       errmsg ("node name required");
10195       return -99;
10196     }
10197   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10198     {
10199       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10200       return -99;
10201     }
10202
10203   M (GET_NODE_INDEX, mp);
10204   clib_memcpy (mp->node_name, name, vec_len (name));
10205   vec_free (name);
10206
10207   S (mp);
10208   W (ret);
10209   return ret;
10210 }
10211
10212 static int
10213 api_get_next_index (vat_main_t * vam)
10214 {
10215   unformat_input_t *i = vam->input;
10216   vl_api_get_next_index_t *mp;
10217   u8 *node_name = 0, *next_node_name = 0;
10218   int ret;
10219
10220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10221     {
10222       if (unformat (i, "node-name %s", &node_name))
10223         ;
10224       else if (unformat (i, "next-node-name %s", &next_node_name))
10225         break;
10226     }
10227
10228   if (node_name == 0)
10229     {
10230       errmsg ("node name required");
10231       return -99;
10232     }
10233   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10234     {
10235       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10236       return -99;
10237     }
10238
10239   if (next_node_name == 0)
10240     {
10241       errmsg ("next node name required");
10242       return -99;
10243     }
10244   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10245     {
10246       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10247       return -99;
10248     }
10249
10250   M (GET_NEXT_INDEX, mp);
10251   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10252   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10253   vec_free (node_name);
10254   vec_free (next_node_name);
10255
10256   S (mp);
10257   W (ret);
10258   return ret;
10259 }
10260
10261 static int
10262 api_add_node_next (vat_main_t * vam)
10263 {
10264   unformat_input_t *i = vam->input;
10265   vl_api_add_node_next_t *mp;
10266   u8 *name = 0;
10267   u8 *next = 0;
10268   int ret;
10269
10270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10271     {
10272       if (unformat (i, "node %s", &name))
10273         ;
10274       else if (unformat (i, "next %s", &next))
10275         ;
10276       else
10277         break;
10278     }
10279   if (name == 0)
10280     {
10281       errmsg ("node name required");
10282       return -99;
10283     }
10284   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10285     {
10286       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10287       return -99;
10288     }
10289   if (next == 0)
10290     {
10291       errmsg ("next node required");
10292       return -99;
10293     }
10294   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10295     {
10296       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10297       return -99;
10298     }
10299
10300   M (ADD_NODE_NEXT, mp);
10301   clib_memcpy (mp->node_name, name, vec_len (name));
10302   clib_memcpy (mp->next_name, next, vec_len (next));
10303   vec_free (name);
10304   vec_free (next);
10305
10306   S (mp);
10307   W (ret);
10308   return ret;
10309 }
10310
10311 static int
10312 api_l2tpv3_create_tunnel (vat_main_t * vam)
10313 {
10314   unformat_input_t *i = vam->input;
10315   ip6_address_t client_address, our_address;
10316   int client_address_set = 0;
10317   int our_address_set = 0;
10318   u32 local_session_id = 0;
10319   u32 remote_session_id = 0;
10320   u64 local_cookie = 0;
10321   u64 remote_cookie = 0;
10322   u8 l2_sublayer_present = 0;
10323   vl_api_l2tpv3_create_tunnel_t *mp;
10324   int ret;
10325
10326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10327     {
10328       if (unformat (i, "client_address %U", unformat_ip6_address,
10329                     &client_address))
10330         client_address_set = 1;
10331       else if (unformat (i, "our_address %U", unformat_ip6_address,
10332                          &our_address))
10333         our_address_set = 1;
10334       else if (unformat (i, "local_session_id %d", &local_session_id))
10335         ;
10336       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10337         ;
10338       else if (unformat (i, "local_cookie %lld", &local_cookie))
10339         ;
10340       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10341         ;
10342       else if (unformat (i, "l2-sublayer-present"))
10343         l2_sublayer_present = 1;
10344       else
10345         break;
10346     }
10347
10348   if (client_address_set == 0)
10349     {
10350       errmsg ("client_address required");
10351       return -99;
10352     }
10353
10354   if (our_address_set == 0)
10355     {
10356       errmsg ("our_address required");
10357       return -99;
10358     }
10359
10360   M (L2TPV3_CREATE_TUNNEL, mp);
10361
10362   clib_memcpy (mp->client_address, client_address.as_u8,
10363                sizeof (mp->client_address));
10364
10365   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10366
10367   mp->local_session_id = ntohl (local_session_id);
10368   mp->remote_session_id = ntohl (remote_session_id);
10369   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10370   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10371   mp->l2_sublayer_present = l2_sublayer_present;
10372   mp->is_ipv6 = 1;
10373
10374   S (mp);
10375   W (ret);
10376   return ret;
10377 }
10378
10379 static int
10380 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10381 {
10382   unformat_input_t *i = vam->input;
10383   u32 sw_if_index;
10384   u8 sw_if_index_set = 0;
10385   u64 new_local_cookie = 0;
10386   u64 new_remote_cookie = 0;
10387   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10388   int ret;
10389
10390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10391     {
10392       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10393         sw_if_index_set = 1;
10394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10395         sw_if_index_set = 1;
10396       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10397         ;
10398       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10399         ;
10400       else
10401         break;
10402     }
10403
10404   if (sw_if_index_set == 0)
10405     {
10406       errmsg ("missing interface name or sw_if_index");
10407       return -99;
10408     }
10409
10410   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
10411
10412   mp->sw_if_index = ntohl (sw_if_index);
10413   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10414   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10415
10416   S (mp);
10417   W (ret);
10418   return ret;
10419 }
10420
10421 static int
10422 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10423 {
10424   unformat_input_t *i = vam->input;
10425   vl_api_l2tpv3_interface_enable_disable_t *mp;
10426   u32 sw_if_index;
10427   u8 sw_if_index_set = 0;
10428   u8 enable_disable = 1;
10429   int ret;
10430
10431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10432     {
10433       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10434         sw_if_index_set = 1;
10435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10436         sw_if_index_set = 1;
10437       else if (unformat (i, "enable"))
10438         enable_disable = 1;
10439       else if (unformat (i, "disable"))
10440         enable_disable = 0;
10441       else
10442         break;
10443     }
10444
10445   if (sw_if_index_set == 0)
10446     {
10447       errmsg ("missing interface name or sw_if_index");
10448       return -99;
10449     }
10450
10451   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
10452
10453   mp->sw_if_index = ntohl (sw_if_index);
10454   mp->enable_disable = enable_disable;
10455
10456   S (mp);
10457   W (ret);
10458   return ret;
10459 }
10460
10461 static int
10462 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10463 {
10464   unformat_input_t *i = vam->input;
10465   vl_api_l2tpv3_set_lookup_key_t *mp;
10466   u8 key = ~0;
10467   int ret;
10468
10469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10470     {
10471       if (unformat (i, "lookup_v6_src"))
10472         key = L2T_LOOKUP_SRC_ADDRESS;
10473       else if (unformat (i, "lookup_v6_dst"))
10474         key = L2T_LOOKUP_DST_ADDRESS;
10475       else if (unformat (i, "lookup_session_id"))
10476         key = L2T_LOOKUP_SESSION_ID;
10477       else
10478         break;
10479     }
10480
10481   if (key == (u8) ~ 0)
10482     {
10483       errmsg ("l2tp session lookup key unset");
10484       return -99;
10485     }
10486
10487   M (L2TPV3_SET_LOOKUP_KEY, mp);
10488
10489   mp->key = key;
10490
10491   S (mp);
10492   W (ret);
10493   return ret;
10494 }
10495
10496 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10497   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10498 {
10499   vat_main_t *vam = &vat_main;
10500
10501   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10502          format_ip6_address, mp->our_address,
10503          format_ip6_address, mp->client_address,
10504          clib_net_to_host_u32 (mp->sw_if_index));
10505
10506   print (vam->ofp,
10507          "   local cookies %016llx %016llx remote cookie %016llx",
10508          clib_net_to_host_u64 (mp->local_cookie[0]),
10509          clib_net_to_host_u64 (mp->local_cookie[1]),
10510          clib_net_to_host_u64 (mp->remote_cookie));
10511
10512   print (vam->ofp, "   local session-id %d remote session-id %d",
10513          clib_net_to_host_u32 (mp->local_session_id),
10514          clib_net_to_host_u32 (mp->remote_session_id));
10515
10516   print (vam->ofp, "   l2 specific sublayer %s\n",
10517          mp->l2_sublayer_present ? "preset" : "absent");
10518
10519 }
10520
10521 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10522   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10523 {
10524   vat_main_t *vam = &vat_main;
10525   vat_json_node_t *node = NULL;
10526   struct in6_addr addr;
10527
10528   if (VAT_JSON_ARRAY != vam->json_tree.type)
10529     {
10530       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10531       vat_json_init_array (&vam->json_tree);
10532     }
10533   node = vat_json_array_add (&vam->json_tree);
10534
10535   vat_json_init_object (node);
10536
10537   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10538   vat_json_object_add_ip6 (node, "our_address", addr);
10539   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10540   vat_json_object_add_ip6 (node, "client_address", addr);
10541
10542   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10543   vat_json_init_array (lc);
10544   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10545   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10546   vat_json_object_add_uint (node, "remote_cookie",
10547                             clib_net_to_host_u64 (mp->remote_cookie));
10548
10549   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10550   vat_json_object_add_uint (node, "local_session_id",
10551                             clib_net_to_host_u32 (mp->local_session_id));
10552   vat_json_object_add_uint (node, "remote_session_id",
10553                             clib_net_to_host_u32 (mp->remote_session_id));
10554   vat_json_object_add_string_copy (node, "l2_sublayer",
10555                                    mp->l2_sublayer_present ? (u8 *) "present"
10556                                    : (u8 *) "absent");
10557 }
10558
10559 static int
10560 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10561 {
10562   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10563   vl_api_control_ping_t *mp_ping;
10564   int ret;
10565
10566   /* Get list of l2tpv3-tunnel interfaces */
10567   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
10568   S (mp);
10569
10570   /* Use a control ping for synchronization */
10571   M (CONTROL_PING, mp_ping);
10572   S (mp_ping);
10573
10574   W (ret);
10575   return ret;
10576 }
10577
10578
10579 static void vl_api_sw_interface_tap_details_t_handler
10580   (vl_api_sw_interface_tap_details_t * mp)
10581 {
10582   vat_main_t *vam = &vat_main;
10583
10584   print (vam->ofp, "%-16s %d",
10585          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10586 }
10587
10588 static void vl_api_sw_interface_tap_details_t_handler_json
10589   (vl_api_sw_interface_tap_details_t * mp)
10590 {
10591   vat_main_t *vam = &vat_main;
10592   vat_json_node_t *node = NULL;
10593
10594   if (VAT_JSON_ARRAY != vam->json_tree.type)
10595     {
10596       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10597       vat_json_init_array (&vam->json_tree);
10598     }
10599   node = vat_json_array_add (&vam->json_tree);
10600
10601   vat_json_init_object (node);
10602   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10603   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10604 }
10605
10606 static int
10607 api_sw_interface_tap_dump (vat_main_t * vam)
10608 {
10609   vl_api_sw_interface_tap_dump_t *mp;
10610   vl_api_control_ping_t *mp_ping;
10611   int ret;
10612
10613   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10614   /* Get list of tap interfaces */
10615   M (SW_INTERFACE_TAP_DUMP, mp);
10616   S (mp);
10617
10618   /* Use a control ping for synchronization */
10619   M (CONTROL_PING, mp_ping);
10620   S (mp_ping);
10621
10622   W (ret);
10623   return ret;
10624 }
10625
10626 static uword unformat_vxlan_decap_next
10627   (unformat_input_t * input, va_list * args)
10628 {
10629   u32 *result = va_arg (*args, u32 *);
10630   u32 tmp;
10631
10632   if (unformat (input, "l2"))
10633     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10634   else if (unformat (input, "%d", &tmp))
10635     *result = tmp;
10636   else
10637     return 0;
10638   return 1;
10639 }
10640
10641 static int
10642 api_vxlan_add_del_tunnel (vat_main_t * vam)
10643 {
10644   unformat_input_t *line_input = vam->input;
10645   vl_api_vxlan_add_del_tunnel_t *mp;
10646   ip46_address_t src, dst;
10647   u8 is_add = 1;
10648   u8 ipv4_set = 0, ipv6_set = 0;
10649   u8 src_set = 0;
10650   u8 dst_set = 0;
10651   u8 grp_set = 0;
10652   u32 mcast_sw_if_index = ~0;
10653   u32 encap_vrf_id = 0;
10654   u32 decap_next_index = ~0;
10655   u32 vni = 0;
10656   int ret;
10657
10658   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10659   memset (&src, 0, sizeof src);
10660   memset (&dst, 0, sizeof dst);
10661
10662   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (unformat (line_input, "del"))
10665         is_add = 0;
10666       else
10667         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10668         {
10669           ipv4_set = 1;
10670           src_set = 1;
10671         }
10672       else
10673         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10674         {
10675           ipv4_set = 1;
10676           dst_set = 1;
10677         }
10678       else
10679         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10680         {
10681           ipv6_set = 1;
10682           src_set = 1;
10683         }
10684       else
10685         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10686         {
10687           ipv6_set = 1;
10688           dst_set = 1;
10689         }
10690       else if (unformat (line_input, "group %U %U",
10691                          unformat_ip4_address, &dst.ip4,
10692                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10693         {
10694           grp_set = dst_set = 1;
10695           ipv4_set = 1;
10696         }
10697       else if (unformat (line_input, "group %U",
10698                          unformat_ip4_address, &dst.ip4))
10699         {
10700           grp_set = dst_set = 1;
10701           ipv4_set = 1;
10702         }
10703       else if (unformat (line_input, "group %U %U",
10704                          unformat_ip6_address, &dst.ip6,
10705                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10706         {
10707           grp_set = dst_set = 1;
10708           ipv6_set = 1;
10709         }
10710       else if (unformat (line_input, "group %U",
10711                          unformat_ip6_address, &dst.ip6))
10712         {
10713           grp_set = dst_set = 1;
10714           ipv6_set = 1;
10715         }
10716       else
10717         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10718         ;
10719       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10720         ;
10721       else if (unformat (line_input, "decap-next %U",
10722                          unformat_vxlan_decap_next, &decap_next_index))
10723         ;
10724       else if (unformat (line_input, "vni %d", &vni))
10725         ;
10726       else
10727         {
10728           errmsg ("parse error '%U'", format_unformat_error, line_input);
10729           return -99;
10730         }
10731     }
10732
10733   if (src_set == 0)
10734     {
10735       errmsg ("tunnel src address not specified");
10736       return -99;
10737     }
10738   if (dst_set == 0)
10739     {
10740       errmsg ("tunnel dst address not specified");
10741       return -99;
10742     }
10743
10744   if (grp_set && !ip46_address_is_multicast (&dst))
10745     {
10746       errmsg ("tunnel group address not multicast");
10747       return -99;
10748     }
10749   if (grp_set && mcast_sw_if_index == ~0)
10750     {
10751       errmsg ("tunnel nonexistent multicast device");
10752       return -99;
10753     }
10754   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10755     {
10756       errmsg ("tunnel dst address must be unicast");
10757       return -99;
10758     }
10759
10760
10761   if (ipv4_set && ipv6_set)
10762     {
10763       errmsg ("both IPv4 and IPv6 addresses specified");
10764       return -99;
10765     }
10766
10767   if ((vni == 0) || (vni >> 24))
10768     {
10769       errmsg ("vni not specified or out of range");
10770       return -99;
10771     }
10772
10773   M (VXLAN_ADD_DEL_TUNNEL, mp);
10774
10775   if (ipv6_set)
10776     {
10777       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10778       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10779     }
10780   else
10781     {
10782       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10783       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10784     }
10785   mp->encap_vrf_id = ntohl (encap_vrf_id);
10786   mp->decap_next_index = ntohl (decap_next_index);
10787   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10788   mp->vni = ntohl (vni);
10789   mp->is_add = is_add;
10790   mp->is_ipv6 = ipv6_set;
10791
10792   S (mp);
10793   W (ret);
10794   return ret;
10795 }
10796
10797 static void vl_api_vxlan_tunnel_details_t_handler
10798   (vl_api_vxlan_tunnel_details_t * mp)
10799 {
10800   vat_main_t *vam = &vat_main;
10801   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
10802   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
10803
10804   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10805          ntohl (mp->sw_if_index),
10806          format_ip46_address, &src, IP46_TYPE_ANY,
10807          format_ip46_address, &dst, IP46_TYPE_ANY,
10808          ntohl (mp->encap_vrf_id),
10809          ntohl (mp->decap_next_index), ntohl (mp->vni),
10810          ntohl (mp->mcast_sw_if_index));
10811 }
10812
10813 static void vl_api_vxlan_tunnel_details_t_handler_json
10814   (vl_api_vxlan_tunnel_details_t * mp)
10815 {
10816   vat_main_t *vam = &vat_main;
10817   vat_json_node_t *node = NULL;
10818
10819   if (VAT_JSON_ARRAY != vam->json_tree.type)
10820     {
10821       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10822       vat_json_init_array (&vam->json_tree);
10823     }
10824   node = vat_json_array_add (&vam->json_tree);
10825
10826   vat_json_init_object (node);
10827   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10828   if (mp->is_ipv6)
10829     {
10830       struct in6_addr ip6;
10831
10832       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10833       vat_json_object_add_ip6 (node, "src_address", ip6);
10834       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10835       vat_json_object_add_ip6 (node, "dst_address", ip6);
10836     }
10837   else
10838     {
10839       struct in_addr ip4;
10840
10841       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10842       vat_json_object_add_ip4 (node, "src_address", ip4);
10843       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10844       vat_json_object_add_ip4 (node, "dst_address", ip4);
10845     }
10846   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10847   vat_json_object_add_uint (node, "decap_next_index",
10848                             ntohl (mp->decap_next_index));
10849   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10850   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10851   vat_json_object_add_uint (node, "mcast_sw_if_index",
10852                             ntohl (mp->mcast_sw_if_index));
10853 }
10854
10855 static int
10856 api_vxlan_tunnel_dump (vat_main_t * vam)
10857 {
10858   unformat_input_t *i = vam->input;
10859   vl_api_vxlan_tunnel_dump_t *mp;
10860   vl_api_control_ping_t *mp_ping;
10861   u32 sw_if_index;
10862   u8 sw_if_index_set = 0;
10863   int ret;
10864
10865   /* Parse args required to build the message */
10866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10867     {
10868       if (unformat (i, "sw_if_index %d", &sw_if_index))
10869         sw_if_index_set = 1;
10870       else
10871         break;
10872     }
10873
10874   if (sw_if_index_set == 0)
10875     {
10876       sw_if_index = ~0;
10877     }
10878
10879   if (!vam->json_output)
10880     {
10881       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10882              "sw_if_index", "src_address", "dst_address",
10883              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10884     }
10885
10886   /* Get list of vxlan-tunnel interfaces */
10887   M (VXLAN_TUNNEL_DUMP, mp);
10888
10889   mp->sw_if_index = htonl (sw_if_index);
10890
10891   S (mp);
10892
10893   /* Use a control ping for synchronization */
10894   M (CONTROL_PING, mp_ping);
10895   S (mp_ping);
10896
10897   W (ret);
10898   return ret;
10899 }
10900
10901 static int
10902 api_gre_add_del_tunnel (vat_main_t * vam)
10903 {
10904   unformat_input_t *line_input = vam->input;
10905   vl_api_gre_add_del_tunnel_t *mp;
10906   ip4_address_t src4, dst4;
10907   u8 is_add = 1;
10908   u8 teb = 0;
10909   u8 src_set = 0;
10910   u8 dst_set = 0;
10911   u32 outer_fib_id = 0;
10912   int ret;
10913
10914   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10915     {
10916       if (unformat (line_input, "del"))
10917         is_add = 0;
10918       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10919         src_set = 1;
10920       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10921         dst_set = 1;
10922       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10923         ;
10924       else if (unformat (line_input, "teb"))
10925         teb = 1;
10926       else
10927         {
10928           errmsg ("parse error '%U'", format_unformat_error, line_input);
10929           return -99;
10930         }
10931     }
10932
10933   if (src_set == 0)
10934     {
10935       errmsg ("tunnel src address not specified");
10936       return -99;
10937     }
10938   if (dst_set == 0)
10939     {
10940       errmsg ("tunnel dst address not specified");
10941       return -99;
10942     }
10943
10944
10945   M (GRE_ADD_DEL_TUNNEL, mp);
10946
10947   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10948   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10949   mp->outer_fib_id = ntohl (outer_fib_id);
10950   mp->is_add = is_add;
10951   mp->teb = teb;
10952
10953   S (mp);
10954   W (ret);
10955   return ret;
10956 }
10957
10958 static void vl_api_gre_tunnel_details_t_handler
10959   (vl_api_gre_tunnel_details_t * mp)
10960 {
10961   vat_main_t *vam = &vat_main;
10962
10963   print (vam->ofp, "%11d%15U%15U%6d%14d",
10964          ntohl (mp->sw_if_index),
10965          format_ip4_address, &mp->src_address,
10966          format_ip4_address, &mp->dst_address,
10967          mp->teb, ntohl (mp->outer_fib_id));
10968 }
10969
10970 static void vl_api_gre_tunnel_details_t_handler_json
10971   (vl_api_gre_tunnel_details_t * mp)
10972 {
10973   vat_main_t *vam = &vat_main;
10974   vat_json_node_t *node = NULL;
10975   struct in_addr ip4;
10976
10977   if (VAT_JSON_ARRAY != vam->json_tree.type)
10978     {
10979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10980       vat_json_init_array (&vam->json_tree);
10981     }
10982   node = vat_json_array_add (&vam->json_tree);
10983
10984   vat_json_init_object (node);
10985   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10986   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10987   vat_json_object_add_ip4 (node, "src_address", ip4);
10988   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10989   vat_json_object_add_ip4 (node, "dst_address", ip4);
10990   vat_json_object_add_uint (node, "teb", mp->teb);
10991   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10992 }
10993
10994 static int
10995 api_gre_tunnel_dump (vat_main_t * vam)
10996 {
10997   unformat_input_t *i = vam->input;
10998   vl_api_gre_tunnel_dump_t *mp;
10999   vl_api_control_ping_t *mp_ping;
11000   u32 sw_if_index;
11001   u8 sw_if_index_set = 0;
11002   int ret;
11003
11004   /* Parse args required to build the message */
11005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11006     {
11007       if (unformat (i, "sw_if_index %d", &sw_if_index))
11008         sw_if_index_set = 1;
11009       else
11010         break;
11011     }
11012
11013   if (sw_if_index_set == 0)
11014     {
11015       sw_if_index = ~0;
11016     }
11017
11018   if (!vam->json_output)
11019     {
11020       print (vam->ofp, "%11s%15s%15s%6s%14s",
11021              "sw_if_index", "src_address", "dst_address", "teb",
11022              "outer_fib_id");
11023     }
11024
11025   /* Get list of gre-tunnel interfaces */
11026   M (GRE_TUNNEL_DUMP, mp);
11027
11028   mp->sw_if_index = htonl (sw_if_index);
11029
11030   S (mp);
11031
11032   /* Use a control ping for synchronization */
11033   M (CONTROL_PING, mp_ping);
11034   S (mp_ping);
11035
11036   W (ret);
11037   return ret;
11038 }
11039
11040 static int
11041 api_l2_fib_clear_table (vat_main_t * vam)
11042 {
11043 //  unformat_input_t * i = vam->input;
11044   vl_api_l2_fib_clear_table_t *mp;
11045   int ret;
11046
11047   M (L2_FIB_CLEAR_TABLE, mp);
11048
11049   S (mp);
11050   W (ret);
11051   return ret;
11052 }
11053
11054 static int
11055 api_l2_interface_efp_filter (vat_main_t * vam)
11056 {
11057   unformat_input_t *i = vam->input;
11058   vl_api_l2_interface_efp_filter_t *mp;
11059   u32 sw_if_index;
11060   u8 enable = 1;
11061   u8 sw_if_index_set = 0;
11062   int ret;
11063
11064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11065     {
11066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11067         sw_if_index_set = 1;
11068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11069         sw_if_index_set = 1;
11070       else if (unformat (i, "enable"))
11071         enable = 1;
11072       else if (unformat (i, "disable"))
11073         enable = 0;
11074       else
11075         {
11076           clib_warning ("parse error '%U'", format_unformat_error, i);
11077           return -99;
11078         }
11079     }
11080
11081   if (sw_if_index_set == 0)
11082     {
11083       errmsg ("missing sw_if_index");
11084       return -99;
11085     }
11086
11087   M (L2_INTERFACE_EFP_FILTER, mp);
11088
11089   mp->sw_if_index = ntohl (sw_if_index);
11090   mp->enable_disable = enable;
11091
11092   S (mp);
11093   W (ret);
11094   return ret;
11095 }
11096
11097 #define foreach_vtr_op                          \
11098 _("disable",  L2_VTR_DISABLED)                  \
11099 _("push-1",  L2_VTR_PUSH_1)                     \
11100 _("push-2",  L2_VTR_PUSH_2)                     \
11101 _("pop-1",  L2_VTR_POP_1)                       \
11102 _("pop-2",  L2_VTR_POP_2)                       \
11103 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
11104 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
11105 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
11106 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
11107
11108 static int
11109 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
11113   u32 sw_if_index;
11114   u8 sw_if_index_set = 0;
11115   u8 vtr_op_set = 0;
11116   u32 vtr_op = 0;
11117   u32 push_dot1q = 1;
11118   u32 tag1 = ~0;
11119   u32 tag2 = ~0;
11120   int ret;
11121
11122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11123     {
11124       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11125         sw_if_index_set = 1;
11126       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11127         sw_if_index_set = 1;
11128       else if (unformat (i, "vtr_op %d", &vtr_op))
11129         vtr_op_set = 1;
11130 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
11131       foreach_vtr_op
11132 #undef _
11133         else if (unformat (i, "push_dot1q %d", &push_dot1q))
11134         ;
11135       else if (unformat (i, "tag1 %d", &tag1))
11136         ;
11137       else if (unformat (i, "tag2 %d", &tag2))
11138         ;
11139       else
11140         {
11141           clib_warning ("parse error '%U'", format_unformat_error, i);
11142           return -99;
11143         }
11144     }
11145
11146   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
11147     {
11148       errmsg ("missing vtr operation or sw_if_index");
11149       return -99;
11150     }
11151
11152   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
11153   mp->sw_if_index = ntohl (sw_if_index);
11154   mp->vtr_op = ntohl (vtr_op);
11155   mp->push_dot1q = ntohl (push_dot1q);
11156   mp->tag1 = ntohl (tag1);
11157   mp->tag2 = ntohl (tag2);
11158
11159   S (mp);
11160   W (ret);
11161   return ret;
11162 }
11163
11164 static int
11165 api_create_vhost_user_if (vat_main_t * vam)
11166 {
11167   unformat_input_t *i = vam->input;
11168   vl_api_create_vhost_user_if_t *mp;
11169   u8 *file_name;
11170   u8 is_server = 0;
11171   u8 file_name_set = 0;
11172   u32 custom_dev_instance = ~0;
11173   u8 hwaddr[6];
11174   u8 use_custom_mac = 0;
11175   u8 *tag = 0;
11176   int ret;
11177
11178   /* Shut up coverity */
11179   memset (hwaddr, 0, sizeof (hwaddr));
11180
11181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (i, "socket %s", &file_name))
11184         {
11185           file_name_set = 1;
11186         }
11187       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11188         ;
11189       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
11190         use_custom_mac = 1;
11191       else if (unformat (i, "server"))
11192         is_server = 1;
11193       else if (unformat (i, "tag %s", &tag))
11194         ;
11195       else
11196         break;
11197     }
11198
11199   if (file_name_set == 0)
11200     {
11201       errmsg ("missing socket file name");
11202       return -99;
11203     }
11204
11205   if (vec_len (file_name) > 255)
11206     {
11207       errmsg ("socket file name too long");
11208       return -99;
11209     }
11210   vec_add1 (file_name, 0);
11211
11212   M (CREATE_VHOST_USER_IF, mp);
11213
11214   mp->is_server = is_server;
11215   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11216   vec_free (file_name);
11217   if (custom_dev_instance != ~0)
11218     {
11219       mp->renumber = 1;
11220       mp->custom_dev_instance = ntohl (custom_dev_instance);
11221     }
11222   mp->use_custom_mac = use_custom_mac;
11223   clib_memcpy (mp->mac_address, hwaddr, 6);
11224   if (tag)
11225     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
11226   vec_free (tag);
11227
11228   S (mp);
11229   W (ret);
11230   return ret;
11231 }
11232
11233 static int
11234 api_modify_vhost_user_if (vat_main_t * vam)
11235 {
11236   unformat_input_t *i = vam->input;
11237   vl_api_modify_vhost_user_if_t *mp;
11238   u8 *file_name;
11239   u8 is_server = 0;
11240   u8 file_name_set = 0;
11241   u32 custom_dev_instance = ~0;
11242   u8 sw_if_index_set = 0;
11243   u32 sw_if_index = (u32) ~ 0;
11244   int ret;
11245
11246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11249         sw_if_index_set = 1;
11250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11251         sw_if_index_set = 1;
11252       else if (unformat (i, "socket %s", &file_name))
11253         {
11254           file_name_set = 1;
11255         }
11256       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
11257         ;
11258       else if (unformat (i, "server"))
11259         is_server = 1;
11260       else
11261         break;
11262     }
11263
11264   if (sw_if_index_set == 0)
11265     {
11266       errmsg ("missing sw_if_index or interface name");
11267       return -99;
11268     }
11269
11270   if (file_name_set == 0)
11271     {
11272       errmsg ("missing socket file name");
11273       return -99;
11274     }
11275
11276   if (vec_len (file_name) > 255)
11277     {
11278       errmsg ("socket file name too long");
11279       return -99;
11280     }
11281   vec_add1 (file_name, 0);
11282
11283   M (MODIFY_VHOST_USER_IF, mp);
11284
11285   mp->sw_if_index = ntohl (sw_if_index);
11286   mp->is_server = is_server;
11287   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11288   vec_free (file_name);
11289   if (custom_dev_instance != ~0)
11290     {
11291       mp->renumber = 1;
11292       mp->custom_dev_instance = ntohl (custom_dev_instance);
11293     }
11294
11295   S (mp);
11296   W (ret);
11297   return ret;
11298 }
11299
11300 static int
11301 api_delete_vhost_user_if (vat_main_t * vam)
11302 {
11303   unformat_input_t *i = vam->input;
11304   vl_api_delete_vhost_user_if_t *mp;
11305   u32 sw_if_index = ~0;
11306   u8 sw_if_index_set = 0;
11307   int ret;
11308
11309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11310     {
11311       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11312         sw_if_index_set = 1;
11313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11314         sw_if_index_set = 1;
11315       else
11316         break;
11317     }
11318
11319   if (sw_if_index_set == 0)
11320     {
11321       errmsg ("missing sw_if_index or interface name");
11322       return -99;
11323     }
11324
11325
11326   M (DELETE_VHOST_USER_IF, mp);
11327
11328   mp->sw_if_index = ntohl (sw_if_index);
11329
11330   S (mp);
11331   W (ret);
11332   return ret;
11333 }
11334
11335 static void vl_api_sw_interface_vhost_user_details_t_handler
11336   (vl_api_sw_interface_vhost_user_details_t * mp)
11337 {
11338   vat_main_t *vam = &vat_main;
11339
11340   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11341          (char *) mp->interface_name,
11342          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11343          clib_net_to_host_u64 (mp->features), mp->is_server,
11344          ntohl (mp->num_regions), (char *) mp->sock_filename);
11345   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11346 }
11347
11348 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11349   (vl_api_sw_interface_vhost_user_details_t * mp)
11350 {
11351   vat_main_t *vam = &vat_main;
11352   vat_json_node_t *node = NULL;
11353
11354   if (VAT_JSON_ARRAY != vam->json_tree.type)
11355     {
11356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11357       vat_json_init_array (&vam->json_tree);
11358     }
11359   node = vat_json_array_add (&vam->json_tree);
11360
11361   vat_json_init_object (node);
11362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11363   vat_json_object_add_string_copy (node, "interface_name",
11364                                    mp->interface_name);
11365   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11366                             ntohl (mp->virtio_net_hdr_sz));
11367   vat_json_object_add_uint (node, "features",
11368                             clib_net_to_host_u64 (mp->features));
11369   vat_json_object_add_uint (node, "is_server", mp->is_server);
11370   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11371   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11372   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11373 }
11374
11375 static int
11376 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11377 {
11378   vl_api_sw_interface_vhost_user_dump_t *mp;
11379   vl_api_control_ping_t *mp_ping;
11380   int ret;
11381   print (vam->ofp,
11382          "Interface name           idx hdr_sz features server regions filename");
11383
11384   /* Get list of vhost-user interfaces */
11385   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
11386   S (mp);
11387
11388   /* Use a control ping for synchronization */
11389   M (CONTROL_PING, mp_ping);
11390   S (mp_ping);
11391
11392   W (ret);
11393   return ret;
11394 }
11395
11396 static int
11397 api_show_version (vat_main_t * vam)
11398 {
11399   vl_api_show_version_t *mp;
11400   int ret;
11401
11402   M (SHOW_VERSION, mp);
11403
11404   S (mp);
11405   W (ret);
11406   return ret;
11407 }
11408
11409
11410 static int
11411 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11412 {
11413   unformat_input_t *line_input = vam->input;
11414   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11415   ip4_address_t local4, remote4;
11416   ip6_address_t local6, remote6;
11417   u8 is_add = 1;
11418   u8 ipv4_set = 0, ipv6_set = 0;
11419   u8 local_set = 0;
11420   u8 remote_set = 0;
11421   u32 encap_vrf_id = 0;
11422   u32 decap_vrf_id = 0;
11423   u8 protocol = ~0;
11424   u32 vni;
11425   u8 vni_set = 0;
11426   int ret;
11427
11428   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11429     {
11430       if (unformat (line_input, "del"))
11431         is_add = 0;
11432       else if (unformat (line_input, "local %U",
11433                          unformat_ip4_address, &local4))
11434         {
11435           local_set = 1;
11436           ipv4_set = 1;
11437         }
11438       else if (unformat (line_input, "remote %U",
11439                          unformat_ip4_address, &remote4))
11440         {
11441           remote_set = 1;
11442           ipv4_set = 1;
11443         }
11444       else if (unformat (line_input, "local %U",
11445                          unformat_ip6_address, &local6))
11446         {
11447           local_set = 1;
11448           ipv6_set = 1;
11449         }
11450       else if (unformat (line_input, "remote %U",
11451                          unformat_ip6_address, &remote6))
11452         {
11453           remote_set = 1;
11454           ipv6_set = 1;
11455         }
11456       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11457         ;
11458       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11459         ;
11460       else if (unformat (line_input, "vni %d", &vni))
11461         vni_set = 1;
11462       else if (unformat (line_input, "next-ip4"))
11463         protocol = 1;
11464       else if (unformat (line_input, "next-ip6"))
11465         protocol = 2;
11466       else if (unformat (line_input, "next-ethernet"))
11467         protocol = 3;
11468       else if (unformat (line_input, "next-nsh"))
11469         protocol = 4;
11470       else
11471         {
11472           errmsg ("parse error '%U'", format_unformat_error, line_input);
11473           return -99;
11474         }
11475     }
11476
11477   if (local_set == 0)
11478     {
11479       errmsg ("tunnel local address not specified");
11480       return -99;
11481     }
11482   if (remote_set == 0)
11483     {
11484       errmsg ("tunnel remote address not specified");
11485       return -99;
11486     }
11487   if (ipv4_set && ipv6_set)
11488     {
11489       errmsg ("both IPv4 and IPv6 addresses specified");
11490       return -99;
11491     }
11492
11493   if (vni_set == 0)
11494     {
11495       errmsg ("vni not specified");
11496       return -99;
11497     }
11498
11499   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
11500
11501
11502   if (ipv6_set)
11503     {
11504       clib_memcpy (&mp->local, &local6, sizeof (local6));
11505       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11506     }
11507   else
11508     {
11509       clib_memcpy (&mp->local, &local4, sizeof (local4));
11510       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11511     }
11512
11513   mp->encap_vrf_id = ntohl (encap_vrf_id);
11514   mp->decap_vrf_id = ntohl (decap_vrf_id);
11515   mp->protocol = protocol;
11516   mp->vni = ntohl (vni);
11517   mp->is_add = is_add;
11518   mp->is_ipv6 = ipv6_set;
11519
11520   S (mp);
11521   W (ret);
11522   return ret;
11523 }
11524
11525 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11526   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11527 {
11528   vat_main_t *vam = &vat_main;
11529
11530   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11531          ntohl (mp->sw_if_index),
11532          format_ip46_address, &(mp->local[0]),
11533          format_ip46_address, &(mp->remote[0]),
11534          ntohl (mp->vni),
11535          ntohl (mp->protocol),
11536          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11537 }
11538
11539 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11540   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11541 {
11542   vat_main_t *vam = &vat_main;
11543   vat_json_node_t *node = NULL;
11544   struct in_addr ip4;
11545   struct in6_addr ip6;
11546
11547   if (VAT_JSON_ARRAY != vam->json_tree.type)
11548     {
11549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11550       vat_json_init_array (&vam->json_tree);
11551     }
11552   node = vat_json_array_add (&vam->json_tree);
11553
11554   vat_json_init_object (node);
11555   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11556   if (mp->is_ipv6)
11557     {
11558       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11559       vat_json_object_add_ip6 (node, "local", ip6);
11560       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11561       vat_json_object_add_ip6 (node, "remote", ip6);
11562     }
11563   else
11564     {
11565       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11566       vat_json_object_add_ip4 (node, "local", ip4);
11567       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11568       vat_json_object_add_ip4 (node, "remote", ip4);
11569     }
11570   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11571   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11572   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11573   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11574   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11575 }
11576
11577 static int
11578 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11579 {
11580   unformat_input_t *i = vam->input;
11581   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11582   vl_api_control_ping_t *mp_ping;
11583   u32 sw_if_index;
11584   u8 sw_if_index_set = 0;
11585   int ret;
11586
11587   /* Parse args required to build the message */
11588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11589     {
11590       if (unformat (i, "sw_if_index %d", &sw_if_index))
11591         sw_if_index_set = 1;
11592       else
11593         break;
11594     }
11595
11596   if (sw_if_index_set == 0)
11597     {
11598       sw_if_index = ~0;
11599     }
11600
11601   if (!vam->json_output)
11602     {
11603       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11604              "sw_if_index", "local", "remote", "vni",
11605              "protocol", "encap_vrf_id", "decap_vrf_id");
11606     }
11607
11608   /* Get list of vxlan-tunnel interfaces */
11609   M (VXLAN_GPE_TUNNEL_DUMP, mp);
11610
11611   mp->sw_if_index = htonl (sw_if_index);
11612
11613   S (mp);
11614
11615   /* Use a control ping for synchronization */
11616   M (CONTROL_PING, mp_ping);
11617   S (mp_ping);
11618
11619   W (ret);
11620   return ret;
11621 }
11622
11623 u8 *
11624 format_l2_fib_mac_address (u8 * s, va_list * args)
11625 {
11626   u8 *a = va_arg (*args, u8 *);
11627
11628   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11629                  a[2], a[3], a[4], a[5], a[6], a[7]);
11630 }
11631
11632 static void vl_api_l2_fib_table_entry_t_handler
11633   (vl_api_l2_fib_table_entry_t * mp)
11634 {
11635   vat_main_t *vam = &vat_main;
11636
11637   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11638          "       %d       %d     %d",
11639          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11640          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11641          mp->bvi_mac);
11642 }
11643
11644 static void vl_api_l2_fib_table_entry_t_handler_json
11645   (vl_api_l2_fib_table_entry_t * mp)
11646 {
11647   vat_main_t *vam = &vat_main;
11648   vat_json_node_t *node = NULL;
11649
11650   if (VAT_JSON_ARRAY != vam->json_tree.type)
11651     {
11652       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11653       vat_json_init_array (&vam->json_tree);
11654     }
11655   node = vat_json_array_add (&vam->json_tree);
11656
11657   vat_json_init_object (node);
11658   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11659   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11660   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11661   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11662   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11663   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11664 }
11665
11666 static int
11667 api_l2_fib_table_dump (vat_main_t * vam)
11668 {
11669   unformat_input_t *i = vam->input;
11670   vl_api_l2_fib_table_dump_t *mp;
11671   vl_api_control_ping_t *mp_ping;
11672   u32 bd_id;
11673   u8 bd_id_set = 0;
11674   int ret;
11675
11676   /* Parse args required to build the message */
11677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11678     {
11679       if (unformat (i, "bd_id %d", &bd_id))
11680         bd_id_set = 1;
11681       else
11682         break;
11683     }
11684
11685   if (bd_id_set == 0)
11686     {
11687       errmsg ("missing bridge domain");
11688       return -99;
11689     }
11690
11691   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11692
11693   /* Get list of l2 fib entries */
11694   M (L2_FIB_TABLE_DUMP, mp);
11695
11696   mp->bd_id = ntohl (bd_id);
11697   S (mp);
11698
11699   /* Use a control ping for synchronization */
11700   M (CONTROL_PING, mp_ping);
11701   S (mp_ping);
11702
11703   W (ret);
11704   return ret;
11705 }
11706
11707
11708 static int
11709 api_interface_name_renumber (vat_main_t * vam)
11710 {
11711   unformat_input_t *line_input = vam->input;
11712   vl_api_interface_name_renumber_t *mp;
11713   u32 sw_if_index = ~0;
11714   u32 new_show_dev_instance = ~0;
11715   int ret;
11716
11717   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11718     {
11719       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11720                     &sw_if_index))
11721         ;
11722       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11723         ;
11724       else if (unformat (line_input, "new_show_dev_instance %d",
11725                          &new_show_dev_instance))
11726         ;
11727       else
11728         break;
11729     }
11730
11731   if (sw_if_index == ~0)
11732     {
11733       errmsg ("missing interface name or sw_if_index");
11734       return -99;
11735     }
11736
11737   if (new_show_dev_instance == ~0)
11738     {
11739       errmsg ("missing new_show_dev_instance");
11740       return -99;
11741     }
11742
11743   M (INTERFACE_NAME_RENUMBER, mp);
11744
11745   mp->sw_if_index = ntohl (sw_if_index);
11746   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11747
11748   S (mp);
11749   W (ret);
11750   return ret;
11751 }
11752
11753 static int
11754 api_want_ip4_arp_events (vat_main_t * vam)
11755 {
11756   unformat_input_t *line_input = vam->input;
11757   vl_api_want_ip4_arp_events_t *mp;
11758   ip4_address_t address;
11759   int address_set = 0;
11760   u32 enable_disable = 1;
11761   int ret;
11762
11763   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11764     {
11765       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11766         address_set = 1;
11767       else if (unformat (line_input, "del"))
11768         enable_disable = 0;
11769       else
11770         break;
11771     }
11772
11773   if (address_set == 0)
11774     {
11775       errmsg ("missing addresses");
11776       return -99;
11777     }
11778
11779   M (WANT_IP4_ARP_EVENTS, mp);
11780   mp->enable_disable = enable_disable;
11781   mp->pid = getpid ();
11782   mp->address = address.as_u32;
11783
11784   S (mp);
11785   W (ret);
11786   return ret;
11787 }
11788
11789 static int
11790 api_want_ip6_nd_events (vat_main_t * vam)
11791 {
11792   unformat_input_t *line_input = vam->input;
11793   vl_api_want_ip6_nd_events_t *mp;
11794   ip6_address_t address;
11795   int address_set = 0;
11796   u32 enable_disable = 1;
11797   int ret;
11798
11799   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11800     {
11801       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11802         address_set = 1;
11803       else if (unformat (line_input, "del"))
11804         enable_disable = 0;
11805       else
11806         break;
11807     }
11808
11809   if (address_set == 0)
11810     {
11811       errmsg ("missing addresses");
11812       return -99;
11813     }
11814
11815   M (WANT_IP6_ND_EVENTS, mp);
11816   mp->enable_disable = enable_disable;
11817   mp->pid = getpid ();
11818   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11819
11820   S (mp);
11821   W (ret);
11822   return ret;
11823 }
11824
11825 static int
11826 api_input_acl_set_interface (vat_main_t * vam)
11827 {
11828   unformat_input_t *i = vam->input;
11829   vl_api_input_acl_set_interface_t *mp;
11830   u32 sw_if_index;
11831   int sw_if_index_set;
11832   u32 ip4_table_index = ~0;
11833   u32 ip6_table_index = ~0;
11834   u32 l2_table_index = ~0;
11835   u8 is_add = 1;
11836   int ret;
11837
11838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11839     {
11840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11841         sw_if_index_set = 1;
11842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11843         sw_if_index_set = 1;
11844       else if (unformat (i, "del"))
11845         is_add = 0;
11846       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11847         ;
11848       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11849         ;
11850       else if (unformat (i, "l2-table %d", &l2_table_index))
11851         ;
11852       else
11853         {
11854           clib_warning ("parse error '%U'", format_unformat_error, i);
11855           return -99;
11856         }
11857     }
11858
11859   if (sw_if_index_set == 0)
11860     {
11861       errmsg ("missing interface name or sw_if_index");
11862       return -99;
11863     }
11864
11865   M (INPUT_ACL_SET_INTERFACE, mp);
11866
11867   mp->sw_if_index = ntohl (sw_if_index);
11868   mp->ip4_table_index = ntohl (ip4_table_index);
11869   mp->ip6_table_index = ntohl (ip6_table_index);
11870   mp->l2_table_index = ntohl (l2_table_index);
11871   mp->is_add = is_add;
11872
11873   S (mp);
11874   W (ret);
11875   return ret;
11876 }
11877
11878 static int
11879 api_ip_address_dump (vat_main_t * vam)
11880 {
11881   unformat_input_t *i = vam->input;
11882   vl_api_ip_address_dump_t *mp;
11883   vl_api_control_ping_t *mp_ping;
11884   u32 sw_if_index = ~0;
11885   u8 sw_if_index_set = 0;
11886   u8 ipv4_set = 0;
11887   u8 ipv6_set = 0;
11888   int ret;
11889
11890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11891     {
11892       if (unformat (i, "sw_if_index %d", &sw_if_index))
11893         sw_if_index_set = 1;
11894       else
11895         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11896         sw_if_index_set = 1;
11897       else if (unformat (i, "ipv4"))
11898         ipv4_set = 1;
11899       else if (unformat (i, "ipv6"))
11900         ipv6_set = 1;
11901       else
11902         break;
11903     }
11904
11905   if (ipv4_set && ipv6_set)
11906     {
11907       errmsg ("ipv4 and ipv6 flags cannot be both set");
11908       return -99;
11909     }
11910
11911   if ((!ipv4_set) && (!ipv6_set))
11912     {
11913       errmsg ("no ipv4 nor ipv6 flag set");
11914       return -99;
11915     }
11916
11917   if (sw_if_index_set == 0)
11918     {
11919       errmsg ("missing interface name or sw_if_index");
11920       return -99;
11921     }
11922
11923   vam->current_sw_if_index = sw_if_index;
11924   vam->is_ipv6 = ipv6_set;
11925
11926   M (IP_ADDRESS_DUMP, mp);
11927   mp->sw_if_index = ntohl (sw_if_index);
11928   mp->is_ipv6 = ipv6_set;
11929   S (mp);
11930
11931   /* Use a control ping for synchronization */
11932   M (CONTROL_PING, mp_ping);
11933   S (mp_ping);
11934
11935   W (ret);
11936   return ret;
11937 }
11938
11939 static int
11940 api_ip_dump (vat_main_t * vam)
11941 {
11942   vl_api_ip_dump_t *mp;
11943   vl_api_control_ping_t *mp_ping;
11944   unformat_input_t *in = vam->input;
11945   int ipv4_set = 0;
11946   int ipv6_set = 0;
11947   int is_ipv6;
11948   int i;
11949   int ret;
11950
11951   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11952     {
11953       if (unformat (in, "ipv4"))
11954         ipv4_set = 1;
11955       else if (unformat (in, "ipv6"))
11956         ipv6_set = 1;
11957       else
11958         break;
11959     }
11960
11961   if (ipv4_set && ipv6_set)
11962     {
11963       errmsg ("ipv4 and ipv6 flags cannot be both set");
11964       return -99;
11965     }
11966
11967   if ((!ipv4_set) && (!ipv6_set))
11968     {
11969       errmsg ("no ipv4 nor ipv6 flag set");
11970       return -99;
11971     }
11972
11973   is_ipv6 = ipv6_set;
11974   vam->is_ipv6 = is_ipv6;
11975
11976   /* free old data */
11977   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11978     {
11979       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11980     }
11981   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11982
11983   M (IP_DUMP, mp);
11984   mp->is_ipv6 = ipv6_set;
11985   S (mp);
11986
11987   /* Use a control ping for synchronization */
11988   M (CONTROL_PING, mp_ping);
11989   S (mp_ping);
11990
11991   W (ret);
11992   return ret;
11993 }
11994
11995 static int
11996 api_ipsec_spd_add_del (vat_main_t * vam)
11997 {
11998   unformat_input_t *i = vam->input;
11999   vl_api_ipsec_spd_add_del_t *mp;
12000   u32 spd_id = ~0;
12001   u8 is_add = 1;
12002   int ret;
12003
12004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12005     {
12006       if (unformat (i, "spd_id %d", &spd_id))
12007         ;
12008       else if (unformat (i, "del"))
12009         is_add = 0;
12010       else
12011         {
12012           clib_warning ("parse error '%U'", format_unformat_error, i);
12013           return -99;
12014         }
12015     }
12016   if (spd_id == ~0)
12017     {
12018       errmsg ("spd_id must be set");
12019       return -99;
12020     }
12021
12022   M (IPSEC_SPD_ADD_DEL, mp);
12023
12024   mp->spd_id = ntohl (spd_id);
12025   mp->is_add = is_add;
12026
12027   S (mp);
12028   W (ret);
12029   return ret;
12030 }
12031
12032 static int
12033 api_ipsec_interface_add_del_spd (vat_main_t * vam)
12034 {
12035   unformat_input_t *i = vam->input;
12036   vl_api_ipsec_interface_add_del_spd_t *mp;
12037   u32 sw_if_index;
12038   u8 sw_if_index_set = 0;
12039   u32 spd_id = (u32) ~ 0;
12040   u8 is_add = 1;
12041   int ret;
12042
12043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12044     {
12045       if (unformat (i, "del"))
12046         is_add = 0;
12047       else if (unformat (i, "spd_id %d", &spd_id))
12048         ;
12049       else
12050         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12051         sw_if_index_set = 1;
12052       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12053         sw_if_index_set = 1;
12054       else
12055         {
12056           clib_warning ("parse error '%U'", format_unformat_error, i);
12057           return -99;
12058         }
12059
12060     }
12061
12062   if (spd_id == (u32) ~ 0)
12063     {
12064       errmsg ("spd_id must be set");
12065       return -99;
12066     }
12067
12068   if (sw_if_index_set == 0)
12069     {
12070       errmsg ("missing interface name or sw_if_index");
12071       return -99;
12072     }
12073
12074   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
12075
12076   mp->spd_id = ntohl (spd_id);
12077   mp->sw_if_index = ntohl (sw_if_index);
12078   mp->is_add = is_add;
12079
12080   S (mp);
12081   W (ret);
12082   return ret;
12083 }
12084
12085 static int
12086 api_ipsec_spd_add_del_entry (vat_main_t * vam)
12087 {
12088   unformat_input_t *i = vam->input;
12089   vl_api_ipsec_spd_add_del_entry_t *mp;
12090   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
12091   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
12092   i32 priority = 0;
12093   u32 rport_start = 0, rport_stop = (u32) ~ 0;
12094   u32 lport_start = 0, lport_stop = (u32) ~ 0;
12095   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
12096   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
12097   int ret;
12098
12099   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
12100   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
12101   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
12102   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
12103   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
12104   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
12105
12106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12107     {
12108       if (unformat (i, "del"))
12109         is_add = 0;
12110       if (unformat (i, "outbound"))
12111         is_outbound = 1;
12112       if (unformat (i, "inbound"))
12113         is_outbound = 0;
12114       else if (unformat (i, "spd_id %d", &spd_id))
12115         ;
12116       else if (unformat (i, "sa_id %d", &sa_id))
12117         ;
12118       else if (unformat (i, "priority %d", &priority))
12119         ;
12120       else if (unformat (i, "protocol %d", &protocol))
12121         ;
12122       else if (unformat (i, "lport_start %d", &lport_start))
12123         ;
12124       else if (unformat (i, "lport_stop %d", &lport_stop))
12125         ;
12126       else if (unformat (i, "rport_start %d", &rport_start))
12127         ;
12128       else if (unformat (i, "rport_stop %d", &rport_stop))
12129         ;
12130       else
12131         if (unformat
12132             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
12133         {
12134           is_ipv6 = 0;
12135           is_ip_any = 0;
12136         }
12137       else
12138         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
12139         {
12140           is_ipv6 = 0;
12141           is_ip_any = 0;
12142         }
12143       else
12144         if (unformat
12145             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
12146         {
12147           is_ipv6 = 0;
12148           is_ip_any = 0;
12149         }
12150       else
12151         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
12152         {
12153           is_ipv6 = 0;
12154           is_ip_any = 0;
12155         }
12156       else
12157         if (unformat
12158             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
12159         {
12160           is_ipv6 = 1;
12161           is_ip_any = 0;
12162         }
12163       else
12164         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
12165         {
12166           is_ipv6 = 1;
12167           is_ip_any = 0;
12168         }
12169       else
12170         if (unformat
12171             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
12172         {
12173           is_ipv6 = 1;
12174           is_ip_any = 0;
12175         }
12176       else
12177         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
12178         {
12179           is_ipv6 = 1;
12180           is_ip_any = 0;
12181         }
12182       else
12183         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
12184         {
12185           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
12186             {
12187               clib_warning ("unsupported action: 'resolve'");
12188               return -99;
12189             }
12190         }
12191       else
12192         {
12193           clib_warning ("parse error '%U'", format_unformat_error, i);
12194           return -99;
12195         }
12196
12197     }
12198
12199   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
12200
12201   mp->spd_id = ntohl (spd_id);
12202   mp->priority = ntohl (priority);
12203   mp->is_outbound = is_outbound;
12204
12205   mp->is_ipv6 = is_ipv6;
12206   if (is_ipv6 || is_ip_any)
12207     {
12208       clib_memcpy (mp->remote_address_start, &raddr6_start,
12209                    sizeof (ip6_address_t));
12210       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
12211                    sizeof (ip6_address_t));
12212       clib_memcpy (mp->local_address_start, &laddr6_start,
12213                    sizeof (ip6_address_t));
12214       clib_memcpy (mp->local_address_stop, &laddr6_stop,
12215                    sizeof (ip6_address_t));
12216     }
12217   else
12218     {
12219       clib_memcpy (mp->remote_address_start, &raddr4_start,
12220                    sizeof (ip4_address_t));
12221       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
12222                    sizeof (ip4_address_t));
12223       clib_memcpy (mp->local_address_start, &laddr4_start,
12224                    sizeof (ip4_address_t));
12225       clib_memcpy (mp->local_address_stop, &laddr4_stop,
12226                    sizeof (ip4_address_t));
12227     }
12228   mp->protocol = (u8) protocol;
12229   mp->local_port_start = ntohs ((u16) lport_start);
12230   mp->local_port_stop = ntohs ((u16) lport_stop);
12231   mp->remote_port_start = ntohs ((u16) rport_start);
12232   mp->remote_port_stop = ntohs ((u16) rport_stop);
12233   mp->policy = (u8) policy;
12234   mp->sa_id = ntohl (sa_id);
12235   mp->is_add = is_add;
12236   mp->is_ip_any = is_ip_any;
12237   S (mp);
12238   W (ret);
12239   return ret;
12240 }
12241
12242 static int
12243 api_ipsec_sad_add_del_entry (vat_main_t * vam)
12244 {
12245   unformat_input_t *i = vam->input;
12246   vl_api_ipsec_sad_add_del_entry_t *mp;
12247   u32 sad_id = 0, spi = 0;
12248   u8 *ck = 0, *ik = 0;
12249   u8 is_add = 1;
12250
12251   u8 protocol = IPSEC_PROTOCOL_AH;
12252   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
12253   u32 crypto_alg = 0, integ_alg = 0;
12254   ip4_address_t tun_src4;
12255   ip4_address_t tun_dst4;
12256   ip6_address_t tun_src6;
12257   ip6_address_t tun_dst6;
12258   int ret;
12259
12260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12261     {
12262       if (unformat (i, "del"))
12263         is_add = 0;
12264       else if (unformat (i, "sad_id %d", &sad_id))
12265         ;
12266       else if (unformat (i, "spi %d", &spi))
12267         ;
12268       else if (unformat (i, "esp"))
12269         protocol = IPSEC_PROTOCOL_ESP;
12270       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
12271         {
12272           is_tunnel = 1;
12273           is_tunnel_ipv6 = 0;
12274         }
12275       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
12276         {
12277           is_tunnel = 1;
12278           is_tunnel_ipv6 = 0;
12279         }
12280       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12281         {
12282           is_tunnel = 1;
12283           is_tunnel_ipv6 = 1;
12284         }
12285       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12286         {
12287           is_tunnel = 1;
12288           is_tunnel_ipv6 = 1;
12289         }
12290       else
12291         if (unformat
12292             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12293         {
12294           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12295               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12296             {
12297               clib_warning ("unsupported crypto-alg: '%U'",
12298                             format_ipsec_crypto_alg, crypto_alg);
12299               return -99;
12300             }
12301         }
12302       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12303         ;
12304       else
12305         if (unformat
12306             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12307         {
12308           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12309               integ_alg >= IPSEC_INTEG_N_ALG)
12310             {
12311               clib_warning ("unsupported integ-alg: '%U'",
12312                             format_ipsec_integ_alg, integ_alg);
12313               return -99;
12314             }
12315         }
12316       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12317         ;
12318       else
12319         {
12320           clib_warning ("parse error '%U'", format_unformat_error, i);
12321           return -99;
12322         }
12323
12324     }
12325
12326   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
12327
12328   mp->sad_id = ntohl (sad_id);
12329   mp->is_add = is_add;
12330   mp->protocol = protocol;
12331   mp->spi = ntohl (spi);
12332   mp->is_tunnel = is_tunnel;
12333   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12334   mp->crypto_algorithm = crypto_alg;
12335   mp->integrity_algorithm = integ_alg;
12336   mp->crypto_key_length = vec_len (ck);
12337   mp->integrity_key_length = vec_len (ik);
12338
12339   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12340     mp->crypto_key_length = sizeof (mp->crypto_key);
12341
12342   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12343     mp->integrity_key_length = sizeof (mp->integrity_key);
12344
12345   if (ck)
12346     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12347   if (ik)
12348     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12349
12350   if (is_tunnel)
12351     {
12352       if (is_tunnel_ipv6)
12353         {
12354           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12355                        sizeof (ip6_address_t));
12356           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12357                        sizeof (ip6_address_t));
12358         }
12359       else
12360         {
12361           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12362                        sizeof (ip4_address_t));
12363           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12364                        sizeof (ip4_address_t));
12365         }
12366     }
12367
12368   S (mp);
12369   W (ret);
12370   return ret;
12371 }
12372
12373 static int
12374 api_ipsec_sa_set_key (vat_main_t * vam)
12375 {
12376   unformat_input_t *i = vam->input;
12377   vl_api_ipsec_sa_set_key_t *mp;
12378   u32 sa_id;
12379   u8 *ck = 0, *ik = 0;
12380   int ret;
12381
12382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12383     {
12384       if (unformat (i, "sa_id %d", &sa_id))
12385         ;
12386       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12387         ;
12388       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12389         ;
12390       else
12391         {
12392           clib_warning ("parse error '%U'", format_unformat_error, i);
12393           return -99;
12394         }
12395     }
12396
12397   M (IPSEC_SA_SET_KEY, mp);
12398
12399   mp->sa_id = ntohl (sa_id);
12400   mp->crypto_key_length = vec_len (ck);
12401   mp->integrity_key_length = vec_len (ik);
12402
12403   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12404     mp->crypto_key_length = sizeof (mp->crypto_key);
12405
12406   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12407     mp->integrity_key_length = sizeof (mp->integrity_key);
12408
12409   if (ck)
12410     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12411   if (ik)
12412     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12413
12414   S (mp);
12415   W (ret);
12416   return ret;
12417 }
12418
12419 static int
12420 api_ikev2_profile_add_del (vat_main_t * vam)
12421 {
12422   unformat_input_t *i = vam->input;
12423   vl_api_ikev2_profile_add_del_t *mp;
12424   u8 is_add = 1;
12425   u8 *name = 0;
12426   int ret;
12427
12428   const char *valid_chars = "a-zA-Z0-9_";
12429
12430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12431     {
12432       if (unformat (i, "del"))
12433         is_add = 0;
12434       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12435         vec_add1 (name, 0);
12436       else
12437         {
12438           errmsg ("parse error '%U'", format_unformat_error, i);
12439           return -99;
12440         }
12441     }
12442
12443   if (!vec_len (name))
12444     {
12445       errmsg ("profile name must be specified");
12446       return -99;
12447     }
12448
12449   if (vec_len (name) > 64)
12450     {
12451       errmsg ("profile name too long");
12452       return -99;
12453     }
12454
12455   M (IKEV2_PROFILE_ADD_DEL, mp);
12456
12457   clib_memcpy (mp->name, name, vec_len (name));
12458   mp->is_add = is_add;
12459   vec_free (name);
12460
12461   S (mp);
12462   W (ret);
12463   return ret;
12464 }
12465
12466 static int
12467 api_ikev2_profile_set_auth (vat_main_t * vam)
12468 {
12469   unformat_input_t *i = vam->input;
12470   vl_api_ikev2_profile_set_auth_t *mp;
12471   u8 *name = 0;
12472   u8 *data = 0;
12473   u32 auth_method = 0;
12474   u8 is_hex = 0;
12475   int ret;
12476
12477   const char *valid_chars = "a-zA-Z0-9_";
12478
12479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12480     {
12481       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12482         vec_add1 (name, 0);
12483       else if (unformat (i, "auth_method %U",
12484                          unformat_ikev2_auth_method, &auth_method))
12485         ;
12486       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12487         is_hex = 1;
12488       else if (unformat (i, "auth_data %v", &data))
12489         ;
12490       else
12491         {
12492           errmsg ("parse error '%U'", format_unformat_error, i);
12493           return -99;
12494         }
12495     }
12496
12497   if (!vec_len (name))
12498     {
12499       errmsg ("profile name must be specified");
12500       return -99;
12501     }
12502
12503   if (vec_len (name) > 64)
12504     {
12505       errmsg ("profile name too long");
12506       return -99;
12507     }
12508
12509   if (!vec_len (data))
12510     {
12511       errmsg ("auth_data must be specified");
12512       return -99;
12513     }
12514
12515   if (!auth_method)
12516     {
12517       errmsg ("auth_method must be specified");
12518       return -99;
12519     }
12520
12521   M (IKEV2_PROFILE_SET_AUTH, mp);
12522
12523   mp->is_hex = is_hex;
12524   mp->auth_method = (u8) auth_method;
12525   mp->data_len = vec_len (data);
12526   clib_memcpy (mp->name, name, vec_len (name));
12527   clib_memcpy (mp->data, data, vec_len (data));
12528   vec_free (name);
12529   vec_free (data);
12530
12531   S (mp);
12532   W (ret);
12533   return ret;
12534 }
12535
12536 static int
12537 api_ikev2_profile_set_id (vat_main_t * vam)
12538 {
12539   unformat_input_t *i = vam->input;
12540   vl_api_ikev2_profile_set_id_t *mp;
12541   u8 *name = 0;
12542   u8 *data = 0;
12543   u8 is_local = 0;
12544   u32 id_type = 0;
12545   ip4_address_t ip4;
12546   int ret;
12547
12548   const char *valid_chars = "a-zA-Z0-9_";
12549
12550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12551     {
12552       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12553         vec_add1 (name, 0);
12554       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12555         ;
12556       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12557         {
12558           data = vec_new (u8, 4);
12559           clib_memcpy (data, ip4.as_u8, 4);
12560         }
12561       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12562         ;
12563       else if (unformat (i, "id_data %v", &data))
12564         ;
12565       else if (unformat (i, "local"))
12566         is_local = 1;
12567       else if (unformat (i, "remote"))
12568         is_local = 0;
12569       else
12570         {
12571           errmsg ("parse error '%U'", format_unformat_error, i);
12572           return -99;
12573         }
12574     }
12575
12576   if (!vec_len (name))
12577     {
12578       errmsg ("profile name must be specified");
12579       return -99;
12580     }
12581
12582   if (vec_len (name) > 64)
12583     {
12584       errmsg ("profile name too long");
12585       return -99;
12586     }
12587
12588   if (!vec_len (data))
12589     {
12590       errmsg ("id_data must be specified");
12591       return -99;
12592     }
12593
12594   if (!id_type)
12595     {
12596       errmsg ("id_type must be specified");
12597       return -99;
12598     }
12599
12600   M (IKEV2_PROFILE_SET_ID, mp);
12601
12602   mp->is_local = is_local;
12603   mp->id_type = (u8) id_type;
12604   mp->data_len = vec_len (data);
12605   clib_memcpy (mp->name, name, vec_len (name));
12606   clib_memcpy (mp->data, data, vec_len (data));
12607   vec_free (name);
12608   vec_free (data);
12609
12610   S (mp);
12611   W (ret);
12612   return ret;
12613 }
12614
12615 static int
12616 api_ikev2_profile_set_ts (vat_main_t * vam)
12617 {
12618   unformat_input_t *i = vam->input;
12619   vl_api_ikev2_profile_set_ts_t *mp;
12620   u8 *name = 0;
12621   u8 is_local = 0;
12622   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12623   ip4_address_t start_addr, end_addr;
12624
12625   const char *valid_chars = "a-zA-Z0-9_";
12626   int ret;
12627
12628   start_addr.as_u32 = 0;
12629   end_addr.as_u32 = (u32) ~ 0;
12630
12631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12632     {
12633       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12634         vec_add1 (name, 0);
12635       else if (unformat (i, "protocol %d", &proto))
12636         ;
12637       else if (unformat (i, "start_port %d", &start_port))
12638         ;
12639       else if (unformat (i, "end_port %d", &end_port))
12640         ;
12641       else
12642         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12643         ;
12644       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12645         ;
12646       else if (unformat (i, "local"))
12647         is_local = 1;
12648       else if (unformat (i, "remote"))
12649         is_local = 0;
12650       else
12651         {
12652           errmsg ("parse error '%U'", format_unformat_error, i);
12653           return -99;
12654         }
12655     }
12656
12657   if (!vec_len (name))
12658     {
12659       errmsg ("profile name must be specified");
12660       return -99;
12661     }
12662
12663   if (vec_len (name) > 64)
12664     {
12665       errmsg ("profile name too long");
12666       return -99;
12667     }
12668
12669   M (IKEV2_PROFILE_SET_TS, mp);
12670
12671   mp->is_local = is_local;
12672   mp->proto = (u8) proto;
12673   mp->start_port = (u16) start_port;
12674   mp->end_port = (u16) end_port;
12675   mp->start_addr = start_addr.as_u32;
12676   mp->end_addr = end_addr.as_u32;
12677   clib_memcpy (mp->name, name, vec_len (name));
12678   vec_free (name);
12679
12680   S (mp);
12681   W (ret);
12682   return ret;
12683 }
12684
12685 static int
12686 api_ikev2_set_local_key (vat_main_t * vam)
12687 {
12688   unformat_input_t *i = vam->input;
12689   vl_api_ikev2_set_local_key_t *mp;
12690   u8 *file = 0;
12691   int ret;
12692
12693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12694     {
12695       if (unformat (i, "file %v", &file))
12696         vec_add1 (file, 0);
12697       else
12698         {
12699           errmsg ("parse error '%U'", format_unformat_error, i);
12700           return -99;
12701         }
12702     }
12703
12704   if (!vec_len (file))
12705     {
12706       errmsg ("RSA key file must be specified");
12707       return -99;
12708     }
12709
12710   if (vec_len (file) > 256)
12711     {
12712       errmsg ("file name too long");
12713       return -99;
12714     }
12715
12716   M (IKEV2_SET_LOCAL_KEY, mp);
12717
12718   clib_memcpy (mp->key_file, file, vec_len (file));
12719   vec_free (file);
12720
12721   S (mp);
12722   W (ret);
12723   return ret;
12724 }
12725
12726 static int
12727 api_ikev2_set_responder (vat_main_t * vam)
12728 {
12729   unformat_input_t *i = vam->input;
12730   vl_api_ikev2_set_responder_t *mp;
12731   int ret;
12732   u8 *name = 0;
12733   u32 sw_if_index = ~0;
12734   ip4_address_t address;
12735
12736   const char *valid_chars = "a-zA-Z0-9_";
12737
12738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12739     {
12740       if (unformat
12741           (i, "%U interface %d address %U", unformat_token, valid_chars,
12742            &name, &sw_if_index, unformat_ip4_address, &address))
12743         vec_add1 (name, 0);
12744       else
12745         {
12746           errmsg ("parse error '%U'", format_unformat_error, i);
12747           return -99;
12748         }
12749     }
12750
12751   if (!vec_len (name))
12752     {
12753       errmsg ("profile name must be specified");
12754       return -99;
12755     }
12756
12757   if (vec_len (name) > 64)
12758     {
12759       errmsg ("profile name too long");
12760       return -99;
12761     }
12762
12763   M (IKEV2_SET_RESPONDER, mp);
12764
12765   clib_memcpy (mp->name, name, vec_len (name));
12766   vec_free (name);
12767
12768   mp->sw_if_index = sw_if_index;
12769   clib_memcpy (mp->address, &address, sizeof (address));
12770
12771   S (mp);
12772   W (ret);
12773   return ret;
12774 }
12775
12776 static int
12777 api_ikev2_set_ike_transforms (vat_main_t * vam)
12778 {
12779   unformat_input_t *i = vam->input;
12780   vl_api_ikev2_set_ike_transforms_t *mp;
12781   int ret;
12782   u8 *name = 0;
12783   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12784
12785   const char *valid_chars = "a-zA-Z0-9_";
12786
12787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12788     {
12789       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12790                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12791         vec_add1 (name, 0);
12792       else
12793         {
12794           errmsg ("parse error '%U'", format_unformat_error, i);
12795           return -99;
12796         }
12797     }
12798
12799   if (!vec_len (name))
12800     {
12801       errmsg ("profile name must be specified");
12802       return -99;
12803     }
12804
12805   if (vec_len (name) > 64)
12806     {
12807       errmsg ("profile name too long");
12808       return -99;
12809     }
12810
12811   M (IKEV2_SET_IKE_TRANSFORMS, mp);
12812
12813   clib_memcpy (mp->name, name, vec_len (name));
12814   vec_free (name);
12815   mp->crypto_alg = crypto_alg;
12816   mp->crypto_key_size = crypto_key_size;
12817   mp->integ_alg = integ_alg;
12818   mp->dh_group = dh_group;
12819
12820   S (mp);
12821   W (ret);
12822   return ret;
12823 }
12824
12825
12826 static int
12827 api_ikev2_set_esp_transforms (vat_main_t * vam)
12828 {
12829   unformat_input_t *i = vam->input;
12830   vl_api_ikev2_set_esp_transforms_t *mp;
12831   int ret;
12832   u8 *name = 0;
12833   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
12834
12835   const char *valid_chars = "a-zA-Z0-9_";
12836
12837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12838     {
12839       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
12840                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
12841         vec_add1 (name, 0);
12842       else
12843         {
12844           errmsg ("parse error '%U'", format_unformat_error, i);
12845           return -99;
12846         }
12847     }
12848
12849   if (!vec_len (name))
12850     {
12851       errmsg ("profile name must be specified");
12852       return -99;
12853     }
12854
12855   if (vec_len (name) > 64)
12856     {
12857       errmsg ("profile name too long");
12858       return -99;
12859     }
12860
12861   M (IKEV2_SET_ESP_TRANSFORMS, mp);
12862
12863   clib_memcpy (mp->name, name, vec_len (name));
12864   vec_free (name);
12865   mp->crypto_alg = crypto_alg;
12866   mp->crypto_key_size = crypto_key_size;
12867   mp->integ_alg = integ_alg;
12868   mp->dh_group = dh_group;
12869
12870   S (mp);
12871   W (ret);
12872   return ret;
12873 }
12874
12875 static int
12876 api_ikev2_set_sa_lifetime (vat_main_t * vam)
12877 {
12878   unformat_input_t *i = vam->input;
12879   vl_api_ikev2_set_sa_lifetime_t *mp;
12880   int ret;
12881   u8 *name = 0;
12882   u64 lifetime, lifetime_maxdata;
12883   u32 lifetime_jitter, handover;
12884
12885   const char *valid_chars = "a-zA-Z0-9_";
12886
12887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12888     {
12889       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
12890                     &lifetime, &lifetime_jitter, &handover,
12891                     &lifetime_maxdata))
12892         vec_add1 (name, 0);
12893       else
12894         {
12895           errmsg ("parse error '%U'", format_unformat_error, i);
12896           return -99;
12897         }
12898     }
12899
12900   if (!vec_len (name))
12901     {
12902       errmsg ("profile name must be specified");
12903       return -99;
12904     }
12905
12906   if (vec_len (name) > 64)
12907     {
12908       errmsg ("profile name too long");
12909       return -99;
12910     }
12911
12912   M (IKEV2_SET_SA_LIFETIME, mp);
12913
12914   clib_memcpy (mp->name, name, vec_len (name));
12915   vec_free (name);
12916   mp->lifetime = lifetime;
12917   mp->lifetime_jitter = lifetime_jitter;
12918   mp->handover = handover;
12919   mp->lifetime_maxdata = lifetime_maxdata;
12920
12921   S (mp);
12922   W (ret);
12923   return ret;
12924 }
12925
12926 static int
12927 api_ikev2_initiate_sa_init (vat_main_t * vam)
12928 {
12929   unformat_input_t *i = vam->input;
12930   vl_api_ikev2_initiate_sa_init_t *mp;
12931   int ret;
12932   u8 *name = 0;
12933
12934   const char *valid_chars = "a-zA-Z0-9_";
12935
12936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12937     {
12938       if (unformat (i, "%U", unformat_token, valid_chars, &name))
12939         vec_add1 (name, 0);
12940       else
12941         {
12942           errmsg ("parse error '%U'", format_unformat_error, i);
12943           return -99;
12944         }
12945     }
12946
12947   if (!vec_len (name))
12948     {
12949       errmsg ("profile name must be specified");
12950       return -99;
12951     }
12952
12953   if (vec_len (name) > 64)
12954     {
12955       errmsg ("profile name too long");
12956       return -99;
12957     }
12958
12959   M (IKEV2_INITIATE_SA_INIT, mp);
12960
12961   clib_memcpy (mp->name, name, vec_len (name));
12962   vec_free (name);
12963
12964   S (mp);
12965   W (ret);
12966   return ret;
12967 }
12968
12969 static int
12970 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
12971 {
12972   unformat_input_t *i = vam->input;
12973   vl_api_ikev2_initiate_del_ike_sa_t *mp;
12974   int ret;
12975   u64 ispi;
12976
12977
12978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12979     {
12980       if (unformat (i, "%lx", &ispi))
12981         ;
12982       else
12983         {
12984           errmsg ("parse error '%U'", format_unformat_error, i);
12985           return -99;
12986         }
12987     }
12988
12989   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
12990
12991   mp->ispi = ispi;
12992
12993   S (mp);
12994   W (ret);
12995   return ret;
12996 }
12997
12998 static int
12999 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
13000 {
13001   unformat_input_t *i = vam->input;
13002   vl_api_ikev2_initiate_del_child_sa_t *mp;
13003   int ret;
13004   u32 ispi;
13005
13006
13007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13008     {
13009       if (unformat (i, "%x", &ispi))
13010         ;
13011       else
13012         {
13013           errmsg ("parse error '%U'", format_unformat_error, i);
13014           return -99;
13015         }
13016     }
13017
13018   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
13019
13020   mp->ispi = ispi;
13021
13022   S (mp);
13023   W (ret);
13024   return ret;
13025 }
13026
13027 static int
13028 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
13029 {
13030   unformat_input_t *i = vam->input;
13031   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
13032   int ret;
13033   u32 ispi;
13034
13035
13036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13037     {
13038       if (unformat (i, "%x", &ispi))
13039         ;
13040       else
13041         {
13042           errmsg ("parse error '%U'", format_unformat_error, i);
13043           return -99;
13044         }
13045     }
13046
13047   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
13048
13049   mp->ispi = ispi;
13050
13051   S (mp);
13052   W (ret);
13053   return ret;
13054 }
13055
13056 /*
13057  * MAP
13058  */
13059 static int
13060 api_map_add_domain (vat_main_t * vam)
13061 {
13062   unformat_input_t *i = vam->input;
13063   vl_api_map_add_domain_t *mp;
13064
13065   ip4_address_t ip4_prefix;
13066   ip6_address_t ip6_prefix;
13067   ip6_address_t ip6_src;
13068   u32 num_m_args = 0;
13069   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
13070     0, psid_length = 0;
13071   u8 is_translation = 0;
13072   u32 mtu = 0;
13073   u32 ip6_src_len = 128;
13074   int ret;
13075
13076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13077     {
13078       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
13079                     &ip4_prefix, &ip4_prefix_len))
13080         num_m_args++;
13081       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
13082                          &ip6_prefix, &ip6_prefix_len))
13083         num_m_args++;
13084       else
13085         if (unformat
13086             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
13087              &ip6_src_len))
13088         num_m_args++;
13089       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
13090         num_m_args++;
13091       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
13092         num_m_args++;
13093       else if (unformat (i, "psid-offset %d", &psid_offset))
13094         num_m_args++;
13095       else if (unformat (i, "psid-len %d", &psid_length))
13096         num_m_args++;
13097       else if (unformat (i, "mtu %d", &mtu))
13098         num_m_args++;
13099       else if (unformat (i, "map-t"))
13100         is_translation = 1;
13101       else
13102         {
13103           clib_warning ("parse error '%U'", format_unformat_error, i);
13104           return -99;
13105         }
13106     }
13107
13108   if (num_m_args < 3)
13109     {
13110       errmsg ("mandatory argument(s) missing");
13111       return -99;
13112     }
13113
13114   /* Construct the API message */
13115   M (MAP_ADD_DOMAIN, mp);
13116
13117   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
13118   mp->ip4_prefix_len = ip4_prefix_len;
13119
13120   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
13121   mp->ip6_prefix_len = ip6_prefix_len;
13122
13123   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
13124   mp->ip6_src_prefix_len = ip6_src_len;
13125
13126   mp->ea_bits_len = ea_bits_len;
13127   mp->psid_offset = psid_offset;
13128   mp->psid_length = psid_length;
13129   mp->is_translation = is_translation;
13130   mp->mtu = htons (mtu);
13131
13132   /* send it... */
13133   S (mp);
13134
13135   /* Wait for a reply, return good/bad news  */
13136   W (ret);
13137   return ret;
13138 }
13139
13140 static int
13141 api_map_del_domain (vat_main_t * vam)
13142 {
13143   unformat_input_t *i = vam->input;
13144   vl_api_map_del_domain_t *mp;
13145
13146   u32 num_m_args = 0;
13147   u32 index;
13148   int ret;
13149
13150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13151     {
13152       if (unformat (i, "index %d", &index))
13153         num_m_args++;
13154       else
13155         {
13156           clib_warning ("parse error '%U'", format_unformat_error, i);
13157           return -99;
13158         }
13159     }
13160
13161   if (num_m_args != 1)
13162     {
13163       errmsg ("mandatory argument(s) missing");
13164       return -99;
13165     }
13166
13167   /* Construct the API message */
13168   M (MAP_DEL_DOMAIN, mp);
13169
13170   mp->index = ntohl (index);
13171
13172   /* send it... */
13173   S (mp);
13174
13175   /* Wait for a reply, return good/bad news  */
13176   W (ret);
13177   return ret;
13178 }
13179
13180 static int
13181 api_map_add_del_rule (vat_main_t * vam)
13182 {
13183   unformat_input_t *i = vam->input;
13184   vl_api_map_add_del_rule_t *mp;
13185   u8 is_add = 1;
13186   ip6_address_t ip6_dst;
13187   u32 num_m_args = 0, index, psid = 0;
13188   int ret;
13189
13190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13191     {
13192       if (unformat (i, "index %d", &index))
13193         num_m_args++;
13194       else if (unformat (i, "psid %d", &psid))
13195         num_m_args++;
13196       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
13197         num_m_args++;
13198       else if (unformat (i, "del"))
13199         {
13200           is_add = 0;
13201         }
13202       else
13203         {
13204           clib_warning ("parse error '%U'", format_unformat_error, i);
13205           return -99;
13206         }
13207     }
13208
13209   /* Construct the API message */
13210   M (MAP_ADD_DEL_RULE, mp);
13211
13212   mp->index = ntohl (index);
13213   mp->is_add = is_add;
13214   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
13215   mp->psid = ntohs (psid);
13216
13217   /* send it... */
13218   S (mp);
13219
13220   /* Wait for a reply, return good/bad news  */
13221   W (ret);
13222   return ret;
13223 }
13224
13225 static int
13226 api_map_domain_dump (vat_main_t * vam)
13227 {
13228   vl_api_map_domain_dump_t *mp;
13229   vl_api_control_ping_t *mp_ping;
13230   int ret;
13231
13232   /* Construct the API message */
13233   M (MAP_DOMAIN_DUMP, mp);
13234
13235   /* send it... */
13236   S (mp);
13237
13238   /* Use a control ping for synchronization */
13239   M (CONTROL_PING, mp_ping);
13240   S (mp_ping);
13241
13242   W (ret);
13243   return ret;
13244 }
13245
13246 static int
13247 api_map_rule_dump (vat_main_t * vam)
13248 {
13249   unformat_input_t *i = vam->input;
13250   vl_api_map_rule_dump_t *mp;
13251   vl_api_control_ping_t *mp_ping;
13252   u32 domain_index = ~0;
13253   int ret;
13254
13255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13256     {
13257       if (unformat (i, "index %u", &domain_index))
13258         ;
13259       else
13260         break;
13261     }
13262
13263   if (domain_index == ~0)
13264     {
13265       clib_warning ("parse error: domain index expected");
13266       return -99;
13267     }
13268
13269   /* Construct the API message */
13270   M (MAP_RULE_DUMP, mp);
13271
13272   mp->domain_index = htonl (domain_index);
13273
13274   /* send it... */
13275   S (mp);
13276
13277   /* Use a control ping for synchronization */
13278   M (CONTROL_PING, mp_ping);
13279   S (mp_ping);
13280
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static void vl_api_map_add_domain_reply_t_handler
13286   (vl_api_map_add_domain_reply_t * mp)
13287 {
13288   vat_main_t *vam = &vat_main;
13289   i32 retval = ntohl (mp->retval);
13290
13291   if (vam->async_mode)
13292     {
13293       vam->async_errors += (retval < 0);
13294     }
13295   else
13296     {
13297       vam->retval = retval;
13298       vam->result_ready = 1;
13299     }
13300 }
13301
13302 static void vl_api_map_add_domain_reply_t_handler_json
13303   (vl_api_map_add_domain_reply_t * mp)
13304 {
13305   vat_main_t *vam = &vat_main;
13306   vat_json_node_t node;
13307
13308   vat_json_init_object (&node);
13309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13310   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
13311
13312   vat_json_print (vam->ofp, &node);
13313   vat_json_free (&node);
13314
13315   vam->retval = ntohl (mp->retval);
13316   vam->result_ready = 1;
13317 }
13318
13319 static int
13320 api_get_first_msg_id (vat_main_t * vam)
13321 {
13322   vl_api_get_first_msg_id_t *mp;
13323   unformat_input_t *i = vam->input;
13324   u8 *name;
13325   u8 name_set = 0;
13326   int ret;
13327
13328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13329     {
13330       if (unformat (i, "client %s", &name))
13331         name_set = 1;
13332       else
13333         break;
13334     }
13335
13336   if (name_set == 0)
13337     {
13338       errmsg ("missing client name");
13339       return -99;
13340     }
13341   vec_add1 (name, 0);
13342
13343   if (vec_len (name) > 63)
13344     {
13345       errmsg ("client name too long");
13346       return -99;
13347     }
13348
13349   M (GET_FIRST_MSG_ID, mp);
13350   clib_memcpy (mp->name, name, vec_len (name));
13351   S (mp);
13352   W (ret);
13353   return ret;
13354 }
13355
13356 static int
13357 api_cop_interface_enable_disable (vat_main_t * vam)
13358 {
13359   unformat_input_t *line_input = vam->input;
13360   vl_api_cop_interface_enable_disable_t *mp;
13361   u32 sw_if_index = ~0;
13362   u8 enable_disable = 1;
13363   int ret;
13364
13365   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13366     {
13367       if (unformat (line_input, "disable"))
13368         enable_disable = 0;
13369       if (unformat (line_input, "enable"))
13370         enable_disable = 1;
13371       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13372                          vam, &sw_if_index))
13373         ;
13374       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13375         ;
13376       else
13377         break;
13378     }
13379
13380   if (sw_if_index == ~0)
13381     {
13382       errmsg ("missing interface name or sw_if_index");
13383       return -99;
13384     }
13385
13386   /* Construct the API message */
13387   M (COP_INTERFACE_ENABLE_DISABLE, mp);
13388   mp->sw_if_index = ntohl (sw_if_index);
13389   mp->enable_disable = enable_disable;
13390
13391   /* send it... */
13392   S (mp);
13393   /* Wait for the reply */
13394   W (ret);
13395   return ret;
13396 }
13397
13398 static int
13399 api_cop_whitelist_enable_disable (vat_main_t * vam)
13400 {
13401   unformat_input_t *line_input = vam->input;
13402   vl_api_cop_whitelist_enable_disable_t *mp;
13403   u32 sw_if_index = ~0;
13404   u8 ip4 = 0, ip6 = 0, default_cop = 0;
13405   u32 fib_id = 0;
13406   int ret;
13407
13408   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13409     {
13410       if (unformat (line_input, "ip4"))
13411         ip4 = 1;
13412       else if (unformat (line_input, "ip6"))
13413         ip6 = 1;
13414       else if (unformat (line_input, "default"))
13415         default_cop = 1;
13416       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
13417                          vam, &sw_if_index))
13418         ;
13419       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13420         ;
13421       else if (unformat (line_input, "fib-id %d", &fib_id))
13422         ;
13423       else
13424         break;
13425     }
13426
13427   if (sw_if_index == ~0)
13428     {
13429       errmsg ("missing interface name or sw_if_index");
13430       return -99;
13431     }
13432
13433   /* Construct the API message */
13434   M (COP_WHITELIST_ENABLE_DISABLE, mp);
13435   mp->sw_if_index = ntohl (sw_if_index);
13436   mp->fib_id = ntohl (fib_id);
13437   mp->ip4 = ip4;
13438   mp->ip6 = ip6;
13439   mp->default_cop = default_cop;
13440
13441   /* send it... */
13442   S (mp);
13443   /* Wait for the reply */
13444   W (ret);
13445   return ret;
13446 }
13447
13448 static int
13449 api_get_node_graph (vat_main_t * vam)
13450 {
13451   vl_api_get_node_graph_t *mp;
13452   int ret;
13453
13454   M (GET_NODE_GRAPH, mp);
13455
13456   /* send it... */
13457   S (mp);
13458   /* Wait for the reply */
13459   W (ret);
13460   return ret;
13461 }
13462
13463 /* *INDENT-OFF* */
13464 /** Used for parsing LISP eids */
13465 typedef CLIB_PACKED(struct{
13466   u8 addr[16];   /**< eid address */
13467   u32 len;       /**< prefix length if IP */
13468   u8 type;      /**< type of eid */
13469 }) lisp_eid_vat_t;
13470 /* *INDENT-ON* */
13471
13472 static uword
13473 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
13474 {
13475   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
13476
13477   memset (a, 0, sizeof (a[0]));
13478
13479   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
13480     {
13481       a->type = 0;              /* ipv4 type */
13482     }
13483   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
13484     {
13485       a->type = 1;              /* ipv6 type */
13486     }
13487   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
13488     {
13489       a->type = 2;              /* mac type */
13490     }
13491   else
13492     {
13493       return 0;
13494     }
13495
13496   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
13497     {
13498       return 0;
13499     }
13500
13501   return 1;
13502 }
13503
13504 static int
13505 lisp_eid_size_vat (u8 type)
13506 {
13507   switch (type)
13508     {
13509     case 0:
13510       return 4;
13511     case 1:
13512       return 16;
13513     case 2:
13514       return 6;
13515     }
13516   return 0;
13517 }
13518
13519 static void
13520 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
13521 {
13522   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
13523 }
13524
13525 static int
13526 api_one_add_del_locator_set (vat_main_t * vam)
13527 {
13528   unformat_input_t *input = vam->input;
13529   vl_api_one_add_del_locator_set_t *mp;
13530   u8 is_add = 1;
13531   u8 *locator_set_name = NULL;
13532   u8 locator_set_name_set = 0;
13533   vl_api_local_locator_t locator, *locators = 0;
13534   u32 sw_if_index, priority, weight;
13535   u32 data_len = 0;
13536
13537   int ret;
13538   /* Parse args required to build the message */
13539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13540     {
13541       if (unformat (input, "del"))
13542         {
13543           is_add = 0;
13544         }
13545       else if (unformat (input, "locator-set %s", &locator_set_name))
13546         {
13547           locator_set_name_set = 1;
13548         }
13549       else if (unformat (input, "sw_if_index %u p %u w %u",
13550                          &sw_if_index, &priority, &weight))
13551         {
13552           locator.sw_if_index = htonl (sw_if_index);
13553           locator.priority = priority;
13554           locator.weight = weight;
13555           vec_add1 (locators, locator);
13556         }
13557       else
13558         if (unformat
13559             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
13560              &sw_if_index, &priority, &weight))
13561         {
13562           locator.sw_if_index = htonl (sw_if_index);
13563           locator.priority = priority;
13564           locator.weight = weight;
13565           vec_add1 (locators, locator);
13566         }
13567       else
13568         break;
13569     }
13570
13571   if (locator_set_name_set == 0)
13572     {
13573       errmsg ("missing locator-set name");
13574       vec_free (locators);
13575       return -99;
13576     }
13577
13578   if (vec_len (locator_set_name) > 64)
13579     {
13580       errmsg ("locator-set name too long");
13581       vec_free (locator_set_name);
13582       vec_free (locators);
13583       return -99;
13584     }
13585   vec_add1 (locator_set_name, 0);
13586
13587   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
13588
13589   /* Construct the API message */
13590   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
13591
13592   mp->is_add = is_add;
13593   clib_memcpy (mp->locator_set_name, locator_set_name,
13594                vec_len (locator_set_name));
13595   vec_free (locator_set_name);
13596
13597   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13598   if (locators)
13599     clib_memcpy (mp->locators, locators, data_len);
13600   vec_free (locators);
13601
13602   /* send it... */
13603   S (mp);
13604
13605   /* Wait for a reply... */
13606   W (ret);
13607   return ret;
13608 }
13609
13610 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
13611
13612 static int
13613 api_one_add_del_locator (vat_main_t * vam)
13614 {
13615   unformat_input_t *input = vam->input;
13616   vl_api_one_add_del_locator_t *mp;
13617   u32 tmp_if_index = ~0;
13618   u32 sw_if_index = ~0;
13619   u8 sw_if_index_set = 0;
13620   u8 sw_if_index_if_name_set = 0;
13621   u32 priority = ~0;
13622   u8 priority_set = 0;
13623   u32 weight = ~0;
13624   u8 weight_set = 0;
13625   u8 is_add = 1;
13626   u8 *locator_set_name = NULL;
13627   u8 locator_set_name_set = 0;
13628   int ret;
13629
13630   /* Parse args required to build the message */
13631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13632     {
13633       if (unformat (input, "del"))
13634         {
13635           is_add = 0;
13636         }
13637       else if (unformat (input, "locator-set %s", &locator_set_name))
13638         {
13639           locator_set_name_set = 1;
13640         }
13641       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13642                          &tmp_if_index))
13643         {
13644           sw_if_index_if_name_set = 1;
13645           sw_if_index = tmp_if_index;
13646         }
13647       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13648         {
13649           sw_if_index_set = 1;
13650           sw_if_index = tmp_if_index;
13651         }
13652       else if (unformat (input, "p %d", &priority))
13653         {
13654           priority_set = 1;
13655         }
13656       else if (unformat (input, "w %d", &weight))
13657         {
13658           weight_set = 1;
13659         }
13660       else
13661         break;
13662     }
13663
13664   if (locator_set_name_set == 0)
13665     {
13666       errmsg ("missing locator-set name");
13667       return -99;
13668     }
13669
13670   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13671     {
13672       errmsg ("missing sw_if_index");
13673       vec_free (locator_set_name);
13674       return -99;
13675     }
13676
13677   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13678     {
13679       errmsg ("cannot use both params interface name and sw_if_index");
13680       vec_free (locator_set_name);
13681       return -99;
13682     }
13683
13684   if (priority_set == 0)
13685     {
13686       errmsg ("missing locator-set priority");
13687       vec_free (locator_set_name);
13688       return -99;
13689     }
13690
13691   if (weight_set == 0)
13692     {
13693       errmsg ("missing locator-set weight");
13694       vec_free (locator_set_name);
13695       return -99;
13696     }
13697
13698   if (vec_len (locator_set_name) > 64)
13699     {
13700       errmsg ("locator-set name too long");
13701       vec_free (locator_set_name);
13702       return -99;
13703     }
13704   vec_add1 (locator_set_name, 0);
13705
13706   /* Construct the API message */
13707   M (ONE_ADD_DEL_LOCATOR, mp);
13708
13709   mp->is_add = is_add;
13710   mp->sw_if_index = ntohl (sw_if_index);
13711   mp->priority = priority;
13712   mp->weight = weight;
13713   clib_memcpy (mp->locator_set_name, locator_set_name,
13714                vec_len (locator_set_name));
13715   vec_free (locator_set_name);
13716
13717   /* send it... */
13718   S (mp);
13719
13720   /* Wait for a reply... */
13721   W (ret);
13722   return ret;
13723 }
13724
13725 #define api_lisp_add_del_locator api_one_add_del_locator
13726
13727 uword
13728 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13729 {
13730   u32 *key_id = va_arg (*args, u32 *);
13731   u8 *s = 0;
13732
13733   if (unformat (input, "%s", &s))
13734     {
13735       if (!strcmp ((char *) s, "sha1"))
13736         key_id[0] = HMAC_SHA_1_96;
13737       else if (!strcmp ((char *) s, "sha256"))
13738         key_id[0] = HMAC_SHA_256_128;
13739       else
13740         {
13741           clib_warning ("invalid key_id: '%s'", s);
13742           key_id[0] = HMAC_NO_KEY;
13743         }
13744     }
13745   else
13746     return 0;
13747
13748   vec_free (s);
13749   return 1;
13750 }
13751
13752 static int
13753 api_one_add_del_local_eid (vat_main_t * vam)
13754 {
13755   unformat_input_t *input = vam->input;
13756   vl_api_one_add_del_local_eid_t *mp;
13757   u8 is_add = 1;
13758   u8 eid_set = 0;
13759   lisp_eid_vat_t _eid, *eid = &_eid;
13760   u8 *locator_set_name = 0;
13761   u8 locator_set_name_set = 0;
13762   u32 vni = 0;
13763   u16 key_id = 0;
13764   u8 *key = 0;
13765   int ret;
13766
13767   /* Parse args required to build the message */
13768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13769     {
13770       if (unformat (input, "del"))
13771         {
13772           is_add = 0;
13773         }
13774       else if (unformat (input, "vni %d", &vni))
13775         {
13776           ;
13777         }
13778       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13779         {
13780           eid_set = 1;
13781         }
13782       else if (unformat (input, "locator-set %s", &locator_set_name))
13783         {
13784           locator_set_name_set = 1;
13785         }
13786       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13787         ;
13788       else if (unformat (input, "secret-key %_%v%_", &key))
13789         ;
13790       else
13791         break;
13792     }
13793
13794   if (locator_set_name_set == 0)
13795     {
13796       errmsg ("missing locator-set name");
13797       return -99;
13798     }
13799
13800   if (0 == eid_set)
13801     {
13802       errmsg ("EID address not set!");
13803       vec_free (locator_set_name);
13804       return -99;
13805     }
13806
13807   if (key && (0 == key_id))
13808     {
13809       errmsg ("invalid key_id!");
13810       return -99;
13811     }
13812
13813   if (vec_len (key) > 64)
13814     {
13815       errmsg ("key too long");
13816       vec_free (key);
13817       return -99;
13818     }
13819
13820   if (vec_len (locator_set_name) > 64)
13821     {
13822       errmsg ("locator-set name too long");
13823       vec_free (locator_set_name);
13824       return -99;
13825     }
13826   vec_add1 (locator_set_name, 0);
13827
13828   /* Construct the API message */
13829   M (ONE_ADD_DEL_LOCAL_EID, mp);
13830
13831   mp->is_add = is_add;
13832   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13833   mp->eid_type = eid->type;
13834   mp->prefix_len = eid->len;
13835   mp->vni = clib_host_to_net_u32 (vni);
13836   mp->key_id = clib_host_to_net_u16 (key_id);
13837   clib_memcpy (mp->locator_set_name, locator_set_name,
13838                vec_len (locator_set_name));
13839   clib_memcpy (mp->key, key, vec_len (key));
13840
13841   vec_free (locator_set_name);
13842   vec_free (key);
13843
13844   /* send it... */
13845   S (mp);
13846
13847   /* Wait for a reply... */
13848   W (ret);
13849   return ret;
13850 }
13851
13852 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
13853
13854 static int
13855 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13856 {
13857   u32 dp_table = 0, vni = 0;;
13858   unformat_input_t *input = vam->input;
13859   vl_api_gpe_add_del_fwd_entry_t *mp;
13860   u8 is_add = 1;
13861   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13862   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13863   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13864   u32 action = ~0, w;
13865   ip4_address_t rmt_rloc4, lcl_rloc4;
13866   ip6_address_t rmt_rloc6, lcl_rloc6;
13867   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13868   int ret;
13869
13870   memset (&rloc, 0, sizeof (rloc));
13871
13872   /* Parse args required to build the message */
13873   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13874     {
13875       if (unformat (input, "del"))
13876         is_add = 0;
13877       else if (unformat (input, "add"))
13878         is_add = 1;
13879       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13880         {
13881           rmt_eid_set = 1;
13882         }
13883       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13884         {
13885           lcl_eid_set = 1;
13886         }
13887       else if (unformat (input, "vrf %d", &dp_table))
13888         ;
13889       else if (unformat (input, "bd %d", &dp_table))
13890         ;
13891       else if (unformat (input, "vni %d", &vni))
13892         ;
13893       else if (unformat (input, "w %d", &w))
13894         {
13895           if (!curr_rloc)
13896             {
13897               errmsg ("No RLOC configured for setting priority/weight!");
13898               return -99;
13899             }
13900           curr_rloc->weight = w;
13901         }
13902       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13903                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13904         {
13905           rloc.is_ip4 = 1;
13906
13907           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13908           rloc.weight = 0;
13909           vec_add1 (lcl_locs, rloc);
13910
13911           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13912           vec_add1 (rmt_locs, rloc);
13913           /* weight saved in rmt loc */
13914           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13915         }
13916       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13917                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13918         {
13919           rloc.is_ip4 = 0;
13920           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13921           rloc.weight = 0;
13922           vec_add1 (lcl_locs, rloc);
13923
13924           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13925           vec_add1 (rmt_locs, rloc);
13926           /* weight saved in rmt loc */
13927           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13928         }
13929       else if (unformat (input, "action %d", &action))
13930         {
13931           ;
13932         }
13933       else
13934         {
13935           clib_warning ("parse error '%U'", format_unformat_error, input);
13936           return -99;
13937         }
13938     }
13939
13940   if (!rmt_eid_set)
13941     {
13942       errmsg ("remote eid addresses not set");
13943       return -99;
13944     }
13945
13946   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13947     {
13948       errmsg ("eid types don't match");
13949       return -99;
13950     }
13951
13952   if (0 == rmt_locs && (u32) ~ 0 == action)
13953     {
13954       errmsg ("action not set for negative mapping");
13955       return -99;
13956     }
13957
13958   /* Construct the API message */
13959   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
13960       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
13961
13962   mp->is_add = is_add;
13963   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13964   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13965   mp->eid_type = rmt_eid->type;
13966   mp->dp_table = clib_host_to_net_u32 (dp_table);
13967   mp->vni = clib_host_to_net_u32 (vni);
13968   mp->rmt_len = rmt_eid->len;
13969   mp->lcl_len = lcl_eid->len;
13970   mp->action = action;
13971
13972   if (0 != rmt_locs && 0 != lcl_locs)
13973     {
13974       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13975       clib_memcpy (mp->locs, lcl_locs,
13976                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
13977
13978       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
13979       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13980                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
13981     }
13982   vec_free (lcl_locs);
13983   vec_free (rmt_locs);
13984
13985   /* send it... */
13986   S (mp);
13987
13988   /* Wait for a reply... */
13989   W (ret);
13990   return ret;
13991 }
13992
13993 static int
13994 api_one_add_del_map_server (vat_main_t * vam)
13995 {
13996   unformat_input_t *input = vam->input;
13997   vl_api_one_add_del_map_server_t *mp;
13998   u8 is_add = 1;
13999   u8 ipv4_set = 0;
14000   u8 ipv6_set = 0;
14001   ip4_address_t ipv4;
14002   ip6_address_t ipv6;
14003   int ret;
14004
14005   /* Parse args required to build the message */
14006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (input, "del"))
14009         {
14010           is_add = 0;
14011         }
14012       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14013         {
14014           ipv4_set = 1;
14015         }
14016       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14017         {
14018           ipv6_set = 1;
14019         }
14020       else
14021         break;
14022     }
14023
14024   if (ipv4_set && ipv6_set)
14025     {
14026       errmsg ("both eid v4 and v6 addresses set");
14027       return -99;
14028     }
14029
14030   if (!ipv4_set && !ipv6_set)
14031     {
14032       errmsg ("eid addresses not set");
14033       return -99;
14034     }
14035
14036   /* Construct the API message */
14037   M (ONE_ADD_DEL_MAP_SERVER, mp);
14038
14039   mp->is_add = is_add;
14040   if (ipv6_set)
14041     {
14042       mp->is_ipv6 = 1;
14043       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14044     }
14045   else
14046     {
14047       mp->is_ipv6 = 0;
14048       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14049     }
14050
14051   /* send it... */
14052   S (mp);
14053
14054   /* Wait for a reply... */
14055   W (ret);
14056   return ret;
14057 }
14058
14059 #define api_lisp_add_del_map_server api_one_add_del_map_server
14060
14061 static int
14062 api_one_add_del_map_resolver (vat_main_t * vam)
14063 {
14064   unformat_input_t *input = vam->input;
14065   vl_api_one_add_del_map_resolver_t *mp;
14066   u8 is_add = 1;
14067   u8 ipv4_set = 0;
14068   u8 ipv6_set = 0;
14069   ip4_address_t ipv4;
14070   ip6_address_t ipv6;
14071   int ret;
14072
14073   /* Parse args required to build the message */
14074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14075     {
14076       if (unformat (input, "del"))
14077         {
14078           is_add = 0;
14079         }
14080       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14081         {
14082           ipv4_set = 1;
14083         }
14084       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14085         {
14086           ipv6_set = 1;
14087         }
14088       else
14089         break;
14090     }
14091
14092   if (ipv4_set && ipv6_set)
14093     {
14094       errmsg ("both eid v4 and v6 addresses set");
14095       return -99;
14096     }
14097
14098   if (!ipv4_set && !ipv6_set)
14099     {
14100       errmsg ("eid addresses not set");
14101       return -99;
14102     }
14103
14104   /* Construct the API message */
14105   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14106
14107   mp->is_add = is_add;
14108   if (ipv6_set)
14109     {
14110       mp->is_ipv6 = 1;
14111       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14112     }
14113   else
14114     {
14115       mp->is_ipv6 = 0;
14116       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14117     }
14118
14119   /* send it... */
14120   S (mp);
14121
14122   /* Wait for a reply... */
14123   W (ret);
14124   return ret;
14125 }
14126
14127 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14128
14129 static int
14130 api_lisp_gpe_enable_disable (vat_main_t * vam)
14131 {
14132   unformat_input_t *input = vam->input;
14133   vl_api_gpe_enable_disable_t *mp;
14134   u8 is_set = 0;
14135   u8 is_en = 1;
14136   int ret;
14137
14138   /* Parse args required to build the message */
14139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14140     {
14141       if (unformat (input, "enable"))
14142         {
14143           is_set = 1;
14144           is_en = 1;
14145         }
14146       else if (unformat (input, "disable"))
14147         {
14148           is_set = 1;
14149           is_en = 0;
14150         }
14151       else
14152         break;
14153     }
14154
14155   if (is_set == 0)
14156     {
14157       errmsg ("Value not set");
14158       return -99;
14159     }
14160
14161   /* Construct the API message */
14162   M (GPE_ENABLE_DISABLE, mp);
14163
14164   mp->is_en = is_en;
14165
14166   /* send it... */
14167   S (mp);
14168
14169   /* Wait for a reply... */
14170   W (ret);
14171   return ret;
14172 }
14173
14174 static int
14175 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14176 {
14177   unformat_input_t *input = vam->input;
14178   vl_api_one_rloc_probe_enable_disable_t *mp;
14179   u8 is_set = 0;
14180   u8 is_en = 0;
14181   int ret;
14182
14183   /* Parse args required to build the message */
14184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14185     {
14186       if (unformat (input, "enable"))
14187         {
14188           is_set = 1;
14189           is_en = 1;
14190         }
14191       else if (unformat (input, "disable"))
14192         is_set = 1;
14193       else
14194         break;
14195     }
14196
14197   if (!is_set)
14198     {
14199       errmsg ("Value not set");
14200       return -99;
14201     }
14202
14203   /* Construct the API message */
14204   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14205
14206   mp->is_enabled = is_en;
14207
14208   /* send it... */
14209   S (mp);
14210
14211   /* Wait for a reply... */
14212   W (ret);
14213   return ret;
14214 }
14215
14216 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14217
14218 static int
14219 api_one_map_register_enable_disable (vat_main_t * vam)
14220 {
14221   unformat_input_t *input = vam->input;
14222   vl_api_one_map_register_enable_disable_t *mp;
14223   u8 is_set = 0;
14224   u8 is_en = 0;
14225   int ret;
14226
14227   /* Parse args required to build the message */
14228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14229     {
14230       if (unformat (input, "enable"))
14231         {
14232           is_set = 1;
14233           is_en = 1;
14234         }
14235       else if (unformat (input, "disable"))
14236         is_set = 1;
14237       else
14238         break;
14239     }
14240
14241   if (!is_set)
14242     {
14243       errmsg ("Value not set");
14244       return -99;
14245     }
14246
14247   /* Construct the API message */
14248   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14249
14250   mp->is_enabled = is_en;
14251
14252   /* send it... */
14253   S (mp);
14254
14255   /* Wait for a reply... */
14256   W (ret);
14257   return ret;
14258 }
14259
14260 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14261
14262 static int
14263 api_one_enable_disable (vat_main_t * vam)
14264 {
14265   unformat_input_t *input = vam->input;
14266   vl_api_one_enable_disable_t *mp;
14267   u8 is_set = 0;
14268   u8 is_en = 0;
14269   int ret;
14270
14271   /* Parse args required to build the message */
14272   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14273     {
14274       if (unformat (input, "enable"))
14275         {
14276           is_set = 1;
14277           is_en = 1;
14278         }
14279       else if (unformat (input, "disable"))
14280         {
14281           is_set = 1;
14282         }
14283       else
14284         break;
14285     }
14286
14287   if (!is_set)
14288     {
14289       errmsg ("Value not set");
14290       return -99;
14291     }
14292
14293   /* Construct the API message */
14294   M (ONE_ENABLE_DISABLE, mp);
14295
14296   mp->is_en = is_en;
14297
14298   /* send it... */
14299   S (mp);
14300
14301   /* Wait for a reply... */
14302   W (ret);
14303   return ret;
14304 }
14305
14306 #define api_lisp_enable_disable api_one_enable_disable
14307
14308 static int
14309 api_show_one_map_register_state (vat_main_t * vam)
14310 {
14311   vl_api_show_one_map_register_state_t *mp;
14312   int ret;
14313
14314   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
14315
14316   /* send */
14317   S (mp);
14318
14319   /* wait for reply */
14320   W (ret);
14321   return ret;
14322 }
14323
14324 #define api_show_lisp_map_register_state api_show_one_map_register_state
14325
14326 static int
14327 api_show_one_rloc_probe_state (vat_main_t * vam)
14328 {
14329   vl_api_show_one_rloc_probe_state_t *mp;
14330   int ret;
14331
14332   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
14333
14334   /* send */
14335   S (mp);
14336
14337   /* wait for reply */
14338   W (ret);
14339   return ret;
14340 }
14341
14342 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
14343
14344 static int
14345 api_one_stats_enable_disable (vat_main_t * vam)
14346 {
14347   vl_api_one_stats_enable_disable_t *mp;
14348   unformat_input_t *input = vam->input;
14349   u8 is_set = 0;
14350   u8 is_en = 0;
14351   int ret;
14352
14353   /* Parse args required to build the message */
14354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14355     {
14356       if (unformat (input, "enable"))
14357         {
14358           is_set = 1;
14359           is_en = 1;
14360         }
14361       else if (unformat (input, "disable"))
14362         {
14363           is_set = 1;
14364         }
14365       else
14366         break;
14367     }
14368
14369   if (!is_set)
14370     {
14371       errmsg ("Value not set");
14372       return -99;
14373     }
14374
14375   M (ONE_STATS_ENABLE_DISABLE, mp);
14376   mp->is_en = is_en;
14377
14378   /* send */
14379   S (mp);
14380
14381   /* wait for reply */
14382   W (ret);
14383   return ret;
14384 }
14385
14386 static int
14387 api_show_one_stats_enable_disable (vat_main_t * vam)
14388 {
14389   vl_api_show_one_stats_enable_disable_t *mp;
14390   int ret;
14391
14392   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
14393
14394   /* send */
14395   S (mp);
14396
14397   /* wait for reply */
14398   W (ret);
14399   return ret;
14400 }
14401
14402 static int
14403 api_show_one_map_request_mode (vat_main_t * vam)
14404 {
14405   vl_api_show_one_map_request_mode_t *mp;
14406   int ret;
14407
14408   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
14409
14410   /* send */
14411   S (mp);
14412
14413   /* wait for reply */
14414   W (ret);
14415   return ret;
14416 }
14417
14418 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
14419
14420 static int
14421 api_one_map_request_mode (vat_main_t * vam)
14422 {
14423   unformat_input_t *input = vam->input;
14424   vl_api_one_map_request_mode_t *mp;
14425   u8 mode = 0;
14426   int ret;
14427
14428   /* Parse args required to build the message */
14429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14430     {
14431       if (unformat (input, "dst-only"))
14432         mode = 0;
14433       else if (unformat (input, "src-dst"))
14434         mode = 1;
14435       else
14436         {
14437           errmsg ("parse error '%U'", format_unformat_error, input);
14438           return -99;
14439         }
14440     }
14441
14442   M (ONE_MAP_REQUEST_MODE, mp);
14443
14444   mp->mode = mode;
14445
14446   /* send */
14447   S (mp);
14448
14449   /* wait for reply */
14450   W (ret);
14451   return ret;
14452 }
14453
14454 #define api_lisp_map_request_mode api_one_map_request_mode
14455
14456 /**
14457  * Enable/disable ONE proxy ITR.
14458  *
14459  * @param vam vpp API test context
14460  * @return return code
14461  */
14462 static int
14463 api_one_pitr_set_locator_set (vat_main_t * vam)
14464 {
14465   u8 ls_name_set = 0;
14466   unformat_input_t *input = vam->input;
14467   vl_api_one_pitr_set_locator_set_t *mp;
14468   u8 is_add = 1;
14469   u8 *ls_name = 0;
14470   int ret;
14471
14472   /* Parse args required to build the message */
14473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14474     {
14475       if (unformat (input, "del"))
14476         is_add = 0;
14477       else if (unformat (input, "locator-set %s", &ls_name))
14478         ls_name_set = 1;
14479       else
14480         {
14481           errmsg ("parse error '%U'", format_unformat_error, input);
14482           return -99;
14483         }
14484     }
14485
14486   if (!ls_name_set)
14487     {
14488       errmsg ("locator-set name not set!");
14489       return -99;
14490     }
14491
14492   M (ONE_PITR_SET_LOCATOR_SET, mp);
14493
14494   mp->is_add = is_add;
14495   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
14496   vec_free (ls_name);
14497
14498   /* send */
14499   S (mp);
14500
14501   /* wait for reply */
14502   W (ret);
14503   return ret;
14504 }
14505
14506 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
14507
14508 static int
14509 api_show_one_pitr (vat_main_t * vam)
14510 {
14511   vl_api_show_one_pitr_t *mp;
14512   int ret;
14513
14514   if (!vam->json_output)
14515     {
14516       print (vam->ofp, "%=20s", "lisp status:");
14517     }
14518
14519   M (SHOW_ONE_PITR, mp);
14520   /* send it... */
14521   S (mp);
14522
14523   /* Wait for a reply... */
14524   W (ret);
14525   return ret;
14526 }
14527
14528 #define api_show_lisp_pitr api_show_one_pitr
14529
14530 static int
14531 api_one_use_petr (vat_main_t * vam)
14532 {
14533   unformat_input_t *input = vam->input;
14534   vl_api_one_use_petr_t *mp;
14535   u8 is_add = 0;
14536   ip_address_t ip;
14537   int ret;
14538
14539   memset (&ip, 0, sizeof (ip));
14540
14541   /* Parse args required to build the message */
14542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14543     {
14544       if (unformat (input, "disable"))
14545         is_add = 0;
14546       else
14547         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
14548         {
14549           is_add = 1;
14550           ip_addr_version (&ip) = IP4;
14551         }
14552       else
14553         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
14554         {
14555           is_add = 1;
14556           ip_addr_version (&ip) = IP6;
14557         }
14558       else
14559         {
14560           errmsg ("parse error '%U'", format_unformat_error, input);
14561           return -99;
14562         }
14563     }
14564
14565   M (ONE_USE_PETR, mp);
14566
14567   mp->is_add = is_add;
14568   if (is_add)
14569     {
14570       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
14571       if (mp->is_ip4)
14572         clib_memcpy (mp->address, &ip, 4);
14573       else
14574         clib_memcpy (mp->address, &ip, 16);
14575     }
14576
14577   /* send */
14578   S (mp);
14579
14580   /* wait for reply */
14581   W (ret);
14582   return ret;
14583 }
14584
14585 #define api_lisp_use_petr api_one_use_petr
14586
14587 static int
14588 api_show_one_use_petr (vat_main_t * vam)
14589 {
14590   vl_api_show_one_use_petr_t *mp;
14591   int ret;
14592
14593   if (!vam->json_output)
14594     {
14595       print (vam->ofp, "%=20s", "Proxy-ETR status:");
14596     }
14597
14598   M (SHOW_ONE_USE_PETR, mp);
14599   /* send it... */
14600   S (mp);
14601
14602   /* Wait for a reply... */
14603   W (ret);
14604   return ret;
14605 }
14606
14607 #define api_show_lisp_use_petr api_show_one_use_petr
14608
14609 /**
14610  * Add/delete mapping between vni and vrf
14611  */
14612 static int
14613 api_one_eid_table_add_del_map (vat_main_t * vam)
14614 {
14615   unformat_input_t *input = vam->input;
14616   vl_api_one_eid_table_add_del_map_t *mp;
14617   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
14618   u32 vni, vrf, bd_index;
14619   int ret;
14620
14621   /* Parse args required to build the message */
14622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14623     {
14624       if (unformat (input, "del"))
14625         is_add = 0;
14626       else if (unformat (input, "vrf %d", &vrf))
14627         vrf_set = 1;
14628       else if (unformat (input, "bd_index %d", &bd_index))
14629         bd_index_set = 1;
14630       else if (unformat (input, "vni %d", &vni))
14631         vni_set = 1;
14632       else
14633         break;
14634     }
14635
14636   if (!vni_set || (!vrf_set && !bd_index_set))
14637     {
14638       errmsg ("missing arguments!");
14639       return -99;
14640     }
14641
14642   if (vrf_set && bd_index_set)
14643     {
14644       errmsg ("error: both vrf and bd entered!");
14645       return -99;
14646     }
14647
14648   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
14649
14650   mp->is_add = is_add;
14651   mp->vni = htonl (vni);
14652   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
14653   mp->is_l2 = bd_index_set;
14654
14655   /* send */
14656   S (mp);
14657
14658   /* wait for reply */
14659   W (ret);
14660   return ret;
14661 }
14662
14663 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
14664
14665 uword
14666 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
14667 {
14668   u32 *action = va_arg (*args, u32 *);
14669   u8 *s = 0;
14670
14671   if (unformat (input, "%s", &s))
14672     {
14673       if (!strcmp ((char *) s, "no-action"))
14674         action[0] = 0;
14675       else if (!strcmp ((char *) s, "natively-forward"))
14676         action[0] = 1;
14677       else if (!strcmp ((char *) s, "send-map-request"))
14678         action[0] = 2;
14679       else if (!strcmp ((char *) s, "drop"))
14680         action[0] = 3;
14681       else
14682         {
14683           clib_warning ("invalid action: '%s'", s);
14684           action[0] = 3;
14685         }
14686     }
14687   else
14688     return 0;
14689
14690   vec_free (s);
14691   return 1;
14692 }
14693
14694 /**
14695  * Add/del remote mapping to/from ONE control plane
14696  *
14697  * @param vam vpp API test context
14698  * @return return code
14699  */
14700 static int
14701 api_one_add_del_remote_mapping (vat_main_t * vam)
14702 {
14703   unformat_input_t *input = vam->input;
14704   vl_api_one_add_del_remote_mapping_t *mp;
14705   u32 vni = 0;
14706   lisp_eid_vat_t _eid, *eid = &_eid;
14707   lisp_eid_vat_t _seid, *seid = &_seid;
14708   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14709   u32 action = ~0, p, w, data_len;
14710   ip4_address_t rloc4;
14711   ip6_address_t rloc6;
14712   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
14713   int ret;
14714
14715   memset (&rloc, 0, sizeof (rloc));
14716
14717   /* Parse args required to build the message */
14718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14719     {
14720       if (unformat (input, "del-all"))
14721         {
14722           del_all = 1;
14723         }
14724       else if (unformat (input, "del"))
14725         {
14726           is_add = 0;
14727         }
14728       else if (unformat (input, "add"))
14729         {
14730           is_add = 1;
14731         }
14732       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14733         {
14734           eid_set = 1;
14735         }
14736       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14737         {
14738           seid_set = 1;
14739         }
14740       else if (unformat (input, "vni %d", &vni))
14741         {
14742           ;
14743         }
14744       else if (unformat (input, "p %d w %d", &p, &w))
14745         {
14746           if (!curr_rloc)
14747             {
14748               errmsg ("No RLOC configured for setting priority/weight!");
14749               return -99;
14750             }
14751           curr_rloc->priority = p;
14752           curr_rloc->weight = w;
14753         }
14754       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14755         {
14756           rloc.is_ip4 = 1;
14757           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14758           vec_add1 (rlocs, rloc);
14759           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14760         }
14761       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14762         {
14763           rloc.is_ip4 = 0;
14764           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14765           vec_add1 (rlocs, rloc);
14766           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14767         }
14768       else if (unformat (input, "action %U",
14769                          unformat_negative_mapping_action, &action))
14770         {
14771           ;
14772         }
14773       else
14774         {
14775           clib_warning ("parse error '%U'", format_unformat_error, input);
14776           return -99;
14777         }
14778     }
14779
14780   if (0 == eid_set)
14781     {
14782       errmsg ("missing params!");
14783       return -99;
14784     }
14785
14786   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14787     {
14788       errmsg ("no action set for negative map-reply!");
14789       return -99;
14790     }
14791
14792   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
14793
14794   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
14795   mp->is_add = is_add;
14796   mp->vni = htonl (vni);
14797   mp->action = (u8) action;
14798   mp->is_src_dst = seid_set;
14799   mp->eid_len = eid->len;
14800   mp->seid_len = seid->len;
14801   mp->del_all = del_all;
14802   mp->eid_type = eid->type;
14803   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14804   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14805
14806   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14807   clib_memcpy (mp->rlocs, rlocs, data_len);
14808   vec_free (rlocs);
14809
14810   /* send it... */
14811   S (mp);
14812
14813   /* Wait for a reply... */
14814   W (ret);
14815   return ret;
14816 }
14817
14818 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
14819
14820 /**
14821  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
14822  * forwarding entries in data-plane accordingly.
14823  *
14824  * @param vam vpp API test context
14825  * @return return code
14826  */
14827 static int
14828 api_one_add_del_adjacency (vat_main_t * vam)
14829 {
14830   unformat_input_t *input = vam->input;
14831   vl_api_one_add_del_adjacency_t *mp;
14832   u32 vni = 0;
14833   ip4_address_t leid4, reid4;
14834   ip6_address_t leid6, reid6;
14835   u8 reid_mac[6] = { 0 };
14836   u8 leid_mac[6] = { 0 };
14837   u8 reid_type, leid_type;
14838   u32 leid_len = 0, reid_len = 0, len;
14839   u8 is_add = 1;
14840   int ret;
14841
14842   leid_type = reid_type = (u8) ~ 0;
14843
14844   /* Parse args required to build the message */
14845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14846     {
14847       if (unformat (input, "del"))
14848         {
14849           is_add = 0;
14850         }
14851       else if (unformat (input, "add"))
14852         {
14853           is_add = 1;
14854         }
14855       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14856                          &reid4, &len))
14857         {
14858           reid_type = 0;        /* ipv4 */
14859           reid_len = len;
14860         }
14861       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14862                          &reid6, &len))
14863         {
14864           reid_type = 1;        /* ipv6 */
14865           reid_len = len;
14866         }
14867       else if (unformat (input, "reid %U", unformat_ethernet_address,
14868                          reid_mac))
14869         {
14870           reid_type = 2;        /* mac */
14871         }
14872       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14873                          &leid4, &len))
14874         {
14875           leid_type = 0;        /* ipv4 */
14876           leid_len = len;
14877         }
14878       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14879                          &leid6, &len))
14880         {
14881           leid_type = 1;        /* ipv6 */
14882           leid_len = len;
14883         }
14884       else if (unformat (input, "leid %U", unformat_ethernet_address,
14885                          leid_mac))
14886         {
14887           leid_type = 2;        /* mac */
14888         }
14889       else if (unformat (input, "vni %d", &vni))
14890         {
14891           ;
14892         }
14893       else
14894         {
14895           errmsg ("parse error '%U'", format_unformat_error, input);
14896           return -99;
14897         }
14898     }
14899
14900   if ((u8) ~ 0 == reid_type)
14901     {
14902       errmsg ("missing params!");
14903       return -99;
14904     }
14905
14906   if (leid_type != reid_type)
14907     {
14908       errmsg ("remote and local EIDs are of different types!");
14909       return -99;
14910     }
14911
14912   M (ONE_ADD_DEL_ADJACENCY, mp);
14913   mp->is_add = is_add;
14914   mp->vni = htonl (vni);
14915   mp->leid_len = leid_len;
14916   mp->reid_len = reid_len;
14917   mp->eid_type = reid_type;
14918
14919   switch (mp->eid_type)
14920     {
14921     case 0:
14922       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14923       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14924       break;
14925     case 1:
14926       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14927       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14928       break;
14929     case 2:
14930       clib_memcpy (mp->leid, leid_mac, 6);
14931       clib_memcpy (mp->reid, reid_mac, 6);
14932       break;
14933     default:
14934       errmsg ("unknown EID type %d!", mp->eid_type);
14935       return 0;
14936     }
14937
14938   /* send it... */
14939   S (mp);
14940
14941   /* Wait for a reply... */
14942   W (ret);
14943   return ret;
14944 }
14945
14946 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
14947
14948 uword
14949 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
14950 {
14951   u32 *mode = va_arg (*args, u32 *);
14952
14953   if (unformat (input, "lisp"))
14954     *mode = 0;
14955   else if (unformat (input, "vxlan"))
14956     *mode = 1;
14957   else
14958     return 0;
14959
14960   return 1;
14961 }
14962
14963 static int
14964 api_gpe_get_encap_mode (vat_main_t * vam)
14965 {
14966   vl_api_gpe_get_encap_mode_t *mp;
14967   int ret;
14968
14969   /* Construct the API message */
14970   M (GPE_GET_ENCAP_MODE, mp);
14971
14972   /* send it... */
14973   S (mp);
14974
14975   /* Wait for a reply... */
14976   W (ret);
14977   return ret;
14978 }
14979
14980 static int
14981 api_gpe_set_encap_mode (vat_main_t * vam)
14982 {
14983   unformat_input_t *input = vam->input;
14984   vl_api_gpe_set_encap_mode_t *mp;
14985   int ret;
14986   u32 mode = 0;
14987
14988   /* Parse args required to build the message */
14989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14990     {
14991       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
14992         ;
14993       else
14994         break;
14995     }
14996
14997   /* Construct the API message */
14998   M (GPE_SET_ENCAP_MODE, mp);
14999
15000   mp->mode = mode;
15001
15002   /* send it... */
15003   S (mp);
15004
15005   /* Wait for a reply... */
15006   W (ret);
15007   return ret;
15008 }
15009
15010 static int
15011 api_lisp_gpe_add_del_iface (vat_main_t * vam)
15012 {
15013   unformat_input_t *input = vam->input;
15014   vl_api_gpe_add_del_iface_t *mp;
15015   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
15016   u32 dp_table = 0, vni = 0;
15017   int ret;
15018
15019   /* Parse args required to build the message */
15020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15021     {
15022       if (unformat (input, "up"))
15023         {
15024           action_set = 1;
15025           is_add = 1;
15026         }
15027       else if (unformat (input, "down"))
15028         {
15029           action_set = 1;
15030           is_add = 0;
15031         }
15032       else if (unformat (input, "table_id %d", &dp_table))
15033         {
15034           dp_table_set = 1;
15035         }
15036       else if (unformat (input, "bd_id %d", &dp_table))
15037         {
15038           dp_table_set = 1;
15039           is_l2 = 1;
15040         }
15041       else if (unformat (input, "vni %d", &vni))
15042         {
15043           vni_set = 1;
15044         }
15045       else
15046         break;
15047     }
15048
15049   if (action_set == 0)
15050     {
15051       errmsg ("Action not set");
15052       return -99;
15053     }
15054   if (dp_table_set == 0 || vni_set == 0)
15055     {
15056       errmsg ("vni and dp_table must be set");
15057       return -99;
15058     }
15059
15060   /* Construct the API message */
15061   M (GPE_ADD_DEL_IFACE, mp);
15062
15063   mp->is_add = is_add;
15064   mp->dp_table = dp_table;
15065   mp->is_l2 = is_l2;
15066   mp->vni = vni;
15067
15068   /* send it... */
15069   S (mp);
15070
15071   /* Wait for a reply... */
15072   W (ret);
15073   return ret;
15074 }
15075
15076 /**
15077  * Add/del map request itr rlocs from ONE control plane and updates
15078  *
15079  * @param vam vpp API test context
15080  * @return return code
15081  */
15082 static int
15083 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
15084 {
15085   unformat_input_t *input = vam->input;
15086   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
15087   u8 *locator_set_name = 0;
15088   u8 locator_set_name_set = 0;
15089   u8 is_add = 1;
15090   int ret;
15091
15092   /* Parse args required to build the message */
15093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15094     {
15095       if (unformat (input, "del"))
15096         {
15097           is_add = 0;
15098         }
15099       else if (unformat (input, "%_%v%_", &locator_set_name))
15100         {
15101           locator_set_name_set = 1;
15102         }
15103       else
15104         {
15105           clib_warning ("parse error '%U'", format_unformat_error, input);
15106           return -99;
15107         }
15108     }
15109
15110   if (is_add && !locator_set_name_set)
15111     {
15112       errmsg ("itr-rloc is not set!");
15113       return -99;
15114     }
15115
15116   if (is_add && vec_len (locator_set_name) > 64)
15117     {
15118       errmsg ("itr-rloc locator-set name too long");
15119       vec_free (locator_set_name);
15120       return -99;
15121     }
15122
15123   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
15124   mp->is_add = is_add;
15125   if (is_add)
15126     {
15127       clib_memcpy (mp->locator_set_name, locator_set_name,
15128                    vec_len (locator_set_name));
15129     }
15130   else
15131     {
15132       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
15133     }
15134   vec_free (locator_set_name);
15135
15136   /* send it... */
15137   S (mp);
15138
15139   /* Wait for a reply... */
15140   W (ret);
15141   return ret;
15142 }
15143
15144 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
15145
15146 static int
15147 api_one_locator_dump (vat_main_t * vam)
15148 {
15149   unformat_input_t *input = vam->input;
15150   vl_api_one_locator_dump_t *mp;
15151   vl_api_control_ping_t *mp_ping;
15152   u8 is_index_set = 0, is_name_set = 0;
15153   u8 *ls_name = 0;
15154   u32 ls_index = ~0;
15155   int ret;
15156
15157   /* Parse args required to build the message */
15158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15159     {
15160       if (unformat (input, "ls_name %_%v%_", &ls_name))
15161         {
15162           is_name_set = 1;
15163         }
15164       else if (unformat (input, "ls_index %d", &ls_index))
15165         {
15166           is_index_set = 1;
15167         }
15168       else
15169         {
15170           errmsg ("parse error '%U'", format_unformat_error, input);
15171           return -99;
15172         }
15173     }
15174
15175   if (!is_index_set && !is_name_set)
15176     {
15177       errmsg ("error: expected one of index or name!");
15178       return -99;
15179     }
15180
15181   if (is_index_set && is_name_set)
15182     {
15183       errmsg ("error: only one param expected!");
15184       return -99;
15185     }
15186
15187   if (vec_len (ls_name) > 62)
15188     {
15189       errmsg ("error: locator set name too long!");
15190       return -99;
15191     }
15192
15193   if (!vam->json_output)
15194     {
15195       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
15196     }
15197
15198   M (ONE_LOCATOR_DUMP, mp);
15199   mp->is_index_set = is_index_set;
15200
15201   if (is_index_set)
15202     mp->ls_index = clib_host_to_net_u32 (ls_index);
15203   else
15204     {
15205       vec_add1 (ls_name, 0);
15206       strncpy ((char *) mp->ls_name, (char *) ls_name,
15207                sizeof (mp->ls_name) - 1);
15208     }
15209
15210   /* send it... */
15211   S (mp);
15212
15213   /* Use a control ping for synchronization */
15214   M (CONTROL_PING, mp_ping);
15215   S (mp_ping);
15216
15217   /* Wait for a reply... */
15218   W (ret);
15219   return ret;
15220 }
15221
15222 #define api_lisp_locator_dump api_one_locator_dump
15223
15224 static int
15225 api_one_locator_set_dump (vat_main_t * vam)
15226 {
15227   vl_api_one_locator_set_dump_t *mp;
15228   vl_api_control_ping_t *mp_ping;
15229   unformat_input_t *input = vam->input;
15230   u8 filter = 0;
15231   int ret;
15232
15233   /* Parse args required to build the message */
15234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15235     {
15236       if (unformat (input, "local"))
15237         {
15238           filter = 1;
15239         }
15240       else if (unformat (input, "remote"))
15241         {
15242           filter = 2;
15243         }
15244       else
15245         {
15246           errmsg ("parse error '%U'", format_unformat_error, input);
15247           return -99;
15248         }
15249     }
15250
15251   if (!vam->json_output)
15252     {
15253       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
15254     }
15255
15256   M (ONE_LOCATOR_SET_DUMP, mp);
15257
15258   mp->filter = filter;
15259
15260   /* send it... */
15261   S (mp);
15262
15263   /* Use a control ping for synchronization */
15264   M (CONTROL_PING, mp_ping);
15265   S (mp_ping);
15266
15267   /* Wait for a reply... */
15268   W (ret);
15269   return ret;
15270 }
15271
15272 #define api_lisp_locator_set_dump api_one_locator_set_dump
15273
15274 static int
15275 api_one_eid_table_map_dump (vat_main_t * vam)
15276 {
15277   u8 is_l2 = 0;
15278   u8 mode_set = 0;
15279   unformat_input_t *input = vam->input;
15280   vl_api_one_eid_table_map_dump_t *mp;
15281   vl_api_control_ping_t *mp_ping;
15282   int ret;
15283
15284   /* Parse args required to build the message */
15285   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15286     {
15287       if (unformat (input, "l2"))
15288         {
15289           is_l2 = 1;
15290           mode_set = 1;
15291         }
15292       else if (unformat (input, "l3"))
15293         {
15294           is_l2 = 0;
15295           mode_set = 1;
15296         }
15297       else
15298         {
15299           errmsg ("parse error '%U'", format_unformat_error, input);
15300           return -99;
15301         }
15302     }
15303
15304   if (!mode_set)
15305     {
15306       errmsg ("expected one of 'l2' or 'l3' parameter!");
15307       return -99;
15308     }
15309
15310   if (!vam->json_output)
15311     {
15312       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
15313     }
15314
15315   M (ONE_EID_TABLE_MAP_DUMP, mp);
15316   mp->is_l2 = is_l2;
15317
15318   /* send it... */
15319   S (mp);
15320
15321   /* Use a control ping for synchronization */
15322   M (CONTROL_PING, mp_ping);
15323   S (mp_ping);
15324
15325   /* Wait for a reply... */
15326   W (ret);
15327   return ret;
15328 }
15329
15330 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
15331
15332 static int
15333 api_one_eid_table_vni_dump (vat_main_t * vam)
15334 {
15335   vl_api_one_eid_table_vni_dump_t *mp;
15336   vl_api_control_ping_t *mp_ping;
15337   int ret;
15338
15339   if (!vam->json_output)
15340     {
15341       print (vam->ofp, "VNI");
15342     }
15343
15344   M (ONE_EID_TABLE_VNI_DUMP, mp);
15345
15346   /* send it... */
15347   S (mp);
15348
15349   /* Use a control ping for synchronization */
15350   M (CONTROL_PING, mp_ping);
15351   S (mp_ping);
15352
15353   /* Wait for a reply... */
15354   W (ret);
15355   return ret;
15356 }
15357
15358 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
15359
15360 static int
15361 api_one_eid_table_dump (vat_main_t * vam)
15362 {
15363   unformat_input_t *i = vam->input;
15364   vl_api_one_eid_table_dump_t *mp;
15365   vl_api_control_ping_t *mp_ping;
15366   struct in_addr ip4;
15367   struct in6_addr ip6;
15368   u8 mac[6];
15369   u8 eid_type = ~0, eid_set = 0;
15370   u32 prefix_length = ~0, t, vni = 0;
15371   u8 filter = 0;
15372   int ret;
15373
15374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15375     {
15376       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
15377         {
15378           eid_set = 1;
15379           eid_type = 0;
15380           prefix_length = t;
15381         }
15382       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
15383         {
15384           eid_set = 1;
15385           eid_type = 1;
15386           prefix_length = t;
15387         }
15388       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
15389         {
15390           eid_set = 1;
15391           eid_type = 2;
15392         }
15393       else if (unformat (i, "vni %d", &t))
15394         {
15395           vni = t;
15396         }
15397       else if (unformat (i, "local"))
15398         {
15399           filter = 1;
15400         }
15401       else if (unformat (i, "remote"))
15402         {
15403           filter = 2;
15404         }
15405       else
15406         {
15407           errmsg ("parse error '%U'", format_unformat_error, i);
15408           return -99;
15409         }
15410     }
15411
15412   if (!vam->json_output)
15413     {
15414       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
15415              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
15416     }
15417
15418   M (ONE_EID_TABLE_DUMP, mp);
15419
15420   mp->filter = filter;
15421   if (eid_set)
15422     {
15423       mp->eid_set = 1;
15424       mp->vni = htonl (vni);
15425       mp->eid_type = eid_type;
15426       switch (eid_type)
15427         {
15428         case 0:
15429           mp->prefix_length = prefix_length;
15430           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
15431           break;
15432         case 1:
15433           mp->prefix_length = prefix_length;
15434           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
15435           break;
15436         case 2:
15437           clib_memcpy (mp->eid, mac, sizeof (mac));
15438           break;
15439         default:
15440           errmsg ("unknown EID type %d!", eid_type);
15441           return -99;
15442         }
15443     }
15444
15445   /* send it... */
15446   S (mp);
15447
15448   /* Use a control ping for synchronization */
15449   M (CONTROL_PING, mp_ping);
15450   S (mp_ping);
15451
15452   /* Wait for a reply... */
15453   W (ret);
15454   return ret;
15455 }
15456
15457 #define api_lisp_eid_table_dump api_one_eid_table_dump
15458
15459 static int
15460 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
15461 {
15462   unformat_input_t *i = vam->input;
15463   vl_api_gpe_fwd_entries_get_t *mp;
15464   u8 vni_set = 0;
15465   u32 vni = ~0;
15466   int ret;
15467
15468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15469     {
15470       if (unformat (i, "vni %d", &vni))
15471         {
15472           vni_set = 1;
15473         }
15474       else
15475         {
15476           errmsg ("parse error '%U'", format_unformat_error, i);
15477           return -99;
15478         }
15479     }
15480
15481   if (!vni_set)
15482     {
15483       errmsg ("vni not set!");
15484       return -99;
15485     }
15486
15487   if (!vam->json_output)
15488     {
15489       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
15490              "leid", "reid");
15491     }
15492
15493   M (GPE_FWD_ENTRIES_GET, mp);
15494   mp->vni = clib_host_to_net_u32 (vni);
15495
15496   /* send it... */
15497   S (mp);
15498
15499   /* Wait for a reply... */
15500   W (ret);
15501   return ret;
15502 }
15503
15504 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
15505 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
15506 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
15507 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
15508
15509 static int
15510 api_one_adjacencies_get (vat_main_t * vam)
15511 {
15512   unformat_input_t *i = vam->input;
15513   vl_api_one_adjacencies_get_t *mp;
15514   u8 vni_set = 0;
15515   u32 vni = ~0;
15516   int ret;
15517
15518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15519     {
15520       if (unformat (i, "vni %d", &vni))
15521         {
15522           vni_set = 1;
15523         }
15524       else
15525         {
15526           errmsg ("parse error '%U'", format_unformat_error, i);
15527           return -99;
15528         }
15529     }
15530
15531   if (!vni_set)
15532     {
15533       errmsg ("vni not set!");
15534       return -99;
15535     }
15536
15537   if (!vam->json_output)
15538     {
15539       print (vam->ofp, "%s %40s", "leid", "reid");
15540     }
15541
15542   M (ONE_ADJACENCIES_GET, mp);
15543   mp->vni = clib_host_to_net_u32 (vni);
15544
15545   /* send it... */
15546   S (mp);
15547
15548   /* Wait for a reply... */
15549   W (ret);
15550   return ret;
15551 }
15552
15553 #define api_lisp_adjacencies_get api_one_adjacencies_get
15554
15555 static int
15556 api_one_map_server_dump (vat_main_t * vam)
15557 {
15558   vl_api_one_map_server_dump_t *mp;
15559   vl_api_control_ping_t *mp_ping;
15560   int ret;
15561
15562   if (!vam->json_output)
15563     {
15564       print (vam->ofp, "%=20s", "Map server");
15565     }
15566
15567   M (ONE_MAP_SERVER_DUMP, mp);
15568   /* send it... */
15569   S (mp);
15570
15571   /* Use a control ping for synchronization */
15572   M (CONTROL_PING, mp_ping);
15573   S (mp_ping);
15574
15575   /* Wait for a reply... */
15576   W (ret);
15577   return ret;
15578 }
15579
15580 #define api_lisp_map_server_dump api_one_map_server_dump
15581
15582 static int
15583 api_one_map_resolver_dump (vat_main_t * vam)
15584 {
15585   vl_api_one_map_resolver_dump_t *mp;
15586   vl_api_control_ping_t *mp_ping;
15587   int ret;
15588
15589   if (!vam->json_output)
15590     {
15591       print (vam->ofp, "%=20s", "Map resolver");
15592     }
15593
15594   M (ONE_MAP_RESOLVER_DUMP, mp);
15595   /* send it... */
15596   S (mp);
15597
15598   /* Use a control ping for synchronization */
15599   M (CONTROL_PING, mp_ping);
15600   S (mp_ping);
15601
15602   /* Wait for a reply... */
15603   W (ret);
15604   return ret;
15605 }
15606
15607 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
15608
15609 static int
15610 api_one_stats_dump (vat_main_t * vam)
15611 {
15612   vl_api_one_stats_dump_t *mp;
15613   vl_api_control_ping_t *mp_ping;
15614   int ret;
15615
15616   M (ONE_STATS_DUMP, mp);
15617   /* send it... */
15618   S (mp);
15619
15620   /* Use a control ping for synchronization */
15621   M (CONTROL_PING, mp_ping);
15622   S (mp_ping);
15623
15624   /* Wait for a reply... */
15625   W (ret);
15626   return ret;
15627 }
15628
15629 static int
15630 api_show_one_status (vat_main_t * vam)
15631 {
15632   vl_api_show_one_status_t *mp;
15633   int ret;
15634
15635   if (!vam->json_output)
15636     {
15637       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
15638     }
15639
15640   M (SHOW_ONE_STATUS, mp);
15641   /* send it... */
15642   S (mp);
15643   /* Wait for a reply... */
15644   W (ret);
15645   return ret;
15646 }
15647
15648 #define api_show_lisp_status api_show_one_status
15649
15650 static int
15651 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
15652 {
15653   vl_api_gpe_fwd_entry_path_dump_t *mp;
15654   vl_api_control_ping_t *mp_ping;
15655   unformat_input_t *i = vam->input;
15656   u32 fwd_entry_index = ~0;
15657   int ret;
15658
15659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15660     {
15661       if (unformat (i, "index %d", &fwd_entry_index))
15662         ;
15663       else
15664         break;
15665     }
15666
15667   if (~0 == fwd_entry_index)
15668     {
15669       errmsg ("no index specified!");
15670       return -99;
15671     }
15672
15673   if (!vam->json_output)
15674     {
15675       print (vam->ofp, "first line");
15676     }
15677
15678   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
15679
15680   /* send it... */
15681   S (mp);
15682   /* Use a control ping for synchronization */
15683   M (CONTROL_PING, mp_ping);
15684   S (mp_ping);
15685
15686   /* Wait for a reply... */
15687   W (ret);
15688   return ret;
15689 }
15690
15691 static int
15692 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
15693 {
15694   vl_api_one_get_map_request_itr_rlocs_t *mp;
15695   int ret;
15696
15697   if (!vam->json_output)
15698     {
15699       print (vam->ofp, "%=20s", "itr-rlocs:");
15700     }
15701
15702   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
15703   /* send it... */
15704   S (mp);
15705   /* Wait for a reply... */
15706   W (ret);
15707   return ret;
15708 }
15709
15710 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
15711
15712 static int
15713 api_af_packet_create (vat_main_t * vam)
15714 {
15715   unformat_input_t *i = vam->input;
15716   vl_api_af_packet_create_t *mp;
15717   u8 *host_if_name = 0;
15718   u8 hw_addr[6];
15719   u8 random_hw_addr = 1;
15720   int ret;
15721
15722   memset (hw_addr, 0, sizeof (hw_addr));
15723
15724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15725     {
15726       if (unformat (i, "name %s", &host_if_name))
15727         vec_add1 (host_if_name, 0);
15728       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15729         random_hw_addr = 0;
15730       else
15731         break;
15732     }
15733
15734   if (!vec_len (host_if_name))
15735     {
15736       errmsg ("host-interface name must be specified");
15737       return -99;
15738     }
15739
15740   if (vec_len (host_if_name) > 64)
15741     {
15742       errmsg ("host-interface name too long");
15743       return -99;
15744     }
15745
15746   M (AF_PACKET_CREATE, mp);
15747
15748   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15749   clib_memcpy (mp->hw_addr, hw_addr, 6);
15750   mp->use_random_hw_addr = random_hw_addr;
15751   vec_free (host_if_name);
15752
15753   S (mp);
15754
15755   /* *INDENT-OFF* */
15756   W2 (ret,
15757       ({
15758         if (ret == 0)
15759           fprintf (vam->ofp ? vam->ofp : stderr,
15760                    " new sw_if_index = %d\n", vam->sw_if_index);
15761       }));
15762   /* *INDENT-ON* */
15763   return ret;
15764 }
15765
15766 static int
15767 api_af_packet_delete (vat_main_t * vam)
15768 {
15769   unformat_input_t *i = vam->input;
15770   vl_api_af_packet_delete_t *mp;
15771   u8 *host_if_name = 0;
15772   int ret;
15773
15774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15775     {
15776       if (unformat (i, "name %s", &host_if_name))
15777         vec_add1 (host_if_name, 0);
15778       else
15779         break;
15780     }
15781
15782   if (!vec_len (host_if_name))
15783     {
15784       errmsg ("host-interface name must be specified");
15785       return -99;
15786     }
15787
15788   if (vec_len (host_if_name) > 64)
15789     {
15790       errmsg ("host-interface name too long");
15791       return -99;
15792     }
15793
15794   M (AF_PACKET_DELETE, mp);
15795
15796   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
15797   vec_free (host_if_name);
15798
15799   S (mp);
15800   W (ret);
15801   return ret;
15802 }
15803
15804 static int
15805 api_policer_add_del (vat_main_t * vam)
15806 {
15807   unformat_input_t *i = vam->input;
15808   vl_api_policer_add_del_t *mp;
15809   u8 is_add = 1;
15810   u8 *name = 0;
15811   u32 cir = 0;
15812   u32 eir = 0;
15813   u64 cb = 0;
15814   u64 eb = 0;
15815   u8 rate_type = 0;
15816   u8 round_type = 0;
15817   u8 type = 0;
15818   u8 color_aware = 0;
15819   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
15820   int ret;
15821
15822   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
15823   conform_action.dscp = 0;
15824   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
15825   exceed_action.dscp = 0;
15826   violate_action.action_type = SSE2_QOS_ACTION_DROP;
15827   violate_action.dscp = 0;
15828
15829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15830     {
15831       if (unformat (i, "del"))
15832         is_add = 0;
15833       else if (unformat (i, "name %s", &name))
15834         vec_add1 (name, 0);
15835       else if (unformat (i, "cir %u", &cir))
15836         ;
15837       else if (unformat (i, "eir %u", &eir))
15838         ;
15839       else if (unformat (i, "cb %u", &cb))
15840         ;
15841       else if (unformat (i, "eb %u", &eb))
15842         ;
15843       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
15844                          &rate_type))
15845         ;
15846       else if (unformat (i, "round_type %U", unformat_policer_round_type,
15847                          &round_type))
15848         ;
15849       else if (unformat (i, "type %U", unformat_policer_type, &type))
15850         ;
15851       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
15852                          &conform_action))
15853         ;
15854       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
15855                          &exceed_action))
15856         ;
15857       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15858                          &violate_action))
15859         ;
15860       else if (unformat (i, "color-aware"))
15861         color_aware = 1;
15862       else
15863         break;
15864     }
15865
15866   if (!vec_len (name))
15867     {
15868       errmsg ("policer name must be specified");
15869       return -99;
15870     }
15871
15872   if (vec_len (name) > 64)
15873     {
15874       errmsg ("policer name too long");
15875       return -99;
15876     }
15877
15878   M (POLICER_ADD_DEL, mp);
15879
15880   clib_memcpy (mp->name, name, vec_len (name));
15881   vec_free (name);
15882   mp->is_add = is_add;
15883   mp->cir = cir;
15884   mp->eir = eir;
15885   mp->cb = cb;
15886   mp->eb = eb;
15887   mp->rate_type = rate_type;
15888   mp->round_type = round_type;
15889   mp->type = type;
15890   mp->conform_action_type = conform_action.action_type;
15891   mp->conform_dscp = conform_action.dscp;
15892   mp->exceed_action_type = exceed_action.action_type;
15893   mp->exceed_dscp = exceed_action.dscp;
15894   mp->violate_action_type = violate_action.action_type;
15895   mp->violate_dscp = violate_action.dscp;
15896   mp->color_aware = color_aware;
15897
15898   S (mp);
15899   W (ret);
15900   return ret;
15901 }
15902
15903 static int
15904 api_policer_dump (vat_main_t * vam)
15905 {
15906   unformat_input_t *i = vam->input;
15907   vl_api_policer_dump_t *mp;
15908   vl_api_control_ping_t *mp_ping;
15909   u8 *match_name = 0;
15910   u8 match_name_valid = 0;
15911   int ret;
15912
15913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15914     {
15915       if (unformat (i, "name %s", &match_name))
15916         {
15917           vec_add1 (match_name, 0);
15918           match_name_valid = 1;
15919         }
15920       else
15921         break;
15922     }
15923
15924   M (POLICER_DUMP, mp);
15925   mp->match_name_valid = match_name_valid;
15926   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15927   vec_free (match_name);
15928   /* send it... */
15929   S (mp);
15930
15931   /* Use a control ping for synchronization */
15932   M (CONTROL_PING, mp_ping);
15933   S (mp_ping);
15934
15935   /* Wait for a reply... */
15936   W (ret);
15937   return ret;
15938 }
15939
15940 static int
15941 api_policer_classify_set_interface (vat_main_t * vam)
15942 {
15943   unformat_input_t *i = vam->input;
15944   vl_api_policer_classify_set_interface_t *mp;
15945   u32 sw_if_index;
15946   int sw_if_index_set;
15947   u32 ip4_table_index = ~0;
15948   u32 ip6_table_index = ~0;
15949   u32 l2_table_index = ~0;
15950   u8 is_add = 1;
15951   int ret;
15952
15953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15954     {
15955       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15956         sw_if_index_set = 1;
15957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15958         sw_if_index_set = 1;
15959       else if (unformat (i, "del"))
15960         is_add = 0;
15961       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15962         ;
15963       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15964         ;
15965       else if (unformat (i, "l2-table %d", &l2_table_index))
15966         ;
15967       else
15968         {
15969           clib_warning ("parse error '%U'", format_unformat_error, i);
15970           return -99;
15971         }
15972     }
15973
15974   if (sw_if_index_set == 0)
15975     {
15976       errmsg ("missing interface name or sw_if_index");
15977       return -99;
15978     }
15979
15980   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
15981
15982   mp->sw_if_index = ntohl (sw_if_index);
15983   mp->ip4_table_index = ntohl (ip4_table_index);
15984   mp->ip6_table_index = ntohl (ip6_table_index);
15985   mp->l2_table_index = ntohl (l2_table_index);
15986   mp->is_add = is_add;
15987
15988   S (mp);
15989   W (ret);
15990   return ret;
15991 }
15992
15993 static int
15994 api_policer_classify_dump (vat_main_t * vam)
15995 {
15996   unformat_input_t *i = vam->input;
15997   vl_api_policer_classify_dump_t *mp;
15998   vl_api_control_ping_t *mp_ping;
15999   u8 type = POLICER_CLASSIFY_N_TABLES;
16000   int ret;
16001
16002   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
16003     ;
16004   else
16005     {
16006       errmsg ("classify table type must be specified");
16007       return -99;
16008     }
16009
16010   if (!vam->json_output)
16011     {
16012       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16013     }
16014
16015   M (POLICER_CLASSIFY_DUMP, mp);
16016   mp->type = type;
16017   /* send it... */
16018   S (mp);
16019
16020   /* Use a control ping for synchronization */
16021   M (CONTROL_PING, mp_ping);
16022   S (mp_ping);
16023
16024   /* Wait for a reply... */
16025   W (ret);
16026   return ret;
16027 }
16028
16029 static int
16030 api_netmap_create (vat_main_t * vam)
16031 {
16032   unformat_input_t *i = vam->input;
16033   vl_api_netmap_create_t *mp;
16034   u8 *if_name = 0;
16035   u8 hw_addr[6];
16036   u8 random_hw_addr = 1;
16037   u8 is_pipe = 0;
16038   u8 is_master = 0;
16039   int ret;
16040
16041   memset (hw_addr, 0, sizeof (hw_addr));
16042
16043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16044     {
16045       if (unformat (i, "name %s", &if_name))
16046         vec_add1 (if_name, 0);
16047       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
16048         random_hw_addr = 0;
16049       else if (unformat (i, "pipe"))
16050         is_pipe = 1;
16051       else if (unformat (i, "master"))
16052         is_master = 1;
16053       else if (unformat (i, "slave"))
16054         is_master = 0;
16055       else
16056         break;
16057     }
16058
16059   if (!vec_len (if_name))
16060     {
16061       errmsg ("interface name must be specified");
16062       return -99;
16063     }
16064
16065   if (vec_len (if_name) > 64)
16066     {
16067       errmsg ("interface name too long");
16068       return -99;
16069     }
16070
16071   M (NETMAP_CREATE, mp);
16072
16073   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16074   clib_memcpy (mp->hw_addr, hw_addr, 6);
16075   mp->use_random_hw_addr = random_hw_addr;
16076   mp->is_pipe = is_pipe;
16077   mp->is_master = is_master;
16078   vec_free (if_name);
16079
16080   S (mp);
16081   W (ret);
16082   return ret;
16083 }
16084
16085 static int
16086 api_netmap_delete (vat_main_t * vam)
16087 {
16088   unformat_input_t *i = vam->input;
16089   vl_api_netmap_delete_t *mp;
16090   u8 *if_name = 0;
16091   int ret;
16092
16093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16094     {
16095       if (unformat (i, "name %s", &if_name))
16096         vec_add1 (if_name, 0);
16097       else
16098         break;
16099     }
16100
16101   if (!vec_len (if_name))
16102     {
16103       errmsg ("interface name must be specified");
16104       return -99;
16105     }
16106
16107   if (vec_len (if_name) > 64)
16108     {
16109       errmsg ("interface name too long");
16110       return -99;
16111     }
16112
16113   M (NETMAP_DELETE, mp);
16114
16115   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
16116   vec_free (if_name);
16117
16118   S (mp);
16119   W (ret);
16120   return ret;
16121 }
16122
16123 static void vl_api_mpls_tunnel_details_t_handler
16124   (vl_api_mpls_tunnel_details_t * mp)
16125 {
16126   vat_main_t *vam = &vat_main;
16127   i32 len = mp->mt_next_hop_n_labels;
16128   i32 i;
16129
16130   print (vam->ofp, "[%d]: via %U %d labels ",
16131          mp->tunnel_index,
16132          format_ip4_address, mp->mt_next_hop,
16133          ntohl (mp->mt_next_hop_sw_if_index));
16134   for (i = 0; i < len; i++)
16135     {
16136       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
16137     }
16138   print (vam->ofp, "");
16139 }
16140
16141 static void vl_api_mpls_tunnel_details_t_handler_json
16142   (vl_api_mpls_tunnel_details_t * mp)
16143 {
16144   vat_main_t *vam = &vat_main;
16145   vat_json_node_t *node = NULL;
16146   struct in_addr ip4;
16147   i32 i;
16148   i32 len = mp->mt_next_hop_n_labels;
16149
16150   if (VAT_JSON_ARRAY != vam->json_tree.type)
16151     {
16152       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16153       vat_json_init_array (&vam->json_tree);
16154     }
16155   node = vat_json_array_add (&vam->json_tree);
16156
16157   vat_json_init_object (node);
16158   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
16159   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
16160   vat_json_object_add_ip4 (node, "next_hop", ip4);
16161   vat_json_object_add_uint (node, "next_hop_sw_if_index",
16162                             ntohl (mp->mt_next_hop_sw_if_index));
16163   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
16164   vat_json_object_add_uint (node, "label_count", len);
16165   for (i = 0; i < len; i++)
16166     {
16167       vat_json_object_add_uint (node, "label",
16168                                 ntohl (mp->mt_next_hop_out_labels[i]));
16169     }
16170 }
16171
16172 static int
16173 api_mpls_tunnel_dump (vat_main_t * vam)
16174 {
16175   vl_api_mpls_tunnel_dump_t *mp;
16176   vl_api_control_ping_t *mp_ping;
16177   i32 index = -1;
16178   int ret;
16179
16180   /* Parse args required to build the message */
16181   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
16182     {
16183       if (!unformat (vam->input, "tunnel_index %d", &index))
16184         {
16185           index = -1;
16186           break;
16187         }
16188     }
16189
16190   print (vam->ofp, "  tunnel_index %d", index);
16191
16192   M (MPLS_TUNNEL_DUMP, mp);
16193   mp->tunnel_index = htonl (index);
16194   S (mp);
16195
16196   /* Use a control ping for synchronization */
16197   M (CONTROL_PING, mp_ping);
16198   S (mp_ping);
16199
16200   W (ret);
16201   return ret;
16202 }
16203
16204 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
16205 #define vl_api_mpls_fib_details_t_print vl_noop_handler
16206
16207 static void
16208 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
16209 {
16210   vat_main_t *vam = &vat_main;
16211   int count = ntohl (mp->count);
16212   vl_api_fib_path2_t *fp;
16213   int i;
16214
16215   print (vam->ofp,
16216          "table-id %d, label %u, ess_bit %u",
16217          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
16218   fp = mp->path;
16219   for (i = 0; i < count; i++)
16220     {
16221       if (fp->afi == IP46_TYPE_IP6)
16222         print (vam->ofp,
16223                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16224                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16225                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16226                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16227                format_ip6_address, fp->next_hop);
16228       else if (fp->afi == IP46_TYPE_IP4)
16229         print (vam->ofp,
16230                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16231                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16232                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16233                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16234                format_ip4_address, fp->next_hop);
16235       fp++;
16236     }
16237 }
16238
16239 static void vl_api_mpls_fib_details_t_handler_json
16240   (vl_api_mpls_fib_details_t * mp)
16241 {
16242   vat_main_t *vam = &vat_main;
16243   int count = ntohl (mp->count);
16244   vat_json_node_t *node = NULL;
16245   struct in_addr ip4;
16246   struct in6_addr ip6;
16247   vl_api_fib_path2_t *fp;
16248   int i;
16249
16250   if (VAT_JSON_ARRAY != vam->json_tree.type)
16251     {
16252       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16253       vat_json_init_array (&vam->json_tree);
16254     }
16255   node = vat_json_array_add (&vam->json_tree);
16256
16257   vat_json_init_object (node);
16258   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16259   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
16260   vat_json_object_add_uint (node, "label", ntohl (mp->label));
16261   vat_json_object_add_uint (node, "path_count", count);
16262   fp = mp->path;
16263   for (i = 0; i < count; i++)
16264     {
16265       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16266       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16267       vat_json_object_add_uint (node, "is_local", fp->is_local);
16268       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16269       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16270       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16271       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16272       if (fp->afi == IP46_TYPE_IP4)
16273         {
16274           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16275           vat_json_object_add_ip4 (node, "next_hop", ip4);
16276         }
16277       else if (fp->afi == IP46_TYPE_IP6)
16278         {
16279           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16280           vat_json_object_add_ip6 (node, "next_hop", ip6);
16281         }
16282     }
16283 }
16284
16285 static int
16286 api_mpls_fib_dump (vat_main_t * vam)
16287 {
16288   vl_api_mpls_fib_dump_t *mp;
16289   vl_api_control_ping_t *mp_ping;
16290   int ret;
16291
16292   M (MPLS_FIB_DUMP, mp);
16293   S (mp);
16294
16295   /* Use a control ping for synchronization */
16296   M (CONTROL_PING, mp_ping);
16297   S (mp_ping);
16298
16299   W (ret);
16300   return ret;
16301 }
16302
16303 #define vl_api_ip_fib_details_t_endian vl_noop_handler
16304 #define vl_api_ip_fib_details_t_print vl_noop_handler
16305
16306 static void
16307 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
16308 {
16309   vat_main_t *vam = &vat_main;
16310   int count = ntohl (mp->count);
16311   vl_api_fib_path_t *fp;
16312   int i;
16313
16314   print (vam->ofp,
16315          "table-id %d, prefix %U/%d",
16316          ntohl (mp->table_id), format_ip4_address, mp->address,
16317          mp->address_length);
16318   fp = mp->path;
16319   for (i = 0; i < count; i++)
16320     {
16321       if (fp->afi == IP46_TYPE_IP6)
16322         print (vam->ofp,
16323                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16324                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16325                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16326                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16327                format_ip6_address, fp->next_hop);
16328       else if (fp->afi == IP46_TYPE_IP4)
16329         print (vam->ofp,
16330                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16331                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16332                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16333                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16334                format_ip4_address, fp->next_hop);
16335       fp++;
16336     }
16337 }
16338
16339 static void vl_api_ip_fib_details_t_handler_json
16340   (vl_api_ip_fib_details_t * mp)
16341 {
16342   vat_main_t *vam = &vat_main;
16343   int count = ntohl (mp->count);
16344   vat_json_node_t *node = NULL;
16345   struct in_addr ip4;
16346   struct in6_addr ip6;
16347   vl_api_fib_path_t *fp;
16348   int i;
16349
16350   if (VAT_JSON_ARRAY != vam->json_tree.type)
16351     {
16352       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16353       vat_json_init_array (&vam->json_tree);
16354     }
16355   node = vat_json_array_add (&vam->json_tree);
16356
16357   vat_json_init_object (node);
16358   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16359   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
16360   vat_json_object_add_ip4 (node, "prefix", ip4);
16361   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16362   vat_json_object_add_uint (node, "path_count", count);
16363   fp = mp->path;
16364   for (i = 0; i < count; i++)
16365     {
16366       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16367       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16368       vat_json_object_add_uint (node, "is_local", fp->is_local);
16369       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16370       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16371       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16372       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16373       if (fp->afi == IP46_TYPE_IP4)
16374         {
16375           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16376           vat_json_object_add_ip4 (node, "next_hop", ip4);
16377         }
16378       else if (fp->afi == IP46_TYPE_IP6)
16379         {
16380           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16381           vat_json_object_add_ip6 (node, "next_hop", ip6);
16382         }
16383     }
16384 }
16385
16386 static int
16387 api_ip_fib_dump (vat_main_t * vam)
16388 {
16389   vl_api_ip_fib_dump_t *mp;
16390   vl_api_control_ping_t *mp_ping;
16391   int ret;
16392
16393   M (IP_FIB_DUMP, mp);
16394   S (mp);
16395
16396   /* Use a control ping for synchronization */
16397   M (CONTROL_PING, mp_ping);
16398   S (mp_ping);
16399
16400   W (ret);
16401   return ret;
16402 }
16403
16404 static int
16405 api_ip_mfib_dump (vat_main_t * vam)
16406 {
16407   vl_api_ip_mfib_dump_t *mp;
16408   vl_api_control_ping_t *mp_ping;
16409   int ret;
16410
16411   M (IP_MFIB_DUMP, mp);
16412   S (mp);
16413
16414   /* Use a control ping for synchronization */
16415   M (CONTROL_PING, mp_ping);
16416   S (mp_ping);
16417
16418   W (ret);
16419   return ret;
16420 }
16421
16422 static void vl_api_ip_neighbor_details_t_handler
16423   (vl_api_ip_neighbor_details_t * mp)
16424 {
16425   vat_main_t *vam = &vat_main;
16426
16427   print (vam->ofp, "%c %U %U",
16428          (mp->is_static) ? 'S' : 'D',
16429          format_ethernet_address, &mp->mac_address,
16430          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
16431          &mp->ip_address);
16432 }
16433
16434 static void vl_api_ip_neighbor_details_t_handler_json
16435   (vl_api_ip_neighbor_details_t * mp)
16436 {
16437
16438   vat_main_t *vam = &vat_main;
16439   vat_json_node_t *node;
16440   struct in_addr ip4;
16441   struct in6_addr ip6;
16442
16443   if (VAT_JSON_ARRAY != vam->json_tree.type)
16444     {
16445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16446       vat_json_init_array (&vam->json_tree);
16447     }
16448   node = vat_json_array_add (&vam->json_tree);
16449
16450   vat_json_init_object (node);
16451   vat_json_object_add_string_copy (node, "flag",
16452                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
16453                                    "dynamic");
16454
16455   vat_json_object_add_string_copy (node, "link_layer",
16456                                    format (0, "%U", format_ethernet_address,
16457                                            &mp->mac_address));
16458
16459   if (mp->is_ipv6)
16460     {
16461       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
16462       vat_json_object_add_ip6 (node, "ip_address", ip6);
16463     }
16464   else
16465     {
16466       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
16467       vat_json_object_add_ip4 (node, "ip_address", ip4);
16468     }
16469 }
16470
16471 static int
16472 api_ip_neighbor_dump (vat_main_t * vam)
16473 {
16474   unformat_input_t *i = vam->input;
16475   vl_api_ip_neighbor_dump_t *mp;
16476   vl_api_control_ping_t *mp_ping;
16477   u8 is_ipv6 = 0;
16478   u32 sw_if_index = ~0;
16479   int ret;
16480
16481   /* Parse args required to build the message */
16482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16483     {
16484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16485         ;
16486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16487         ;
16488       else if (unformat (i, "ip6"))
16489         is_ipv6 = 1;
16490       else
16491         break;
16492     }
16493
16494   if (sw_if_index == ~0)
16495     {
16496       errmsg ("missing interface name or sw_if_index");
16497       return -99;
16498     }
16499
16500   M (IP_NEIGHBOR_DUMP, mp);
16501   mp->is_ipv6 = (u8) is_ipv6;
16502   mp->sw_if_index = ntohl (sw_if_index);
16503   S (mp);
16504
16505   /* Use a control ping for synchronization */
16506   M (CONTROL_PING, mp_ping);
16507   S (mp_ping);
16508
16509   W (ret);
16510   return ret;
16511 }
16512
16513 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
16514 #define vl_api_ip6_fib_details_t_print vl_noop_handler
16515
16516 static void
16517 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
16518 {
16519   vat_main_t *vam = &vat_main;
16520   int count = ntohl (mp->count);
16521   vl_api_fib_path_t *fp;
16522   int i;
16523
16524   print (vam->ofp,
16525          "table-id %d, prefix %U/%d",
16526          ntohl (mp->table_id), format_ip6_address, mp->address,
16527          mp->address_length);
16528   fp = mp->path;
16529   for (i = 0; i < count; i++)
16530     {
16531       if (fp->afi == IP46_TYPE_IP6)
16532         print (vam->ofp,
16533                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16534                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16535                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16536                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16537                format_ip6_address, fp->next_hop);
16538       else if (fp->afi == IP46_TYPE_IP4)
16539         print (vam->ofp,
16540                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
16541                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
16542                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
16543                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
16544                format_ip4_address, fp->next_hop);
16545       fp++;
16546     }
16547 }
16548
16549 static void vl_api_ip6_fib_details_t_handler_json
16550   (vl_api_ip6_fib_details_t * mp)
16551 {
16552   vat_main_t *vam = &vat_main;
16553   int count = ntohl (mp->count);
16554   vat_json_node_t *node = NULL;
16555   struct in_addr ip4;
16556   struct in6_addr ip6;
16557   vl_api_fib_path_t *fp;
16558   int i;
16559
16560   if (VAT_JSON_ARRAY != vam->json_tree.type)
16561     {
16562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16563       vat_json_init_array (&vam->json_tree);
16564     }
16565   node = vat_json_array_add (&vam->json_tree);
16566
16567   vat_json_init_object (node);
16568   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
16569   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
16570   vat_json_object_add_ip6 (node, "prefix", ip6);
16571   vat_json_object_add_uint (node, "mask_length", mp->address_length);
16572   vat_json_object_add_uint (node, "path_count", count);
16573   fp = mp->path;
16574   for (i = 0; i < count; i++)
16575     {
16576       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
16577       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
16578       vat_json_object_add_uint (node, "is_local", fp->is_local);
16579       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
16580       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
16581       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
16582       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
16583       if (fp->afi == IP46_TYPE_IP4)
16584         {
16585           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
16586           vat_json_object_add_ip4 (node, "next_hop", ip4);
16587         }
16588       else if (fp->afi == IP46_TYPE_IP6)
16589         {
16590           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
16591           vat_json_object_add_ip6 (node, "next_hop", ip6);
16592         }
16593     }
16594 }
16595
16596 static int
16597 api_ip6_fib_dump (vat_main_t * vam)
16598 {
16599   vl_api_ip6_fib_dump_t *mp;
16600   vl_api_control_ping_t *mp_ping;
16601   int ret;
16602
16603   M (IP6_FIB_DUMP, mp);
16604   S (mp);
16605
16606   /* Use a control ping for synchronization */
16607   M (CONTROL_PING, mp_ping);
16608   S (mp_ping);
16609
16610   W (ret);
16611   return ret;
16612 }
16613
16614 static int
16615 api_ip6_mfib_dump (vat_main_t * vam)
16616 {
16617   vl_api_ip6_mfib_dump_t *mp;
16618   vl_api_control_ping_t *mp_ping;
16619   int ret;
16620
16621   M (IP6_MFIB_DUMP, mp);
16622   S (mp);
16623
16624   /* Use a control ping for synchronization */
16625   M (CONTROL_PING, mp_ping);
16626   S (mp_ping);
16627
16628   W (ret);
16629   return ret;
16630 }
16631
16632 int
16633 api_classify_table_ids (vat_main_t * vam)
16634 {
16635   vl_api_classify_table_ids_t *mp;
16636   int ret;
16637
16638   /* Construct the API message */
16639   M (CLASSIFY_TABLE_IDS, mp);
16640   mp->context = 0;
16641
16642   S (mp);
16643   W (ret);
16644   return ret;
16645 }
16646
16647 int
16648 api_classify_table_by_interface (vat_main_t * vam)
16649 {
16650   unformat_input_t *input = vam->input;
16651   vl_api_classify_table_by_interface_t *mp;
16652
16653   u32 sw_if_index = ~0;
16654   int ret;
16655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16656     {
16657       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16658         ;
16659       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16660         ;
16661       else
16662         break;
16663     }
16664   if (sw_if_index == ~0)
16665     {
16666       errmsg ("missing interface name or sw_if_index");
16667       return -99;
16668     }
16669
16670   /* Construct the API message */
16671   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
16672   mp->context = 0;
16673   mp->sw_if_index = ntohl (sw_if_index);
16674
16675   S (mp);
16676   W (ret);
16677   return ret;
16678 }
16679
16680 int
16681 api_classify_table_info (vat_main_t * vam)
16682 {
16683   unformat_input_t *input = vam->input;
16684   vl_api_classify_table_info_t *mp;
16685
16686   u32 table_id = ~0;
16687   int ret;
16688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16689     {
16690       if (unformat (input, "table_id %d", &table_id))
16691         ;
16692       else
16693         break;
16694     }
16695   if (table_id == ~0)
16696     {
16697       errmsg ("missing table id");
16698       return -99;
16699     }
16700
16701   /* Construct the API message */
16702   M (CLASSIFY_TABLE_INFO, mp);
16703   mp->context = 0;
16704   mp->table_id = ntohl (table_id);
16705
16706   S (mp);
16707   W (ret);
16708   return ret;
16709 }
16710
16711 int
16712 api_classify_session_dump (vat_main_t * vam)
16713 {
16714   unformat_input_t *input = vam->input;
16715   vl_api_classify_session_dump_t *mp;
16716   vl_api_control_ping_t *mp_ping;
16717
16718   u32 table_id = ~0;
16719   int ret;
16720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16721     {
16722       if (unformat (input, "table_id %d", &table_id))
16723         ;
16724       else
16725         break;
16726     }
16727   if (table_id == ~0)
16728     {
16729       errmsg ("missing table id");
16730       return -99;
16731     }
16732
16733   /* Construct the API message */
16734   M (CLASSIFY_SESSION_DUMP, mp);
16735   mp->context = 0;
16736   mp->table_id = ntohl (table_id);
16737   S (mp);
16738
16739   /* Use a control ping for synchronization */
16740   M (CONTROL_PING, mp_ping);
16741   S (mp_ping);
16742
16743   W (ret);
16744   return ret;
16745 }
16746
16747 static void
16748 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
16749 {
16750   vat_main_t *vam = &vat_main;
16751
16752   print (vam->ofp, "collector_address %U, collector_port %d, "
16753          "src_address %U, vrf_id %d, path_mtu %u, "
16754          "template_interval %u, udp_checksum %d",
16755          format_ip4_address, mp->collector_address,
16756          ntohs (mp->collector_port),
16757          format_ip4_address, mp->src_address,
16758          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
16759          ntohl (mp->template_interval), mp->udp_checksum);
16760
16761   vam->retval = 0;
16762   vam->result_ready = 1;
16763 }
16764
16765 static void
16766   vl_api_ipfix_exporter_details_t_handler_json
16767   (vl_api_ipfix_exporter_details_t * mp)
16768 {
16769   vat_main_t *vam = &vat_main;
16770   vat_json_node_t node;
16771   struct in_addr collector_address;
16772   struct in_addr src_address;
16773
16774   vat_json_init_object (&node);
16775   clib_memcpy (&collector_address, &mp->collector_address,
16776                sizeof (collector_address));
16777   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
16778   vat_json_object_add_uint (&node, "collector_port",
16779                             ntohs (mp->collector_port));
16780   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
16781   vat_json_object_add_ip4 (&node, "src_address", src_address);
16782   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
16783   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
16784   vat_json_object_add_uint (&node, "template_interval",
16785                             ntohl (mp->template_interval));
16786   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
16787
16788   vat_json_print (vam->ofp, &node);
16789   vat_json_free (&node);
16790   vam->retval = 0;
16791   vam->result_ready = 1;
16792 }
16793
16794 int
16795 api_ipfix_exporter_dump (vat_main_t * vam)
16796 {
16797   vl_api_ipfix_exporter_dump_t *mp;
16798   int ret;
16799
16800   /* Construct the API message */
16801   M (IPFIX_EXPORTER_DUMP, mp);
16802   mp->context = 0;
16803
16804   S (mp);
16805   W (ret);
16806   return ret;
16807 }
16808
16809 static int
16810 api_ipfix_classify_stream_dump (vat_main_t * vam)
16811 {
16812   vl_api_ipfix_classify_stream_dump_t *mp;
16813   int ret;
16814
16815   /* Construct the API message */
16816   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
16817   mp->context = 0;
16818
16819   S (mp);
16820   W (ret);
16821   return ret;
16822   /* NOTREACHED */
16823   return 0;
16824 }
16825
16826 static void
16827   vl_api_ipfix_classify_stream_details_t_handler
16828   (vl_api_ipfix_classify_stream_details_t * mp)
16829 {
16830   vat_main_t *vam = &vat_main;
16831   print (vam->ofp, "domain_id %d, src_port %d",
16832          ntohl (mp->domain_id), ntohs (mp->src_port));
16833   vam->retval = 0;
16834   vam->result_ready = 1;
16835 }
16836
16837 static void
16838   vl_api_ipfix_classify_stream_details_t_handler_json
16839   (vl_api_ipfix_classify_stream_details_t * mp)
16840 {
16841   vat_main_t *vam = &vat_main;
16842   vat_json_node_t node;
16843
16844   vat_json_init_object (&node);
16845   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
16846   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
16847
16848   vat_json_print (vam->ofp, &node);
16849   vat_json_free (&node);
16850   vam->retval = 0;
16851   vam->result_ready = 1;
16852 }
16853
16854 static int
16855 api_ipfix_classify_table_dump (vat_main_t * vam)
16856 {
16857   vl_api_ipfix_classify_table_dump_t *mp;
16858   vl_api_control_ping_t *mp_ping;
16859   int ret;
16860
16861   if (!vam->json_output)
16862     {
16863       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
16864              "transport_protocol");
16865     }
16866
16867   /* Construct the API message */
16868   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
16869
16870   /* send it... */
16871   S (mp);
16872
16873   /* Use a control ping for synchronization */
16874   M (CONTROL_PING, mp_ping);
16875   S (mp_ping);
16876
16877   W (ret);
16878   return ret;
16879 }
16880
16881 static void
16882   vl_api_ipfix_classify_table_details_t_handler
16883   (vl_api_ipfix_classify_table_details_t * mp)
16884 {
16885   vat_main_t *vam = &vat_main;
16886   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16887          mp->transport_protocol);
16888 }
16889
16890 static void
16891   vl_api_ipfix_classify_table_details_t_handler_json
16892   (vl_api_ipfix_classify_table_details_t * mp)
16893 {
16894   vat_json_node_t *node = NULL;
16895   vat_main_t *vam = &vat_main;
16896
16897   if (VAT_JSON_ARRAY != vam->json_tree.type)
16898     {
16899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16900       vat_json_init_array (&vam->json_tree);
16901     }
16902
16903   node = vat_json_array_add (&vam->json_tree);
16904   vat_json_init_object (node);
16905
16906   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16907   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16908   vat_json_object_add_uint (node, "transport_protocol",
16909                             mp->transport_protocol);
16910 }
16911
16912 static int
16913 api_sw_interface_span_enable_disable (vat_main_t * vam)
16914 {
16915   unformat_input_t *i = vam->input;
16916   vl_api_sw_interface_span_enable_disable_t *mp;
16917   u32 src_sw_if_index = ~0;
16918   u32 dst_sw_if_index = ~0;
16919   u8 state = 3;
16920   int ret;
16921
16922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16923     {
16924       if (unformat
16925           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16926         ;
16927       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16928         ;
16929       else
16930         if (unformat
16931             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16932         ;
16933       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16934         ;
16935       else if (unformat (i, "disable"))
16936         state = 0;
16937       else if (unformat (i, "rx"))
16938         state = 1;
16939       else if (unformat (i, "tx"))
16940         state = 2;
16941       else if (unformat (i, "both"))
16942         state = 3;
16943       else
16944         break;
16945     }
16946
16947   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
16948
16949   mp->sw_if_index_from = htonl (src_sw_if_index);
16950   mp->sw_if_index_to = htonl (dst_sw_if_index);
16951   mp->state = state;
16952
16953   S (mp);
16954   W (ret);
16955   return ret;
16956 }
16957
16958 static void
16959 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16960                                             * mp)
16961 {
16962   vat_main_t *vam = &vat_main;
16963   u8 *sw_if_from_name = 0;
16964   u8 *sw_if_to_name = 0;
16965   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16966   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16967   char *states[] = { "none", "rx", "tx", "both" };
16968   hash_pair_t *p;
16969
16970   /* *INDENT-OFF* */
16971   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16972   ({
16973     if ((u32) p->value[0] == sw_if_index_from)
16974       {
16975         sw_if_from_name = (u8 *)(p->key);
16976         if (sw_if_to_name)
16977           break;
16978       }
16979     if ((u32) p->value[0] == sw_if_index_to)
16980       {
16981         sw_if_to_name = (u8 *)(p->key);
16982         if (sw_if_from_name)
16983           break;
16984       }
16985   }));
16986   /* *INDENT-ON* */
16987   print (vam->ofp, "%20s => %20s (%s)",
16988          sw_if_from_name, sw_if_to_name, states[mp->state]);
16989 }
16990
16991 static void
16992   vl_api_sw_interface_span_details_t_handler_json
16993   (vl_api_sw_interface_span_details_t * mp)
16994 {
16995   vat_main_t *vam = &vat_main;
16996   vat_json_node_t *node = NULL;
16997   u8 *sw_if_from_name = 0;
16998   u8 *sw_if_to_name = 0;
16999   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
17000   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
17001   hash_pair_t *p;
17002
17003   /* *INDENT-OFF* */
17004   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
17005   ({
17006     if ((u32) p->value[0] == sw_if_index_from)
17007       {
17008         sw_if_from_name = (u8 *)(p->key);
17009         if (sw_if_to_name)
17010           break;
17011       }
17012     if ((u32) p->value[0] == sw_if_index_to)
17013       {
17014         sw_if_to_name = (u8 *)(p->key);
17015         if (sw_if_from_name)
17016           break;
17017       }
17018   }));
17019   /* *INDENT-ON* */
17020
17021   if (VAT_JSON_ARRAY != vam->json_tree.type)
17022     {
17023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17024       vat_json_init_array (&vam->json_tree);
17025     }
17026   node = vat_json_array_add (&vam->json_tree);
17027
17028   vat_json_init_object (node);
17029   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
17030   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
17031   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
17032   if (0 != sw_if_to_name)
17033     {
17034       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
17035     }
17036   vat_json_object_add_uint (node, "state", mp->state);
17037 }
17038
17039 static int
17040 api_sw_interface_span_dump (vat_main_t * vam)
17041 {
17042   vl_api_sw_interface_span_dump_t *mp;
17043   vl_api_control_ping_t *mp_ping;
17044   int ret;
17045
17046   M (SW_INTERFACE_SPAN_DUMP, mp);
17047   S (mp);
17048
17049   /* Use a control ping for synchronization */
17050   M (CONTROL_PING, mp_ping);
17051   S (mp_ping);
17052
17053   W (ret);
17054   return ret;
17055 }
17056
17057 int
17058 api_pg_create_interface (vat_main_t * vam)
17059 {
17060   unformat_input_t *input = vam->input;
17061   vl_api_pg_create_interface_t *mp;
17062
17063   u32 if_id = ~0;
17064   int ret;
17065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17066     {
17067       if (unformat (input, "if_id %d", &if_id))
17068         ;
17069       else
17070         break;
17071     }
17072   if (if_id == ~0)
17073     {
17074       errmsg ("missing pg interface index");
17075       return -99;
17076     }
17077
17078   /* Construct the API message */
17079   M (PG_CREATE_INTERFACE, mp);
17080   mp->context = 0;
17081   mp->interface_id = ntohl (if_id);
17082
17083   S (mp);
17084   W (ret);
17085   return ret;
17086 }
17087
17088 int
17089 api_pg_capture (vat_main_t * vam)
17090 {
17091   unformat_input_t *input = vam->input;
17092   vl_api_pg_capture_t *mp;
17093
17094   u32 if_id = ~0;
17095   u8 enable = 1;
17096   u32 count = 1;
17097   u8 pcap_file_set = 0;
17098   u8 *pcap_file = 0;
17099   int ret;
17100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17101     {
17102       if (unformat (input, "if_id %d", &if_id))
17103         ;
17104       else if (unformat (input, "pcap %s", &pcap_file))
17105         pcap_file_set = 1;
17106       else if (unformat (input, "count %d", &count))
17107         ;
17108       else if (unformat (input, "disable"))
17109         enable = 0;
17110       else
17111         break;
17112     }
17113   if (if_id == ~0)
17114     {
17115       errmsg ("missing pg interface index");
17116       return -99;
17117     }
17118   if (pcap_file_set > 0)
17119     {
17120       if (vec_len (pcap_file) > 255)
17121         {
17122           errmsg ("pcap file name is too long");
17123           return -99;
17124         }
17125     }
17126
17127   u32 name_len = vec_len (pcap_file);
17128   /* Construct the API message */
17129   M (PG_CAPTURE, mp);
17130   mp->context = 0;
17131   mp->interface_id = ntohl (if_id);
17132   mp->is_enabled = enable;
17133   mp->count = ntohl (count);
17134   mp->pcap_name_length = ntohl (name_len);
17135   if (pcap_file_set != 0)
17136     {
17137       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
17138     }
17139   vec_free (pcap_file);
17140
17141   S (mp);
17142   W (ret);
17143   return ret;
17144 }
17145
17146 int
17147 api_pg_enable_disable (vat_main_t * vam)
17148 {
17149   unformat_input_t *input = vam->input;
17150   vl_api_pg_enable_disable_t *mp;
17151
17152   u8 enable = 1;
17153   u8 stream_name_set = 0;
17154   u8 *stream_name = 0;
17155   int ret;
17156   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17157     {
17158       if (unformat (input, "stream %s", &stream_name))
17159         stream_name_set = 1;
17160       else if (unformat (input, "disable"))
17161         enable = 0;
17162       else
17163         break;
17164     }
17165
17166   if (stream_name_set > 0)
17167     {
17168       if (vec_len (stream_name) > 255)
17169         {
17170           errmsg ("stream name too long");
17171           return -99;
17172         }
17173     }
17174
17175   u32 name_len = vec_len (stream_name);
17176   /* Construct the API message */
17177   M (PG_ENABLE_DISABLE, mp);
17178   mp->context = 0;
17179   mp->is_enabled = enable;
17180   if (stream_name_set != 0)
17181     {
17182       mp->stream_name_length = ntohl (name_len);
17183       clib_memcpy (mp->stream_name, stream_name, name_len);
17184     }
17185   vec_free (stream_name);
17186
17187   S (mp);
17188   W (ret);
17189   return ret;
17190 }
17191
17192 int
17193 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
17194 {
17195   unformat_input_t *input = vam->input;
17196   vl_api_ip_source_and_port_range_check_add_del_t *mp;
17197
17198   u16 *low_ports = 0;
17199   u16 *high_ports = 0;
17200   u16 this_low;
17201   u16 this_hi;
17202   ip4_address_t ip4_addr;
17203   ip6_address_t ip6_addr;
17204   u32 length;
17205   u32 tmp, tmp2;
17206   u8 prefix_set = 0;
17207   u32 vrf_id = ~0;
17208   u8 is_add = 1;
17209   u8 is_ipv6 = 0;
17210   int ret;
17211
17212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17213     {
17214       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
17215         {
17216           prefix_set = 1;
17217         }
17218       else
17219         if (unformat
17220             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
17221         {
17222           prefix_set = 1;
17223           is_ipv6 = 1;
17224         }
17225       else if (unformat (input, "vrf %d", &vrf_id))
17226         ;
17227       else if (unformat (input, "del"))
17228         is_add = 0;
17229       else if (unformat (input, "port %d", &tmp))
17230         {
17231           if (tmp == 0 || tmp > 65535)
17232             {
17233               errmsg ("port %d out of range", tmp);
17234               return -99;
17235             }
17236           this_low = tmp;
17237           this_hi = this_low + 1;
17238           vec_add1 (low_ports, this_low);
17239           vec_add1 (high_ports, this_hi);
17240         }
17241       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
17242         {
17243           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
17244             {
17245               errmsg ("incorrect range parameters");
17246               return -99;
17247             }
17248           this_low = tmp;
17249           /* Note: in debug CLI +1 is added to high before
17250              passing to real fn that does "the work"
17251              (ip_source_and_port_range_check_add_del).
17252              This fn is a wrapper around the binary API fn a
17253              control plane will call, which expects this increment
17254              to have occurred. Hence letting the binary API control
17255              plane fn do the increment for consistency between VAT
17256              and other control planes.
17257            */
17258           this_hi = tmp2;
17259           vec_add1 (low_ports, this_low);
17260           vec_add1 (high_ports, this_hi);
17261         }
17262       else
17263         break;
17264     }
17265
17266   if (prefix_set == 0)
17267     {
17268       errmsg ("<address>/<mask> not specified");
17269       return -99;
17270     }
17271
17272   if (vrf_id == ~0)
17273     {
17274       errmsg ("VRF ID required, not specified");
17275       return -99;
17276     }
17277
17278   if (vrf_id == 0)
17279     {
17280       errmsg
17281         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17282       return -99;
17283     }
17284
17285   if (vec_len (low_ports) == 0)
17286     {
17287       errmsg ("At least one port or port range required");
17288       return -99;
17289     }
17290
17291   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
17292
17293   mp->is_add = is_add;
17294
17295   if (is_ipv6)
17296     {
17297       mp->is_ipv6 = 1;
17298       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
17299     }
17300   else
17301     {
17302       mp->is_ipv6 = 0;
17303       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
17304     }
17305
17306   mp->mask_length = length;
17307   mp->number_of_ranges = vec_len (low_ports);
17308
17309   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
17310   vec_free (low_ports);
17311
17312   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
17313   vec_free (high_ports);
17314
17315   mp->vrf_id = ntohl (vrf_id);
17316
17317   S (mp);
17318   W (ret);
17319   return ret;
17320 }
17321
17322 int
17323 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
17324 {
17325   unformat_input_t *input = vam->input;
17326   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
17327   u32 sw_if_index = ~0;
17328   int vrf_set = 0;
17329   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
17330   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
17331   u8 is_add = 1;
17332   int ret;
17333
17334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17335     {
17336       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17337         ;
17338       else if (unformat (input, "sw_if_index %d", &sw_if_index))
17339         ;
17340       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
17341         vrf_set = 1;
17342       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
17343         vrf_set = 1;
17344       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
17345         vrf_set = 1;
17346       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
17347         vrf_set = 1;
17348       else if (unformat (input, "del"))
17349         is_add = 0;
17350       else
17351         break;
17352     }
17353
17354   if (sw_if_index == ~0)
17355     {
17356       errmsg ("Interface required but not specified");
17357       return -99;
17358     }
17359
17360   if (vrf_set == 0)
17361     {
17362       errmsg ("VRF ID required but not specified");
17363       return -99;
17364     }
17365
17366   if (tcp_out_vrf_id == 0
17367       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
17368     {
17369       errmsg
17370         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
17371       return -99;
17372     }
17373
17374   /* Construct the API message */
17375   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
17376
17377   mp->sw_if_index = ntohl (sw_if_index);
17378   mp->is_add = is_add;
17379   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
17380   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
17381   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
17382   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
17383
17384   /* send it... */
17385   S (mp);
17386
17387   /* Wait for a reply... */
17388   W (ret);
17389   return ret;
17390 }
17391
17392 static int
17393 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
17394 {
17395   unformat_input_t *i = vam->input;
17396   vl_api_ipsec_gre_add_del_tunnel_t *mp;
17397   u32 local_sa_id = 0;
17398   u32 remote_sa_id = 0;
17399   ip4_address_t src_address;
17400   ip4_address_t dst_address;
17401   u8 is_add = 1;
17402   int ret;
17403
17404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17405     {
17406       if (unformat (i, "local_sa %d", &local_sa_id))
17407         ;
17408       else if (unformat (i, "remote_sa %d", &remote_sa_id))
17409         ;
17410       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
17411         ;
17412       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
17413         ;
17414       else if (unformat (i, "del"))
17415         is_add = 0;
17416       else
17417         {
17418           clib_warning ("parse error '%U'", format_unformat_error, i);
17419           return -99;
17420         }
17421     }
17422
17423   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
17424
17425   mp->local_sa_id = ntohl (local_sa_id);
17426   mp->remote_sa_id = ntohl (remote_sa_id);
17427   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
17428   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
17429   mp->is_add = is_add;
17430
17431   S (mp);
17432   W (ret);
17433   return ret;
17434 }
17435
17436 static int
17437 api_punt (vat_main_t * vam)
17438 {
17439   unformat_input_t *i = vam->input;
17440   vl_api_punt_t *mp;
17441   u32 ipv = ~0;
17442   u32 protocol = ~0;
17443   u32 port = ~0;
17444   int is_add = 1;
17445   int ret;
17446
17447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17448     {
17449       if (unformat (i, "ip %d", &ipv))
17450         ;
17451       else if (unformat (i, "protocol %d", &protocol))
17452         ;
17453       else if (unformat (i, "port %d", &port))
17454         ;
17455       else if (unformat (i, "del"))
17456         is_add = 0;
17457       else
17458         {
17459           clib_warning ("parse error '%U'", format_unformat_error, i);
17460           return -99;
17461         }
17462     }
17463
17464   M (PUNT, mp);
17465
17466   mp->is_add = (u8) is_add;
17467   mp->ipv = (u8) ipv;
17468   mp->l4_protocol = (u8) protocol;
17469   mp->l4_port = htons ((u16) port);
17470
17471   S (mp);
17472   W (ret);
17473   return ret;
17474 }
17475
17476 static void vl_api_ipsec_gre_tunnel_details_t_handler
17477   (vl_api_ipsec_gre_tunnel_details_t * mp)
17478 {
17479   vat_main_t *vam = &vat_main;
17480
17481   print (vam->ofp, "%11d%15U%15U%14d%14d",
17482          ntohl (mp->sw_if_index),
17483          format_ip4_address, &mp->src_address,
17484          format_ip4_address, &mp->dst_address,
17485          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
17486 }
17487
17488 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
17489   (vl_api_ipsec_gre_tunnel_details_t * mp)
17490 {
17491   vat_main_t *vam = &vat_main;
17492   vat_json_node_t *node = NULL;
17493   struct in_addr ip4;
17494
17495   if (VAT_JSON_ARRAY != vam->json_tree.type)
17496     {
17497       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17498       vat_json_init_array (&vam->json_tree);
17499     }
17500   node = vat_json_array_add (&vam->json_tree);
17501
17502   vat_json_init_object (node);
17503   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17504   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
17505   vat_json_object_add_ip4 (node, "src_address", ip4);
17506   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
17507   vat_json_object_add_ip4 (node, "dst_address", ip4);
17508   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
17509   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
17510 }
17511
17512 static int
17513 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
17514 {
17515   unformat_input_t *i = vam->input;
17516   vl_api_ipsec_gre_tunnel_dump_t *mp;
17517   vl_api_control_ping_t *mp_ping;
17518   u32 sw_if_index;
17519   u8 sw_if_index_set = 0;
17520   int ret;
17521
17522   /* Parse args required to build the message */
17523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17524     {
17525       if (unformat (i, "sw_if_index %d", &sw_if_index))
17526         sw_if_index_set = 1;
17527       else
17528         break;
17529     }
17530
17531   if (sw_if_index_set == 0)
17532     {
17533       sw_if_index = ~0;
17534     }
17535
17536   if (!vam->json_output)
17537     {
17538       print (vam->ofp, "%11s%15s%15s%14s%14s",
17539              "sw_if_index", "src_address", "dst_address",
17540              "local_sa_id", "remote_sa_id");
17541     }
17542
17543   /* Get list of gre-tunnel interfaces */
17544   M (IPSEC_GRE_TUNNEL_DUMP, mp);
17545
17546   mp->sw_if_index = htonl (sw_if_index);
17547
17548   S (mp);
17549
17550   /* Use a control ping for synchronization */
17551   M (CONTROL_PING, mp_ping);
17552   S (mp_ping);
17553
17554   W (ret);
17555   return ret;
17556 }
17557
17558 static int
17559 api_delete_subif (vat_main_t * vam)
17560 {
17561   unformat_input_t *i = vam->input;
17562   vl_api_delete_subif_t *mp;
17563   u32 sw_if_index = ~0;
17564   int ret;
17565
17566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17567     {
17568       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17569         ;
17570       if (unformat (i, "sw_if_index %d", &sw_if_index))
17571         ;
17572       else
17573         break;
17574     }
17575
17576   if (sw_if_index == ~0)
17577     {
17578       errmsg ("missing sw_if_index");
17579       return -99;
17580     }
17581
17582   /* Construct the API message */
17583   M (DELETE_SUBIF, mp);
17584   mp->sw_if_index = ntohl (sw_if_index);
17585
17586   S (mp);
17587   W (ret);
17588   return ret;
17589 }
17590
17591 #define foreach_pbb_vtr_op      \
17592 _("disable",  L2_VTR_DISABLED)  \
17593 _("pop",  L2_VTR_POP_2)         \
17594 _("push",  L2_VTR_PUSH_2)
17595
17596 static int
17597 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
17598 {
17599   unformat_input_t *i = vam->input;
17600   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
17601   u32 sw_if_index = ~0, vtr_op = ~0;
17602   u16 outer_tag = ~0;
17603   u8 dmac[6], smac[6];
17604   u8 dmac_set = 0, smac_set = 0;
17605   u16 vlanid = 0;
17606   u32 sid = ~0;
17607   u32 tmp;
17608   int ret;
17609
17610   /* Shut up coverity */
17611   memset (dmac, 0, sizeof (dmac));
17612   memset (smac, 0, sizeof (smac));
17613
17614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17615     {
17616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17617         ;
17618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17619         ;
17620       else if (unformat (i, "vtr_op %d", &vtr_op))
17621         ;
17622 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
17623       foreach_pbb_vtr_op
17624 #undef _
17625         else if (unformat (i, "translate_pbb_stag"))
17626         {
17627           if (unformat (i, "%d", &tmp))
17628             {
17629               vtr_op = L2_VTR_TRANSLATE_2_1;
17630               outer_tag = tmp;
17631             }
17632           else
17633             {
17634               errmsg
17635                 ("translate_pbb_stag operation requires outer tag definition");
17636               return -99;
17637             }
17638         }
17639       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
17640         dmac_set++;
17641       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
17642         smac_set++;
17643       else if (unformat (i, "sid %d", &sid))
17644         ;
17645       else if (unformat (i, "vlanid %d", &tmp))
17646         vlanid = tmp;
17647       else
17648         {
17649           clib_warning ("parse error '%U'", format_unformat_error, i);
17650           return -99;
17651         }
17652     }
17653
17654   if ((sw_if_index == ~0) || (vtr_op == ~0))
17655     {
17656       errmsg ("missing sw_if_index or vtr operation");
17657       return -99;
17658     }
17659   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
17660       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
17661     {
17662       errmsg
17663         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
17664       return -99;
17665     }
17666
17667   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
17668   mp->sw_if_index = ntohl (sw_if_index);
17669   mp->vtr_op = ntohl (vtr_op);
17670   mp->outer_tag = ntohs (outer_tag);
17671   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
17672   clib_memcpy (mp->b_smac, smac, sizeof (smac));
17673   mp->b_vlanid = ntohs (vlanid);
17674   mp->i_sid = ntohl (sid);
17675
17676   S (mp);
17677   W (ret);
17678   return ret;
17679 }
17680
17681 static int
17682 api_flow_classify_set_interface (vat_main_t * vam)
17683 {
17684   unformat_input_t *i = vam->input;
17685   vl_api_flow_classify_set_interface_t *mp;
17686   u32 sw_if_index;
17687   int sw_if_index_set;
17688   u32 ip4_table_index = ~0;
17689   u32 ip6_table_index = ~0;
17690   u8 is_add = 1;
17691   int ret;
17692
17693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17694     {
17695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17696         sw_if_index_set = 1;
17697       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17698         sw_if_index_set = 1;
17699       else if (unformat (i, "del"))
17700         is_add = 0;
17701       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17702         ;
17703       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17704         ;
17705       else
17706         {
17707           clib_warning ("parse error '%U'", format_unformat_error, i);
17708           return -99;
17709         }
17710     }
17711
17712   if (sw_if_index_set == 0)
17713     {
17714       errmsg ("missing interface name or sw_if_index");
17715       return -99;
17716     }
17717
17718   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
17719
17720   mp->sw_if_index = ntohl (sw_if_index);
17721   mp->ip4_table_index = ntohl (ip4_table_index);
17722   mp->ip6_table_index = ntohl (ip6_table_index);
17723   mp->is_add = is_add;
17724
17725   S (mp);
17726   W (ret);
17727   return ret;
17728 }
17729
17730 static int
17731 api_flow_classify_dump (vat_main_t * vam)
17732 {
17733   unformat_input_t *i = vam->input;
17734   vl_api_flow_classify_dump_t *mp;
17735   vl_api_control_ping_t *mp_ping;
17736   u8 type = FLOW_CLASSIFY_N_TABLES;
17737   int ret;
17738
17739   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
17740     ;
17741   else
17742     {
17743       errmsg ("classify table type must be specified");
17744       return -99;
17745     }
17746
17747   if (!vam->json_output)
17748     {
17749       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17750     }
17751
17752   M (FLOW_CLASSIFY_DUMP, mp);
17753   mp->type = type;
17754   /* send it... */
17755   S (mp);
17756
17757   /* Use a control ping for synchronization */
17758   M (CONTROL_PING, mp_ping);
17759   S (mp_ping);
17760
17761   /* Wait for a reply... */
17762   W (ret);
17763   return ret;
17764 }
17765
17766 static int
17767 api_feature_enable_disable (vat_main_t * vam)
17768 {
17769   unformat_input_t *i = vam->input;
17770   vl_api_feature_enable_disable_t *mp;
17771   u8 *arc_name = 0;
17772   u8 *feature_name = 0;
17773   u32 sw_if_index = ~0;
17774   u8 enable = 1;
17775   int ret;
17776
17777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17778     {
17779       if (unformat (i, "arc_name %s", &arc_name))
17780         ;
17781       else if (unformat (i, "feature_name %s", &feature_name))
17782         ;
17783       else
17784         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17785         ;
17786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17787         ;
17788       else if (unformat (i, "disable"))
17789         enable = 0;
17790       else
17791         break;
17792     }
17793
17794   if (arc_name == 0)
17795     {
17796       errmsg ("missing arc name");
17797       return -99;
17798     }
17799   if (vec_len (arc_name) > 63)
17800     {
17801       errmsg ("arc name too long");
17802     }
17803
17804   if (feature_name == 0)
17805     {
17806       errmsg ("missing feature name");
17807       return -99;
17808     }
17809   if (vec_len (feature_name) > 63)
17810     {
17811       errmsg ("feature name too long");
17812     }
17813
17814   if (sw_if_index == ~0)
17815     {
17816       errmsg ("missing interface name or sw_if_index");
17817       return -99;
17818     }
17819
17820   /* Construct the API message */
17821   M (FEATURE_ENABLE_DISABLE, mp);
17822   mp->sw_if_index = ntohl (sw_if_index);
17823   mp->enable = enable;
17824   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
17825   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
17826   vec_free (arc_name);
17827   vec_free (feature_name);
17828
17829   S (mp);
17830   W (ret);
17831   return ret;
17832 }
17833
17834 static int
17835 api_sw_interface_tag_add_del (vat_main_t * vam)
17836 {
17837   unformat_input_t *i = vam->input;
17838   vl_api_sw_interface_tag_add_del_t *mp;
17839   u32 sw_if_index = ~0;
17840   u8 *tag = 0;
17841   u8 enable = 1;
17842   int ret;
17843
17844   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17845     {
17846       if (unformat (i, "tag %s", &tag))
17847         ;
17848       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17849         ;
17850       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17851         ;
17852       else if (unformat (i, "del"))
17853         enable = 0;
17854       else
17855         break;
17856     }
17857
17858   if (sw_if_index == ~0)
17859     {
17860       errmsg ("missing interface name or sw_if_index");
17861       return -99;
17862     }
17863
17864   if (enable && (tag == 0))
17865     {
17866       errmsg ("no tag specified");
17867       return -99;
17868     }
17869
17870   /* Construct the API message */
17871   M (SW_INTERFACE_TAG_ADD_DEL, mp);
17872   mp->sw_if_index = ntohl (sw_if_index);
17873   mp->is_add = enable;
17874   if (enable)
17875     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17876   vec_free (tag);
17877
17878   S (mp);
17879   W (ret);
17880   return ret;
17881 }
17882
17883 static void vl_api_l2_xconnect_details_t_handler
17884   (vl_api_l2_xconnect_details_t * mp)
17885 {
17886   vat_main_t *vam = &vat_main;
17887
17888   print (vam->ofp, "%15d%15d",
17889          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17890 }
17891
17892 static void vl_api_l2_xconnect_details_t_handler_json
17893   (vl_api_l2_xconnect_details_t * mp)
17894 {
17895   vat_main_t *vam = &vat_main;
17896   vat_json_node_t *node = NULL;
17897
17898   if (VAT_JSON_ARRAY != vam->json_tree.type)
17899     {
17900       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17901       vat_json_init_array (&vam->json_tree);
17902     }
17903   node = vat_json_array_add (&vam->json_tree);
17904
17905   vat_json_init_object (node);
17906   vat_json_object_add_uint (node, "rx_sw_if_index",
17907                             ntohl (mp->rx_sw_if_index));
17908   vat_json_object_add_uint (node, "tx_sw_if_index",
17909                             ntohl (mp->tx_sw_if_index));
17910 }
17911
17912 static int
17913 api_l2_xconnect_dump (vat_main_t * vam)
17914 {
17915   vl_api_l2_xconnect_dump_t *mp;
17916   vl_api_control_ping_t *mp_ping;
17917   int ret;
17918
17919   if (!vam->json_output)
17920     {
17921       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17922     }
17923
17924   M (L2_XCONNECT_DUMP, mp);
17925
17926   S (mp);
17927
17928   /* Use a control ping for synchronization */
17929   M (CONTROL_PING, mp_ping);
17930   S (mp_ping);
17931
17932   W (ret);
17933   return ret;
17934 }
17935
17936 static int
17937 api_sw_interface_set_mtu (vat_main_t * vam)
17938 {
17939   unformat_input_t *i = vam->input;
17940   vl_api_sw_interface_set_mtu_t *mp;
17941   u32 sw_if_index = ~0;
17942   u32 mtu = 0;
17943   int ret;
17944
17945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17946     {
17947       if (unformat (i, "mtu %d", &mtu))
17948         ;
17949       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17950         ;
17951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17952         ;
17953       else
17954         break;
17955     }
17956
17957   if (sw_if_index == ~0)
17958     {
17959       errmsg ("missing interface name or sw_if_index");
17960       return -99;
17961     }
17962
17963   if (mtu == 0)
17964     {
17965       errmsg ("no mtu specified");
17966       return -99;
17967     }
17968
17969   /* Construct the API message */
17970   M (SW_INTERFACE_SET_MTU, mp);
17971   mp->sw_if_index = ntohl (sw_if_index);
17972   mp->mtu = ntohs ((u16) mtu);
17973
17974   S (mp);
17975   W (ret);
17976   return ret;
17977 }
17978
17979
17980 static int
17981 q_or_quit (vat_main_t * vam)
17982 {
17983 #if VPP_API_TEST_BUILTIN == 0
17984   longjmp (vam->jump_buf, 1);
17985 #endif
17986   return 0;                     /* not so much */
17987 }
17988
17989 static int
17990 q (vat_main_t * vam)
17991 {
17992   return q_or_quit (vam);
17993 }
17994
17995 static int
17996 quit (vat_main_t * vam)
17997 {
17998   return q_or_quit (vam);
17999 }
18000
18001 static int
18002 comment (vat_main_t * vam)
18003 {
18004   return 0;
18005 }
18006
18007 static int
18008 cmd_cmp (void *a1, void *a2)
18009 {
18010   u8 **c1 = a1;
18011   u8 **c2 = a2;
18012
18013   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
18014 }
18015
18016 static int
18017 help (vat_main_t * vam)
18018 {
18019   u8 **cmds = 0;
18020   u8 *name = 0;
18021   hash_pair_t *p;
18022   unformat_input_t *i = vam->input;
18023   int j;
18024
18025   if (unformat (i, "%s", &name))
18026     {
18027       uword *hs;
18028
18029       vec_add1 (name, 0);
18030
18031       hs = hash_get_mem (vam->help_by_name, name);
18032       if (hs)
18033         print (vam->ofp, "usage: %s %s", name, hs[0]);
18034       else
18035         print (vam->ofp, "No such msg / command '%s'", name);
18036       vec_free (name);
18037       return 0;
18038     }
18039
18040   print (vam->ofp, "Help is available for the following:");
18041
18042     /* *INDENT-OFF* */
18043     hash_foreach_pair (p, vam->function_by_name,
18044     ({
18045       vec_add1 (cmds, (u8 *)(p->key));
18046     }));
18047     /* *INDENT-ON* */
18048
18049   vec_sort_with_function (cmds, cmd_cmp);
18050
18051   for (j = 0; j < vec_len (cmds); j++)
18052     print (vam->ofp, "%s", cmds[j]);
18053
18054   vec_free (cmds);
18055   return 0;
18056 }
18057
18058 static int
18059 set (vat_main_t * vam)
18060 {
18061   u8 *name = 0, *value = 0;
18062   unformat_input_t *i = vam->input;
18063
18064   if (unformat (i, "%s", &name))
18065     {
18066       /* The input buffer is a vector, not a string. */
18067       value = vec_dup (i->buffer);
18068       vec_delete (value, i->index, 0);
18069       /* Almost certainly has a trailing newline */
18070       if (value[vec_len (value) - 1] == '\n')
18071         value[vec_len (value) - 1] = 0;
18072       /* Make sure it's a proper string, one way or the other */
18073       vec_add1 (value, 0);
18074       (void) clib_macro_set_value (&vam->macro_main,
18075                                    (char *) name, (char *) value);
18076     }
18077   else
18078     errmsg ("usage: set <name> <value>");
18079
18080   vec_free (name);
18081   vec_free (value);
18082   return 0;
18083 }
18084
18085 static int
18086 unset (vat_main_t * vam)
18087 {
18088   u8 *name = 0;
18089
18090   if (unformat (vam->input, "%s", &name))
18091     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
18092       errmsg ("unset: %s wasn't set", name);
18093   vec_free (name);
18094   return 0;
18095 }
18096
18097 typedef struct
18098 {
18099   u8 *name;
18100   u8 *value;
18101 } macro_sort_t;
18102
18103
18104 static int
18105 macro_sort_cmp (void *a1, void *a2)
18106 {
18107   macro_sort_t *s1 = a1;
18108   macro_sort_t *s2 = a2;
18109
18110   return strcmp ((char *) (s1->name), (char *) (s2->name));
18111 }
18112
18113 static int
18114 dump_macro_table (vat_main_t * vam)
18115 {
18116   macro_sort_t *sort_me = 0, *sm;
18117   int i;
18118   hash_pair_t *p;
18119
18120     /* *INDENT-OFF* */
18121     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
18122     ({
18123       vec_add2 (sort_me, sm, 1);
18124       sm->name = (u8 *)(p->key);
18125       sm->value = (u8 *) (p->value[0]);
18126     }));
18127     /* *INDENT-ON* */
18128
18129   vec_sort_with_function (sort_me, macro_sort_cmp);
18130
18131   if (vec_len (sort_me))
18132     print (vam->ofp, "%-15s%s", "Name", "Value");
18133   else
18134     print (vam->ofp, "The macro table is empty...");
18135
18136   for (i = 0; i < vec_len (sort_me); i++)
18137     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
18138   return 0;
18139 }
18140
18141 static int
18142 dump_node_table (vat_main_t * vam)
18143 {
18144   int i, j;
18145   vlib_node_t *node, *next_node;
18146
18147   if (vec_len (vam->graph_nodes) == 0)
18148     {
18149       print (vam->ofp, "Node table empty, issue get_node_graph...");
18150       return 0;
18151     }
18152
18153   for (i = 0; i < vec_len (vam->graph_nodes); i++)
18154     {
18155       node = vam->graph_nodes[i];
18156       print (vam->ofp, "[%d] %s", i, node->name);
18157       for (j = 0; j < vec_len (node->next_nodes); j++)
18158         {
18159           if (node->next_nodes[j] != ~0)
18160             {
18161               next_node = vam->graph_nodes[node->next_nodes[j]];
18162               print (vam->ofp, "  [%d] %s", j, next_node->name);
18163             }
18164         }
18165     }
18166   return 0;
18167 }
18168
18169 static int
18170 value_sort_cmp (void *a1, void *a2)
18171 {
18172   name_sort_t *n1 = a1;
18173   name_sort_t *n2 = a2;
18174
18175   if (n1->value < n2->value)
18176     return -1;
18177   if (n1->value > n2->value)
18178     return 1;
18179   return 0;
18180 }
18181
18182
18183 static int
18184 dump_msg_api_table (vat_main_t * vam)
18185 {
18186   api_main_t *am = &api_main;
18187   name_sort_t *nses = 0, *ns;
18188   hash_pair_t *hp;
18189   int i;
18190
18191   /* *INDENT-OFF* */
18192   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
18193   ({
18194     vec_add2 (nses, ns, 1);
18195     ns->name = (u8 *)(hp->key);
18196     ns->value = (u32) hp->value[0];
18197   }));
18198   /* *INDENT-ON* */
18199
18200   vec_sort_with_function (nses, value_sort_cmp);
18201
18202   for (i = 0; i < vec_len (nses); i++)
18203     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
18204   vec_free (nses);
18205   return 0;
18206 }
18207
18208 static int
18209 get_msg_id (vat_main_t * vam)
18210 {
18211   u8 *name_and_crc;
18212   u32 message_index;
18213
18214   if (unformat (vam->input, "%s", &name_and_crc))
18215     {
18216       message_index = vl_api_get_msg_index (name_and_crc);
18217       if (message_index == ~0)
18218         {
18219           print (vam->ofp, " '%s' not found", name_and_crc);
18220           return 0;
18221         }
18222       print (vam->ofp, " '%s' has message index %d",
18223              name_and_crc, message_index);
18224       return 0;
18225     }
18226   errmsg ("name_and_crc required...");
18227   return 0;
18228 }
18229
18230 static int
18231 search_node_table (vat_main_t * vam)
18232 {
18233   unformat_input_t *line_input = vam->input;
18234   u8 *node_to_find;
18235   int j;
18236   vlib_node_t *node, *next_node;
18237   uword *p;
18238
18239   if (vam->graph_node_index_by_name == 0)
18240     {
18241       print (vam->ofp, "Node table empty, issue get_node_graph...");
18242       return 0;
18243     }
18244
18245   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
18246     {
18247       if (unformat (line_input, "%s", &node_to_find))
18248         {
18249           vec_add1 (node_to_find, 0);
18250           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
18251           if (p == 0)
18252             {
18253               print (vam->ofp, "%s not found...", node_to_find);
18254               goto out;
18255             }
18256           node = vam->graph_nodes[p[0]];
18257           print (vam->ofp, "[%d] %s", p[0], node->name);
18258           for (j = 0; j < vec_len (node->next_nodes); j++)
18259             {
18260               if (node->next_nodes[j] != ~0)
18261                 {
18262                   next_node = vam->graph_nodes[node->next_nodes[j]];
18263                   print (vam->ofp, "  [%d] %s", j, next_node->name);
18264                 }
18265             }
18266         }
18267
18268       else
18269         {
18270           clib_warning ("parse error '%U'", format_unformat_error,
18271                         line_input);
18272           return -99;
18273         }
18274
18275     out:
18276       vec_free (node_to_find);
18277
18278     }
18279
18280   return 0;
18281 }
18282
18283
18284 static int
18285 script (vat_main_t * vam)
18286 {
18287 #if (VPP_API_TEST_BUILTIN==0)
18288   u8 *s = 0;
18289   char *save_current_file;
18290   unformat_input_t save_input;
18291   jmp_buf save_jump_buf;
18292   u32 save_line_number;
18293
18294   FILE *new_fp, *save_ifp;
18295
18296   if (unformat (vam->input, "%s", &s))
18297     {
18298       new_fp = fopen ((char *) s, "r");
18299       if (new_fp == 0)
18300         {
18301           errmsg ("Couldn't open script file %s", s);
18302           vec_free (s);
18303           return -99;
18304         }
18305     }
18306   else
18307     {
18308       errmsg ("Missing script name");
18309       return -99;
18310     }
18311
18312   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
18313   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
18314   save_ifp = vam->ifp;
18315   save_line_number = vam->input_line_number;
18316   save_current_file = (char *) vam->current_file;
18317
18318   vam->input_line_number = 0;
18319   vam->ifp = new_fp;
18320   vam->current_file = s;
18321   do_one_file (vam);
18322
18323   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
18324   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
18325   vam->ifp = save_ifp;
18326   vam->input_line_number = save_line_number;
18327   vam->current_file = (u8 *) save_current_file;
18328   vec_free (s);
18329
18330   return 0;
18331 #else
18332   clib_warning ("use the exec command...");
18333   return -99;
18334 #endif
18335 }
18336
18337 static int
18338 echo (vat_main_t * vam)
18339 {
18340   print (vam->ofp, "%v", vam->input->buffer);
18341   return 0;
18342 }
18343
18344 /* List of API message constructors, CLI names map to api_xxx */
18345 #define foreach_vpe_api_msg                                             \
18346 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
18347 _(sw_interface_dump,"")                                                 \
18348 _(sw_interface_set_flags,                                               \
18349   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
18350 _(sw_interface_add_del_address,                                         \
18351   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
18352 _(sw_interface_set_table,                                               \
18353   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
18354 _(sw_interface_set_mpls_enable,                                         \
18355   "<intfc> | sw_if_index [disable | dis]")                              \
18356 _(sw_interface_set_vpath,                                               \
18357   "<intfc> | sw_if_index <id> enable | disable")                        \
18358 _(sw_interface_set_vxlan_bypass,                                        \
18359   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
18360 _(sw_interface_set_l2_xconnect,                                         \
18361   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18362   "enable | disable")                                                   \
18363 _(sw_interface_set_l2_bridge,                                           \
18364   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
18365   "[shg <split-horizon-group>] [bvi]\n"                                 \
18366   "enable | disable")                                                   \
18367 _(bridge_domain_add_del,                                                \
18368   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
18369 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
18370 _(l2fib_add_del,                                                        \
18371   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
18372 _(l2_flags,                                                             \
18373   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
18374 _(bridge_flags,                                                         \
18375   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
18376 _(tap_connect,                                                          \
18377   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
18378 _(tap_modify,                                                           \
18379   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
18380 _(tap_delete,                                                           \
18381   "<vpp-if-name> | sw_if_index <id>")                                   \
18382 _(sw_interface_tap_dump, "")                                            \
18383 _(ip_add_del_route,                                                     \
18384   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
18385   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18386   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18387   "[multipath] [count <n>]")                                            \
18388 _(ip_mroute_add_del,                                                    \
18389   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
18390   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
18391 _(mpls_route_add_del,                                                   \
18392   "<label> <eos> via <addr> [table-id <n>]\n"                           \
18393   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
18394   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
18395   "[multipath] [count <n>]")                                            \
18396 _(mpls_ip_bind_unbind,                                                  \
18397   "<label> <addr/len>")                                                 \
18398 _(mpls_tunnel_add_del,                                                  \
18399   " via <addr> [table-id <n>]\n"                                        \
18400   "sw_if_index <id>] [l2]  [del]")                                      \
18401 _(proxy_arp_add_del,                                                    \
18402   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
18403 _(proxy_arp_intfc_enable_disable,                                       \
18404   "<intfc> | sw_if_index <id> enable | disable")                        \
18405 _(sw_interface_set_unnumbered,                                          \
18406   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
18407 _(ip_neighbor_add_del,                                                  \
18408   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
18409   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
18410 _(reset_vrf, "vrf <id> [ipv6]")                                         \
18411 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
18412 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
18413   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
18414   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
18415   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
18416 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
18417 _(reset_fib, "vrf <n> [ipv6]")                                          \
18418 _(dhcp_proxy_config,                                                    \
18419   "svr <v46-address> src <v46-address>\n"                               \
18420    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
18421 _(dhcp_proxy_set_vss,                                                   \
18422   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
18423 _(dhcp_proxy_dump, "ip6")                                               \
18424 _(dhcp_client_config,                                                   \
18425   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
18426 _(set_ip_flow_hash,                                                     \
18427   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
18428 _(sw_interface_ip6_enable_disable,                                      \
18429   "<intfc> | sw_if_index <id> enable | disable")                        \
18430 _(sw_interface_ip6_set_link_local_address,                              \
18431   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
18432 _(ip6nd_proxy_add_del,                                                  \
18433   "<intfc> | sw_if_index <id> <ip6-address>")                           \
18434 _(ip6nd_proxy_dump, "")                                                 \
18435 _(sw_interface_ip6nd_ra_prefix,                                         \
18436   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
18437   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
18438   "[nolink] [isno]")                                                    \
18439 _(sw_interface_ip6nd_ra_config,                                         \
18440   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
18441   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
18442   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
18443 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
18444 _(l2_patch_add_del,                                                     \
18445   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
18446   "enable | disable")                                                   \
18447 _(sr_localsid_add_del,                                                  \
18448   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
18449   "fib-table <num> (end.psp) sw_if_index <num>")                        \
18450 _(classify_add_del_table,                                               \
18451   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
18452   " [del] [del-chain] mask <mask-value>\n"                              \
18453   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
18454   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
18455 _(classify_add_del_session,                                             \
18456   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
18457   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
18458   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
18459   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
18460 _(classify_set_interface_ip_table,                                      \
18461   "<intfc> | sw_if_index <nn> table <nn>")                              \
18462 _(classify_set_interface_l2_tables,                                     \
18463   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18464   "  [other-table <nn>]")                                               \
18465 _(get_node_index, "node <node-name")                                    \
18466 _(add_node_next, "node <node-name> next <next-node-name>")              \
18467 _(l2tpv3_create_tunnel,                                                 \
18468   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
18469   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
18470   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
18471 _(l2tpv3_set_tunnel_cookies,                                            \
18472   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
18473   "[new_remote_cookie <nn>]\n")                                         \
18474 _(l2tpv3_interface_enable_disable,                                      \
18475   "<intfc> | sw_if_index <nn> enable | disable")                        \
18476 _(l2tpv3_set_lookup_key,                                                \
18477   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
18478 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
18479 _(vxlan_add_del_tunnel,                                                 \
18480   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
18481   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
18482   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
18483 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
18484 _(gre_add_del_tunnel,                                                   \
18485   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
18486 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
18487 _(l2_fib_clear_table, "")                                               \
18488 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
18489 _(l2_interface_vlan_tag_rewrite,                                        \
18490   "<intfc> | sw_if_index <nn> \n"                                       \
18491   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
18492   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
18493 _(create_vhost_user_if,                                                 \
18494         "socket <filename> [server] [renumber <dev_instance>] "         \
18495         "[mac <mac_address>]")                                          \
18496 _(modify_vhost_user_if,                                                 \
18497         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
18498         "[server] [renumber <dev_instance>]")                           \
18499 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
18500 _(sw_interface_vhost_user_dump, "")                                     \
18501 _(show_version, "")                                                     \
18502 _(vxlan_gpe_add_del_tunnel,                                             \
18503   "local <addr> remote <addr> vni <nn>\n"                               \
18504     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
18505   "[next-ethernet] [next-nsh]\n")                                       \
18506 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
18507 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
18508 _(interface_name_renumber,                                              \
18509   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
18510 _(input_acl_set_interface,                                              \
18511   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18512   "  [l2-table <nn>] [del]")                                            \
18513 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
18514 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
18515 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
18516 _(ip_dump, "ipv4 | ipv6")                                               \
18517 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
18518 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
18519   "  spid_id <n> ")                                                     \
18520 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
18521   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
18522   "  integ_alg <alg> integ_key <hex>")                                  \
18523 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
18524   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
18525   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
18526   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
18527 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
18528 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
18529 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
18530   "(auth_data 0x<data> | auth_data <data>)")                            \
18531 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
18532   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
18533 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
18534   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
18535   "(local|remote)")                                                     \
18536 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
18537 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
18538 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18539 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
18540 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
18541 _(ikev2_initiate_sa_init, "<profile_name>")                             \
18542 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
18543 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
18544 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
18545 _(delete_loopback,"sw_if_index <nn>")                                   \
18546 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
18547 _(map_add_domain,                                                       \
18548   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
18549   "ip6-src <ip6addr> "                                                  \
18550   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
18551 _(map_del_domain, "index <n>")                                          \
18552 _(map_add_del_rule,                                                     \
18553   "index <n> psid <n> dst <ip6addr> [del]")                             \
18554 _(map_domain_dump, "")                                                  \
18555 _(map_rule_dump, "index <map-domain>")                                  \
18556 _(want_interface_events,  "enable|disable")                             \
18557 _(want_stats,"enable|disable")                                          \
18558 _(get_first_msg_id, "client <name>")                                    \
18559 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
18560 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
18561   "fib-id <nn> [ip4][ip6][default]")                                    \
18562 _(get_node_graph, " ")                                                  \
18563 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
18564 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
18565 _(ioam_disable, "")                                                     \
18566 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
18567                             " sw_if_index <sw_if_index> p <priority> "  \
18568                             "w <weight>] [del]")                        \
18569 _(one_add_del_locator, "locator-set <locator_name> "                    \
18570                         "iface <intf> | sw_if_index <sw_if_index> "     \
18571                         "p <priority> w <weight> [del]")                \
18572 _(one_add_del_local_eid,"vni <vni> eid "                                \
18573                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18574                          "locator-set <locator_name> [del]"             \
18575                          "[key-id sha1|sha256 secret-key <secret-key>]")\
18576 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
18577 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
18578 _(one_enable_disable, "enable|disable")                                 \
18579 _(one_map_register_enable_disable, "enable|disable")                    \
18580 _(one_rloc_probe_enable_disable, "enable|disable")                      \
18581 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
18582                                "[seid <seid>] "                         \
18583                                "rloc <locator> p <prio> "               \
18584                                "w <weight> [rloc <loc> ... ] "          \
18585                                "action <action> [del-all]")             \
18586 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
18587                           "<local-eid>")                                \
18588 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
18589 _(one_use_petr, "ip-address> | disable")                                \
18590 _(one_map_request_mode, "src-dst|dst-only")                             \
18591 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
18592 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
18593 _(one_locator_set_dump, "[local | remote]")                             \
18594 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
18595 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
18596                        "[local] | [remote]")                            \
18597 _(one_stats_enable_disable, "enable|disalbe")                           \
18598 _(show_one_stats_enable_disable, "")                                    \
18599 _(one_eid_table_vni_dump, "")                                           \
18600 _(one_eid_table_map_dump, "l2|l3")                                      \
18601 _(one_map_resolver_dump, "")                                            \
18602 _(one_map_server_dump, "")                                              \
18603 _(one_adjacencies_get, "vni <vni>")                                     \
18604 _(show_one_rloc_probe_state, "")                                        \
18605 _(show_one_map_register_state, "")                                      \
18606 _(show_one_status, "")                                                  \
18607 _(one_stats_dump, "")                                                   \
18608 _(one_get_map_request_itr_rlocs, "")                                    \
18609 _(show_one_pitr, "")                                                    \
18610 _(show_one_use_petr, "")                                                \
18611 _(show_one_map_request_mode, "")                                        \
18612 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
18613                             " sw_if_index <sw_if_index> p <priority> "  \
18614                             "w <weight>] [del]")                        \
18615 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
18616                         "iface <intf> | sw_if_index <sw_if_index> "     \
18617                         "p <priority> w <weight> [del]")                \
18618 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
18619                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
18620                          "locator-set <locator_name> [del]"             \
18621                          "[key-id sha1|sha256 secret-key <secret-key>]") \
18622 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
18623 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
18624 _(lisp_enable_disable, "enable|disable")                                \
18625 _(lisp_map_register_enable_disable, "enable|disable")                   \
18626 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
18627 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
18628                                "[seid <seid>] "                         \
18629                                "rloc <locator> p <prio> "               \
18630                                "w <weight> [rloc <loc> ... ] "          \
18631                                "action <action> [del-all]")             \
18632 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
18633                           "<local-eid>")                                \
18634 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
18635 _(lisp_use_petr, "<ip-address> | disable")                              \
18636 _(lisp_map_request_mode, "src-dst|dst-only")                            \
18637 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
18638 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
18639 _(lisp_locator_set_dump, "[local | remote]")                            \
18640 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
18641 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
18642                        "[local] | [remote]")                            \
18643 _(lisp_eid_table_vni_dump, "")                                          \
18644 _(lisp_eid_table_map_dump, "l2|l3")                                     \
18645 _(lisp_map_resolver_dump, "")                                           \
18646 _(lisp_map_server_dump, "")                                             \
18647 _(lisp_adjacencies_get, "vni <vni>")                                    \
18648 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
18649 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
18650 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
18651 _(gpe_get_encap_mode, "")                                               \
18652 _(lisp_gpe_add_del_iface, "up|down")                                    \
18653 _(lisp_gpe_enable_disable, "enable|disable")                            \
18654 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
18655   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
18656 _(show_lisp_rloc_probe_state, "")                                       \
18657 _(show_lisp_map_register_state, "")                                     \
18658 _(show_lisp_status, "")                                                 \
18659 _(lisp_get_map_request_itr_rlocs, "")                                   \
18660 _(show_lisp_pitr, "")                                                   \
18661 _(show_lisp_use_petr, "")                                               \
18662 _(show_lisp_map_request_mode, "")                                       \
18663 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
18664 _(af_packet_delete, "name <host interface name>")                       \
18665 _(policer_add_del, "name <policer name> <params> [del]")                \
18666 _(policer_dump, "[name <policer name>]")                                \
18667 _(policer_classify_set_interface,                                       \
18668   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
18669   "  [l2-table <nn>] [del]")                                            \
18670 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
18671 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
18672     "[master|slave]")                                                   \
18673 _(netmap_delete, "name <interface name>")                               \
18674 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
18675 _(mpls_fib_dump, "")                                                    \
18676 _(classify_table_ids, "")                                               \
18677 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
18678 _(classify_table_info, "table_id <nn>")                                 \
18679 _(classify_session_dump, "table_id <nn>")                               \
18680 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
18681     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
18682     "[template_interval <nn>] [udp_checksum]")                          \
18683 _(ipfix_exporter_dump, "")                                              \
18684 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
18685 _(ipfix_classify_stream_dump, "")                                       \
18686 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
18687 _(ipfix_classify_table_dump, "")                                        \
18688 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
18689 _(sw_interface_span_dump, "")                                           \
18690 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
18691 _(pg_create_interface, "if_id <nn>")                                    \
18692 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
18693 _(pg_enable_disable, "[stream <id>] disable")                           \
18694 _(ip_source_and_port_range_check_add_del,                               \
18695   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
18696 _(ip_source_and_port_range_check_interface_add_del,                     \
18697   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
18698   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
18699 _(ipsec_gre_add_del_tunnel,                                             \
18700   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
18701 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
18702 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
18703 _(l2_interface_pbb_tag_rewrite,                                         \
18704   "<intfc> | sw_if_index <nn> \n"                                       \
18705   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
18706   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
18707 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
18708 _(flow_classify_set_interface,                                          \
18709   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
18710 _(flow_classify_dump, "type [ip4|ip6]")                                 \
18711 _(ip_fib_dump, "")                                                      \
18712 _(ip_mfib_dump, "")                                                     \
18713 _(ip6_fib_dump, "")                                                     \
18714 _(ip6_mfib_dump, "")                                                    \
18715 _(feature_enable_disable, "arc_name <arc_name> "                        \
18716   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
18717 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
18718 "[disable]")                                                            \
18719 _(l2_xconnect_dump, "")                                                 \
18720 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
18721 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
18722 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
18723
18724 /* List of command functions, CLI names map directly to functions */
18725 #define foreach_cli_function                                    \
18726 _(comment, "usage: comment <ignore-rest-of-line>")              \
18727 _(dump_interface_table, "usage: dump_interface_table")          \
18728 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
18729 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
18730 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
18731 _(dump_stats_table, "usage: dump_stats_table")                  \
18732 _(dump_macro_table, "usage: dump_macro_table ")                 \
18733 _(dump_node_table, "usage: dump_node_table")                    \
18734 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
18735 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
18736 _(echo, "usage: echo <message>")                                \
18737 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
18738 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
18739 _(help, "usage: help")                                          \
18740 _(q, "usage: quit")                                             \
18741 _(quit, "usage: quit")                                          \
18742 _(search_node_table, "usage: search_node_table <name>...")      \
18743 _(set, "usage: set <variable-name> <value>")                    \
18744 _(script, "usage: script <file-name>")                          \
18745 _(unset, "usage: unset <variable-name>")
18746
18747 #define _(N,n)                                  \
18748     static void vl_api_##n##_t_handler_uni      \
18749     (vl_api_##n##_t * mp)                       \
18750     {                                           \
18751         vat_main_t * vam = &vat_main;           \
18752         if (vam->json_output) {                 \
18753             vl_api_##n##_t_handler_json(mp);    \
18754         } else {                                \
18755             vl_api_##n##_t_handler(mp);         \
18756         }                                       \
18757     }
18758 foreach_vpe_api_reply_msg;
18759 #if VPP_API_TEST_BUILTIN == 0
18760 foreach_standalone_reply_msg;
18761 #endif
18762 #undef _
18763
18764 void
18765 vat_api_hookup (vat_main_t * vam)
18766 {
18767 #define _(N,n)                                                  \
18768     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
18769                            vl_api_##n##_t_handler_uni,          \
18770                            vl_noop_handler,                     \
18771                            vl_api_##n##_t_endian,               \
18772                            vl_api_##n##_t_print,                \
18773                            sizeof(vl_api_##n##_t), 1);
18774   foreach_vpe_api_reply_msg;
18775 #if VPP_API_TEST_BUILTIN == 0
18776   foreach_standalone_reply_msg;
18777 #endif
18778 #undef _
18779
18780 #if (VPP_API_TEST_BUILTIN==0)
18781   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
18782
18783   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
18784
18785   vam->function_by_name = hash_create_string (0, sizeof (uword));
18786
18787   vam->help_by_name = hash_create_string (0, sizeof (uword));
18788 #endif
18789
18790   /* API messages we can send */
18791 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
18792   foreach_vpe_api_msg;
18793 #undef _
18794
18795   /* Help strings */
18796 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18797   foreach_vpe_api_msg;
18798 #undef _
18799
18800   /* CLI functions */
18801 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
18802   foreach_cli_function;
18803 #undef _
18804
18805   /* Help strings */
18806 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
18807   foreach_cli_function;
18808 #undef _
18809 }
18810
18811 #if VPP_API_TEST_BUILTIN
18812 static clib_error_t *
18813 vat_api_hookup_shim (vlib_main_t * vm)
18814 {
18815   vat_api_hookup (&vat_main);
18816   return 0;
18817 }
18818
18819 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
18820 #endif
18821
18822 /*
18823  * fd.io coding-style-patch-verification: ON
18824  *
18825  * Local Variables:
18826  * eval: (c-set-style "gnu")
18827  * End:
18828  */